diff options
-rw-r--r-- | include/mbgl/style/expression/dsl.hpp | 1 | ||||
-rw-r--r-- | include/mbgl/style/expression/expression.hpp | 15 | ||||
-rw-r--r-- | include/mbgl/style/expression/format_expression.hpp | 15 | ||||
-rw-r--r-- | include/mbgl/style/expression/formatted.hpp | 22 | ||||
-rw-r--r-- | include/mbgl/style/property_expression.hpp | 103 | ||||
-rw-r--r-- | src/core-files.json | 1 | ||||
-rw-r--r-- | src/mbgl/style/conversion/function.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/expression/compound_expression.cpp | 11 | ||||
-rw-r--r-- | src/mbgl/style/expression/dsl.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/style/expression/format_expression.cpp | 62 | ||||
-rw-r--r-- | src/mbgl/style/expression/formatted.cpp | 42 | ||||
-rw-r--r-- | src/mbgl/style/expression/is_constant.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/style/property_expression.cpp | 68 |
13 files changed, 240 insertions, 121 deletions
diff --git a/include/mbgl/style/expression/dsl.hpp b/include/mbgl/style/expression/dsl.hpp index bd94a765e7..fcbca25941 100644 --- a/include/mbgl/style/expression/dsl.hpp +++ b/include/mbgl/style/expression/dsl.hpp @@ -82,6 +82,7 @@ std::unique_ptr<Expression> concat(std::vector<std::unique_ptr<Expression>> inpu std::unique_ptr<Expression> format(const char* value); std::unique_ptr<Expression> format(std::unique_ptr<Expression>); +std::unique_ptr<Expression> textSection(); } // namespace dsl } // namespace expression diff --git a/include/mbgl/style/expression/expression.hpp b/include/mbgl/style/expression/expression.hpp index 97b143b3d9..d868b17e00 100644 --- a/include/mbgl/style/expression/expression.hpp +++ b/include/mbgl/style/expression/expression.hpp @@ -25,18 +25,25 @@ public: class EvaluationContext { public: - EvaluationContext(float zoom_) : zoom(zoom_), feature(nullptr) {} - EvaluationContext(GeometryTileFeature const * feature_) : zoom(optional<float>()), feature(feature_) {} + EvaluationContext() = default; + explicit EvaluationContext(float zoom_) : zoom(zoom_) {} + EvaluationContext(GeometryTileFeature const * feature_) : feature(feature_) {} EvaluationContext(float zoom_, GeometryTileFeature const * feature_) : zoom(zoom_), feature(feature_) {} EvaluationContext(optional<float> zoom_, GeometryTileFeature const * feature_, optional<double> colorRampParameter_) : zoom(std::move(zoom_)), feature(feature_), colorRampParameter(std::move(colorRampParameter_)) {} - + + EvaluationContext& withFormattedSection(const Value* formattedSection_) noexcept { + formattedSection = formattedSection_; + return *this; + }; + optional<float> zoom; - GeometryTileFeature const * feature; + GeometryTileFeature const * feature = nullptr; optional<double> colorRampParameter; + const Value* formattedSection = nullptr; }; template <typename T> diff --git a/include/mbgl/style/expression/format_expression.hpp b/include/mbgl/style/expression/format_expression.hpp index b00674a88e..09feaf4819 100644 --- a/include/mbgl/style/expression/format_expression.hpp +++ b/include/mbgl/style/expression/format_expression.hpp @@ -1,11 +1,7 @@ #pragma once #include <mbgl/style/expression/expression.hpp> -#include <mbgl/style/expression/formatted.hpp> #include <mbgl/style/expression/parsing_context.hpp> -#include <mbgl/style/conversion.hpp> - -#include <memory> namespace mbgl { namespace style { @@ -14,16 +10,18 @@ namespace expression { struct FormatExpressionSection { FormatExpressionSection(std::unique_ptr<Expression> text_, optional<std::unique_ptr<Expression>> fontScale_, - optional<std::unique_ptr<Expression>> textFont_); + optional<std::unique_ptr<Expression>> textFont_, + optional<std::unique_ptr<Expression>> sectionID_); std::shared_ptr<Expression> text; optional<std::shared_ptr<Expression>> fontScale; optional<std::shared_ptr<Expression>> textFont; + optional<std::shared_ptr<Expression>> sectionID; }; -class FormatExpression : public Expression { +class FormatExpression final : public Expression { public: - FormatExpression(std::vector<FormatExpressionSection> sections); + explicit FormatExpression(std::vector<FormatExpressionSection> sections); EvaluationResult evaluate(const EvaluationContext&) const override; static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&); @@ -42,9 +40,6 @@ public: std::string getOperator() const override { return "format"; } private: std::vector<FormatExpressionSection> sections; - std::unique_ptr<Expression> text; - optional<std::unique_ptr<Expression>> fontScale; - optional<std::unique_ptr<Expression>> textFont; }; } // namespace expression diff --git a/include/mbgl/style/expression/formatted.hpp b/include/mbgl/style/expression/formatted.hpp index 9e7e7308cb..28964de941 100644 --- a/include/mbgl/style/expression/formatted.hpp +++ b/include/mbgl/style/expression/formatted.hpp @@ -12,15 +12,33 @@ namespace mbgl { namespace style { namespace expression { +extern const char* const kFormattedSectionFontScale; +extern const char* const kFormattedSectionTextFont; +extern const char* const kFormattedSectionID; + +using FormattedSectionID = variant<double, std::string>; + +template<class Variant> +optional<FormattedSectionID> toFormattedSectionID(const Variant& variant) { + return variant.match( + [] (double t) -> FormattedSectionID { return t; }, + [] (const std::string& t) -> FormattedSectionID { return t;}, + [] (auto&) -> optional<FormattedSectionID> { return nullopt; }); +} + struct FormattedSection { - FormattedSection(std::string text_, optional<double> fontScale_, optional<FontStack> fontStack_) + FormattedSection(std::string text_, optional<double> fontScale_, + optional<FontStack> fontStack_, optional<FormattedSectionID> id_) : text(std::move(text_)) , fontScale(std::move(fontScale_)) , fontStack(std::move(fontStack_)) + , id(std::move(id_)) {} + std::string text; optional<double> fontScale; optional<FontStack> fontStack; + optional<FormattedSectionID> id; }; class Formatted { @@ -28,7 +46,7 @@ public: Formatted() = default; Formatted(const char* plainU8String) { - sections.emplace_back(std::string(plainU8String), nullopt, nullopt); + sections.emplace_back(std::string(plainU8String), nullopt, nullopt, nullopt); } Formatted(std::vector<FormattedSection> sections_) diff --git a/include/mbgl/style/property_expression.hpp b/include/mbgl/style/property_expression.hpp index b198de02b2..43e80dfac4 100644 --- a/include/mbgl/style/property_expression.hpp +++ b/include/mbgl/style/property_expression.hpp @@ -1,7 +1,6 @@ #pragma once #include <mbgl/style/expression/expression.hpp> -#include <mbgl/style/expression/value.hpp> #include <mbgl/style/expression/is_constant.hpp> #include <mbgl/style/expression/interpolate.hpp> #include <mbgl/style/expression/step.hpp> @@ -11,46 +10,38 @@ namespace mbgl { namespace style { -template <class T> -class PropertyExpression { +class PropertyExpressionBase { public: - // Second parameter to be used only for conversions from legacy functions. - PropertyExpression(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {}) - : expression(std::move(expression_)), - defaultValue(std::move(defaultValue_)), - zoomCurve(expression::findZoomCurveChecked(expression.get())) { - } + explicit PropertyExpressionBase(std::unique_ptr<expression::Expression>); - bool isZoomConstant() const { return expression::isZoomConstant(*expression); } - bool isFeatureConstant() const { return expression::isFeatureConstant(*expression); } + bool isZoomConstant() const noexcept; + bool isFeatureConstant() const noexcept; + bool canEvaluateWith(const expression::EvaluationContext&) const noexcept; + float interpolationFactor(const Range<float>&, const float) const noexcept; + Range<float> getCoveringStops(const float, const float) const noexcept; + const expression::Expression& getExpression() const noexcept; - T evaluate(float zoom) const { - assert(!expression::isZoomConstant(*expression)); - assert(expression::isFeatureConstant(*expression)); - const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(zoom, nullptr)); - if (result) { - const optional<T> typed = expression::fromExpressionValue<T>(*result); - return typed ? *typed : defaultValue ? *defaultValue : T(); - } - return defaultValue ? *defaultValue : T(); - } + bool useIntegerZoom = false; - template <class Feature> - T evaluate(const Feature& feature, T finalDefaultValue) const { - assert(expression::isZoomConstant(*expression)); - assert(!expression::isFeatureConstant(*expression)); - const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(&feature)); - if (result) { - const optional<T> typed = expression::fromExpressionValue<T>(*result); - return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue; - } - return defaultValue ? *defaultValue : finalDefaultValue; +protected: + std::shared_ptr<const expression::Expression> expression; + variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve; + bool isZoomConstant_; + bool isFeatureConstant_; +}; + +template <class T> +class PropertyExpression final : public PropertyExpressionBase { +public: + // Second parameter to be used only for conversions from legacy functions. + PropertyExpression(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {}) + : PropertyExpressionBase(std::move(expression_)), + defaultValue(std::move(defaultValue_)) { } - template <class Feature> - T evaluate(float zoom, const Feature& feature, T finalDefaultValue) const { - assert(!expression::isFeatureConstant(*expression)); - const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext({zoom}, &feature)); + T evaluate(const expression::EvaluationContext& context, T finalDefaultValue = T()) const { + assert(canEvaluateWith(context)); + const expression::EvaluationResult result = expression->evaluate(context); if (result) { const optional<T> typed = expression::fromExpressionValue<T>(*result); return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue; @@ -58,59 +49,29 @@ public: return defaultValue ? *defaultValue : finalDefaultValue; } - float interpolationFactor(const Range<float>& inputLevels, const float inputValue) const { - return zoomCurve.match( - [](std::nullptr_t) { - assert(false); - return 0.0f; - }, - [&](const expression::Interpolate* z) { - return z->interpolationFactor(Range<double> { inputLevels.min, inputLevels.max }, inputValue); - }, - [&](const expression::Step*) { - return 0.0f; - } - ); + T evaluate(float zoom) const { + return evaluate(expression::EvaluationContext(zoom)); } - Range<float> getCoveringStops(const float lower, const float upper) const { - return zoomCurve.match( - [](std::nullptr_t) { - assert(false); - return Range<float>(0.0f, 0.0f); - }, - [&](auto z) { - return z->getCoveringStops(lower, upper); - } - ); + T evaluate(const GeometryTileFeature& feature, T finalDefaultValue) const { + return evaluate(expression::EvaluationContext(&feature), finalDefaultValue); } - // Return the range obtained by evaluating the function at each of the zoom levels in zoomRange - template <class Feature> - Range<T> evaluate(const Range<float>& zoomRange, const Feature& feature, T finalDefaultValue) { - return Range<T> { - evaluate(zoomRange.min, feature, finalDefaultValue), - evaluate(zoomRange.max, feature, finalDefaultValue) - }; + T evaluate(float zoom, const GeometryTileFeature& feature, T finalDefaultValue) const { + return evaluate(expression::EvaluationContext(zoom, &feature), finalDefaultValue); } std::vector<optional<T>> possibleOutputs() const { return expression::fromExpressionValues<T>(expression->possibleOutputs()); } - const expression::Expression& getExpression() const { return *expression; } - - bool useIntegerZoom = false; - friend bool operator==(const PropertyExpression& lhs, const PropertyExpression& rhs) { return *lhs.expression == *rhs.expression; } private: - std::shared_ptr<const expression::Expression> expression; optional<T> defaultValue; - variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve; }; } // namespace style diff --git a/src/core-files.json b/src/core-files.json index 42a30a3ea8..f27bd268bd 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -223,6 +223,7 @@ "src/mbgl/style/light.cpp", "src/mbgl/style/light_impl.cpp", "src/mbgl/style/parser.cpp", + "src/mbgl/style/property_expression.cpp", "src/mbgl/style/source.cpp", "src/mbgl/style/source_impl.cpp", "src/mbgl/style/sources/custom_geometry_source.cpp", diff --git a/src/mbgl/style/conversion/function.cpp b/src/mbgl/style/conversion/function.cpp index 5877d0eb7c..79ad2fc7d8 100644 --- a/src/mbgl/style/conversion/function.cpp +++ b/src/mbgl/style/conversion/function.cpp @@ -41,7 +41,7 @@ bool hasTokens(const std::string& source) { std::unique_ptr<Expression> convertTokenStringToFormatExpression(const std::string& source) { auto textExpression = convertTokenStringToExpression(source); std::vector<FormatExpressionSection> sections; - sections.emplace_back(std::move(textExpression), nullopt, nullopt); + sections.emplace_back(std::move(textExpression), nullopt, nullopt, nullopt); return std::make_unique<FormatExpression>(sections); } diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index cc1d58025b..27dfe6c151 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -662,6 +662,16 @@ const auto& errorCompoundExpression() { return signature; } +const auto& textSectionCompoundExpression() { + static auto signature = detail::makeSignature("text-section", [](const EvaluationContext& params) -> Result<Value> { + if (!params.formattedSection) { + return EvaluationError {"Formatted section is unavailable in the current evaluation context."}; + } + return *params.formattedSection; + }); + return signature; +} + // Legacy Filters const auto& filterEqualsCompoundExpression() { static auto signature = detail::makeSignature("filter-==", [](const EvaluationContext& params, const std::string& key, const Value &lhs) -> Result<bool> { @@ -907,6 +917,7 @@ MAPBOX_ETERNAL_CONSTEXPR const auto compoundExpressionRegistry = mapbox::eternal { "concat", concatCompoundExpression }, { "resolved-locale", resolvedLocaleCompoundExpression }, { "error", errorCompoundExpression }, + { "text-section", textSectionCompoundExpression }, // Legacy Filters { "filter-==", filterEqualsCompoundExpression }, { "filter-id-==", filterIdEqualsCompoundExpression }, diff --git a/src/mbgl/style/expression/dsl.cpp b/src/mbgl/style/expression/dsl.cpp index f5ff83a9e7..f999c90b07 100644 --- a/src/mbgl/style/expression/dsl.cpp +++ b/src/mbgl/style/expression/dsl.cpp @@ -189,13 +189,17 @@ std::unique_ptr<Expression> concat(std::vector<std::unique_ptr<Expression>> inpu std::unique_ptr<Expression> format(const char* value) { return std::make_unique<Literal>(Formatted(value)); } - + std::unique_ptr<Expression> format(std::unique_ptr<Expression> input) { std::vector<FormatExpressionSection> sections; - sections.emplace_back(std::move(input), nullopt, nullopt); + sections.emplace_back(std::move(input), nullopt, nullopt, nullopt); return std::make_unique<FormatExpression>(sections); } - + +std::unique_ptr<Expression> textSection() { + return compound("text-section"); +} + } // namespace dsl } // namespace expression } // namespace style diff --git a/src/mbgl/style/expression/format_expression.cpp b/src/mbgl/style/expression/format_expression.cpp index 144df4b160..57204313b4 100644 --- a/src/mbgl/style/expression/format_expression.cpp +++ b/src/mbgl/style/expression/format_expression.cpp @@ -1,8 +1,6 @@ #include <mbgl/style/conversion_impl.hpp> #include <mbgl/style/expression/format_expression.hpp> -#include <mbgl/style/expression/literal.hpp> -#include <mbgl/util/font_stack.hpp> -#include <mbgl/util/string.hpp> +#include <mbgl/style/expression/formatted.hpp> namespace mbgl { namespace style { @@ -10,15 +8,21 @@ namespace expression { FormatExpressionSection::FormatExpressionSection(std::unique_ptr<Expression> text_, optional<std::unique_ptr<Expression>> fontScale_, - optional<std::unique_ptr<Expression>> textFont_) + optional<std::unique_ptr<Expression>> textFont_, + optional<std::unique_ptr<Expression>> sectionID_) : text(std::move(text_)) { if (fontScale_) { fontScale = std::shared_ptr<Expression>(std::move(*fontScale_)); } + if (textFont_) { textFont = std::shared_ptr<Expression>(std::move(*textFont_)); } + + if (sectionID_) { + sectionID = std::shared_ptr<Expression>(std::move(*sectionID_)); + } } FormatExpression::FormatExpression(std::vector<FormatExpressionSection> sections_) @@ -53,7 +57,7 @@ ParseResult FormatExpression::parse(const Convertible& value, ParsingContext& ct return ParseResult(); } - const optional<Convertible> fontScaleOption = objectMember(options, "font-scale"); + const optional<Convertible> fontScaleOption = objectMember(options, kFormattedSectionFontScale); ParseResult fontScale; if (fontScaleOption) { fontScale = ctx.parse(*fontScaleOption, 1, {type::Number}); @@ -62,7 +66,7 @@ ParseResult FormatExpression::parse(const Convertible& value, ParsingContext& ct } } - const optional<Convertible> textFontOption = objectMember(options, "text-font"); + const optional<Convertible> textFontOption = objectMember(options, kFormattedSectionTextFont); ParseResult textFont; if (textFontOption) { textFont = ctx.parse(*textFontOption, 1, {type::Array(type::String)}); @@ -70,7 +74,20 @@ ParseResult FormatExpression::parse(const Convertible& value, ParsingContext& ct return ParseResult(); } } - sections.emplace_back(std::move(*text), std::move(fontScale), std::move(textFont)); + + const optional<Convertible> sectionIDOption = objectMember(options, kFormattedSectionID); + ParseResult sectionID; + if (sectionIDOption) { + sectionID = ctx.parse(*sectionIDOption, 1, {type::Value}); + if (!sectionID) { + return ParseResult(); + } + } + + sections.emplace_back(std::move(*text), + std::move(fontScale), + std::move(textFont), + std::move(sectionID)); } return ParseResult(std::make_unique<FormatExpression>(std::move(sections))); @@ -85,6 +102,9 @@ void FormatExpression::eachChild(const std::function<void(const Expression&)>& f if (section.textFont) { fn(**section.textFont); } + if (section.sectionID) { + fn(**section.sectionID); + } } } @@ -108,6 +128,10 @@ bool FormatExpression::operator==(const Expression& e) const { (!lhsSection.textFont && rhsSection.textFont)) { return false; } + if ((lhsSection.sectionID && (!rhsSection.sectionID || **lhsSection.sectionID != **rhsSection.sectionID)) || + (!lhsSection.sectionID && rhsSection.sectionID)) { + return false; + } } return true; } @@ -115,15 +139,18 @@ bool FormatExpression::operator==(const Expression& e) const { } mbgl::Value FormatExpression::serialize() const { - std::vector<mbgl::Value> serialized{{ std::string("format") }}; + std::vector<mbgl::Value> serialized{{ getOperator() }}; for (const auto& section : sections) { serialized.push_back(section.text->serialize()); std::unordered_map<std::string, mbgl::Value> options; if (section.fontScale) { - options.emplace("font-scale", (*section.fontScale)->serialize()); + options.emplace(kFormattedSectionFontScale, (*section.fontScale)->serialize()); } if (section.textFont) { - options.emplace("text-font", (*section.textFont)->serialize()); + options.emplace(kFormattedSectionTextFont, (*section.textFont)->serialize()); + } + if (section.sectionID) { + options.emplace(kFormattedSectionID, (*section.sectionID)->serialize()); } serialized.push_back(options); } @@ -164,7 +191,20 @@ EvaluationResult FormatExpression::evaluate(const EvaluationContext& params) con } evaluatedTextFont = *textFontValue; } - evaluatedSections.emplace_back(*evaluatedText, evaluatedFontScale, evaluatedTextFont); + + optional<FormattedSectionID> evaluatedID; + if (section.sectionID) { + auto sectionIDResult = (*section.sectionID)->evaluate(params); + if (!sectionIDResult) { + return sectionIDResult.error(); + } + + evaluatedID = toFormattedSectionID(*sectionIDResult); + if (!evaluatedID) { + return EvaluationError { "Format section id option must evaluate to string or number" }; + } + } + evaluatedSections.emplace_back(*evaluatedText, evaluatedFontScale, evaluatedTextFont, evaluatedID); } return Formatted(evaluatedSections); } diff --git a/src/mbgl/style/expression/formatted.cpp b/src/mbgl/style/expression/formatted.cpp index 8232d0c698..fef834b20c 100644 --- a/src/mbgl/style/expression/formatted.cpp +++ b/src/mbgl/style/expression/formatted.cpp @@ -1,18 +1,15 @@ #include <mbgl/style/expression/formatted.hpp> #include <mbgl/style/conversion_impl.hpp> -#include <mbgl/style/expression/is_constant.hpp> -#include <mbgl/style/expression/is_expression.hpp> -#include <mbgl/style/expression/literal.hpp> -#include <mbgl/style/expression/expression.hpp> -#include <mbgl/style/expression/type.hpp> -#include <mbgl/style/expression/compound_expression.hpp> -#include <mbgl/style/expression/boolean_operator.hpp> +#include <mbgl/style/conversion/constant.hpp> namespace mbgl { namespace style { - namespace expression { +const char* const kFormattedSectionFontScale = "font-scale"; +const char* const kFormattedSectionTextFont = "text-font"; +const char* const kFormattedSectionID = "id"; + bool Formatted::operator==(const Formatted& other) const { if (other.sections.size() != sections.size()) { return false; @@ -22,14 +19,14 @@ bool Formatted::operator==(const Formatted& other) const { const auto& otherSection = other.sections.at(i); if (thisSection.text != otherSection.text || thisSection.fontScale != otherSection.fontScale || - thisSection.fontStack != otherSection.fontStack) { + thisSection.fontStack != otherSection.fontStack || + thisSection.id != otherSection.id) { return false; } } return true; } - - + std::string Formatted::toString() const { std::string result; for (const auto& section : sections) { @@ -37,7 +34,7 @@ std::string Formatted::toString() const { } return result; } - + } // namespace expression namespace conversion { @@ -65,6 +62,7 @@ optional<Formatted> Converter<Formatted>::operator()(const Convertible& value, E optional<double> fontScale; optional<FontStack> textFont; + optional<FormattedSectionID> id; if (sectionLength > 1) { Convertible sectionParams = arrayMember(section, 1); if (!isObject(sectionParams)) { @@ -72,12 +70,12 @@ optional<Formatted> Converter<Formatted>::operator()(const Convertible& value, E return nullopt; } - optional<Convertible> fontScaleMember = objectMember(sectionParams, "font-scale"); + optional<Convertible> fontScaleMember = objectMember(sectionParams, kFormattedSectionFontScale); if (fontScaleMember) { fontScale = toDouble(*fontScaleMember); } - optional<Convertible> textFontMember = objectMember(sectionParams, "text-font"); + optional<Convertible> textFontMember = objectMember(sectionParams, kFormattedSectionTextFont); if (textFontMember) { if (isArray(*textFontMember)) { std::vector<std::string> fontsVector; @@ -96,9 +94,23 @@ optional<Formatted> Converter<Formatted>::operator()(const Convertible& value, E return nullopt; } } + + optional<Convertible> sectionIDMember = objectMember(sectionParams, kFormattedSectionID); + if (sectionIDMember) { + auto result = toValue(*sectionIDMember); + if (!result) { + return nullopt; + } + + id = toFormattedSectionID(*result); + if (!id) { + error.message = "Section id has to be a string or a number."; + return nullopt; + } + } } - sections.push_back(FormattedSection(*sectionText, fontScale, textFont)); + sections.push_back(FormattedSection(*sectionText, fontScale, textFont, id)); } return Formatted(sections); } else if (optional<std::string> result = toString(value)) { diff --git a/src/mbgl/style/expression/is_constant.cpp b/src/mbgl/style/expression/is_constant.cpp index 3b20f49a86..8ac362373c 100644 --- a/src/mbgl/style/expression/is_constant.cpp +++ b/src/mbgl/style/expression/is_constant.cpp @@ -17,15 +17,16 @@ bool isFeatureConstant(const Expression& expression) { return false; } else if (name == "has" && parameterCount && *parameterCount == 1) { return false; - } else if (0 == name.rfind(filter, 0)) { - // Legacy filters begin with "filter-" and are never constant. - return false; } else if ( name == "properties" || name == "geometry-type" || - name == "id" + name == "id" || + name == "text-section" ) { return false; + } else if (0 == name.rfind(filter, 0)) { + // Legacy filters begin with "filter-" and are never constant. + return false; } } diff --git a/src/mbgl/style/property_expression.cpp b/src/mbgl/style/property_expression.cpp new file mode 100644 index 0000000000..6ba0416ad3 --- /dev/null +++ b/src/mbgl/style/property_expression.cpp @@ -0,0 +1,68 @@ +#include <mbgl/style/property_expression.hpp> + +namespace mbgl { +namespace style { + +PropertyExpressionBase::PropertyExpressionBase(std::unique_ptr<expression::Expression> expression_) + : expression(std::move(expression_)), + zoomCurve(expression::findZoomCurveChecked(expression.get())) { + isZoomConstant_ = expression::isZoomConstant(*expression); + isFeatureConstant_ = expression::isFeatureConstant(*expression); +} + +bool PropertyExpressionBase::isZoomConstant() const noexcept { + return isZoomConstant_; +} + +bool PropertyExpressionBase::isFeatureConstant() const noexcept { + return isFeatureConstant_; +} + +bool PropertyExpressionBase::canEvaluateWith(const expression::EvaluationContext& context) const noexcept { + if (context.zoom) { + if (context.feature != nullptr) { + return !isFeatureConstant(); + } + return !isZoomConstant() && isFeatureConstant(); + } + + if (context.feature != nullptr) { + return isZoomConstant() && !isFeatureConstant(); + } + + return true; +} + +float PropertyExpressionBase::interpolationFactor(const Range<float>& inputLevels, const float inputValue) const noexcept { + return zoomCurve.match( + [](std::nullptr_t) { + assert(false); + return 0.0f; + }, + [&](const expression::Interpolate* z) { + return z->interpolationFactor(Range<double> { inputLevels.min, inputLevels.max }, inputValue); + }, + [&](const expression::Step*) { + return 0.0f; + } + ); +} + +Range<float> PropertyExpressionBase::getCoveringStops(const float lower, const float upper) const noexcept { + return zoomCurve.match( + [](std::nullptr_t) { + assert(false); + return Range<float>(0.0f, 0.0f); + }, + [&](auto z) { + return z->getCoveringStops(lower, upper); + } + ); +} + +const expression::Expression& PropertyExpressionBase::getExpression() const noexcept { + return *expression; +} + +} // namespace style +} // namespace mbgl |