2016-06-30 16:59:10 +03:00
|
|
|
package com.mapbox.reactnativemapboxgl;
|
|
|
|
|
|
|
|
|
|
import android.content.Context;
|
2016-07-02 18:34:06 +03:00
|
|
|
import android.graphics.PointF;
|
|
|
|
|
import android.location.Location;
|
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
|
import android.support.annotation.UiThread;
|
2016-06-30 20:25:01 +03:00
|
|
|
import android.widget.LinearLayout;
|
2016-07-02 18:34:06 +03:00
|
|
|
import android.widget.RelativeLayout;
|
2016-06-30 16:59:10 +03:00
|
|
|
|
2016-07-02 18:34:06 +03:00
|
|
|
import com.facebook.react.bridge.Arguments;
|
2016-06-30 21:31:59 +03:00
|
|
|
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
2016-06-30 16:59:10 +03:00
|
|
|
import com.facebook.react.bridge.LifecycleEventListener;
|
2016-07-02 18:34:06 +03:00
|
|
|
import com.facebook.react.bridge.ReactContext;
|
|
|
|
|
import com.facebook.react.bridge.WritableArray;
|
|
|
|
|
import com.facebook.react.bridge.WritableMap;
|
2016-07-01 02:33:30 +03:00
|
|
|
import com.facebook.react.common.MapBuilder;
|
2016-07-02 18:34:06 +03:00
|
|
|
import com.facebook.react.common.ReactConstants;
|
|
|
|
|
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
2016-06-30 20:25:01 +03:00
|
|
|
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
2016-07-01 02:33:30 +03:00
|
|
|
import com.mapbox.mapboxsdk.camera.CameraUpdate;
|
|
|
|
|
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
2016-06-30 20:25:01 +03:00
|
|
|
import com.mapbox.mapboxsdk.geometry.LatLng;
|
2016-07-01 02:33:30 +03:00
|
|
|
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
|
2016-06-30 16:59:10 +03:00
|
|
|
import com.mapbox.mapboxsdk.maps.MapView;
|
|
|
|
|
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
2016-06-30 20:25:01 +03:00
|
|
|
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
2016-06-30 16:59:10 +03:00
|
|
|
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
2016-07-01 02:57:35 +03:00
|
|
|
import com.mapbox.mapboxsdk.maps.UiSettings;
|
2016-06-30 16:59:10 +03:00
|
|
|
|
2016-07-01 02:33:30 +03:00
|
|
|
import java.util.Map;
|
2016-07-02 18:34:06 +03:00
|
|
|
import java.util.logging.Handler;
|
2016-07-01 02:33:30 +03:00
|
|
|
|
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
|
|
2016-07-02 18:34:06 +03:00
|
|
|
public class ReactNativeMapboxGLView extends RelativeLayout implements
|
|
|
|
|
OnMapReadyCallback, LifecycleEventListener,
|
|
|
|
|
MapboxMap.OnMapClickListener, MapboxMap.OnMapLongClickListener,
|
|
|
|
|
MapboxMap.OnMyBearingTrackingModeChangeListener, MapboxMap.OnMyLocationTrackingModeChangeListener,
|
|
|
|
|
MapboxMap.OnMyLocationChangeListener,
|
|
|
|
|
MapView.OnMapChangedListener
|
|
|
|
|
{
|
2016-06-30 16:59:10 +03:00
|
|
|
|
|
|
|
|
private MapboxMap _map = null;
|
2016-06-30 20:25:01 +03:00
|
|
|
private MapView _mapView = null;
|
2016-06-30 16:59:10 +03:00
|
|
|
private ReactNativeMapboxGLManager _manager;
|
|
|
|
|
private boolean _paused = false;
|
|
|
|
|
|
2016-06-30 20:25:01 +03:00
|
|
|
private CameraPosition.Builder _initialCamera = new CameraPosition.Builder();
|
|
|
|
|
private MapboxMapOptions _mapOptions;
|
|
|
|
|
private int _locationTrackingMode;
|
|
|
|
|
private int _bearingTrackingMode;
|
2016-07-02 18:34:06 +03:00
|
|
|
private boolean _trackingModeUpdateScheduled = false;
|
2016-06-30 20:25:01 +03:00
|
|
|
private boolean _showsUserLocation;
|
2016-07-01 12:57:58 +03:00
|
|
|
private boolean _zoomEnabled = true;
|
|
|
|
|
private boolean _scrollEnabled = true;
|
|
|
|
|
private boolean _rotateEnabled = true;
|
2016-06-30 20:48:01 +03:00
|
|
|
private int _paddingTop, _paddingRight, _paddingBottom, _paddingLeft;
|
2016-06-30 16:59:10 +03:00
|
|
|
|
2016-07-02 18:34:06 +03:00
|
|
|
private android.os.Handler _trackingModeHandler;
|
|
|
|
|
|
|
|
|
|
@UiThread
|
2016-06-30 16:59:10 +03:00
|
|
|
public ReactNativeMapboxGLView(Context context, ReactNativeMapboxGLManager manager) {
|
|
|
|
|
super(context);
|
2016-07-02 18:34:06 +03:00
|
|
|
_trackingModeHandler = new android.os.Handler();
|
2016-06-30 16:59:10 +03:00
|
|
|
_manager = manager;
|
2016-06-30 20:25:01 +03:00
|
|
|
_mapOptions = MapboxMapOptions.createFromAttributes(context, null);
|
2016-07-01 12:57:58 +03:00
|
|
|
_mapOptions.zoomGesturesEnabled(true);
|
|
|
|
|
_mapOptions.rotateGesturesEnabled(true);
|
|
|
|
|
_mapOptions.scrollGesturesEnabled(true);
|
|
|
|
|
_mapOptions.tiltGesturesEnabled(true);
|
2016-06-30 16:59:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Lifecycle methods
|
|
|
|
|
|
2016-07-02 18:51:09 +03:00
|
|
|
public void onAfterUpdateTransaction() {
|
|
|
|
|
if (_mapView != null) { return; }
|
|
|
|
|
setupMapView();
|
2016-06-30 16:59:10 +03:00
|
|
|
_paused = false;
|
2016-06-30 20:25:01 +03:00
|
|
|
_mapView.onResume();
|
2016-06-30 16:59:10 +03:00
|
|
|
_manager.getContext().addLifecycleEventListener(this);
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-02 18:51:09 +03:00
|
|
|
public void onDrop() {
|
|
|
|
|
if (_mapView == null) { return; }
|
2016-06-30 16:59:10 +03:00
|
|
|
_manager.getContext().removeLifecycleEventListener(this);
|
2016-07-02 18:51:09 +03:00
|
|
|
if (!_paused) {
|
|
|
|
|
_paused = true;
|
|
|
|
|
_mapView.onPause();
|
|
|
|
|
}
|
|
|
|
|
destroyMapView();
|
|
|
|
|
_mapView = null;
|
2016-06-30 16:59:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onHostResume() {
|
|
|
|
|
_paused = false;
|
2016-06-30 20:25:01 +03:00
|
|
|
_mapView.onResume();
|
2016-06-30 16:59:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onHostPause() {
|
|
|
|
|
_paused = true;
|
2016-06-30 20:25:01 +03:00
|
|
|
_mapView.onPause();
|
2016-06-30 16:59:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onHostDestroy() {
|
2016-07-02 18:51:09 +03:00
|
|
|
onDrop();
|
2016-06-30 20:25:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialization
|
|
|
|
|
|
|
|
|
|
private void setupMapView() {
|
|
|
|
|
_mapOptions.camera(_initialCamera.build());
|
|
|
|
|
_mapView = new MapView(this.getContext(), _mapOptions);
|
|
|
|
|
this.addView(_mapView);
|
2016-07-02 18:34:06 +03:00
|
|
|
_mapView.addOnMapChangedListener(this);
|
|
|
|
|
_mapView.onCreate(null);
|
|
|
|
|
_mapView.getMapAsync(this);
|
2016-06-30 16:59:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onMapReady(MapboxMap mapboxMap) {
|
2016-07-02 18:51:09 +03:00
|
|
|
if (_mapView == null) { return; }
|
2016-06-30 16:59:10 +03:00
|
|
|
_map = mapboxMap;
|
2016-07-02 18:34:06 +03:00
|
|
|
|
|
|
|
|
// Configure map
|
2016-06-30 16:59:10 +03:00
|
|
|
_map.setMyLocationEnabled(_showsUserLocation);
|
2016-06-30 20:25:01 +03:00
|
|
|
_map.getTrackingSettings().setMyLocationTrackingMode(_locationTrackingMode);
|
|
|
|
|
_map.getTrackingSettings().setMyBearingTrackingMode(_bearingTrackingMode);
|
2016-06-30 20:48:01 +03:00
|
|
|
_map.setPadding(_paddingLeft, _paddingTop, _paddingRight, _paddingBottom);
|
2016-07-01 12:57:58 +03:00
|
|
|
UiSettings uiSettings = _map.getUiSettings();
|
|
|
|
|
uiSettings.setZoomGesturesEnabled(_zoomEnabled);
|
|
|
|
|
uiSettings.setScrollGesturesEnabled(_scrollEnabled);
|
|
|
|
|
uiSettings.setRotateGesturesEnabled(_rotateEnabled);
|
2016-06-30 20:25:01 +03:00
|
|
|
|
|
|
|
|
// If these settings changed between setupMapView() and onMapReady(), coerce them to their right values
|
2016-07-01 02:57:35 +03:00
|
|
|
// This doesn't happen in the current implementation of MapView, but let's be future proof
|
2016-06-30 20:25:01 +03:00
|
|
|
if (_map.isDebugActive() != _mapOptions.getDebugActive()) {
|
|
|
|
|
_map.setDebugActive(_mapOptions.getDebugActive());
|
|
|
|
|
}
|
|
|
|
|
if (!_map.getStyleUrl().equals(_mapOptions.getStyle())) {
|
|
|
|
|
_map.setStyleUrl(_mapOptions.getStyle());
|
|
|
|
|
}
|
2016-07-01 02:57:35 +03:00
|
|
|
if (uiSettings.isLogoEnabled() != _mapOptions.getLogoEnabled()) {
|
|
|
|
|
uiSettings.setLogoEnabled(_mapOptions.getLogoEnabled());
|
|
|
|
|
}
|
|
|
|
|
if (uiSettings.isAttributionEnabled() != _mapOptions.getAttributionEnabled()) {
|
|
|
|
|
uiSettings.setAttributionEnabled(_mapOptions.getAttributionEnabled());
|
|
|
|
|
}
|
|
|
|
|
if (uiSettings.isCompassEnabled() != _mapOptions.getCompassEnabled()) {
|
|
|
|
|
uiSettings.setCompassEnabled(_mapOptions.getCompassEnabled());
|
|
|
|
|
}
|
2016-07-02 18:34:06 +03:00
|
|
|
|
|
|
|
|
// Attach listeners
|
|
|
|
|
_map.setOnMapClickListener(this);
|
|
|
|
|
_map.setOnMapLongClickListener(this);
|
|
|
|
|
_map.setOnMyLocationTrackingModeChangeListener(this);
|
|
|
|
|
_map.setOnMyBearingTrackingModeChangeListener(this);
|
|
|
|
|
_map.setOnMyLocationChangeListener(this);
|
2016-06-30 20:25:01 +03:00
|
|
|
}
|
|
|
|
|
|
2016-07-02 18:51:09 +03:00
|
|
|
private void destroyMapView() {
|
|
|
|
|
_mapView.removeOnMapChangedListener(this);
|
|
|
|
|
if (_map != null) {
|
|
|
|
|
_map.setOnMapClickListener(null);
|
|
|
|
|
_map.setOnMapLongClickListener(null);
|
|
|
|
|
_map.setOnMyLocationTrackingModeChangeListener(null);
|
|
|
|
|
_map.setOnMyBearingTrackingModeChangeListener(null);
|
|
|
|
|
_map.setOnMyLocationChangeListener(null);
|
|
|
|
|
_map = null;
|
|
|
|
|
}
|
|
|
|
|
_mapView.onDestroy();
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-30 16:59:10 +03:00
|
|
|
// Props
|
|
|
|
|
|
2016-06-30 20:25:01 +03:00
|
|
|
public void setInitialZoomLevel(double value) {
|
|
|
|
|
_initialCamera.zoom(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setInitialDirection(double value) {
|
|
|
|
|
_initialCamera.bearing(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setInitialCenterCoordinate(double lat, double lon) {
|
|
|
|
|
_initialCamera.target(new LatLng(lat, lon));
|
2016-06-30 16:59:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setShowsUserLocation(boolean value) {
|
2016-06-30 20:25:01 +03:00
|
|
|
if (_showsUserLocation == value) { return; }
|
2016-06-30 16:59:10 +03:00
|
|
|
_showsUserLocation = value;
|
|
|
|
|
if (_map != null) { _map.setMyLocationEnabled(value); }
|
|
|
|
|
}
|
2016-06-30 20:25:01 +03:00
|
|
|
|
|
|
|
|
public void setRotateEnabled(boolean value) {
|
2016-07-01 12:57:58 +03:00
|
|
|
if (_rotateEnabled == value) { return; }
|
|
|
|
|
_rotateEnabled = value;
|
2016-07-01 02:46:59 +03:00
|
|
|
if (_map != null) {
|
|
|
|
|
_map.getUiSettings().setRotateGesturesEnabled(value);
|
|
|
|
|
}
|
2016-06-30 20:25:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setScrollEnabled(boolean value) {
|
2016-07-01 12:57:58 +03:00
|
|
|
if (_scrollEnabled == value) { return; }
|
|
|
|
|
_scrollEnabled = value;
|
2016-07-01 02:46:59 +03:00
|
|
|
if (_map != null) {
|
|
|
|
|
_map.getUiSettings().setScrollGesturesEnabled(value);
|
|
|
|
|
}
|
2016-06-30 20:25:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setZoomEnabled(boolean value) {
|
2016-07-01 12:57:58 +03:00
|
|
|
if (_zoomEnabled == value) { return; }
|
|
|
|
|
_zoomEnabled = value;
|
2016-07-01 02:46:59 +03:00
|
|
|
if (_map != null) {
|
|
|
|
|
_map.getUiSettings().setZoomGesturesEnabled(value);
|
|
|
|
|
}
|
2016-06-30 20:25:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setStyleURL(String styleURL) {
|
|
|
|
|
if (styleURL.equals(_mapOptions.getStyle())) { return; }
|
|
|
|
|
_mapOptions.styleUrl(styleURL);
|
|
|
|
|
if (_map != null) { _map.setStyleUrl(styleURL); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setDebugActive(boolean value) {
|
|
|
|
|
if (_mapOptions.getDebugActive() == value) { return; }
|
|
|
|
|
_mapOptions.debugActive(value);
|
|
|
|
|
if (_map != null) { _map.setDebugActive(value); };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setLocationTracking(int value) {
|
|
|
|
|
if (_locationTrackingMode == value) { return; }
|
|
|
|
|
_locationTrackingMode = value;
|
|
|
|
|
if (_map != null) { _map.getTrackingSettings().setMyLocationTrackingMode(value); };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setBearingTracking(int value) {
|
|
|
|
|
if (_bearingTrackingMode == value) { return; }
|
|
|
|
|
_bearingTrackingMode = value;
|
|
|
|
|
if (_map != null) { _map.getTrackingSettings().setMyBearingTrackingMode(value); };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setAttributionButtonIsHidden(boolean value) {
|
|
|
|
|
if (_mapOptions.getAttributionEnabled() == !value) { return; }
|
|
|
|
|
_mapOptions.attributionEnabled(!value);
|
2016-07-01 02:46:59 +03:00
|
|
|
if (_map != null) {
|
|
|
|
|
_map.getUiSettings().setAttributionEnabled(!value);
|
|
|
|
|
}
|
2016-06-30 20:25:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setLogoIsHidden(boolean value) {
|
|
|
|
|
if (_mapOptions.getLogoEnabled() == !value) { return; }
|
|
|
|
|
_mapOptions.logoEnabled(!value);
|
2016-07-01 02:46:59 +03:00
|
|
|
if (_map != null) {
|
|
|
|
|
_map.getUiSettings().setLogoEnabled(!value);
|
|
|
|
|
}
|
2016-06-30 20:25:01 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setCompassIsHidden(boolean value) {
|
|
|
|
|
if (_mapOptions.getCompassEnabled() == !value) { return; }
|
|
|
|
|
_mapOptions.compassEnabled(!value);
|
2016-07-01 02:46:59 +03:00
|
|
|
if (_map != null) {
|
|
|
|
|
_map.getUiSettings().setCompassEnabled(!value);
|
|
|
|
|
}
|
2016-06-30 20:25:01 +03:00
|
|
|
}
|
2016-06-30 20:48:01 +03:00
|
|
|
|
|
|
|
|
public void setContentInset(int top, int right, int bottom, int left) {
|
|
|
|
|
if (top == _paddingTop &&
|
|
|
|
|
bottom == _paddingBottom &&
|
|
|
|
|
left == _paddingLeft &&
|
|
|
|
|
right == _paddingRight) { return; }
|
|
|
|
|
_paddingTop = top;
|
|
|
|
|
_paddingRight = right;
|
|
|
|
|
_paddingBottom = bottom;
|
|
|
|
|
_paddingLeft = left;
|
|
|
|
|
if (_map != null) { _map.setPadding(left, top, right, bottom); }
|
|
|
|
|
}
|
2016-07-01 02:33:30 +03:00
|
|
|
|
2016-07-02 18:34:06 +03:00
|
|
|
// Events
|
|
|
|
|
|
|
|
|
|
void emitEvent(String name, @Nullable WritableMap event) {
|
|
|
|
|
if (event == null) {
|
|
|
|
|
event = Arguments.createMap();
|
|
|
|
|
}
|
|
|
|
|
((ReactContext)getContext())
|
|
|
|
|
.getJSModule(RCTEventEmitter.class)
|
2016-07-02 19:04:23 +03:00
|
|
|
.receiveEvent(getId(), name, event);
|
2016-07-02 18:34:06 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onMapClick(LatLng point) {
|
|
|
|
|
PointF screenCoords = _map.getProjection().toScreenLocation(point);
|
|
|
|
|
|
|
|
|
|
WritableMap event = Arguments.createMap();
|
|
|
|
|
WritableMap src = Arguments.createMap();
|
|
|
|
|
src.putDouble("latitude", point.getLatitude());
|
|
|
|
|
src.putDouble("longitude", point.getLongitude());
|
|
|
|
|
src.putDouble("screenCoordX", screenCoords.x);
|
|
|
|
|
src.putDouble("screenCoordY", screenCoords.y);
|
|
|
|
|
event.putMap("src", src);
|
|
|
|
|
|
|
|
|
|
emitEvent("onTap", event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onMapLongClick(@NonNull LatLng point) {
|
|
|
|
|
PointF screenCoords = _map.getProjection().toScreenLocation(point);
|
|
|
|
|
|
|
|
|
|
WritableMap event = Arguments.createMap();
|
|
|
|
|
WritableMap src = Arguments.createMap();
|
|
|
|
|
src.putDouble("latitude", point.getLatitude());
|
|
|
|
|
src.putDouble("longitude", point.getLongitude());
|
|
|
|
|
src.putDouble("screenCoordX", screenCoords.x);
|
|
|
|
|
src.putDouble("screenCoordY", screenCoords.y);
|
|
|
|
|
event.putMap("src", src);
|
|
|
|
|
|
|
|
|
|
emitEvent("onLongPress", event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onMyLocationChange(@Nullable Location location) {
|
|
|
|
|
WritableMap event = Arguments.createMap();
|
|
|
|
|
WritableMap src = Arguments.createMap();
|
|
|
|
|
|
|
|
|
|
if (location == null) {
|
|
|
|
|
src.putString("message", "Could not get user location");
|
|
|
|
|
event.putMap("src", src);
|
|
|
|
|
emitEvent("onLocateUserFailed", event);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
src.putDouble("latitude", location.getLatitude());
|
|
|
|
|
src.putDouble("longitude", location.getLongitude());
|
|
|
|
|
src.putDouble("magneticHeading", location.getBearing());
|
|
|
|
|
src.putDouble("trueHeading", location.getBearing());
|
|
|
|
|
src.putDouble("headingAccuracy", 10.0);
|
|
|
|
|
src.putBoolean("isUpdating", true);
|
|
|
|
|
event.putMap("src", src);
|
|
|
|
|
emitEvent("onUpdateUserLocation", event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class TrackingModeChangeRunnable implements Runnable {
|
|
|
|
|
ReactNativeMapboxGLView target;
|
|
|
|
|
TrackingModeChangeRunnable(ReactNativeMapboxGLView target) {
|
|
|
|
|
this.target = target;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
target.onTrackingModeChange();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onTrackingModeChange() {
|
|
|
|
|
if (!_trackingModeUpdateScheduled) { return; }
|
|
|
|
|
_trackingModeUpdateScheduled = false;
|
|
|
|
|
|
|
|
|
|
for (int mode = 0; mode < ReactNativeMapboxGLModule.locationTrackingModes.length; mode++) {
|
|
|
|
|
if (_locationTrackingMode == ReactNativeMapboxGLModule.locationTrackingModes[mode] &&
|
|
|
|
|
_bearingTrackingMode == ReactNativeMapboxGLModule.bearingTrackingModes[mode]) {
|
|
|
|
|
WritableMap event = Arguments.createMap();
|
|
|
|
|
event.putInt("src", mode);
|
|
|
|
|
emitEvent("onChangeUserTrackingMode", event);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@UiThread
|
|
|
|
|
public void onMyBearingTrackingModeChange(int myBearingTrackingMode) {
|
|
|
|
|
if (_bearingTrackingMode == myBearingTrackingMode) { return; }
|
|
|
|
|
_bearingTrackingMode = myBearingTrackingMode;
|
|
|
|
|
_trackingModeUpdateScheduled = true;
|
|
|
|
|
_trackingModeHandler.post(new TrackingModeChangeRunnable(this));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@UiThread
|
|
|
|
|
public void onMyLocationTrackingModeChange(int myLocationTrackingMode) {
|
|
|
|
|
if (_locationTrackingMode == myLocationTrackingMode) { return; }
|
|
|
|
|
_locationTrackingMode = myLocationTrackingMode;
|
|
|
|
|
_trackingModeUpdateScheduled = true;
|
|
|
|
|
_trackingModeHandler.post(new TrackingModeChangeRunnable(this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WritableMap serializeCurrentRegion() {
|
|
|
|
|
CameraPosition camera = _map == null
|
|
|
|
|
? _initialCamera.build()
|
|
|
|
|
: _map.getCameraPosition();
|
|
|
|
|
|
|
|
|
|
WritableMap event = Arguments.createMap();
|
|
|
|
|
WritableMap src = Arguments.createMap();
|
|
|
|
|
src.putDouble("longitude", camera.target.getLongitude());
|
|
|
|
|
src.putDouble("latitude", camera.target.getLatitude());
|
|
|
|
|
src.putDouble("zoomLevel", camera.zoom);
|
|
|
|
|
src.putDouble("direction", camera.bearing);
|
|
|
|
|
src.putDouble("pitch", camera.tilt);
|
|
|
|
|
event.putMap("src", src);
|
|
|
|
|
return event;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onMapChanged(int change) {
|
|
|
|
|
switch (change) {
|
|
|
|
|
case MapView.REGION_WILL_CHANGE:
|
|
|
|
|
case MapView.REGION_WILL_CHANGE_ANIMATED:
|
|
|
|
|
emitEvent("onRegionWillChange", serializeCurrentRegion()); // TODO: These should be throttled
|
|
|
|
|
break;
|
|
|
|
|
case MapView.REGION_DID_CHANGE:
|
|
|
|
|
case MapView.REGION_DID_CHANGE_ANIMATED:
|
2016-07-02 19:13:01 +03:00
|
|
|
emitEvent("onRegionDidChange", serializeCurrentRegion());
|
2016-07-02 18:34:06 +03:00
|
|
|
break;
|
|
|
|
|
case MapView.WILL_START_LOADING_MAP:
|
|
|
|
|
emitEvent("onStartLoadingMap", null);
|
|
|
|
|
break;
|
|
|
|
|
case MapView.DID_FINISH_LOADING_MAP:
|
|
|
|
|
emitEvent("onFinishLoadingMap", null);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-01 02:57:35 +03:00
|
|
|
// Getters
|
|
|
|
|
|
2016-07-01 02:33:30 +03:00
|
|
|
public CameraPosition getCameraPosition() {
|
|
|
|
|
if (_map == null) { return _initialCamera.build(); }
|
|
|
|
|
return _map.getCameraPosition();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public LatLngBounds getBounds() {
|
|
|
|
|
if (_map == null) { return new LatLngBounds.Builder().build(); };
|
|
|
|
|
return _map.getProjection().getVisibleRegion().latLngBounds;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-01 02:57:35 +03:00
|
|
|
// Camera setters
|
|
|
|
|
|
2016-07-01 02:33:30 +03:00
|
|
|
public void setCameraPosition(CameraPosition position, int duration, @Nullable Runnable callback) {
|
|
|
|
|
if (_map == null) {
|
|
|
|
|
_initialCamera = new CameraPosition.Builder(position);
|
|
|
|
|
if (callback != null) { callback.run(); }
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
|
|
|
|
|
setCameraUpdate(update, duration, callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setCameraUpdate(CameraUpdate update, int duration, @Nullable Runnable callback) {
|
|
|
|
|
if (_map == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (duration == 0) {
|
|
|
|
|
_map.moveCamera(update);
|
|
|
|
|
if (callback != null) { callback.run(); }
|
|
|
|
|
} else {
|
|
|
|
|
// Ugh... Java callbacks suck
|
|
|
|
|
class CameraCallback implements MapboxMap.CancelableCallback {
|
|
|
|
|
Runnable callback;
|
|
|
|
|
CameraCallback(Runnable callback) {
|
|
|
|
|
this.callback = callback;
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public void onCancel() {
|
|
|
|
|
if (callback != null) { callback.run(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onFinish() {
|
|
|
|
|
if (callback != null) { callback.run(); }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_map.animateCamera(update, duration, new CameraCallback(callback));
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-06-30 16:59:10 +03:00
|
|
|
}
|