summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/mbgl/map/transform.cpp16
-rw-r--r--test/map/transform.cpp22
3 files changed, 38 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d956fbc3ac..8473923779 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -51,6 +51,7 @@ Known issues:
## iOS master
+- Fixed screen coordinates for LatLng coordinates accross the antimeridian. ([#4215](https://github.com/mapbox/mapbox-gl-native/issues/4155))
- Fixed a bounce-back effect when panning the map. ([#4214](https://github.com/mapbox/mapbox-gl-native/pull/4214))
- An icon laid out along a line no longer appears if it would extend past the end of the line. Some one-way arrows no longer point the wrong way. ([#3839](https://github.com/mapbox/mapbox-gl-native/pull/3839))
- Reduce slanted segments in dashed lines near corners. ([#3914](https://github.com/mapbox/mapbox-gl-native/pull/3914))
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 45386b9dc8..d3cd30a627 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -660,7 +660,21 @@ void Transform::setGestureInProgress(bool inProgress) {
ScreenCoordinate Transform::latLngToScreenCoordinate(const LatLng& latLng) const {
if (!latLng) return {};
- ScreenCoordinate point = state.latLngToScreenCoordinate(latLng);
+
+ // If the center and point coordinates are not in the same side of the
+ // antimeridian, we need to unwrap the point longitude to make sure it can
+ // still be seen from the visible side of the antimeridian that is opposite
+ // to the center side.
+ double longitude = latLng.longitude;
+ const double centerLng = getLatLng().longitude;
+ if (centerLng - latLng.longitude > util::LONGITUDE_MAX) {
+ if (centerLng > 0 && latLng.longitude < 0) {
+ longitude += util::DEGREES_MAX;
+ } else if (centerLng < 0 && latLng.longitude > 0) {
+ longitude -= util::DEGREES_MAX;
+ }
+ }
+ ScreenCoordinate point = state.latLngToScreenCoordinate({ latLng.latitude, longitude });
point.y = state.height - point.y;
return point;
}
diff --git a/test/map/transform.cpp b/test/map/transform.cpp
index ada20c5872..6b9e960fe6 100644
--- a/test/map/transform.cpp
+++ b/test/map/transform.cpp
@@ -297,3 +297,25 @@ TEST(Transform, MoveBy) {
ASSERT_NEAR(0, trueCenter.latitude, 1.1);
ASSERT_NEAR(0, trueCenter.longitude, 1.1);
}
+
+TEST(Transform, Antimeridian) {
+ MockView view;
+ Transform transform(view, ConstrainMode::HeightOnly);
+ transform.resize({{ 1000, 1000 }});
+ transform.setLatLngZoom({ 0, 0 }, 1);
+
+ const LatLng coordinateSanFrancisco { 37.7833, -122.4167 };
+ ScreenCoordinate pixelSF = transform.latLngToScreenCoordinate(coordinateSanFrancisco);
+ ASSERT_DOUBLE_EQ(151.79409149185352, pixelSF.x);
+ ASSERT_DOUBLE_EQ(383.76774094913071, pixelSF.y);
+
+ transform.setLatLng({ 0, -181 });
+ ScreenCoordinate pixelSFBackwards = transform.latLngToScreenCoordinate(coordinateSanFrancisco);
+ ASSERT_DOUBLE_EQ(666.63617954008976, pixelSFBackwards.x);
+ ASSERT_DOUBLE_EQ(pixelSF.y, pixelSFBackwards.y);
+
+ transform.setLatLng({ 0, 179 });
+ ScreenCoordinate pixelSFForwards = transform.latLngToScreenCoordinate(coordinateSanFrancisco);
+ ASSERT_DOUBLE_EQ(pixelSFBackwards.x, pixelSFForwards.x);
+ ASSERT_DOUBLE_EQ(pixelSFBackwards.y, pixelSFForwards.y);
+}