summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/core-files.cmake2
-rw-r--r--include/mbgl/style/expression/compound_expression.hpp15
-rw-r--r--include/mbgl/style/expression/dsl.hpp63
-rw-r--r--include/mbgl/style/expression/literal.hpp4
-rw-r--r--include/mbgl/style/function/composite_function.hpp3
-rw-r--r--include/mbgl/style/function/source_function.hpp3
-rw-r--r--platform/glfw/glfw_view.cpp41
-rw-r--r--src/mbgl/style/expression/compound_expression.cpp144
-rw-r--r--src/mbgl/style/expression/dsl.cpp147
-rw-r--r--src/mbgl/style/expression/literal.cpp9
-rw-r--r--test/api/query.test.cpp20
-rw-r--r--test/programs/symbol_program.test.cpp52
-rw-r--r--test/renderer/group_by_layout.test.cpp6
-rw-r--r--test/style/conversion/stringify.test.cpp73
-rw-r--r--test/style/function/camera_function.test.cpp59
-rw-r--r--test/style/function/composite_function.test.cpp69
-rw-r--r--test/style/function/source_function.test.cpp76
-rw-r--r--test/style/properties.test.cpp11
18 files changed, 435 insertions, 362 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index 714d6d5c8f..09c12897b0 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -448,6 +448,7 @@ set(MBGL_CORE_FILES
include/mbgl/style/expression/coalesce.hpp
include/mbgl/style/expression/coercion.hpp
include/mbgl/style/expression/compound_expression.hpp
+ include/mbgl/style/expression/dsl.hpp
include/mbgl/style/expression/equals.hpp
include/mbgl/style/expression/expression.hpp
include/mbgl/style/expression/find_zoom_curve.hpp
@@ -473,6 +474,7 @@ set(MBGL_CORE_FILES
src/mbgl/style/expression/coalesce.cpp
src/mbgl/style/expression/coercion.cpp
src/mbgl/style/expression/compound_expression.cpp
+ src/mbgl/style/expression/dsl.cpp
src/mbgl/style/expression/equals.cpp
src/mbgl/style/expression/find_zoom_curve.cpp
src/mbgl/style/expression/get_covering_stops.cpp
diff --git a/include/mbgl/style/expression/compound_expression.hpp b/include/mbgl/style/expression/compound_expression.hpp
index 431afb4d13..9d39194563 100644
--- a/include/mbgl/style/expression/compound_expression.hpp
+++ b/include/mbgl/style/expression/compound_expression.hpp
@@ -134,24 +134,9 @@ struct CompoundExpressionRegistry {
ParseResult parseCompoundExpression(const std::string name, const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
-ParseResult createCompoundExpression(const CompoundExpressionRegistry::Definition& definition,
- std::vector<std::unique_ptr<Expression>> args,
- ParsingContext& ctx);
-
ParseResult createCompoundExpression(const std::string& name,
std::vector<std::unique_ptr<Expression>> args,
ParsingContext& ctx);
-// Convenience method for use expressions that have 0, 1, or 2 args.
-ParseResult createCompoundExpression(const std::string& name, ParsingContext& ctx);
-
-ParseResult createCompoundExpression(const std::string& name,
- std::unique_ptr<Expression> arg1,
- ParsingContext& ctx);
-
-ParseResult createCompoundExpression(const std::string& name,
- std::unique_ptr<Expression> arg1,
- std::unique_ptr<Expression> arg2,
- ParsingContext& ctx);
} // namespace expression
} // namespace style
diff --git a/include/mbgl/style/expression/dsl.hpp b/include/mbgl/style/expression/dsl.hpp
new file mode 100644
index 0000000000..b4e1ed436e
--- /dev/null
+++ b/include/mbgl/style/expression/dsl.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <mbgl/style/expression/value.hpp>
+#include <mbgl/style/expression/expression.hpp>
+#include <mbgl/style/expression/interpolator.hpp>
+
+#include <memory>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+namespace dsl {
+
+// This convenience API does little to no expression validation or type-checking, and is intended for
+// use only by test and other non-production code.
+
+std::unique_ptr<Expression> literal(const char* value);
+std::unique_ptr<Expression> literal(Value value);
+
+std::unique_ptr<Expression> number(std::unique_ptr<Expression>);
+std::unique_ptr<Expression> string(std::unique_ptr<Expression>);
+
+std::unique_ptr<Expression> toColor(const char* value);
+std::unique_ptr<Expression> toColor(std::unique_ptr<Expression>);
+
+std::unique_ptr<Expression> get(const char* value);
+std::unique_ptr<Expression> get(std::unique_ptr<Expression>);
+
+std::unique_ptr<Expression> id();
+std::unique_ptr<Expression> zoom();
+
+std::unique_ptr<Expression> eq(std::unique_ptr<Expression>,
+ std::unique_ptr<Expression>);
+std::unique_ptr<Expression> ne(std::unique_ptr<Expression>,
+ std::unique_ptr<Expression>);
+std::unique_ptr<Expression> gt(std::unique_ptr<Expression>,
+ std::unique_ptr<Expression>);
+std::unique_ptr<Expression> lt(std::unique_ptr<Expression>,
+ std::unique_ptr<Expression>);
+
+Interpolator linear();
+Interpolator exponential(double base);
+Interpolator cubicBezier(double x1, double y1, double x2, double y2);
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1);
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1,
+ double input2, std::unique_ptr<Expression> output2);
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1,
+ double input2, std::unique_ptr<Expression> output2,
+ double input3, std::unique_ptr<Expression> output3);
+
+} // namespace dsl
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/expression/literal.hpp b/include/mbgl/style/expression/literal.hpp
index d3b3a20cce..44c095bf28 100644
--- a/include/mbgl/style/expression/literal.hpp
+++ b/include/mbgl/style/expression/literal.hpp
@@ -47,13 +47,11 @@ public:
mbgl::Value serialize() const override;
std::string getOperator() const override { return "literal"; }
+
private:
Value value;
};
-std::unique_ptr<Literal> createLiteral(const char* value);
-std::unique_ptr<Literal> createLiteral(Value value);
-
} // namespace expression
} // namespace style
} // namespace mbgl
diff --git a/include/mbgl/style/function/composite_function.hpp b/include/mbgl/style/function/composite_function.hpp
index 93986f82f2..f99fc973ed 100644
--- a/include/mbgl/style/function/composite_function.hpp
+++ b/include/mbgl/style/function/composite_function.hpp
@@ -50,8 +50,9 @@ public:
CompositeIntervalStops<T>,
CompositeCategoricalStops<T>>>;
- CompositeFunction(std::unique_ptr<expression::Expression> expression_)
+ CompositeFunction(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {})
: isExpression(true),
+ defaultValue(std::move(defaultValue_)),
expression(std::move(expression_)),
zoomCurve(expression::findZoomCurveChecked(expression.get()))
{
diff --git a/include/mbgl/style/function/source_function.hpp b/include/mbgl/style/function/source_function.hpp
index 5b51d0bf81..bc4e3b9c7d 100644
--- a/include/mbgl/style/function/source_function.hpp
+++ b/include/mbgl/style/function/source_function.hpp
@@ -29,8 +29,9 @@ public:
CategoricalStops<T>,
IdentityStops<T>>>;
- SourceFunction(std::unique_ptr<expression::Expression> expression_)
+ SourceFunction(std::unique_ptr<expression::Expression> expression_, optional<T> defaultValue_ = {})
: isExpression(true),
+ defaultValue(std::move(defaultValue_)),
expression(std::move(expression_))
{
assert(expression::isZoomConstant(*expression));
diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp
index fcb470e114..a08dc7c768 100644
--- a/platform/glfw/glfw_view.cpp
+++ b/platform/glfw/glfw_view.cpp
@@ -7,8 +7,7 @@
#include <mbgl/style/image.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/layers/fill_extrusion_layer.hpp>
-#include <mbgl/style/expression/compound_expression.hpp>
-#include <mbgl/style/expression/literal.hpp>
+#include <mbgl/style/expression/dsl.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/platform.hpp>
#include <mbgl/util/string.hpp>
@@ -622,8 +621,8 @@ void GLFWView::onDidFinishLoadingStyle() {
void GLFWView::toggle3DExtrusions(bool visible) {
using namespace mbgl::style;
- using namespace mbgl::style::expression;
-
+ using namespace mbgl::style::expression::dsl;
+
show3DExtrusions = visible;
// Satellite-only style does not contain building extrusions data.
@@ -632,34 +631,22 @@ void GLFWView::toggle3DExtrusions(bool visible) {
}
if (auto layer = map->getStyle().getLayer("3d-buildings")) {
- layer->setVisibility(mbgl::style::VisibilityType(!show3DExtrusions));
+ layer->setVisibility(VisibilityType(!show3DExtrusions));
return;
}
- auto extrusionLayer = std::make_unique<mbgl::style::FillExtrusionLayer>("3d-buildings", "composite");
+ auto extrusionLayer = std::make_unique<FillExtrusionLayer>("3d-buildings", "composite");
extrusionLayer->setSourceLayer("building");
extrusionLayer->setMinZoom(15.0f);
-
- ParsingContext parsingContext;
- extrusionLayer->setFilter(Filter(createCompoundExpression("filter-==", createLiteral("extrude"), createLiteral("true"), parsingContext)));
-
- auto colorFn = mbgl::style::SourceFunction<mbgl::Color> { "height",
- mbgl::style::ExponentialStops<mbgl::Color> {
- std::map<float, mbgl::Color> {
- { 0.f, *mbgl::Color::parse("#160e23") },
- { 50.f, *mbgl::Color::parse("#00615f") },
- { 100.f, *mbgl::Color::parse("#55e9ff") }
- }
- }
- };
- extrusionLayer->setFillExtrusionColor({ colorFn });
- extrusionLayer->setFillExtrusionOpacity({ 0.6f });
-
- auto heightSourceFn = mbgl::style::SourceFunction<float> { "height", mbgl::style::IdentityStops<float>() };
- extrusionLayer->setFillExtrusionHeight({ heightSourceFn });
-
- auto baseSourceFn = mbgl::style::SourceFunction<float> { "min_height", mbgl::style::IdentityStops<float>() };
- extrusionLayer->setFillExtrusionBase({ baseSourceFn });
+ extrusionLayer->setFilter(Filter(eq(get("extrude"), literal("true"))));
+ extrusionLayer->setFillExtrusionColor(SourceFunction<mbgl::Color>(
+ interpolate(linear(), get("height"),
+ 0.f, toColor("#160e23"),
+ 50.f, toColor("#00615f"),
+ 100.f, toColor("#55e9ff"))));
+ extrusionLayer->setFillExtrusionOpacity(0.6f);
+ extrusionLayer->setFillExtrusionHeight(SourceFunction<float>(get("height")));
+ extrusionLayer->setFillExtrusionBase(SourceFunction<float>(get("min_height")));
map->getStyle().addLayer(std::move(extrusionLayer));
}
diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp
index a961de60ae..c37f02612b 100644
--- a/src/mbgl/style/expression/compound_expression.cpp
+++ b/src/mbgl/style/expression/compound_expression.cpp
@@ -640,76 +640,13 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
std::unordered_map<std::string, Definition> CompoundExpressionRegistry::definitions = initializeDefinitions();
using namespace mbgl::style::conversion;
-ParseResult parseCompoundExpression(const std::string name, const Convertible& value, ParsingContext& ctx) {
- assert(isArray(value) && arrayLength(value) > 0);
-
- auto it = CompoundExpressionRegistry::definitions.find(name);
- if (it == CompoundExpressionRegistry::definitions.end()) {
- ctx.error(
- R"(Unknown expression ")" + name + R"(". If you wanted a literal array, use ["literal", [...]].)",
- 0
- );
- return ParseResult();
- }
- const CompoundExpressionRegistry::Definition& definition = it->second;
-
- auto length = arrayLength(value);
-
- // Check if we have a single signature with the correct number of
- // parameters. If so, then use that signature's parameter types for parsing
- // (and inferring the types of) the arguments.
- optional<std::size_t> singleMatchingSignature;
- for (std::size_t j = 0; j < definition.size(); j++) {
- const std::unique_ptr<detail::SignatureBase>& signature = definition[j];
- if (
- signature->params.is<VarargsType>() ||
- signature->params.get<std::vector<type::Type>>().size() == length - 1
- ) {
- if (singleMatchingSignature) {
- singleMatchingSignature = {};
- } else {
- singleMatchingSignature = j;
- }
- }
- }
- // parse subexpressions first
- std::vector<std::unique_ptr<Expression>> args;
- args.reserve(length - 1);
- for (std::size_t i = 1; i < length; i++) {
- optional<type::Type> expected;
-
- if (singleMatchingSignature) {
- expected = definition[*singleMatchingSignature]->params.match(
- [](const VarargsType& varargs) { return varargs.type; },
- [&](const std::vector<type::Type>& params_) { return params_[i - 1]; }
- );
- }
-
- auto parsed = ctx.parse(arrayMember(value, i), i, expected);
- if (!parsed) {
- return parsed;
- }
- args.push_back(std::move(*parsed));
- }
- return createCompoundExpression(definition, std::move(args), ctx);
-}
-
-
-ParseResult createCompoundExpression(const std::string& name,
- std::vector<std::unique_ptr<Expression>> args,
- ParsingContext& ctx)
-{
- return createCompoundExpression(CompoundExpressionRegistry::definitions.at(name), std::move(args), ctx);
-}
-
-
-ParseResult createCompoundExpression(const Definition& definition,
- std::vector<std::unique_ptr<Expression>> args,
- ParsingContext& ctx)
+static ParseResult createCompoundExpression(const Definition& definition,
+ std::vector<std::unique_ptr<Expression>> args,
+ ParsingContext& ctx)
{
ParsingContext signatureContext(ctx.getKey());
-
+
for (const std::unique_ptr<detail::SignatureBase>& signature : definition) {
signatureContext.clearErrors();
@@ -767,7 +704,7 @@ ParseResult createCompoundExpression(const Definition& definition,
signatures += ")";
}
);
-
+
}
std::string actualTypes;
for (const auto& arg : args) {
@@ -782,26 +719,67 @@ ParseResult createCompoundExpression(const Definition& definition,
return ParseResult();
}
-ParseResult createCompoundExpression(const std::string& name, ParsingContext& ctx) {
- return createCompoundExpression(name, std::vector<std::unique_ptr<Expression>>(), ctx);
-}
+ParseResult parseCompoundExpression(const std::string name, const Convertible& value, ParsingContext& ctx) {
+ assert(isArray(value) && arrayLength(value) > 0);
-ParseResult createCompoundExpression(const std::string& name,
- std::unique_ptr<Expression> arg1,
- ParsingContext& ctx) {
+ auto it = CompoundExpressionRegistry::definitions.find(name);
+ if (it == CompoundExpressionRegistry::definitions.end()) {
+ ctx.error(
+ R"(Unknown expression ")" + name + R"(". If you wanted a literal array, use ["literal", [...]].)",
+ 0
+ );
+ return ParseResult();
+ }
+ const CompoundExpressionRegistry::Definition& definition = it->second;
+
+ auto length = arrayLength(value);
+
+ // Check if we have a single signature with the correct number of
+ // parameters. If so, then use that signature's parameter types for parsing
+ // (and inferring the types of) the arguments.
+ optional<std::size_t> singleMatchingSignature;
+ for (std::size_t j = 0; j < definition.size(); j++) {
+ const std::unique_ptr<detail::SignatureBase>& signature = definition[j];
+ if (
+ signature->params.is<VarargsType>() ||
+ signature->params.get<std::vector<type::Type>>().size() == length - 1
+ ) {
+ if (singleMatchingSignature) {
+ singleMatchingSignature = {};
+ } else {
+ singleMatchingSignature = j;
+ }
+ }
+ }
+
+ // parse subexpressions first
std::vector<std::unique_ptr<Expression>> args;
- args.push_back(std::move(arg1));
- return createCompoundExpression(name, std::move(args), ctx);
+ args.reserve(length - 1);
+ for (std::size_t i = 1; i < length; i++) {
+ optional<type::Type> expected;
+
+ if (singleMatchingSignature) {
+ expected = definition[*singleMatchingSignature]->params.match(
+ [](const VarargsType& varargs) { return varargs.type; },
+ [&](const std::vector<type::Type>& params_) { return params_[i - 1]; }
+ );
+ }
+
+ auto parsed = ctx.parse(arrayMember(value, i), i, expected);
+ if (!parsed) {
+ return parsed;
+ }
+ args.push_back(std::move(*parsed));
+ }
+
+ return createCompoundExpression(definition, std::move(args), ctx);
}
ParseResult createCompoundExpression(const std::string& name,
- std::unique_ptr<Expression> arg1,
- std::unique_ptr<Expression> arg2,
- ParsingContext& ctx) {
- std::vector<std::unique_ptr<Expression>> args;
- args.push_back(std::move(arg1));
- args.push_back(std::move(arg2));
- return createCompoundExpression(name, std::move(args), ctx);
+ std::vector<std::unique_ptr<Expression>> args,
+ ParsingContext& ctx)
+{
+ return createCompoundExpression(CompoundExpressionRegistry::definitions.at(name), std::move(args), ctx);
}
} // namespace expression
diff --git a/src/mbgl/style/expression/dsl.cpp b/src/mbgl/style/expression/dsl.cpp
new file mode 100644
index 0000000000..9f204cadc9
--- /dev/null
+++ b/src/mbgl/style/expression/dsl.cpp
@@ -0,0 +1,147 @@
+#include <mbgl/style/expression/dsl.hpp>
+#include <mbgl/style/expression/literal.hpp>
+#include <mbgl/style/expression/assertion.hpp>
+#include <mbgl/style/expression/coercion.hpp>
+#include <mbgl/style/expression/equals.hpp>
+#include <mbgl/style/expression/interpolate.hpp>
+#include <mbgl/style/expression/compound_expression.hpp>
+#include <mbgl/util/ignore.hpp>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+namespace dsl {
+
+template <class... Args>
+static std::vector<std::unique_ptr<Expression>> vec(Args... args) {
+ std::vector<std::unique_ptr<Expression>> result;
+ util::ignore({ (result.push_back(std::move(args)), 0)... });
+ return result;
+}
+
+template <class... Args>
+static std::unique_ptr<Expression> compound(const char* op, Args... args) {
+ ParsingContext ctx;
+ ParseResult result = createCompoundExpression(op, vec(std::move(args)...), ctx);
+ assert(result);
+ return std::move(*result);
+}
+
+std::unique_ptr<Expression> literal(const char* value) {
+ return literal(std::string(value));
+}
+
+std::unique_ptr<Expression> literal(Value value) {
+ return std::make_unique<Literal>(value);
+}
+
+std::unique_ptr<Expression> number(std::unique_ptr<Expression> value) {
+ return std::make_unique<Assertion>(type::Number, vec(std::move(value)));
+}
+
+std::unique_ptr<Expression> string(std::unique_ptr<Expression> value) {
+ return std::make_unique<Assertion>(type::String, vec(std::move(value)));
+}
+
+std::unique_ptr<Expression> toColor(const char* value) {
+ return toColor(literal(value));
+}
+
+std::unique_ptr<Expression> toColor(std::unique_ptr<Expression> value) {
+ return std::make_unique<Coercion>(type::Color, vec(std::move(value)));
+}
+
+std::unique_ptr<Expression> get(const char* value) {
+ return get(literal(value));
+}
+
+std::unique_ptr<Expression> get(std::unique_ptr<Expression> property) {
+ return compound("get", std::move(property));
+}
+
+std::unique_ptr<Expression> id() {
+ return compound("id");
+}
+
+std::unique_ptr<Expression> zoom() {
+ return compound("zoom");
+}
+
+std::unique_ptr<Expression> eq(std::unique_ptr<Expression> lhs,
+ std::unique_ptr<Expression> rhs) {
+ return std::make_unique<Equals>(std::move(lhs), std::move(rhs), false);
+}
+
+std::unique_ptr<Expression> ne(std::unique_ptr<Expression> lhs,
+ std::unique_ptr<Expression> rhs) {
+ return std::make_unique<Equals>(std::move(lhs), std::move(rhs), true);
+}
+
+std::unique_ptr<Expression> gt(std::unique_ptr<Expression> lhs,
+ std::unique_ptr<Expression> rhs) {
+ return compound(">", std::move(lhs), std::move(rhs));
+}
+
+std::unique_ptr<Expression> lt(std::unique_ptr<Expression> lhs,
+ std::unique_ptr<Expression> rhs) {
+ return compound("<", std::move(lhs), std::move(rhs));
+}
+
+Interpolator linear() {
+ return ExponentialInterpolator(1.0);
+}
+
+Interpolator exponential(double base) {
+ return ExponentialInterpolator(base);
+}
+
+Interpolator cubicBezier(double x1, double y1, double x2, double y2) {
+ return CubicBezierInterpolator(x1, y1, x2, y2);
+}
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1) {
+ type::Type type = output1->getType();
+ std::map<double, std::unique_ptr<Expression>> stops;
+ stops[input1] = std::move(output1);
+ ParsingContext ctx;
+ ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx);
+ assert(result);
+ return std::move(*result);
+}
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1,
+ double input2, std::unique_ptr<Expression> output2) {
+ type::Type type = output1->getType();
+ std::map<double, std::unique_ptr<Expression>> stops;
+ stops[input1] = std::move(output1);
+ stops[input2] = std::move(output2);
+ ParsingContext ctx;
+ ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx);
+ assert(result);
+ return std::move(*result);
+}
+
+std::unique_ptr<Expression> interpolate(Interpolator interpolator,
+ std::unique_ptr<Expression> input,
+ double input1, std::unique_ptr<Expression> output1,
+ double input2, std::unique_ptr<Expression> output2,
+ double input3, std::unique_ptr<Expression> output3) {
+ type::Type type = output1->getType();
+ std::map<double, std::unique_ptr<Expression>> stops;
+ stops[input1] = std::move(output1);
+ stops[input2] = std::move(output2);
+ stops[input3] = std::move(output3);
+ ParsingContext ctx;
+ ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx);
+ assert(result);
+ return std::move(*result);
+}
+
+} // namespace dsl
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/expression/literal.cpp b/src/mbgl/style/expression/literal.cpp
index f68cfd5cf5..345a52de9b 100644
--- a/src/mbgl/style/expression/literal.cpp
+++ b/src/mbgl/style/expression/literal.cpp
@@ -109,16 +109,7 @@ mbgl::Value Literal::serialize() const {
return *fromExpressionValue<mbgl::Value>(value);
}
}
-
-std::unique_ptr<Literal> createLiteral(const char* value) {
- return createLiteral(std::string(value));
-}
-
-std::unique_ptr<Literal> createLiteral(Value value) {
- return std::make_unique<Literal>(value);
-}
} // namespace expression
} // namespace style
} // namespace mbgl
-
diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp
index ffab52692b..5960de3b31 100644
--- a/test/api/query.test.cpp
+++ b/test/api/query.test.cpp
@@ -8,6 +8,7 @@
#include <mbgl/style/style.hpp>
#include <mbgl/style/image.hpp>
#include <mbgl/style/source.hpp>
+#include <mbgl/style/expression/dsl.hpp>
#include <mbgl/renderer/renderer.hpp>
#include <mbgl/gl/headless_frontend.hpp>
@@ -67,20 +68,20 @@ TEST(Query, QueryRenderedFeaturesFilterLayer) {
}
TEST(Query, QueryRenderedFeaturesFilter) {
- QueryTest test;
- ParsingContext context;
+ using namespace mbgl::style::expression::dsl;
+ QueryTest test;
auto zz = test.map.pixelForLatLng({ 0, 0 });
- const Filter eqFilter(createCompoundExpression("filter-==", createLiteral("key1"), createLiteral("value1"), context));
+ const Filter eqFilter(eq(get("key1"), literal("value1")));
auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{}, { eqFilter }});
EXPECT_EQ(features1.size(), 1u);
- const Filter idNotEqFilter(createCompoundExpression("!", std::move(*createCompoundExpression("filter-id-==", createLiteral("feature1"), context)), context));
+ const Filter idNotEqFilter(ne(id(), literal("feature1")));
auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer4" }}, { idNotEqFilter }});
EXPECT_EQ(features2.size(), 0u);
- const Filter gtFilter(createCompoundExpression("filter->", createLiteral("key2"), createLiteral(1.0), context));
+ const Filter gtFilter(gt(number(get("key2")), literal(1.0)));
auto features3 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{ }, { gtFilter }});
EXPECT_EQ(features3.size(), 1u);
}
@@ -109,18 +110,19 @@ TEST(Query, QuerySourceFeaturesOptionValidation) {
}
TEST(Query, QuerySourceFeaturesFilter) {
+ using namespace mbgl::style::expression::dsl;
+
QueryTest test;
- ParsingContext context;
- const Filter eqFilter(createCompoundExpression("filter-==", createLiteral("key1"), createLiteral("value1"), context));
+ const Filter eqFilter(eq(get("key1"), literal("value1")));
auto features1 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { eqFilter }});
EXPECT_EQ(features1.size(), 1u);
- const Filter idNotEqFilter(createCompoundExpression("!", std::move(*createCompoundExpression("filter-id-==", createLiteral("feature1"), context)), context));
+ const Filter idNotEqFilter(ne(id(), literal("feature1")));
auto features2 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { idNotEqFilter }});
EXPECT_EQ(features2.size(), 0u);
- const Filter gtFilter(createCompoundExpression("filter->", createLiteral("key2"), createLiteral(1.0), context));
+ const Filter gtFilter(gt(number(get("key2")), literal(1.0)));
auto features3 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { gtFilter }});
EXPECT_EQ(features3.size(), 1u);
}
diff --git a/test/programs/symbol_program.test.cpp b/test/programs/symbol_program.test.cpp
index 62a2e58d7b..ed709a4ba7 100644
--- a/test/programs/symbol_program.test.cpp
+++ b/test/programs/symbol_program.test.cpp
@@ -1,8 +1,10 @@
#include <mbgl/test/util.hpp>
#include <mbgl/programs/symbol_program.hpp>
+#include <mbgl/style/expression/dsl.hpp>
using namespace mbgl;
+using namespace mbgl::style::expression::dsl;
TEST(SymbolProgram, SymbolSizeBinder) {
auto binder = SymbolSizeBinder::create(5.0f, 12.0f, 0.0f);
@@ -11,45 +13,55 @@ TEST(SymbolProgram, SymbolSizeBinder) {
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, true);
EXPECT_EQ(uniformValues.get<uniforms::u_size>().t, 12.0f);
- binder = SymbolSizeBinder::create(1.0f, style::CameraFunction<float>(style::ExponentialStops<float>({
- {0.0f, 8.0f},
- {10.0f, 18.0f}
- }, 1.0f)), 0.0f);
+ binder = SymbolSizeBinder::create(1.0f, style::CameraFunction<float>(
+ interpolate(
+ linear(),
+ zoom(),
+ 0., literal(8.),
+ 10., literal(18.))), 0.0f);
uniformValues = binder->uniformValues(1.5f);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, false);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, true);
EXPECT_EQ(uniformValues.get<uniforms::u_size>().t, 9.5f);
- binder = SymbolSizeBinder::create(0.0f, style::CameraFunction<float>(style::ExponentialStops<float>({
- {1.0f, 8.0f},
- {11.0f, 18.0f}
- }, 1.0f)), 0.0f);
+ binder = SymbolSizeBinder::create(0.0f, style::CameraFunction<float>(
+ interpolate(
+ linear(),
+ zoom(),
+ 1., literal(8.),
+ 11., literal(18.))), 0.0f);
uniformValues = binder->uniformValues(0.5f);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, false);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, true);
EXPECT_EQ(uniformValues.get<uniforms::u_size>().t, 8.0f);
- binder = SymbolSizeBinder::create(12.0f, style::CameraFunction<float>(style::ExponentialStops<float>({
- {1.0f, 8.0f},
- {11.0f, 18.0f}
- }, 1.0f)), 0.0f);
+ binder = SymbolSizeBinder::create(12.0f, style::CameraFunction<float>(
+ interpolate(
+ linear(),
+ zoom(),
+ 1., literal(8.),
+ 11., literal(18.))), 0.0f);
uniformValues = binder->uniformValues(12.5f);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, false);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, true);
EXPECT_EQ(uniformValues.get<uniforms::u_size>().t, 18.0f);
- binder = SymbolSizeBinder::create(0.0f, style::SourceFunction<float>("x", style::ExponentialStops<float>({
- {1.0f, 8.0f},
- {11.0f, 18.0f}
- }, 1.0f)), 0.0f);
+ binder = SymbolSizeBinder::create(0.0f, style::SourceFunction<float>(
+ interpolate(
+ linear(),
+ number(get("x")),
+ 1., literal(8.),
+ 11., literal(18.))), 0.0f);
uniformValues = binder->uniformValues(12.5f);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, true);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, false);
- binder = SymbolSizeBinder::create(5.0f, style::CompositeFunction<float>("x", style::CompositeExponentialStops<float>({
- {1.0f, {{0.0f, 8.0f}, {100.0f, 18.0f}}},
- {11.0f, {{0.0f, 12.0f}, {100.0f, 24.9f}}}
- }, 1.0f)), 0.0f);
+ binder = SymbolSizeBinder::create(5.0f, style::CompositeFunction<float>(
+ interpolate(
+ linear(),
+ zoom(),
+ 1., interpolate(linear(), number(get("x")), 0., literal(8.), 100., literal(18.)),
+ 11., interpolate(linear(), number(get("x")), 0., literal(12.), 100., literal(24.9)))), 0.0f);
uniformValues = binder->uniformValues(5.5f);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_zoom_constant>().t, false);
EXPECT_EQ(uniformValues.get<uniforms::u_is_size_feature_constant>().t, false);
diff --git a/test/renderer/group_by_layout.test.cpp b/test/renderer/group_by_layout.test.cpp
index 6cf17e2279..8d0b432481 100644
--- a/test/renderer/group_by_layout.test.cpp
+++ b/test/renderer/group_by_layout.test.cpp
@@ -5,7 +5,7 @@
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/style/layers/line_layer.hpp>
-#include <mbgl/style/expression/compound_expression.hpp>
+#include <mbgl/style/expression/dsl.hpp>
using namespace mbgl;
using namespace mbgl::style;
@@ -38,11 +38,11 @@ TEST(GroupByLayout, UnrelatedType) {
}
TEST(GroupByLayout, UnrelatedFilter) {
+ using namespace mbgl::style::expression::dsl;
std::vector<std::unique_ptr<Layer>> layers;
layers.push_back(std::make_unique<LineLayer>("a", "source"));
layers.push_back(std::make_unique<LineLayer>("b", "source"));
- ParsingContext context;
- layers[0]->as<LineLayer>()->setFilter(Filter(createCompoundExpression("filter-has-id", context)));
+ layers[0]->as<LineLayer>()->setFilter(Filter(get("property")));
auto result = groupByLayout(toRenderLayers(layers));
ASSERT_EQ(2u, result.size());
}
diff --git a/test/style/conversion/stringify.test.cpp b/test/style/conversion/stringify.test.cpp
index c3faf1f838..567c022036 100644
--- a/test/style/conversion/stringify.test.cpp
+++ b/test/style/conversion/stringify.test.cpp
@@ -4,6 +4,7 @@
#include <mbgl/style/conversion/stringify.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
+#include <mbgl/style/expression/dsl.hpp>
#include <mbgl/util/rapidjson.hpp>
#include <rapidjson/writer.h>
@@ -76,56 +77,62 @@ TEST(Stringify, Value) {
}
TEST(Stringify, Filter) {
- using namespace mbgl::style::expression;
-
+ using namespace mbgl::style::expression::dsl;
ASSERT_EQ(stringify(Filter()), "null");
-
- ParsingContext context;
- ASSERT_EQ(stringify(Filter(createCompoundExpression("filter-==", createLiteral("a"), createLiteral(1.0), context))), "[\"filter-==\",\"a\",1.0]");
+ ASSERT_EQ(stringify(Filter(eq(literal("a"), literal(1.0)))), "[\"==\",\"a\",1.0]");
}
TEST(Stringify, CameraFunction) {
- ASSERT_EQ(stringify(CameraFunction<float>(ExponentialStops<float> { {{0, 1}}, 1 })),
- "[\"interpolate\",[\"linear\"],[\"zoom\"],0.0,1.0]");
- ASSERT_EQ(stringify(CameraFunction<float>(ExponentialStops<float> { {{0, 1}}, 2 })),
- "[\"interpolate\",[\"exponential\",2.0],[\"zoom\"],0.0,1.0]");
- ASSERT_EQ(stringify(CameraFunction<float>(IntervalStops<float> { {{0, 1}} })),
- "[\"step\",[\"zoom\"],0.0,1.0]");
+ using namespace mbgl::style::expression::dsl;
+ ASSERT_EQ(stringify(CameraFunction<float>(
+ interpolate(
+ linear(),
+ zoom(),
+ 0.0, literal(1.0),
+ 1.0, literal(2.0)
+ ))),
+ "[\"interpolate\",[\"linear\"],[\"zoom\"],0.0,1.0,1.0,2.0]");
}
TEST(Stringify, SourceFunction) {
- ASSERT_EQ(stringify(SourceFunction<float>("property", ExponentialStops<float> { {{0, 1}}, 2 })),
- "[\"interpolate\",[\"exponential\",2.0],[\"number\",[\"get\",\"property\"]],0.0,1.0]");
- ASSERT_EQ(stringify(SourceFunction<float>("property", IntervalStops<float> { {{0, 1}} })),
- "[\"step\",[\"number\",[\"get\",\"property\"]],0.0,1.0]");
- ASSERT_EQ(stringify(SourceFunction<float>("property", CategoricalStops<float> { {{CategoricalValue(true), 1}} })),
- "[\"case\",[\"boolean\",[\"get\",\"property\"]],1.0,[\"error\"]]");
- ASSERT_EQ(stringify(SourceFunction<float>("property", IdentityStops<float> {})),
- "[\"number\",[\"get\",\"property\"]]");
- ASSERT_EQ(stringify(SourceFunction<float>("property", IdentityStops<float> {}, 0.0f)),
- "[\"number\",[\"get\",\"property\"]]");
+ using namespace mbgl::style::expression::dsl;
+ ASSERT_EQ(stringify(SourceFunction<float>(
+ interpolate(
+ exponential(2.0),
+ number(get("property")),
+ 0.0, literal(1.0),
+ 1.0, literal(2.0)
+ ))),
+ "[\"interpolate\",[\"exponential\",2.0],[\"number\",[\"get\",\"property\"]],0.0,1.0,1.0,2.0]");
}
TEST(Stringify, CompositeFunction) {
- ASSERT_EQ(stringify(CompositeFunction<float>("property",
- CompositeExponentialStops<float> {
- {
- { 0, {{0, 1}} },
- { 1, {{0, 1}} }
- },
- 2
- }, 0.0f)),
+ using namespace mbgl::style::expression::dsl;
+ ASSERT_EQ(stringify(CompositeFunction<float>(
+ interpolate(
+ linear(),
+ zoom(),
+ 0.0, interpolate(exponential(2.0), number(get("property")), 0.0, literal(1.0), 1.0, literal(2.0)),
+ 1.0, interpolate(exponential(2.0), number(get("property")), 0.0, literal(1.0), 1.0, literal(2.0))
+ ))),
"[\"interpolate\","
"[\"linear\"],"
"[\"zoom\"],"
- "0.0,[\"interpolate\",[\"exponential\",2.0],[\"number\",[\"get\",\"property\"]],0.0,1.0],"
- "1.0,[\"interpolate\",[\"exponential\",2.0],[\"number\",[\"get\",\"property\"]],0.0,1.0]]");
+ "0.0,[\"interpolate\",[\"exponential\",2.0],[\"number\",[\"get\",\"property\"]],0.0,1.0,1.0,2.0],"
+ "1.0,[\"interpolate\",[\"exponential\",2.0],[\"number\",[\"get\",\"property\"]],0.0,1.0,1.0,2.0]]");
}
TEST(Stringify, PropertyValue) {
+ using namespace mbgl::style::expression::dsl;
ASSERT_EQ(stringify(PropertyValue<float>(1)), "1.0");
- ASSERT_EQ(stringify(PropertyValue<float>(CameraFunction<float>(ExponentialStops<float> { {{0, 1}}, 2 }))),
- "[\"interpolate\",[\"exponential\",2.0],[\"zoom\"],0.0,1.0]");
+ ASSERT_EQ(stringify(PropertyValue<float>(CameraFunction<float>(
+ interpolate(
+ exponential(2.0),
+ zoom(),
+ 0.0, literal(1.0),
+ 1.0, literal(2.0)
+ )))),
+ "[\"interpolate\",[\"exponential\",2.0],[\"zoom\"],0.0,1.0,1.0,2.0]");
}
TEST(Stringify, Layout) {
diff --git a/test/style/function/camera_function.test.cpp b/test/style/function/camera_function.test.cpp
index 59e3f2cef3..1f7e81fc2c 100644
--- a/test/style/function/camera_function.test.cpp
+++ b/test/style/function/camera_function.test.cpp
@@ -3,19 +3,15 @@
#include <mbgl/renderer/property_evaluator.hpp>
#include <mbgl/renderer/property_evaluation_parameters.hpp>
+#include <mbgl/style/expression/dsl.hpp>
using namespace mbgl;
using namespace mbgl::style;
+using namespace mbgl::style::expression::dsl;
float evaluate(PropertyValue<float> value, float zoom) {
return value.evaluate(PropertyEvaluator<float>(PropertyEvaluationParameters(zoom), 0));
}
-std::string evaluate(PropertyValue<std::string> value, float zoom) {
- return value.evaluate(PropertyEvaluator<std::string>(PropertyEvaluationParameters(zoom), ""));
-}
-bool evaluate(PropertyValue<bool> value, float zoom) {
- return value.evaluate(PropertyEvaluator<bool>(PropertyEvaluationParameters(zoom), false));
-}
TEST(CameraFunction, Constant) {
EXPECT_EQ(2.0f, evaluate(PropertyValue<float>(2.0), 0));
@@ -29,51 +25,8 @@ TEST(CameraFunction, Constant) {
EXPECT_EQ(22.0f, evaluate(PropertyValue<float>(22.0), 22));
}
-TEST(CameraFunction, Stops) {
- // Explicit constant slope in fringe regions.
- CameraFunction<float> slope_1(ExponentialStops<float> { { { 0, 1.5 }, { 6, 1.5 }, { 8, 3 }, { 22, 3 } }, 1.75});
- EXPECT_EQ(1.5, evaluate(slope_1, 0));
- EXPECT_EQ(1.5, evaluate(slope_1, 4));
- EXPECT_EQ(1.5, evaluate(slope_1, 6));
- ASSERT_FLOAT_EQ(2.0454545454545454, evaluate(slope_1, 7));
- EXPECT_EQ(3.0, evaluate(slope_1, 8));
- EXPECT_EQ(3.0, evaluate(slope_1, 9));
- EXPECT_EQ(3.0, evaluate(slope_1, 15));
- EXPECT_EQ(3.0, evaluate(slope_1, 22));
-
-
- // Test constant values in fringe regions.
- CameraFunction<float> slope_2(ExponentialStops<float> { { { 6, 1.5 }, { 8, 3 } }, 1.75 });
- EXPECT_EQ(1.5, evaluate(slope_2, 0));
- EXPECT_EQ(1.5, evaluate(slope_2, 4));
- EXPECT_EQ(1.5, evaluate(slope_2, 6));
- ASSERT_FLOAT_EQ(2.0454545454545454, evaluate(slope_2, 7));
- EXPECT_EQ(3.0, evaluate(slope_2, 8));
- EXPECT_EQ(3.0, evaluate(slope_2, 9));
- EXPECT_EQ(3.0, evaluate(slope_2, 15));
- EXPECT_EQ(3.0, evaluate(slope_2, 22));
-
-
- // Explicit constant slope in fringe regions.
- CameraFunction<float> slope_4(ExponentialStops<float> { { { 0, 2 }, { 8, 10 } }, 1 });
- EXPECT_EQ(2, evaluate(slope_4, 0));
- EXPECT_EQ(3, evaluate(slope_4, 1));
- EXPECT_EQ(4, evaluate(slope_4, 2));
- EXPECT_EQ(4.75, evaluate(slope_4, 2.75));
- EXPECT_EQ(10, evaluate(slope_4, 8));
-
- // discrete values
- CameraFunction<std::string> discrete_0(IntervalStops<std::string> { {{3, "string0"}, {6, "string1"}, {9, "string2"}} });
- EXPECT_EQ("string0", evaluate(discrete_0, 2));
- EXPECT_EQ("string0", evaluate(discrete_0, 4));
- EXPECT_EQ("string1", evaluate(discrete_0, 7));
- EXPECT_EQ("string2", evaluate(discrete_0, 9));
- EXPECT_EQ("string2", evaluate(discrete_0, 10));
-
- CameraFunction<bool> discreteBool(IntervalStops<bool> { {{1, false}, {3, true}} });
- EXPECT_FALSE(evaluate(discreteBool, 0));
- EXPECT_FALSE(evaluate(discreteBool, 1));
- EXPECT_FALSE(evaluate(discreteBool, 2));
- EXPECT_TRUE(evaluate(discreteBool, 3));
- EXPECT_TRUE(evaluate(discreteBool, 4));
+TEST(CameraFunction, Expression) {
+ CameraFunction<float> function(interpolate(linear(), zoom(), 0.0, literal(0.0), 1.0, literal(1.0)));
+ EXPECT_EQ(0.0, evaluate(function, 0.0));
+ EXPECT_EQ(0.5, evaluate(function, 0.5));
}
diff --git a/test/style/function/composite_function.test.cpp b/test/style/function/composite_function.test.cpp
index 09b79a8b8f..917689ce23 100644
--- a/test/style/function/composite_function.test.cpp
+++ b/test/style/function/composite_function.test.cpp
@@ -2,9 +2,11 @@
#include <mbgl/test/stub_geometry_tile_feature.hpp>
#include <mbgl/style/function/composite_function.hpp>
+#include <mbgl/style/expression/dsl.hpp>
using namespace mbgl;
using namespace mbgl::style;
+using namespace mbgl::style::expression::dsl;
using namespace std::string_literals;
@@ -13,54 +15,61 @@ static StubGeometryTileFeature oneInteger {
};
TEST(CompositeFunction, ZoomInterpolation) {
- EXPECT_EQ(40.0f, CompositeFunction<float>("property", CompositeExponentialStops<float>({
- {0.0f, {{uint64_t(1), 24.0f}}},
- {1.5f, {{uint64_t(1), 36.0f}}},
- {3.0f, {{uint64_t(1), 48.0f}}}
- }), 0.0f)
+ EXPECT_EQ(40.0f, CompositeFunction<float>(
+ interpolate(linear(), zoom(),
+ 0.0, interpolate(linear(), number(get("property")), 1.0, literal(24.0)),
+ 1.5, interpolate(linear(), number(get("property")), 1.0, literal(36.0)),
+ 3.0, interpolate(linear(), number(get("property")), 1.0, literal(48.0))
+ ), 0.0f)
.evaluate(2.0f, oneInteger, -1.0f)) << "Should interpolate between stops";
- EXPECT_EQ(33.0, CompositeFunction<float>("property", CompositeExponentialStops<float>({
- {5.0f, {{uint64_t(1), 33.0f}}},
- {10.0f, {{uint64_t(1), 66.0f}}}
- }), 0.0f)
+ EXPECT_EQ(33.0, CompositeFunction<float>(
+ interpolate(linear(), zoom(),
+ 5.0, interpolate(linear(), number(get("property")), 1.0, literal(33.0)),
+ 10.0, interpolate(linear(), number(get("property")), 1.0, literal(66.0))
+ ), 0.0f)
.evaluate(0.0f, oneInteger, -1.0f)) << "Use first stop output for input values from -inf to first stop";
- EXPECT_EQ(66.0, CompositeFunction<float>("property", CompositeExponentialStops<float>({
- {0.0f, {{uint64_t(1), 33.0f}}},
- {10.0f, {{uint64_t(1), 66.0f}}}
- }), 0.0f)
+ EXPECT_EQ(66.0, CompositeFunction<float>(
+ interpolate(linear(), zoom(),
+ 0.0, interpolate(linear(), number(get("property")), 1.0, literal(33.0)),
+ 10.0, interpolate(linear(), number(get("property")), 1.0, literal(66.0))
+ ), 0.0f)
.evaluate(20.0f, oneInteger, -1.0f)) << "Use last stop output for input values from last stop to +inf";
- EXPECT_EQ(66.0f, CompositeFunction<float>("property", CompositeExponentialStops<float>({
- {0.0f, {{uint64_t(1), 33.0f}}},
- {10.0f, {{uint64_t(1), 66.0f}}}
- }), 0.0f)
+ EXPECT_EQ(66.0f, CompositeFunction<float>(
+ interpolate(linear(), zoom(),
+ 0.0, interpolate(linear(), number(get("property")), 1.0, literal(33.0)),
+ 10.0, interpolate(linear(), number(get("property")), 1.0, literal(66.0))
+ ), 0.0f)
.evaluate(10.0f, oneInteger, -1.0f)) << "Should interpolate TO the last stop.";
- EXPECT_EQ(33.0f, CompositeFunction<float>("property", CompositeExponentialStops<float>({
- {0.0f, {{uint64_t(1), 33.0f}}},
- {10.0f, {{uint64_t(1), 66.0f}}}
- }), 0.0f)
+ EXPECT_EQ(33.0f, CompositeFunction<float>(
+ interpolate(linear(), zoom(),
+ 0.0, interpolate(linear(), number(get("property")), 1.0, literal(33.0)),
+ 10.0, interpolate(linear(), number(get("property")), 1.0, literal(66.0))
+ ), 0.0f)
.evaluate(0.0f, oneInteger, -1.0f)) << "Should interpolate TO the first stop";
}
TEST(CompositeFunction, Issue8460) {
- CompositeFunction<float> fn1("property", CompositeExponentialStops<float>({
- {15.0f, {{uint64_t(1), 0.0f}}},
- {15.2f, {{uint64_t(1), 600.0f}}},
- }), 0.0f);
+ CompositeFunction<float> fn1(
+ interpolate(linear(), zoom(),
+ 15.0, interpolate(linear(), number(get("property")), 1.0, literal(0.0)),
+ 15.2, interpolate(linear(), number(get("property")), 1.0, literal(600.0))
+ ), 0.0f);
EXPECT_NEAR( 0.0f, fn1.evaluate(15.0f, oneInteger, -1.0f), 0.00);
EXPECT_NEAR(300.0f, fn1.evaluate(15.1f, oneInteger, -1.0f), 0.01);
EXPECT_NEAR(600.0f, fn1.evaluate(15.2f, oneInteger, -1.0f), 0.00);
EXPECT_NEAR(600.0f, fn1.evaluate(16.0f, oneInteger, -1.0f), 0.00);
- CompositeFunction<float> fn2("property", CompositeExponentialStops<float>({
- {15.0f, {{uint64_t(1), 0.0f}}},
- {15.2f, {{uint64_t(1), 300.0f}}},
- {18.0f, {{uint64_t(1), 600.0f}}},
- }), 0.0f);
+ CompositeFunction<float> fn2(
+ interpolate(linear(), zoom(),
+ 15.0, interpolate(linear(), number(get("property")), 1.0, literal(0.0)),
+ 15.2, interpolate(linear(), number(get("property")), 1.0, literal(300.0)),
+ 18.0, interpolate(linear(), number(get("property")), 1.0, literal(600.0))
+ ), 0.0f);
EXPECT_NEAR( 0.0f, fn2.evaluate(15.0f, oneInteger, -1.0f), 0.00);
EXPECT_NEAR(150.0f, fn2.evaluate(15.1f, oneInteger, -1.0f), 0.01);
diff --git a/test/style/function/source_function.test.cpp b/test/style/function/source_function.test.cpp
index 46ad961002..d1e5e1a974 100644
--- a/test/style/function/source_function.test.cpp
+++ b/test/style/function/source_function.test.cpp
@@ -2,6 +2,7 @@
#include <mbgl/test/stub_geometry_tile_feature.hpp>
#include <mbgl/style/function/source_function.hpp>
+#include <mbgl/style/expression/dsl.hpp>
using namespace mbgl;
using namespace mbgl::style;
@@ -20,78 +21,15 @@ static StubGeometryTileFeature oneString {
PropertyMap {{ "property", "1"s }}
};
-static StubGeometryTileFeature red {
- PropertyMap {{ "property", "red"s }}
-};
-
-static StubGeometryTileFeature oneTwoInteger {
- PropertyMap {{ "property", std::vector<Value>({uint64_t(1), uint64_t(2)}) }}
-};
-
-static StubGeometryTileFeature oneTwoDouble {
- PropertyMap {{ "property", std::vector<Value>({1.0, 2.0}) }}
-};
-
-static StubGeometryTileFeature oneTwoString {
- PropertyMap {{ "property", std::vector<Value>({"1"s, "2"s}) }}
-};
-
-static StubGeometryTileFeature trueFeature {
- PropertyMap {{ "property", true }}
-};
+TEST(SourceFunction, Defaults) {
+ using namespace mbgl::style::expression::dsl;
-static StubGeometryTileFeature falseFeature {
- PropertyMap {{ "property", false }}
-};
-
-TEST(SourceFunction, Identity) {
- EXPECT_EQ(1.0f, SourceFunction<float>("property", IdentityStops<float>(), 0.0f)
+ EXPECT_EQ(1.0f, SourceFunction<float>(number(get("property")), 0.0)
.evaluate(oneInteger, 2.0f));
- EXPECT_EQ(1.0f, SourceFunction<float>("property", IdentityStops<float>(), 0.0f)
+ EXPECT_EQ(1.0f, SourceFunction<float>(number(get("property")), 0.0)
.evaluate(oneDouble, 2.0f));
- EXPECT_EQ(0.0f, SourceFunction<float>("property", IdentityStops<float>(), 0.0f)
+ EXPECT_EQ(0.0f, SourceFunction<float>(number(get("property")), 0.0)
.evaluate(oneString, 2.0f));
- EXPECT_EQ(2.0f, SourceFunction<float>("property", IdentityStops<float>())
+ EXPECT_EQ(2.0f, SourceFunction<float>(number(get("property")))
.evaluate(oneString, 2.0f));
-
- EXPECT_EQ(Color::red(), SourceFunction<Color>("property", IdentityStops<Color>(), Color::black())
- .evaluate(red, Color::black()));
- EXPECT_EQ(Color::black(), SourceFunction<Color>("property", IdentityStops<Color>(), Color::black())
- .evaluate(oneInteger, Color::black()));
-
- std::array<float, 2> zeroArray {{ 0, 0 }};
- EXPECT_EQ((std::array<float, 2> {{ 1, 2 }}), (SourceFunction<std::array<float, 2>>("property", IdentityStops<std::array<float, 2>>(), zeroArray)
- .evaluate(oneTwoInteger, zeroArray)));
- EXPECT_EQ((std::array<float, 2> {{ 1, 2 }}), (SourceFunction<std::array<float, 2>>("property", IdentityStops<std::array<float, 2>>(), zeroArray)
- .evaluate(oneTwoDouble, zeroArray)));
- EXPECT_EQ((std::array<float, 2> {{ 0, 0 }}), (SourceFunction<std::array<float, 2>>("property", IdentityStops<std::array<float, 2>>(), zeroArray)
- .evaluate(oneTwoString, zeroArray)));
-}
-
-TEST(SourceFunction, Categorical) {
- EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ int64_t(1), 1.0f }}))
- .evaluate(oneInteger, 0.0f));
- EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ int64_t(1), 1.0f }}))
- .evaluate(oneDouble, 0.0f));
- EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>({{ int64_t(1), 1.0f }}))
- .evaluate(oneString, 0.0f));
-
- CategoricalStops<float>::Stops stops;
- stops["1"s] = 1.0f;
-
- EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>(stops))
- .evaluate(oneInteger, 0.0f));
- EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>(stops))
- .evaluate(oneDouble, 0.0f));
- EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>(stops))
- .evaluate(oneString, 0.0f));
-
- EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ true, 1.0f }}))
- .evaluate(trueFeature, 0.0f));
- EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>({{ true, 1.0f }}))
- .evaluate(falseFeature, 0.0f));
- EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>({{ false, 1.0f }}))
- .evaluate(trueFeature, 0.0f));
- EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ false, 1.0f }}))
- .evaluate(falseFeature, 0.0f));
}
diff --git a/test/style/properties.test.cpp b/test/style/properties.test.cpp
index 279fadb8c2..4d63f7e671 100644
--- a/test/style/properties.test.cpp
+++ b/test/style/properties.test.cpp
@@ -1,6 +1,7 @@
#include <mbgl/test/util.hpp>
#include <mbgl/style/properties.hpp>
+#include <mbgl/style/expression/dsl.hpp>
#include <mbgl/renderer/property_evaluator.hpp>
#include <mbgl/renderer/data_driven_property_evaluator.hpp>
@@ -120,12 +121,10 @@ TEST(TransitioningDataDrivenPropertyValue, Evaluate) {
TransitionOptions(),
TimePoint::min()
};
-
- SourceFunction<float> sourceFunction = {
- "property_name",
- IdentityStops<float>()
- };
-
+
+ using namespace mbgl::style::expression::dsl;
+ SourceFunction<float> sourceFunction(number(get("property_name")));
+
Transitioning<DataDrivenPropertyValue<float>> t1 {
DataDrivenPropertyValue<float>(sourceFunction),
t0,