diff options
-rw-r--r-- | include/mbgl/map/camera.hpp | 13 | ||||
-rw-r--r-- | include/mbgl/map/map.hpp | 1 | ||||
-rw-r--r-- | include/mbgl/util/geo.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/map/map.cpp | 11 | ||||
-rw-r--r-- | src/mbgl/map/transform.hpp | 2 | ||||
-rw-r--r-- | test/map/map.test.cpp | 22 |
6 files changed, 57 insertions, 0 deletions
diff --git a/include/mbgl/map/camera.hpp b/include/mbgl/map/camera.hpp index 1c389577f0..20b863cf4e 100644 --- a/include/mbgl/map/camera.hpp +++ b/include/mbgl/map/camera.hpp @@ -36,6 +36,19 @@ struct CameraOptions { optional<double> pitch; }; +constexpr bool operator==(const CameraOptions& a, const CameraOptions& b) { + return a.center == b.center + && a.padding == b.padding + && a.anchor == b.anchor + && a.zoom == b.zoom + && a.angle == b.angle + && a.pitch == b.pitch; +} + +constexpr bool operator!=(const CameraOptions& a, const CameraOptions& b) { + return !(a == b); +} + /** Various options for describing a transition between viewpoints with animation. All fields are optional; the default values depend on how this struct is used. */ diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 30963f25db..d4eb0ce8d1 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -107,6 +107,7 @@ public: void setLatLngZoom(const LatLng&, double zoom, optional<EdgeInsets>, const AnimationOptions& = {}); CameraOptions cameraForLatLngBounds(const LatLngBounds&, optional<EdgeInsets>) const; CameraOptions cameraForLatLngs(const std::vector<LatLng>&, optional<EdgeInsets>) const; + LatLngBounds latLngBoundsForCamera(const CameraOptions&) const; void resetZoom(); void setMinZoom(const double minZoom); double getMinZoom() const; diff --git a/include/mbgl/util/geo.hpp b/include/mbgl/util/geo.hpp index 57a028e467..2cc9297aae 100644 --- a/include/mbgl/util/geo.hpp +++ b/include/mbgl/util/geo.hpp @@ -218,4 +218,12 @@ public: ScreenCoordinate getCenter(uint16_t width, uint16_t height) const; }; +constexpr bool operator==(const EdgeInsets& a, const EdgeInsets& b) { + return a.top == b.top && a.left == b.left && a.bottom == b.bottom && a.right == b.right; +} + +constexpr bool operator!=(const EdgeInsets& a, const EdgeInsets& b) { + return !(a == b); +} + } // namespace mbgl diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index a883a69282..9e0b1a7575 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -644,6 +644,17 @@ CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, optional return options; } +LatLngBounds Map::latLngBoundsForCamera(const CameraOptions& camera) const { + Transform shallow { impl->transform.getState() }; + Size size = shallow.getState().getSize(); + + shallow.jumpTo(camera); + return LatLngBounds::hull( + shallow.screenCoordinateToLatLng({}), + shallow.screenCoordinateToLatLng({ double(size.width), double(size.height) }) + ); +} + void Map::resetZoom() { impl->cameraMutated = true; setZoom(0); diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp index 087ae8e690..f11ac81287 100644 --- a/src/mbgl/map/transform.hpp +++ b/src/mbgl/map/transform.hpp @@ -22,6 +22,8 @@ public: ConstrainMode = ConstrainMode::HeightOnly, ViewportMode = ViewportMode::Default); + Transform(const TransformState &state_) : observer(MapObserver::nullObserver()), state(state_) {} + // Map view bool resize(Size size); diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index c5017aeb04..8f81a5d8c5 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -69,6 +69,28 @@ TEST(Map, LatLngBehavior) { ASSERT_DOUBLE_EQ(latLng1.longitude, latLng2.longitude); } +TEST(Map, CameraToLatLngBounds) { + MapTest test; + Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still); + + map.setLatLngZoom({ 45, 90 }, 16); + + LatLngBounds bounds = LatLngBounds::hull( + map.latLngForPixel({}), + map.latLngForPixel({ double(map.getSize().width), double(map.getSize().height) })); + + CameraOptions camera = map.getCameraOptions({}); + + ASSERT_EQ(bounds, map.latLngBoundsForCamera(camera)); + + CameraOptions virtualCamera = map.cameraForLatLngBounds(bounds, {}); + ASSERT_NEAR(*camera.zoom, *virtualCamera.zoom, 1e-7); + ASSERT_NEAR(*camera.angle, *virtualCamera.angle, 1e-10); + ASSERT_NEAR(*camera.pitch, *virtualCamera.pitch, 1e-10); + ASSERT_NEAR(camera.center->latitude, virtualCamera.center->latitude, 1e-10); + ASSERT_NEAR(camera.center->longitude, virtualCamera.center->longitude, 1e-10); +} + TEST(Map, Offline) { MapTest test; DefaultFileSource fileSource(":memory:", "."); |