diff options
-rw-r--r-- | include/mbgl/annotation/shape_annotation.hpp | 11 | ||||
-rw-r--r-- | include/mbgl/platform/default/glfw_view.hpp | 4 | ||||
-rwxr-xr-x | platform/android/src/jni.cpp | 74 | ||||
-rw-r--r-- | platform/darwin/src/MGLMultiPoint.mm | 16 | ||||
-rw-r--r-- | platform/darwin/src/MGLMultiPoint_Private.h | 7 | ||||
-rw-r--r-- | platform/darwin/src/MGLPolygon.mm | 31 | ||||
-rw-r--r-- | platform/darwin/src/MGLPolyline.mm | 19 | ||||
-rw-r--r-- | platform/default/glfw_view.cpp | 23 | ||||
-rw-r--r-- | platform/ios/src/MGLMapView.mm | 10 | ||||
-rw-r--r-- | platform/osx/src/MGLMapView.mm | 2 | ||||
-rw-r--r-- | src/mbgl/annotation/shape_annotation_impl.cpp | 101 | ||||
-rw-r--r-- | src/mbgl/map/map.cpp | 5 | ||||
-rw-r--r-- | src/mbgl/util/geometry.hpp | 3 | ||||
-rw-r--r-- | test/api/annotations.cpp | 22 |
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); |