diff options
Diffstat (limited to 'include/mbgl/style')
-rw-r--r-- | include/mbgl/style/expression/interpolate.hpp | 73 | ||||
-rw-r--r-- | include/mbgl/style/function/convert.hpp | 59 |
2 files changed, 30 insertions, 102 deletions
diff --git a/include/mbgl/style/expression/interpolate.hpp b/include/mbgl/style/expression/interpolate.hpp index 1a98189e29..dcdfa302ba 100644 --- a/include/mbgl/style/expression/interpolate.hpp +++ b/include/mbgl/style/expression/interpolate.hpp @@ -79,74 +79,11 @@ protected: const std::map<double, std::unique_ptr<Expression>> stops; }; -template <typename T> -class Interpolate : public InterpolateBase { -public: - Interpolate(type::Type type_, - Interpolator interpolator_, - std::unique_ptr<Expression> input_, - std::map<double, std::unique_ptr<Expression>> stops_ - ) : InterpolateBase(std::move(type_), std::move(interpolator_), std::move(input_), std::move(stops_)) - { - static_assert(util::Interpolatable<T>::value, "Interpolate expression requires an interpolatable value type."); - } - - EvaluationResult evaluate(const EvaluationContext& params) const override { - const EvaluationResult evaluatedInput = input->evaluate(params); - if (!evaluatedInput) { - return evaluatedInput.error(); - } - - float x = *fromExpressionValue<float>(*evaluatedInput); - if (std::isnan(x)) { - return EvaluationError { "Input is not a number." }; - } - - if (stops.empty()) { - return EvaluationError { "No stops in exponential curve." }; - } - - auto it = stops.upper_bound(x); - if (it == stops.end()) { - return stops.rbegin()->second->evaluate(params); - } else if (it == stops.begin()) { - return stops.begin()->second->evaluate(params); - } else { - float t = interpolationFactor({ std::prev(it)->first, it->first }, x); - - if (t == 0.0f) { - return std::prev(it)->second->evaluate(params); - } - if (t == 1.0f) { - return it->second->evaluate(params); - } - - EvaluationResult lower = std::prev(it)->second->evaluate(params); - if (!lower) { - return lower.error(); - } - EvaluationResult upper = it->second->evaluate(params); - if (!upper) { - return upper.error(); - } - - if (!lower->is<T>()) { - return EvaluationError { - "Expected value to be of type " + toString(valueTypeToExpressionType<T>()) + - ", but found " + toString(typeOf(*lower)) + " instead." - }; - } - - if (!upper->is<T>()) { - return EvaluationError { - "Expected value to be of type " + toString(valueTypeToExpressionType<T>()) + - ", but found " + toString(typeOf(*upper)) + " instead." - }; - } - return util::interpolate(lower->get<T>(), upper->get<T>(), t); - } - } -}; +ParseResult createInterpolate(type::Type type, + Interpolator interpolator, + std::unique_ptr<Expression> input, + std::map<double, std::unique_ptr<Expression>> stops, + ParsingContext& ctx); } // namespace expression } // namespace style diff --git a/include/mbgl/style/function/convert.hpp b/include/mbgl/style/function/convert.hpp index b34071d219..e5a5808e1d 100644 --- a/include/mbgl/style/function/convert.hpp +++ b/include/mbgl/style/function/convert.hpp @@ -91,22 +91,6 @@ struct Convert { return std::make_unique<detail::ErrorExpression>(message); } - template <typename OutputType> - static ParseResult makeInterpolate(type::Type type, - std::unique_ptr<Expression> input, - std::map<double, std::unique_ptr<Expression>> convertedStops, - Interpolator interpolator) - { - ParseResult curve = ParseResult(std::make_unique<Interpolate<OutputType>>( - std::move(type), - std::move(interpolator), - std::move(input), - std::move(convertedStops) - )); - assert(curve); - return std::move(*curve); - } - template <typename Key> static ParseResult makeMatch(type::Type type, std::unique_ptr<Expression> input, @@ -191,11 +175,12 @@ struct Convert { template <typename T> static std::unique_ptr<Expression> toExpression(const ExponentialStops<T>& stops) { - ParseResult e = makeInterpolate<typename ValueConverter<T>::ExpressionType>( - valueTypeToExpressionType<T>(), - makeZoom(), - convertStops(stops.stops), - ExponentialInterpolator(stops.base)); + ParsingContext ctx; + ParseResult e = createInterpolate(valueTypeToExpressionType<T>(), + ExponentialInterpolator(stops.base), + makeZoom(), + convertStops(stops.stops), + ctx); assert(e); return std::move(*e); } @@ -214,10 +199,12 @@ struct Convert { static std::unique_ptr<Expression> toExpression(const std::string& property, const ExponentialStops<T>& stops) { - ParseResult e = makeInterpolate<typename ValueConverter<T>::ExpressionType>(valueTypeToExpressionType<T>(), - makeGet(type::Number, property), - convertStops(stops.stops), - ExponentialInterpolator(stops.base)); + ParsingContext ctx; + ParseResult e = createInterpolate(valueTypeToExpressionType<T>(), + ExponentialInterpolator(stops.base), + makeGet(type::Number, property), + convertStops(stops.stops), + ctx); assert(e); return std::move(*e); } @@ -247,10 +234,12 @@ struct Convert { template <typename T> static typename std::enable_if_t<util::Interpolatable<T>::value, ParseResult> makeZoomCurve(std::map<double, std::unique_ptr<Expression>> stops) { - return makeInterpolate<typename ValueConverter<T>::ExpressionType>(valueTypeToExpressionType<T>(), - makeZoom(), - std::move(stops), - ExponentialInterpolator(1.0)); + ParsingContext ctx; + return createInterpolate(valueTypeToExpressionType<T>(), + ExponentialInterpolator(1.0), + makeZoom(), + std::move(stops), + ctx); } // non-interpolatable zoom curve @@ -264,13 +253,15 @@ struct Convert { static std::unique_ptr<Expression> toExpression(const std::string& property, const CompositeExponentialStops<T>& stops) { + ParsingContext ctx; + std::map<double, std::unique_ptr<Expression>> outerStops; for (const std::pair<float, std::map<float, T>>& stop : stops.stops) { - std::unique_ptr<Expression> get = makeGet(type::Number, property); - ParseResult innerInterpolate = makeInterpolate<typename ValueConverter<T>::ExpressionType>(valueTypeToExpressionType<T>(), - std::move(get), - convertStops(stop.second), - ExponentialInterpolator(stops.base)); + ParseResult innerInterpolate = createInterpolate(valueTypeToExpressionType<T>(), + ExponentialInterpolator(stops.base), + makeGet(type::Number, property), + convertStops(stop.second), + ctx); assert(innerInterpolate); outerStops.emplace(stop.first, std::move(*innerInterpolate)); } |