summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-03-07 18:07:23 +0200
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-03-10 03:36:45 +0200
commit026b6d4c01a3d96af9629cc1790373137ecab950 (patch)
treec63cdb8429c793c3abfa8bc92c68c8fb848d7c54 /include
parent808bf7004a4360a4cc7095f97c235c92d3679f8b (diff)
downloadqtlocation-mapboxgl-026b6d4c01a3d96af9629cc1790373137ecab950.tar.gz
[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.
Diffstat (limited to 'include')
-rw-r--r--include/mbgl/annotation/point_annotation.hpp5
-rw-r--r--include/mbgl/annotation/shape_annotation.hpp17
-rw-r--r--include/mbgl/util/geo.hpp24
3 files changed, 28 insertions, 18 deletions
diff --git a/include/mbgl/annotation/point_annotation.hpp b/include/mbgl/annotation/point_annotation.hpp
index e226673997..3dea9a3e3e 100644
--- a/include/mbgl/annotation/point_annotation.hpp
+++ b/include/mbgl/annotation/point_annotation.hpp
@@ -9,9 +9,8 @@ namespace mbgl {
class PointAnnotation {
public:
- inline PointAnnotation(const LatLng& position_, const std::string& icon_ = "")
- : position(position_), icon(icon_) {
- }
+ PointAnnotation(const LatLng& position_, const std::string& icon_ = "")
+ : position(position_.wrapped()), icon(icon_) {}
const LatLng position;
const std::string icon;
diff --git a/include/mbgl/annotation/shape_annotation.hpp b/include/mbgl/annotation/shape_annotation.hpp
index fffa7dab6e..121cb7f1d7 100644
--- a/include/mbgl/annotation/shape_annotation.hpp
+++ b/include/mbgl/annotation/shape_annotation.hpp
@@ -33,11 +33,24 @@ public:
std::string>; // creates an annotation whose type and properties are sourced from a style layer
ShapeAnnotation(const AnnotationSegments& segments_, const Properties& properties_)
- : segments(segments_), properties(properties_) {
- }
+ : segments(wrapCoordinates(segments_)), properties(properties_) {}
const AnnotationSegments segments;
const Properties properties;
+
+private:
+ AnnotationSegments wrapCoordinates(const AnnotationSegments& segments_) {
+ AnnotationSegments wrappedSegments;
+ // Wrap all segments coordinates.
+ for (const auto& segment_ : segments_) {
+ AnnotationSegment wrappedSegment;
+ for (const auto& latLng_ : segment_) {
+ wrappedSegment.push_back(latLng_.wrapped());
+ }
+ wrappedSegments.push_back(wrappedSegment);
+ }
+ return wrappedSegments;
+ }
};
} // namespace mbgl
diff --git a/include/mbgl/util/geo.hpp b/include/mbgl/util/geo.hpp
index 56d575ceaa..9e2d7a2bb1 100644
--- a/include/mbgl/util/geo.hpp
+++ b/include/mbgl/util/geo.hpp
@@ -25,19 +25,17 @@ public:
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) {
- if (start.longitude > 0 && longitude < 0) {
- longitude += util::DEGREES_MAX;
- } else if (start.longitude < 0 && longitude > 0) {
- longitude -= util::DEGREES_MAX;
- }
+ if (longitude < -util::LONGITUDE_MAX) longitude = util::LONGITUDE_MAX + std::fmod(longitude + util::LONGITUDE_MAX, util::DEGREES_MAX);
+ if (longitude > util::LONGITUDE_MAX) longitude = -util::LONGITUDE_MAX + std::fmod(longitude + util::LONGITUDE_MAX, util::DEGREES_MAX);
+ }
+
+ // If we pass through the antimeridian, we update the start coordinate to make sure
+ // the end coordinate is always wrapped.
+ void unwrapForShortestPath(const LatLng& end) {
+ if (end.longitude < -util::LONGITUDE_MAX) {
+ longitude += util::DEGREES_MAX;
+ } else if (end.longitude > util::LONGITUDE_MAX) {
+ longitude -= util::DEGREES_MAX;
}
}