diff options
author | Ander Conselvan de Oliveira <ander.deoliveira@mapbox.com> | 2019-03-08 12:43:05 +0200 |
---|---|---|
committer | Ander Conselvan de Oliveira <ander.deoliveira@mapbox.com> | 2019-03-14 18:33:11 +0200 |
commit | 57334407473a31ff43baa645dafd2f5e1bd910fb (patch) | |
tree | e981f87c0040799a1ebc45f86d05b3ece6916aba | |
parent | 11de777628e9e2c4b219bae3f1a6eabd86f2a3c5 (diff) | |
download | qtlocation-mapboxgl-57334407473a31ff43baa645dafd2f5e1bd910fb.tar.gz |
[core] Group Map LatLngBounds, min and max zoom methods
Group bounds, minimum and maximum zoom related methods together using
the new BoundOptions.
v2: Document that getBounds() initializes all optional fields.
- Add test for getBounds() on a map with default values.
-rw-r--r-- | include/mbgl/map/bound_options.hpp | 30 | ||||
-rw-r--r-- | include/mbgl/map/map.hpp | 17 | ||||
-rwxr-xr-x | platform/android/src/native_map_view.cpp | 14 | ||||
-rw-r--r-- | platform/glfw/glfw_view.cpp | 2 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 16 | ||||
-rw-r--r-- | platform/macos/src/MGLMapView.mm | 10 | ||||
-rw-r--r-- | platform/qt/src/qmapboxgl.cpp | 4 | ||||
-rw-r--r-- | src/core-files.json | 1 | ||||
-rw-r--r-- | src/mbgl/map/map.cpp | 49 | ||||
-rw-r--r-- | test/api/annotations.test.cpp | 10 | ||||
-rw-r--r-- | test/map/map.test.cpp | 26 |
11 files changed, 123 insertions, 56 deletions
diff --git a/include/mbgl/map/bound_options.hpp b/include/mbgl/map/bound_options.hpp new file mode 100644 index 0000000000..69d353a301 --- /dev/null +++ b/include/mbgl/map/bound_options.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include <mbgl/util/geo.hpp> +#include <mbgl/util/optional.hpp> + +namespace mbgl { + +/** + * @brief Holds options to limit what parts of a map are visible. All fields are + * optional. + */ +struct BoundOptions { + /// Sets the latitude and longitude bounds to which the camera center are constrained + BoundOptions& withLatLngBounds(LatLngBounds b) { bounds = b; return *this; } + /// Sets the minimum zoom level + BoundOptions& withMinZoom(double z) { minZoom = z; return *this; } + /// Sets the maximum zoom level + BoundOptions& withMaxZoom(double z) { maxZoom = z; return *this; } + + /// Constrain the center of the camera to be within these bounds. + optional<LatLngBounds> bounds; + + /// Maximum zoom level allowed. + optional<double> maxZoom; + + /// Minimum zoom level allowed. + optional<double> minZoom; +}; + +} // namespace mbgl diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 93e5190f99..b4f60a19ba 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -2,6 +2,7 @@ #include <mbgl/util/optional.hpp> #include <mbgl/util/chrono.hpp> +#include <mbgl/map/bound_options.hpp> #include <mbgl/map/map_observer.hpp> #include <mbgl/map/map_options.hpp> #include <mbgl/map/mode.hpp> @@ -76,13 +77,15 @@ public: CameraOptions cameraForGeometry(const Geometry<double>&, const EdgeInsets&, optional<double> bearing = {}, optional<double> pitch = {}) const; LatLngBounds latLngBoundsForCamera(const CameraOptions&) const; - // Bounds - void setLatLngBounds(LatLngBounds); - LatLngBounds getLatLngBounds() const; - void setMinZoom(double); - double getMinZoom() const; - void setMaxZoom(double); - double getMaxZoom() const; + /// @name Bounds + /// @{ + + void setBounds(const BoundOptions& options); + + /// Returns the current map bound options. All optional fields in BoundOptions are set. + BoundOptions getBounds() const; + + /// @} // North Orientation void setNorthOrientation(NorthOrientation); diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 83a158efa9..3a4e2014ba 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -287,11 +287,13 @@ void NativeMapView::setStyleJson(jni::JNIEnv& env, const jni::String& json) { } void NativeMapView::setLatLngBounds(jni::JNIEnv& env, const jni::Object<mbgl::android::LatLngBounds>& jBounds) { + mbgl::BoundOptions bounds; if (jBounds) { - map->setLatLngBounds(mbgl::android::LatLngBounds::getLatLngBounds(env, jBounds)); + bounds.withLatLngBounds(mbgl::android::LatLngBounds::getLatLngBounds(env, jBounds)); } else { - map->setLatLngBounds(mbgl::LatLngBounds::world()); + bounds.withLatLngBounds(mbgl::LatLngBounds::world()); } + map->setBounds(bounds); } void NativeMapView::cancelTransitions(jni::JNIEnv&) { @@ -424,19 +426,19 @@ void NativeMapView::resetZoom(jni::JNIEnv&) { } void NativeMapView::setMinZoom(jni::JNIEnv&, jni::jdouble zoom) { - map->setMinZoom(zoom); + map->setBounds(BoundOptions().withMinZoom(zoom)); } jni::jdouble NativeMapView::getMinZoom(jni::JNIEnv&) { - return map->getMinZoom(); + return *map->getBounds().minZoom; } void NativeMapView::setMaxZoom(jni::JNIEnv&, jni::jdouble zoom) { - map->setMaxZoom(zoom); + map->setBounds(BoundOptions().withMaxZoom(zoom)); } jni::jdouble NativeMapView::getMaxZoom(jni::JNIEnv&) { - return map->getMaxZoom(); + return *map->getBounds().maxZoom; } void NativeMapView::rotateBy(jni::JNIEnv&, jni::jdouble sx, jni::jdouble sy, jni::jdouble ex, jni::jdouble ey, jni::jlong duration) { diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp index 86833da6ee..e768851a53 100644 --- a/platform/glfw/glfw_view.cpp +++ b/platform/glfw/glfw_view.cpp @@ -296,7 +296,7 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, mbgl::LatLngBounds bound = bounds[nextBound++]; nextBound = nextBound % bounds.size(); - view->map->setLatLngBounds(bound); + view->map->setBounds(mbgl::BoundOptions().withLatLngBounds(bound)); if (bound == mbgl::LatLngBounds::unbounded()) { view->map->removeAnnotation(boundAnnotationID); diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index f393dec0c1..692da30f04 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -1661,7 +1661,7 @@ public: newScale += scale / (velocity * duration) * 0.1; } - if (newScale <= 0 || log2(newScale) < self.mbglMap.getMinZoom()) + if (newScale <= 0 || log2(newScale) < *self.mbglMap.getBounds().minZoom) { velocity = 0; } @@ -1927,7 +1927,7 @@ public: if ( ! self.isZoomEnabled) return; - if ([self zoomLevel] == self.mbglMap.getMinZoom()) return; + if ([self zoomLevel] == *self.mbglMap.getBounds().minZoom) return; [self cancelTransitions]; @@ -1979,7 +1979,7 @@ public: { CGFloat distance = [quickZoom locationInView:quickZoom.view].y - self.quickZoomStart; - CGFloat newZoom = MAX(log2f(self.scale) + (distance / 75), self.mbglMap.getMinZoom()); + CGFloat newZoom = MAX(log2f(self.scale) + (distance / 75), *self.mbglMap.getBounds().minZoom); if ([self zoomLevel] == newZoom) return; @@ -3251,23 +3251,23 @@ public: - (void)setMinimumZoomLevel:(double)minimumZoomLevel { MGLLogDebug(@"Setting minimumZoomLevel: %f", minimumZoomLevel); - self.mbglMap.setMinZoom(minimumZoomLevel); + self.mbglMap.setBounds(mbgl::BoundOptions().withMinZoom(minimumZoomLevel)); } - (double)minimumZoomLevel { - return self.mbglMap.getMinZoom(); + return *self.mbglMap.getBounds().minZoom; } - (void)setMaximumZoomLevel:(double)maximumZoomLevel { MGLLogDebug(@"Setting maximumZoomLevel: %f", maximumZoomLevel); - self.mbglMap.setMaxZoom(maximumZoomLevel); + self.mbglMap.setBounds(mbgl::BoundOptions().withMaxZoom(maximumZoomLevel)); } - (double)maximumZoomLevel { - return self.mbglMap.getMaxZoom(); + return *self.mbglMap.getBounds().maxZoom; } - (MGLCoordinateBounds)visibleCoordinateBounds @@ -5847,7 +5847,7 @@ public: - (CGFloat)currentMinimumZoom { - return fmaxf(self.mbglMap.getMinZoom(), MGLMinimumZoom); + return fmaxf(*self.mbglMap.getBounds().minZoom, MGLMinimumZoom); } - (BOOL)isRotationAllowed diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 054b91d44c..320abf740c 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -328,7 +328,7 @@ public: mbgl::CameraOptions options; options.center = mbgl::LatLng(0, 0); options.padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInsets); - options.zoom = _mbglMap->getMinZoom(); + options.zoom = *_mbglMap->getBounds().minZoom; _mbglMap->jumpTo(options); _pendingLatitude = NAN; _pendingLongitude = NAN; @@ -1094,21 +1094,21 @@ public: - (void)setMinimumZoomLevel:(double)minimumZoomLevel { MGLLogDebug(@"Setting minimumZoomLevel: %f", minimumZoomLevel); - _mbglMap->setMinZoom(minimumZoomLevel); + _mbglMap->setBounds(mbgl::BoundOptions().withMinZoom(minimumZoomLevel)); } - (void)setMaximumZoomLevel:(double)maximumZoomLevel { MGLLogDebug(@"Setting maximumZoomLevel: %f", maximumZoomLevel); - _mbglMap->setMaxZoom(maximumZoomLevel); + _mbglMap->setBounds(mbgl::BoundOptions().withMaxZoom(maximumZoomLevel)); } - (double)maximumZoomLevel { - return _mbglMap->getMaxZoom(); + return *_mbglMap->getBounds().maxZoom; } - (double)minimumZoomLevel { - return _mbglMap->getMinZoom(); + return *_mbglMap->getBounds().minZoom; } /// Respond to a click on the zoom control. diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index 990e70c97f..b05c82a783 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -765,7 +765,7 @@ void QMapboxGL::setZoom(double zoom_) */ double QMapboxGL::minimumZoom() const { - return d_ptr->mapObj->getMinZoom(); + return *d_ptr->mapObj->getBounds().minZoom; } /*! @@ -775,7 +775,7 @@ double QMapboxGL::minimumZoom() const */ double QMapboxGL::maximumZoom() const { - return d_ptr->mapObj->getMaxZoom(); + return *d_ptr->mapObj->getBounds().maxZoom; } /*! diff --git a/src/core-files.json b/src/core-files.json index 8915ebc49d..6415f03182 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -328,6 +328,7 @@ "mbgl/layermanager/line_layer_factory.hpp": "include/mbgl/layermanager/line_layer_factory.hpp", "mbgl/layermanager/raster_layer_factory.hpp": "include/mbgl/layermanager/raster_layer_factory.hpp", "mbgl/layermanager/symbol_layer_factory.hpp": "include/mbgl/layermanager/symbol_layer_factory.hpp", + "mbgl/map/bound_options.hpp": "include/mbgl/map/bound_options.hpp", "mbgl/map/camera.hpp": "include/mbgl/map/camera.hpp", "mbgl/map/change.hpp": "include/mbgl/map/change.hpp", "mbgl/map/map.hpp": "include/mbgl/map/map.hpp", diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index e45d4b85f2..f545fc8095 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -275,36 +275,41 @@ LatLngBounds Map::latLngBoundsForCamera(const CameraOptions& camera) const { #pragma mark - Bounds -LatLngBounds Map::getLatLngBounds() const { - return impl->transform.getState().getLatLngBounds(); -} +void Map::setBounds(const BoundOptions& options) { + bool changeCamera = false; + CameraOptions cameraOptions; -void Map::setLatLngBounds(LatLngBounds bounds) { - impl->cameraMutated = true; - impl->transform.setLatLngBounds(std::move(bounds)); - impl->onUpdate(); -} + if (options.bounds) { + changeCamera = true; + impl->transform.setLatLngBounds(*options.bounds); + } -void Map::setMinZoom(const double minZoom) { - impl->transform.setMinZoom(minZoom); - if (impl->transform.getZoom() < minZoom) { - jumpTo(CameraOptions().withZoom(minZoom)); + if (options.minZoom) { + impl->transform.setMinZoom(*options.minZoom); + if (impl->transform.getZoom() < *options.minZoom) { + changeCamera = true; + cameraOptions.withZoom(*options.minZoom); + } } -} -double Map::getMinZoom() const { - return impl->transform.getState().getMinZoom(); -} + if (options.maxZoom) { + impl->transform.setMaxZoom(*options.maxZoom); + if (impl->transform.getZoom() > *options.maxZoom) { + changeCamera = true; + cameraOptions.withZoom(*options.maxZoom); + } + } -void Map::setMaxZoom(const double maxZoom) { - impl->transform.setMaxZoom(maxZoom); - if (impl->transform.getZoom() > maxZoom) { - jumpTo(CameraOptions().withZoom(maxZoom)); + if (changeCamera) { + jumpTo(cameraOptions); } } -double Map::getMaxZoom() const { - return impl->transform.getState().getMaxZoom(); +BoundOptions Map::getBounds() const { + return BoundOptions() + .withLatLngBounds(impl->transform.getState().getLatLngBounds()) + .withMinZoom(impl->transform.getState().getMinZoom()) + .withMaxZoom(impl->transform.getState().getMaxZoom()); } #pragma mark - Size diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp index 89ce357d84..aad85f8d57 100644 --- a/test/api/annotations.test.cpp +++ b/test/api/annotations.test.cpp @@ -85,7 +85,7 @@ TEST(Annotations, LineAnnotation) { test.map.addAnnotation(annotation); test.checkRendering("line_annotation"); - test.map.jumpTo(CameraOptions().withZoom(test.map.getMaxZoom())); + test.map.jumpTo(CameraOptions().withZoom(*test.map.getBounds().maxZoom)); test.checkRendering("line_annotation_max_zoom"); } @@ -100,7 +100,7 @@ TEST(Annotations, FillAnnotation) { test.map.addAnnotation(annotation); test.checkRendering("fill_annotation"); - test.map.jumpTo(CameraOptions().withZoom(test.map.getMaxZoom())); + test.map.jumpTo(CameraOptions().withZoom(*test.map.getBounds().maxZoom)); test.checkRendering("fill_annotation_max_zoom"); } @@ -481,11 +481,11 @@ TEST(Annotations, ChangeMaxZoom) { annotation.color = Color::red(); annotation.width = { 5 }; - test.map.setMaxZoom(6); + test.map.setBounds(BoundOptions().withMaxZoom(6)); test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.map.addAnnotation(annotation); - test.map.setMaxZoom(14); - test.map.jumpTo(CameraOptions().withZoom(test.map.getMaxZoom())); + test.map.setBounds(BoundOptions().withMaxZoom(14)); + test.map.jumpTo(CameraOptions().withZoom(*test.map.getBounds().maxZoom)); test.checkRendering("line_annotation_max_zoom"); } diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 0197202a9d..410a7e76af 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -282,6 +282,32 @@ TEST(Map, ProjectionMode) { EXPECT_EQ(*options.ySkew, 0.0); } +TEST(Map, BoundOptions) { + MapTest<> test; + + LatLngBounds llb = LatLngBounds::hull({-10, -10}, {10, 10}); + test.map.setBounds(BoundOptions().withMinZoom(4).withMaxZoom(10).withLatLngBounds(llb)); + auto bounds = test.map.getBounds(); + + EXPECT_EQ(*bounds.minZoom, 4); + EXPECT_EQ(*bounds.maxZoom, 10); + EXPECT_EQ(*bounds.bounds, llb); +} + +TEST(Map, DefaultBoundOptions) { + MapTest<> test; + + auto bounds = test.map.getBounds(); + + EXPECT_TRUE(bounds.minZoom); + EXPECT_TRUE(bounds.maxZoom); + EXPECT_TRUE(bounds.bounds); + + EXPECT_EQ(*bounds.minZoom, util::MIN_ZOOM); + EXPECT_EQ(*bounds.maxZoom, util::DEFAULT_MAX_ZOOM); + EXPECT_EQ(*bounds.bounds, LatLngBounds::unbounded()); +} + TEST(Map, SetStyleInvalidJSON) { Log::setObserver(std::make_unique<FixtureLogObserver>()); |