From 0fba70d5a8465499b0dce900e5aa74f7189e4594 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 31 May 2016 17:34:11 -0700 Subject: [PATCH] [all] Rationalize annotation API --- include/mbgl/annotation/annotation.hpp | 41 +++++++++ include/mbgl/annotation/point_annotation.hpp | 18 ---- include/mbgl/annotation/shape_annotation.hpp | 37 -------- include/mbgl/map/map.hpp | 13 +-- include/mbgl/platform/default/glfw_view.hpp | 1 - {src => include}/mbgl/util/geometry.hpp | 0 platform/android/src/jni.cpp | 79 ++++++++-------- platform/darwin/src/MGLGeometry_Private.h | 5 ++ platform/darwin/src/MGLMultiPoint_Private.h | 4 +- platform/darwin/src/MGLPolygon.mm | 14 +-- platform/darwin/src/MGLPolyline.mm | 14 +-- platform/default/glfw_view.cpp | 40 ++------- platform/ios/src/MGLMapView.mm | 75 ++++------------ platform/osx/src/MGLMapView.mm | 80 ++++++----------- platform/qt/include/qmapbox.hpp | 2 - platform/qt/include/qmapboxgl.hpp | 4 - platform/qt/src/qmapboxgl.cpp | 63 ++----------- src/mbgl/annotation/annotation_manager.cpp | 89 +++++++++---------- src/mbgl/annotation/annotation_manager.hpp | 31 ++++--- src/mbgl/annotation/fill_annotation_impl.cpp | 36 ++++++++ src/mbgl/annotation/fill_annotation_impl.hpp | 19 ++++ src/mbgl/annotation/line_annotation_impl.cpp | 37 ++++++++ src/mbgl/annotation/line_annotation_impl.hpp | 19 ++++ src/mbgl/annotation/shape_annotation_impl.cpp | 80 ++--------------- src/mbgl/annotation/shape_annotation_impl.hpp | 18 ++-- .../style_sourced_annotation_impl.cpp | 38 ++++++++ .../style_sourced_annotation_impl.hpp | 19 ++++ ...on_impl.cpp => symbol_annotation_impl.cpp} | 19 ++-- ...on_impl.hpp => symbol_annotation_impl.hpp} | 21 ++--- src/mbgl/map/map.cpp | 30 ++----- test/api/annotations.cpp | 58 ++++++------ test/style/source.cpp | 2 + 32 files changed, 461 insertions(+), 545 deletions(-) delete mode 100644 include/mbgl/annotation/point_annotation.hpp delete mode 100644 include/mbgl/annotation/shape_annotation.hpp rename {src => include}/mbgl/util/geometry.hpp (100%) create mode 100644 src/mbgl/annotation/fill_annotation_impl.cpp create mode 100644 src/mbgl/annotation/fill_annotation_impl.hpp create mode 100644 src/mbgl/annotation/line_annotation_impl.cpp create mode 100644 src/mbgl/annotation/line_annotation_impl.hpp create mode 100644 src/mbgl/annotation/style_sourced_annotation_impl.cpp create mode 100644 src/mbgl/annotation/style_sourced_annotation_impl.hpp rename src/mbgl/annotation/{point_annotation_impl.cpp => symbol_annotation_impl.cpp} (55%) rename src/mbgl/annotation/{point_annotation_impl.hpp => symbol_annotation_impl.hpp} (68%) diff --git a/include/mbgl/annotation/annotation.hpp b/include/mbgl/annotation/annotation.hpp index 52916549c..3b2b7f3ad 100644 --- a/include/mbgl/annotation/annotation.hpp +++ b/include/mbgl/annotation/annotation.hpp @@ -1,11 +1,52 @@ #pragma once +#include + +#include +#include + #include #include +#include namespace mbgl { using AnnotationID = uint32_t; using AnnotationIDs = std::vector; +class SymbolAnnotation { +public: + Geometry geometry; + std::string icon; +}; + +class LineAnnotation { +public: + Geometry geometry; + float opacity = 1; + float width = 1; + Color color = {{ 0, 0, 0, 1 }}; +}; + +class FillAnnotation { +public: + Geometry geometry; + float opacity = 1; + Color color = {{ 0, 0, 0, 1 }}; + Color outlineColor = {{ 0, 0, 0, -1 }}; +}; + +// An annotation whose type and properties are sourced from a style layer. +class StyleSourcedAnnotation { +public: + Geometry geometry; + std::string layerID; +}; + +using Annotation = variant< + SymbolAnnotation, + LineAnnotation, + FillAnnotation, + StyleSourcedAnnotation>; + } // namespace mbgl diff --git a/include/mbgl/annotation/point_annotation.hpp b/include/mbgl/annotation/point_annotation.hpp deleted file mode 100644 index c9236c3c0..000000000 --- a/include/mbgl/annotation/point_annotation.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include - -namespace mbgl { - -class PointAnnotation { -public: - PointAnnotation(const LatLng& position_, const std::string& icon_ = "") - : position(position_.wrapped()), icon(icon_) {} - - const LatLng position; - const std::string icon; -}; - -} // namespace mbgl diff --git a/include/mbgl/annotation/shape_annotation.hpp b/include/mbgl/annotation/shape_annotation.hpp deleted file mode 100644 index 7dca1ec13..000000000 --- a/include/mbgl/annotation/shape_annotation.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -namespace mbgl { - -struct FillAnnotationProperties { - float opacity = 1; - Color color = {{ 0, 0, 0, 1 }}; - Color outlineColor = {{ 0, 0, 0, -1 }}; -}; - -struct LineAnnotationProperties { - float opacity = 1; - float width = 1; - Color color = {{ 0, 0, 0, 1 }}; -}; - -class ShapeAnnotation { -public: - using Properties = variant< - FillAnnotationProperties, // creates a fill annotation - LineAnnotationProperties, // creates a line annotation - std::string>; // creates an annotation whose type and properties are sourced from a style layer - - ShapeAnnotation(const Geometry& geometry_, const Properties& properties_) - : geometry(geometry_), properties(properties_) {} - - const Geometry geometry; - const Properties properties; -}; - -} // namespace mbgl diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index f074a5ae5..a728e2dd6 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -23,8 +23,6 @@ namespace mbgl { class FileSource; class View; class SpriteImage; -class PointAnnotation; -class ShapeAnnotation; struct CameraOptions; struct AnimationOptions; @@ -142,16 +140,9 @@ public: void removeAnnotationIcon(const std::string&); double getTopOffsetPixelsForAnnotationIcon(const std::string&); - AnnotationID addPointAnnotation(const PointAnnotation&); - AnnotationIDs addPointAnnotations(const std::vector&); - - AnnotationID addShapeAnnotation(const ShapeAnnotation&); - AnnotationIDs addShapeAnnotations(const std::vector&); - - void updatePointAnnotation(AnnotationID, const PointAnnotation&); - + AnnotationID addAnnotation(const Annotation&); + void updateAnnotation(AnnotationID, const Annotation&); void removeAnnotation(AnnotationID); - void removeAnnotations(const AnnotationIDs&); AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&); diff --git a/include/mbgl/platform/default/glfw_view.hpp b/include/mbgl/platform/default/glfw_view.hpp index b3b6116ad..b1204ce96 100644 --- a/include/mbgl/platform/default/glfw_view.hpp +++ b/include/mbgl/platform/default/glfw_view.hpp @@ -44,7 +44,6 @@ public: void report(float duration); private: - mbgl::LatLng makeRandomLatLng() const; mbgl::Point makeRandomPoint() const; static std::shared_ptr makeSpriteImage(int width, int height, float pixelRatio); diff --git a/src/mbgl/util/geometry.hpp b/include/mbgl/util/geometry.hpp similarity index 100% rename from src/mbgl/util/geometry.hpp rename to include/mbgl/util/geometry.hpp diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 4c3f77e9d..ed2563cf7 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -13,8 +13,7 @@ #include #include -#include -#include +#include #include #include #include @@ -681,8 +680,10 @@ void nativeUpdateMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble latitude = jni::GetField(*env, position, *latLngLatitudeId); jdouble longitude = jni::GetField(*env, position, *latLngLongitudeId); - // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long. - nativeMapView->getMap().updatePointAnnotation(markerId, mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), iconId)); + nativeMapView->getMap().updateAnnotation(markerId, mbgl::SymbolAnnotation { + mbgl::Point(longitude, latitude), + iconId + }); } jni::jarray* nativeAddMarkers(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray* jarray) { @@ -693,30 +694,30 @@ jni::jarray* nativeAddMarkers(JNIEnv *env, jni::jobject* obj, jlong nativ NullCheck(*env, jarray); std::size_t len = jni::GetArrayLength(*env, *jarray); - std::vector markers; - markers.reserve(len); + std::vector ids; + ids.reserve(len); for (std::size_t i = 0; i < len; i++) { jni::jobject* marker = jni::GetObjectArrayElement(*env, *jarray, i); jni::jobject* position = jni::GetField(*env, marker, *markerPositionId); jni::jobject* icon = jni::GetField(*env, marker, *markerIconId); - jni::DeleteLocalRef(*env, marker); - jni::jstring* jid = reinterpret_cast(jni::GetField(*env, icon, *iconIdId)); - jni::DeleteLocalRef(*env, icon); - - std::string id = std_string_from_jstring(env, jid); - jni::DeleteLocalRef(*env, jid); jdouble latitude = jni::GetField(*env, position, *latLngLatitudeId); jdouble longitude = jni::GetField(*env, position, *latLngLongitudeId); - jni::DeleteLocalRef(*env, position); - markers.emplace_back(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), id)); + ids.push_back(nativeMapView->getMap().addAnnotation(mbgl::SymbolAnnotation { + mbgl::Point(longitude, latitude), + std_string_from_jstring(env, jid) + })); + + jni::DeleteLocalRef(*env, position); + jni::DeleteLocalRef(*env, jid); + jni::DeleteLocalRef(*env, icon); + jni::DeleteLocalRef(*env, marker); } - std::vector pointAnnotationIDs = nativeMapView->getMap().addPointAnnotations(markers); - return std_vector_uint_to_jobject(env, pointAnnotationIDs); + return std_vector_uint_to_jobject(env, ids); } static mbgl::Color toColor(jint color) { @@ -762,24 +763,23 @@ jni::jarray* nativeAddPolylines(JNIEnv *env, jni::jobject* obj, jlong nat NullCheck(*env, jarray); std::size_t len = jni::GetArrayLength(*env, *jarray); - std::vector shapes; - shapes.reserve(len); + std::vector ids; + ids.reserve(len); for (std::size_t i = 0; i < len; i++) { jni::jobject* polyline = jni::GetObjectArrayElement(*env, *jarray, i); - - mbgl::LineAnnotationProperties lineProperties; - lineProperties.opacity = jni::GetField(*env, polyline, *polylineAlphaId); - lineProperties.color = toColor(jni::GetField(*env, polyline, *polylineColorId)); - lineProperties.width = jni::GetField(*env, polyline, *polylineWidthId); - jni::jobject* points = jni::GetField(*env, polyline, *polylinePointsId); - shapes.emplace_back(toGeometry>(env, points), lineProperties); + + mbgl::LineAnnotation annotation { toGeometry>(env, points) }; + annotation.opacity = jni::GetField(*env, polyline, *polylineAlphaId); + annotation.color = toColor(jni::GetField(*env, polyline, *polylineColorId)); + annotation.width = jni::GetField(*env, polyline, *polylineWidthId); + ids.push_back(nativeMapView->getMap().addAnnotation(annotation)); jni::DeleteLocalRef(*env, polyline); } - return std_vector_uint_to_jobject(env, nativeMapView->getMap().addShapeAnnotations(shapes)); + return std_vector_uint_to_jobject(env, ids); } jni::jarray* nativeAddPolygons(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray* jarray) { @@ -790,24 +790,23 @@ jni::jarray* nativeAddPolygons(JNIEnv *env, jni::jobject* obj, jlong nati NullCheck(*env, jarray); std::size_t len = jni::GetArrayLength(*env, *jarray); - std::vector shapes; - shapes.reserve(len); + std::vector ids; + ids.reserve(len); for (std::size_t i = 0; i < len; i++) { jni::jobject* polygon = jni::GetObjectArrayElement(*env, *jarray, i); - - mbgl::FillAnnotationProperties fillProperties; - fillProperties.opacity = jni::GetField(*env, polygon, *polygonAlphaId); - fillProperties.outlineColor = toColor(jni::GetField(*env, polygon, *polygonStrokeColorId)); - fillProperties.color = toColor(jni::GetField(*env, polygon, *polygonFillColorId)); - jni::jobject* points = jni::GetField(*env, polygon, *polygonPointsId); - shapes.emplace_back(mbgl::Polygon { toGeometry>(env, points) }, fillProperties); + + mbgl::FillAnnotation annotation { mbgl::Polygon { toGeometry>(env, points) } }; + annotation.opacity = jni::GetField(*env, polygon, *polygonAlphaId); + annotation.outlineColor = toColor(jni::GetField(*env, polygon, *polygonStrokeColorId)); + annotation.color = toColor(jni::GetField(*env, polygon, *polygonFillColorId)); + ids.push_back(nativeMapView->getMap().addAnnotation(annotation)); jni::DeleteLocalRef(*env, polygon); } - return std_vector_uint_to_jobject(env, nativeMapView->getMap().addShapeAnnotations(shapes)); + return std_vector_uint_to_jobject(env, ids); } void nativeRemoveAnnotations(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray* jarray) { @@ -817,20 +816,14 @@ void nativeRemoveAnnotations(JNIEnv *env, jni::jobject* obj, jlong nativeMapView NullCheck(*env, jarray); std::size_t len = jni::GetArrayLength(*env, *jarray); - - std::vector ids; - ids.reserve(len); - auto elements = jni::GetArrayElements(*env, *jarray); jlong* jids = std::get<0>(elements).get(); for (std::size_t i = 0; i < len; i++) { if(jids[i] == -1L) continue; - ids.push_back(static_cast(jids[i])); + nativeMapView->getMap().removeAnnotation(jids[i]); } - - nativeMapView->getMap().removeAnnotations(ids); } jni::jarray* nativeGetAnnotationsInBounds(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* latLngBounds_) { diff --git a/platform/darwin/src/MGLGeometry_Private.h b/platform/darwin/src/MGLGeometry_Private.h index 0538cd94e..fc5746012 100644 --- a/platform/darwin/src/MGLGeometry_Private.h +++ b/platform/darwin/src/MGLGeometry_Private.h @@ -6,6 +6,7 @@ #endif #import +#import /// Returns the smallest rectangle that contains both the given rectangle and /// the given point. @@ -15,6 +16,10 @@ NS_INLINE mbgl::LatLng MGLLatLngFromLocationCoordinate2D(CLLocationCoordinate2D return mbgl::LatLng(coordinate.latitude, coordinate.longitude); } +NS_INLINE mbgl::Point MGLPointFromLocationCoordinate2D(CLLocationCoordinate2D coordinate) { + return mbgl::Point(coordinate.longitude, coordinate.latitude); +} + NS_INLINE CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng) { return CLLocationCoordinate2DMake(latLng.latitude, latLng.longitude); } diff --git a/platform/darwin/src/MGLMultiPoint_Private.h b/platform/darwin/src/MGLMultiPoint_Private.h index f7a7bd4ff..aa52a02fc 100644 --- a/platform/darwin/src/MGLMultiPoint_Private.h +++ b/platform/darwin/src/MGLMultiPoint_Private.h @@ -3,7 +3,7 @@ #import "MGLGeometry.h" #import "MGLTypes.h" -#import +#import #import #import @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds; /** Constructs a shape annotation object, asking the delegate for style values. */ -- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id )delegate; +- (mbgl::Annotation)annotationObjectWithDelegate:(id )delegate; @end diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm index 47be07024..c009d9e3d 100644 --- a/platform/darwin/src/MGLPolygon.mm +++ b/platform/darwin/src/MGLPolygon.mm @@ -36,19 +36,19 @@ return result; } -- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id )delegate { - mbgl::FillAnnotationProperties fillProperties; - fillProperties.opacity = [delegate alphaForShapeAnnotation:self]; - fillProperties.outlineColor = [delegate strokeColorForShapeAnnotation:self]; - fillProperties.color = [delegate fillColorForPolygonAnnotation:self]; - +- (mbgl::Annotation)annotationObjectWithDelegate:(id )delegate { mbgl::Polygon geometry; geometry.push_back(self.ring); for (MGLPolygon *polygon in self.interiorPolygons) { geometry.push_back(polygon.ring); } - return mbgl::ShapeAnnotation(geometry, fillProperties); + mbgl::FillAnnotation annotation { geometry }; + annotation.opacity = [delegate alphaForShapeAnnotation:self]; + annotation.outlineColor = [delegate strokeColorForShapeAnnotation:self]; + annotation.color = [delegate fillColorForPolygonAnnotation:self]; + + return annotation; } @end diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm index ebba5c862..15ea5a095 100644 --- a/platform/darwin/src/MGLPolyline.mm +++ b/platform/darwin/src/MGLPolyline.mm @@ -13,12 +13,7 @@ return [[self alloc] initWithCoordinates:coords count:count]; } -- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id )delegate { - mbgl::LineAnnotationProperties lineProperties; - lineProperties.opacity = [delegate alphaForShapeAnnotation:self]; - lineProperties.color = [delegate strokeColorForShapeAnnotation:self]; - lineProperties.width = [delegate lineWidthForPolylineAnnotation:self]; - +- (mbgl::Annotation)annotationObjectWithDelegate:(id )delegate { NSUInteger count = self.pointCount; CLLocationCoordinate2D *coordinates = self.coordinates; @@ -28,7 +23,12 @@ geometry.push_back(mbgl::Point(coordinates[i].longitude, coordinates[i].latitude)); } - return mbgl::ShapeAnnotation(geometry, lineProperties); + mbgl::LineAnnotation annotation { geometry }; + annotation.opacity = [delegate alphaForShapeAnnotation:self]; + annotation.color = [delegate strokeColorForShapeAnnotation:self]; + annotation.width = [delegate lineWidthForPolylineAnnotation:self]; + + return annotation; } @end diff --git a/platform/default/glfw_view.cpp b/platform/default/glfw_view.cpp index 4a04595c3..2280c3f2a 100644 --- a/platform/default/glfw_view.cpp +++ b/platform/default/glfw_view.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include #include #include #include @@ -208,14 +207,10 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, } } -mbgl::LatLng GLFWView::makeRandomLatLng() const { +mbgl::Point GLFWView::makeRandomPoint() 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 GLFWView::makeRandomPoint() const { - mbgl::LatLng latLng = makeRandomLatLng(); + mbgl::LatLng latLng = map->latLngForPixel({ x, y }); return { latLng.longitude, latLng.latitude }; } @@ -259,53 +254,34 @@ void GLFWView::nextOrientation() { } void GLFWView::addRandomCustomPointAnnotations(int count) { - std::vector points; - for (int i = 0; i < count; i++) { static int spriteID = 1; const auto name = std::string{ "marker-" } + mbgl::util::toString(spriteID++); map->addAnnotationIcon(name, makeSpriteImage(22, 22, 1)); spriteIDs.push_back(name); - points.emplace_back(makeRandomLatLng(), name); + annotationIDs.push_back(map->addAnnotation(mbgl::SymbolAnnotation { makeRandomPoint(), name })); } - - auto newIDs = map->addPointAnnotations(points); - annotationIDs.insert(annotationIDs.end(), newIDs.begin(), newIDs.end()); } void GLFWView::addRandomPointAnnotations(int count) { - std::vector points; - for (int i = 0; i < count; i++) { - points.emplace_back(makeRandomLatLng(), "default_marker"); + annotationIDs.push_back(map->addAnnotation(mbgl::SymbolAnnotation { makeRandomPoint(), "default_marker" })); } - - auto newIDs = map->addPointAnnotations(points); - annotationIDs.insert(annotationIDs.end(), newIDs.begin(), newIDs.end()); } void GLFWView::addRandomShapeAnnotations(int count) { - std::vector shapes; - - mbgl::FillAnnotationProperties properties; - properties.opacity = .1; - for (int i = 0; i < count; i++) { mbgl::Polygon triangle; triangle.push_back({ makeRandomPoint(), makeRandomPoint(), makeRandomPoint() }); - shapes.emplace_back(triangle, properties); + annotationIDs.push_back(map->addAnnotation(mbgl::FillAnnotation { triangle, .1 })); } - - auto newIDs = map->addShapeAnnotations(shapes); - annotationIDs.insert(annotationIDs.end(), newIDs.begin(), newIDs.end()); } void GLFWView::clearAnnotations() { - if (annotationIDs.empty()) { - return; + for (const auto& id : annotationIDs) { + map->removeAnnotation(id); } - map->removeAnnotations(annotationIDs); annotationIDs.clear(); } diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index eacd2f7b7..87d821fba 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -7,8 +7,7 @@ #import #include -#include -#include +#include #include #include #include @@ -1776,9 +1775,9 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) // but safely updated. if (annotation == [self annotationWithTag:annotationTag]) { - const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate); + const mbgl::Point point = MGLPointFromLocationCoordinate2D(annotation.coordinate); MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag]; - _mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" }); + _mbglMap->updateAnnotation(annotationTag, mbgl::SymbolAnnotation { point, annotationImage.styleIconIdentifier.UTF8String ?: "" }); if (annotationTag == _selectedAnnotationTag) { [self deselectAnnotation:annotation animated:YES]; @@ -2796,11 +2795,6 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) if ( ! annotations) return; [self willChangeValueForKey:@"annotations"]; - NSMutableArray *userPoints = [NSMutableArray array]; - std::vector points; - NSMutableArray *userShapes = [NSMutableArray array]; - std::vector shapes; - NSMutableDictionary *annotationImagesForAnnotation = [NSMutableDictionary dictionary]; NSMutableDictionary *annotationViewsForAnnotation = [NSMutableDictionary dictionary]; @@ -2820,8 +2814,11 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) if (!multiPoint.pointCount) { continue; } - shapes.emplace_back([multiPoint shapeAnnotationObjectWithDelegate:self]); - [userShapes addObject:annotation]; + + MGLAnnotationTag annotationTag = _mbglMap->addAnnotation([multiPoint annotationObjectWithDelegate:self]); + MGLAnnotationContext context; + context.annotation = annotation; + _annotationContextsByAnnotationTag[annotationTag] = context; } else if ([annotation isKindOfClass:[MGLMultiPolyline class]] || [annotation isKindOfClass:[MGLMultiPolygon class]] @@ -2877,22 +2874,11 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) annotationImagesForAnnotation[annotationValue] = annotationImage; } - [userPoints addObject:annotation]; - points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName.UTF8String ?: ""); - } - } + MGLAnnotationTag annotationTag = _mbglMap->addAnnotation(mbgl::SymbolAnnotation { + MGLPointFromLocationCoordinate2D(annotation.coordinate), + symbolName.UTF8String ?: "" + }); - if (points.size()) - { - // refactor this to build contexts above and just associate with tags here - - std::vector annotationTags = _mbglMap->addPointAnnotations(points); - - for (size_t i = 0; i < annotationTags.size(); ++i) - { - id annotation = userPoints[i]; - NSValue *annotationValue = [NSValue valueWithNonretainedObject:annotation]; - MGLAnnotationContext context; context.annotation = annotation; MGLAnnotationImage *annotationImage = annotationImagesForAnnotation[annotationValue]; @@ -2900,13 +2886,11 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) if (annotationImage) { context.imageReuseIdentifier = annotationImage.reuseIdentifier; } - MGLAnnotationView *annotationView = annotationViewsForAnnotation[annotationValue]; if (annotationView) { context.annotationView = annotationView; context.viewReuseIdentifier = annotationView.reuseIdentifier; } - MGLAnnotationTag annotationTag = annotationTags[i]; _annotationContextsByAnnotationTag[annotationTag] = context; if ([annotation isKindOfClass:[NSObject class]]) { NSAssert(![annotation isKindOfClass:[MGLMultiPoint class]], @"Point annotation should not be MGLMultiPoint."); @@ -2915,21 +2899,6 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) } } - if (shapes.size()) - { - std::vector annotationTags = _mbglMap->addShapeAnnotations(shapes); - - for (size_t i = 0; i < annotationTags.size(); ++i) - { - MGLAnnotationTag annotationTag = annotationTags[i]; - id annotation = userShapes[i]; - - MGLAnnotationContext context; - context.annotation = annotation; - _annotationContextsByAnnotationTag[annotationTag] = context; - } - } - [self updateAnnotationContainerViewWithAnnotationViews:newAnnotationViews]; [self didChangeValueForKey:@"annotations"]; @@ -3072,8 +3041,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) { if ( ! annotations) return; - std::vector annotationTagsToRemove; - annotationTagsToRemove.reserve(annotations.count); + [self willChangeValueForKey:@"annotations"]; for (id annotation in annotations) { @@ -3088,8 +3056,6 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag); MGLAnnotationView *annotationView = annotationContext.annotationView; [annotationView removeFromSuperview]; - - annotationTagsToRemove.push_back(annotationTag); if (annotationTag == _selectedAnnotationTag) { @@ -3102,15 +3068,12 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) { [(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag]; } + + _mbglMap->removeAnnotation(annotationTag); } - if ( ! annotationTagsToRemove.empty()) - { - [self willChangeValueForKey:@"annotations"]; - _mbglMap->removeAnnotations(annotationTagsToRemove); - [self didChangeValueForKey:@"annotations"]; - UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); - } + [self didChangeValueForKey:@"annotations"]; + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil); } - (void)addOverlay:(id )overlay @@ -3675,8 +3638,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration) { if ([pair.second.imageReuseIdentifier isEqualToString:reuseIdentifier]) { - const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(pair.second.annotation.coordinate); - _mbglMap->updatePointAnnotation(pair.first, { latLng, iconIdentifier.UTF8String ?: "" }); + const mbgl::Point point = MGLPointFromLocationCoordinate2D(pair.second.annotation.coordinate); + _mbglMap->updateAnnotation(pair.first, mbgl::SymbolAnnotation { point, iconIdentifier.UTF8String ?: "" }); } } } diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm index 019f49764..03b94c25b 100644 --- a/platform/osx/src/MGLMapView.mm +++ b/platform/osx/src/MGLMapView.mm @@ -18,7 +18,7 @@ #import "MGLMapViewDelegate.h" #import -#import +#import #import #import #import @@ -481,9 +481,9 @@ public: // match a valid annotation tag, the annotation will be unnecessarily // but safely updated. if (annotation == [self annotationWithTag:annotationTag]) { - const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate); + const mbgl::Point point = MGLPointFromLocationCoordinate2D(annotation.coordinate); MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag]; - _mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" }); + _mbglMap->updateAnnotation(annotationTag, mbgl::SymbolAnnotation { point, annotationImage.styleIconIdentifier.UTF8String ?: "" }); if (annotationTag == _selectedAnnotationTag) { [self deselectAnnotation:annotation]; } @@ -1604,12 +1604,6 @@ public: BOOL delegateHasImagesForAnnotations = [self.delegate respondsToSelector:@selector(mapView:imageForAnnotation:)]; - NSMutableArray *userPoints = [NSMutableArray array]; - std::vector points; - NSMutableArray *userShapes = [NSMutableArray array]; - std::vector shapes; - NSMutableArray *annotationImages = [NSMutableArray arrayWithCapacity:annotations.count]; - for (id annotation in annotations) { NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation"); @@ -1619,8 +1613,11 @@ public: if (!multiPoint.pointCount) { continue; } - shapes.emplace_back([multiPoint shapeAnnotationObjectWithDelegate:self]); - [userShapes addObject:annotation]; + + MGLAnnotationTag annotationTag = _mbglMap->addAnnotation([multiPoint annotationObjectWithDelegate:self]); + MGLAnnotationContext context; + context.annotation = annotation; + _annotationContextsByAnnotationTag[annotationTag] = context; } else if ([annotation isKindOfClass:[MGLMultiPolyline class]] || [annotation isKindOfClass:[MGLMultiPolygon class]] || [annotation isKindOfClass:[MGLShapeCollection class]]) { @@ -1647,28 +1644,12 @@ public: self.annotationImagesByIdentifier[annotationImage.reuseIdentifier] = annotationImage; [self installAnnotationImage:annotationImage]; } - [annotationImages addObject:annotationImage]; - - [userPoints addObject:annotation]; - points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName.UTF8String ?: ""); - - // Opt into potentially expensive tooltip tracking areas. - if (annotation.toolTip.length) { - _wantsToolTipRects = YES; - } - } - } - - // Add any point annotations to mbgl and our own index. - if (points.size()) { - std::vector annotationTags = _mbglMap->addPointAnnotations(points); - - for (size_t i = 0; i < annotationTags.size(); ++i) { - MGLAnnotationTag annotationTag = annotationTags[i]; - MGLAnnotationImage *annotationImage = annotationImages[i]; - annotationImage.styleIconIdentifier = @(points[i].icon.c_str()); - id annotation = userPoints[i]; - + + MGLAnnotationTag annotationTag = _mbglMap->addAnnotation(mbgl::SymbolAnnotation { + MGLPointFromLocationCoordinate2D(annotation.coordinate), + symbolName.UTF8String ?: "" + }); + MGLAnnotationContext context; context.annotation = annotation; context.imageReuseIdentifier = annotationImage.reuseIdentifier; @@ -1678,23 +1659,14 @@ public: NSAssert(![annotation isKindOfClass:[MGLMultiPoint class]], @"Point annotation should not be MGLMultiPoint."); [(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:(void *)(NSUInteger)annotationTag]; } + + // Opt into potentially expensive tooltip tracking areas. + if (annotation.toolTip.length) { + _wantsToolTipRects = YES; + } } } - - // Add any shape annotations to mbgl and our own index. - if (shapes.size()) { - std::vector annotationTags = _mbglMap->addShapeAnnotations(shapes); - - for (size_t i = 0; i < annotationTags.size(); ++i) { - MGLAnnotationTag annotationTag = annotationTags[i]; - id annotation = userShapes[i]; - - MGLAnnotationContext context; - context.annotation = annotation; - _annotationContextsByAnnotationTag[annotationTag] = context; - } - } - + [self didChangeValueForKey:@"annotations"]; [self updateAnnotationTrackingAreas]; @@ -1765,16 +1737,14 @@ public: return; } - std::vector annotationTagsToRemove; - annotationTagsToRemove.reserve(annotations.count); - + [self willChangeValueForKey:@"annotations"]; + for (id annotation in annotations) { NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation"); MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation]; NSAssert(annotationTag != MGLAnnotationTagNotFound, @"No ID for annotation %@", annotation); - annotationTagsToRemove.push_back(annotationTag); - + if (annotationTag == _selectedAnnotationTag) { [self deselectAnnotation:annotation]; } @@ -1788,10 +1758,10 @@ public: ![annotation isKindOfClass:[MGLMultiPoint class]]) { [(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag]; } + + _mbglMap->removeAnnotation(annotationTag); } - [self willChangeValueForKey:@"annotations"]; - _mbglMap->removeAnnotations(annotationTagsToRemove); [self didChangeValueForKey:@"annotations"]; [self updateAnnotationTrackingAreas]; diff --git a/platform/qt/include/qmapbox.hpp b/platform/qt/include/qmapbox.hpp index f2cf363ea..3200da272 100644 --- a/platform/qt/include/qmapbox.hpp +++ b/platform/qt/include/qmapbox.hpp @@ -20,11 +20,9 @@ typedef quint32 AnnotationID; typedef QList AnnotationIDs; typedef QPair PointAnnotation; -typedef QList PointAnnotations; // FIXME: We need to add support for custom style properties typedef QPair ShapeAnnotation; -typedef QList ShapeAnnotations; enum NetworkMode { Online, // Default diff --git a/platform/qt/include/qmapboxgl.hpp b/platform/qt/include/qmapboxgl.hpp index 3b10dadc9..8ce6b02f4 100644 --- a/platform/qt/include/qmapboxgl.hpp +++ b/platform/qt/include/qmapboxgl.hpp @@ -165,15 +165,11 @@ public: QStringList getClasses() const; QMapbox::AnnotationID addPointAnnotation(const QMapbox::PointAnnotation &); - QMapbox::AnnotationIDs addPointAnnotations(const QMapbox::PointAnnotations &); - QMapbox::AnnotationID addShapeAnnotation(const QMapbox::ShapeAnnotation &); - QMapbox::AnnotationIDs addShapeAnnotations(const QMapbox::ShapeAnnotations &); void updatePointAnnotation(QMapbox::AnnotationID, const QMapbox::PointAnnotation &); void removeAnnotation(QMapbox::AnnotationID); - void removeAnnotations(const QMapbox::AnnotationIDs &); bool isRotating() const; bool isScaling() const; diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index 976da9a1e..1f8657c04 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -1,7 +1,6 @@ #include "qmapboxgl_p.hpp" -#include -#include +#include #include #include #include @@ -376,40 +375,23 @@ QStringList QMapboxGL::getClasses() const return classNames; } -mbgl::PointAnnotation fromPointAnnotation(const PointAnnotation &pointAnnotation) { +mbgl::Annotation fromPointAnnotation(const PointAnnotation &pointAnnotation) { const Coordinate &coordinate = pointAnnotation.first; const QString &icon = pointAnnotation.second; - return { { coordinate.first, coordinate.second }, icon.toStdString() }; + return mbgl::SymbolAnnotation { mbgl::Point { coordinate.second, coordinate.first }, icon.toStdString() }; } AnnotationID QMapboxGL::addPointAnnotation(const PointAnnotation &pointAnnotation) { - return d_ptr->mapObj->addPointAnnotation(fromPointAnnotation(pointAnnotation)); -} - -AnnotationIDs QMapboxGL::addPointAnnotations(const PointAnnotations &pointAnnotations) -{ - std::vector mbglPointAnnotations; - mbglPointAnnotations.reserve(pointAnnotations.size()); - - for (const PointAnnotation &pointAnnotation : pointAnnotations) { - mbglPointAnnotations.emplace_back(fromPointAnnotation(pointAnnotation)); - } - - AnnotationIDs ids; - for (const mbgl::AnnotationID &id : d_ptr->mapObj->addPointAnnotations(mbglPointAnnotations)) { - ids << id; - } - - return ids; + return d_ptr->mapObj->addAnnotation(fromPointAnnotation(pointAnnotation)); } void QMapboxGL::updatePointAnnotation(AnnotationID id, const PointAnnotation &pointAnnotation) { - d_ptr->mapObj->updatePointAnnotation(id, fromPointAnnotation(pointAnnotation)); + d_ptr->mapObj->updateAnnotation(id, fromPointAnnotation(pointAnnotation)); } -mbgl::ShapeAnnotation fromQMapboxGLShapeAnnotation(const ShapeAnnotation &shapeAnnotation) { +mbgl::Annotation fromQMapboxGLShapeAnnotation(const ShapeAnnotation &shapeAnnotation) { const CoordinateSegments &segments = shapeAnnotation.first; const QString &styleLayer = shapeAnnotation.second; @@ -427,29 +409,12 @@ mbgl::ShapeAnnotation fromQMapboxGLShapeAnnotation(const ShapeAnnotation &shapeA polygon.emplace_back(linearRing); } - return { polygon, styleLayer.toStdString() }; + return mbgl::StyleSourcedAnnotation { polygon, styleLayer.toStdString() }; } AnnotationID QMapboxGL::addShapeAnnotation(const ShapeAnnotation &shapeAnnotation) { - return d_ptr->mapObj->addShapeAnnotation(fromQMapboxGLShapeAnnotation(shapeAnnotation)); -} - -AnnotationIDs QMapboxGL::addShapeAnnotations(const ShapeAnnotations &shapeAnnotations) -{ - std::vector mbglShapeAnnotations; - mbglShapeAnnotations.reserve(shapeAnnotations.size()); - - for (const ShapeAnnotation &shapeAnnotation : shapeAnnotations) { - mbglShapeAnnotations.emplace_back(fromQMapboxGLShapeAnnotation(shapeAnnotation)); - } - - AnnotationIDs ids; - for (const mbgl::AnnotationID &id : d_ptr->mapObj->addShapeAnnotations(mbglShapeAnnotations)) { - ids << id; - } - - return ids; + return d_ptr->mapObj->addAnnotation(fromQMapboxGLShapeAnnotation(shapeAnnotation)); } void QMapboxGL::removeAnnotation(AnnotationID annotationID) @@ -457,18 +422,6 @@ void QMapboxGL::removeAnnotation(AnnotationID annotationID) d_ptr->mapObj->removeAnnotation(annotationID); } -void QMapboxGL::removeAnnotations(const AnnotationIDs &annotationIDs) -{ - std::vector mbglAnnotationIds; - mbglAnnotationIds.reserve(annotationIDs.size()); - - for (const AnnotationID annotationID : annotationIDs) { - mbglAnnotationIds.emplace_back(annotationID); - } - - d_ptr->mapObj->removeAnnotations(mbglAnnotationIds); -} - bool QMapboxGL::isRotating() const { return d_ptr->mapObj->isRotating(); diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index e5f43eb3b..4d7059f80 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -1,5 +1,9 @@ #include #include +#include +#include +#include +#include #include #include #include @@ -18,63 +22,54 @@ AnnotationManager::AnnotationManager(float pixelRatio) AnnotationManager::~AnnotationManager() = default; -AnnotationIDs -AnnotationManager::addPointAnnotations(const std::vector& points, const uint8_t) { - AnnotationIDs annotationIDs; - annotationIDs.reserve(points.size()); - - for (const auto& point : points) { - const uint32_t annotationID = nextID++; - auto annotation = std::make_shared(annotationID, point); - pointTree.insert(annotation); - pointAnnotations.emplace(annotationID, annotation); - annotationIDs.push_back(annotationID); - } - - return annotationIDs; +AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation, const uint8_t maxZoom) { + AnnotationID id = nextID++; + updateAnnotation(id, annotation, maxZoom); + return id; } -AnnotationIDs -AnnotationManager::addShapeAnnotations(const std::vector& shapes, const uint8_t maxZoom) { - AnnotationIDs annotationIDs; - annotationIDs.reserve(shapes.size()); - - for (const auto& shape : shapes) { - const uint32_t annotationID = nextID++; - shapeAnnotations.emplace(annotationID, - std::make_unique(annotationID, shape, maxZoom)); - annotationIDs.push_back(annotationID); - } - - return annotationIDs; +void AnnotationManager::updateAnnotation(const AnnotationID& id, const Annotation& annotation, const uint8_t maxZoom) { + removeAnnotation(id); + Annotation::visit(annotation, [&] (const auto& annotation_) { + this->add(id, annotation_, maxZoom); + }); } -void AnnotationManager::updatePointAnnotation(const AnnotationID& id, const PointAnnotation& point, const uint8_t) { - auto foundAnnotation = pointAnnotations.find(id); - if (foundAnnotation != pointAnnotations.end()) { - auto updatedAnnotation = std::make_shared(id, point); - pointTree.remove(foundAnnotation->second); - pointTree.insert(updatedAnnotation); - foundAnnotation->second = updatedAnnotation; +void AnnotationManager::removeAnnotation(const AnnotationID& id) { + if (symbolAnnotations.find(id) != symbolAnnotations.end()) { + symbolTree.remove(symbolAnnotations.at(id)); + symbolAnnotations.erase(id); + } else if (shapeAnnotations.find(id) != shapeAnnotations.end()) { + obsoleteShapeAnnotationLayers.push_back(shapeAnnotations.at(id)->layerID); + shapeAnnotations.erase(id); } } -void AnnotationManager::removeAnnotations(const AnnotationIDs& ids) { - for (const auto& id : ids) { - if (pointAnnotations.find(id) != pointAnnotations.end()) { - pointTree.remove(pointAnnotations.at(id)); - pointAnnotations.erase(id); - } else if (shapeAnnotations.find(id) != shapeAnnotations.end()) { - obsoleteShapeAnnotationLayers.push_back(shapeAnnotations.at(id)->layerID); - shapeAnnotations.erase(id); - } - } +void AnnotationManager::add(const AnnotationID& id, const SymbolAnnotation& annotation, const uint8_t) { + auto impl = std::make_shared(id, annotation); + symbolTree.insert(impl); + symbolAnnotations.emplace(id, impl); +} + +void AnnotationManager::add(const AnnotationID& id, const LineAnnotation& annotation, const uint8_t maxZoom) { + shapeAnnotations.emplace(id, + std::make_unique(id, annotation, maxZoom)); +} + +void AnnotationManager::add(const AnnotationID& id, const FillAnnotation& annotation, const uint8_t maxZoom) { + shapeAnnotations.emplace(id, + std::make_unique(id, annotation, maxZoom)); +} + +void AnnotationManager::add(const AnnotationID& id, const StyleSourcedAnnotation& annotation, const uint8_t maxZoom) { + shapeAnnotations.emplace(id, + std::make_unique(id, annotation, maxZoom)); } AnnotationIDs AnnotationManager::getPointAnnotationsInBounds(const LatLngBounds& bounds) const { AnnotationIDs result; - pointTree.query(boost::geometry::index::intersects(bounds), + symbolTree.query(boost::geometry::index::intersects(bounds), boost::make_function_output_iterator([&](const auto& val){ result.push_back(val->id); })); @@ -83,7 +78,7 @@ AnnotationIDs AnnotationManager::getPointAnnotationsInBounds(const LatLngBounds& } std::unique_ptr AnnotationManager::getTile(const CanonicalTileID& tileID) { - if (pointAnnotations.empty() && shapeAnnotations.empty()) + if (symbolAnnotations.empty() && shapeAnnotations.empty()) return nullptr; auto tile = std::make_unique(); @@ -94,7 +89,7 @@ std::unique_ptr AnnotationManager::getTile(const CanonicalTileID LatLngBounds tileBounds(tileID); - pointTree.query(boost::geometry::index::intersects(tileBounds), + symbolTree.query(boost::geometry::index::intersects(tileBounds), boost::make_function_output_iterator([&](const auto& val){ val->updateLayer(tileID, pointLayer); })); diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index aaa60278c..6862739eb 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -1,8 +1,7 @@ #pragma once #include -#include -#include +#include #include #include #include @@ -11,13 +10,14 @@ #include #include #include +#include namespace mbgl { -class PointAnnotation; -class ShapeAnnotation; class AnnotationTile; class AnnotationTileMonitor; +class SymbolAnnotationImpl; +class ShapeAnnotationImpl; class Style; class AnnotationManager : private util::noncopyable { @@ -25,10 +25,9 @@ public: AnnotationManager(float pixelRatio); ~AnnotationManager(); - AnnotationIDs addPointAnnotations(const std::vector&, const uint8_t maxZoom); - AnnotationIDs addShapeAnnotations(const std::vector&, const uint8_t maxZoom); - void updatePointAnnotation(const AnnotationID&, const PointAnnotation&, const uint8_t maxZoom); - void removeAnnotations(const AnnotationIDs&); + AnnotationID addAnnotation(const Annotation&, const uint8_t maxZoom); + void updateAnnotation(const AnnotationID&, const Annotation&, const uint8_t maxZoom); + void removeAnnotation(const AnnotationID&); AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&) const; @@ -46,12 +45,22 @@ public: static const std::string PointLayerID; private: + void add(const AnnotationID&, const SymbolAnnotation&, const uint8_t); + void add(const AnnotationID&, const LineAnnotation&, const uint8_t); + void add(const AnnotationID&, const FillAnnotation&, const uint8_t); + void add(const AnnotationID&, const StyleSourcedAnnotation&, const uint8_t); + std::unique_ptr getTile(const CanonicalTileID&); AnnotationID nextID = 0; - PointAnnotationImpl::Tree pointTree; - PointAnnotationImpl::Map pointAnnotations; - ShapeAnnotationImpl::Map shapeAnnotations; + + using SymbolAnnotationTree = boost::geometry::index::rtree, boost::geometry::index::rstar<16, 4>>; + using SymbolAnnotationMap = std::unordered_map>; + using ShapeAnnotationMap = std::unordered_map>; + + SymbolAnnotationTree symbolTree; + SymbolAnnotationMap symbolAnnotations; + ShapeAnnotationMap shapeAnnotations; std::vector obsoleteShapeAnnotationLayers; std::set monitors; diff --git a/src/mbgl/annotation/fill_annotation_impl.cpp b/src/mbgl/annotation/fill_annotation_impl.cpp new file mode 100644 index 000000000..2555f9043 --- /dev/null +++ b/src/mbgl/annotation/fill_annotation_impl.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +namespace mbgl { + +namespace geojsonvt = mapbox::geojsonvt; + +FillAnnotationImpl::FillAnnotationImpl(const AnnotationID id_, const FillAnnotation& annotation_, const uint8_t maxZoom_) + : ShapeAnnotationImpl(id_, maxZoom_), + annotation(annotation_) { +} + +void FillAnnotationImpl::updateStyle(Style& style) const { + if (style.getLayer(layerID)) + return; + + std::unique_ptr layer = std::make_unique(); + + layer->paint.fillOpacity = annotation.opacity; + layer->paint.fillColor = annotation.color; + layer->paint.fillOutlineColor = annotation.outlineColor; + + layer->id = layerID; + layer->source = AnnotationManager::SourceID; + layer->sourceLayer = layer->id; + + style.addLayer(std::move(layer), AnnotationManager::PointLayerID); +} + +const Geometry& FillAnnotationImpl::geometry() const { + return annotation.geometry; +} + +} // namespace mbgl diff --git a/src/mbgl/annotation/fill_annotation_impl.hpp b/src/mbgl/annotation/fill_annotation_impl.hpp new file mode 100644 index 000000000..1d98505c4 --- /dev/null +++ b/src/mbgl/annotation/fill_annotation_impl.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace mbgl { + +class FillAnnotationImpl : public ShapeAnnotationImpl { +public: + FillAnnotationImpl(const AnnotationID, const FillAnnotation&, const uint8_t maxZoom); + + void updateStyle(Style&) const final; + const Geometry& geometry() const final; + +private: + const FillAnnotation annotation; +}; + +} // namespace mbgl diff --git a/src/mbgl/annotation/line_annotation_impl.cpp b/src/mbgl/annotation/line_annotation_impl.cpp new file mode 100644 index 000000000..e22c36bcb --- /dev/null +++ b/src/mbgl/annotation/line_annotation_impl.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +namespace mbgl { + +namespace geojsonvt = mapbox::geojsonvt; + +LineAnnotationImpl::LineAnnotationImpl(const AnnotationID id_, const LineAnnotation& annotation_, const uint8_t maxZoom_) + : ShapeAnnotationImpl(id_, maxZoom_), + annotation(annotation_) { +} + +void LineAnnotationImpl::updateStyle(Style& style) const { + if (style.getLayer(layerID)) + return; + + std::unique_ptr layer = std::make_unique(); + layer->layout.lineJoin = LineJoinType::Round; + + layer->paint.lineOpacity = annotation.opacity; + layer->paint.lineWidth = annotation.width; + layer->paint.lineColor = annotation.color; + + layer->id = layerID; + layer->source = AnnotationManager::SourceID; + layer->sourceLayer = layer->id; + + style.addLayer(std::move(layer), AnnotationManager::PointLayerID); +} + +const Geometry& LineAnnotationImpl::geometry() const { + return annotation.geometry; +} + +} // namespace mbgl diff --git a/src/mbgl/annotation/line_annotation_impl.hpp b/src/mbgl/annotation/line_annotation_impl.hpp new file mode 100644 index 000000000..05a79fc0c --- /dev/null +++ b/src/mbgl/annotation/line_annotation_impl.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace mbgl { + +class LineAnnotationImpl : public ShapeAnnotationImpl { +public: + LineAnnotationImpl(const AnnotationID, const LineAnnotation&, const uint8_t maxZoom); + + void updateStyle(Style&) const final; + const Geometry& geometry() const final; + +private: + const LineAnnotation annotation; +}; + +} // namespace mbgl diff --git a/src/mbgl/annotation/shape_annotation_impl.cpp b/src/mbgl/annotation/shape_annotation_impl.cpp index a96c4eae7..a5116be72 100644 --- a/src/mbgl/annotation/shape_annotation_impl.cpp +++ b/src/mbgl/annotation/shape_annotation_impl.cpp @@ -1,83 +1,21 @@ #include #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include +#include +#include namespace mbgl { namespace geojsonvt = mapbox::geojsonvt; -ShapeAnnotationImpl::ShapeAnnotationImpl(const AnnotationID id_, - const ShapeAnnotation& shape_, - const uint8_t maxZoom_) -: id(id_), - layerID("com.mapbox.annotations.shape." + util::toString(id)), - shape(shape_), - maxZoom(maxZoom_) { -} - -void ShapeAnnotationImpl::updateStyle(Style& style) { - if (style.getLayer(layerID)) - return; - - if (shape.properties.is()) { - type = geojsonvt::ProjectedFeatureType::LineString; - - std::unique_ptr layer = std::make_unique(); - layer->layout.lineJoin = LineJoinType::Round; - - const LineAnnotationProperties& properties = shape.properties.get(); - layer->paint.lineOpacity = properties.opacity; - layer->paint.lineWidth = properties.width; - layer->paint.lineColor = properties.color; - - layer->id = layerID; - layer->source = AnnotationManager::SourceID; - layer->sourceLayer = layer->id; - - style.addLayer(std::move(layer), AnnotationManager::PointLayerID); - - } else if (shape.properties.is()) { - type = geojsonvt::ProjectedFeatureType::Polygon; - - std::unique_ptr layer = std::make_unique(); - - const FillAnnotationProperties& properties = shape.properties.get(); - layer->paint.fillOpacity = properties.opacity; - layer->paint.fillColor = properties.color; - layer->paint.fillOutlineColor = properties.outlineColor; - - layer->id = layerID; - layer->source = AnnotationManager::SourceID; - layer->sourceLayer = layer->id; - - style.addLayer(std::move(layer), AnnotationManager::PointLayerID); - - } else { - const StyleLayer* sourceLayer = style.getLayer(shape.properties.get()); - if (!sourceLayer) return; - - std::unique_ptr layer = sourceLayer->clone(); - - type = layer->is() - ? geojsonvt::ProjectedFeatureType::LineString - : geojsonvt::ProjectedFeatureType::Polygon; - - layer->id = layerID; - layer->ref = ""; - layer->source = AnnotationManager::SourceID; - layer->sourceLayer = layer->id; - layer->visibility = VisibilityType::Visible; - - style.addLayer(std::move(layer), sourceLayer->id); - } +ShapeAnnotationImpl::ShapeAnnotationImpl(const AnnotationID id_, const uint8_t maxZoom_) + : id(id_), + maxZoom(maxZoom_), + layerID("com.mapbox.annotations.shape." + util::toString(id)) { } struct ToGeoJSONVT { @@ -166,7 +104,7 @@ void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTi const double tolerance = baseTolerance / (maxAmountOfTiles * util::EXTENT); std::vector features = { - Geometry::visit(shape.geometry, ToGeoJSONVT(tolerance)) + Geometry::visit(geometry(), ToGeoJSONVT(tolerance)) }; mapbox::geojsonvt::Options options; diff --git a/src/mbgl/annotation/shape_annotation_impl.hpp b/src/mbgl/annotation/shape_annotation_impl.hpp index fb3ef2d89..f342c4b1f 100644 --- a/src/mbgl/annotation/shape_annotation_impl.hpp +++ b/src/mbgl/annotation/shape_annotation_impl.hpp @@ -3,12 +3,9 @@ #include #include -#include -#include -#include #include -#include +#include namespace mbgl { @@ -18,20 +15,17 @@ class CanonicalTileID; class ShapeAnnotationImpl { public: - using Map = std::map>; + ShapeAnnotationImpl(const AnnotationID, const uint8_t maxZoom); + virtual ~ShapeAnnotationImpl() = default; - ShapeAnnotationImpl(const AnnotationID, const ShapeAnnotation&, const uint8_t maxZoom); + virtual void updateStyle(Style&) const = 0; + virtual const Geometry& geometry() const = 0; - void updateStyle(Style&); void updateTile(const CanonicalTileID&, AnnotationTile&); const AnnotationID id; - const std::string layerID; - const ShapeAnnotation shape; - -private: const uint8_t maxZoom; - mapbox::geojsonvt::ProjectedFeatureType type; + const std::string layerID; std::unique_ptr shapeTiler; }; diff --git a/src/mbgl/annotation/style_sourced_annotation_impl.cpp b/src/mbgl/annotation/style_sourced_annotation_impl.cpp new file mode 100644 index 000000000..5d8f1f0da --- /dev/null +++ b/src/mbgl/annotation/style_sourced_annotation_impl.cpp @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +namespace mbgl { + +namespace geojsonvt = mapbox::geojsonvt; + +StyleSourcedAnnotationImpl::StyleSourcedAnnotationImpl(const AnnotationID id_, const StyleSourcedAnnotation& annotation_, const uint8_t maxZoom_) + : ShapeAnnotationImpl(id_, maxZoom_), + annotation(annotation_) { +} + +void StyleSourcedAnnotationImpl::updateStyle(Style& style) const { + if (style.getLayer(layerID)) + return; + + const StyleLayer* sourceLayer = style.getLayer(annotation.layerID); + if (!sourceLayer) + return; + + std::unique_ptr layer = sourceLayer->clone(); + + layer->id = layerID; + layer->ref = ""; + layer->source = AnnotationManager::SourceID; + layer->sourceLayer = layer->id; + layer->visibility = VisibilityType::Visible; + + style.addLayer(std::move(layer), sourceLayer->id); +} + +const Geometry& StyleSourcedAnnotationImpl::geometry() const { + return annotation.geometry; +} + +} // namespace mbgl diff --git a/src/mbgl/annotation/style_sourced_annotation_impl.hpp b/src/mbgl/annotation/style_sourced_annotation_impl.hpp new file mode 100644 index 000000000..734f6c829 --- /dev/null +++ b/src/mbgl/annotation/style_sourced_annotation_impl.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace mbgl { + +class StyleSourcedAnnotationImpl : public ShapeAnnotationImpl { +public: + StyleSourcedAnnotationImpl(const AnnotationID, const StyleSourcedAnnotation&, const uint8_t maxZoom); + + void updateStyle(Style&) const final; + const Geometry& geometry() const final; + +private: + const StyleSourcedAnnotation annotation; +}; + +} // namespace mbgl diff --git a/src/mbgl/annotation/point_annotation_impl.cpp b/src/mbgl/annotation/symbol_annotation_impl.cpp similarity index 55% rename from src/mbgl/annotation/point_annotation_impl.cpp rename to src/mbgl/annotation/symbol_annotation_impl.cpp index a1367f390..5ad6142ee 100644 --- a/src/mbgl/annotation/point_annotation_impl.cpp +++ b/src/mbgl/annotation/symbol_annotation_impl.cpp @@ -1,24 +1,29 @@ -#include +#include #include #include namespace mbgl { -PointAnnotationImpl::PointAnnotationImpl(const AnnotationID id_, const PointAnnotation& point_) +SymbolAnnotationImpl::SymbolAnnotationImpl(const AnnotationID id_, const SymbolAnnotation& annotation_) : id(id_), - point(point_) { + annotation(annotation_) { + if (!annotation.geometry.is>()) { + throw std::runtime_error("unsupported symbol annotation geometry type"); + } } -void PointAnnotationImpl::updateLayer(const CanonicalTileID& tileID, AnnotationTileLayer& layer) const { +void SymbolAnnotationImpl::updateLayer(const CanonicalTileID& tileID, AnnotationTileLayer& layer) const { std::unordered_map featureProperties; - featureProperties.emplace("sprite", point.icon.empty() ? std::string("default_marker") : point.icon); + featureProperties.emplace("sprite", annotation.icon.empty() ? std::string("default_marker") : annotation.icon); + + const Point& p = annotation.geometry.get>(); // Clamp to the latitude limits of Web Mercator. - const double constrainedLatitude = util::clamp(point.position.latitude, -util::LATITUDE_MAX, util::LATITUDE_MAX); + const double constrainedLatitude = util::clamp(p.y, -util::LATITUDE_MAX, util::LATITUDE_MAX); // Project a coordinate into unit space in a square map. const double sine = std::sin(constrainedLatitude * util::DEG2RAD); - const double x = point.position.longitude / util::DEGREES_MAX + 0.5; + const double x = p.x / util::DEGREES_MAX + 0.5; const double y = 0.5 - 0.25 * std::log((1.0 + sine) / (1.0 - sine)) / M_PI; Point projected(x, y); diff --git a/src/mbgl/annotation/point_annotation_impl.hpp b/src/mbgl/annotation/symbol_annotation_impl.hpp similarity index 68% rename from src/mbgl/annotation/point_annotation_impl.hpp rename to src/mbgl/annotation/symbol_annotation_impl.hpp index d8852fca9..43c490140 100644 --- a/src/mbgl/annotation/point_annotation_impl.hpp +++ b/src/mbgl/annotation/symbol_annotation_impl.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include @@ -36,31 +35,29 @@ namespace mbgl { class AnnotationTileLayer; class CanonicalTileID; -class PointAnnotationImpl { +class SymbolAnnotationImpl { public: - using Map = std::map>; - using Tree = boost::geometry::index::rtree, boost::geometry::index::rstar<16, 4>>; - - PointAnnotationImpl(const AnnotationID, const PointAnnotation&); + SymbolAnnotationImpl(const AnnotationID, const SymbolAnnotation&); void updateLayer(const CanonicalTileID&, AnnotationTileLayer&) const; const AnnotationID id; - const PointAnnotation point; + const SymbolAnnotation annotation; }; } // namespace mbgl -// Tell Boost Geometry how to access a std::shared_ptr object. +// Tell Boost Geometry how to access a std::shared_ptr object. namespace boost { namespace geometry { namespace index { template <> -struct indexable> { - using result_type = const mbgl::LatLng&; - inline const mbgl::LatLng& operator()(const std::shared_ptr& v) const { - return v->point.position; +struct indexable> { + using result_type = mbgl::LatLng; + inline mbgl::LatLng operator()(const std::shared_ptr& v) const { + const mbgl::Point& p = v->annotation.geometry.get>(); + return mbgl::LatLng(p.y, p.x); } }; diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index e0a73c2a0..f89fde1f0 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -3,8 +3,6 @@ #include #include #include -#include -#include #include #include #include @@ -693,37 +691,19 @@ double Map::getTopOffsetPixelsForAnnotationIcon(const std::string& name) { return impl->annotationManager->getTopOffsetPixelsForIcon(name); } -AnnotationID Map::addPointAnnotation(const PointAnnotation& annotation) { - return addPointAnnotations({ annotation }).front(); -} - -AnnotationIDs Map::addPointAnnotations(const std::vector& annotations) { - auto result = impl->annotationManager->addPointAnnotations(annotations, getMaxZoom()); +AnnotationID Map::addAnnotation(const Annotation& annotation) { + auto result = impl->annotationManager->addAnnotation(annotation, getMaxZoom()); update(Update::Annotations); return result; } -AnnotationID Map::addShapeAnnotation(const ShapeAnnotation& annotation) { - return addShapeAnnotations({ annotation }).front(); -} - -AnnotationIDs Map::addShapeAnnotations(const std::vector& annotations) { - auto result = impl->annotationManager->addShapeAnnotations(annotations, getMaxZoom()); - update(Update::Annotations); - return result; -} - -void Map::updatePointAnnotation(AnnotationID annotationId, const PointAnnotation& annotation) { - impl->annotationManager->updatePointAnnotation(annotationId, annotation, getMaxZoom()); +void Map::updateAnnotation(AnnotationID id, const Annotation& annotation) { + impl->annotationManager->updateAnnotation(id, annotation, getMaxZoom()); update(Update::Annotations); } void Map::removeAnnotation(AnnotationID annotation) { - removeAnnotations({ annotation }); -} - -void Map::removeAnnotations(const AnnotationIDs& annotations) { - impl->annotationManager->removeAnnotations(annotations); + impl->annotationManager->removeAnnotation(annotation); update(Update::Annotations); } diff --git a/test/api/annotations.cpp b/test/api/annotations.cpp index 3c73fb444..d2e2a63a5 100644 --- a/test/api/annotations.cpp +++ b/test/api/annotations.cpp @@ -1,8 +1,7 @@ #include #include -#include -#include +#include #include #include #include @@ -29,7 +28,7 @@ void checkRendering(Map& map, const char * name) { } // end namespace -TEST(Annotations, PointAnnotation) { +TEST(Annotations, SymbolAnnotation) { util::RunLoop loop; auto display = std::make_shared(); @@ -39,7 +38,7 @@ TEST(Annotations, PointAnnotation) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); map.addAnnotationIcon("default_marker", namedMarker("default_marker.png")); - map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker")); + map.addAnnotation(SymbolAnnotation { Point(0, 0), "default_marker" }); checkRendering(map, "point_annotation"); } @@ -56,11 +55,11 @@ TEST(Annotations, LineAnnotation) { LineString line = {{ { 0, 0 }, { 45, 45 } }}; - LineAnnotationProperties properties; - properties.color = {{ 255, 0, 0, 1 }}; - properties.width = 5; + LineAnnotation annotation { line }; + annotation.color = {{ 255, 0, 0, 1 }}; + annotation.width = 5; - map.addShapeAnnotation(ShapeAnnotation(line, properties)); + map.addAnnotation(annotation); checkRendering(map, "line_annotation"); } @@ -77,10 +76,10 @@ TEST(Annotations, FillAnnotation) { Polygon polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }}; - FillAnnotationProperties properties; - properties.color = {{ 255, 0, 0, 1 }}; + FillAnnotation annotation { polygon }; + annotation.color = {{ 255, 0, 0, 1 }}; - map.addShapeAnnotation(ShapeAnnotation(polygon, properties)); + map.addAnnotation(annotation); checkRendering(map, "fill_annotation"); } @@ -97,7 +96,7 @@ TEST(Annotations, StyleSourcedShapeAnnotation) { Polygon polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }}; - map.addShapeAnnotation(ShapeAnnotation(polygon, "annotation")); + map.addAnnotation(StyleSourcedAnnotation { polygon, "annotation" }); checkRendering(map, "style_sourced_shape_annotation"); } @@ -112,11 +111,11 @@ TEST(Annotations, AddMultiple) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); map.addAnnotationIcon("default_marker", namedMarker("default_marker.png")); - map.addPointAnnotation(PointAnnotation({ 0, -10 }, "default_marker")); + map.addAnnotation(SymbolAnnotation { Point { -10, 0 }, "default_marker" }); test::render(map); - map.addPointAnnotation(PointAnnotation({ 0, 10 }, "default_marker")); + map.addAnnotation(SymbolAnnotation { Point { 10, 0 }, "default_marker" }); checkRendering(map, "add_multiple"); } @@ -135,10 +134,10 @@ TEST(Annotations, NonImmediateAdd) { Polygon polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }}; - FillAnnotationProperties properties; - properties.color = {{ 255, 0, 0, 1 }}; + FillAnnotation annotation { polygon }; + annotation.color = {{ 255, 0, 0, 1 }}; - map.addShapeAnnotation(ShapeAnnotation(polygon, properties)); + map.addAnnotation(annotation); checkRendering(map, "non_immediate_add"); } @@ -153,7 +152,7 @@ TEST(Annotations, UpdateIcon) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); map.addAnnotationIcon("flipped_marker", namedMarker("default_marker.png")); - map.addPointAnnotation(PointAnnotation({ 0, 0 }, "flipped_marker")); + map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "flipped_marker" }); test::render(map); @@ -175,11 +174,11 @@ TEST(Annotations, UpdatePoint) { map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); map.addAnnotationIcon("default_marker", namedMarker("default_marker.png")); map.addAnnotationIcon("flipped_marker", namedMarker("flipped_marker.png")); - AnnotationID point = map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker")); + AnnotationID point = map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); test::render(map); - map.updatePointAnnotation(point, PointAnnotation({ 0, -10 }, "flipped_marker")); + map.updateAnnotation(point, SymbolAnnotation { Point { -10, 0 }, "flipped_marker" }); checkRendering(map, "update_point"); } @@ -194,7 +193,7 @@ TEST(Annotations, RemovePoint) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); map.addAnnotationIcon("default_marker", namedMarker("default_marker.png")); - AnnotationID point = map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker")); + AnnotationID point = map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); test::render(map); @@ -212,13 +211,13 @@ TEST(Annotations, RemoveShape) { LineString line = {{ { 0, 0 }, { 45, 45 } }}; - LineAnnotationProperties properties; - properties.color = {{ 255, 0, 0, 1 }}; - properties.width = 5; + LineAnnotation annotation { line }; + annotation.color = {{ 255, 0, 0, 1 }}; + annotation.width = 5; Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); - AnnotationID shape = map.addShapeAnnotation(ShapeAnnotation(line, properties)); + AnnotationID shape = map.addAnnotation(annotation); test::render(map); @@ -235,7 +234,7 @@ TEST(Annotations, ImmediateRemoveShape) { StubFileSource fileSource; Map map(view, fileSource, MapMode::Still); - map.removeAnnotation(map.addShapeAnnotation(ShapeAnnotation(LineString(), {}))); + map.removeAnnotation(map.addAnnotation(LineAnnotation { LineString() })); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); test::render(map); @@ -251,7 +250,7 @@ TEST(Annotations, SwitchStyle) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); map.addAnnotationIcon("default_marker", namedMarker("default_marker.png")); - map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker")); + map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); test::render(map); @@ -270,12 +269,11 @@ TEST(Annotations, QueryRenderedFeatures) { Map map(view, fileSource, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), ""); map.addAnnotationIcon("default_marker", namedMarker("default_marker.png")); - const LatLng latLng(0, 0); - map.addPointAnnotation(PointAnnotation(latLng, "default_marker")); + map.addAnnotation(SymbolAnnotation { Point { 0, 0 }, "default_marker" }); test::render(map); - auto point = map.pixelForLatLng(latLng); + auto point = map.pixelForLatLng({ 0, 0 }); auto features = map.queryRenderedFeatures(point); EXPECT_EQ(features.size(), 1); } diff --git a/test/style/source.cpp b/test/style/source.cpp index 622ec7ae7..5023a9efe 100644 --- a/test/style/source.cpp +++ b/test/style/source.cpp @@ -16,6 +16,8 @@ #include #include +#include + using namespace mbgl; class SourceTest {