diff options
Diffstat (limited to 'src/mbgl/map/map_context.cpp')
-rw-r--r-- | src/mbgl/map/map_context.cpp | 114 |
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(); |