package camp.kuznetsov.rn.yandexmapkit; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.WritableMap; import com.facebook.react.uimanager.events.RCTEventEmitter; import javax.annotation.Nullable; import ru.yandex.yandexmapkit.MapController; import ru.yandex.yandexmapkit.MapView; import ru.yandex.yandexmapkit.map.GeoCode; import ru.yandex.yandexmapkit.map.GeoCodeListener; import ru.yandex.yandexmapkit.map.MapEvent; import ru.yandex.yandexmapkit.map.OnMapListener; import ru.yandex.yandexmapkit.overlay.location.MyLocationItem; import ru.yandex.yandexmapkit.overlay.location.MyLocationOverlay; import ru.yandex.yandexmapkit.utils.GeoPoint; import ru.yandex.yandexmapkit.utils.ScreenPoint; public class RNYandexMapKitView extends MapView implements OnMapListener, GeoCodeListener { public static final String MAP_EVENT = "onMapEvent"; public static final String GEOCODING_EVENT = "onGeocodingEvent"; private Boolean mGeocodingEnabled = false; public RNYandexMapKitView(Context context, String s) { super(context, s); this.getMapController().addMapListener(this); } public RNYandexMapKitView(Context context, AttributeSet attributeSet) { super(context, attributeSet); } @Override public void onMapActionEvent(MapEvent mapEvent) { MapController controller = getMapController(); GeoPoint mapCenter = controller.getMapCenter(); int msg = mapEvent.getMsg(); if (mGeocodingEnabled && msg == MapEvent.MSG_SCALE_END || msg == MapEvent.MSG_SCROLL_END || msg == MapEvent.MSG_ZOOM_END){ controller.getDownloader().getGeoCode(this, mapCenter); } Rect viewport = controller.getViewport(); if (viewport.width() == 0 || viewport.height() == 0) return; GeoPoint topLeft = controller.getGeoPoint(new ScreenPoint(viewport.left, viewport.top)); GeoPoint bottomRight = controller.getGeoPoint(new ScreenPoint(viewport.right, viewport.bottom)); double latDelta = Math.abs(bottomRight.getLat() - topLeft.getLat()); double lonDelta = Math.abs(bottomRight.getLon() - topLeft.getLon()); WritableMap payload = Arguments.createMap(); payload.putInt("type", msg); payload.putDouble("latitude", mapCenter.getLat()); payload.putDouble("longitude", mapCenter.getLon()); payload.putDouble("latitudeDelta", latDelta); payload.putDouble("longitudeDelta", lonDelta); ReactContext reactContext = (ReactContext) getContext(); reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(this.getId(), MAP_EVENT, payload); } public void setGeocodingEnabled(Boolean geocodingEnabled) { this.mGeocodingEnabled = geocodingEnabled; } @Override public boolean onFinishGeoCode(GeoCode geoCode) { if (geoCode != null) { WritableMap payload = Arguments.createMap(); payload.putString("displayName", geoCode.getDisplayName()); payload.putString("kind", geoCode.getKind()); payload.putString("title", geoCode.getTitle()); payload.putString("subtitle", geoCode.getSubtitle()); WritableMap point = Arguments.createMap(); GeoPoint geoPoint = geoCode.getGeoPoint(); point.putDouble("latitude", geoPoint.getLat()); point.putDouble("longitude", geoPoint.getLon()); payload.putMap("point", point); ReactContext reactContext = (ReactContext) getContext(); reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(this.getId(), GEOCODING_EVENT, payload); } return true; } public void animateToCoordinate(@Nullable GeoPoint coordinate){ MapController controller = getMapController(); if (coordinate == null){ MyLocationItem myLocation = controller.getOverlayManager().getMyLocation().getMyLocationItem(); if (myLocation != null){ controller.setPositionAnimationTo(myLocation.getGeoPoint()); } } else { controller.setPositionAnimationTo(coordinate); } } }