From 1a4b8f3e2f76fd55abccf09b6a07bc1035aa89a8 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Thu, 10 Mar 2016 03:24:47 +0200 Subject: [core] Fix screen coordinates when crossing the antimeridian 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. Fixes #4155. --- CHANGELOG.md | 1 + src/mbgl/map/transform.cpp | 16 +++++++++++++++- test/map/transform.cpp | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) 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); +} -- cgit v1.2.1