2015-12-12 12:40:14 -08:00
2015-10-11 11:53:56 -07:00
package com.mapbox.reactnativemapboxgl ;
2016-07-01 02:33:30 +03:00
import com.facebook.infer.annotation.Assertions ;
import com.facebook.react.bridge.Arguments ;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException ;
2016-06-30 16:59:10 +03:00
import com.facebook.react.bridge.ReactApplicationContext ;
2016-06-30 20:48:01 +03:00
import com.facebook.react.bridge.ReadableArray ;
2015-10-11 20:47:58 -07:00
import com.facebook.react.bridge.ReadableMap ;
2016-07-01 02:33:30 +03:00
import com.facebook.react.bridge.WritableArray ;
import com.facebook.react.bridge.WritableMap ;
import com.facebook.react.common.MapBuilder ;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter ;
2016-02-08 21:05:53 -08:00
import com.facebook.react.uimanager.annotations.ReactProp ;
2015-10-11 11:53:56 -07:00
import com.facebook.react.uimanager.ThemedReactContext ;
2016-06-30 16:59:10 +03:00
import com.facebook.react.uimanager.SimpleViewManager ;
2016-07-01 02:33:30 +03:00
import com.mapbox.mapboxsdk.camera.CameraPosition ;
import com.mapbox.mapboxsdk.camera.CameraUpdate ;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory ;
import com.mapbox.mapboxsdk.constants.MapboxConstants ;
import com.mapbox.mapboxsdk.geometry.LatLng ;
import com.mapbox.mapboxsdk.geometry.LatLngBounds ;
import java.util.Map ;
2015-10-31 10:19:55 -07:00
2016-06-30 16:59:10 +03:00
import javax.annotation.Nonnull ;
2016-07-01 02:33:30 +03:00
import javax.annotation.Nullable ;
2015-12-17 11:47:22 -08:00
2016-06-30 16:59:10 +03:00
public class ReactNativeMapboxGLManager extends SimpleViewManager < ReactNativeMapboxGLView > {
2015-10-11 11:53:56 -07:00
2016-06-30 16:59:10 +03:00
private static final String REACT_CLASS = "RCTMapboxGL" ;
2015-12-12 12:40:14 -08:00
2016-06-30 16:59:10 +03:00
private ReactApplicationContext _context ;
2015-10-11 11:53:56 -07:00
2016-06-30 16:59:10 +03:00
public ReactNativeMapboxGLManager ( ReactApplicationContext context ) {
super ();
_context = context ;
2015-10-11 11:53:56 -07:00
}
2016-06-30 16:59:10 +03:00
@Override
2016-07-01 02:33:30 +03:00
public String getName () {
return REACT_CLASS ;
}
2016-06-30 16:59:10 +03:00
2016-07-01 02:33:30 +03:00
public ReactApplicationContext getContext () {
return _context ;
}
2016-06-30 16:59:10 +03:00
@Override
public ReactNativeMapboxGLView createViewInstance ( ThemedReactContext context ) {
return new ReactNativeMapboxGLView ( context , this );
}
2016-07-02 18:51:09 +03:00
@Override
protected void onAfterUpdateTransaction ( ReactNativeMapboxGLView view ) {
super . onAfterUpdateTransaction ( view );
view . onAfterUpdateTransaction ();
}
@Override
public void onDropViewInstance ( ReactNativeMapboxGLView view ) {
view . onDrop ();
}
2016-06-30 20:25:01 +03:00
// Props
@ReactProp ( name = "initialZoomLevel" )
public void setInitialZoomLevel ( ReactNativeMapboxGLView view , double value ) {
view . setInitialZoomLevel ( value );
}
@ReactProp ( name = "initialDirection" )
public void setInitialDirection ( ReactNativeMapboxGLView view , double value ) {
view . setInitialDirection ( value );
}
@ReactProp ( name = "initialCenterCoordinate" )
public void setInitialCenterCoordinate ( ReactNativeMapboxGLView view , ReadableMap coord ) {
double lat = coord . getDouble ( "latitude" );
double lon = coord . getDouble ( "longitude" );
view . setInitialCenterCoordinate ( lat , lon );
}
@ReactProp ( name = "debugActive" )
public void setDebugActive ( ReactNativeMapboxGLView view , boolean value ) {
view . setDebugActive ( value );
}
@ReactProp ( name = "rotateEnabled" )
public void setRotateEnabled ( ReactNativeMapboxGLView view , boolean value ) {
view . setRotateEnabled ( value );
}
@ReactProp ( name = "scrollEnabled" )
public void setScrollEnabled ( ReactNativeMapboxGLView view , boolean value ) {
view . setScrollEnabled ( value );
}
@ReactProp ( name = "zoomEnabled" )
public void setZoomEnabled ( ReactNativeMapboxGLView view , boolean value ) {
view . setZoomEnabled ( value );
2016-06-30 16:59:10 +03:00
}
@ReactProp ( name = "showsUserLocation" )
public void setShowsUserLocation ( ReactNativeMapboxGLView view , boolean value ) {
view . setShowsUserLocation ( value );
}
2016-06-30 20:25:01 +03:00
@ReactProp ( name = "styleURL" )
public void setStyleUrl ( ReactNativeMapboxGLView view , @Nonnull String styleURL ) {
view . setStyleURL ( styleURL );
}
@ReactProp ( name = "userTrackingMode" )
public void setUserTrackingMode ( ReactNativeMapboxGLView view , int mode ) {
view . setLocationTracking ( ReactNativeMapboxGLModule . locationTrackingModes [ mode ] );
view . setBearingTracking ( ReactNativeMapboxGLModule . bearingTrackingModes [ mode ] );
}
@ReactProp ( name = "attributionButtonIsHidden" )
public void setAttributionButtonIsHidden ( ReactNativeMapboxGLView view , boolean value ) {
view . setAttributionButtonIsHidden ( value );
}
@ReactProp ( name = "logoIsHidden" )
public void setLogoIsHidden ( ReactNativeMapboxGLView view , boolean value ) {
view . setLogoIsHidden ( value );
}
@ReactProp ( name = "compassIsHidden" )
public void setCompassIsHidden ( ReactNativeMapboxGLView view , boolean value ) {
view . setCompassIsHidden ( value );
}
2016-06-30 20:48:01 +03:00
@ReactProp ( name = "contentInset" )
public void setContentInset ( ReactNativeMapboxGLView view , ReadableArray inset ) {
view . setContentInset ( inset . getInt ( 0 ), inset . getInt ( 1 ), inset . getInt ( 2 ), inset . getInt ( 3 ));
}
2016-07-01 02:33:30 +03:00
// Commands
2016-06-30 16:59:10 +03:00
2016-07-01 02:33:30 +03:00
public static final int COMMAND_GET_DIRECTION = 0 ;
2016-07-01 12:57:58 +03:00
public static final int COMMAND_GET_PITCH = 1 ;
public static final int COMMAND_GET_CENTER_COORDINATE_ZOOM_LEVEL = 2 ;
public static final int COMMAND_GET_BOUNDS = 3 ;
public static final int COMMAND_EASE_TO = 4 ;
public static final int COMMAND_SET_CAMERA = 5 ;
public static final int COMMAND_SET_VISIBLE_COORDINATE_BOUNDS = 6 ;
public static final int COMMAND_SELECT_ANNOTATION = 7 ;
public static final int COMMAND_SPLICE_ANNOTATIONS = 8 ;
2016-07-01 02:33:30 +03:00
@Override
public
@Nullable
Map < String , Integer > getCommandsMap () {
return MapBuilder . < String , Integer > builder ()
. put ( "getDirection" , COMMAND_GET_DIRECTION )
2016-07-01 12:57:58 +03:00
. put ( "getPitch" , COMMAND_GET_PITCH )
2016-07-01 02:33:30 +03:00
. put ( "getCenterCoordinateZoomLevel" , COMMAND_GET_CENTER_COORDINATE_ZOOM_LEVEL )
. put ( "getBounds" , COMMAND_GET_BOUNDS )
2016-07-01 12:57:58 +03:00
. put ( "easeTo" , COMMAND_EASE_TO )
2016-07-01 02:33:30 +03:00
. put ( "setCamera" , COMMAND_SET_CAMERA )
. put ( "setVisibleCoordinateBounds" , COMMAND_SET_VISIBLE_COORDINATE_BOUNDS )
. put ( "selectAnnotation" , COMMAND_SELECT_ANNOTATION )
. put ( "spliceAnnotations" , COMMAND_SPLICE_ANNOTATIONS )
. build ();
}
private void fireCallback ( int callbackId , WritableArray args ) {
WritableArray event = Arguments . createArray ();
event . pushInt ( callbackId );
event . pushArray ( args );
_context . getJSModule ( RCTNativeAppEventEmitter . class )
. emit ( "MapboxAndroidCallback" , event );
}
@Override
public void receiveCommand ( ReactNativeMapboxGLView view , int commandId , @Nullable ReadableArray args ) {
Assertions . assertNotNull ( args );
switch ( commandId ) {
case COMMAND_GET_DIRECTION :
getDirection ( view , args . getInt ( 0 ));
break ;
2016-07-01 12:57:58 +03:00
case COMMAND_GET_PITCH :
getPitch ( view , args . getInt ( 0 ));
break ;
2016-07-01 02:33:30 +03:00
case COMMAND_GET_CENTER_COORDINATE_ZOOM_LEVEL :
getCenterCoordinateZoomLevel ( view , args . getInt ( 0 ));
break ;
case COMMAND_GET_BOUNDS :
getBounds ( view , args . getInt ( 0 ));
break ;
2016-07-01 12:57:58 +03:00
case COMMAND_EASE_TO :
easeTo ( view , args . getMap ( 0 ), args . getBoolean ( 1 ), args . getInt ( 2 ));
2016-07-01 02:33:30 +03:00
break ;
case COMMAND_SET_CAMERA :
setCamera ( view , args . getDouble ( 0 ),
args . getDouble ( 1 ), args . getDouble ( 2 ), args . getDouble ( 3 ), args . getDouble ( 4 ),
args . getDouble ( 5 )
);
break ;
case COMMAND_SET_VISIBLE_COORDINATE_BOUNDS :
setVisibleCoordinateBounds ( view ,
args . getDouble ( 0 ), args . getDouble ( 1 ), args . getDouble ( 2 ), args . getDouble ( 3 ),
args . getDouble ( 4 ), args . getDouble ( 5 ), args . getDouble ( 6 ), args . getDouble ( 7 ),
args . getBoolean ( 8 )
);
break ;
case COMMAND_SELECT_ANNOTATION :
selectAnnotation ( view , args . getString ( 0 ), args . getBoolean ( 1 ));
break ;
case COMMAND_SPLICE_ANNOTATIONS :
spliceAnnotations ( view , args . getBoolean ( 0 ), args . getArray ( 1 ), args . getArray ( 2 ));
break ;
default :
throw new JSApplicationIllegalArgumentException ( "Invalid commandId " + commandId + " sent to " + getClass (). getSimpleName ());
2015-10-11 11:53:56 -07:00
}
2015-11-15 14:12:26 -04:00
}
2016-07-01 02:33:30 +03:00
// Getters
private void getDirection ( ReactNativeMapboxGLView view , int callbackId ) {
WritableArray result = Arguments . createArray ();
result . pushDouble ( view . getCameraPosition (). bearing );
fireCallback ( callbackId , result );
2015-12-12 12:40:14 -08:00
}
2016-07-01 12:57:58 +03:00
private void getPitch ( ReactNativeMapboxGLView view , int callbackId ) {
WritableArray result = Arguments . createArray ();
result . pushDouble ( view . getCameraPosition (). tilt );
fireCallback ( callbackId , result );
}
2016-07-01 02:33:30 +03:00
private void getCenterCoordinateZoomLevel ( ReactNativeMapboxGLView view , int callbackId ) {
CameraPosition camera = view . getCameraPosition ();
2015-12-17 11:47:22 -08:00
2016-07-01 02:33:30 +03:00
WritableArray args = Arguments . createArray ();
WritableMap result = Arguments . createMap ();
result . putDouble ( "latitude" , camera . target . getLatitude ());
result . putDouble ( "longitude" , camera . target . getLongitude ());
result . putDouble ( "zoomLevel" , camera . zoom );
args . pushMap ( result );
2015-12-17 11:47:22 -08:00
2016-07-01 02:33:30 +03:00
fireCallback ( callbackId , args );
2015-12-17 11:47:22 -08:00
}
2016-07-01 02:33:30 +03:00
private void getBounds ( ReactNativeMapboxGLView view , int callbackId ) {
LatLngBounds bounds = view . getBounds ();
WritableArray args = Arguments . createArray ();
WritableArray result = Arguments . createArray ();
result . pushDouble ( bounds . getLatSouth ());
result . pushDouble ( bounds . getLonWest ());
result . pushDouble ( bounds . getLatNorth ());
result . pushDouble ( bounds . getLonEast ());
args . pushArray ( result );
fireCallback ( callbackId , args );
2016-04-11 23:13:02 +02:00
}
2016-07-01 02:33:30 +03:00
// Setters
2016-01-11 15:51:12 -08:00
2016-07-01 12:57:58 +03:00
private void easeTo ( ReactNativeMapboxGLView view , ReadableMap updates , boolean animated , int callbackId ) {
2016-07-01 02:33:30 +03:00
CameraPosition . Builder cameraBuilder = new CameraPosition . Builder ( view . getCameraPosition ());
if ( updates . hasKey ( "latitude" ) && updates . hasKey ( "longitude" )) {
cameraBuilder . target ( new LatLng ( updates . getDouble ( "latitude" ), updates . getDouble ( "longitude" )));
}
if ( updates . hasKey ( "zoomLevel" )) {
cameraBuilder . zoom ( updates . getDouble ( "zoomLevel" ));
}
if ( updates . hasKey ( "direction" )) {
cameraBuilder . bearing ( updates . getDouble ( "direction" ));
2015-10-11 11:53:56 -07:00
}
2016-07-01 12:57:58 +03:00
if ( updates . hasKey ( "pitch" )) {
cameraBuilder . tilt ( updates . getDouble ( "pitch" ));
}
2015-11-15 14:12:26 -04:00
2016-07-01 02:33:30 +03:00
// I want lambdas :(
class CallbackRunnable implements Runnable {
int callbackId ;
ReactNativeMapboxGLManager manager ;
2015-11-15 14:12:26 -04:00
2016-07-01 02:33:30 +03:00
CallbackRunnable ( ReactNativeMapboxGLManager manager , int callbackId ) {
this . callbackId = callbackId ;
this . manager = manager ;
}
2015-11-15 14:12:26 -04:00
@Override
2016-07-01 02:33:30 +03:00
public void run () {
manager . fireCallback ( callbackId , Arguments . createArray ());
2015-11-15 14:12:26 -04:00
}
2015-10-11 11:53:56 -07:00
}
2016-07-01 02:33:30 +03:00
int duration = animated ? MapboxConstants . ANIMATION_DURATION : 0 ;
view . setCameraPosition ( cameraBuilder . build (), duration , new CallbackRunnable ( this , callbackId ));
2015-11-15 14:12:26 -04:00
}
2016-07-01 02:33:30 +03:00
public void setCamera (
ReactNativeMapboxGLView view ,
double latitude , double longitude ,
2016-07-01 12:57:58 +03:00
double altitude , double pitch , double direction ,
2016-07-01 02:33:30 +03:00
double duration ) {
2016-07-01 12:57:58 +03:00
throw new JSApplicationIllegalArgumentException ( "MapView.setCamera() is not supported on Android. If you're trying to change pitch, use MapView.easeTo()" );
2015-11-15 14:12:26 -04:00
}
2016-07-01 02:33:30 +03:00
public void setVisibleCoordinateBounds (
ReactNativeMapboxGLView view ,
double latS , double lonW , double latN , double lonE ,
double paddingTop , double paddingRight , double paddingBottom , double paddingLeft ,
boolean animated ) {
CameraUpdate update = CameraUpdateFactory . newLatLngBounds (
new LatLngBounds . Builder ()
. include ( new LatLng ( latS , lonW ))
. include ( new LatLng ( latN , lonE ))
. build (),
2016-07-01 12:57:58 +03:00
( int ) paddingLeft ,
( int ) paddingTop ,
( int ) paddingRight ,
( int ) paddingBottom
2016-07-01 02:33:30 +03:00
);
view . setCameraUpdate ( update , animated ? MapboxConstants . ANIMATION_DURATION : 0 , null );
2015-11-15 14:12:26 -04:00
}
2016-07-01 02:33:30 +03:00
// Annotations
public void spliceAnnotations ( ReactNativeMapboxGLView view , boolean removeAll , ReadableArray itemsToRemove , ReadableArray itemsToAdd ) {
// TODO
2015-11-15 14:12:26 -04:00
}
2016-07-01 02:33:30 +03:00
public void selectAnnotation ( ReactNativeMapboxGLView view , String annotationId , boolean animated ) {
// TODO
2015-11-15 14:12:26 -04:00
}
2016-01-09 13:37:14 +00:00
}