11package com .mapbox .mapboxandroiddemo .examples .labs ;
22
3+ import android .graphics .Color ;
34import android .os .Bundle ;
5+ import android .view .View ;
46
7+ import com .mapbox .geojson .Feature ;
8+ import com .mapbox .geojson .LineString ;
9+ import com .mapbox .geojson .Point ;
510import com .mapbox .mapboxandroiddemo .R ;
611import com .mapbox .mapboxsdk .Mapbox ;
712import com .mapbox .mapboxsdk .camera .CameraPosition ;
813import com .mapbox .mapboxsdk .camera .CameraUpdateFactory ;
914import com .mapbox .mapboxsdk .geometry .LatLng ;
15+ import com .mapbox .mapboxsdk .geometry .LatLngBounds ;
1016import com .mapbox .mapboxsdk .maps .MapView ;
1117import com .mapbox .mapboxsdk .maps .MapboxMap ;
1218import com .mapbox .mapboxsdk .maps .MapboxMapOptions ;
1319import com .mapbox .mapboxsdk .maps .OnMapReadyCallback ;
1420import com .mapbox .mapboxsdk .maps .Style ;
1521import com .mapbox .mapboxsdk .maps .SupportMapFragment ;
22+ import com .mapbox .mapboxsdk .style .layers .Layer ;
23+ import com .mapbox .mapboxsdk .style .layers .LineLayer ;
24+ import com .mapbox .mapboxsdk .style .layers .Property ;
25+ import com .mapbox .mapboxsdk .style .sources .GeoJsonSource ;
26+
27+ import java .util .ArrayList ;
28+ import java .util .List ;
1629
1730import androidx .annotation .NonNull ;
1831import androidx .appcompat .app .AppCompatActivity ;
1932import androidx .fragment .app .FragmentTransaction ;
2033
21- public class InsetMapActivity extends AppCompatActivity {
34+ import static com .mapbox .mapboxsdk .style .layers .Property .NONE ;
35+ import static com .mapbox .mapboxsdk .style .layers .Property .VISIBLE ;
36+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineCap ;
37+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineColor ;
38+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineJoin ;
39+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .lineWidth ;
40+ import static com .mapbox .mapboxsdk .style .layers .PropertyFactory .visibility ;
41+
42+ public class InsetMapActivity extends AppCompatActivity implements MapboxMap .OnCameraMoveListener {
2243
2344 private static final String STYLE_URL = "mapbox://styles/mapbox/cj5l80zrp29942rmtg0zctjto" ;
2445 private static final String INSET_FRAGMENT_TAG = "com.mapbox.insetMapFragment" ;
46+ private static final String BOUNDS_LINE_LAYER_SOURCE_ID = "BOUNDS_LINE_LAYER_SOURCE_ID" ;
47+ private static final String BOUNDS_LINE_LAYER_LAYER_ID = "BOUNDS_LINE_LAYER_LAYER_ID" ;
2548 private static final int ZOOM_DISTANCE_BETWEEN_MAIN_AND_INSET_MAPS = 3 ;
2649
2750 private MapView mainMapView ;
@@ -41,7 +64,18 @@ protected void onCreate(Bundle savedInstanceState) {
4164
4265 mainMapView = findViewById (R .id .mapView );
4366 mainMapView .onCreate (savedInstanceState );
44- mainMapView .getMapAsync (mainLargeMapReadyCallback );
67+ mainMapView .getMapAsync (new OnMapReadyCallback () {
68+ @ Override
69+ public void onMapReady (@ NonNull MapboxMap mapboxMap ) {
70+ InsetMapActivity .this .mainMapboxMap = mapboxMap ;
71+ mapboxMap .setStyle (new Style .Builder ().fromUri (STYLE_URL ), new Style .OnStyleLoaded () {
72+ @ Override
73+ public void onStyleLoaded (@ NonNull Style style ) {
74+ mainMapboxMap .addOnCameraMoveListener (InsetMapActivity .this );
75+ }
76+ });
77+ }
78+ });
4579
4680 SupportMapFragment insetMapFragment =
4781 (SupportMapFragment ) getSupportFragmentManager ().findFragmentByTag (INSET_FRAGMENT_TAG );
@@ -71,42 +105,93 @@ protected void onCreate(Bundle savedInstanceState) {
71105 transaction .commit ();
72106 }
73107
74- insetMapFragment .getMapAsync (insetMapReadyCallback );
108+ insetMapFragment .getMapAsync (new OnMapReadyCallback () {
109+ @ Override
110+ public void onMapReady (@ NonNull MapboxMap mapboxMap ) {
111+ insetMapboxMap = mapboxMap ;
112+ mapboxMap .setStyle (new Style .Builder ().fromUri (STYLE_URL ), new Style .OnStyleLoaded () {
113+ @ Override
114+ public void onStyleLoaded (@ NonNull Style style ) {
115+
116+ // Create the LineString from the list of coordinates and then make a GeoJSON
117+ // FeatureCollection so we can add the line to our map as a layer.
118+ style .addSource (new GeoJsonSource (BOUNDS_LINE_LAYER_SOURCE_ID ));
119+
120+ // The layer properties for our line. This is where we make the line dotted, set the
121+ // color, etc.
122+ style .addLayer (new LineLayer (BOUNDS_LINE_LAYER_LAYER_ID , BOUNDS_LINE_LAYER_SOURCE_ID )
123+ .withProperties (
124+ lineCap (Property .LINE_CAP_ROUND ),
125+ lineJoin (Property .LINE_JOIN_ROUND ),
126+ lineWidth (3f ),
127+ lineColor (Color .YELLOW ),
128+ visibility (VISIBLE )
129+ ));
130+
131+ updateInsetMapLineLayerBounds (style );
132+ }
133+ });
134+ }
135+ });
136+
137+ findViewById (R .id .show_bounds_toggle_fab ).setOnClickListener (new View .OnClickListener () {
138+ @ Override
139+ public void onClick (View view ) {
140+ // Toggle the visibility of the camera bounds LineLayer
141+ insetMapboxMap .getStyle (new Style .OnStyleLoaded () {
142+ @ Override
143+ public void onStyleLoaded (@ NonNull Style style ) {
144+ Layer lineLayer = style .getLayer (BOUNDS_LINE_LAYER_LAYER_ID );
145+ if (lineLayer != null ) {
146+ lineLayer .setProperties (
147+ VISIBLE .equals (lineLayer .getVisibility ().getValue ()) ? visibility (NONE ) : visibility (VISIBLE ));
148+ }
149+ }
150+ });
151+ }
152+ });
75153 }
76154
77- private OnMapReadyCallback mainLargeMapReadyCallback = new OnMapReadyCallback () {
78- @ Override
79- public void onMapReady (@ NonNull MapboxMap mapboxMap ) {
80- InsetMapActivity .this .mainMapboxMap = mapboxMap ;
81- mapboxMap .setStyle (new Style .Builder ().fromUri (STYLE_URL ), new Style .OnStyleLoaded () {
155+ @ Override
156+ public void onCameraMove () {
157+ CameraPosition mainCameraPosition = mainMapboxMap .getCameraPosition ();
158+ CameraPosition insetCameraPosition = new CameraPosition .Builder (mainCameraPosition )
159+ .zoom (mainCameraPosition .zoom - ZOOM_DISTANCE_BETWEEN_MAIN_AND_INSET_MAPS ).build ();
160+ insetMapboxMap .moveCamera (CameraUpdateFactory .newCameraPosition (insetCameraPosition ));
161+ if (insetMapboxMap != null ) {
162+ insetMapboxMap .getStyle (new Style .OnStyleLoaded () {
82163 @ Override
83164 public void onStyleLoaded (@ NonNull Style style ) {
84- mainMapboxMap . addOnCameraMoveListener ( mainCameraMoveListener );
165+ updateInsetMapLineLayerBounds ( style );
85166 }
86167 });
87168 }
88- };
89-
90- private OnMapReadyCallback insetMapReadyCallback = new OnMapReadyCallback () {
91- @ Override
92- public void onMapReady (@ NonNull MapboxMap mapboxMap ) {
93- insetMapboxMap = mapboxMap ;
94- mapboxMap .setStyle (new Style .Builder ().fromUri (STYLE_URL ));
95- }
96- };
97-
98- private MapboxMap .OnCameraMoveListener mainCameraMoveListener = new MapboxMap .OnCameraMoveListener () {
99- @ Override
100- public void onCameraMove () {
101- CameraPosition mainCameraPosition = mainMapboxMap .getCameraPosition ();
102- CameraPosition insetCameraPosition = new CameraPosition .Builder (mainCameraPosition )
103- .zoom (mainCameraPosition .zoom - ZOOM_DISTANCE_BETWEEN_MAIN_AND_INSET_MAPS ).build ();
169+ }
104170
105- if (insetMapboxMap != null ) {
106- insetMapboxMap .moveCamera (CameraUpdateFactory .newCameraPosition (insetCameraPosition ));
107- }
171+ /**
172+ * Update the LineLayer with the latest coordinates of the main map's viewport bounds.
173+ *
174+ * @param fullyLoadedStyle the inset map's fully loaded style
175+ */
176+ private void updateInsetMapLineLayerBounds (@ NonNull Style fullyLoadedStyle ) {
177+ GeoJsonSource lineLayerSource = fullyLoadedStyle .getSourceAs (BOUNDS_LINE_LAYER_SOURCE_ID );
178+ if (lineLayerSource != null ) {
179+ LatLngBounds bounds = mainMapboxMap .getProjection ().getVisibleRegion ().latLngBounds ;
180+ List <Point > pointList = new ArrayList <>();
181+ pointList .add (Point .fromLngLat (bounds .getNorthWest ().getLongitude (),
182+ bounds .getNorthWest ().getLatitude ()));
183+ pointList .add (Point .fromLngLat (bounds .getNorthEast ().getLongitude (),
184+ bounds .getNorthEast ().getLatitude ()));
185+ pointList .add (Point .fromLngLat (bounds .getSouthEast ().getLongitude (),
186+ bounds .getSouthEast ().getLatitude ()));
187+ pointList .add (Point .fromLngLat (bounds .getSouthWest ().getLongitude (),
188+ bounds .getSouthWest ().getLatitude ()));
189+ pointList .add (Point .fromLngLat (bounds .getNorthWest ().getLongitude (),
190+ bounds .getNorthWest ().getLatitude ()));
191+
192+ lineLayerSource .setGeoJson (Feature .fromGeometry (LineString .fromLngLats (pointList )));
108193 }
109- };
194+ }
110195
111196 // Add the mapView lifecycle to the activity's lifecycle methods
112197 @ Override
@@ -143,7 +228,7 @@ public void onLowMemory() {
143228 protected void onDestroy () {
144229 super .onDestroy ();
145230 if (mainMapboxMap != null ) {
146- mainMapboxMap .removeOnCameraMoveListener (mainCameraMoveListener );
231+ mainMapboxMap .removeOnCameraMoveListener (this );
147232 }
148233 mainMapView .onDestroy ();
149234 }
0 commit comments