summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-09-21 13:15:58 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-09-28 14:10:23 -0700
commitaf392b9434fd176704e564dfc22ee74f3a50cdf6 (patch)
treec3c333a4729a18c660b4edd68adeb801c779721e /src
parent24a58344284ca8c882bf2ab83b9129ca8ce9d4b3 (diff)
downloadqtlocation-mapboxgl-af392b9434fd176704e564dfc22ee74f3a50cdf6.tar.gz
Rewrite annotation invalidation strategy
First, move style mutation code out of StyleParser and into AnnotationManager, coalescing it with the mutation code for shape layers. Second, allow AnnotationManager to keep track of stale tiles entirely internally. There's no reason to pass sets of TileIDs around. Third, correct the logic for invalidating the shape source. Since AnnotationManager does not track shape invalidations on a tile-by-tile basis, don't try to invalidate the shape source tile-by-tile. Fixes #1675 Fixes #2322 Fixes #2095
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp150
-rw-r--r--src/mbgl/annotation/annotation_manager.hpp27
-rw-r--r--src/mbgl/map/map.cpp12
-rw-r--r--src/mbgl/map/map_context.cpp19
-rw-r--r--src/mbgl/map/map_context.hpp3
-rw-r--r--src/mbgl/map/source.cpp18
-rw-r--r--src/mbgl/map/source.hpp1
-rw-r--r--src/mbgl/style/style.cpp40
-rw-r--r--src/mbgl/style/style.hpp6
-rw-r--r--src/mbgl/style/style_parser.cpp42
10 files changed, 128 insertions, 190 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index 31b50b1c51..786ca42433 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -137,8 +137,13 @@ AnnotationManager::addShapeAnnotation(const ShapeAnnotation& shape, const uint8_
}
uint32_t
-AnnotationManager::addPointAnnotation(const PointAnnotation& point, const uint8_t maxZoom,
- std::unordered_set<TileID, TileID::Hash>& affectedTiles) {
+AnnotationManager::addPointAnnotation(const PointAnnotation& point, const uint8_t maxZoom) {
+ // We pre-generate tiles to contain each annotation up to the map's max zoom.
+ // We do this for fast rendering without projection conversions on the fly, as well as
+ // to simplify bounding box queries of annotations later. Tiles get invalidated when
+ // annotations are added or removed in order to refresh the map render without
+ // touching the base map underneath.
+
const uint32_t annotationID = nextID();
// at render time we style the point according to its {sprite} field
@@ -178,7 +183,7 @@ AnnotationManager::addPointAnnotation(const PointAnnotation& point, const uint8_
// check for annotation layer & create if necessary
util::ptr<LiveTileLayer> layer;
- std::string layerID = PointLayerID;
+ std::string layerID = PointSourceID;
if (tile_pos.second || tile_pos.first->second.second->getMutableLayer(layerID) == nullptr) {
layer = std::make_shared<LiveTileLayer>();
@@ -198,7 +203,7 @@ AnnotationManager::addPointAnnotation(const PointAnnotation& point, const uint8_
annotation->tilePointFeatures.emplace(featureTileID, std::weak_ptr<const LiveTileFeature>(feature));
// track affected tile
- affectedTiles.insert(featureTileID);
+ stalePointTileIDs.insert(featureTileID);
}
annotations.emplace(annotationID, std::move(annotation));
@@ -206,37 +211,22 @@ AnnotationManager::addPointAnnotation(const PointAnnotation& point, const uint8_
return annotationID;
}
-std::pair<AnnotationManager::AffectedTiles, AnnotationIDs>
+AnnotationIDs
AnnotationManager::addPointAnnotations(const std::vector<PointAnnotation>& points,
const uint8_t maxZoom) {
- // We pre-generate tiles to contain each annotation up to the map's max zoom.
- // We do this for fast rendering without projection conversions on the fly, as well as
- // to simplify bounding box queries of annotations later. Tiles get invalidated when
- // annotations are added or removed in order to refresh the map render without
- // touching the base map underneath.
-
AnnotationIDs annotationIDs;
annotationIDs.reserve(points.size());
- AffectedTiles affectedTiles;
-
for (const auto& point : points) {
- annotationIDs.push_back(addPointAnnotation(point, maxZoom, affectedTiles));
+ annotationIDs.push_back(addPointAnnotation(point, maxZoom));
}
- // Tile:IDs that need refreshed and the annotation identifiers held onto by the client.
- return std::make_pair(affectedTiles, annotationIDs);
+ return annotationIDs;
}
-std::pair<AnnotationManager::AffectedTiles, AnnotationIDs>
+AnnotationIDs
AnnotationManager::addShapeAnnotations(const std::vector<ShapeAnnotation>& shapes,
const uint8_t maxZoom) {
- // We pre-generate tiles to contain each annotation up to the map's max zoom.
- // We do this for fast rendering without projection conversions on the fly, as well as
- // to simplify bounding box queries of annotations later. Tiles get invalidated when
- // annotations are added or removed in order to refresh the map render without
- // touching the base map underneath.
-
AnnotationIDs annotationIDs;
annotationIDs.reserve(shapes.size());
@@ -244,16 +234,10 @@ AnnotationManager::addShapeAnnotations(const std::vector<ShapeAnnotation>& shape
annotationIDs.push_back(addShapeAnnotation(shape, maxZoom));
}
- // Tile:IDs that need refreshed and the annotation identifiers held onto by the client.
- // Shapes are tiled "on-the-fly", so we don't get any "affected tiles" and just expire
- // all annotation tiles for shape adds.
- return std::make_pair(AffectedTiles(), annotationIDs);
+ return annotationIDs;
}
-std::unordered_set<TileID, TileID::Hash> AnnotationManager::removeAnnotations(const AnnotationIDs& ids,
- const uint8_t maxZoom) {
- std::unordered_set<TileID, TileID::Hash> affectedTiles;
-
+void AnnotationManager::removeAnnotations(const AnnotationIDs& ids, const uint8_t maxZoom) {
std::vector<uint32_t> z2s;
const uint8_t zoomCount = maxZoom + 1;
z2s.reserve(zoomCount);
@@ -287,17 +271,16 @@ std::unordered_set<TileID, TileID::Hash> AnnotationManager::removeAnnotations(co
const auto& features_it = annotation->tilePointFeatures.find(tid);
if (features_it != annotation->tilePointFeatures.end()) {
// points share a layer; remove feature
- auto layer = tiles[tid].second->getMutableLayer(PointLayerID);
+ auto layer = tiles[tid].second->getMutableLayer(PointSourceID);
layer->removeFeature(features_it->second);
- affectedTiles.insert(tid);
+ stalePointTileIDs.insert(tid);
}
}
} else {
// remove shape layer from tiles if relevant
for (auto tile_it = tiles.begin(); tile_it != tiles.end(); ++tile_it) {
if (tile_it->second.first.count(annotationID)) {
- tile_it->second.second->removeLayer(ShapeLayerID + "." + util::toString(annotationID));
- affectedTiles.insert(tile_it->first);
+ tile_it->second.second->removeLayer(ShapeSourceID + "." + util::toString(annotationID));
}
}
@@ -312,9 +295,6 @@ std::unordered_set<TileID, TileID::Hash> AnnotationManager::removeAnnotations(co
annotations.erase(annotationID);
}
}
-
- // TileIDs for tiles that need refreshed.
- return affectedTiles;
}
AnnotationIDs AnnotationManager::getAnnotationsInBounds(const LatLngBounds& queryBounds,
@@ -414,7 +394,7 @@ const LiveTile* AnnotationManager::getTile(const TileID& id) {
// create shape tile layers from GeoJSONVT queries
for (auto& tiler_it : shapeTilers) {
const auto annotationID = tiler_it.first;
- const std::string layerID = ShapeLayerID + "." + util::toString(annotationID);
+ const std::string layerID = ShapeSourceID + "." + util::toString(annotationID);
// check for existing render layer
auto renderLayer = renderTile->getMutableLayer(layerID);
@@ -478,42 +458,48 @@ const LiveTile* AnnotationManager::getTile(const TileID& id) {
return renderTile;
}
-void AnnotationManager::updateTilesIfNeeded(Style* style) {
- if (!staleTiles.empty()) {
- updateTiles(staleTiles, style);
+void AnnotationManager::updateStyle(Style& style) {
+ // Create shape source
+ if (!style.getSource(ShapeSourceID)) {
+ std::unique_ptr<Source> shapeSource = std::make_unique<Source>();
+ shapeSource->info.type = SourceType::Annotations;
+ shapeSource->info.source_id = ShapeSourceID;
+ shapeSource->enabled = true;
+ style.addSource(std::move(shapeSource));
}
-}
-
-void AnnotationManager::updateTiles(const AffectedTiles& ids, Style* style) {
- std::copy(ids.begin(), ids.end(), std::inserter(staleTiles, staleTiles.begin()));
-
- if (!style) {
- return;
- }
-
- // grab existing, single shape annotations source
- const auto& shapeID = AnnotationManager::ShapeLayerID;
- Source* shapeAnnotationSource = style->getSource(shapeID);
- // Style not parsed yet
- if (!shapeAnnotationSource) {
- return;
+ // Create point source and singular layer and bucket
+ if (!style.getSource(PointSourceID)) {
+ std::unique_ptr<Source> pointSource = std::make_unique<Source>();
+ pointSource->info.type = SourceType::Annotations;
+ pointSource->info.source_id = PointSourceID;
+ pointSource->enabled = true;
+ style.addSource(std::move(pointSource));
+
+ std::map<ClassID, ClassProperties> pointPaints;
+ pointPaints.emplace(ClassID::Default, ClassProperties());
+ std::unique_ptr<StyleLayer> pointLayer = std::make_unique<StyleLayer>(PointSourceID, std::move(pointPaints));
+ pointLayer->type = StyleLayerType::Symbol;
+
+ util::ptr<StyleBucket> pointBucket = std::make_shared<StyleBucket>(pointLayer->type);
+ pointBucket->name = pointLayer->id;
+ pointBucket->source = PointSourceID;
+ pointBucket->source_layer = pointLayer->id;
+ pointBucket->layout.set(PropertyKey::IconImage, ConstantFunction<std::string>("{sprite}"));
+ pointBucket->layout.set(PropertyKey::IconAllowOverlap, ConstantFunction<bool>(true));
+
+ pointLayer->bucket = pointBucket;
+ style.addLayer(std::move(pointLayer));
}
- shapeAnnotationSource->enabled = true;
-
- const auto& layers = style->layers;
-
- // create (if necessary) layers and buckets for each shape
- for (const auto& shapeAnnotationID : orderedShapeAnnotations) {
- const std::string shapeLayerID = shapeID + "." + util::toString(shapeAnnotationID);
-
- if (std::find_if(layers.begin(), layers.end(), [&](auto l) { return l->id == shapeLayerID; }) != layers.end()) {
+ // Create new shape layers and buckets
+ for (const auto& shapeID : orderedShapeAnnotations) {
+ const std::string shapeLayerID = ShapeSourceID + "." + util::toString(shapeID);
+ if (style.getLayer(shapeLayerID)) {
continue;
}
- // apply shape paint properties
- const StyleProperties& shapeStyle = annotations.at(shapeAnnotationID)->styleProperties;
+ const StyleProperties& shapeStyle = annotations.at(shapeID)->styleProperties;
ClassProperties paintProperties;
if (shapeStyle.is<LineProperties>()) {
@@ -530,40 +516,28 @@ void AnnotationManager::updateTiles(const AffectedTiles& ids, Style* style) {
std::map<ClassID, ClassProperties> shapePaints;
shapePaints.emplace(ClassID::Default, std::move(paintProperties));
-
- // create shape layer
- util::ptr<StyleLayer> shapeLayer = std::make_shared<StyleLayer>(shapeLayerID, std::move(shapePaints));
+ std::unique_ptr<StyleLayer> shapeLayer = std::make_unique<StyleLayer>(shapeLayerID, std::move(shapePaints));
shapeLayer->type = (shapeStyle.is<LineProperties>() ? StyleLayerType::Line : StyleLayerType::Fill);
- // add to end of other shape layers just before (last) point layer
- style->layers.emplace((style->layers.end() - 1), shapeLayer);
-
- // create shape bucket & connect to source
util::ptr<StyleBucket> shapeBucket = std::make_shared<StyleBucket>(shapeLayer->type);
shapeBucket->name = shapeLayer->id;
- shapeBucket->source = shapeID;
+ shapeBucket->source = ShapeSourceID;
shapeBucket->source_layer = shapeLayer->id;
-
- // apply line layout properties to bucket
if (shapeStyle.is<LineProperties>()) {
shapeBucket->layout.set(PropertyKey::LineJoin, ConstantFunction<JoinType>(JoinType::Round));
}
- // connect layer to bucket
shapeLayer->bucket = shapeBucket;
+ style.addLayer(std::move(shapeLayer), PointSourceID);
}
- // invalidate annotations layer tiles
- for (const auto &source : style->sources) {
- if (source->info.type == SourceType::Annotations) {
- source->invalidateTiles(ids);
- }
- }
+ style.getSource(PointSourceID)->invalidateTiles(stalePointTileIDs);
+ style.getSource(ShapeSourceID)->invalidateTiles();
- staleTiles.clear();
+ stalePointTileIDs.clear();
}
-const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points";
-const std::string AnnotationManager::ShapeLayerID = "com.mapbox.annotations.shape";
+const std::string AnnotationManager::PointSourceID = "com.mapbox.annotations.points";
+const std::string AnnotationManager::ShapeSourceID = "com.mapbox.annotations.shape";
}
diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp
index cf8d8e3e77..248fb798d6 100644
--- a/src/mbgl/annotation/annotation_manager.hpp
+++ b/src/mbgl/annotation/annotation_manager.hpp
@@ -29,48 +29,37 @@ using GeoJSONVT = mapbox::util::geojsonvt::GeoJSONVT;
class AnnotationManager : private util::noncopyable {
public:
- typedef std::unordered_set<TileID, TileID::Hash> AffectedTiles;
-
AnnotationManager();
~AnnotationManager();
void setDefaultPointAnnotationSymbol(const std::string& symbol);
- std::pair<AffectedTiles, AnnotationIDs>
- addPointAnnotations(const std::vector<PointAnnotation>&, const uint8_t maxZoom);
-
- std::pair<AffectedTiles, AnnotationIDs>
- addShapeAnnotations(const std::vector<ShapeAnnotation>&, const uint8_t maxZoom);
-
- AffectedTiles
- removeAnnotations(const AnnotationIDs&, const uint8_t maxZoom);
-
- void updateTilesIfNeeded(Style*);
- void updateTiles(const AffectedTiles&, Style*);
+ AnnotationIDs addPointAnnotations(const std::vector<PointAnnotation>&, const uint8_t maxZoom);
+ AnnotationIDs addShapeAnnotations(const std::vector<ShapeAnnotation>&, const uint8_t maxZoom);
+ void removeAnnotations(const AnnotationIDs&, const uint8_t maxZoom);
AnnotationIDs getAnnotationsInBounds(const LatLngBounds&, const uint8_t maxZoom, const AnnotationType& = AnnotationType::Any) const;
LatLngBounds getBoundsForAnnotations(const AnnotationIDs&) const;
+ void updateStyle(Style&);
const LiveTile* getTile(const TileID& id);
- static const std::string PointLayerID;
- static const std::string ShapeLayerID;
+ static const std::string PointSourceID;
+ static const std::string ShapeSourceID;
private:
inline uint32_t nextID();
static vec2<double> projectPoint(const LatLng& point);
uint32_t addShapeAnnotation(const ShapeAnnotation&, const uint8_t maxZoom);
- uint32_t addPointAnnotation(const PointAnnotation&, const uint8_t maxZoom, AffectedTiles&);
-
- const StyleProperties getAnnotationStyleProperties(uint32_t) const;
+ uint32_t addPointAnnotation(const PointAnnotation&, const uint8_t maxZoom);
std::string defaultPointAnnotationSymbol;
std::unordered_map<uint32_t, std::unique_ptr<Annotation>> annotations;
std::vector<uint32_t> orderedShapeAnnotations;
std::unordered_map<TileID, std::pair<std::unordered_set<uint32_t>, std::unique_ptr<LiveTile>>, TileID::Hash> tiles;
std::unordered_map<uint32_t, std::unique_ptr<GeoJSONVT>> shapeTilers;
- std::unordered_set<TileID, TileID::Hash> staleTiles;
+ std::unordered_set<TileID, TileID::Hash> stalePointTileIDs;
uint32_t nextID_ = 0;
};
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 3e7a61a4e8..4ba8d6cd8f 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -348,8 +348,8 @@ uint32_t Map::addPointAnnotation(const PointAnnotation& annotation) {
AnnotationIDs Map::addPointAnnotations(const std::vector<PointAnnotation>& annotations) {
auto result = data->getAnnotationManager()->addPointAnnotations(annotations, getMaxZoom());
- context->invoke(&MapContext::updateAnnotationTiles, result.first);
- return result.second;
+ update(Update::Annotations);
+ return result;
}
uint32_t Map::addShapeAnnotation(const ShapeAnnotation& annotation) {
@@ -358,8 +358,8 @@ uint32_t Map::addShapeAnnotation(const ShapeAnnotation& annotation) {
AnnotationIDs Map::addShapeAnnotations(const std::vector<ShapeAnnotation>& annotations) {
auto result = data->getAnnotationManager()->addShapeAnnotations(annotations, getMaxZoom());
- context->invoke(&MapContext::updateAnnotationTiles, result.first);
- return result.second;
+ update(Update::Annotations);
+ return result;
}
void Map::removeAnnotation(uint32_t annotation) {
@@ -367,8 +367,8 @@ void Map::removeAnnotation(uint32_t annotation) {
}
void Map::removeAnnotations(const std::vector<uint32_t>& annotations) {
- auto result = data->getAnnotationManager()->removeAnnotations(annotations, getMaxZoom());
- context->invoke(&MapContext::updateAnnotationTiles, result);
+ data->getAnnotationManager()->removeAnnotations(annotations, getMaxZoom());
+ update(Update::Annotations);
}
std::vector<uint32_t> Map::getAnnotationsInBounds(const LatLngBounds& bounds, const AnnotationType& type) {
diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp
index 1c0c98b599..c2b5900b16 100644
--- a/src/mbgl/map/map_context.cpp
+++ b/src/mbgl/map/map_context.cpp
@@ -137,13 +137,7 @@ void MapContext::loadStyleJSON(const std::string& json, const std::string& base)
// force style cascade, causing all pending transitions to complete.
style->cascade();
- updateFlags |= Update::DefaultTransition | Update::Classes | Update::Zoom;
- asyncUpdate->send();
-}
-
-void MapContext::updateAnnotationTiles(const std::unordered_set<TileID, TileID::Hash>& ids) {
- data.getAnnotationManager()->updateTiles(ids, style.get());
- updateFlags |= Update::Classes;
+ updateFlags |= Update::DefaultTransition | Update::Classes | Update::Zoom | Update::Annotations;
asyncUpdate->send();
}
@@ -160,6 +154,11 @@ void MapContext::update() {
data.setAnimationTime(Clock::now());
+ if (style->sprite && updateFlags & Update::Annotations) {
+ data.getAnnotationManager()->updateStyle(*style);
+ updateFlags |= Update::Classes;
+ }
+
if (updateFlags & Update::Classes) {
style->cascade();
}
@@ -313,10 +312,4 @@ void MapContext::onResourceLoadingFailed(std::exception_ptr error) {
}
}
-void MapContext::onSpriteStoreLoaded() {
- data.getAnnotationManager()->updateTilesIfNeeded(style.get());
- updateFlags |= Update::Classes;
- asyncUpdate->send();
-}
-
}
diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp
index f3ac636a40..b78d3283a7 100644
--- a/src/mbgl/map/map_context.hpp
+++ b/src/mbgl/map/map_context.hpp
@@ -54,7 +54,7 @@ public:
bool isLoaded() const;
double getTopOffsetPixelsForAnnotationSymbol(const std::string& symbol);
- void updateAnnotationTiles(const std::unordered_set<TileID, TileID::Hash>&);
+ void updateAnnotations();
void setSourceTileCacheSize(size_t size);
void onLowMemory();
@@ -66,7 +66,6 @@ public:
// Style::Observer implementation.
void onTileDataChanged() override;
void onResourceLoadingFailed(std::exception_ptr error) override;
- void onSpriteStoreLoaded() override;
private:
// Update the state indicated by the accumulated Update flags, then render.
diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp
index 572973b79a..989d2eb75d 100644
--- a/src/mbgl/map/source.cpp
+++ b/src/mbgl/map/source.cpp
@@ -515,18 +515,20 @@ bool Source::update(MapData& data,
void Source::invalidateTiles(const std::unordered_set<TileID, TileID::Hash>& ids) {
cache.clear();
- if (!ids.empty()) {
- for (auto& id : ids) {
- tiles.erase(id);
- tile_data.erase(id);
- }
- } else {
- tiles.clear();
- tile_data.clear();
+ for (const auto& id : ids) {
+ tiles.erase(id);
+ tile_data.erase(id);
}
updateTilePtrs();
}
+void Source::invalidateTiles() {
+ cache.clear();
+ tiles.clear();
+ tile_data.clear();
+ updateTilePtrs();
+}
+
void Source::updateTilePtrs() {
tilePtrs.clear();
for (const auto& pair : tiles) {
diff --git a/src/mbgl/map/source.hpp b/src/mbgl/map/source.hpp
index 336caa5b93..421f819640 100644
--- a/src/mbgl/map/source.hpp
+++ b/src/mbgl/map/source.hpp
@@ -78,6 +78,7 @@ public:
bool shouldReparsePartialTiles);
void invalidateTiles(const std::unordered_set<TileID, TileID::Hash>&);
+ void invalidateTiles();
void updateMatrices(const mat4 &projMatrix, const TransformState &transform);
void drawClippingMasks(Painter &painter);
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index d4c9bd4e56..7945a45b1d 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -44,18 +44,18 @@ void Style::setJSON(const std::string& json, const std::string&) {
StyleParser parser(data);
parser.parse(doc);
- sources = parser.getSources();
- layers = parser.getLayers();
+ for (auto& source : parser.getSources()) {
+ addSource(std::move(source));
+ }
+
+ for (auto& layer : parser.getLayers()) {
+ addLayer(std::move(layer));
+ }
sprite = std::make_unique<Sprite>(parser.getSprite(), data.pixelRatio);
sprite->setObserver(this);
glyphStore->setURL(parser.getGlyphURL());
-
- for (const auto& source : sources) {
- source->setObserver(this);
- source->load();
- }
}
Style::~Style() {
@@ -70,6 +70,20 @@ Style::~Style() {
}
}
+void Style::addSource(std::unique_ptr<Source> source) {
+ source->setObserver(this);
+ source->load();
+ sources.emplace_back(std::move(source));
+}
+
+void Style::addLayer(util::ptr<StyleLayer> layer) {
+ layers.emplace_back(std::move(layer));
+}
+
+void Style::addLayer(util::ptr<StyleLayer> layer, const std::string& before) {
+ layers.emplace(std::find_if(layers.begin(), layers.end(), [&](const auto& l) { return l->id == before; }), std::move(layer));
+}
+
void Style::update(const TransformState& transform,
TexturePool& texturePool) {
bool allTilesUpdated = true;
@@ -126,6 +140,14 @@ Source* Style::getSource(const std::string& id) const {
return it != sources.end() ? it->get() : nullptr;
}
+StyleLayer* Style::getLayer(const std::string& id) const {
+ const auto it = std::find_if(layers.begin(), layers.end(), [&](const auto& layer) {
+ return layer->id == id;
+ });
+
+ return it != layers.end() ? it->get() : nullptr;
+}
+
bool Style::hasTransitions() const {
for (const auto& layer : layers) {
if (layer->hasTransitions()) {
@@ -190,10 +212,6 @@ void Style::onSpriteLoaded(const Sprites& sprites) {
// Add all sprite images to the SpriteStore object
spriteStore->setSprites(sprites);
- if (observer) {
- observer->onSpriteStoreLoaded();
- }
-
shouldReparsePartialTiles = true;
emitTileDataChanged();
}
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index 3f9696ffbf..9c5091863e 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -39,7 +39,6 @@ public:
virtual ~Observer() = default;
virtual void onTileDataChanged() = 0;
- virtual void onSpriteStoreLoaded() = 0;
virtual void onResourceLoadingFailed(std::exception_ptr error) = 0;
};
@@ -63,6 +62,11 @@ public:
}
Source* getSource(const std::string& id) const;
+ StyleLayer* getLayer(const std::string& id) const;
+
+ void addSource(std::unique_ptr<Source>);
+ void addLayer(util::ptr<StyleLayer>);
+ void addLayer(util::ptr<StyleLayer>, const std::string& beforeLayerID);
MapData& data;
std::unique_ptr<GlyphStore> glyphStore;
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp
index 2e298e9a6c..04c3a45553 100644
--- a/src/mbgl/style/style_parser.cpp
+++ b/src/mbgl/style/style_parser.cpp
@@ -1,7 +1,6 @@
#include <mbgl/style/style_parser.hpp>
#include <mbgl/map/source.hpp>
#include <mbgl/style/style_layer.hpp>
-#include <mbgl/annotation/annotation_manager.hpp>
#include <mbgl/map/map_data.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/vec.hpp>
@@ -40,47 +39,6 @@ void StyleParser::parse(JSVal document) {
if (document.HasMember("layers")) {
parseLayers(document["layers"]);
-
- // create shape annotations source
- const std::string& shapeID = AnnotationManager::ShapeLayerID;
-
- std::unique_ptr<Source> shapeAnnotationsSource = std::make_unique<Source>();
- shapeAnnotationsSource->info.type = SourceType::Annotations;
- shapeAnnotationsSource->info.source_id = shapeID;
- sourcesMap.emplace(shapeID, shapeAnnotationsSource.get());
- sources.emplace_back(std::move(shapeAnnotationsSource));
-
- // create point annotations layer
- const std::string& pointID = AnnotationManager::PointLayerID;
-
- std::map<ClassID, ClassProperties> pointPaints;
- util::ptr<StyleLayer> pointAnnotationsLayer = std::make_shared<StyleLayer>(pointID, std::move(pointPaints));
- pointAnnotationsLayer->type = StyleLayerType::Symbol;
- layersMap.emplace(pointID, std::pair<JSVal, util::ptr<StyleLayer>> { JSVal(pointID), pointAnnotationsLayer });
- layers.emplace_back(pointAnnotationsLayer);
-
- // create point annotations symbol bucket
- util::ptr<StyleBucket> pointBucket = std::make_shared<StyleBucket>(pointAnnotationsLayer->type);
- pointBucket->name = pointAnnotationsLayer->id;
- pointBucket->source = pointID;
- pointBucket->source_layer = pointAnnotationsLayer->id;
-
- // build up point annotations style
- rapidjson::Document d;
- rapidjson::Value iconImage(rapidjson::kObjectType);
- iconImage.AddMember("icon-image", "{sprite}", d.GetAllocator());
- parseLayout(iconImage, pointBucket);
- rapidjson::Value iconOverlap(rapidjson::kObjectType);
- iconOverlap.AddMember("icon-allow-overlap", true, d.GetAllocator());
- parseLayout(iconOverlap, pointBucket);
-
- // create point annotations source & connect to bucket & layer
- std::unique_ptr<Source> pointAnnotationsSource = std::make_unique<Source>();
- pointAnnotationsSource->info.type = SourceType::Annotations;
- pointAnnotationsSource->info.source_id = pointID;
- pointAnnotationsLayer->bucket = pointBucket;
- sourcesMap.emplace(pointID, pointAnnotationsSource.get());
- sources.emplace_back(std::move(pointAnnotationsSource));
}
if (document.HasMember("sprite")) {