diff options
Diffstat (limited to 'src/mbgl/annotation')
18 files changed, 307 insertions, 246 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index 88153f5fb7..a69dba1bf2 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -4,8 +4,7 @@ #include <mbgl/annotation/symbol_annotation_impl.hpp> #include <mbgl/annotation/line_annotation_impl.hpp> #include <mbgl/annotation/fill_annotation_impl.hpp> -#include <mbgl/annotation/style_sourced_annotation_impl.hpp> -#include <mbgl/style/style.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> #include <mbgl/storage/file_source.hpp> @@ -19,16 +18,11 @@ using namespace style; const std::string AnnotationManager::SourceID = "com.mapbox.annotations"; const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points"; -AnnotationManager::AnnotationManager(float pixelRatio) - : spriteAtlas({ 1024, 1024 }, pixelRatio) { - // This is a special atlas, holding only images added via addIcon, so we always treat it as - // loaded. - spriteAtlas.markAsLoaded(); -} - +AnnotationManager::AnnotationManager() = default; AnnotationManager::~AnnotationManager() = default; AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation, const uint8_t maxZoom) { + std::lock_guard<std::mutex> lock(mutex); AnnotationID id = nextID++; Annotation::visit(annotation, [&] (const auto& annotation_) { this->add(id, annotation_, maxZoom); @@ -37,21 +31,15 @@ AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation, cons } Update AnnotationManager::updateAnnotation(const AnnotationID& id, const Annotation& annotation, const uint8_t maxZoom) { + std::lock_guard<std::mutex> lock(mutex); return Annotation::visit(annotation, [&] (const auto& annotation_) { return this->update(id, annotation_, maxZoom); }); } 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.insert(shapeAnnotations.at(id)->layerID); - shapeAnnotations.erase(id); - } else { - assert(false); // Should never happen - } + std::lock_guard<std::mutex> lock(mutex); + remove(id); } void AnnotationManager::add(const AnnotationID& id, const SymbolAnnotation& annotation, const uint8_t) { @@ -72,12 +60,6 @@ void AnnotationManager::add(const AnnotationID& id, const FillAnnotation& annota obsoleteShapeAnnotationLayers.erase(impl.layerID); } -void AnnotationManager::add(const AnnotationID& id, const StyleSourcedAnnotation& annotation, const uint8_t maxZoom) { - ShapeAnnotationImpl& impl = *shapeAnnotations.emplace(id, - std::make_unique<StyleSourcedAnnotationImpl>(id, annotation, maxZoom)).first->second; - obsoleteShapeAnnotationLayers.erase(impl.layerID); -} - Update AnnotationManager::update(const AnnotationID& id, const SymbolAnnotation& annotation, const uint8_t maxZoom) { Update result = Update::Nothing; @@ -110,6 +92,7 @@ Update AnnotationManager::update(const AnnotationID& id, const LineAnnotation& a assert(false); // Attempt to update a non-existent shape annotation return Update::Nothing; } + removeAndAdd(id, annotation, maxZoom); return Update::AnnotationData | Update::AnnotationStyle; } @@ -120,40 +103,43 @@ Update AnnotationManager::update(const AnnotationID& id, const FillAnnotation& a assert(false); // Attempt to update a non-existent shape annotation return Update::Nothing; } - removeAndAdd(id, annotation, maxZoom); - return Update::AnnotationData | Update::AnnotationStyle; -} -Update AnnotationManager::update(const AnnotationID& id, const StyleSourcedAnnotation& annotation, const uint8_t maxZoom) { - auto it = shapeAnnotations.find(id); - if (it == shapeAnnotations.end()) { - assert(false); // Attempt to update a non-existent shape annotation - return Update::Nothing; - } removeAndAdd(id, annotation, maxZoom); return Update::AnnotationData | Update::AnnotationStyle; } void AnnotationManager::removeAndAdd(const AnnotationID& id, const Annotation& annotation, const uint8_t maxZoom) { - removeAnnotation(id); + remove(id); Annotation::visit(annotation, [&] (const auto& annotation_) { this->add(id, annotation_, maxZoom); }); } +void AnnotationManager::remove(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.insert(shapeAnnotations.at(id)->layerID); + shapeAnnotations.erase(id); + } else { + assert(false); // Should never happen + } +} + std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const CanonicalTileID& tileID) { if (symbolAnnotations.empty() && shapeAnnotations.empty()) return nullptr; auto tileData = std::make_unique<AnnotationTileData>(); - AnnotationTileLayer& pointLayer = tileData->layers.emplace(PointLayerID, PointLayerID).first->second; + auto pointLayer = tileData->addLayer(PointLayerID); LatLngBounds tileBounds(tileID); symbolTree.query(boost::geometry::index::intersects(tileBounds), boost::make_function_output_iterator([&](const auto& val){ - val->updateLayer(tileID, pointLayer); + val->updateLayer(tileID, *pointLayer); })); for (const auto& shape : shapeAnnotations) { @@ -163,60 +149,99 @@ std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const Canonic return tileData; } -void AnnotationManager::updateStyle(Style& style) { - // Create annotation source, point layer, and point bucket +void AnnotationManager::updateStyle(Style::Impl& style) { + // Create annotation source, point layer, and point bucket. We do everything via Style::Impl + // because we don't want annotation mutations to trigger Style::Impl::styleMutated to be set. if (!style.getSource(SourceID)) { style.addSource(std::make_unique<AnnotationSource>()); std::unique_ptr<SymbolLayer> layer = std::make_unique<SymbolLayer>(PointLayerID, SourceID); layer->setSourceLayer(PointLayerID); - layer->setIconImage({"{sprite}"}); + layer->setIconImage({SourceID + ".{sprite}"}); layer->setIconAllowOverlap(true); layer->setIconIgnorePlacement(true); style.addLayer(std::move(layer)); } + std::lock_guard<std::mutex> lock(mutex); + for (const auto& shape : shapeAnnotations) { shape.second->updateStyle(style); } + for (const auto& image : 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 + // of which images need to be added because we don't know if the style is the same + // instance as in the last updateStyle call. If it's a new style, we need to add all + // images.) + style.addImage(std::make_unique<style::Image>(image.second)); + } + for (const auto& layer : obsoleteShapeAnnotationLayers) { if (style.getLayer(layer)) { style.removeLayer(layer); } } + for (const auto& image : obsoleteImages) { + if (style.getImage(image)) { + style.removeImage(image); + } + } + obsoleteShapeAnnotationLayers.clear(); + obsoleteImages.clear(); } void AnnotationManager::updateData() { + std::lock_guard<std::mutex> lock(mutex); for (auto& tile : tiles) { tile->setData(getTileData(tile->id.canonical)); } } void AnnotationManager::addTile(AnnotationTile& tile) { + std::lock_guard<std::mutex> lock(mutex); tiles.insert(&tile); tile.setData(getTileData(tile.id.canonical)); } void AnnotationManager::removeTile(AnnotationTile& tile) { + std::lock_guard<std::mutex> lock(mutex); tiles.erase(&tile); } -void AnnotationManager::addImage(const std::string& id, std::unique_ptr<style::Image> image) { - spriteAtlas.addImage(id, std::move(image)); +// To ensure that annotation images do not collide with images from the style, +// we prefix input image IDs with "com.mapbox.annotations". +static std::string prefixedImageID(const std::string& id) { + return AnnotationManager::SourceID + "." + id; +} + +void AnnotationManager::addImage(std::unique_ptr<style::Image> image) { + std::lock_guard<std::mutex> lock(mutex); + const std::string id = prefixedImageID(image->getID()); + images.erase(id); + images.emplace(id, + style::Image(id, image->getImage().clone(), image->getPixelRatio(), image->isSdf())); + obsoleteImages.erase(id); } -void AnnotationManager::removeImage(const std::string& id) { - spriteAtlas.removeImage(id); +void AnnotationManager::removeImage(const std::string& id_) { + std::lock_guard<std::mutex> lock(mutex); + const std::string id = prefixedImageID(id_); + images.erase(id); + obsoleteImages.insert(id); } -double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id) { - const style::Image* image = spriteAtlas.getImage(id); - return image ? -(image->image.size.height / image->pixelRatio) / 2 : 0; +double AnnotationManager::getTopOffsetPixelsForImage(const std::string& id_) { + 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; } } // namespace mbgl diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index 0ab43bec15..6906791db7 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -2,13 +2,16 @@ #include <mbgl/annotation/annotation.hpp> #include <mbgl/annotation/symbol_annotation_impl.hpp> -#include <mbgl/sprite/sprite_atlas.hpp> +#include <mbgl/style/image.hpp> #include <mbgl/map/update.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/util/noncopyable.hpp> +#include <mutex> #include <string> #include <vector> #include <unordered_set> +#include <unordered_map> namespace mbgl { @@ -18,26 +21,20 @@ class AnnotationTileData; class SymbolAnnotationImpl; class ShapeAnnotationImpl; -namespace style { -class Style; -class Image; -} // namespace style - class AnnotationManager : private util::noncopyable { public: - AnnotationManager(float pixelRatio); + AnnotationManager(); ~AnnotationManager(); AnnotationID addAnnotation(const Annotation&, const uint8_t maxZoom); Update updateAnnotation(const AnnotationID&, const Annotation&, const uint8_t maxZoom); void removeAnnotation(const AnnotationID&); - void addImage(const std::string&, std::unique_ptr<style::Image>); + void addImage(std::unique_ptr<style::Image>); void removeImage(const std::string&); double getTopOffsetPixelsForImage(const std::string&); - SpriteAtlas& getSpriteAtlas() { return spriteAtlas; } - void updateStyle(style::Style&); + void updateStyle(style::Style::Impl&); void updateData(); void addTile(AnnotationTile&); @@ -50,17 +47,19 @@ 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); Update update(const AnnotationID&, const SymbolAnnotation&, const uint8_t); Update update(const AnnotationID&, const LineAnnotation&, const uint8_t); Update update(const AnnotationID&, const FillAnnotation&, const uint8_t); - Update update(const AnnotationID&, const StyleSourcedAnnotation&, const uint8_t); void removeAndAdd(const AnnotationID&, const Annotation&, const uint8_t); + void remove(const AnnotationID&); + std::unique_ptr<AnnotationTileData> getTileData(const CanonicalTileID&); + std::mutex mutex; + AnnotationID nextID = 0; using SymbolAnnotationTree = boost::geometry::index::rtree<std::shared_ptr<const SymbolAnnotationImpl>, boost::geometry::index::rstar<16, 4>>; @@ -68,13 +67,15 @@ private: // <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<std::string> obsoleteShapeAnnotationLayers; + std::unordered_set<std::string> obsoleteImages; std::unordered_set<AnnotationTile*> tiles; - SpriteAtlas spriteAtlas; friend class AnnotationTile; }; diff --git a/src/mbgl/annotation/annotation_source.cpp b/src/mbgl/annotation/annotation_source.cpp index 9956140179..68f36f2d3a 100644 --- a/src/mbgl/annotation/annotation_source.cpp +++ b/src/mbgl/annotation/annotation_source.cpp @@ -1,25 +1,24 @@ #include <mbgl/annotation/annotation_source.hpp> #include <mbgl/annotation/annotation_manager.hpp> -#include <mbgl/annotation/render_annotation_source.hpp> namespace mbgl { using namespace style; AnnotationSource::AnnotationSource() - : Source(SourceType::Annotations, std::make_unique<Impl>(*this)) { + : Source(makeMutable<Impl>()) { } -AnnotationSource::Impl::Impl(Source& base_) - : Source::Impl(SourceType::Annotations, AnnotationManager::SourceID, base_) { +AnnotationSource::Impl::Impl() + : Source::Impl(SourceType::Annotations, AnnotationManager::SourceID) { } -void AnnotationSource::Impl::loadDescription(FileSource&) { +void AnnotationSource::loadDescription(FileSource&) { loaded = true; } -std::unique_ptr<RenderSource> AnnotationSource::Impl::createRenderSource() const { - return std::make_unique<RenderAnnotationSource>(*this); +optional<std::string> AnnotationSource::Impl::getAttribution() const { + return {}; } } // namespace mbgl diff --git a/src/mbgl/annotation/annotation_source.hpp b/src/mbgl/annotation/annotation_source.hpp index 46c9564443..0728f3207e 100644 --- a/src/mbgl/annotation/annotation_source.hpp +++ b/src/mbgl/annotation/annotation_source.hpp @@ -10,14 +10,19 @@ public: AnnotationSource(); class Impl; + const Impl& impl() const; + +private: + void loadDescription(FileSource&) final; + + Mutable<Impl> mutableImpl() const; }; class AnnotationSource::Impl : public style::Source::Impl { public: - Impl(Source&); + Impl(); - void loadDescription(FileSource&) final; - std::unique_ptr<RenderSource> createRenderSource() const final; + optional<std::string> getAttribution() const final; }; } // namespace mbgl diff --git a/src/mbgl/annotation/annotation_tile.cpp b/src/mbgl/annotation/annotation_tile.cpp index 1253681414..0596d60f4f 100644 --- a/src/mbgl/annotation/annotation_tile.cpp +++ b/src/mbgl/annotation/annotation_tile.cpp @@ -3,7 +3,6 @@ #include <mbgl/util/constants.hpp> #include <mbgl/storage/file_source.hpp> #include <mbgl/renderer/tile_parameters.hpp> -#include <mbgl/style/style.hpp> #include <utility> @@ -11,9 +10,7 @@ namespace mbgl { AnnotationTile::AnnotationTile(const OverscaledTileID& overscaledTileID, const TileParameters& parameters) - : GeometryTile(overscaledTileID, AnnotationManager::SourceID, parameters, - *parameters.style.glyphAtlas, - parameters.annotationManager.spriteAtlas), + : GeometryTile(overscaledTileID, AnnotationManager::SourceID, parameters), annotationManager(parameters.annotationManager) { annotationManager.addTile(*this); } @@ -22,37 +19,105 @@ AnnotationTile::~AnnotationTile() { annotationManager.removeTile(*this); } -void AnnotationTile::setNecessity(Necessity) {} +void AnnotationTile::setNecessity(Necessity) { +} + +class AnnotationTileFeatureData { +public: + AnnotationTileFeatureData(const AnnotationID id_, + FeatureType type_, + GeometryCollection&& geometries_, + std::unordered_map<std::string, std::string>&& properties_) + : id(id_), + type(type_), + geometries(std::move(geometries_)), + properties(std::move(properties_)) { + } + + AnnotationID id; + FeatureType type; + GeometryCollection geometries; + std::unordered_map<std::string, std::string> properties; +}; -AnnotationTileFeature::AnnotationTileFeature(const AnnotationID id_, - FeatureType type_, GeometryCollection geometries_, - std::unordered_map<std::string, std::string> properties_) - : id(id_), - type(type_), - properties(std::move(properties_)), - geometries(std::move(geometries_)) {} +AnnotationTileFeature::AnnotationTileFeature(std::shared_ptr<const AnnotationTileFeatureData> data_) + : data(std::move(data_)) { +} + +AnnotationTileFeature::~AnnotationTileFeature() = default; + +FeatureType AnnotationTileFeature::getType() const { + return data->type; +} optional<Value> AnnotationTileFeature::getValue(const std::string& key) const { - auto it = properties.find(key); - if (it != properties.end()) { + auto it = data->properties.find(key); + if (it != data->properties.end()) { return optional<Value>(it->second); } return optional<Value>(); } -AnnotationTileLayer::AnnotationTileLayer(std::string name_) - : name(std::move(name_)) {} +optional<FeatureIdentifier> AnnotationTileFeature::getID() const { + return { static_cast<uint64_t>(data->id) }; +} + +GeometryCollection AnnotationTileFeature::getGeometries() const { + return data->geometries; +} + +class AnnotationTileLayerData { +public: + AnnotationTileLayerData(const std::string& name_) : name(name_) { + } + + const std::string name; + std::vector<std::shared_ptr<const AnnotationTileFeatureData>> features; +}; + +AnnotationTileLayer::AnnotationTileLayer(std::shared_ptr<AnnotationTileLayerData> layer_) : layer(std::move(layer_)) { +} + +std::size_t AnnotationTileLayer::featureCount() const { + return layer->features.size(); +} + +std::unique_ptr<GeometryTileFeature> AnnotationTileLayer::getFeature(std::size_t i) const { + return std::make_unique<AnnotationTileFeature>(layer->features.at(i)); +} + +std::string AnnotationTileLayer::getName() const { + return layer->name; +} + +void AnnotationTileLayer::addFeature(const AnnotationID id, + FeatureType type, + GeometryCollection geometries, + std::unordered_map<std::string, std::string> properties) { + + layer->features.emplace_back(std::make_shared<AnnotationTileFeatureData>( + id, type, std::move(geometries), std::move(properties))); +} std::unique_ptr<GeometryTileData> AnnotationTileData::clone() const { return std::make_unique<AnnotationTileData>(*this); } -const GeometryTileLayer* AnnotationTileData::getLayer(const std::string& name) const { +std::unique_ptr<GeometryTileLayer> AnnotationTileData::getLayer(const std::string& name) const { auto it = layers.find(name); if (it != layers.end()) { - return &it->second; + return std::make_unique<AnnotationTileLayer>(it->second); } return nullptr; } +std::unique_ptr<AnnotationTileLayer> AnnotationTileData::addLayer(const std::string& name) { + // Only constructs a new layer if it doesn't yet exist, otherwise, we'll use the existing one. + auto it = layers.find(name); + if (it == layers.end()) { + it = layers.emplace(name, std::make_shared<AnnotationTileLayerData>(name)).first; + } + return std::make_unique<AnnotationTileLayer>(it->second); +} + } // namespace mbgl diff --git a/src/mbgl/annotation/annotation_tile.hpp b/src/mbgl/annotation/annotation_tile.hpp index ea4ff5ebd5..88505c50e3 100644 --- a/src/mbgl/annotation/annotation_tile.hpp +++ b/src/mbgl/annotation/annotation_tile.hpp @@ -11,8 +11,7 @@ class TileParameters; class AnnotationTile : public GeometryTile { public: - AnnotationTile(const OverscaledTileID&, - const TileParameters&); + AnnotationTile(const OverscaledTileID&, const TileParameters&); ~AnnotationTile() override; void setNecessity(Necessity) final; @@ -21,46 +20,50 @@ private: AnnotationManager& annotationManager; }; +class AnnotationTileFeatureData; + class AnnotationTileFeature : public GeometryTileFeature { public: - AnnotationTileFeature(AnnotationID, FeatureType, GeometryCollection, - std::unordered_map<std::string, std::string> properties = {{}}); + AnnotationTileFeature(std::shared_ptr<const AnnotationTileFeatureData>); + ~AnnotationTileFeature() override; - FeatureType getType() const override { return type; } + FeatureType getType() const override; optional<Value> getValue(const std::string&) const override; - optional<FeatureIdentifier> getID() const override { return { static_cast<uint64_t>(id) }; } - GeometryCollection getGeometries() const override { return geometries; } + optional<FeatureIdentifier> getID() const override; + GeometryCollection getGeometries() const override; - const AnnotationID id; - const FeatureType type; - const std::unordered_map<std::string, std::string> properties; - const GeometryCollection geometries; +private: + std::shared_ptr<const AnnotationTileFeatureData> data; }; +class AnnotationTileLayerData; + class AnnotationTileLayer : public GeometryTileLayer { public: - AnnotationTileLayer(std::string); - - std::size_t featureCount() const override { return features.size(); } + AnnotationTileLayer(std::shared_ptr<AnnotationTileLayerData>); - std::unique_ptr<GeometryTileFeature> getFeature(std::size_t i) const override { - return std::make_unique<AnnotationTileFeature>(features.at(i)); - } + std::size_t featureCount() const override; + std::unique_ptr<GeometryTileFeature> getFeature(std::size_t i) const override; + std::string getName() const override; - std::string getName() const override { return name; }; - - std::vector<AnnotationTileFeature> features; + void addFeature(const AnnotationID, + FeatureType, + GeometryCollection, + std::unordered_map<std::string, std::string> properties = { {} }); private: - std::string name; + std::shared_ptr<AnnotationTileLayerData> layer; }; class AnnotationTileData : public GeometryTileData { public: std::unique_ptr<GeometryTileData> clone() const override; - const GeometryTileLayer* getLayer(const std::string&) const override; + std::unique_ptr<GeometryTileLayer> getLayer(const std::string&) const override; + + std::unique_ptr<AnnotationTileLayer> addLayer(const std::string&); - std::unordered_map<std::string, AnnotationTileLayer> layers; +private: + std::unordered_map<std::string, std::shared_ptr<AnnotationTileLayerData>> layers; }; } // namespace mbgl diff --git a/src/mbgl/annotation/fill_annotation_impl.cpp b/src/mbgl/annotation/fill_annotation_impl.cpp index 3e91524e86..5dc36edab0 100644 --- a/src/mbgl/annotation/fill_annotation_impl.cpp +++ b/src/mbgl/annotation/fill_annotation_impl.cpp @@ -1,6 +1,6 @@ #include <mbgl/annotation/fill_annotation_impl.hpp> #include <mbgl/annotation/annotation_manager.hpp> -#include <mbgl/style/style.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/layers/fill_layer.hpp> namespace mbgl { @@ -12,7 +12,7 @@ FillAnnotationImpl::FillAnnotationImpl(AnnotationID id_, FillAnnotation annotati annotation({ ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.color, annotation_.outlineColor }) { } -void FillAnnotationImpl::updateStyle(Style& style) const { +void FillAnnotationImpl::updateStyle(Style::Impl& style) const { Layer* layer = style.getLayer(layerID); if (!layer) { @@ -21,7 +21,7 @@ void FillAnnotationImpl::updateStyle(Style& style) const { layer = style.addLayer(std::move(newLayer), AnnotationManager::PointLayerID); } - FillLayer* fillLayer = layer->as<FillLayer>(); + auto* fillLayer = layer->as<FillLayer>(); fillLayer->setFillOpacity(annotation.opacity); fillLayer->setFillColor(annotation.color); fillLayer->setFillOutlineColor(annotation.outlineColor); diff --git a/src/mbgl/annotation/fill_annotation_impl.hpp b/src/mbgl/annotation/fill_annotation_impl.hpp index 6376eee880..5c49e447b8 100644 --- a/src/mbgl/annotation/fill_annotation_impl.hpp +++ b/src/mbgl/annotation/fill_annotation_impl.hpp @@ -9,7 +9,7 @@ class FillAnnotationImpl : public ShapeAnnotationImpl { public: FillAnnotationImpl(AnnotationID, FillAnnotation, uint8_t maxZoom); - void updateStyle(style::Style&) const final; + void updateStyle(style::Style::Impl&) const final; const ShapeAnnotationGeometry& geometry() const final; private: diff --git a/src/mbgl/annotation/line_annotation_impl.cpp b/src/mbgl/annotation/line_annotation_impl.cpp index 15fa2c67f3..8954ecfa58 100644 --- a/src/mbgl/annotation/line_annotation_impl.cpp +++ b/src/mbgl/annotation/line_annotation_impl.cpp @@ -1,6 +1,6 @@ #include <mbgl/annotation/line_annotation_impl.hpp> #include <mbgl/annotation/annotation_manager.hpp> -#include <mbgl/style/style.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/layers/line_layer.hpp> namespace mbgl { @@ -12,7 +12,7 @@ LineAnnotationImpl::LineAnnotationImpl(AnnotationID id_, LineAnnotation annotati annotation({ ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.width, annotation_.color }) { } -void LineAnnotationImpl::updateStyle(Style& style) const { +void LineAnnotationImpl::updateStyle(Style::Impl& style) const { Layer* layer = style.getLayer(layerID); if (!layer) { @@ -22,7 +22,7 @@ void LineAnnotationImpl::updateStyle(Style& style) const { layer = style.addLayer(std::move(newLayer), AnnotationManager::PointLayerID); } - LineLayer* lineLayer = layer->as<LineLayer>(); + auto* lineLayer = layer->as<LineLayer>(); lineLayer->setLineOpacity(annotation.opacity); lineLayer->setLineWidth(annotation.width); lineLayer->setLineColor(annotation.color); diff --git a/src/mbgl/annotation/line_annotation_impl.hpp b/src/mbgl/annotation/line_annotation_impl.hpp index 7945da5d97..548a094d53 100644 --- a/src/mbgl/annotation/line_annotation_impl.hpp +++ b/src/mbgl/annotation/line_annotation_impl.hpp @@ -9,7 +9,7 @@ class LineAnnotationImpl : public ShapeAnnotationImpl { public: LineAnnotationImpl(AnnotationID, LineAnnotation, uint8_t maxZoom); - void updateStyle(style::Style&) const final; + void updateStyle(style::Style::Impl&) const final; const ShapeAnnotationGeometry& geometry() const final; private: diff --git a/src/mbgl/annotation/render_annotation_source.cpp b/src/mbgl/annotation/render_annotation_source.cpp index a62d2d51d3..8fb11785fd 100644 --- a/src/mbgl/annotation/render_annotation_source.cpp +++ b/src/mbgl/annotation/render_annotation_source.cpp @@ -1,6 +1,7 @@ #include <mbgl/annotation/render_annotation_source.hpp> #include <mbgl/annotation/annotation_tile.hpp> #include <mbgl/renderer/render_tile.hpp> +#include <mbgl/renderer/painter.hpp> #include <mbgl/algorithm/generate_clip_ids.hpp> #include <mbgl/algorithm/generate_clip_ids_impl.hpp> @@ -9,22 +10,43 @@ namespace mbgl { using namespace style; -RenderAnnotationSource::RenderAnnotationSource(const AnnotationSource::Impl& impl_) +RenderAnnotationSource::RenderAnnotationSource(Immutable<AnnotationSource::Impl> impl_) : RenderSource(impl_) { tilePyramid.setObserver(this); } +const AnnotationSource::Impl& RenderAnnotationSource::impl() const { + return static_cast<const AnnotationSource::Impl&>(*baseImpl); +} + bool RenderAnnotationSource::isLoaded() const { return tilePyramid.isLoaded(); } -void RenderAnnotationSource::invalidateTiles() { - tilePyramid.invalidateTiles(); +void RenderAnnotationSource::update(Immutable<style::Source::Impl> baseImpl_, + const std::vector<Immutable<Layer::Impl>>& layers, + const bool needsRendering, + const bool needsRelayout, + const TileParameters& parameters) { + std::swap(baseImpl, baseImpl_); + + enabled = needsRendering; + + tilePyramid.update(layers, + needsRendering, + needsRelayout, + parameters, + SourceType::Annotations, + util::tileSize, + { 0, 22 }, + [&] (const OverscaledTileID& tileID) { + return std::make_unique<AnnotationTile>(tileID, parameters); + }); } -void RenderAnnotationSource::startRender(algorithm::ClipIDGenerator& generator, const mat4& projMatrix, const mat4& clipMatrix, const TransformState& transform) { - generator.update(tilePyramid.getRenderTiles()); - tilePyramid.startRender(projMatrix, clipMatrix, transform); +void RenderAnnotationSource::startRender(Painter& painter) { + painter.clipIDGenerator.update(tilePyramid.getRenderTiles()); + tilePyramid.startRender(painter); } void RenderAnnotationSource::finishRender(Painter& painter) { @@ -35,39 +57,18 @@ std::map<UnwrappedTileID, RenderTile>& RenderAnnotationSource::getRenderTiles() return tilePyramid.getRenderTiles(); } -void RenderAnnotationSource::updateTiles(const TileParameters& parameters) { - tilePyramid.updateTiles(parameters, - SourceType::Annotations, - util::tileSize, - { 0, 22 }, - [&] (const OverscaledTileID& tileID) { - return std::make_unique<AnnotationTile>(tileID, parameters); - }); -} - -void RenderAnnotationSource::removeTiles() { - tilePyramid.removeTiles(); -} - -void RenderAnnotationSource::reloadTiles() { - tilePyramid.reloadTiles(); -} - std::unordered_map<std::string, std::vector<Feature>> RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry, - const TransformState& transformState, - const RenderedQueryOptions& options) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, options); + const TransformState& transformState, + const RenderStyle& style, + const RenderedQueryOptions& options) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, style, options); } std::vector<Feature> RenderAnnotationSource::querySourceFeatures(const SourceQueryOptions&) const { return {}; } -void RenderAnnotationSource::setCacheSize(size_t size) { - tilePyramid.setCacheSize(size); -} - void RenderAnnotationSource::onLowMemory() { tilePyramid.onLowMemory(); } diff --git a/src/mbgl/annotation/render_annotation_source.hpp b/src/mbgl/annotation/render_annotation_source.hpp index 9ae9340477..7231452d4f 100644 --- a/src/mbgl/annotation/render_annotation_source.hpp +++ b/src/mbgl/annotation/render_annotation_source.hpp @@ -8,28 +8,17 @@ namespace mbgl { class RenderAnnotationSource : public RenderSource { public: - RenderAnnotationSource(const AnnotationSource::Impl&); + RenderAnnotationSource(Immutable<AnnotationSource::Impl>); bool isLoaded() const final; - // Called when the camera has changed. May load new tiles, unload obsolete tiles, or - // trigger re-placement of existing complete tiles. - void updateTiles(const TileParameters&) final; + void update(Immutable<style::Source::Impl>, + const std::vector<Immutable<style::Layer::Impl>>&, + bool needsRendering, + bool needsRelayout, + const TileParameters&) final; - // Removes all tiles (by putting them into the cache). - void removeTiles() final; - - // Remove all tiles and clear the cache. - void invalidateTiles() final; - - // Request that all loaded tiles re-run the layout operation on the existing source - // data with fresh style information. - void reloadTiles() final; - - void startRender(algorithm::ClipIDGenerator&, - const mat4& projMatrix, - const mat4& clipMatrix, - const TransformState&) final; + void startRender(Painter&) final; void finishRender(Painter&) final; std::map<UnwrappedTileID, RenderTile>& getRenderTiles() final; @@ -37,17 +26,24 @@ public: std::unordered_map<std::string, std::vector<Feature>> queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, + const RenderStyle& style, const RenderedQueryOptions& options) const final; std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final; - void setCacheSize(size_t) final; void onLowMemory() final; void dumpDebugLogs() const final; private: + const AnnotationSource::Impl& impl() const; + TilePyramid tilePyramid; }; +template <> +inline bool RenderSource::is<RenderAnnotationSource>() const { + return baseImpl->type == SourceType::Annotations; +} + } // namespace mbgl diff --git a/src/mbgl/annotation/shape_annotation_impl.cpp b/src/mbgl/annotation/shape_annotation_impl.cpp index d3ddf62b9e..0c1a631ad8 100644 --- a/src/mbgl/annotation/shape_annotation_impl.cpp +++ b/src/mbgl/annotation/shape_annotation_impl.cpp @@ -38,7 +38,7 @@ void ShapeAnnotationImpl::updateTileData(const CanonicalTileID& tileID, Annotati if (shapeTile.features.empty()) return; - AnnotationTileLayer& layer = data.layers.emplace(layerID, layerID).first->second; + auto layer = data.addLayer(layerID); ToGeometryCollection toGeometryCollection; ToFeatureType toFeatureType; @@ -53,7 +53,7 @@ void ShapeAnnotationImpl::updateTileData(const CanonicalTileID& tileID, Annotati renderGeometry = fixupPolygons(renderGeometry); } - layer.features.emplace_back(id, featureType, renderGeometry); + layer->addFeature(id, featureType, renderGeometry); } } diff --git a/src/mbgl/annotation/shape_annotation_impl.hpp b/src/mbgl/annotation/shape_annotation_impl.hpp index 800b4ec313..ed9e8d015a 100644 --- a/src/mbgl/annotation/shape_annotation_impl.hpp +++ b/src/mbgl/annotation/shape_annotation_impl.hpp @@ -4,6 +4,7 @@ #include <mbgl/annotation/annotation.hpp> #include <mbgl/util/geometry.hpp> +#include <mbgl/style/style.hpp> #include <string> #include <memory> @@ -13,16 +14,12 @@ namespace mbgl { class AnnotationTileData; class CanonicalTileID; -namespace style { -class Style; -} // namespace style - class ShapeAnnotationImpl { public: ShapeAnnotationImpl(const AnnotationID, const uint8_t maxZoom); virtual ~ShapeAnnotationImpl() = default; - virtual void updateStyle(style::Style&) const = 0; + virtual void updateStyle(style::Style::Impl&) const = 0; virtual const ShapeAnnotationGeometry& geometry() const = 0; void updateTileData(const CanonicalTileID&, AnnotationTileData&); diff --git a/src/mbgl/annotation/style_sourced_annotation_impl.cpp b/src/mbgl/annotation/style_sourced_annotation_impl.cpp deleted file mode 100644 index cb664cf15d..0000000000 --- a/src/mbgl/annotation/style_sourced_annotation_impl.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include <mbgl/annotation/style_sourced_annotation_impl.hpp> -#include <mbgl/annotation/annotation_manager.hpp> -#include <mbgl/style/style.hpp> -#include <mbgl/style/layer.hpp> -#include <mbgl/style/layer_impl.hpp> -#include <mbgl/style/layers/line_layer.hpp> -#include <mbgl/style/layers/fill_layer.hpp> - -namespace mbgl { - -using namespace style; - -StyleSourcedAnnotationImpl::StyleSourcedAnnotationImpl(AnnotationID id_, StyleSourcedAnnotation annotation_, uint8_t maxZoom_) - : ShapeAnnotationImpl(id_, maxZoom_), - annotation(std::move(annotation_)) { -} - -void StyleSourcedAnnotationImpl::updateStyle(Style& style) const { - if (style.getLayer(layerID)) - return; - - const Layer* sourceLayer = style.getLayer(annotation.layerID); - if (!sourceLayer) - return; - - if (sourceLayer->is<LineLayer>()) { - std::unique_ptr<Layer> layer = sourceLayer->baseImpl->copy(layerID, AnnotationManager::SourceID); - layer->as<LineLayer>()->setSourceLayer(layerID); - layer->as<LineLayer>()->setVisibility(VisibilityType::Visible); - style.addLayer(std::move(layer), sourceLayer->getID()); - } else if (sourceLayer->is<FillLayer>()) { - std::unique_ptr<Layer> layer = sourceLayer->baseImpl->copy(layerID, AnnotationManager::SourceID); - layer->as<FillLayer>()->setSourceLayer(layerID); - layer->as<FillLayer>()->setVisibility(VisibilityType::Visible); - style.addLayer(std::move(layer), sourceLayer->getID()); - } -} - -const ShapeAnnotationGeometry& 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 deleted file mode 100644 index 82b947302d..0000000000 --- a/src/mbgl/annotation/style_sourced_annotation_impl.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include <mbgl/annotation/shape_annotation_impl.hpp> -#include <mbgl/annotation/annotation.hpp> - -namespace mbgl { - -class StyleSourcedAnnotationImpl : public ShapeAnnotationImpl { -public: - StyleSourcedAnnotationImpl(AnnotationID, StyleSourcedAnnotation, uint8_t maxZoom); - - void updateStyle(style::Style&) const final; - const ShapeAnnotationGeometry& geometry() const final; - -private: - const StyleSourcedAnnotation annotation; -}; - -} // namespace mbgl diff --git a/src/mbgl/annotation/symbol_annotation_impl.cpp b/src/mbgl/annotation/symbol_annotation_impl.cpp index e5ae5f4b91..c95eb481b5 100644 --- a/src/mbgl/annotation/symbol_annotation_impl.cpp +++ b/src/mbgl/annotation/symbol_annotation_impl.cpp @@ -18,7 +18,7 @@ void SymbolAnnotationImpl::updateLayer(const CanonicalTileID& tileID, Annotation LatLng latLng { annotation.geometry.y, annotation.geometry.x }; TileCoordinate coordinate = TileCoordinate::fromLatLng(0, latLng); GeometryCoordinate tilePoint = TileCoordinate::toGeometryCoordinate(UnwrappedTileID(0, tileID), coordinate.p); - layer.features.emplace_back(id, FeatureType::Point, GeometryCollection {{ {{ tilePoint }} }}, featureProperties); + layer.addFeature(id, FeatureType::Point, GeometryCollection {{ {{ tilePoint }} }}, featureProperties); } } // namespace mbgl diff --git a/src/mbgl/annotation/symbol_annotation_impl.hpp b/src/mbgl/annotation/symbol_annotation_impl.hpp index c9a99ffb8d..9270acb857 100644 --- a/src/mbgl/annotation/symbol_annotation_impl.hpp +++ b/src/mbgl/annotation/symbol_annotation_impl.hpp @@ -18,6 +18,7 @@ #pragma GCC diagnostic ignored "-Wshorten-64-to-32" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#pragma GCC diagnostic ignored "-Wmisleading-indentation" #include <boost/geometry.hpp> #include <boost/geometry/geometries/point.hpp> #include <boost/geometry/geometries/box.hpp> @@ -26,10 +27,6 @@ #include <boost/geometry/index/rtree.hpp> #pragma GCC diagnostic pop -// Make Boost Geometry aware of our LatLng type -BOOST_GEOMETRY_REGISTER_POINT_2D_CONST(mbgl::LatLng, double, boost::geometry::cs::cartesian, longitude(), latitude()) -BOOST_GEOMETRY_REGISTER_BOX(mbgl::LatLngBounds, mbgl::LatLng, southwest(), northeast()) - namespace mbgl { class AnnotationTileLayer; @@ -47,9 +44,42 @@ public: } // namespace mbgl -// Tell Boost Geometry how to access a std::shared_ptr<mbgl::SymbolAnnotation> object. namespace boost { namespace geometry { + +// Make Boost Geometry aware of our LatLng type +namespace traits { + +template<> struct tag<mbgl::LatLng> { using type = point_tag; }; +template<> struct dimension<mbgl::LatLng> : boost::mpl::int_<2> {}; +template<> struct coordinate_type<mbgl::LatLng> { using type = double; }; +template<> struct coordinate_system<mbgl::LatLng> { using type = boost::geometry::cs::cartesian; }; + +template<> struct access<mbgl::LatLng, 0> { static inline double get(mbgl::LatLng const& p) { return p.longitude(); } }; +template<> struct access<mbgl::LatLng, 1> { static inline double get(mbgl::LatLng const& p) { return p.latitude(); } }; + +template<> struct tag<mbgl::LatLngBounds> { using type = box_tag; }; +template<> struct point_type<mbgl::LatLngBounds> { using type = mbgl::LatLng; }; + +template <size_t D> +struct indexed_access<mbgl::LatLngBounds, min_corner, D> +{ + using ct = coordinate_type<mbgl::LatLng>::type; + static inline ct get(mbgl::LatLngBounds const& b) { return geometry::get<D>(b.southwest()); } + static inline void set(mbgl::LatLngBounds& b, ct const& value) { geometry::set<D>(b.southwest(), value); } +}; + +template <size_t D> +struct indexed_access<mbgl::LatLngBounds, max_corner, D> +{ + using ct = coordinate_type<mbgl::LatLng>::type; + static inline ct get(mbgl::LatLngBounds const& b) { return geometry::get<D>(b.northeast()); } + static inline void set(mbgl::LatLngBounds& b, ct const& value) { geometry::set<D>(b.northeast(), value); } +}; + +} // namespace traits + +// Tell Boost Geometry how to access a std::shared_ptr<mbgl::SymbolAnnotation> object. namespace index { template <> @@ -61,6 +91,7 @@ struct indexable<std::shared_ptr<const mbgl::SymbolAnnotationImpl>> { } }; -} // end namespace index -} // end namespace geometry -} // end namespace boost +} // namespace index + +} // namespace geometry +} // namespace boost |