1 #pragma once
2 
3 #include <mbgl/style/expression/expression.hpp>
4 #include <mbgl/style/expression/parsing_context.hpp>
5 #include <mbgl/style/expression/get_covering_stops.hpp>
6 #include <mbgl/style/expression/interpolator.hpp>
7 #include <mbgl/style/conversion.hpp>
8 
9 #include <memory>
10 #include <map>
11 #include <cmath>
12 
13 namespace mbgl {
14 namespace style {
15 namespace expression {
16 
17 ParseResult parseInterpolate(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
18 
19 class Interpolate : public Expression {
20 public:
21     Interpolate(const type::Type& type_,
22                 Interpolator interpolator_,
23                 std::unique_ptr<Expression> input_,
24                 std::map<double, std::unique_ptr<Expression>> stops_);
25 
getInput() const26     const std::unique_ptr<Expression>& getInput() const { return input; }
getInterpolator() const27     const Interpolator& getInterpolator() const { return interpolator; }
28 
eachChild(const std::function<void (const Expression &)> & visit) const29     void eachChild(const std::function<void(const Expression&)>& visit) const override {
30         visit(*input);
31         for (const auto& stop : stops) {
32             visit(*stop.second);
33         }
34     }
35 
eachStop(const std::function<void (double,const Expression &)> & visit) const36     void eachStop(const std::function<void(double, const Expression&)>& visit) const {
37         for (const auto& stop : stops) {
38             visit(stop.first, *stop.second);
39         }
40     }
41 
42     // Return the smallest range of stops that covers the interval [lower, upper]
getCoveringStops(const double lower,const double upper) const43     Range<float> getCoveringStops(const double lower, const double upper) const {
44         return ::mbgl::style::expression::getCoveringStops(stops, lower, upper);
45     }
46 
interpolationFactor(const Range<double> & inputLevels,const double inputValue) const47     double interpolationFactor(const Range<double>& inputLevels, const double inputValue) const {
48         return interpolator.match(
49             [&](const auto& interp) { return interp.interpolationFactor(inputLevels, inputValue); }
50         );
51     }
52 
operator ==(const Expression & e) const53     bool operator==(const Expression& e) const override {
54         if (e.getKind() == Kind::Interpolate) {
55             auto rhs = static_cast<const Interpolate*>(&e);
56             if (interpolator != rhs->interpolator ||
57                 *input != *(rhs->input) ||
58                 stops.size() != rhs->stops.size())
59             {
60                 return false;
61             }
62 
63             return Expression::childrenEqual(stops, rhs->stops);
64         }
65         return false;
66     }
67 
68     std::vector<optional<Value>> possibleOutputs() const override;
69     mbgl::Value serialize() const override;
getOperator() const70     std::string getOperator() const override { return "interpolate"; }
71 
72 protected:
73     const Interpolator interpolator;
74     const std::unique_ptr<Expression> input;
75     const std::map<double, std::unique_ptr<Expression>> stops;
76 };
77 
78 ParseResult createInterpolate(type::Type type,
79                               Interpolator interpolator,
80                               std::unique_ptr<Expression> input,
81                               std::map<double, std::unique_ptr<Expression>> stops,
82                               ParsingContext& ctx);
83 
84 } // namespace expression
85 } // namespace style
86 } // namespace mbgl
87