1 #pragma once 2 3 #include <mbgl/style/expression/expression.hpp> 4 #include <mbgl/style/expression/value.hpp> 5 #include <mbgl/style/expression/is_constant.hpp> 6 #include <mbgl/style/expression/interpolate.hpp> 7 #include <mbgl/style/expression/step.hpp> 8 #include <mbgl/style/expression/find_zoom_curve.hpp> 9 #include <mbgl/util/range.hpp> 10 11 namespace mbgl { 12 namespace style { 13 14 template <class T> 15 class PropertyExpression { 16 public: 17 // Second parameter to be used only for conversions from legacy functions. PropertyExpression(std::unique_ptr<expression::Expression> expression_,optional<T> defaultValue_={})18 PropertyExpression(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {}) 19 : expression(std::move(expression_)), 20 defaultValue(std::move(defaultValue_)), 21 zoomCurve(expression::findZoomCurveChecked(expression.get())) { 22 } 23 isZoomConstant() const24 bool isZoomConstant() const { return expression::isZoomConstant(*expression); } isFeatureConstant() const25 bool isFeatureConstant() const { return expression::isFeatureConstant(*expression); } 26 evaluate(float zoom) const27 T evaluate(float zoom) const { 28 assert(!expression::isZoomConstant(*expression)); 29 assert(expression::isFeatureConstant(*expression)); 30 const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(zoom, nullptr)); 31 if (result) { 32 const optional<T> typed = expression::fromExpressionValue<T>(*result); 33 return typed ? *typed : defaultValue ? *defaultValue : T(); 34 } 35 return defaultValue ? *defaultValue : T(); 36 } 37 38 template <class Feature> evaluate(const Feature & feature,T finalDefaultValue) const39 T evaluate(const Feature& feature, T finalDefaultValue) const { 40 assert(expression::isZoomConstant(*expression)); 41 assert(!expression::isFeatureConstant(*expression)); 42 const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(&feature)); 43 if (result) { 44 const optional<T> typed = expression::fromExpressionValue<T>(*result); 45 return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue; 46 } 47 return defaultValue ? *defaultValue : finalDefaultValue; 48 } 49 50 template <class Feature> evaluate(float zoom,const Feature & feature,T finalDefaultValue) const51 T evaluate(float zoom, const Feature& feature, T finalDefaultValue) const { 52 assert(!expression::isFeatureConstant(*expression)); 53 const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext({zoom}, &feature)); 54 if (result) { 55 const optional<T> typed = expression::fromExpressionValue<T>(*result); 56 return typed ? *typed : defaultValue ? *defaultValue : finalDefaultValue; 57 } 58 return defaultValue ? *defaultValue : finalDefaultValue; 59 } 60 interpolationFactor(const Range<float> & inputLevels,const float inputValue) const61 float interpolationFactor(const Range<float>& inputLevels, const float inputValue) const { 62 return zoomCurve.match( 63 [](std::nullptr_t) { 64 assert(false); 65 return 0.0f; 66 }, 67 [&](const expression::Interpolate* z) { 68 return z->interpolationFactor(Range<double> { inputLevels.min, inputLevels.max }, inputValue); 69 }, 70 [&](const expression::Step*) { 71 return 0.0f; 72 } 73 ); 74 } 75 getCoveringStops(const float lower,const float upper) const76 Range<float> getCoveringStops(const float lower, const float upper) const { 77 return zoomCurve.match( 78 [](std::nullptr_t) { 79 assert(false); 80 return Range<float>(0.0f, 0.0f); 81 }, 82 [&](auto z) { 83 return z->getCoveringStops(lower, upper); 84 } 85 ); 86 } 87 88 // Return the range obtained by evaluating the function at each of the zoom levels in zoomRange 89 template <class Feature> evaluate(const Range<float> & zoomRange,const Feature & feature,T finalDefaultValue)90 Range<T> evaluate(const Range<float>& zoomRange, const Feature& feature, T finalDefaultValue) { 91 return Range<T> { 92 evaluate(zoomRange.min, feature, finalDefaultValue), 93 evaluate(zoomRange.max, feature, finalDefaultValue) 94 }; 95 } 96 possibleOutputs() const97 std::vector<optional<T>> possibleOutputs() const { 98 return expression::fromExpressionValues<T>(expression->possibleOutputs()); 99 } 100 getExpression() const101 const expression::Expression& getExpression() const { return *expression; } 102 103 bool useIntegerZoom = false; 104 operator ==(const PropertyExpression & lhs,const PropertyExpression & rhs)105 friend bool operator==(const PropertyExpression& lhs, 106 const PropertyExpression& rhs) { 107 return *lhs.expression == *rhs.expression; 108 } 109 110 private: 111 std::shared_ptr<const expression::Expression> expression; 112 optional<T> defaultValue; 113 variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve; 114 }; 115 116 } // namespace style 117 } // namespace mbgl 118