summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mbgl/map/map.hpp2
-rw-r--r--src/mbgl/map/map.cpp9
-rw-r--r--src/mbgl/map/transform.cpp6
-rw-r--r--src/mbgl/map/transform.hpp1
-rw-r--r--src/mbgl/map/transform_state.cpp15
-rw-r--r--src/mbgl/map/transform_state.hpp4
-rw-r--r--test/map/transform.test.cpp39
7 files changed, 74 insertions, 2 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index b740c3462e..908beb6b29 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -111,6 +111,8 @@ public:
void resetZoom();
// Bounds
+ void setLatLngBounds(const LatLngBounds&);
+ LatLngBounds getLatLngBounds() const;
void setMinZoom(double);
double getMinZoom() const;
void setMaxZoom(double);
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index f42c11bdbb..261d2f149f 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -666,6 +666,15 @@ void Map::resetZoom() {
#pragma mark - Bounds
+LatLngBounds Map::getLatLngBounds() const {
+ return impl->transform.getState().getLatLngBounds();
+}
+
+void Map::setLatLngBounds(const LatLngBounds& bounds) {
+ impl->cameraMutated = true;
+ impl->transform.setLatLngBounds(bounds);
+ impl->onUpdate(Update::Repaint);
+}
void Map::setMinZoom(const double minZoom) {
impl->transform.setMinZoom(minZoom);
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index b8c3c3fefb..469db09e0a 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -435,6 +435,12 @@ void Transform::setScale(double scale, optional<EdgeInsets> padding, const Anima
#pragma mark - Bounds
+void Transform::setLatLngBounds(const LatLngBounds& bounds) {
+ if (bounds.valid()) {
+ state.setLatLngBounds(bounds);
+ }
+}
+
void Transform::setMinZoom(const double minZoom) {
if (std::isnan(minZoom)) return;
state.setMinZoom(minZoom);
diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp
index 4b97e07b52..a4a08f4ad9 100644
--- a/src/mbgl/map/transform.hpp
+++ b/src/mbgl/map/transform.hpp
@@ -57,6 +57,7 @@ public:
// Bounds
+ void setLatLngBounds(const LatLngBounds&);
void setMinZoom(double);
void setMaxZoom(double);
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 3336c71125..764845bc8c 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -142,6 +142,15 @@ double TransformState::getScale() const {
#pragma mark - Bounds
+void TransformState::setLatLngBounds(const LatLngBounds& bounds_) {
+ bounds = bounds_;
+ setLatLngZoom(getLatLng(LatLng::Unwrapped), getZoom());
+}
+
+LatLngBounds TransformState::getLatLngBounds() const {
+ return bounds;
+}
+
void TransformState::setMinZoom(const double minZoom) {
if (minZoom <= getMaxZoom()) {
min_scale = zoomScale(util::clamp(minZoom, util::MIN_ZOOM, util::MAX_ZOOM));
@@ -324,16 +333,18 @@ void TransformState::moveLatLng(const LatLng& latLng, const ScreenCoordinate& an
}
void TransformState::setLatLngZoom(const LatLng &latLng, double zoom) {
+ const LatLng constrained = bounds.constrain(latLng);
+
double newScale = zoomScale(zoom);
const double newWorldSize = newScale * util::tileSize;
Bc = newWorldSize / util::DEGREES_MAX;
Cc = newWorldSize / util::M2PI;
const double m = 1 - 1e-15;
- const double f = util::clamp(std::sin(util::DEG2RAD * latLng.latitude()), -m, m);
+ const double f = util::clamp(std::sin(util::DEG2RAD * constrained.latitude()), -m, m);
ScreenCoordinate point = {
- -latLng.longitude() * Bc,
+ -constrained.longitude() * Bc,
0.5 * Cc * std::log((1 + f) / (1 - f)),
};
setScalePoint(newScale, point);
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 4a0218e10e..b8baefdba1 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -51,6 +51,8 @@ public:
double getZoomFraction() const;
// Bounds
+ void setLatLngBounds(const LatLngBounds&);
+ LatLngBounds getLatLngBounds() const;
void setMinZoom(double);
double getMinZoom() const;
void setMaxZoom(double);
@@ -84,6 +86,8 @@ private:
bool rotatedNorth() const;
void constrain(double& scale, double& x, double& y) const;
+ LatLngBounds bounds = LatLngBounds::world();
+
// Limit the amount of zooming possible on the map.
double min_scale = std::pow(2, 0);
double max_scale = std::pow(2, 20);
diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp
index a8869b41bf..caee0ba23d 100644
--- a/test/map/transform.test.cpp
+++ b/test/map/transform.test.cpp
@@ -534,3 +534,42 @@ TEST(Transform, DefaultTransform) {
ASSERT_DOUBLE_EQ(point.x, center.x);
ASSERT_DOUBLE_EQ(point.y, center.y);
}
+
+TEST(Transform, LatLngBounds) {
+ const LatLng nullIsland {};
+ const LatLng sanFrancisco { 37.7749, -122.4194 };
+
+ Transform transform;
+ transform.resize({ 1000, 1000 });
+ transform.setLatLngZoom({ 0, 0 }, transform.getState().getMaxZoom());
+
+ // Default bounds.
+ ASSERT_EQ(transform.getState().getLatLngBounds(), LatLngBounds::world());
+ ASSERT_EQ(transform.getLatLng(), nullIsland);
+
+ // Invalid bounds.
+ transform.setLatLngBounds(LatLngBounds::empty());
+ ASSERT_EQ(transform.getState().getLatLngBounds(), LatLngBounds::world());
+
+ transform.setLatLng(sanFrancisco);
+ ASSERT_EQ(transform.getLatLng(), sanFrancisco);
+
+ // Single location.
+ transform.setLatLngBounds(LatLngBounds::singleton(sanFrancisco));
+ ASSERT_EQ(transform.getLatLng(), sanFrancisco);
+
+ transform.setLatLngBounds(LatLngBounds::hull({ -90.0, -180.0 }, { 0.0, 180.0 }));
+ transform.setLatLng(sanFrancisco);
+ ASSERT_EQ(transform.getLatLng().latitude(), 0.0);
+ ASSERT_EQ(transform.getLatLng().longitude(), sanFrancisco.longitude());
+
+ transform.setLatLngBounds(LatLngBounds::hull({ -90.0, 0.0 }, { 90.0, 180.0 }));
+ transform.setLatLng(sanFrancisco);
+ ASSERT_EQ(transform.getLatLng().latitude(), sanFrancisco.latitude());
+ ASSERT_EQ(transform.getLatLng().longitude(), 0.0);
+
+ transform.setLatLngBounds(LatLngBounds::hull({ -90.0, 0.0 }, { 0.0, 180.0 }));
+ transform.setLatLng(sanFrancisco);
+ ASSERT_EQ(transform.getLatLng().latitude(), 0.0);
+ ASSERT_EQ(transform.getLatLng().longitude(), 0.0);
+}