summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-05-26 16:35:55 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-06-01 17:36:50 -0700
commit8985b1311b7d00cf761752bd9291566325ae207a (patch)
treeaa42e0a0f5e0dc592d6dcafdf5ff54013ccc7a25
parentaa1a54c577a95082824f2a5a6bdf4948506fcaa9 (diff)
downloadqtlocation-mapboxgl-8985b1311b7d00cf761752bd9291566325ae207a.tar.gz
[core] Use geometry.hpp types for shape annotations
-rw-r--r--include/mbgl/annotation/shape_annotation.hpp11
-rw-r--r--include/mbgl/platform/default/glfw_view.hpp4
-rwxr-xr-xplatform/android/src/jni.cpp74
-rw-r--r--platform/darwin/src/MGLMultiPoint.mm16
-rw-r--r--platform/darwin/src/MGLMultiPoint_Private.h7
-rw-r--r--platform/darwin/src/MGLPolygon.mm31
-rw-r--r--platform/darwin/src/MGLPolyline.mm19
-rw-r--r--platform/default/glfw_view.cpp23
-rw-r--r--platform/ios/src/MGLMapView.mm10
-rw-r--r--platform/osx/src/MGLMapView.mm2
-rw-r--r--src/mbgl/annotation/shape_annotation_impl.cpp101
-rw-r--r--src/mbgl/map/map.cpp5
-rw-r--r--src/mbgl/util/geometry.hpp3
-rw-r--r--test/api/annotations.cpp22
14 files changed, 186 insertions, 142 deletions
diff --git a/include/mbgl/annotation/shape_annotation.hpp b/include/mbgl/annotation/shape_annotation.hpp
index c5d4c42d87..7dca1ec134 100644
--- a/include/mbgl/annotation/shape_annotation.hpp
+++ b/include/mbgl/annotation/shape_annotation.hpp
@@ -3,14 +3,11 @@
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/style/types.hpp>
-#include <mbgl/util/geo.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/variant.hpp>
namespace mbgl {
-using AnnotationSegment = std::vector<LatLng>;
-using AnnotationSegments = std::vector<AnnotationSegment>;
-
struct FillAnnotationProperties {
float opacity = 1;
Color color = {{ 0, 0, 0, 1 }};
@@ -30,10 +27,10 @@ public:
LineAnnotationProperties, // creates a line annotation
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_) {}
+ ShapeAnnotation(const Geometry<double>& geometry_, const Properties& properties_)
+ : geometry(geometry_), properties(properties_) {}
- const AnnotationSegments segments;
+ const Geometry<double> geometry;
const Properties properties;
};
diff --git a/include/mbgl/platform/default/glfw_view.hpp b/include/mbgl/platform/default/glfw_view.hpp
index b5931e6262..b3b6116ad7 100644
--- a/include/mbgl/platform/default/glfw_view.hpp
+++ b/include/mbgl/platform/default/glfw_view.hpp
@@ -3,6 +3,7 @@
#include <mbgl/mbgl.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/timer.hpp>
+#include <mbgl/util/geometry.hpp>
#ifdef MBGL_USE_GLES2
#define GLFW_INCLUDE_ES2
@@ -43,7 +44,8 @@ public:
void report(float duration);
private:
- mbgl::LatLng makeRandomPoint() const;
+ mbgl::LatLng makeRandomLatLng() const;
+ mbgl::Point<double> makeRandomPoint() const;
static std::shared_ptr<const mbgl::SpriteImage>
makeSpriteImage(int width, int height, float pixelRatio);
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index 5afe398a80..4c3f77e9da 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -248,35 +248,6 @@ jni::jarray<jlong>* std_vector_uint_to_jobject(JNIEnv *env, std::vector<uint32_t
return &jarray;
}
-mbgl::AnnotationSegment annotation_segment_from_latlng_jlist(JNIEnv *env, jni::jobject* jlist) {
- mbgl::AnnotationSegment segment;
-
- NullCheck(*env, jlist);
- jni::jarray<jni::jobject>* jarray =
- reinterpret_cast<jni::jarray<jni::jobject>*>(jni::CallMethod<jni::jobject*>(*env, jlist, *listToArrayId));
-
- NullCheck(*env, jarray);
- std::size_t len = jni::GetArrayLength(*env, *jarray);
-
- segment.reserve(len);
-
- for (std::size_t i = 0; i < len; i++) {
- jni::jobject* latLng = reinterpret_cast<jni::jobject*>(jni::GetObjectArrayElement(*env, *jarray, i));
- NullCheck(*env, latLng);
-
- jdouble latitude = jni::GetField<jdouble>(*env, latLng, *latLngLatitudeId);
- jdouble longitude = jni::GetField<jdouble>(*env, latLng, *latLngLongitudeId);
-
- segment.push_back(mbgl::LatLng(latitude, longitude));
- jni::DeleteLocalRef(*env, latLng);
- }
-
- jni::DeleteLocalRef(*env, jarray);
- jarray = nullptr;
-
- return segment;
-}
-
static std::vector<uint8_t> metadata_from_java(JNIEnv* env, jni::jarray<jbyte>& j) {
mbgl::Log::Debug(mbgl::Event::JNI, "metadata_from_java");
std::size_t length = jni::GetArrayLength(*env, j);
@@ -756,6 +727,33 @@ static mbgl::Color toColor(jint color) {
return {{ r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f }};
}
+template <class Geometry>
+Geometry toGeometry(JNIEnv *env, jni::jobject* jlist) {
+ NullCheck(*env, jlist);
+ jni::jarray<jni::jobject>* jarray =
+ reinterpret_cast<jni::jarray<jni::jobject>*>(jni::CallMethod<jni::jobject*>(*env, jlist, *listToArrayId));
+ NullCheck(*env, jarray);
+
+ Geometry geometry;
+ geometry.reserve(jni::GetArrayLength(*env, *jarray));
+
+ for (std::size_t i = 0; i < geometry.size(); i++) {
+ jni::jobject* latLng = reinterpret_cast<jni::jobject*>(jni::GetObjectArrayElement(*env, *jarray, i));
+ NullCheck(*env, latLng);
+
+ geometry.push_back(mbgl::Point<double>(
+ jni::GetField<jdouble>(*env, latLng, *latLngLongitudeId),
+ jni::GetField<jdouble>(*env, latLng, *latLngLatitudeId)));
+
+ jni::DeleteLocalRef(*env, latLng);
+ }
+
+ jni::DeleteLocalRef(*env, jarray);
+ jni::DeleteLocalRef(*env, jlist);
+
+ return geometry;
+}
+
jni::jarray<jlong>* nativeAddPolylines(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray<jni::jobject>* jarray) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolylines");
assert(nativeMapViewPtr != 0);
@@ -776,10 +774,7 @@ jni::jarray<jlong>* nativeAddPolylines(JNIEnv *env, jni::jobject* obj, jlong nat
lineProperties.width = jni::GetField<jfloat>(*env, polyline, *polylineWidthId);
jni::jobject* points = jni::GetField<jni::jobject*>(*env, polyline, *polylinePointsId);
- mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points);
- jni::DeleteLocalRef(*env, points);
-
- shapes.emplace_back(mbgl::AnnotationSegments { segment }, lineProperties);
+ shapes.emplace_back(toGeometry<mbgl::LineString<double>>(env, points), lineProperties);
jni::DeleteLocalRef(*env, polyline);
}
@@ -807,10 +802,7 @@ jni::jarray<jlong>* nativeAddPolygons(JNIEnv *env, jni::jobject* obj, jlong nati
fillProperties.color = toColor(jni::GetField<jint>(*env, polygon, *polygonFillColorId));
jni::jobject* points = jni::GetField<jni::jobject*>(*env, polygon, *polygonPointsId);
- mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points);
- jni::DeleteLocalRef(*env, points);
-
- shapes.emplace_back(mbgl::AnnotationSegments { segment }, fillProperties);
+ shapes.emplace_back(mbgl::Polygon<double> { toGeometry<mbgl::LinearRing<double>>(env, points) }, fillProperties);
jni::DeleteLocalRef(*env, polygon);
}
@@ -899,17 +891,17 @@ void nativeSetVisibleCoordinateBounds(JNIEnv *env, jni::jobject* obj, jlong nati
std::size_t count = jni::GetArrayLength(*env, *coordinates);
mbgl::EdgeInsets mbglInsets = {top, left, bottom, right};
- mbgl::AnnotationSegment segment;
- segment.reserve(count);
+ std::vector<mbgl::LatLng> latLngs;
+ latLngs.reserve(count);
for (std::size_t i = 0; i < count; i++) {
jni::jobject* latLng = jni::GetObjectArrayElement(*env, *coordinates, i);
jdouble latitude = jni::GetField<jdouble>(*env, latLng, *latLngLatitudeId);
jdouble longitude = jni::GetField<jdouble>(*env, latLng, *latLngLongitudeId);
- segment.push_back(mbgl::LatLng(latitude, longitude));
+ latLngs.push_back(mbgl::LatLng(latitude, longitude));
}
- mbgl::CameraOptions cameraOptions = nativeMapView->getMap().cameraForLatLngs(segment, mbglInsets);
+ mbgl::CameraOptions cameraOptions = nativeMapView->getMap().cameraForLatLngs(latLngs, mbglInsets);
if (direction >= 0) {
// convert from degrees to radians
cameraOptions.angle = (-direction * M_PI) / 180;
diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm
index aaf8447274..b75cd68e7b 100644
--- a/platform/darwin/src/MGLMultiPoint.mm
+++ b/platform/darwin/src/MGLMultiPoint.mm
@@ -103,22 +103,6 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor) {
return MGLLatLngBoundsFromCoordinateBounds(_bounds).intersects(MGLLatLngBoundsFromCoordinateBounds(overlayBounds));
}
-- (mbgl::AnnotationSegments)annotationSegments {
- NSUInteger count = self.pointCount;
- CLLocationCoordinate2D *coordinates = self.coordinates;
-
- mbgl::AnnotationSegment segment;
- segment.reserve(count);
- for (NSUInteger i = 0; i < count; i++) {
- segment.push_back(MGLLatLngFromLocationCoordinate2D(coordinates[i]));
- }
- return { segment };
-}
-
-- (mbgl::ShapeAnnotation::Properties)shapeAnnotationPropertiesObjectWithDelegate:(__unused id <MGLMultiPointDelegate>)delegate {
- return mbgl::ShapeAnnotation::Properties();
-}
-
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>",
diff --git a/platform/darwin/src/MGLMultiPoint_Private.h b/platform/darwin/src/MGLMultiPoint_Private.h
index 2c1e0b7222..f7a7bd4ffd 100644
--- a/platform/darwin/src/MGLMultiPoint_Private.h
+++ b/platform/darwin/src/MGLMultiPoint_Private.h
@@ -21,11 +21,8 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds;
-/** Returns the shape’s annotation segments. */
-- (mbgl::AnnotationSegments)annotationSegments;
-
-/** Constructs a shape annotation properties object by asking the delegate for style values. */
-- (mbgl::ShapeAnnotation::Properties)shapeAnnotationPropertiesObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate;
+/** Constructs a shape annotation object, asking the delegate for style values. */
+- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate;
@end
diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm
index 5a24cb0791..47be070246 100644
--- a/platform/darwin/src/MGLPolygon.mm
+++ b/platform/darwin/src/MGLPolygon.mm
@@ -24,26 +24,31 @@
return self;
}
-- (mbgl::AnnotationSegments)annotationSegments {
- auto segments = super.annotationSegments;
- for (MGLPolygon *polygon in self.interiorPolygons) {
- auto interiorSegments = polygon.annotationSegments;
- segments.push_back(interiorSegments.front());
+- (mbgl::LinearRing<double>)ring {
+ NSUInteger count = self.pointCount;
+ CLLocationCoordinate2D *coordinates = self.coordinates;
+
+ mbgl::LinearRing<double> result;
+ result.reserve(self.pointCount);
+ for (NSUInteger i = 0; i < count; i++) {
+ result.push_back(mbgl::Point<double>(coordinates[i].longitude, coordinates[i].latitude));
}
- return segments;
+ return result;
}
-- (mbgl::ShapeAnnotation::Properties)shapeAnnotationPropertiesObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
- mbgl::ShapeAnnotation::Properties shapeProperties = [super shapeAnnotationPropertiesObjectWithDelegate:delegate];
-
+- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
mbgl::FillAnnotationProperties fillProperties;
fillProperties.opacity = [delegate alphaForShapeAnnotation:self];
fillProperties.outlineColor = [delegate strokeColorForShapeAnnotation:self];
fillProperties.color = [delegate fillColorForPolygonAnnotation:self];
-
- shapeProperties.set<mbgl::FillAnnotationProperties>(fillProperties);
-
- return shapeProperties;
+
+ mbgl::Polygon<double> geometry;
+ geometry.push_back(self.ring);
+ for (MGLPolygon *polygon in self.interiorPolygons) {
+ geometry.push_back(polygon.ring);
+ }
+
+ return mbgl::ShapeAnnotation(geometry, fillProperties);
}
@end
diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm
index 810b359bb0..ebba5c862e 100644
--- a/platform/darwin/src/MGLPolyline.mm
+++ b/platform/darwin/src/MGLPolyline.mm
@@ -13,17 +13,22 @@
return [[self alloc] initWithCoordinates:coords count:count];
}
-- (mbgl::ShapeAnnotation::Properties)shapeAnnotationPropertiesObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
- mbgl::ShapeAnnotation::Properties shapeProperties = [super shapeAnnotationPropertiesObjectWithDelegate:delegate];
-
+- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
mbgl::LineAnnotationProperties lineProperties;
lineProperties.opacity = [delegate alphaForShapeAnnotation:self];
lineProperties.color = [delegate strokeColorForShapeAnnotation:self];
lineProperties.width = [delegate lineWidthForPolylineAnnotation:self];
-
- shapeProperties.set<mbgl::LineAnnotationProperties>(lineProperties);
-
- return shapeProperties;
+
+ NSUInteger count = self.pointCount;
+ CLLocationCoordinate2D *coordinates = self.coordinates;
+
+ mbgl::LineString<double> geometry;
+ geometry.reserve(self.pointCount);
+ for (NSUInteger i = 0; i < count; i++) {
+ geometry.push_back(mbgl::Point<double>(coordinates[i].longitude, coordinates[i].latitude));
+ }
+
+ return mbgl::ShapeAnnotation(geometry, lineProperties);
}
@end
diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp
index f5fdb60df7..4a04595c33 100644
--- a/platform/default/glfw_view.cpp
+++ b/platform/default/glfw_view.cpp
@@ -208,12 +208,17 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
}
}
-mbgl::LatLng GLFWView::makeRandomPoint() const {
+mbgl::LatLng GLFWView::makeRandomLatLng() const {
const double x = width * double(std::rand()) / RAND_MAX;
const double y = height * double(std::rand()) / RAND_MAX;
return map->latLngForPixel({ x, y });
}
+mbgl::Point<double> GLFWView::makeRandomPoint() const {
+ mbgl::LatLng latLng = makeRandomLatLng();
+ return { latLng.longitude, latLng.latitude };
+}
+
std::shared_ptr<const mbgl::SpriteImage>
GLFWView::makeSpriteImage(int width, int height, float pixelRatio) {
const int r = 255 * (double(std::rand()) / RAND_MAX);
@@ -261,7 +266,7 @@ void GLFWView::addRandomCustomPointAnnotations(int count) {
const auto name = std::string{ "marker-" } + mbgl::util::toString(spriteID++);
map->addAnnotationIcon(name, makeSpriteImage(22, 22, 1));
spriteIDs.push_back(name);
- points.emplace_back(makeRandomPoint(), name);
+ points.emplace_back(makeRandomLatLng(), name);
}
auto newIDs = map->addPointAnnotations(points);
@@ -272,7 +277,7 @@ void GLFWView::addRandomPointAnnotations(int count) {
std::vector<mbgl::PointAnnotation> points;
for (int i = 0; i < count; i++) {
- points.emplace_back(makeRandomPoint(), "default_marker");
+ points.emplace_back(makeRandomLatLng(), "default_marker");
}
auto newIDs = map->addPointAnnotations(points);
@@ -286,15 +291,9 @@ void GLFWView::addRandomShapeAnnotations(int count) {
properties.opacity = .1;
for (int i = 0; i < count; i++) {
- mbgl::AnnotationSegment triangle;
- triangle.push_back(makeRandomPoint());
- triangle.push_back(makeRandomPoint());
- triangle.push_back(makeRandomPoint());
-
- mbgl::AnnotationSegments segments;
- segments.push_back(triangle);
-
- shapes.emplace_back(segments, properties);
+ mbgl::Polygon<double> triangle;
+ triangle.push_back({ makeRandomPoint(), makeRandomPoint(), makeRandomPoint() });
+ shapes.emplace_back(triangle, properties);
}
auto newIDs = map->addShapeAnnotations(shapes);
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index e5a65d42ea..eacd2f7b74 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -2309,14 +2309,14 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
[self willChangeValueForKey:@"visibleCoordinateBounds"];
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
- mbgl::AnnotationSegment segment;
- segment.reserve(count);
+ std::vector<mbgl::LatLng> latLngs;
+ latLngs.reserve(count);
for (NSUInteger i = 0; i < count; i++)
{
- segment.push_back({coordinates[i].latitude, coordinates[i].longitude});
+ latLngs.push_back({coordinates[i].latitude, coordinates[i].longitude});
}
- mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngs(segment, padding);
+ mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngs(latLngs, padding);
if (direction >= 0)
{
cameraOptions.angle = MGLRadiansFromDegrees(-direction);
@@ -2820,7 +2820,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
if (!multiPoint.pointCount) {
continue;
}
- shapes.emplace_back(multiPoint.annotationSegments, [multiPoint shapeAnnotationPropertiesObjectWithDelegate:self]);
+ shapes.emplace_back([multiPoint shapeAnnotationObjectWithDelegate:self]);
[userShapes addObject:annotation];
}
else if ([annotation isKindOfClass:[MGLMultiPolyline class]]
diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm
index c398a9424b..019f497649 100644
--- a/platform/osx/src/MGLMapView.mm
+++ b/platform/osx/src/MGLMapView.mm
@@ -1619,7 +1619,7 @@ public:
if (!multiPoint.pointCount) {
continue;
}
- shapes.emplace_back(multiPoint.annotationSegments, [multiPoint shapeAnnotationPropertiesObjectWithDelegate:self]);
+ shapes.emplace_back([multiPoint shapeAnnotationObjectWithDelegate:self]);
[userShapes addObject:annotation];
} else if ([annotation isKindOfClass:[MGLMultiPolyline class]]
|| [annotation isKindOfClass:[MGLMultiPolygon class]]
diff --git a/src/mbgl/annotation/shape_annotation_impl.cpp b/src/mbgl/annotation/shape_annotation_impl.cpp
index 76a237bfc2..a96c4eae72 100644
--- a/src/mbgl/annotation/shape_annotation_impl.cpp
+++ b/src/mbgl/annotation/shape_annotation_impl.cpp
@@ -80,33 +80,94 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
}
}
-void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTile& tile) {
- static const double baseTolerance = 4;
+struct ToGeoJSONVT {
+ const double tolerance;
- if (!shapeTiler) {
- const uint64_t maxAmountOfTiles = 1 << maxZoom;
- const double tolerance = baseTolerance / (maxAmountOfTiles * util::EXTENT);
+ ToGeoJSONVT(const double tolerance_)
+ : tolerance(tolerance_) {
+ }
- geojsonvt::ProjectedRings rings;
- for (auto& segment : shape.segments) {
- std::vector<geojsonvt::LonLat> points;
- for (auto& latLng : segment) {
- const double wrappedLongitude = util::wrap(latLng.longitude, -util::LONGITUDE_MAX, util::LONGITUDE_MAX);
- const double clampedLatitude = util::clamp(latLng.latitude, -util::LATITUDE_MAX, util::LATITUDE_MAX);
- points.push_back(geojsonvt::LonLat(wrappedLongitude, clampedLatitude));
- }
+ geojsonvt::ProjectedFeature operator()(const LineString<double>& line) const {
+ geojsonvt::ProjectedRings converted;
+ converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::Polygon, line));
+ return convertFeature(geojsonvt::ProjectedFeatureType::LineString, converted);
+ }
- if (type == geojsonvt::ProjectedFeatureType::Polygon &&
- (points.front().lon != points.back().lon || points.front().lat != points.back().lat)) {
- points.push_back(geojsonvt::LonLat(points.front().lon, points.front().lat));
+ geojsonvt::ProjectedFeature operator()(const Polygon<double>& polygon) const {
+ geojsonvt::ProjectedRings converted;
+ for (const auto& ring : polygon) {
+ converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::Polygon, ring));
+ }
+ return convertFeature(geojsonvt::ProjectedFeatureType::Polygon, converted);
+ }
+
+ geojsonvt::ProjectedFeature operator()(const MultiLineString<double>& lines) const {
+ geojsonvt::ProjectedRings converted;
+ for (const auto& line : lines) {
+ converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::LineString, line));
+ }
+ return convertFeature(geojsonvt::ProjectedFeatureType::LineString, converted);
+ }
+
+ geojsonvt::ProjectedFeature operator()(const MultiPolygon<double>& polygons) const {
+ geojsonvt::ProjectedRings converted;
+ for (const auto& polygon : polygons) {
+ for (const auto& ring : polygon) {
+ converted.push_back(convertPoints(geojsonvt::ProjectedFeatureType::Polygon, ring));
}
+ }
+ return convertFeature(geojsonvt::ProjectedFeatureType::Polygon, converted);
+ }
+
+ geojsonvt::ProjectedFeature operator()(const Point<double>&) {
+ throw std::runtime_error("unsupported shape annotation geometry type");
+ }
+
+ geojsonvt::ProjectedFeature operator()(const MultiPoint<double>&) {
+ throw std::runtime_error("unsupported shape annotation geometry type");
+ }
+
+ geojsonvt::ProjectedFeature operator()(const mapbox::geometry::geometry_collection<double>&) {
+ throw std::runtime_error("unsupported shape annotation geometry type");
+ }
+
+private:
+ geojsonvt::LonLat convertPoint(const Point<double>& p) const {
+ return {
+ util::wrap(p.x, -util::LONGITUDE_MAX, util::LONGITUDE_MAX),
+ util::clamp(p.y, -util::LATITUDE_MAX, util::LATITUDE_MAX)
+ };
+ }
- auto ring = geojsonvt::Convert::projectRing(points, tolerance);
- rings.push_back(ring);
+ geojsonvt::ProjectedRing convertPoints(geojsonvt::ProjectedFeatureType type, const std::vector<Point<double>>& points) const {
+ std::vector<geojsonvt::LonLat> converted;
+
+ for (const auto& p : points) {
+ converted.push_back(convertPoint(p));
+ }
+
+ if (type == geojsonvt::ProjectedFeatureType::Polygon && points.front() != points.back()) {
+ converted.push_back(converted.front());
}
- std::vector<geojsonvt::ProjectedFeature> features;
- features.push_back(geojsonvt::Convert::create(geojsonvt::Tags(), type, rings));
+ return geojsonvt::Convert::projectRing(converted, tolerance);
+ }
+
+ geojsonvt::ProjectedFeature convertFeature(geojsonvt::ProjectedFeatureType type, const geojsonvt::ProjectedRings& rings) const {
+ return geojsonvt::Convert::create(geojsonvt::Tags(), type, rings);
+ }
+};
+
+void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTile& tile) {
+ static const double baseTolerance = 4;
+
+ if (!shapeTiler) {
+ const uint64_t maxAmountOfTiles = 1 << maxZoom;
+ const double tolerance = baseTolerance / (maxAmountOfTiles * util::EXTENT);
+
+ std::vector<geojsonvt::ProjectedFeature> features = {
+ Geometry<double>::visit(shape.geometry, ToGeoJSONVT(tolerance))
+ };
mapbox::geojsonvt::Options options;
options.maxZoom = maxZoom;
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index b7b8b584ec..e0a73c2a06 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -481,13 +481,12 @@ void Map::setLatLngZoom(const LatLng& latLng, double zoom, optional<EdgeInsets>
}
CameraOptions Map::cameraForLatLngBounds(const LatLngBounds& bounds, optional<EdgeInsets> padding) const {
- AnnotationSegment segment = {
+ return cameraForLatLngs({
bounds.northwest(),
bounds.southwest(),
bounds.southeast(),
bounds.northeast(),
- };
- return cameraForLatLngs(segment, padding);
+ }, padding);
}
CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, optional<EdgeInsets> padding) const {
diff --git a/src/mbgl/util/geometry.hpp b/src/mbgl/util/geometry.hpp
index f9b91bcb39..6b9c332bf2 100644
--- a/src/mbgl/util/geometry.hpp
+++ b/src/mbgl/util/geometry.hpp
@@ -26,6 +26,9 @@ using MultiPolygon = mapbox::geometry::multi_polygon<T>;
template <class T>
using LinearRing = mapbox::geometry::linear_ring<T>;
+template <class T>
+using Geometry = mapbox::geometry::geometry<T>;
+
template <class S, class T>
Point<S> convertPoint(const Point<T>& p) {
return Point<S>(p.x, p.y);
diff --git a/test/api/annotations.cpp b/test/api/annotations.cpp
index f7554fb65e..3c73fb444c 100644
--- a/test/api/annotations.cpp
+++ b/test/api/annotations.cpp
@@ -54,13 +54,13 @@ TEST(Annotations, LineAnnotation) {
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
- AnnotationSegments segments = {{ {{ { 0, 0 }, { 45, 45 } }} }};
+ LineString<double> line = {{ { 0, 0 }, { 45, 45 } }};
LineAnnotationProperties properties;
properties.color = {{ 255, 0, 0, 1 }};
properties.width = 5;
- map.addShapeAnnotation(ShapeAnnotation(segments, properties));
+ map.addShapeAnnotation(ShapeAnnotation(line, properties));
checkRendering(map, "line_annotation");
}
@@ -75,12 +75,12 @@ TEST(Annotations, FillAnnotation) {
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
- AnnotationSegments segments = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
+ Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
FillAnnotationProperties properties;
properties.color = {{ 255, 0, 0, 1 }};
- map.addShapeAnnotation(ShapeAnnotation(segments, properties));
+ map.addShapeAnnotation(ShapeAnnotation(polygon, properties));
checkRendering(map, "fill_annotation");
}
@@ -95,9 +95,9 @@ TEST(Annotations, StyleSourcedShapeAnnotation) {
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/annotation.json"), "");
- AnnotationSegments segments = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
+ Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
- map.addShapeAnnotation(ShapeAnnotation(segments, "annotation"));
+ map.addShapeAnnotation(ShapeAnnotation(polygon, "annotation"));
checkRendering(map, "style_sourced_shape_annotation");
}
@@ -133,12 +133,12 @@ TEST(Annotations, NonImmediateAdd) {
test::render(map);
- AnnotationSegments segments = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
+ Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
FillAnnotationProperties properties;
properties.color = {{ 255, 0, 0, 1 }};
- map.addShapeAnnotation(ShapeAnnotation(segments, properties));
+ map.addShapeAnnotation(ShapeAnnotation(polygon, properties));
checkRendering(map, "non_immediate_add");
}
@@ -210,7 +210,7 @@ TEST(Annotations, RemoveShape) {
HeadlessView view(display, 1);
StubFileSource fileSource;
- AnnotationSegments segments = {{ {{ { 0, 0 }, { 45, 45 } }} }};
+ LineString<double> line = {{ { 0, 0 }, { 45, 45 } }};
LineAnnotationProperties properties;
properties.color = {{ 255, 0, 0, 1 }};
@@ -218,7 +218,7 @@ TEST(Annotations, RemoveShape) {
Map map(view, fileSource, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
- AnnotationID shape = map.addShapeAnnotation(ShapeAnnotation(segments, properties));
+ AnnotationID shape = map.addShapeAnnotation(ShapeAnnotation(line, properties));
test::render(map);
@@ -235,7 +235,7 @@ TEST(Annotations, ImmediateRemoveShape) {
StubFileSource fileSource;
Map map(view, fileSource, MapMode::Still);
- map.removeAnnotation(map.addShapeAnnotation(ShapeAnnotation({}, {})));
+ map.removeAnnotation(map.addShapeAnnotation(ShapeAnnotation(LineString<double>(), {})));
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
test::render(map);