#pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { class GeometryTileFeature; namespace style { // A CompositeFunction consists of an outer zoom function whose stop range values are // "inner" source functions. It provides the GL Native implementation of // "zoom-and-property" functions from the style spec. template class CompositeFunction { public: using InnerStops = std::conditional_t< util::Interpolatable::value, variant< ExponentialStops, IntervalStops, CategoricalStops>, variant< IntervalStops, CategoricalStops>>; using Stops = std::conditional_t< util::Interpolatable::value, variant< CompositeExponentialStops, CompositeIntervalStops, CompositeCategoricalStops>, variant< CompositeIntervalStops, CompositeCategoricalStops>>; using Curve = expression::Curve::ExpressionType>; CompositeFunction(std::unique_ptr expression_) : expression(std::move(expression_)), zoomCurve(*Curve::findZoomCurve(expression.get())) { assert(!expression->isZoomConstant()); assert(!expression->isFeatureConstant()); } CompositeFunction(std::string property_, Stops stops_, optional defaultValue_ = {}) : property(std::move(property_)), stops(std::move(stops_)), defaultValue(std::move(defaultValue_)), expression(stops.match([&] (const auto& s) { return expression::Convert::toExpression(property, s, defaultValue); })), zoomCurve(*Curve::findZoomCurve(expression.get())) {} // Return the range obtained by evaluating the function at each of the zoom levels in zoomRange template Range evaluate(const Range& zoomRange, const Feature& feature, T finalDefaultValue) { return Range { evaluate(zoomRange.min, feature, finalDefaultValue), evaluate(zoomRange.max, feature, finalDefaultValue) }; } template T evaluate(float zoom, const Feature& feature, T finalDefaultValue) const { const expression::EvaluationResult result = expression->evaluate(expression::EvaluationParameters({zoom}, &feature)); if (result) { const optional typed = expression::fromExpressionValue(*result); return typed ? *typed : finalDefaultValue; } return finalDefaultValue; } float interpolationFactor(const Range& inputLevels, const float& inputValue) const { return zoomCurve->interpolationFactor(Range { inputLevels.min, inputLevels.max }, inputValue); } Range getCoveringStops(const float lower, const float upper) const { return zoomCurve->getCoveringStops(lower, upper); } friend bool operator==(const CompositeFunction& lhs, const CompositeFunction& rhs) { return std::tie(lhs.property, lhs.stops, lhs.defaultValue) == std::tie(rhs.property, rhs.stops, rhs.defaultValue); } std::string property; Stops stops; optional defaultValue; bool useIntegerZoom = false; private: std::shared_ptr expression; const Curve* zoomCurve; }; } // namespace style } // namespace mbgl