diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md index 98ee22a1a9f..c420643fb3c 100644 --- a/platform/android/CHANGELOG.md +++ b/platform/android/CHANGELOG.md @@ -6,6 +6,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to 5.1.0 builds further on 5.0.1 and adds: +* Limit Viewport [#8622](https://github.com/mapbox/mapbox-gl-native/pull/8622) * Transition Properties for Layer attributes [#8509](https://github.com/mapbox/mapbox-gl-native/pull/8509) * Style wide transition duration and transition offset in milliseconds [#8576](https://github.com/mapbox/mapbox-gl-native/pull/8576) * Transifex integration, Catalan & Dutch translations [#8556](https://github.com/mapbox/mapbox-gl-native/pull/8556) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 40585700d1a..779f482693c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -36,6 +36,7 @@ import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.layers.Layer; @@ -1504,6 +1505,22 @@ public boolean isAllowConcurrentMultipleOpenInfoWindows() { return annotationManager.getInfoWindowManager().isAllowConcurrentMultipleOpenInfoWindows(); } + // + // LatLngBounds + // + + /** + * Sets a LatLngBounds that constraints map transformations to this bounds. + *

+ * Set to null to clear current bounds, newly set bounds will override previously set bounds. + *

+ * + * @param latLngBounds the bounds to constrain the map with + */ + public void setLatLngBoundsForCameraTarget(@Nullable LatLngBounds latLngBounds) { + nativeMapView.setLatLngBounds(latLngBounds); + } + // // Padding // diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index f2905cd6c35..a9dedcf7dce 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -19,6 +19,7 @@ import com.mapbox.mapboxsdk.annotations.Polyline; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.geometry.ProjectedMeters; import com.mapbox.mapboxsdk.storage.FileSource; import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException; @@ -259,6 +260,13 @@ public String getStyleJson() { return nativeGetStyleJson(); } + public void setLatLngBounds(LatLngBounds latLngBounds) { + if (isDestroyedOn("setLatLngBounds")) { + return; + } + nativeSetLatLngBounds(latLngBounds); + } + public void cancelTransitions() { if (isDestroyedOn("cancelTransitions")) { return; @@ -999,6 +1007,8 @@ private native void nativeInitialize(NativeMapView nativeMapView, private native String nativeGetStyleJson(); + private native void nativeSetLatLngBounds(LatLngBounds latLngBounds); + private native void nativeCancelTransitions(); private native void nativeSetGestureInProgress(boolean inProgress); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java index c110935133f..8480028a2f9 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java @@ -19,6 +19,7 @@ import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.exceptions.InvalidMarkerPositionException; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; @@ -107,6 +108,25 @@ public void onViewAction(UiController uiController, View view) { })); } + // + // CameraForLatLngBounds + // + @Test + public void testCameraForLatLngBounds() { + ViewUtils.checkViewIsDisplayed(R.id.mapView); + final MapboxMap mapboxMap = activity.getMapboxMap(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() { + @Override + public void onViewAction(UiController uiController, View view) { + // set + mapboxMap.setLatLngBoundsForCameraTarget( + new LatLngBounds.Builder().include(new LatLng()).include(new LatLng(1, 1)).build()); + // reset + mapboxMap.setLatLngBoundsForCameraTarget(null); + } + })); + } + // // MinZoomLevel // diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml index 13160878f6e..eee7c86403d 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml @@ -592,6 +592,17 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activity.FeatureOverviewActivity"/> + + + + - - diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/LatLngBoundsForCameraActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/LatLngBoundsForCameraActivity.java new file mode 100644 index 00000000000..9ac87deb0d9 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/LatLngBoundsForCameraActivity.java @@ -0,0 +1,109 @@ +package com.mapbox.mapboxsdk.testapp.activity.maplayout; + +import android.graphics.Color; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.Gravity; +import android.view.View; +import android.widget.FrameLayout; + +import com.mapbox.mapboxsdk.annotations.PolygonOptions; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.maps.MapView; +import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.testapp.R; + +/** + * Test Activity showcasing restricting user gestures to a bounds around Iceland. + */ +public class LatLngBoundsForCameraActivity extends AppCompatActivity implements OnMapReadyCallback { + + private static final LatLngBounds ICELAND_BOUNDS = new LatLngBounds.Builder() + .include(new LatLng(66.852863, -25.985652)) + .include(new LatLng(62.985661, -12.626277)) + .build(); + + private MapView mapView; + private MapboxMap mapboxMap; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_restricted_bounds); + + mapView = (MapView) findViewById(R.id.mapView); + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(this); + } + + @Override + public void onMapReady(MapboxMap mapboxMap) { + this.mapboxMap = mapboxMap; + mapboxMap.setLatLngBoundsForCameraTarget(ICELAND_BOUNDS); + mapboxMap.setMinZoomPreference(2); + showBoundsArea(); + showCrosshair(); + } + + private void showBoundsArea() { + PolygonOptions boundsArea = new PolygonOptions() + .add(ICELAND_BOUNDS.getNorthWest()) + .add(ICELAND_BOUNDS.getNorthEast()) + .add(ICELAND_BOUNDS.getSouthEast()) + .add(ICELAND_BOUNDS.getSouthWest()); + boundsArea.alpha(0.25f); + boundsArea.fillColor(Color.RED); + mapboxMap.addPolygon(boundsArea); + } + + private void showCrosshair() { + View crosshair = new View(this); + crosshair.setLayoutParams(new FrameLayout.LayoutParams(10, 10, Gravity.CENTER)); + crosshair.setBackgroundColor(Color.BLUE); + mapView.addView(crosshair); + } + + @Override + protected void onStart() { + super.onStart(); + mapView.onStart(); + } + + @Override + protected void onResume() { + super.onResume(); + mapView.onResume(); + } + + @Override + protected void onPause() { + super.onPause(); + mapView.onPause(); + } + + @Override + protected void onStop() { + super.onStop(); + mapView.onStop(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mapView.onSaveInstanceState(outState); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + mapView.onDestroy(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapView.onLowMemory(); + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_restricted_bounds.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_restricted_bounds.xml new file mode 100644 index 00000000000..e17807201b7 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_restricted_bounds.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml index d2442fb161b..5e0d25d2ec2 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml @@ -55,6 +55,7 @@ Dialog with map Marker views in rectangle Url transform + Restrict camera to a bounds Tracks the location of the user @@ -109,6 +110,7 @@ Marker Views within a rectangle Show bus stops and route in Singapore Transform urls on the fly + Limit viewport to Iceland category diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 5e202221b69..c33998bf6d3 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -43,6 +43,7 @@ #include "bitmap.hpp" #include "run_loop_impl.hpp" #include "java/util.hpp" +#include "geometry/lat_lng_bounds.hpp" namespace mbgl { namespace android { @@ -354,6 +355,14 @@ void NativeMapView::setStyleJson(jni::JNIEnv& env, jni::String json) { map->setStyleJSON(jni::Make(env, json)); } +void NativeMapView::setLatLngBounds(jni::JNIEnv& env, jni::Object jBounds) { + if (jBounds) { + map->setLatLngBounds(mbgl::android::LatLngBounds::getLatLngBounds(env, jBounds)); + } else { + map->setLatLngBounds(mbgl::LatLngBounds::world()); + } +} + void NativeMapView::cancelTransitions(jni::JNIEnv&) { map->cancelTransitions(); } @@ -1560,7 +1569,8 @@ void NativeMapView::registerNative(jni::JNIEnv& env) { METHOD(&NativeMapView::removeSourceById, "nativeRemoveSourceById"), METHOD(&NativeMapView::removeSource, "nativeRemoveSource"), METHOD(&NativeMapView::addImage, "nativeAddImage"), - METHOD(&NativeMapView::removeImage, "nativeRemoveImage") + METHOD(&NativeMapView::removeImage, "nativeRemoveImage"), + METHOD(&NativeMapView::setLatLngBounds, "nativeSetLatLngBounds") ); } diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index de98e6313ee..341205cd094 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -22,6 +22,7 @@ #include "geometry/projected_meters.hpp" #include "style/layers/layers.hpp" #include "style/sources/sources.hpp" +#include "geometry/lat_lng_bounds.hpp" #include #include @@ -110,6 +111,8 @@ class NativeMapView : public View, public Backend { void setStyleJson(jni::JNIEnv&, jni::String); + void setLatLngBounds(jni::JNIEnv&, jni::Object); + void cancelTransitions(jni::JNIEnv&); void setGestureInProgress(jni::JNIEnv&, jni::jboolean);