#pragma once #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { namespace style { template class CameraFunction { public: using Stops = std::conditional_t< util::Interpolatable::value, variant< ExponentialStops, IntervalStops>, variant< IntervalStops>>; CameraFunction(std::unique_ptr expression_) : expression(std::move(expression_)), zoomCurve(expression::findZoomCurveChecked(expression.get())) { assert(!expression::isZoomConstant(*expression)); assert(expression::isFeatureConstant(*expression)); } CameraFunction(Stops stops_) : stops(std::move(stops_)), expression(stops.match([&] (const auto& s) { return expression::Convert::toExpression(s); })), zoomCurve(expression::findZoomCurveChecked(expression.get())) {} T evaluate(float zoom) const { const expression::EvaluationResult result = expression->evaluate(expression::EvaluationContext(zoom, nullptr)); if (result) { const optional typed = expression::fromExpressionValue(*result); return typed ? *typed : T(); } return T(); } float interpolationFactor(const Range& inputLevels, const float inputValue) const { return zoomCurve.match( [&](const expression::InterpolateBase* z) { return z->interpolationFactor(Range { inputLevels.min, inputLevels.max }, inputValue); }, [&](const expression::Step*) { return 0.0f; } ); } Range getCoveringStops(const float lower, const float upper) const { return zoomCurve.match( [&](auto z) { return z->getCoveringStops(lower, upper); } ); } std::vector> possibleOutputs() const { return expression::fromExpressionValues(expression->possibleOutputs()); } friend bool operator==(const CameraFunction& lhs, const CameraFunction& rhs) { return *lhs.expression == *rhs.expression; } bool useIntegerZoom = false; const expression::Expression& getExpression() const { return *expression; } // retained for compatibility with pre-expression function API Stops stops; private: std::shared_ptr expression; const variant zoomCurve; }; } // namespace style } // namespace mbgl