diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2018-07-13 18:14:12 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2018-07-20 11:56:30 -0700 |
commit | c8edbb0500cbf4baf1d5fdb0e63679539e166585 (patch) | |
tree | 750f3b72b9e3b1c91ddbc0541cfc64d7d80ffe71 /src | |
parent | 6d7072162b764c2432c010cd463a5a2c0093d606 (diff) | |
download | qtlocation-mapboxgl-c8edbb0500cbf4baf1d5fdb0e63679539e166585.tar.gz |
[core] Replace {Source,Camera,Composite}Function with PropertyExpression
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/programs/symbol_program.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/programs/symbol_program.hpp | 42 | ||||
-rw-r--r-- | src/mbgl/renderer/cross_faded_property_evaluator.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/cross_faded_property_evaluator.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/data_driven_property_evaluator.hpp | 19 | ||||
-rw-r--r-- | src/mbgl/renderer/paint_property_binder.hpp | 33 | ||||
-rw-r--r-- | src/mbgl/renderer/possibly_evaluated_property_value.hpp | 23 | ||||
-rw-r--r-- | src/mbgl/renderer/property_evaluator.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/conversion/function.cpp | 297 | ||||
-rw-r--r-- | src/mbgl/style/conversion/stringify.hpp | 12 | ||||
-rw-r--r-- | src/mbgl/style/expression/find_zoom_curve.cpp | 14 | ||||
-rw-r--r-- | src/mbgl/style/properties.hpp | 5 |
12 files changed, 216 insertions, 259 deletions
diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index 84a7a53f1d..8df3b4ae3c 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -17,14 +17,20 @@ std::unique_ptr<SymbolSizeBinder> SymbolSizeBinder::create(const float tileZoom, const style::DataDrivenPropertyValue<float>& sizeProperty, const float defaultValue) { return sizeProperty.match( - [&] (const style::CompositeFunction<float>& function) -> std::unique_ptr<SymbolSizeBinder> { - return std::make_unique<CompositeFunctionSymbolSizeBinder>(tileZoom, function, defaultValue); - }, - [&] (const style::SourceFunction<float>& function) { - return std::make_unique<SourceFunctionSymbolSizeBinder>(tileZoom, function, defaultValue); + [&] (const Undefined& value) -> std::unique_ptr<SymbolSizeBinder> { + return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, value, defaultValue); }, - [&] (const auto& value) -> std::unique_ptr<SymbolSizeBinder> { + [&] (float value) -> std::unique_ptr<SymbolSizeBinder> { return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, value, defaultValue); + }, + [&] (const style::PropertyExpression<float>& expression) -> std::unique_ptr<SymbolSizeBinder> { + if (expression.isFeatureConstant()) { + return std::make_unique<ConstantSymbolSizeBinder>(tileZoom, expression, defaultValue); + } else if (expression.isZoomConstant()) { + return std::make_unique<SourceFunctionSymbolSizeBinder>(tileZoom, expression, defaultValue); + } else { + return std::make_unique<CompositeFunctionSymbolSizeBinder>(tileZoom, expression, defaultValue); + } } ); } diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 51f9a48f7f..35b5821918 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -143,13 +143,13 @@ public: ConstantSymbolSizeBinder(const float /*tileZoom*/, const style::Undefined&, const float defaultValue) : layoutSize(defaultValue) {} - ConstantSymbolSizeBinder(const float tileZoom, const style::CameraFunction<float>& function_, const float /*defaultValue*/) - : layoutSize(function_.evaluate(tileZoom + 1)), - function(function_) { - const Range<float> zoomLevels = function_.getCoveringStops(tileZoom, tileZoom + 1); + ConstantSymbolSizeBinder(const float tileZoom, const style::PropertyExpression<float>& expression_, const float /*defaultValue*/) + : layoutSize(expression_.evaluate(tileZoom + 1)), + expression(expression_) { + const Range<float> zoomLevels = expression_.getCoveringStops(tileZoom, tileZoom + 1); coveringRanges = std::make_tuple( zoomLevels, - Range<float> { function_.evaluate(zoomLevels.min), function_.evaluate(zoomLevels.max) } + Range<float> { expression_.evaluate(zoomLevels.min), expression_.evaluate(zoomLevels.max) } ); } @@ -157,7 +157,7 @@ public: ZoomEvaluatedSize evaluateForZoom(float currentZoom) const override { float size = layoutSize; - bool isZoomConstant = !(coveringRanges || function); + bool isZoomConstant = !(coveringRanges || expression); if (coveringRanges) { // Even though we could get the exact value of the camera function // at z = currentZoom, we intentionally do not: instead, we interpolate @@ -167,12 +167,12 @@ public: const Range<float>& zoomLevels = std::get<0>(*coveringRanges); const Range<float>& sizeLevels = std::get<1>(*coveringRanges); float t = util::clamp( - function->interpolationFactor(zoomLevels, currentZoom), + expression->interpolationFactor(zoomLevels, currentZoom), 0.0f, 1.0f ); size = sizeLevels.min + t * (sizeLevels.max - sizeLevels.min); - } else if (function) { - size = function->evaluate(currentZoom); + } else if (expression) { + size = expression->evaluate(currentZoom); } const float unused = 0.0f; @@ -181,7 +181,7 @@ public: float layoutSize; optional<std::tuple<Range<float>, Range<float>>> coveringRanges; - optional<style::CameraFunction<float>> function; + optional<style::PropertyExpression<float>> expression; }; class SourceFunctionSymbolSizeBinder final : public SymbolSizeBinder { @@ -190,13 +190,13 @@ public: using VertexVector = gl::VertexVector<Vertex>; using VertexBuffer = gl::VertexBuffer<Vertex>; - SourceFunctionSymbolSizeBinder(const float /*tileZoom*/, const style::SourceFunction<float>& function_, const float defaultValue_) - : function(function_), + SourceFunctionSymbolSizeBinder(const float /*tileZoom*/, style::PropertyExpression<float> expression_, const float defaultValue_) + : expression(std::move(expression_)), defaultValue(defaultValue_) { } Range<float> getVertexSizeData(const GeometryTileFeature& feature) override { - const float size = function.evaluate(feature, defaultValue); + const float size = expression.evaluate(feature, defaultValue); return { size, size }; }; @@ -205,30 +205,30 @@ public: return { true, false, unused, unused, unused }; } - style::SourceFunction<float> function; + style::PropertyExpression<float> expression; const float defaultValue; }; class CompositeFunctionSymbolSizeBinder final : public SymbolSizeBinder { public: - CompositeFunctionSymbolSizeBinder(const float tileZoom, const style::CompositeFunction<float>& function_, const float defaultValue_) - : function(function_), + CompositeFunctionSymbolSizeBinder(const float tileZoom, style::PropertyExpression<float> expression_, const float defaultValue_) + : expression(std::move(expression_)), defaultValue(defaultValue_), layoutZoom(tileZoom + 1), - coveringZoomStops(function.getCoveringStops(tileZoom, tileZoom + 1)) + coveringZoomStops(expression.getCoveringStops(tileZoom, tileZoom + 1)) {} Range<float> getVertexSizeData(const GeometryTileFeature& feature) override { return { - function.evaluate(coveringZoomStops.min, feature, defaultValue), - function.evaluate(coveringZoomStops.max, feature, defaultValue) + expression.evaluate(coveringZoomStops.min, feature, defaultValue), + expression.evaluate(coveringZoomStops.max, feature, defaultValue) }; }; ZoomEvaluatedSize evaluateForZoom(float currentZoom) const override { float sizeInterpolationT = util::clamp( - function.interpolationFactor(coveringZoomStops, currentZoom), + expression.interpolationFactor(coveringZoomStops, currentZoom), 0.0f, 1.0f ); @@ -236,7 +236,7 @@ public: return { false, false, sizeInterpolationT, unused, unused }; } - style::CompositeFunction<float> function; + style::PropertyExpression<float> expression; const float defaultValue; float layoutZoom; Range<float> coveringZoomStops; diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.cpp b/src/mbgl/renderer/cross_faded_property_evaluator.cpp index 4dff9dbf12..9a7af8636c 100644 --- a/src/mbgl/renderer/cross_faded_property_evaluator.cpp +++ b/src/mbgl/renderer/cross_faded_property_evaluator.cpp @@ -16,10 +16,10 @@ Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const T& constant) const { } template <typename T> -Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const style::CameraFunction<T>& function) const { - return calculate(function.evaluate(parameters.z - 1.0f), - function.evaluate(parameters.z), - function.evaluate(parameters.z + 1.0f)); +Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const style::PropertyExpression<T>& expression) const { + return calculate(expression.evaluate(parameters.z - 1.0f), + expression.evaluate(parameters.z), + expression.evaluate(parameters.z + 1.0f)); } template <typename T> diff --git a/src/mbgl/renderer/cross_faded_property_evaluator.hpp b/src/mbgl/renderer/cross_faded_property_evaluator.hpp index 40ecba5d93..1d17c5eb2f 100644 --- a/src/mbgl/renderer/cross_faded_property_evaluator.hpp +++ b/src/mbgl/renderer/cross_faded_property_evaluator.hpp @@ -27,7 +27,7 @@ public: Faded<T> operator()(const style::Undefined&) const; Faded<T> operator()(const T& constant) const; - Faded<T> operator()(const style::CameraFunction<T>&) const; + Faded<T> operator()(const style::PropertyExpression<T>&) const; private: Faded<T> calculate(const T& min, const T& mid, const T& max) const; diff --git a/src/mbgl/renderer/data_driven_property_evaluator.hpp b/src/mbgl/renderer/data_driven_property_evaluator.hpp index 79ecd0d495..f9452cc572 100644 --- a/src/mbgl/renderer/data_driven_property_evaluator.hpp +++ b/src/mbgl/renderer/data_driven_property_evaluator.hpp @@ -23,21 +23,18 @@ public: return ResultType(constant); } - ResultType operator()(const style::CameraFunction<T>& function) const { - if (!parameters.useIntegerZoom) { - return ResultType(function.evaluate(parameters.z)); + ResultType operator()(const style::PropertyExpression<T>& expression) const { + if (!expression.isFeatureConstant()) { + auto returnExpression = expression; + returnExpression.useIntegerZoom = parameters.useIntegerZoom; + return ResultType(returnExpression); + } else if (!parameters.useIntegerZoom) { + return ResultType(expression.evaluate(parameters.z)); } else { - return ResultType(function.evaluate(floor(parameters.z))); + return ResultType(expression.evaluate(floor(parameters.z))); } } - template <class Function> - ResultType operator()(const Function& function) const { - auto returnFunction = function; - returnFunction.useIntegerZoom = parameters.useIntegerZoom; - return ResultType(returnFunction); - } - private: const PropertyEvaluationParameters& parameters; T defaultValue; diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index 3a49882f12..aade672ae7 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -130,13 +130,13 @@ public: using Attribute = ZoomInterpolatedAttributeType<A>; using AttributeBinding = typename Attribute::Binding; - SourceFunctionPaintPropertyBinder(style::SourceFunction<T> function_, T defaultValue_) - : function(std::move(function_)), + SourceFunctionPaintPropertyBinder(style::PropertyExpression<T> expression_, T defaultValue_) + : expression(std::move(expression_)), defaultValue(std::move(defaultValue_)) { } void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override { - auto evaluated = function.evaluate(feature, defaultValue); + auto evaluated = expression.evaluate(feature, defaultValue); this->statistics.add(evaluated); auto value = attributeValue(evaluated); for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) { @@ -170,7 +170,7 @@ public: } private: - style::SourceFunction<T> function; + style::PropertyExpression<T> expression; T defaultValue; gl::VertexVector<BaseVertex> vertexVector; optional<gl::VertexBuffer<BaseVertex>> vertexBuffer; @@ -187,14 +187,14 @@ public: using AttributeBinding = typename Attribute::Binding; using Vertex = gl::detail::Vertex<Attribute>; - CompositeFunctionPaintPropertyBinder(style::CompositeFunction<T> function_, float zoom, T defaultValue_) - : function(std::move(function_)), + CompositeFunctionPaintPropertyBinder(style::PropertyExpression<T> expression_, float zoom, T defaultValue_) + : expression(std::move(expression_)), defaultValue(std::move(defaultValue_)), zoomRange({zoom, zoom + 1}) { } void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) override { - Range<T> range = function.evaluate(zoomRange, feature, defaultValue); + Range<T> range = expression.evaluate(zoomRange, feature, defaultValue); this->statistics.add(range.min); this->statistics.add(range.max); AttributeValue value = zoomInterpolatedAttributeValue( @@ -218,10 +218,10 @@ public: } float interpolationFactor(float currentZoom) const override { - if (function.useIntegerZoom) { - return function.interpolationFactor(zoomRange, std::floor(currentZoom)); + if (expression.useIntegerZoom) { + return expression.interpolationFactor(zoomRange, std::floor(currentZoom)); } else { - return function.interpolationFactor(zoomRange, currentZoom); + return expression.interpolationFactor(zoomRange, currentZoom); } } @@ -235,7 +235,7 @@ public: } private: - style::CompositeFunction<T> function; + style::PropertyExpression<T> expression; T defaultValue; Range<float> zoomRange; gl::VertexVector<Vertex> vertexVector; @@ -249,11 +249,12 @@ PaintPropertyBinder<T, A>::create(const PossiblyEvaluatedPropertyValue<T>& value [&] (const T& constant) -> std::unique_ptr<PaintPropertyBinder<T, A>> { return std::make_unique<ConstantPaintPropertyBinder<T, A>>(constant); }, - [&] (const style::SourceFunction<T>& function) { - return std::make_unique<SourceFunctionPaintPropertyBinder<T, A>>(function, defaultValue); - }, - [&] (const style::CompositeFunction<T>& function) { - return std::make_unique<CompositeFunctionPaintPropertyBinder<T, A>>(function, zoom, defaultValue); + [&] (const style::PropertyExpression<T>& expression) -> std::unique_ptr<PaintPropertyBinder<T, A>> { + if (expression.isZoomConstant()) { + return std::make_unique<SourceFunctionPaintPropertyBinder<T, A>>(expression, defaultValue); + } else { + return std::make_unique<CompositeFunctionPaintPropertyBinder<T, A>>(expression, zoom, defaultValue); + } } ); } diff --git a/src/mbgl/renderer/possibly_evaluated_property_value.hpp b/src/mbgl/renderer/possibly_evaluated_property_value.hpp index e662d5dfb1..f2d265f2f7 100644 --- a/src/mbgl/renderer/possibly_evaluated_property_value.hpp +++ b/src/mbgl/renderer/possibly_evaluated_property_value.hpp @@ -1,7 +1,6 @@ #pragma once -#include <mbgl/style/function/source_function.hpp> -#include <mbgl/style/function/composite_function.hpp> +#include <mbgl/style/property_expression.hpp> #include <mbgl/util/interpolate.hpp> #include <mbgl/util/variant.hpp> @@ -12,8 +11,7 @@ class PossiblyEvaluatedPropertyValue { private: using Value = variant< T, - style::SourceFunction<T>, - style::CompositeFunction<T>>; + style::PropertyExpression<T>>; Value value; @@ -45,17 +43,14 @@ public: template <class Feature> T evaluate(const Feature& feature, float zoom, T defaultValue) const { return this->match( - [&] (const T& constant_) { return constant_; }, - [&] (const style::SourceFunction<T>& function) { - return function.evaluate(feature, defaultValue); - }, - [&] (const style::CompositeFunction<T>& function) { - if (useIntegerZoom) { - return function.evaluate(floor(zoom), feature, defaultValue); - } else { - return function.evaluate(zoom, feature, defaultValue); - } + [&] (const T& constant_) { return constant_; }, + [&] (const style::PropertyExpression<T>& expression) { + if (useIntegerZoom) { + return expression.evaluate(floor(zoom), feature, defaultValue); + } else { + return expression.evaluate(zoom, feature, defaultValue); } + } ); } diff --git a/src/mbgl/renderer/property_evaluator.hpp b/src/mbgl/renderer/property_evaluator.hpp index 3ac0573920..03e0f5a002 100644 --- a/src/mbgl/renderer/property_evaluator.hpp +++ b/src/mbgl/renderer/property_evaluator.hpp @@ -16,7 +16,7 @@ public: T operator()(const style::Undefined&) const { return defaultValue; } T operator()(const T& constant) const { return constant; } - T operator()(const style::CameraFunction<T>& fn) const { return fn.evaluate(parameters.z); } + T operator()(const style::PropertyExpression<T>& fn) const { return fn.evaluate(parameters.z); } private: const PropertyEvaluationParameters& parameters; diff --git a/src/mbgl/style/conversion/function.cpp b/src/mbgl/style/conversion/function.cpp index 64adf522a1..39e061d75a 100644 --- a/src/mbgl/style/conversion/function.cpp +++ b/src/mbgl/style/conversion/function.cpp @@ -66,29 +66,6 @@ static bool interpolatable(type::Type type) { ); } -static FunctionType functionType(type::Type type, const Convertible& value) { - auto typeValue = objectMember(value, "type"); - if (!typeValue) { - return interpolatable(type) ? FunctionType::Exponential : FunctionType::Interval; - } - - optional<std::string> string = toString(*typeValue); - if (!string) { - return FunctionType::Invalid; - } - - if (*string == "interval") - return FunctionType::Interval; - if (*string == "exponential" && interpolatable(type)) - return FunctionType::Exponential; - if (*string == "categorical") - return FunctionType::Categorical; - if (*string == "identity") - return FunctionType::Identity; - - return FunctionType::Invalid; -} - static optional<std::unique_ptr<Expression>> convertLiteral(type::Type type, const Convertible& value, Error& error) { return type.match( [&] (const type::NumberType&) -> optional<std::unique_ptr<Expression>> { @@ -426,106 +403,16 @@ static optional<std::unique_ptr<Expression>> convertCategoricalFunction(type::Ty return {}; } -optional<std::unique_ptr<Expression>> convertCameraFunctionToExpression(type::Type type, - const Convertible& value, - Error& error) { - if (!isObject(value)) { - error = { "function must be an object" }; - return {}; - } - - switch (functionType(type, value)) { - case FunctionType::Interval: - return convertIntervalFunction(type, value, error, zoom()); - case FunctionType::Exponential: - return convertExponentialFunction(type, value, error, zoom()); - default: - error = { "unsupported function type" }; - return {}; - } -} - -optional<std::unique_ptr<Expression>> convertSourceFunctionToExpression(type::Type type, - const Convertible& value, - Error& error) { - if (!isObject(value)) { - error = { "function must be an object" }; - return {}; - } - - auto propertyValue = objectMember(value, "property"); - if (!propertyValue) { - error = { "function must specify property" }; - return {}; - } - - auto property = toString(*propertyValue); - if (!property) { - error = { "function property must be a string" }; - return {}; - } - - switch (functionType(type, value)) { - case FunctionType::Interval: - return convertIntervalFunction(type, value, error, number(get(literal(*property)))); - case FunctionType::Exponential: - return convertExponentialFunction(type, value, error, number(get(literal(*property)))); - case FunctionType::Categorical: - return convertCategoricalFunction(type, value, error, *property); - case FunctionType::Identity: - return type.match( - [&] (const type::StringType&) -> optional<std::unique_ptr<Expression>> { - return string(get(literal(*property))); - }, - [&] (const type::NumberType&) -> optional<std::unique_ptr<Expression>> { - return number(get(literal(*property))); - }, - [&] (const type::BooleanType&) -> optional<std::unique_ptr<Expression>> { - return boolean(get(literal(*property))); - }, - [&] (const type::ColorType&) -> optional<std::unique_ptr<Expression>> { - return toColor(get(literal(*property))); - }, - [&] (const type::Array& array) -> optional<std::unique_ptr<Expression>> { - return std::unique_ptr<Expression>( - std::make_unique<ArrayAssertion>(array, get(literal(*property)))); - }, - [&] (const auto&) -> optional<std::unique_ptr<Expression>> { - assert(false); // No properties use this type. - return {}; - } - ); - default: - error = { "unsupported function type" }; - return {}; - } -} - -template <class T> +template <class T, class Fn> optional<std::unique_ptr<Expression>> composite(type::Type type, const Convertible& value, Error& error, - std::unique_ptr<Expression> (*makeInnerExpression) (type::Type type, - double base, - const std::string& property, - std::map<T, std::unique_ptr<Expression>>)) { - auto propertyValue = objectMember(value, "property"); - if (!propertyValue) { - error = { "function must specify property" }; - return {}; - } - + const Fn& makeInnerExpression) { auto base = convertBase(value, error); if (!base) { return {}; } - auto propertyString = toString(*propertyValue); - if (!propertyString) { - error = { "function property must be a string" }; - return {}; - } - auto stopsValue = objectMember(value, "stops"); // Checked by caller. @@ -587,7 +474,7 @@ optional<std::unique_ptr<Expression>> composite(type::Type type, std::map<double, std::unique_ptr<Expression>> stops; for (auto& e : map) { - stops.emplace(e.first, makeInnerExpression(type, *base, *propertyString, std::move(e.second))); + stops.emplace(e.first, makeInnerExpression(type, *base, std::move(e.second))); } if (interpolatable(type)) { @@ -597,14 +484,83 @@ optional<std::unique_ptr<Expression>> composite(type::Type type, } } -optional<std::unique_ptr<Expression>> convertCompositeFunctionToExpression(type::Type type, - const Convertible& value, - Error& err) { +optional<std::unique_ptr<Expression>> convertFunctionToExpression(type::Type type, + const Convertible& value, + Error& err) { if (!isObject(value)) { err = { "function must be an object" }; return {}; } + FunctionType functionType = FunctionType::Invalid; + + auto typeValue = objectMember(value, "type"); + if (!typeValue) { + functionType = interpolatable(type) ? FunctionType::Exponential : FunctionType::Interval; + } else { + optional<std::string> string = toString(*typeValue); + if (string) { + if (*string == "interval") + functionType = FunctionType::Interval; + if (*string == "exponential" && interpolatable(type)) + functionType = FunctionType::Exponential; + if (*string == "categorical") + functionType = FunctionType::Categorical; + if (*string == "identity") + functionType = FunctionType::Identity; + } + } + + if (!objectMember(value, "property")) { + // Camera function. + switch (functionType) { + case FunctionType::Interval: + return convertIntervalFunction(type, value, err, zoom()); + case FunctionType::Exponential: + return convertExponentialFunction(type, value, err, zoom()); + default: + err = { "unsupported function type" }; + return {}; + } + } + + auto propertyValue = objectMember(value, "property"); + if (!propertyValue) { + err = { "function must specify property" }; + return {}; + } + + auto property = toString(*propertyValue); + if (!property) { + err = { "function property must be a string" }; + return {}; + } + + if (functionType == FunctionType::Identity) { + return type.match( + [&] (const type::StringType&) -> optional<std::unique_ptr<Expression>> { + return string(get(literal(*property))); + }, + [&] (const type::NumberType&) -> optional<std::unique_ptr<Expression>> { + return number(get(literal(*property))); + }, + [&] (const type::BooleanType&) -> optional<std::unique_ptr<Expression>> { + return boolean(get(literal(*property))); + }, + [&] (const type::ColorType&) -> optional<std::unique_ptr<Expression>> { + return toColor(get(literal(*property))); + }, + [&] (const type::Array& array) -> optional<std::unique_ptr<Expression>> { + return std::unique_ptr<Expression>( + std::make_unique<ArrayAssertion>(array, get(literal(*property)))); + }, + [&] (const auto&) -> optional<std::unique_ptr<Expression>> { + assert(false); // No properties use this type. + return {}; + } + ); + } + auto stopsValue = objectMember(value, "stops"); if (!stopsValue) { err = { "function value must specify stops" }; @@ -636,62 +592,73 @@ optional<std::unique_ptr<Expression>> convertCompositeFunctionToExpression(type: const auto& stop = arrayMember(first, 0); if (!isObject(stop)) { - err = { "stop must be an object" }; - return {}; - } - - auto sourceValue = objectMember(stop, "value"); - if (!sourceValue) { - err = { "stop must specify value" }; - return {}; - } - - if (toBool(*sourceValue)) { - switch (functionType(type, value)) { - case FunctionType::Categorical: - return composite<bool>(type, value, err, [] (type::Type type_, double, const std::string& property, std::map<bool, std::unique_ptr<Expression>> stops) { - return categorical<bool>(type_, property, std::move(stops)); - }); - default: - err = { "unsupported function type" }; - return {}; - } - } - - if (toNumber(*sourceValue)) { - switch (functionType(type, value)) { + // Source function. + switch (functionType) { case FunctionType::Interval: - return composite<double>(type, value, err, [] (type::Type type_, double, const std::string& property, std::map<double, std::unique_ptr<Expression>> stops) { - return step(type_, number(get(literal(property))), std::move(stops)); - }); + return convertIntervalFunction(type, value, err, number(get(literal(*property)))); case FunctionType::Exponential: - return composite<double>(type, value, err, [] (type::Type type_, double base, const std::string& property, std::map<double, std::unique_ptr<Expression>> stops) { - return interpolate(type_, exponential(base), number(get(literal(property))), std::move(stops)); - }); + return convertExponentialFunction(type, value, err, number(get(literal(*property)))); case FunctionType::Categorical: - return composite<int64_t>(type, value, err, [] (type::Type type_, double, const std::string& property, std::map<int64_t, std::unique_ptr<Expression>> stops) { - return categorical<int64_t>(type_, property, std::move(stops)); - }); + return convertCategoricalFunction(type, value, err, *property); default: err = { "unsupported function type" }; return {}; } - } - - if (toString(*sourceValue)) { - switch (functionType(type, value)) { - case FunctionType::Categorical: - return composite<std::string>(type, value, err, [] (type::Type type_, double, const std::string& property, std::map<std::string, std::unique_ptr<Expression>> stops) { - return categorical<std::string>(type_, property, std::move(stops)); - }); - default: - err = { "unsupported function type" }; + } else { + // Composite function. + auto sourceValue = objectMember(stop, "value"); + if (!sourceValue) { + err = { "stop must specify value" }; return {}; } - } - err = { "stop domain value must be a number, string, or boolean" }; - return {}; + if (toBool(*sourceValue)) { + switch (functionType) { + case FunctionType::Categorical: + return composite<bool>(type, value, err, [&] (type::Type type_, double, std::map<bool, std::unique_ptr<Expression>> stops) { + return categorical<bool>(type_, *property, std::move(stops)); + }); + default: + err = { "unsupported function type" }; + return {}; + } + } + + if (toNumber(*sourceValue)) { + switch (functionType) { + case FunctionType::Interval: + return composite<double>(type, value, err, [&] (type::Type type_, double, std::map<double, std::unique_ptr<Expression>> stops) { + return step(type_, number(get(literal(*property))), std::move(stops)); + }); + case FunctionType::Exponential: + return composite<double>(type, value, err, [&] (type::Type type_, double base, std::map<double, std::unique_ptr<Expression>> stops) { + return interpolate(type_, exponential(base), number(get(literal(*property))), std::move(stops)); + }); + case FunctionType::Categorical: + return composite<int64_t>(type, value, err, [&] (type::Type type_, double, std::map<int64_t, std::unique_ptr<Expression>> stops) { + return categorical<int64_t>(type_, *property, std::move(stops)); + }); + default: + err = { "unsupported function type" }; + return {}; + } + } + + if (toString(*sourceValue)) { + switch (functionType) { + case FunctionType::Categorical: + return composite<std::string>(type, value, err, [&] (type::Type type_, double, std::map<std::string, std::unique_ptr<Expression>> stops) { + return categorical<std::string>(type_, *property, std::move(stops)); + }); + default: + err = { "unsupported function type" }; + return {}; + } + } + + err = { "stop domain value must be a number, string, or boolean" }; + return {}; + } } } // namespace conversion diff --git a/src/mbgl/style/conversion/stringify.hpp b/src/mbgl/style/conversion/stringify.hpp index 74171763a0..77a39c51f9 100644 --- a/src/mbgl/style/conversion/stringify.hpp +++ b/src/mbgl/style/conversion/stringify.hpp @@ -138,17 +138,7 @@ void stringify(Writer& writer, const Undefined&) { } template <class Writer, class T> -void stringify(Writer& writer, const CameraFunction<T>& fn) { - stringify(writer, fn.getExpression().serialize()); -} - -template <class Writer, class T> -void stringify(Writer& writer, const SourceFunction<T>& fn) { - stringify(writer, fn.getExpression().serialize()); -} - -template <class Writer, class T> -void stringify(Writer& writer, const CompositeFunction<T>& fn) { +void stringify(Writer& writer, const PropertyExpression<T>& fn) { stringify(writer, fn.getExpression().serialize()); } diff --git a/src/mbgl/style/expression/find_zoom_curve.cpp b/src/mbgl/style/expression/find_zoom_curve.cpp index ce8487a3af..1e0a936605 100644 --- a/src/mbgl/style/expression/find_zoom_curve.cpp +++ b/src/mbgl/style/expression/find_zoom_curve.cpp @@ -2,6 +2,7 @@ #include <mbgl/style/expression/compound_expression.hpp> #include <mbgl/style/expression/let.hpp> #include <mbgl/style/expression/coalesce.hpp> +#include <mbgl/style/expression/is_constant.hpp> #include <mbgl/util/variant.hpp> #include <mbgl/util/optional.hpp> @@ -59,14 +60,17 @@ optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(c return result; } -variant<const Interpolate*, const Step*> findZoomCurveChecked(const expression::Expression* e) { +variant<std::nullptr_t, const Interpolate*, const Step*> findZoomCurveChecked(const expression::Expression* e) { + if (isZoomConstant(*e)) { + return nullptr; + } return findZoomCurve(e)->match( - [](const ParsingError&) -> variant<const Interpolate*, const Step*> { + [](const ParsingError&) -> variant<std::nullptr_t, const Interpolate*, const Step*> { assert(false); - return {}; + return nullptr; }, - [](auto zoomCurve) -> variant<const Interpolate*, const Step*> { - return {std::move(zoomCurve)}; + [](auto zoomCurve) -> variant<std::nullptr_t, const Interpolate*, const Step*> { + return zoomCurve; } ); } diff --git a/src/mbgl/style/properties.hpp b/src/mbgl/style/properties.hpp index dfcf7993a7..9206e96982 100644 --- a/src/mbgl/style/properties.hpp +++ b/src/mbgl/style/properties.hpp @@ -154,10 +154,7 @@ public: [&] (const T& t) { return t; }, - [&] (const SourceFunction<T>& t) { - return t.evaluate(feature, defaultValue); - }, - [&] (const CompositeFunction<T>& t) { + [&] (const PropertyExpression<T>& t) { return t.evaluate(z, feature, defaultValue); }); } |