diff --git a/CHANGELOG.md b/CHANGELOG.md index d956fbc3ace..8473923779c 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 45386b9dc8c..d3cd30a6275 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 ada20c5872d..6b9e960fe6b 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); +}