Move updateAnnotationTiles[IfNeeded] to AnnotationManager
This commit is contained in:
@@ -7,6 +7,9 @@
|
||||
#include <mbgl/util/geojsonvt/geojsonvt_convert.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/style_bucket.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -63,14 +66,6 @@ AnnotationManager::~AnnotationManager() {
|
||||
// Annotation so we can't destruct the object with just the header file.
|
||||
}
|
||||
|
||||
void AnnotationManager::markStaleTiles(std::unordered_set<TileID, TileID::Hash> ids) {
|
||||
std::copy(ids.begin(), ids.end(), std::inserter(staleTiles, staleTiles.begin()));
|
||||
}
|
||||
|
||||
std::unordered_set<TileID, TileID::Hash> AnnotationManager::resetStaleTiles() {
|
||||
return std::move(staleTiles);
|
||||
}
|
||||
|
||||
void AnnotationManager::setDefaultPointAnnotationSymbol(const std::string& symbol) {
|
||||
defaultPointAnnotationSymbol = symbol;
|
||||
}
|
||||
@@ -322,13 +317,6 @@ std::unordered_set<TileID, TileID::Hash> AnnotationManager::removeAnnotations(co
|
||||
return affectedTiles;
|
||||
}
|
||||
|
||||
const StyleProperties AnnotationManager::getAnnotationStyleProperties(uint32_t annotationID) const {
|
||||
auto anno_it = annotations.find(annotationID);
|
||||
assert(anno_it != annotations.end());
|
||||
|
||||
return anno_it->second->styleProperties;
|
||||
}
|
||||
|
||||
AnnotationIDs AnnotationManager::getAnnotationsInBounds(const LatLngBounds& queryBounds,
|
||||
const uint8_t maxZoom,
|
||||
const AnnotationType& type) const {
|
||||
@@ -490,6 +478,91 @@ const LiveTile* AnnotationManager::getTile(const TileID& id) {
|
||||
return renderTile;
|
||||
}
|
||||
|
||||
void AnnotationManager::updateTilesIfNeeded(Style* style) {
|
||||
if (!staleTiles.empty()) {
|
||||
updateTiles(staleTiles, style);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// apply shape paint properties
|
||||
const StyleProperties& shapeStyle = annotations.at(shapeAnnotationID)->styleProperties;
|
||||
ClassProperties paintProperties;
|
||||
|
||||
if (shapeStyle.is<LineProperties>()) {
|
||||
const LineProperties& lineProperties = shapeStyle.get<LineProperties>();
|
||||
paintProperties.set(PropertyKey::LineOpacity, ConstantFunction<float>(lineProperties.opacity));
|
||||
paintProperties.set(PropertyKey::LineWidth, ConstantFunction<float>(lineProperties.width));
|
||||
paintProperties.set(PropertyKey::LineColor, ConstantFunction<Color>(lineProperties.color));
|
||||
} else if (shapeStyle.is<FillProperties>()) {
|
||||
const FillProperties& fillProperties = shapeStyle.get<FillProperties>();
|
||||
paintProperties.set(PropertyKey::FillOpacity, ConstantFunction<float>(fillProperties.opacity));
|
||||
paintProperties.set(PropertyKey::FillColor, ConstantFunction<Color>(fillProperties.fill_color));
|
||||
paintProperties.set(PropertyKey::FillOutlineColor, ConstantFunction<Color>(fillProperties.stroke_color));
|
||||
}
|
||||
|
||||
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() - 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_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;
|
||||
}
|
||||
|
||||
// invalidate annotations layer tiles
|
||||
for (const auto &source : style->sources) {
|
||||
if (source->info.type == SourceType::Annotations) {
|
||||
source->invalidateTiles(ids);
|
||||
}
|
||||
}
|
||||
|
||||
staleTiles.clear();
|
||||
}
|
||||
|
||||
const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points";
|
||||
const std::string AnnotationManager::ShapeLayerID = "com.mapbox.annotations.shape";
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ class Annotation;
|
||||
class PointAnnotation;
|
||||
class ShapeAnnotation;
|
||||
class LiveTile;
|
||||
class Style;
|
||||
|
||||
using GeoJSONVT = mapbox::util::geojsonvt::GeoJSONVT;
|
||||
|
||||
@@ -33,10 +34,6 @@ public:
|
||||
AnnotationManager();
|
||||
~AnnotationManager();
|
||||
|
||||
void markStaleTiles(std::unordered_set<TileID, TileID::Hash>);
|
||||
size_t getStaleTileCount() const { return staleTiles.size(); }
|
||||
std::unordered_set<TileID, TileID::Hash> resetStaleTiles();
|
||||
|
||||
void setDefaultPointAnnotationSymbol(const std::string& symbol);
|
||||
|
||||
std::pair<AffectedTiles, AnnotationIDs>
|
||||
@@ -48,8 +45,8 @@ public:
|
||||
AffectedTiles
|
||||
removeAnnotations(const AnnotationIDs&, const uint8_t maxZoom);
|
||||
|
||||
AnnotationIDs getOrderedShapeAnnotations() const { return orderedShapeAnnotations; }
|
||||
const StyleProperties getAnnotationStyleProperties(uint32_t) const;
|
||||
void updateTilesIfNeeded(Style*);
|
||||
void updateTiles(const AffectedTiles&, Style*);
|
||||
|
||||
AnnotationIDs getAnnotationsInBounds(const LatLngBounds&, const uint8_t maxZoom, const AnnotationType& = AnnotationType::Any) const;
|
||||
LatLngBounds getBoundsForAnnotations(const AnnotationIDs&) const;
|
||||
@@ -66,7 +63,8 @@ private:
|
||||
uint32_t addShapeAnnotation(const ShapeAnnotation&, const uint8_t maxZoom);
|
||||
uint32_t addPointAnnotation(const PointAnnotation&, const uint8_t maxZoom, AffectedTiles&);
|
||||
|
||||
private:
|
||||
const StyleProperties getAnnotationStyleProperties(uint32_t) const;
|
||||
|
||||
std::string defaultPointAnnotationSymbol;
|
||||
std::unordered_map<uint32_t, std::unique_ptr<Annotation>> annotations;
|
||||
std::vector<uint32_t> orderedShapeAnnotations;
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/style_bucket.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
#include <mbgl/util/uv_detail.hpp>
|
||||
@@ -143,113 +141,10 @@ void MapContext::loadStyleJSON(const std::string& json, const std::string& base)
|
||||
asyncUpdate->send();
|
||||
}
|
||||
|
||||
void MapContext::updateAnnotationTilesIfNeeded() {
|
||||
if (data.getAnnotationManager()->getStaleTileCount()) {
|
||||
auto staleTiles = data.getAnnotationManager()->resetStaleTiles();
|
||||
updateAnnotationTiles(staleTiles);
|
||||
}
|
||||
}
|
||||
|
||||
void MapContext::updateAnnotationTiles(const std::unordered_set<TileID, TileID::Hash>& ids) {
|
||||
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
util::exclusive<AnnotationManager> annotationManager = data.getAnnotationManager();
|
||||
annotationManager->markStaleTiles(ids);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
shapeAnnotationSource->enabled = true;
|
||||
|
||||
// create (if necessary) layers and buckets for each shape
|
||||
for (const auto &shapeAnnotationID : annotationManager->getOrderedShapeAnnotations()) {
|
||||
const std::string shapeLayerID = shapeID + "." + util::toString(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 = 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() - 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_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;
|
||||
}
|
||||
}
|
||||
|
||||
// invalidate annotations layer tiles
|
||||
for (const auto &source : style->sources) {
|
||||
if (source->info.type == SourceType::Annotations) {
|
||||
source->invalidateTiles(ids);
|
||||
}
|
||||
}
|
||||
|
||||
data.getAnnotationManager()->updateTiles(ids, style.get());
|
||||
updateFlags |= Update::Classes;
|
||||
asyncUpdate->send();
|
||||
|
||||
annotationManager->resetStaleTiles();
|
||||
}
|
||||
|
||||
void MapContext::update() {
|
||||
@@ -419,7 +314,9 @@ void MapContext::onResourceLoadingFailed(std::exception_ptr error) {
|
||||
}
|
||||
|
||||
void MapContext::onSpriteStoreLoaded() {
|
||||
updateAnnotationTilesIfNeeded();
|
||||
data.getAnnotationManager()->updateTilesIfNeeded(style.get());
|
||||
updateFlags |= Update::Classes;
|
||||
asyncUpdate->send();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ public:
|
||||
bool isLoaded() const;
|
||||
|
||||
double getTopOffsetPixelsForAnnotationSymbol(const std::string& symbol);
|
||||
void updateAnnotationTilesIfNeeded();
|
||||
void updateAnnotationTiles(const std::unordered_set<TileID, TileID::Hash>&);
|
||||
|
||||
void setSourceTileCacheSize(size_t size);
|
||||
|
||||
Reference in New Issue
Block a user