From 026b6d4c01a3d96af9629cc1790373137ecab950 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Mon, 7 Mar 2016 18:07:23 +0200 Subject: [core] Coordinate wrapping fixes - Make returning LatLngs unwrapped by default. - PointAnnotation and ShapeAnnotation are always wrapped so they can be selected via intersection from the visible tile boundaries. - Fixes LatLng::wrap() calculation. - Fixes LatLng::unwrapForShortestPath() calculation. The new unwrapForShortestPath algorithm unwraps the start coordinate either forwards or backwards depending on the end coordinate value, so we can always cross the antimeridian when needed and still obtain a wrapped end coordinate in the end. Fixes #4214. --- src/mbgl/map/transform.cpp | 20 +++++++++++++++----- src/mbgl/map/transform_state.cpp | 31 ++----------------------------- src/mbgl/map/transform_state.hpp | 4 ++-- src/mbgl/util/tile_cover.cpp | 2 +- 4 files changed, 20 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp index 74e43a62fe..79b43f8901 100644 --- a/src/mbgl/map/transform.cpp +++ b/src/mbgl/map/transform.cpp @@ -95,12 +95,17 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim if (camera.padding) { padding = *camera.padding; } - const LatLng startLatLng = getLatLng(padding); + + LatLng startLatLng = getLatLng(padding); + startLatLng.unwrapForShortestPath(latLng); + + // Make sure the end coordinate always remains valid. + latLng.wrap(); + const ScreenCoordinate startPoint = { state.lngX(startLatLng.longitude), state.latY(startLatLng.latitude), }; - latLng.unwrapForShortestPath(getLatLng()); const ScreenCoordinate endPoint = { state.lngX(latLng.longitude), state.latY(latLng.latitude), @@ -136,7 +141,7 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim ScreenCoordinate framePoint = util::interpolate(startPoint, endPoint, t); LatLng frameLatLng = { state.yLat(framePoint.y, startWorldSize), - state.xLng(framePoint.x, startWorldSize), + state.xLng(framePoint.x, startWorldSize) }; double frameScale = util::interpolate(startScale, scale, t); state.setLatLngZoom(frameLatLng, state.scaleZoom(frameScale)); @@ -178,12 +183,17 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima if (camera.padding) { padding = *camera.padding; } - const LatLng startLatLng = getLatLng(padding); + + LatLng startLatLng = getLatLng(padding); + startLatLng.unwrapForShortestPath(latLng); + + // Make sure the end coordinate always remains valid. + latLng.wrap(); + const ScreenCoordinate startPoint = { state.lngX(startLatLng.longitude), state.latY(startLatLng.latitude), }; - latLng.unwrapForShortestPath(getLatLng()); const ScreenCoordinate endPoint = { state.lngX(latLng.longitude), state.latY(latLng.latitude), diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index 006a8d5d3a..a23ee71f99 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -89,38 +89,11 @@ ConstrainMode TransformState::getConstrainMode() const { #pragma mark - Position LatLng TransformState::getLatLng(LatLng::WrapMode wrapMode) const { - LatLng ll { + return { util::RAD2DEG * (2 * std::atan(std::exp(y / Cc)) - 0.5 * M_PI), -x / Bc, wrapMode }; - - if (wrapMode == LatLng::Unwrapped) return ll; - - // adjust for date line - double w = worldSize() / 2; - double x_ = x; - if (x_ > w) { - while (x_ > w) { - x_ -= w; - if (ll.longitude < 0) { - ll.longitude += util::LONGITUDE_MAX; - } else if (ll.longitude > 0) { - ll.longitude -= util::LONGITUDE_MAX; - } - } - } else if (x_ < -w) { - while (x_ < -w) { - x_ += w; - if (ll.longitude < 0) { - ll.longitude -= util::LONGITUDE_MAX; - } else if (ll.longitude > 0) { - ll.longitude -= util::LONGITUDE_MAX; - } - } - } - - return ll; } double TransformState::pixel_x() const { @@ -350,7 +323,7 @@ void TransformState::moveLatLng(const LatLng& latLng, const ScreenCoordinate& an auto centerCoord = latLngToTileCoord(getLatLng(LatLng::Unwrapped)); auto latLngCoord = latLngToTileCoord(latLng); - auto anchorCoord = latLngToTileCoord(screenCoordinateToLatLng(anchor, LatLng::Unwrapped)); + auto anchorCoord = latLngToTileCoord(screenCoordinateToLatLng(anchor)); setLatLngZoom(tileCoordToLatLng(centerCoord + latLngCoord - anchorCoord), getZoom()); } diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp index 797a28692e..ef3a5dfefd 100644 --- a/src/mbgl/map/transform_state.hpp +++ b/src/mbgl/map/transform_state.hpp @@ -37,7 +37,7 @@ public: ConstrainMode getConstrainMode() const; // Position - LatLng getLatLng(LatLng::WrapMode = LatLng::Wrapped) const; + LatLng getLatLng(LatLng::WrapMode = LatLng::Unwrapped) const; double pixel_x() const; double pixel_y() const; @@ -65,7 +65,7 @@ public: // Conversion and projection ScreenCoordinate latLngToScreenCoordinate(const LatLng&) const; - LatLng screenCoordinateToLatLng(const ScreenCoordinate&, LatLng::WrapMode = LatLng::Wrapped) const; + LatLng screenCoordinateToLatLng(const ScreenCoordinate&, LatLng::WrapMode = LatLng::Unwrapped) const; double xLng(double x, double worldSize) const; double yLat(double y, double worldSize) const; diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp index 0fae940271..6efff4bb57 100644 --- a/src/mbgl/util/tile_cover.cpp +++ b/src/mbgl/util/tile_cover.cpp @@ -23,7 +23,7 @@ public: } static TileCoordinate fromScreenCoordinate(const TransformState& state, double zoom, const ScreenCoordinate& point) { - return fromLatLng(state, zoom, state.screenCoordinateToLatLng(point, LatLng::Unwrapped)); + return fromLatLng(state, zoom, state.screenCoordinateToLatLng(point)); } }; -- cgit v1.2.1