summaryrefslogtreecommitdiff
path: root/src/mbgl/annotation
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/annotation')
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp117
-rw-r--r--src/mbgl/annotation/annotation_manager.hpp27
-rw-r--r--src/mbgl/annotation/annotation_source.cpp13
-rw-r--r--src/mbgl/annotation/annotation_source.hpp11
-rw-r--r--src/mbgl/annotation/annotation_tile.cpp101
-rw-r--r--src/mbgl/annotation/annotation_tile.hpp49
-rw-r--r--src/mbgl/annotation/fill_annotation_impl.cpp6
-rw-r--r--src/mbgl/annotation/fill_annotation_impl.hpp2
-rw-r--r--src/mbgl/annotation/line_annotation_impl.cpp6
-rw-r--r--src/mbgl/annotation/line_annotation_impl.hpp2
-rw-r--r--src/mbgl/annotation/render_annotation_source.cpp63
-rw-r--r--src/mbgl/annotation/render_annotation_source.hpp34
-rw-r--r--src/mbgl/annotation/shape_annotation_impl.cpp4
-rw-r--r--src/mbgl/annotation/shape_annotation_impl.hpp7
-rw-r--r--src/mbgl/annotation/style_sourced_annotation_impl.cpp43
-rw-r--r--src/mbgl/annotation/style_sourced_annotation_impl.hpp19
-rw-r--r--src/mbgl/annotation/symbol_annotation_impl.cpp2
-rw-r--r--src/mbgl/annotation/symbol_annotation_impl.hpp47
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