diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-02-24 00:54:03 +0200 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-03-01 20:58:54 +0000 |
commit | abe3f9ce7ab8087b13871472a11e7f5021084642 (patch) | |
tree | c1b0128546be655a30628c167bc50a8fe1c86862 /include/mbgl/util | |
parent | b325df880baf6f3a454c51d2e21d69114477c276 (diff) | |
download | qtlocation-mapboxgl-abe3f9ce7ab8087b13871472a11e7f5021084642.tar.gz |
[core] Moved wrapping to LatLng scope
Fixes a precision loss when converting unwrapped LatLngs.
Diffstat (limited to 'include/mbgl/util')
-rw-r--r-- | include/mbgl/util/geo.hpp | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/include/mbgl/util/geo.hpp b/include/mbgl/util/geo.hpp index fa36896869..5636cd0bdf 100644 --- a/include/mbgl/util/geo.hpp +++ b/include/mbgl/util/geo.hpp @@ -2,6 +2,7 @@ #define MBGL_UTIL_GEO #include <mbgl/util/vec.hpp> +#include <mbgl/util/constants.hpp> #include <cmath> @@ -13,11 +14,28 @@ using ScreenCoordinate = vec2<double>; class LatLng { public: - double latitude = 0; - double longitude = 0; + double latitude; + double longitude; - LatLng(double lat = 0, double lon = 0) - : latitude(lat), longitude(lon) {} + enum WrapMode : bool { Unwrapped, Wrapped }; + + LatLng(double lat = 0, double lon = 0, WrapMode mode = Unwrapped) + : latitude(lat), longitude(lon) { if (mode == Wrapped) wrap(); } + + LatLng wrapped() const { return { latitude, longitude, Wrapped }; } + + void wrap() { + if (longitude < -util::LONGITUDE_MAX) longitude = std::fmod(longitude, util::LONGITUDE_MAX * 2); + if (longitude > util::LONGITUDE_MAX) longitude = -util::LONGITUDE_MAX + std::fmod(longitude, util::LONGITUDE_MAX); + } + + /** If a path crossing the antemeridian would be shorter, extend the final + coordinate so that interpolating between the two endpoints will cross it. */ + void unwrapForShortestPath(const LatLng& start) { + if (std::abs(start.longitude) + std::abs(longitude) > util::LONGITUDE_MAX) { + longitude += (start.longitude > 0 && longitude < 0) ? 360 : -360; + } + } explicit operator bool() const { return !(std::isnan(latitude) || std::isnan(longitude)); |