diff --git a/src/mbgl/map/annotation.cpp b/src/mbgl/map/annotation.cpp index 917dc2f98..1252399b8 100644 --- a/src/mbgl/map/annotation.cpp +++ b/src/mbgl/map/annotation.cpp @@ -77,13 +77,14 @@ vec2 AnnotationManager::projectPoint(const LatLng& point) { return { x, y }; } -std::unordered_set -AnnotationManager::addShapeFeature(const uint32_t annotationID, - const AnnotationSegments& segments, - const StyleProperties& styleProperties, - const uint8_t maxZoom) { - // Currently unused. - std::unordered_set affectedTiles; +uint32_t +AnnotationManager::addShapeAnnotation(const ShapeAnnotation& shape, const uint8_t maxZoom) { + const uint32_t annotationID = nextID(); + + annotations.emplace(annotationID, std::make_unique( + AnnotationType::Shape, + shape.segments, + shape.styleProperties)); orderedShapeAnnotations.push_back(annotationID); @@ -99,14 +100,14 @@ AnnotationManager::addShapeFeature(const uint32_t annotationID, std::vector points; - for (size_t i = 0; i < segments[0].size(); ++i) { // first segment for now (no holes) - const double constraintedLatitude = ::fmin(::fmax(segments[0][i].latitude, -util::LATITUDE_MAX), util::LATITUDE_MAX); - points.push_back(LonLat(segments[0][i].longitude, constraintedLatitude)); + for (size_t i = 0; i < shape.segments[0].size(); ++i) { // first segment for now (no holes) + const double constraintedLatitude = ::fmin(::fmax(shape.segments[0][i].latitude, -util::LATITUDE_MAX), util::LATITUDE_MAX); + points.push_back(LonLat(shape.segments[0][i].longitude, constraintedLatitude)); } ProjectedFeatureType featureType; - if (styleProperties.is()) { + if (shape.styleProperties.is()) { featureType = ProjectedFeatureType::Polygon; if (points.front().lon != points.back().lon || points.front().lat != points.back().lat) { @@ -124,21 +125,31 @@ AnnotationManager::addShapeFeature(const uint32_t annotationID, shapeTilers.emplace(annotationID, std::make_unique(features, maxZoom, 4, 100, 10)); - return affectedTiles; + return annotationID; } -std::unordered_set -AnnotationManager::addPointFeature(const uint32_t annotationID, - const std::vector>>& projectedFeature, - const std::unordered_map& featureProperties, - const uint8_t maxZoom) { - std::unordered_set affectedTiles; +uint32_t +AnnotationManager::addPointAnnotation(const PointAnnotation& point, const uint8_t maxZoom, + std::unordered_set& affectedTiles) { + const uint32_t annotationID = nextID(); - auto anno_it = annotations.find(annotationID); - assert(anno_it != annotations.end()); + // at render time we style the point according to its {sprite} field + std::unordered_map featureProperties; + if (point.icon.length()) { + featureProperties.emplace("sprite", point.icon); + } else { + featureProperties.emplace("sprite", defaultPointAnnotationSymbol); + } + + std::unique_ptr annotation = std::make_unique( + AnnotationType::Point, + AnnotationSegments({{ point.position }}), + StyleProperties({{ }})); const uint16_t extent = 4096; - auto& pp = projectedFeature[0][0]; + + // projection conversion into unit space + vec2 pp = projectPoint(point.position); for (int8_t z = maxZoom; z >= 0; z--) { uint32_t z2 = 1 << z; @@ -176,16 +187,18 @@ AnnotationManager::addPointFeature(const uint32_t annotationID, // Record annotation association with tile and tile feature. This is used to determine stale tiles, // as well as to remove the feature from the tile upon annotation deletion. - anno_it->second->tilePointFeatures.emplace(featureTileID, std::weak_ptr(feature)); + annotation->tilePointFeatures.emplace(featureTileID, std::weak_ptr(feature)); // track affected tile affectedTiles.insert(featureTileID); } - return affectedTiles; + annotations.emplace(annotationID, std::move(annotation)); + + return annotationID; } -std::pair, AnnotationIDs> +std::pair AnnotationManager::addPointAnnotations(const std::vector& points, const uint8_t maxZoom) { // We pre-generate tiles to contain each annotation up to the map's max zoom. @@ -197,43 +210,17 @@ AnnotationManager::addPointAnnotations(const std::vector& point AnnotationIDs annotationIDs; annotationIDs.reserve(points.size()); - std::unordered_set affectedTiles; + AffectedTiles affectedTiles; - for (const PointAnnotation& point : points) { - // projection conversion into unit space - const auto pp = projectPoint(point.position); - const uint32_t pointAnnotationID = nextID(); - - // at render time we style the point according to its {sprite} field - std::unordered_map pointFeatureProperties; - if (point.icon.length()) { - pointFeatureProperties.emplace("sprite", point.icon); - } else { - pointFeatureProperties.emplace("sprite", defaultPointAnnotationSymbol); - } - - // track the annotation global ID and its original geometry - annotations.emplace(pointAnnotationID, std::make_unique( - AnnotationType::Point, - AnnotationSegments({{ point.position }}), - StyleProperties({{ }}))); - - auto featureAffectedTiles = addPointFeature( - pointAnnotationID, - std::vector>>({{ pp }}), - pointFeatureProperties, - maxZoom); - - std::copy(featureAffectedTiles.begin(), featureAffectedTiles.end(), std::inserter(affectedTiles, affectedTiles.begin())); - - annotationIDs.push_back(pointAnnotationID); + for (const auto& point : points) { + annotationIDs.push_back(addPointAnnotation(point, maxZoom, affectedTiles)); } // Tile:IDs that need refreshed and the annotation identifiers held onto by the client. return std::make_pair(affectedTiles, annotationIDs); } -std::pair, AnnotationIDs> +std::pair AnnotationManager::addShapeAnnotations(const std::vector& shapes, const uint8_t maxZoom) { // We pre-generate tiles to contain each annotation up to the map's max zoom. @@ -245,27 +232,14 @@ AnnotationManager::addShapeAnnotations(const std::vector& shape AnnotationIDs annotationIDs; annotationIDs.reserve(shapes.size()); - std::unordered_set affectedTiles; - - for (const ShapeAnnotation& shape : shapes) { - const uint32_t shapeAnnotationID = nextID(); - - // current shape tiles are on-the-fly, so we don't get any "affected tiles" - // and just expire all annotation tiles for shape adds - - // track the annotation global ID and its original geometry - annotations.emplace(shapeAnnotationID, std::make_unique( - AnnotationType::Shape, - shape.segments, - shape.styleProperties)); - - addShapeFeature(shapeAnnotationID, shape.segments, shape.styleProperties, maxZoom); - - annotationIDs.push_back(shapeAnnotationID); + for (const auto& shape : shapes) { + annotationIDs.push_back(addShapeAnnotation(shape, maxZoom)); } // Tile:IDs that need refreshed and the annotation identifiers held onto by the client. - return std::make_pair(affectedTiles, annotationIDs); + // Shapes are tiled "on-the-fly", so we don't get any "affected tiles" and just expire + // all annotation tiles for shape adds. + return std::make_pair(AffectedTiles(), annotationIDs); } std::unordered_set AnnotationManager::removeAnnotations(const AnnotationIDs& ids, diff --git a/src/mbgl/map/annotation.hpp b/src/mbgl/map/annotation.hpp index ddae05b6f..6f76b697f 100644 --- a/src/mbgl/map/annotation.hpp +++ b/src/mbgl/map/annotation.hpp @@ -48,6 +48,8 @@ private: class AnnotationManager : private util::noncopyable { public: + typedef std::unordered_set AffectedTiles; + AnnotationManager(); ~AnnotationManager(); @@ -57,15 +59,15 @@ public: void setDefaultPointAnnotationSymbol(const std::string& symbol); - std::pair, AnnotationIDs> - addPointAnnotations(const std::vector&, - const uint8_t maxZoom); + std::pair + addPointAnnotations(const std::vector&, const uint8_t maxZoom); - std::pair, AnnotationIDs> - addShapeAnnotations(const std::vector&, - const uint8_t maxZoom); + std::pair + addShapeAnnotations(const std::vector&, const uint8_t maxZoom); + + AffectedTiles + removeAnnotations(const AnnotationIDs&, const uint8_t maxZoom); - std::unordered_set removeAnnotations(const AnnotationIDs&, const uint8_t maxZoom); AnnotationIDs getOrderedShapeAnnotations() const { return orderedShapeAnnotations; } const StyleProperties getAnnotationStyleProperties(uint32_t) const; @@ -81,17 +83,8 @@ private: inline uint32_t nextID(); static vec2 projectPoint(const LatLng& point); - std::unordered_set - addShapeFeature(const uint32_t annotationID, - const AnnotationSegments& segments, - const StyleProperties& styleProperties, - const uint8_t maxZoom); - - std::unordered_set - addPointFeature(const uint32_t annotationID, - const std::vector>>& projectedFeature, - const std::unordered_map& featureProperties, - const uint8_t maxZoom); + uint32_t addShapeAnnotation(const ShapeAnnotation&, const uint8_t maxZoom); + uint32_t addPointAnnotation(const PointAnnotation&, const uint8_t maxZoom, AffectedTiles&); private: std::string defaultPointAnnotationSymbol;