summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mbgl/map/camera.hpp13
-rw-r--r--include/mbgl/map/map.hpp1
-rw-r--r--include/mbgl/util/geo.hpp8
-rw-r--r--src/mbgl/map/map.cpp11
-rw-r--r--src/mbgl/map/transform.hpp2
-rw-r--r--test/map/map.test.cpp22
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:", ".");