summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmiao <miao.zhao@mapbox.com>2020-02-12 12:28:05 +0200
committerzmiao <miao.zhao@mapbox.com>2020-02-12 17:35:18 +0200
commit759dfe8bf630b30173880551db70f54c43697b98 (patch)
tree504c1da77f53aa33dda0e71f3276a5491e1f3135
parentc57af518426acc99fada188990e831cacc8170fe (diff)
downloadqtlocation-mapboxgl-759dfe8bf630b30173880551db70f54c43697b98.tar.gz
[core] Support [within expression] with layout property
-rw-r--r--include/mbgl/style/property_expression.hpp33
-rw-r--r--metrics/ignores/platform-all.json3
-rw-r--r--src/mbgl/layout/pattern_layout.hpp30
-rw-r--r--src/mbgl/layout/symbol_layout.cpp57
-rw-r--r--src/mbgl/layout/symbol_layout.hpp1
-rw-r--r--src/mbgl/renderer/buckets/fill_bucket.cpp2
-rw-r--r--src/mbgl/renderer/buckets/line_bucket.cpp8
-rw-r--r--src/mbgl/renderer/buckets/line_bucket.hpp2
-rw-r--r--src/mbgl/renderer/possibly_evaluated_property_value.hpp14
-rw-r--r--src/mbgl/style/properties.hpp37
10 files changed, 142 insertions, 45 deletions
diff --git a/include/mbgl/style/property_expression.hpp b/include/mbgl/style/property_expression.hpp
index 7439ac9ca1..8502bfefbd 100644
--- a/include/mbgl/style/property_expression.hpp
+++ b/include/mbgl/style/property_expression.hpp
@@ -73,6 +73,20 @@ public:
finalDefaultValue);
}
+ T evaluate(const GeometryTileFeature& feature, const CanonicalTileID& canonical, T finalDefaultValue) const {
+ return evaluate(expression::EvaluationContext(&feature).withCanonicalTileID(&canonical), finalDefaultValue);
+ }
+
+ T evaluate(const GeometryTileFeature& feature,
+ const std::set<std::string>& availableImages,
+ const CanonicalTileID& canonical,
+ T finalDefaultValue) const {
+ return evaluate(expression::EvaluationContext(&feature)
+ .withAvailableImages(&availableImages)
+ .withCanonicalTileID(&canonical),
+ finalDefaultValue);
+ }
+
T evaluate(float zoom, const GeometryTileFeature& feature, T finalDefaultValue) const {
return evaluate(expression::EvaluationContext(zoom, &feature), finalDefaultValue);
}
@@ -85,6 +99,25 @@ public:
finalDefaultValue);
}
+ T evaluate(float zoom,
+ const GeometryTileFeature& feature,
+ const std::set<std::string>& availableImages,
+ const CanonicalTileID& canonical,
+ T finalDefaultValue) const {
+ return evaluate(expression::EvaluationContext(zoom, &feature)
+ .withAvailableImages(&availableImages)
+ .withCanonicalTileID(&canonical),
+ finalDefaultValue);
+ }
+
+ T evaluate(float zoom,
+ const GeometryTileFeature& feature,
+ const CanonicalTileID& canonical,
+ T finalDefaultValue) const {
+ return evaluate(expression::EvaluationContext(zoom, &feature).withCanonicalTileID(&canonical),
+ finalDefaultValue);
+ }
+
T evaluate(float zoom, const GeometryTileFeature& feature, const FeatureState& state, T finalDefaultValue) const {
assert(!isFeatureConstant());
return evaluate(expression::EvaluationContext(zoom, &feature, &state), finalDefaultValue);
diff --git a/metrics/ignores/platform-all.json b/metrics/ignores/platform-all.json
index f27941a3b6..e9ee792f37 100644
--- a/metrics/ignores/platform-all.json
+++ b/metrics/ignores/platform-all.json
@@ -132,6 +132,5 @@
"render-tests/text-variable-anchor/left-top-right-buttom-offset-tile-map-mode":"https://github.com/mapbox/mapbox-gl-js/pull/9202",
"render-tests/line-pattern/with-dasharray":"https://github.com/mapbox/mapbox-gl-js/pull/9189",
"render-tests/symbol-sort-key/placement-tile-boundary-right-then-left": "https://github.com/mapbox/mapbox-gl-js/pull/9054",
- "render-tests/line-dasharray/zero-length-gap":"https://github.com/mapbox/mapbox-gl-js/pull/9246",
- "render-tests/within/layout-text": "TODO: Fix by enabling `within` expreesion with layout property"
+ "render-tests/line-dasharray/zero-length-gap":"https://github.com/mapbox/mapbox-gl-js/pull/9246"
}
diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp
index 81ff3996db..8d612d2589 100644
--- a/src/mbgl/layout/pattern_layout.hpp
+++ b/src/mbgl/layout/pattern_layout.hpp
@@ -45,7 +45,8 @@ struct PatternFeatureInserter<void> {
std::unique_ptr<GeometryTileFeature> feature,
PatternLayerMap patternDependencyMap,
float /*zoom*/,
- const PropertiesType&) {
+ const PropertiesType&,
+ const CanonicalTileID&) {
features.emplace_back(index, std::move(feature), std::move(patternDependencyMap));
}
};
@@ -58,9 +59,10 @@ struct PatternFeatureInserter {
std::unique_ptr<GeometryTileFeature> feature,
PatternLayerMap patternDependencyMap,
float zoom,
- const PropertiesType& properties) {
+ const PropertiesType& properties,
+ const CanonicalTileID& canonical) {
const auto& sortKeyProperty = properties.template get<SortKeyPropertyType>();
- float sortKey = sortKeyProperty.evaluate(*feature, zoom, SortKeyPropertyType::defaultValue());
+ float sortKey = sortKeyProperty.evaluate(*feature, zoom, canonical, SortKeyPropertyType::defaultValue());
PatternFeature patternFeature{index, std::move(feature), std::move(patternDependencyMap), sortKey};
const auto lowerBound = std::lower_bound(features.cbegin(), features.cend(), patternFeature);
features.insert(lowerBound, std::move(patternFeature));
@@ -127,12 +129,17 @@ public:
const auto min = patternProperty.evaluate(*feature,
zoom - 1,
layoutParameters.availableImages,
+ parameters.tileID.canonical,
+ PatternPropertyType::defaultValue());
+ const auto mid = patternProperty.evaluate(*feature,
+ zoom,
+ layoutParameters.availableImages,
+ parameters.tileID.canonical,
PatternPropertyType::defaultValue());
- const auto mid = patternProperty.evaluate(
- *feature, zoom, layoutParameters.availableImages, PatternPropertyType::defaultValue());
const auto max = patternProperty.evaluate(*feature,
zoom + 1,
layoutParameters.availableImages,
+ parameters.tileID.canonical,
PatternPropertyType::defaultValue());
layoutParameters.imageDependencies.emplace(min.to.id(), ImageType::Pattern);
@@ -145,14 +152,17 @@ public:
}
}
- PatternFeatureInserter<SortKeyPropertyType>::insert(
- features, i, std::move(feature), std::move(patternDependencyMap), zoom, layout);
+ PatternFeatureInserter<SortKeyPropertyType>::insert(features,
+ i,
+ std::move(feature),
+ std::move(patternDependencyMap),
+ zoom,
+ layout,
+ parameters.tileID.canonical);
}
};
- bool hasDependencies() const override {
- return hasPattern;
- }
+ bool hasDependencies() const override { return hasPattern; }
void createBucket(const ImagePositions& patternPositions,
std::unique_ptr<FeatureIndex>& featureIndex,
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index e954a26a50..63ce223574 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -86,6 +86,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
sourceLayer(std::move(sourceLayer_)),
overscaling(parameters.tileID.overscaleFactor()),
zoom(parameters.tileID.overscaledZ),
+ canonicalID(parameters.tileID.canonical),
mode(parameters.mode),
pixelRatio(parameters.pixelRatio),
tileSize(util::tileSize * overscaling),
@@ -141,9 +142,9 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
ft.index = i;
if (hasText) {
- auto formatted = layout->evaluate<TextField>(zoom, ft, layoutParameters.availableImages);
- auto textTransform = layout->evaluate<TextTransform>(zoom, ft);
- FontStack baseFontStack = layout->evaluate<TextFont>(zoom, ft);
+ auto formatted = layout->evaluate<TextField>(zoom, ft, layoutParameters.availableImages, canonicalID);
+ auto textTransform = layout->evaluate<TextTransform>(zoom, ft, canonicalID);
+ FontStack baseFontStack = layout->evaluate<TextFont>(zoom, ft, canonicalID);
ft.formattedText = TaggedString();
for (const auto & section : formatted.sections) {
@@ -188,13 +189,13 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
}
if (hasIcon) {
- ft.icon = layout->evaluate<IconImage>(zoom, ft, layoutParameters.availableImages);
+ ft.icon = layout->evaluate<IconImage>(zoom, ft, layoutParameters.availableImages, canonicalID);
layoutParameters.imageDependencies.emplace(ft.icon->id(), ImageType::Icon);
}
if (ft.formattedText || ft.icon) {
if (sortFeaturesByKey) {
- ft.sortKey = layout->evaluate<SymbolSortKey>(zoom, ft);
+ ft.sortKey = layout->evaluate<SymbolSortKey>(zoom, ft, canonicalID);
const auto lowerBound = std::lower_bound(features.begin(), features.end(), ft);
features.insert(lowerBound, std::move(ft));
} else {
@@ -355,14 +356,16 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap,
ShapedTextOrientations shapedTextOrientations;
optional<PositionedIcon> shapedIcon;
std::array<float, 2> textOffset{{0.0f, 0.0f}};
- const float layoutTextSize = layout->evaluate<TextSize>(zoom + 1, feature);
- const float layoutTextSizeAtBucketZoomLevel = layout->evaluate<TextSize>(zoom, feature);
- const float layoutIconSize = layout->evaluate<IconSize>(zoom + 1, feature);
+ const float layoutTextSize = layout->evaluate<TextSize>(zoom + 1, feature, canonicalID);
+ const float layoutTextSizeAtBucketZoomLevel = layout->evaluate<TextSize>(zoom, feature, canonicalID);
+ const float layoutIconSize = layout->evaluate<IconSize>(zoom + 1, feature, canonicalID);
// if feature has text, shape the text
if (feature.formattedText && layoutTextSize > 0.0f) {
const float lineHeight = layout->get<TextLineHeight>() * util::ONE_EM;
- const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText()) ? layout->evaluate<TextLetterSpacing>(zoom, feature) * util::ONE_EM : 0.0f;
+ const float spacing = util::i18n::allowsLetterSpacing(feature.formattedText->rawText())
+ ? layout->evaluate<TextLetterSpacing>(zoom, feature, canonicalID) * util::ONE_EM
+ : 0.0f;
auto applyShaping = [&](const TaggedString& formattedText,
WritingModeType writingMode,
@@ -371,7 +374,7 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap,
const Shaping result = getShaping(
/* string */ formattedText,
/* maxWidth: ems */
- isPointPlacement ? layout->evaluate<TextMaxWidth>(zoom, feature) * util::ONE_EM : 0.0f,
+ isPointPlacement ? layout->evaluate<TextMaxWidth>(zoom, feature, canonicalID) * util::ONE_EM : 0.0f,
/* ems */ lineHeight,
textAnchor,
textJustify,
@@ -389,22 +392,24 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap,
return result;
};
- const std::vector<style::TextVariableAnchorType> variableTextAnchor = layout->evaluate<TextVariableAnchor>(zoom, feature);
- const SymbolAnchorType textAnchor = layout->evaluate<TextAnchor>(zoom, feature);
+ const std::vector<style::TextVariableAnchorType> variableTextAnchor =
+ layout->evaluate<TextVariableAnchor>(zoom, feature, canonicalID);
+ const SymbolAnchorType textAnchor = layout->evaluate<TextAnchor>(zoom, feature, canonicalID);
if (variableTextAnchor.empty()) {
// Layers with variable anchors use the `text-radial-offset` property and the [x, y] offset vector
// is calculated at placement time instead of layout time
- const float radialOffset = layout->evaluate<TextRadialOffset>(zoom, feature);
+ const float radialOffset = layout->evaluate<TextRadialOffset>(zoom, feature, canonicalID);
if (radialOffset > 0.0f) {
// The style spec says don't use `text-offset` and `text-radial-offset` together
// but doesn't actually specify what happens if you use both. We go with the radial offset.
textOffset = evaluateRadialOffset(textAnchor, radialOffset * util::ONE_EM);
} else {
- textOffset = {{layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM,
- layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}};
+ textOffset = {{layout->evaluate<TextOffset>(zoom, feature, canonicalID)[0] * util::ONE_EM,
+ layout->evaluate<TextOffset>(zoom, feature, canonicalID)[1] * util::ONE_EM}};
}
}
- TextJustifyType textJustify = textAlongLine ? TextJustifyType::Center : layout->evaluate<TextJustify>(zoom, feature);
+ TextJustifyType textJustify =
+ textAlongLine ? TextJustifyType::Center : layout->evaluate<TextJustify>(zoom, feature, canonicalID);
const auto addVerticalShapingForPointLabelIfNeeded = [&] {
if (allowVerticalPlacement && feature.formattedText->allowsVerticalWritingMode()) {
@@ -474,8 +479,8 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap,
if (image != imageMap.end()) {
iconType = SymbolContent::IconRGBA;
shapedIcon = PositionedIcon::shapeIcon(imagePositions.at(feature.icon->id()),
- layout->evaluate<IconOffset>(zoom, feature),
- layout->evaluate<IconAnchor>(zoom, feature));
+ layout->evaluate<IconOffset>(zoom, feature, canonicalID),
+ layout->evaluate<IconAnchor>(zoom, feature, canonicalID));
if (image->second->sdf) {
iconType = SymbolContent::IconSDF;
}
@@ -520,13 +525,13 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
const float minScale = 0.5f;
const float glyphSize = 24.0f;
- const std::array<float, 2> iconOffset = layout->evaluate<IconOffset>(zoom, feature);
+ const std::array<float, 2> iconOffset = layout->evaluate<IconOffset>(zoom, feature, canonicalID);
// To reduce the number of labels that jump around when zooming we need
// to use a text-size value that is the same for all zoom levels.
// This calculates text-size at a high zoom level so that all tiles can
// use the same value when calculating anchor positions.
- const float textMaxSize = layout->evaluate<TextSize>(18, feature);
+ const float textMaxSize = layout->evaluate<TextSize>(18, feature, canonicalID);
const float fontScale = layoutTextSize / glyphSize;
const float textBoxScale = tilePixelRatio * fontScale;
@@ -536,15 +541,15 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex,
const float textPadding = layout->get<TextPadding>() * tilePixelRatio;
const float iconPadding = layout->get<IconPadding>() * tilePixelRatio;
const float textMaxAngle = layout->get<TextMaxAngle>() * util::DEG2RAD;
- const float iconRotation = layout->evaluate<IconRotate>(zoom, feature);
- const float textRotation = layout->evaluate<TextRotate>(zoom, feature);
+ const float iconRotation = layout->evaluate<IconRotate>(zoom, feature, canonicalID);
+ const float textRotation = layout->evaluate<TextRotate>(zoom, feature, canonicalID);
std::array<float, 2> variableTextOffset;
if (!textRadialOffset.isUndefined()) {
- variableTextOffset = {{layout->evaluate<TextRadialOffset>(zoom, feature) * util::ONE_EM,
- INVALID_OFFSET_VALUE}};
+ variableTextOffset = {
+ {layout->evaluate<TextRadialOffset>(zoom, feature, canonicalID) * util::ONE_EM, INVALID_OFFSET_VALUE}};
} else {
- variableTextOffset = {{layout->evaluate<TextOffset>(zoom, feature)[0] * util::ONE_EM,
- layout->evaluate<TextOffset>(zoom, feature)[1] * util::ONE_EM}};
+ variableTextOffset = {{layout->evaluate<TextOffset>(zoom, feature, canonicalID)[0] * util::ONE_EM,
+ layout->evaluate<TextOffset>(zoom, feature, canonicalID)[1] * util::ONE_EM}};
}
const SymbolPlacementType textPlacement = layout->get<TextRotationAlignment>() != AlignmentType::Map
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index 740a69df9e..a1c0b86fd9 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -115,6 +115,7 @@ private:
const std::unique_ptr<GeometryTileLayer> sourceLayer;
const float overscaling;
const float zoom;
+ const CanonicalTileID canonicalID;
const MapMode mode;
const float pixelRatio;
diff --git a/src/mbgl/renderer/buckets/fill_bucket.cpp b/src/mbgl/renderer/buckets/fill_bucket.cpp
index 73c2530241..f42dc59579 100644
--- a/src/mbgl/renderer/buckets/fill_bucket.cpp
+++ b/src/mbgl/renderer/buckets/fill_bucket.cpp
@@ -115,7 +115,7 @@ void FillBucket::addFeature(const GeometryTileFeature& feature,
for (auto& pair : paintPropertyBinders) {
const auto it = patternDependencies.find(pair.first);
- if (it != patternDependencies.end()){
+ if (it != patternDependencies.end()) {
pair.second.populateVertexVectors(
feature, vertices.elements(), index, patternPositions, it->second, canonical);
} else {
diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp
index fdb110bc9d..55593aaa66 100644
--- a/src/mbgl/renderer/buckets/line_bucket.cpp
+++ b/src/mbgl/renderer/buckets/line_bucket.cpp
@@ -34,7 +34,7 @@ void LineBucket::addFeature(const GeometryTileFeature& feature,
std::size_t index,
const CanonicalTileID& canonical) {
for (auto& line : geometryCollection) {
- addGeometry(line, feature);
+ addGeometry(line, feature, canonical);
}
for (auto& pair : paintPropertyBinders) {
@@ -97,7 +97,9 @@ private:
double total;
};
-void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const GeometryTileFeature& feature) {
+void LineBucket::addGeometry(const GeometryCoordinates& coordinates,
+ const GeometryTileFeature& feature,
+ const CanonicalTileID& canonical) {
const FeatureType type = feature.getType();
const std::size_t len = [&coordinates] {
std::size_t l = coordinates.size();
@@ -137,7 +139,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome
*numericValue<double>(clip_start_it->second), *numericValue<double>(clip_end_it->second), total_length};
}
- const LineJoinType joinType = layout.evaluate<LineJoin>(zoom, feature);
+ const LineJoinType joinType = layout.evaluate<LineJoin>(zoom, feature, canonical);
const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>());
diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp
index a3821d108b..111c16b348 100644
--- a/src/mbgl/renderer/buckets/line_bucket.hpp
+++ b/src/mbgl/renderer/buckets/line_bucket.hpp
@@ -52,7 +52,7 @@ public:
std::map<std::string, LineProgram::Binders> paintPropertyBinders;
private:
- void addGeometry(const GeometryCoordinates&, const GeometryTileFeature&);
+ void addGeometry(const GeometryCoordinates&, const GeometryTileFeature&, const CanonicalTileID&);
struct TriangleElement {
TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {}
diff --git a/src/mbgl/renderer/possibly_evaluated_property_value.hpp b/src/mbgl/renderer/possibly_evaluated_property_value.hpp
index 5e412855a4..466e042cbc 100644
--- a/src/mbgl/renderer/possibly_evaluated_property_value.hpp
+++ b/src/mbgl/renderer/possibly_evaluated_property_value.hpp
@@ -51,6 +51,14 @@ public:
}
template <class Feature>
+ T evaluate(const Feature& feature, float zoom, const CanonicalTileID& canonical, T defaultValue) const {
+ return this->match([&](const T& constant_) { return constant_; },
+ [&](const style::PropertyExpression<T>& expression) {
+ return expression.evaluate(zoom, feature, canonical, defaultValue);
+ });
+ }
+
+ template <class Feature>
T evaluate(const Feature& feature, float zoom, const FeatureState& featureState, T defaultValue) const {
return this->match([&](const T& constant_) { return constant_; },
[&](const style::PropertyExpression<T>& expression) {
@@ -96,13 +104,15 @@ public:
Faded<T> evaluate(const Feature& feature,
float zoom,
const std::set<std::string>& availableImages,
+ const CanonicalTileID& canonical,
T defaultValue) const {
return this->match(
[&] (const Faded<T>& constant_) { return constant_; },
[&] (const style::PropertyExpression<T>& expression) {
if (!expression.isZoomConstant()) {
- const T min = expression.evaluate(floor(zoom), feature, availableImages, defaultValue);
- const T max = expression.evaluate(floor(zoom) + 1, feature, availableImages, defaultValue);
+ const T min = expression.evaluate(floor(zoom), feature, availableImages, canonical, defaultValue);
+ const T max =
+ expression.evaluate(floor(zoom) + 1, feature, availableImages, canonical, defaultValue);
return Faded<T> {min, max};
} else {
const T evaluated = expression.evaluate(feature, availableImages, defaultValue);
diff --git a/src/mbgl/style/properties.hpp b/src/mbgl/style/properties.hpp
index 2fab53ad12..39b6672734 100644
--- a/src/mbgl/style/properties.hpp
+++ b/src/mbgl/style/properties.hpp
@@ -169,6 +169,11 @@ public:
}
template <class T>
+ static T evaluate(float, const GeometryTileFeature&, const CanonicalTileID&, const T& t, const T&) {
+ return t;
+ }
+
+ template <class T>
static T evaluate(float z,
const GeometryTileFeature& feature,
const PossiblyEvaluatedPropertyValue<T>& v,
@@ -194,6 +199,30 @@ public:
}
template <class T>
+ static T evaluate(float z,
+ const GeometryTileFeature& feature,
+ const PossiblyEvaluatedPropertyValue<T>& v,
+ const T& defaultValue,
+ const std::set<std::string>& availableImages,
+ const CanonicalTileID& canonical) {
+ return v.match([&](const T& t) { return t; },
+ [&](const PropertyExpression<T>& t) {
+ return t.evaluate(z, feature, availableImages, canonical, defaultValue);
+ });
+ }
+
+ template <class T>
+ static T evaluate(float z,
+ const GeometryTileFeature& feature,
+ const CanonicalTileID& canonical,
+ const PossiblyEvaluatedPropertyValue<T>& v,
+ const T& defaultValue) {
+ return v.match(
+ [&](const T& t) { return t; },
+ [&](const PropertyExpression<T>& t) { return t.evaluate(z, feature, canonical, defaultValue); });
+ }
+
+ template <class T>
static T evaluate(float z, const GeometryTileFeature& feature, const FeatureState& state,
const PossiblyEvaluatedPropertyValue<T>& v, const T& defaultValue) {
return v.match([&](const T& t) { return t; },
@@ -220,6 +249,14 @@ public:
return evaluate(z, feature, this->template get<P>(), P::defaultValue(), availableImages);
}
+ template <class P>
+ auto evaluate(float z,
+ const GeometryTileFeature& feature,
+ const std::set<std::string>& availableImages,
+ const CanonicalTileID& canonical) const {
+ return evaluate(z, feature, this->template get<P>(), P::defaultValue(), availableImages, canonical);
+ }
+
Evaluated evaluate(float z, const GeometryTileFeature& feature) const {
return Evaluated {
evaluate<Ps>(z, feature)...