[core] Add feature state support to bucket classes
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include <mapbox/feature.hpp>
|
||||
|
||||
@@ -32,4 +33,27 @@ optional<T> numericValue(const Value& value) {
|
||||
});
|
||||
}
|
||||
|
||||
inline optional<std::string> featureIDtoString(const FeatureIdentifier& id) {
|
||||
if (id.is<NullValue>()) {
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
return id.match(
|
||||
[] (const std::string& value_) {
|
||||
return value_;
|
||||
},
|
||||
[] (uint64_t value_) {
|
||||
return util::toString(value_);
|
||||
},
|
||||
[] (int64_t value_) {
|
||||
return util::toString(value_);
|
||||
},
|
||||
[] (double value_) {
|
||||
return util::toString(value_);
|
||||
},
|
||||
[] (const auto&) -> optional<std::string> {
|
||||
return nullopt;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -20,6 +20,11 @@ public:
|
||||
v.resize(v.size() + n, val);
|
||||
}
|
||||
|
||||
Vertex& at(std::size_t n) {
|
||||
assert(n < v.size());
|
||||
return v.at(n);
|
||||
}
|
||||
|
||||
std::size_t elements() const {
|
||||
return v.size();
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
const PatternLayerMap& patterns = patternFeature.patterns;
|
||||
const GeometryCollection& geometries = feature->getGeometries();
|
||||
|
||||
bucket->addFeature(*feature, geometries, patternPositions, patterns);
|
||||
bucket->addFeature(*feature, geometries, patternPositions, patterns, i);
|
||||
featureIndex->insert(geometries, i, sourceLayerID, bucketLeaderID);
|
||||
}
|
||||
if (bucket->hasData()) {
|
||||
|
||||
@@ -713,7 +713,7 @@ void SymbolLayout::createBucket(const ImagePositions&, std::unique_ptr<FeatureIn
|
||||
}
|
||||
|
||||
for (auto& pair : bucket->paintProperties) {
|
||||
pair.second.iconBinders.populateVertexVectors(feature, iconBuffer.vertices.elements(), {}, {});
|
||||
pair.second.iconBinders.populateVertexVectors(feature, iconBuffer.vertices.elements(), symbolInstance.dataFeatureIndex, {}, {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -765,7 +765,7 @@ void SymbolLayout::updatePaintPropertiesForSection(SymbolBucket& bucket,
|
||||
std::size_t sectionIndex) {
|
||||
const auto& formattedSection = sectionOptionsToValue((*feature.formattedText).sectionAt(sectionIndex));
|
||||
for (auto& pair : bucket.paintProperties) {
|
||||
pair.second.textBinders.populateVertexVectors(feature, bucket.text.vertices.elements(), {}, {}, formattedSection);
|
||||
pair.second.textBinders.populateVertexVectors(feature, bucket.text.vertices.elements(), feature.index, {}, {}, formattedSection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,11 @@ public:
|
||||
virtual void addFeature(const GeometryTileFeature&,
|
||||
const GeometryCollection&,
|
||||
const ImagePositions&,
|
||||
const PatternLayerMap&) {};
|
||||
const PatternLayerMap&,
|
||||
std::size_t) {};
|
||||
|
||||
virtual void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) {}
|
||||
|
||||
|
||||
// As long as this bucket has a Prepare render pass, this function is getting called. Typically,
|
||||
// this only happens once when the bucket is being rendered for the first time.
|
||||
|
||||
@@ -25,8 +25,10 @@ CircleBucket::CircleBucket(const BucketParameters& parameters, const std::vector
|
||||
CircleBucket::~CircleBucket() = default;
|
||||
|
||||
void CircleBucket::upload(gfx::UploadPass& uploadPass) {
|
||||
vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices));
|
||||
indexBuffer = uploadPass.createIndexBuffer(std::move(triangles));
|
||||
if (!uploaded) {
|
||||
vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices));
|
||||
indexBuffer = uploadPass.createIndexBuffer(std::move(triangles));
|
||||
}
|
||||
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
pair.second.upload(uploadPass);
|
||||
@@ -42,7 +44,8 @@ bool CircleBucket::hasData() const {
|
||||
void CircleBucket::addFeature(const GeometryTileFeature& feature,
|
||||
const GeometryCollection& geometry,
|
||||
const ImagePositions&,
|
||||
const PatternLayerMap&) {
|
||||
const PatternLayerMap&,
|
||||
std::size_t featureIndex) {
|
||||
constexpr const uint16_t vertexLength = 4;
|
||||
|
||||
for (auto& circle : geometry) {
|
||||
@@ -90,7 +93,7 @@ void CircleBucket::addFeature(const GeometryTileFeature& feature,
|
||||
}
|
||||
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), {}, {});
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), featureIndex, {}, {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,4 +115,12 @@ float CircleBucket::getQueryRadius(const RenderLayer& layer) const {
|
||||
return radius + stroke + util::length(translate[0], translate[1]);
|
||||
}
|
||||
|
||||
void CircleBucket::update(const FeatureStates& states, const GeometryTileLayer& layer, const std::string& layerID, const ImagePositions& imagePositions) {
|
||||
auto it = paintPropertyBinders.find(layerID);
|
||||
if (it != paintPropertyBinders.end()) {
|
||||
it->second.updateVertexVectors(states, layer, imagePositions);
|
||||
uploaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -21,7 +21,8 @@ public:
|
||||
void addFeature(const GeometryTileFeature&,
|
||||
const GeometryCollection&,
|
||||
const ImagePositions&,
|
||||
const PatternLayerMap&) override;
|
||||
const PatternLayerMap&,
|
||||
std::size_t) override;
|
||||
|
||||
bool hasData() const override;
|
||||
|
||||
@@ -29,6 +30,8 @@ public:
|
||||
|
||||
float getQueryRadius(const RenderLayer&) const override;
|
||||
|
||||
void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) override;
|
||||
|
||||
gfx::VertexVector<CircleLayoutVertex> vertices;
|
||||
gfx::IndexVector<gfx::Triangles> triangles;
|
||||
SegmentVector<CircleAttributes> segments;
|
||||
|
||||
@@ -47,7 +47,8 @@ FillBucket::~FillBucket() = default;
|
||||
void FillBucket::addFeature(const GeometryTileFeature& feature,
|
||||
const GeometryCollection& geometry,
|
||||
const ImagePositions& patternPositions,
|
||||
const PatternLayerMap& patternDependencies) {
|
||||
const PatternLayerMap& patternDependencies,
|
||||
std::size_t index) {
|
||||
for (auto& polygon : classifyRings(geometry)) {
|
||||
// Optimize polygons with many interior rings for earcut tesselation.
|
||||
limitHoles(polygon, 500);
|
||||
@@ -114,17 +115,19 @@ void FillBucket::addFeature(const GeometryTileFeature& feature,
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
const auto it = patternDependencies.find(pair.first);
|
||||
if (it != patternDependencies.end()){
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, it->second);
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, it->second);
|
||||
} else {
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, {});
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FillBucket::upload(gfx::UploadPass& uploadPass) {
|
||||
vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices));
|
||||
lineIndexBuffer = uploadPass.createIndexBuffer(std::move(lines));
|
||||
triangleIndexBuffer = triangles.empty() ? optional<gfx::IndexBuffer> {} : uploadPass.createIndexBuffer(std::move(triangles));
|
||||
if (!uploaded) {
|
||||
vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices));
|
||||
lineIndexBuffer = uploadPass.createIndexBuffer(std::move(lines));
|
||||
triangleIndexBuffer = triangles.empty() ? optional<gfx::IndexBuffer> {} : uploadPass.createIndexBuffer(std::move(triangles));
|
||||
}
|
||||
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
pair.second.upload(uploadPass);
|
||||
@@ -143,4 +146,12 @@ float FillBucket::getQueryRadius(const RenderLayer& layer) const {
|
||||
return util::length(translate[0], translate[1]);
|
||||
}
|
||||
|
||||
void FillBucket::update(const FeatureStates& states, const GeometryTileLayer& layer, const std::string& layerID, const ImagePositions& imagePositions) {
|
||||
auto it = paintPropertyBinders.find(layerID);
|
||||
if (it != paintPropertyBinders.end()) {
|
||||
it->second.updateVertexVectors(states, layer, imagePositions);
|
||||
uploaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -29,7 +29,8 @@ public:
|
||||
void addFeature(const GeometryTileFeature&,
|
||||
const GeometryCollection&,
|
||||
const mbgl::ImagePositions&,
|
||||
const PatternLayerMap&) override;
|
||||
const PatternLayerMap&,
|
||||
std::size_t) override;
|
||||
|
||||
bool hasData() const override;
|
||||
|
||||
@@ -37,6 +38,8 @@ public:
|
||||
|
||||
float getQueryRadius(const RenderLayer&) const override;
|
||||
|
||||
void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) override;
|
||||
|
||||
gfx::VertexVector<FillLayoutVertex> vertices;
|
||||
gfx::IndexVector<gfx::Lines> lines;
|
||||
gfx::IndexVector<gfx::Triangles> triangles;
|
||||
|
||||
@@ -53,7 +53,8 @@ FillExtrusionBucket::~FillExtrusionBucket() = default;
|
||||
void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature,
|
||||
const GeometryCollection& geometry,
|
||||
const ImagePositions& patternPositions,
|
||||
const PatternLayerMap& patternDependencies) {
|
||||
const PatternLayerMap& patternDependencies,
|
||||
std::size_t index) {
|
||||
for (auto& polygon : classifyRings(geometry)) {
|
||||
// Optimize polygons with many interior rings for earcut tesselation.
|
||||
limitHoles(polygon, 500);
|
||||
@@ -158,16 +159,18 @@ void FillExtrusionBucket::addFeature(const GeometryTileFeature& feature,
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
const auto it = patternDependencies.find(pair.first);
|
||||
if (it != patternDependencies.end()){
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, it->second);
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, it->second);
|
||||
} else {
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, {});
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FillExtrusionBucket::upload(gfx::UploadPass& uploadPass) {
|
||||
vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices));
|
||||
indexBuffer = uploadPass.createIndexBuffer(std::move(triangles));
|
||||
if (!uploaded) {
|
||||
vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices));
|
||||
indexBuffer = uploadPass.createIndexBuffer(std::move(triangles));
|
||||
}
|
||||
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
pair.second.upload(uploadPass);
|
||||
@@ -186,4 +189,12 @@ float FillExtrusionBucket::getQueryRadius(const RenderLayer& layer) const {
|
||||
return util::length(translate[0], translate[1]);
|
||||
}
|
||||
|
||||
void FillExtrusionBucket::update(const FeatureStates& states, const GeometryTileLayer& layer, const std::string& layerID, const ImagePositions& imagePositions) {
|
||||
auto it = paintPropertyBinders.find(layerID);
|
||||
if (it != paintPropertyBinders.end()) {
|
||||
it->second.updateVertexVectors(states, layer, imagePositions);
|
||||
uploaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -27,7 +27,8 @@ public:
|
||||
void addFeature(const GeometryTileFeature&,
|
||||
const GeometryCollection&,
|
||||
const mbgl::ImagePositions&,
|
||||
const PatternLayerMap&) override;
|
||||
const PatternLayerMap&,
|
||||
std::size_t) override;
|
||||
|
||||
bool hasData() const override;
|
||||
|
||||
@@ -35,6 +36,8 @@ public:
|
||||
|
||||
float getQueryRadius(const RenderLayer&) const override;
|
||||
|
||||
void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) override;
|
||||
|
||||
gfx::VertexVector<FillExtrusionLayoutVertex> vertices;
|
||||
gfx::IndexVector<gfx::Triangles> triangles;
|
||||
SegmentVector<FillExtrusionAttributes> triangleSegments;
|
||||
|
||||
@@ -42,7 +42,8 @@ bool HeatmapBucket::hasData() const {
|
||||
void HeatmapBucket::addFeature(const GeometryTileFeature& feature,
|
||||
const GeometryCollection& geometry,
|
||||
const ImagePositions&,
|
||||
const PatternLayerMap&) {
|
||||
const PatternLayerMap&,
|
||||
std::size_t featureIndex) {
|
||||
constexpr const uint16_t vertexLength = 4;
|
||||
|
||||
for (auto& points : geometry) {
|
||||
@@ -89,7 +90,7 @@ void HeatmapBucket::addFeature(const GeometryTileFeature& feature,
|
||||
}
|
||||
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), {}, {});
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), featureIndex, {}, {});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ public:
|
||||
void addFeature(const GeometryTileFeature&,
|
||||
const GeometryCollection&,
|
||||
const ImagePositions&,
|
||||
const PatternLayerMap&) override;
|
||||
const PatternLayerMap&,
|
||||
std::size_t) override;
|
||||
bool hasData() const override;
|
||||
|
||||
void upload(gfx::UploadPass&) override;
|
||||
|
||||
@@ -33,7 +33,8 @@ LineBucket::~LineBucket() = default;
|
||||
void LineBucket::addFeature(const GeometryTileFeature& feature,
|
||||
const GeometryCollection& geometryCollection,
|
||||
const ImagePositions& patternPositions,
|
||||
const PatternLayerMap& patternDependencies) {
|
||||
const PatternLayerMap& patternDependencies,
|
||||
std::size_t index) {
|
||||
for (auto& line : geometryCollection) {
|
||||
addGeometry(line, feature);
|
||||
}
|
||||
@@ -41,9 +42,9 @@ void LineBucket::addFeature(const GeometryTileFeature& feature,
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
const auto it = patternDependencies.find(pair.first);
|
||||
if (it != patternDependencies.end()){
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, it->second);
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, it->second);
|
||||
} else {
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), patternPositions, {});
|
||||
pair.second.populateVertexVectors(feature, vertices.elements(), index, patternPositions, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -517,8 +518,10 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
|
||||
}
|
||||
|
||||
void LineBucket::upload(gfx::UploadPass& uploadPass) {
|
||||
vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices));
|
||||
indexBuffer = uploadPass.createIndexBuffer(std::move(triangles));
|
||||
if (!uploaded) {
|
||||
vertexBuffer = uploadPass.createVertexBuffer(std::move(vertices));
|
||||
indexBuffer = uploadPass.createIndexBuffer(std::move(triangles));
|
||||
}
|
||||
|
||||
for (auto& pair : paintPropertyBinders) {
|
||||
pair.second.upload(uploadPass);
|
||||
@@ -554,4 +557,12 @@ float LineBucket::getQueryRadius(const RenderLayer& layer) const {
|
||||
return lineWidth / 2.0f + std::abs(offset) + util::length(translate[0], translate[1]);
|
||||
}
|
||||
|
||||
void LineBucket::update(const FeatureStates& states, const GeometryTileLayer& layer, const std::string& layerID, const ImagePositions& imagePositions) {
|
||||
auto it = paintPropertyBinders.find(layerID);
|
||||
if (it != paintPropertyBinders.end()) {
|
||||
it->second.updateVertexVectors(states, layer, imagePositions);
|
||||
uploaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -29,7 +29,8 @@ public:
|
||||
void addFeature(const GeometryTileFeature&,
|
||||
const GeometryCollection&,
|
||||
const mbgl::ImagePositions& patternPositions,
|
||||
const PatternLayerMap&) override;
|
||||
const PatternLayerMap&,
|
||||
std::size_t) override;
|
||||
|
||||
bool hasData() const override;
|
||||
|
||||
@@ -37,6 +38,8 @@ public:
|
||||
|
||||
float getQueryRadius(const RenderLayer&) const override;
|
||||
|
||||
void update(const FeatureStates&, const GeometryTileLayer&, const std::string&, const ImagePositions&) override;
|
||||
|
||||
PossiblyEvaluatedLayoutProperties layout;
|
||||
|
||||
gfx::VertexVector<LineLayoutVertex> vertices;
|
||||
|
||||
@@ -19,6 +19,15 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
// Maps vertex range to feature index
|
||||
struct FeatureVertexRange {
|
||||
std::size_t featureIndex;
|
||||
std::size_t start;
|
||||
std::size_t end;
|
||||
};
|
||||
|
||||
using FeatureVertexRangeMap = std::map<std::string, std::vector<FeatureVertexRange>>;
|
||||
|
||||
/*
|
||||
ZoomInterpolatedAttribute<Attr> is a 'compound' attribute, representing two values of the
|
||||
the base attribute Attr. These two values are provided to the shader to allow interpolation
|
||||
@@ -97,9 +106,17 @@ public:
|
||||
virtual ~PaintPropertyBinder() = default;
|
||||
|
||||
virtual void populateVertexVector(const GeometryTileFeature& feature,
|
||||
std::size_t length, const ImagePositions&,
|
||||
std::size_t length, std::size_t index,
|
||||
const ImagePositions&,
|
||||
const optional<PatternDependency>&,
|
||||
const style::expression::Value&) = 0;
|
||||
|
||||
virtual void updateVertexVectors(const FeatureStates&,
|
||||
const GeometryTileLayer&,
|
||||
const ImagePositions&) {}
|
||||
|
||||
virtual void updateVertexVector(std::size_t, std::size_t, const GeometryTileFeature&, const FeatureState&) = 0;
|
||||
|
||||
virtual void upload(gfx::UploadPass&) = 0;
|
||||
virtual void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) = 0;
|
||||
virtual std::tuple<ExpandToType<As, optional<gfx::AttributeBinding>>...> attributeBinding(const PossiblyEvaluatedType& currentValue) const = 0;
|
||||
@@ -118,7 +135,8 @@ public:
|
||||
: constant(std::move(constant_)) {
|
||||
}
|
||||
|
||||
void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {}
|
||||
void populateVertexVector(const GeometryTileFeature&, std::size_t, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {}
|
||||
void updateVertexVector(std::size_t, std::size_t, const GeometryTileFeature&, const FeatureState&) override {}
|
||||
void upload(gfx::UploadPass&) override {}
|
||||
void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) override {};
|
||||
|
||||
@@ -145,7 +163,8 @@ public:
|
||||
: constant(std::move(constant_)), constantPatternPositions({}) {
|
||||
}
|
||||
|
||||
void populateVertexVector(const GeometryTileFeature&, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {}
|
||||
void populateVertexVector(const GeometryTileFeature&, std::size_t, std::size_t, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value&) override {}
|
||||
void updateVertexVector(std::size_t, std::size_t, const GeometryTileFeature&, const FeatureState&) override {}
|
||||
void upload(gfx::UploadPass&) override {}
|
||||
|
||||
void setPatternParameters(const optional<ImagePosition>& posA, const optional<ImagePosition>& posB, const CrossfadeParameters&) override {
|
||||
@@ -187,14 +206,46 @@ public:
|
||||
defaultValue(std::move(defaultValue_)) {
|
||||
}
|
||||
void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) override {};
|
||||
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value& formattedSection) override {
|
||||
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, std::size_t index, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value& formattedSection) override {
|
||||
using style::expression::EvaluationContext;
|
||||
auto evaluated = expression.evaluate(EvaluationContext(&feature).withFormattedSection(&formattedSection), defaultValue);
|
||||
this->statistics.add(evaluated);
|
||||
auto value = attributeValue(evaluated);
|
||||
for (std::size_t i = vertexVector.elements(); i < length; ++i) {
|
||||
auto elements = vertexVector.elements();
|
||||
for (std::size_t i = elements; i < length; ++i) {
|
||||
vertexVector.emplace_back(BaseVertex { value });
|
||||
}
|
||||
optional<std::string> idStr = featureIDtoString(feature.getID());
|
||||
if (idStr) {
|
||||
featureMap[*idStr].emplace_back(FeatureVertexRange { index, elements, length });
|
||||
}
|
||||
}
|
||||
|
||||
void updateVertexVectors(const FeatureStates& states, const GeometryTileLayer& layer, const ImagePositions&) override {
|
||||
for (const auto& it : states) {
|
||||
const auto positions = featureMap.find(it.first);
|
||||
if (positions == featureMap.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto& pos : positions->second) {
|
||||
std::unique_ptr<GeometryTileFeature> feature = layer.getFeature(pos.featureIndex);
|
||||
if (feature) {
|
||||
updateVertexVector(pos.start, pos.end, *feature, it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateVertexVector(std::size_t start, std::size_t end, const GeometryTileFeature& feature, const FeatureState& state) override {
|
||||
using style::expression::EvaluationContext;
|
||||
|
||||
auto evaluated = expression.evaluate(EvaluationContext(&feature).withFeatureState(&state), defaultValue);
|
||||
this->statistics.add(evaluated);
|
||||
auto value = attributeValue(evaluated);
|
||||
for (std::size_t i = start; i < end; ++i) {
|
||||
vertexVector.at(i) = BaseVertex { value };
|
||||
}
|
||||
}
|
||||
|
||||
void upload(gfx::UploadPass& uploadPass) override {
|
||||
@@ -229,6 +280,7 @@ private:
|
||||
T defaultValue;
|
||||
gfx::VertexVector<BaseVertex> vertexVector;
|
||||
optional<gfx::VertexBuffer<BaseVertex>> vertexBuffer;
|
||||
FeatureVertexRangeMap featureMap;
|
||||
};
|
||||
|
||||
template <class T, class A>
|
||||
@@ -245,7 +297,7 @@ public:
|
||||
zoomRange({zoom, zoom + 1}) {
|
||||
}
|
||||
void setPatternParameters(const optional<ImagePosition>&, const optional<ImagePosition>&, const CrossfadeParameters&) override {};
|
||||
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value& formattedSection) override {
|
||||
void populateVertexVector(const GeometryTileFeature& feature, std::size_t length, std::size_t index, const ImagePositions&, const optional<PatternDependency>&, const style::expression::Value& formattedSection) override {
|
||||
using style::expression::EvaluationContext;
|
||||
Range<T> range = {
|
||||
expression.evaluate(EvaluationContext(zoomRange.min, &feature).withFormattedSection(&formattedSection), defaultValue),
|
||||
@@ -256,9 +308,47 @@ public:
|
||||
AttributeValue value = zoomInterpolatedAttributeValue(
|
||||
attributeValue(range.min),
|
||||
attributeValue(range.max));
|
||||
for (std::size_t i = vertexVector.elements(); i < length; ++i) {
|
||||
auto elements = vertexVector.elements();
|
||||
for (std::size_t i = elements; i < length; ++i) {
|
||||
vertexVector.emplace_back(Vertex { value });
|
||||
}
|
||||
optional<std::string> idStr = featureIDtoString(feature.getID());
|
||||
if (idStr) {
|
||||
featureMap[*idStr].emplace_back(FeatureVertexRange { index, elements, length });
|
||||
}
|
||||
}
|
||||
|
||||
void updateVertexVectors(const FeatureStates& states, const GeometryTileLayer& layer, const ImagePositions&) override {
|
||||
for (const auto& it : states) {
|
||||
const auto positions = featureMap.find(it.first);
|
||||
if (positions == featureMap.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto& pos : positions->second) {
|
||||
std::unique_ptr<GeometryTileFeature> feature = layer.getFeature(pos.featureIndex);
|
||||
if (feature) {
|
||||
updateVertexVector(pos.start, pos.end, *feature, it.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateVertexVector(std::size_t start, std::size_t end, const GeometryTileFeature& feature, const FeatureState& state) override {
|
||||
using style::expression::EvaluationContext;
|
||||
Range<T> range = {
|
||||
expression.evaluate(EvaluationContext(zoomRange.min, &feature, &state), defaultValue),
|
||||
expression.evaluate(EvaluationContext(zoomRange.max, &feature, &state), defaultValue),
|
||||
};
|
||||
this->statistics.add(range.min);
|
||||
this->statistics.add(range.max);
|
||||
AttributeValue value = zoomInterpolatedAttributeValue(
|
||||
attributeValue(range.min),
|
||||
attributeValue(range.max));
|
||||
|
||||
for (std::size_t i = start; i < end; ++i) {
|
||||
vertexVector.at(i) = Vertex { value };
|
||||
}
|
||||
}
|
||||
|
||||
void upload(gfx::UploadPass& uploadPass) override {
|
||||
@@ -298,6 +388,7 @@ private:
|
||||
Range<float> zoomRange;
|
||||
gfx::VertexVector<Vertex> vertexVector;
|
||||
optional<gfx::VertexBuffer<Vertex>> vertexBuffer;
|
||||
FeatureVertexRangeMap featureMap;
|
||||
};
|
||||
|
||||
template <class T, class A1, class A2>
|
||||
@@ -322,7 +413,7 @@ public:
|
||||
crossfade = crossfade_;
|
||||
};
|
||||
|
||||
void populateVertexVector(const GeometryTileFeature&, std::size_t length, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value&) override {
|
||||
void populateVertexVector(const GeometryTileFeature&, std::size_t length, std::size_t /* index */, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value&) override {
|
||||
|
||||
if (!patternDependencies || patternDependencies->mid.empty()) {
|
||||
// Unlike other propperties with expressions that evaluate to null, the default value for `*-pattern` properties is an empty
|
||||
@@ -353,6 +444,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void updateVertexVector(std::size_t, std::size_t, const GeometryTileFeature&, const FeatureState&) override {}
|
||||
|
||||
void upload(gfx::UploadPass& uploadPass) override {
|
||||
if (!patternToVertexVector.empty()) {
|
||||
assert(!zoomInVertexVector.empty());
|
||||
@@ -491,9 +584,15 @@ public:
|
||||
PaintPropertyBinders(PaintPropertyBinders&&) = default;
|
||||
PaintPropertyBinders(const PaintPropertyBinders&) = delete;
|
||||
|
||||
void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value& formattedSection = {}) {
|
||||
void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length, std::size_t index, const ImagePositions& patternPositions, const optional<PatternDependency>& patternDependencies, const style::expression::Value& formattedSection = {}) {
|
||||
util::ignore({
|
||||
(binders.template get<Ps>()->populateVertexVector(feature, length, patternPositions, patternDependencies, formattedSection), 0)...
|
||||
(binders.template get<Ps>()->populateVertexVector(feature, length, index, patternPositions, patternDependencies, formattedSection), 0)...
|
||||
});
|
||||
}
|
||||
|
||||
void updateVertexVectors(const FeatureStates& states, const GeometryTileLayer& layer, const ImagePositions& imagePositions) {
|
||||
util::ignore({
|
||||
(binders.template get<Ps>()->updateVertexVectors(states, layer, imagePositions), 0)...
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -384,7 +384,7 @@ void GeometryTileWorker::parse() {
|
||||
continue;
|
||||
|
||||
const GeometryCollection& geometries = feature->getGeometries();
|
||||
bucket->addFeature(*feature, geometries, {}, PatternLayerMap ());
|
||||
bucket->addFeature(*feature, geometries, {}, PatternLayerMap (), i);
|
||||
featureIndex->insert(geometries, i, sourceLayerID, leaderImpl.id);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user