summaryrefslogtreecommitdiff
path: root/src/mbgl/map/map_context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/map/map_context.cpp')
-rw-r--r--src/mbgl/map/map_context.cpp114
1 files changed, 110 insertions, 4 deletions
diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp
index c349bdd155..bd288a5cda 100644
--- a/src/mbgl/map/map_context.cpp
+++ b/src/mbgl/map/map_context.cpp
@@ -3,6 +3,7 @@
#include <mbgl/map/view.hpp>
#include <mbgl/map/environment.hpp>
#include <mbgl/map/still_image.hpp>
+#include <mbgl/map/annotation.hpp>
#include <mbgl/platform/log.hpp>
@@ -12,12 +13,16 @@
#include <mbgl/storage/response.hpp>
#include <mbgl/style/style.hpp>
+#include <mbgl/style/style_bucket.hpp>
+#include <mbgl/style/style_layer.hpp>
#include <mbgl/util/uv_detail.hpp>
#include <mbgl/util/worker.hpp>
#include <mbgl/util/texture_pool.hpp>
#include <mbgl/util/exception.hpp>
+#include <algorithm>
+
namespace mbgl {
MapContext::MapContext(uv_loop_t* loop, View& view_, FileSource& fileSource, MapData& data_)
@@ -112,6 +117,11 @@ void MapContext::loadStyleJSON(const std::string& json, const std::string& base)
style->setObserver(this);
triggerUpdate(Update::Zoom);
+
+ auto staleTiles = data.annotationManager.resetStaleTiles();
+ if (staleTiles.size()) {
+ updateAnnotationTiles(staleTiles);
+ }
}
void MapContext::updateTiles() {
@@ -120,15 +130,111 @@ void MapContext::updateTiles() {
style->update(data, transformState, *texturePool);
}
-void MapContext::updateAnnotationTiles(const std::vector<TileID>& ids) {
+void MapContext::updateAnnotationTiles(const std::unordered_set<TileID, TileID::Hash>& ids) {
assert(Environment::currentlyOn(ThreadType::Map));
+
+ data.annotationManager.markStaleTiles(ids);
+
if (!style) return;
+
+ // grab existing, single shape annotations source
+ const auto& shapeID = AnnotationManager::ShapeLayerID;
+
+ const auto source_it = std::find_if(style->sources.begin(), style->sources.end(),
+ [&shapeID](util::ptr<Source> source) {
+ return (source->info.source_id == shapeID);
+ });
+ assert(source_it != style->sources.end());
+ source_it->get()->enabled = true;
+
+ // create (if necessary) layers and buckets for each shape
+ for (const auto &shapeAnnotationID : data.annotationManager.getOrderedShapeAnnotations()) {
+ const std::string shapeLayerID = shapeID + "." + std::to_string(shapeAnnotationID);
+
+ const auto layer_it = std::find_if(style->layers.begin(), style->layers.end(),
+ [&shapeLayerID](util::ptr<StyleLayer> layer) {
+ return (layer->id == shapeLayerID);
+ });
+
+ if (layer_it == style->layers.end()) {
+ // query shape styling
+ auto& shapeStyle = data.annotationManager.getAnnotationStyleProperties(shapeAnnotationID);
+
+ // apply shape paint properties
+ ClassProperties paintProperties;
+
+ if (shapeStyle.is<LineProperties>()) {
+ // opacity
+ PropertyValue lineOpacity = ConstantFunction<float>(shapeStyle.get<LineProperties>().opacity);
+ paintProperties.set(PropertyKey::LineOpacity, lineOpacity);
+
+ // line width
+ PropertyValue lineWidth = ConstantFunction<float>(shapeStyle.get<LineProperties>().width);
+ paintProperties.set(PropertyKey::LineWidth, lineWidth);
+
+ // stroke color
+ PropertyValue strokeColor = ConstantFunction<Color>(shapeStyle.get<LineProperties>().color);
+ paintProperties.set(PropertyKey::LineColor, strokeColor);
+ } else if (shapeStyle.is<FillProperties>()) {
+ // opacity
+ PropertyValue fillOpacity = ConstantFunction<float>(shapeStyle.get<FillProperties>().opacity);
+ paintProperties.set(PropertyKey::FillOpacity, fillOpacity);
+
+ // fill color
+ PropertyValue fillColor = ConstantFunction<Color>(shapeStyle.get<FillProperties>().fill_color);
+ paintProperties.set(PropertyKey::FillColor, fillColor);
+
+ // stroke color
+ PropertyValue strokeColor = ConstantFunction<Color>(shapeStyle.get<FillProperties>().stroke_color);
+ paintProperties.set(PropertyKey::FillOutlineColor, strokeColor);
+ }
+
+ 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));
+ 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() - 2), shapeLayer);
+
+ // create shape bucket & connect to source
+ util::ptr<StyleBucket> shapeBucket = std::make_shared<StyleBucket>(shapeLayer->type);
+ shapeBucket->name = shapeLayer->id;
+ shapeBucket->source_layer = shapeLayer->id;
+ shapeBucket->source = *source_it;
+
+ // 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;
+ }
+ }
+
+ // invalidate annotations layer tiles
for (const auto &source : style->sources) {
if (source->info.type == SourceType::Annotations) {
source->invalidateTiles(ids);
}
}
- triggerUpdate();
+
+ cascadeClasses();
+
+ triggerUpdate(Update::Classes);
+
+ data.annotationManager.resetStaleTiles();
+}
+
+void MapContext::cascadeClasses() {
+ style->cascade(data.getClasses());
+}
+
+void MapContext::recalculateStyle(TimePoint now) {
+ style->recalculate(transformState.getNormalizedZoom(), now);
}
void MapContext::update() {
@@ -146,12 +252,12 @@ void MapContext::update() {
}
if (updated & static_cast<UpdateType>(Update::Classes)) {
- style->cascade(data.getClasses());
+ cascadeClasses();
}
if (updated & static_cast<UpdateType>(Update::Classes) ||
updated & static_cast<UpdateType>(Update::Zoom)) {
- style->recalculate(transformState.getNormalizedZoom(), now);
+ recalculateStyle(now);
}
updateTiles();