diff options
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/annotation/annotation_manager.cpp | 107 | ||||
-rw-r--r-- | src/mbgl/annotation/annotation_manager.hpp | 18 | ||||
-rw-r--r-- | src/mbgl/map/map_impl.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/map/map_impl.hpp | 3 |
4 files changed, 78 insertions, 60 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index b5dfea8e1a..c4d9f3fb8e 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -4,6 +4,7 @@ #include <mbgl/annotation/fill_annotation_impl.hpp> #include <mbgl/annotation/line_annotation_impl.hpp> #include <mbgl/annotation/symbol_annotation_impl.hpp> + #include <mbgl/layermanager/layer_manager.hpp> #include <mbgl/style/expression/dsl.hpp> #include <mbgl/style/expression/image.hpp> @@ -31,10 +32,27 @@ const std::string AnnotationManager::SourceID = "com.mapbox.annotations"; const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points"; const std::string AnnotationManager::ShapeLayerID = "com.mapbox.annotations.shape."; -AnnotationManager::AnnotationManager(Style& style_) - : style(style_) { +class AnnotationManager::Impl : private util::noncopyable { +public: + using SymbolAnnotationTree = boost::geometry::index::rtree<std::shared_ptr<const SymbolAnnotationImpl>, + boost::geometry::index::rstar<16, 4>>; + // Unlike std::unordered_map, std::map is guaranteed to sort by AnnotationID, ensuring that older annotations are + // below newer annotations. <https://github.com/mapbox/mapbox-gl-native/issues/5691> + using SymbolAnnotationMap = std::map<AnnotationID, std::shared_ptr<SymbolAnnotationImpl>>; + using ShapeAnnotationMap = std::map<AnnotationID, std::unique_ptr<ShapeAnnotationImpl>>; + using ImageMap = std::unordered_map<std::string, style::Image>; + + SymbolAnnotationTree symbolTree; + SymbolAnnotationMap symbolAnnotations; + ShapeAnnotationMap shapeAnnotations; + ImageMap images; + + std::unordered_set<AnnotationTile*> tiles; }; + +AnnotationManager::AnnotationManager(Style& style_) : style(style_), impl(std::make_unique<Impl>()){}; + AnnotationManager::~AnnotationManager() = default; void AnnotationManager::setStyle(Style& style_) { @@ -75,26 +93,28 @@ void AnnotationManager::removeAnnotation(const AnnotationID& id) { } void AnnotationManager::add(const AnnotationID& id, const SymbolAnnotation& annotation) { - auto impl = std::make_shared<SymbolAnnotationImpl>(id, annotation); - symbolTree.insert(impl); - symbolAnnotations.emplace(id, impl); + auto impl_ = std::make_shared<SymbolAnnotationImpl>(id, annotation); + AnnotationManager::impl->symbolTree.insert(impl_); + AnnotationManager::impl->symbolAnnotations.emplace(id, impl_); } void AnnotationManager::add(const AnnotationID& id, const LineAnnotation& annotation) { - ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id, - std::make_unique<LineAnnotationImpl>(id, annotation)).first->second; - impl.updateStyle(*style.get().impl); + ShapeAnnotationImpl& impl_ = + *AnnotationManager::impl->shapeAnnotations.emplace(id, std::make_unique<LineAnnotationImpl>(id, annotation)) + .first->second; + impl_.updateStyle(*style.get().impl); } void AnnotationManager::add(const AnnotationID& id, const FillAnnotation& annotation) { - ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id, - std::make_unique<FillAnnotationImpl>(id, annotation)).first->second; - impl.updateStyle(*style.get().impl); + ShapeAnnotationImpl& impl_ = + *AnnotationManager::impl->shapeAnnotations.emplace(id, std::make_unique<FillAnnotationImpl>(id, annotation)) + .first->second; + impl_.updateStyle(*style.get().impl); } void AnnotationManager::update(const AnnotationID& id, const SymbolAnnotation& annotation) { - auto it = symbolAnnotations.find(id); - if (it == symbolAnnotations.end()) { + auto it = AnnotationManager::impl->symbolAnnotations.find(id); + if (it == AnnotationManager::impl->symbolAnnotations.end()) { assert(false); // Attempt to update a non-existent symbol annotation return; } @@ -110,45 +130,45 @@ void AnnotationManager::update(const AnnotationID& id, const SymbolAnnotation& a } void AnnotationManager::update(const AnnotationID& id, const LineAnnotation& annotation) { - auto it = shapeAnnotations.find(id); - if (it == shapeAnnotations.end()) { + auto it = AnnotationManager::impl->shapeAnnotations.find(id); + if (it == AnnotationManager::impl->shapeAnnotations.end()) { assert(false); // Attempt to update a non-existent shape annotation return; } - shapeAnnotations.erase(it); + AnnotationManager::impl->shapeAnnotations.erase(it); add(id, annotation); dirty = true; } void AnnotationManager::update(const AnnotationID& id, const FillAnnotation& annotation) { - auto it = shapeAnnotations.find(id); - if (it == shapeAnnotations.end()) { + auto it = AnnotationManager::impl->shapeAnnotations.find(id); + if (it == AnnotationManager::impl->shapeAnnotations.end()) { assert(false); // Attempt to update a non-existent shape annotation return; } - shapeAnnotations.erase(it); + AnnotationManager::impl->shapeAnnotations.erase(it); add(id, annotation); dirty = true; } void AnnotationManager::remove(const AnnotationID& id) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); - if (symbolAnnotations.find(id) != symbolAnnotations.end()) { - symbolTree.remove(symbolAnnotations.at(id)); - symbolAnnotations.erase(id); - } else if (shapeAnnotations.find(id) != shapeAnnotations.end()) { - auto it = shapeAnnotations.find(id); + if (AnnotationManager::impl->symbolAnnotations.find(id) != AnnotationManager::impl->symbolAnnotations.end()) { + AnnotationManager::impl->symbolTree.remove(AnnotationManager::impl->symbolAnnotations.at(id)); + AnnotationManager::impl->symbolAnnotations.erase(id); + } else if (AnnotationManager::impl->shapeAnnotations.find(id) != AnnotationManager::impl->shapeAnnotations.end()) { + auto it = AnnotationManager::impl->shapeAnnotations.find(id); *style.get().impl->removeLayer(it->second->layerID); - shapeAnnotations.erase(it); + AnnotationManager::impl->shapeAnnotations.erase(it); } else { assert(false); // Should never happen } } std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const CanonicalTileID& tileID) { - if (symbolAnnotations.empty() && shapeAnnotations.empty()) + if (AnnotationManager::impl->symbolAnnotations.empty() && AnnotationManager::impl->shapeAnnotations.empty()) return nullptr; auto tileData = std::make_unique<AnnotationTileData>(); @@ -162,13 +182,12 @@ std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const Canonic // The rendering/querying logic will make sure the symbols show up in only one of the tiles tileBounds.extend(LatLng(tileBounds.south() - 0.000000001, tileBounds.west() - 0.000000001)); tileBounds.extend(LatLng(tileBounds.north() + 0.000000001, tileBounds.east() + 0.000000001)); - - symbolTree.query(boost::geometry::index::intersects(tileBounds), - boost::make_function_output_iterator([&](const auto& val){ - val->updateLayer(tileID, *pointLayer); - })); - for (const auto& shape : shapeAnnotations) { + AnnotationManager::impl->symbolTree.query( + boost::geometry::index::intersects(tileBounds), + boost::make_function_output_iterator([&](const auto& val) { val->updateLayer(tileID, *pointLayer); })); + + for (const auto& shape : AnnotationManager::impl->shapeAnnotations) { shape.second->updateTileData(tileID, *tileData); } @@ -195,11 +214,11 @@ void AnnotationManager::updateStyle() { std::lock_guard<std::mutex> lock(mutex); - for (const auto& shape : shapeAnnotations) { + for (const auto& shape : AnnotationManager::impl->shapeAnnotations) { shape.second->updateStyle(*style.get().impl); } - for (const auto& image : images) { + for (const auto& image : AnnotationManager::impl->images) { // Call addImage even for images we may have previously added, because we must support // addAnnotationImage being used to update an existing image. Creating a new image is // relatively cheap, as it copies only the Immutable reference. (We can't keep track @@ -214,7 +233,7 @@ void AnnotationManager::updateData() { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard<std::mutex> lock(mutex); if (dirty) { - for (auto& tile : tiles) { + for (auto& tile : AnnotationManager::impl->tiles) { tile->setData(getTileData(tile->id.canonical)); } dirty = false; @@ -224,14 +243,14 @@ void AnnotationManager::updateData() { void AnnotationManager::addTile(AnnotationTile& tile) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard<std::mutex> lock(mutex); - tiles.insert(&tile); + AnnotationManager::impl->tiles.insert(&tile); tile.setData(getTileData(tile.id.canonical)); } void AnnotationManager::removeTile(AnnotationTile& tile) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard<std::mutex> lock(mutex); - tiles.erase(&tile); + AnnotationManager::impl->tiles.erase(&tile); } // To ensure that annotation images do not collide with images from the style, @@ -244,9 +263,9 @@ void AnnotationManager::addImage(std::unique_ptr<style::Image> image) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard<std::mutex> lock(mutex); const std::string id = prefixedImageID(image->getID()); - images.erase(id); - auto inserted = images.emplace(id, style::Image(id, image->getImage().clone(), - image->getPixelRatio(), image->isSdf())); + AnnotationManager::impl->images.erase(id); + auto inserted = AnnotationManager::impl->images.emplace( + id, style::Image(id, image->getImage().clone(), image->getPixelRatio(), image->isSdf())); style.get().impl->addImage(std::make_unique<style::Image>(inserted.first->second)); } @@ -254,7 +273,7 @@ void AnnotationManager::removeImage(const std::string& id_) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(); std::lock_guard<std::mutex> lock(mutex); const std::string id = prefixedImageID(id_); - images.erase(id); + AnnotationManager::impl->images.erase(id); style.get().impl->removeImage(id); } @@ -262,8 +281,10 @@ double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id_) { CHECK_ANNOTATIONS_ENABLED_AND_RETURN(0.0); std::lock_guard<std::mutex> lock(mutex); const std::string id = prefixedImageID(id_); - auto it = images.find(id); - return it != images.end() ? -(it->second.getImage().size.height / it->second.getPixelRatio()) / 2 : 0.0; + auto it = AnnotationManager::impl->images.find(id); + return it != AnnotationManager::impl->images.end() + ? -(it->second.getImage().size.height / it->second.getPixelRatio()) / 2 + : 0.0; } } // namespace mbgl diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index a9389d8ca9..65ef3a3cbf 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -1,7 +1,6 @@ #pragma once #include <mbgl/annotation/annotation.hpp> -#include <mbgl/annotation/symbol_annotation_impl.hpp> #include <mbgl/style/image.hpp> #include <mbgl/util/noncopyable.hpp> @@ -18,8 +17,6 @@ namespace mbgl { class LatLngBounds; class AnnotationTile; class AnnotationTileData; -class SymbolAnnotationImpl; -class ShapeAnnotationImpl; namespace style { class Style; @@ -75,19 +72,8 @@ private: AnnotationID nextID = 0; - using SymbolAnnotationTree = boost::geometry::index::rtree<std::shared_ptr<const SymbolAnnotationImpl>, boost::geometry::index::rstar<16, 4>>; - // Unlike std::unordered_map, std::map is guaranteed to sort by AnnotationID, ensuring that older annotations are below newer annotations. - // <https://github.com/mapbox/mapbox-gl-native/issues/5691> - using SymbolAnnotationMap = std::map<AnnotationID, std::shared_ptr<SymbolAnnotationImpl>>; - using ShapeAnnotationMap = std::map<AnnotationID, std::unique_ptr<ShapeAnnotationImpl>>; - using ImageMap = std::unordered_map<std::string, style::Image>; - - SymbolAnnotationTree symbolTree; - SymbolAnnotationMap symbolAnnotations; - ShapeAnnotationMap shapeAnnotations; - ImageMap images; - - std::unordered_set<AnnotationTile*> tiles; + class Impl; + const std::unique_ptr<Impl> impl; mapbox::base::WeakPtrFactory<AnnotationManager> weakFactory{this}; }; diff --git a/src/mbgl/map/map_impl.cpp b/src/mbgl/map/map_impl.cpp index 0edc715134..2d1ce3d386 100644 --- a/src/mbgl/map/map_impl.cpp +++ b/src/mbgl/map/map_impl.cpp @@ -30,7 +30,15 @@ Map::Impl::~Impl() { // Explicitly reset the RendererFrontend first to ensure it releases // All shared resources (AnnotationManager) rendererFrontend.reset(); -}; +} + +Map::Impl *Map::Impl::get(Map& map) { + return map.impl.get(); +} + +const Map::Impl *Map::Impl::get(const Map& map) { + return map.impl.get(); +} #pragma mark - Map::Impl StyleObserver diff --git a/src/mbgl/map/map_impl.hpp b/src/mbgl/map/map_impl.hpp index 416662f9e5..b89a584fae 100644 --- a/src/mbgl/map/map_impl.hpp +++ b/src/mbgl/map/map_impl.hpp @@ -31,6 +31,9 @@ public: Impl(RendererFrontend&, MapObserver&, std::shared_ptr<FileSource>, const MapOptions&); ~Impl() final; + static Map::Impl *get(Map&); + static const Map::Impl *get(const Map&); + // StyleObserver void onSourceChanged(style::Source&) final; void onUpdate() final; |