Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Fix screen coordinates when crossing the antimeridian
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
brunoabinader committed Mar 10, 2016
1 parent 7dde622 commit 1a4b8f3
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
16 changes: 15 additions & 1 deletion src/mbgl/map/transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
22 changes: 22 additions & 0 deletions test/map/transform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 1a4b8f3

Please sign in to comment.