summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Liu <peng.liu@mapbox.com>2020-01-09 15:53:23 +0200
committerGitHub <noreply@github.com>2020-01-09 15:53:23 +0200
commit236afc03958cc729b3b8121a1c5a72660f0e9fa2 (patch)
treead7da4d786c7ef7ce0ee14ecacd303e5a3eb34f2
parentd3a5ed968cc5288c171404d5c3f8d16a552ff28a (diff)
downloadqtlocation-mapboxgl-236afc03958cc729b3b8121a1c5a72660f0e9fa2.tar.gz
[android][core] Add `Map::latLngBoundsForCameraUnwrapped` and jni binding for `getVisibleCoordinateBounds`. (#16069)
* [android] Add getVisibleCoordinateBounds method. * Fix Map::latLngBoundsForCamera, add Android binding for getVisibleRegionBounds. * Add unit tests for CameraToLatLngBoundsWithRotation and CameraToLatLngBoundsCrossDateLine. * Move API breaking changes to a new method name latLngBoundsForCameraUnwrapped.
-rw-r--r--include/mbgl/map/map.hpp1
-rw-r--r--platform/android/src/native_map_view.cpp21
-rw-r--r--[-rwxr-xr-x]platform/android/src/native_map_view.hpp2
-rw-r--r--src/mbgl/map/map.cpp21
-rw-r--r--test/map/map.test.cpp42
5 files changed, 87 insertions, 0 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index a3794962c6..62bb39e8c2 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -72,6 +72,7 @@ public:
CameraOptions cameraForLatLngs(const std::vector<LatLng>&, const EdgeInsets&, optional<double> bearing = {}, optional<double> pitch = {}) const;
CameraOptions cameraForGeometry(const Geometry<double>&, const EdgeInsets&, optional<double> bearing = {}, optional<double> pitch = {}) const;
LatLngBounds latLngBoundsForCamera(const CameraOptions&) const;
+ LatLngBounds latLngBoundsForCameraUnwrapped(const CameraOptions&) const;
/// @name Bounds
/// @{
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 554a59de76..d7351c7677 100644
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -529,6 +529,26 @@ void NativeMapView::setVisibleCoordinateBounds(JNIEnv& env, const jni::Array<jni
map->easeTo(cameraOptions, animationOptions);
}
+void NativeMapView::getVisibleCoordinateBounds(JNIEnv& env, jni::Array<jdouble>& output) {
+ auto latlngBounds = map->latLngBoundsForCameraUnwrapped(map->getCameraOptions(mbgl::nullopt));
+
+ double latNorth = latlngBounds.north();
+ double lonEast = latlngBounds.east();
+ double latSouth = latlngBounds.south();
+ double lonWest = latlngBounds.west();
+
+ std::vector<jdouble> buffer;
+ buffer.reserve(4);
+
+ // Order of the LatLngBounds: double latNorth, double lonEast, double latSouth, double lonWest
+ buffer.push_back(latNorth);
+ buffer.push_back(lonEast);
+ buffer.push_back(latSouth);
+ buffer.push_back(lonWest);
+
+ output.SetRegion<std::vector<jdouble>>(env, 0, buffer);
+}
+
void NativeMapView::scheduleSnapshot(jni::JNIEnv&) {
mapRenderer.requestSnapshot([&](PremultipliedImage image) {
auto _env = android::AttachEnv();
@@ -1172,6 +1192,7 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
METHOD(&NativeMapView::projectedMetersForLatLng, "nativeProjectedMetersForLatLng"),
METHOD(&NativeMapView::pixelForLatLng, "nativePixelForLatLng"),
METHOD(&NativeMapView::pixelsForLatLngs, "nativePixelsForLatLngs"),
+ METHOD(&NativeMapView::getVisibleCoordinateBounds, "nativeGetVisibleCoordinateBounds"),
METHOD(&NativeMapView::latLngForProjectedMeters, "nativeLatLngForProjectedMeters"),
METHOD(&NativeMapView::latLngForPixel, "nativeLatLngForPixel"),
METHOD(&NativeMapView::latLngsForPixels, "nativeLatLngsForPixels"),
diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp
index 622c454b7d..ab93fab81f 100755..100644
--- a/platform/android/src/native_map_view.hpp
+++ b/platform/android/src/native_map_view.hpp
@@ -139,6 +139,8 @@ public:
void setVisibleCoordinateBounds(JNIEnv&, const jni::Array<jni::Object<LatLng>>&, const jni::Object<RectF>&, jni::jdouble, jni::jlong);
+ void getVisibleCoordinateBounds(JNIEnv& env, jni::Array<jdouble>& output);
+
void scheduleSnapshot(jni::JNIEnv&);
jni::Local<jni::Object<CameraPosition>> getCameraPosition(jni::JNIEnv&);
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 9cd9fdc15f..a994af305f 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -256,6 +256,27 @@ LatLngBounds Map::latLngBoundsForCamera(const CameraOptions& camera) const {
);
}
+LatLngBounds Map::latLngBoundsForCameraUnwrapped(const CameraOptions& camera) const {
+ Transform shallow{impl->transform.getState()};
+ Size size = shallow.getState().getSize();
+
+ shallow.jumpTo(camera);
+ LatLng nw = shallow.screenCoordinateToLatLng({});
+ LatLng se = shallow.screenCoordinateToLatLng({double(size.width), double(size.height)});
+ LatLng ne = shallow.screenCoordinateToLatLng({double(size.width), 0.0});
+ LatLng sw = shallow.screenCoordinateToLatLng({0.0, double(size.height)});
+ LatLng center = shallow.screenCoordinateToLatLng({double(size.width) / 2, double(size.height) / 2});
+ nw.unwrapForShortestPath(center);
+ se.unwrapForShortestPath(center);
+ ne.unwrapForShortestPath(center);
+ sw.unwrapForShortestPath(center);
+ LatLngBounds bounds = LatLngBounds::hull(nw, se);
+ bounds.extend(ne);
+ bounds.extend(sw);
+ bounds.extend(center);
+ return bounds;
+}
+
#pragma mark - Bounds
void Map::setBounds(const BoundOptions& options) {
diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp
index 31cc85619e..a0cd64bdd5 100644
--- a/test/map/map.test.cpp
+++ b/test/map/map.test.cpp
@@ -252,6 +252,48 @@ TEST(Map, CameraToLatLngBounds) {
ASSERT_NEAR(camera.center->longitude(), virtualCamera.center->longitude(), 1e-7);
}
+TEST(Map, CameraToLatLngBoundsUnwrappedWithRotation) {
+ MapTest<> test;
+
+ test.map.jumpTo(CameraOptions().withCenter(LatLng{45, 90}).withZoom(16.0).withBearing(45.0));
+
+ const Size size = test.map.getMapOptions().size();
+
+ CameraOptions camera = test.map.getCameraOptions();
+
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).contains(test.map.latLngForPixel({})));
+ ASSERT_TRUE(
+ test.map.latLngBoundsForCameraUnwrapped(camera).contains(test.map.latLngForPixel({0.0, double(size.height)})));
+ ASSERT_TRUE(
+ test.map.latLngBoundsForCameraUnwrapped(camera).contains(test.map.latLngForPixel({double(size.width), 0.0})));
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).contains(
+ test.map.latLngForPixel({double(size.width), double(size.height)})));
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).contains(
+ test.map.latLngForPixel({double(size.width) / 2, double(size.height) / 2})));
+}
+
+TEST(Map, CameraToLatLngBoundsUnwrappedCrossDateLine) {
+ MapTest<> test;
+
+ test.map.jumpTo(CameraOptions().withCenter(LatLng{0, 180}).withZoom(16.0));
+
+ const Size size = test.map.getMapOptions().size();
+
+ CameraOptions camera = test.map.getCameraOptions();
+
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).contains(test.map.latLngForPixel({}), LatLng::Wrapped));
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).contains(
+ test.map.latLngForPixel({0.0, double(size.height)}), LatLng::Wrapped));
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).contains(
+ test.map.latLngForPixel({double(size.width), 0.0}), LatLng::Wrapped));
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).contains(
+ test.map.latLngForPixel({double(size.width), double(size.height)}), LatLng::Wrapped));
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).contains(
+ test.map.latLngForPixel({double(size.width) / 2, double(size.height) / 2})));
+
+ ASSERT_TRUE(test.map.latLngBoundsForCameraUnwrapped(camera).crossesAntimeridian());
+}
+
TEST(Map, Offline) {
MapTest<DefaultFileSource> test {":memory:", "."};