diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-06-21 17:22:51 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-06-21 18:24:49 -0700 |
commit | 3459b83736f0e4eedfb95a1394d9e4ee1523b917 (patch) | |
tree | 2e8cc0abacdaad54b394af1291e846c7483acfa2 | |
parent | 220fc7adc952c97db3fb8ce7edb855db9469ef5a (diff) | |
download | qtlocation-mapboxgl-3459b83736f0e4eedfb95a1394d9e4ee1523b917.tar.gz |
[core, node] Node bindings for setFilter
-rw-r--r-- | benchmark/parse/filter.cpp | 5 | ||||
-rw-r--r-- | include/mbgl/style/conversion.hpp | 132 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | platform/node/src/node_conversion.hpp | 19 | ||||
-rw-r--r-- | platform/node/src/node_map.cpp | 37 | ||||
-rw-r--r-- | platform/node/src/node_map.hpp | 1 | ||||
-rw-r--r-- | platform/node/src/node_style_properties.hpp | 24 | ||||
-rw-r--r-- | platform/node/src/node_style_properties.hpp.ejs | 16 | ||||
-rw-r--r-- | src/mbgl/style/conversion.cpp | 25 | ||||
-rw-r--r-- | src/mbgl/style/parser.cpp | 175 | ||||
-rw-r--r-- | src/mbgl/style/parser.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/style/rapidjson_conversion.hpp | 23 | ||||
-rw-r--r-- | test/style/filter.cpp | 5 |
13 files changed, 291 insertions, 176 deletions
diff --git a/benchmark/parse/filter.cpp b/benchmark/parse/filter.cpp index 8beff3b308..4269f8e169 100644 --- a/benchmark/parse/filter.cpp +++ b/benchmark/parse/filter.cpp @@ -2,7 +2,8 @@ #include <mbgl/style/filter.hpp> #include <mbgl/style/filter_evaluator.hpp> -#include <mbgl/style/parser.hpp> +#include <mbgl/style/rapidjson_conversion.hpp> +#include <mbgl/style/conversion.hpp> #include <mbgl/tile/geometry_tile_data.hpp> #include <rapidjson/document.h> @@ -16,7 +17,7 @@ typedef std::multimap<std::string, Value> Properties; style::Filter parse(const char* expression) { rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> doc; doc.Parse<0>(expression); - return style::parseFilter(doc); + return style::conversion::convertFilter(doc).get<style::Filter>(); } static void Parse_Filter(benchmark::State& state) { diff --git a/include/mbgl/style/conversion.hpp b/include/mbgl/style/conversion.hpp index 0507d452fd..18326c8dd1 100644 --- a/include/mbgl/style/conversion.hpp +++ b/include/mbgl/style/conversion.hpp @@ -2,7 +2,7 @@ #include <mbgl/style/types.hpp> #include <mbgl/style/property_value.hpp> -#include <mbgl/style/transition_options.hpp> +#include <mbgl/style/filter.hpp> #include <mbgl/util/variant.hpp> #include <mbgl/util/optional.hpp> @@ -27,6 +27,12 @@ namespace conversion { This is used concretely for conversions from RapidJSON types in mbgl core, and from v8 types in the node bindings. + It also defines a convertion from `V` to `Filter`, representing a JSON object conforming to a Style + Specification filter object: + + template <class V> + Result<Filter> convertFilter(const V& value); + The requirements are that the following are legal expressions for a value `v` of type `const V&`: * `isArray(v)` -- returns a boolean indicating whether `v` represents a JSON array @@ -41,6 +47,9 @@ namespace conversion { * `toBool(v)` -- returns `optional<bool>`, absence indicating `v` is not a JSON boolean * `toNumber(v)` -- returns `optional<float>`, absence indicating `v` is not a JSON number * `toString(v)` -- returns `optional<std::string>`, absence indicating `v` is not a JSON string + * `toValue(v)` -- returns `optional<mbgl::Value>`, a variant type, for generic conversion, + absence indicating `v` is not a boolean, number, or string. Numbers should be converted to + unsigned integer, signed integer, or floating point, in descending preference. If for any reason the conversion fails, the result of `convertPropertyValue` will be the `Error` variant, which includes explanatory text. @@ -258,6 +267,127 @@ Result<PropertyValue<T>> convertPropertyValue(const V& value) { return Function<T>(stops, *base); } +Result<Value> normalizeFilterValue(const std::string& key, const optional<Value>&); + +template <class V> +Result<Filter> convertFilter(const V& value); + +template <class FilterType, class V> +Result<Filter> parseUnaryFilter(const V& value) { + if (arrayLength(value) < 2) { + return Error { "filter expression must have 2 elements" }; + } + + optional<std::string> key = toString(arrayMember(value, 1)); + if (!key) { + return Error { "filter expression key must be a string" }; + } + + return FilterType { *key }; +} + +template <class FilterType, class V> +Result<Filter> parseBinaryFilter(const V& value) { + if (arrayLength(value) < 3) { + return Error { "filter expression must have 3 elements" }; + } + + optional<std::string> key = toString(arrayMember(value, 1)); + if (!key) { + return Error { "filter expression key must be a string" }; + } + + Result<Value> filterValue = normalizeFilterValue(*key, toValue(arrayMember(value, 2))); + if (filterValue.is<Error>()) { + return filterValue.get<Error>(); + } + + return FilterType { *key, filterValue.get<Value>() }; +} + +template <class FilterType, class V> +Result<Filter> parseSetFilter(const V& value) { + if (arrayLength(value) < 2) { + return Error { "filter expression must at least 2 elements" }; + } + + optional<std::string> key = toString(arrayMember(value, 1)); + if (!key) { + return Error { "filter expression key must be a string" }; + } + + std::vector<Value> values; + for (std::size_t i = 2; i < arrayLength(value); ++i) { + Result<Value> filterValue = normalizeFilterValue(*key, toValue(arrayMember(value, i))); + if (filterValue.is<Error>()) { + return filterValue.get<Error>(); + } + values.push_back(filterValue.get<Value>()); + } + + return FilterType { *key, std::move(values) }; +} + +template <class FilterType, class V> +Result<Filter> parseCompoundFilter(const V& value) { + std::vector<Filter> filters; + for (std::size_t i = 1; i < arrayLength(value); ++i) { + Result<Filter> element = convertFilter(arrayMember(value, i)); + if (element.is<Error>()) { + return element; + } + filters.push_back(element.get<Filter>()); + } + + return FilterType { std::move(filters) }; +} + +template <class V> +Result<Filter> convertFilter(const V& value) { + if (!isArray(value)) { + return Error { "filter expression must be an array" }; + } + + if (arrayLength(value) < 1) { + return Error { "filter expression must have at least 1 element" }; + } + + optional<std::string> op = toString(arrayMember(value, 0)); + if (!op) { + return Error { "filter operator must be a string" }; + } + + if (*op == "==") { + return parseBinaryFilter<EqualsFilter>(value); + } else if (*op == "!=") { + return parseBinaryFilter<NotEqualsFilter>(value); + } else if (*op == ">") { + return parseBinaryFilter<GreaterThanFilter>(value); + } else if (*op == ">=") { + return parseBinaryFilter<GreaterThanEqualsFilter>(value); + } else if (*op == "<") { + return parseBinaryFilter<LessThanFilter>(value); + } else if (*op == "<=") { + return parseBinaryFilter<LessThanEqualsFilter>(value); + } else if (*op == "in") { + return parseSetFilter<InFilter>(value); + } else if (*op == "!in") { + return parseSetFilter<NotInFilter>(value); + } else if (*op == "all") { + return parseCompoundFilter<AllFilter>(value); + } else if (*op == "any") { + return parseCompoundFilter<AnyFilter>(value); + } else if (*op == "none") { + return parseCompoundFilter<NoneFilter>(value); + } else if (*op == "has") { + return parseUnaryFilter<HasFilter>(value); + } else if (*op == "!has") { + return parseUnaryFilter<NotHasFilter>(value); + } + + return Error { "filter operator must be one of \"==\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"in\", \"!in\", \"all\", \"any\", \"none\", \"has\", or \"!has\"" }; +} + } // namespace conversion } // namespace style } // namespace mbgl diff --git a/package.json b/package.json index 053083fb07..dba546af43 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "express": "^4.11.1", "mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#59e998295d548f208ee3ec10cdd21ff2630e2079", "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#194fc55b6a7dd54c1e2cf2dd9048fbb5e836716d", - "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#87d237a9d7372325fffd0c04036b2d77e601e72b", + "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#47bbd92debe0f72ec9759d2e12d9c8d4a57232c5", "node-gyp": "^3.3.1", "request": "^2.72.0", "tape": "^4.5.1" diff --git a/platform/node/src/node_conversion.hpp b/platform/node/src/node_conversion.hpp index 51443f28eb..03c13b5846 100644 --- a/platform/node/src/node_conversion.hpp +++ b/platform/node/src/node_conversion.hpp @@ -7,6 +7,7 @@ #pragma GCC diagnostic pop #include <mbgl/util/optional.hpp> +#include <mbgl/util/feature.hpp> namespace mbgl { namespace style { @@ -68,6 +69,24 @@ inline optional<std::string> toString(v8::Local<v8::Value> value) { return std::string(*Nan::Utf8String(value)); } +inline optional<Value> toValue(v8::Local<v8::Value> value) { + if (value->IsFalse()) { + return { false }; + } else if (value->IsTrue()) { + return { true }; + } else if (value->IsString()) { + return { std::string(*Nan::Utf8String(value)) }; + } else if (value->IsUint32()) { + return { value->Uint32Value() }; + } else if (value->IsInt32()) { + return { value->Int32Value() }; + } else if (value->IsNumber()) { + return { value->NumberValue() }; + } else { + return {}; + } +} + } // namespace conversion } // namespace style } // namespace mbgl diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index c416082b69..e6ee84ee53 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -58,6 +58,7 @@ NAN_MODULE_INIT(NodeMap::Init) { Nan::SetPrototypeMethod(tpl, "addClass", AddClass); Nan::SetPrototypeMethod(tpl, "setLayoutProperty", SetLayoutProperty); Nan::SetPrototypeMethod(tpl, "setPaintProperty", SetPaintProperty); + Nan::SetPrototypeMethod(tpl, "setFilter", SetFilter); Nan::SetPrototypeMethod(tpl, "dumpDebugLogs", DumpDebugLogs); Nan::SetPrototypeMethod(tpl, "queryRenderedFeatures", QueryRenderedFeatures); @@ -526,6 +527,42 @@ NAN_METHOD(NodeMap::SetPaintProperty) { setProperty(info, setters); } +NAN_METHOD(NodeMap::SetFilter) { + auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); + if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); + + if (info.Length() < 2) { + return Nan::ThrowTypeError("Two arguments required"); + } + + if (!info[0]->IsString()) { + return Nan::ThrowTypeError("First argument must be a string"); + } + + mbgl::style::Layer* layer = nodeMap->map->getLayer(*Nan::Utf8String(info[0])); + if (!layer) { + return Nan::ThrowTypeError("layer not found"); + } + + mbgl::style::Filter filter; + + if (!info[1]->IsNull() && !info[1]->IsUndefined()) { + mbgl::style::conversion::Result<mbgl::style::Filter> converted + = mbgl::style::conversion::convertFilter(info[1]); + if (converted.is<mbgl::style::conversion::Error>()) { + Nan::ThrowTypeError(converted.get<mbgl::style::conversion::Error>().message); + return; + } + filter = std::move(converted.get<mbgl::style::Filter>()); + } + + if (!setFilter(*layer, filter)) { + return; + } + + info.GetReturnValue().SetUndefined(); +} + NAN_METHOD(NodeMap::DumpDebugLogs) { auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp index fb7fc77e5b..58773e33da 100644 --- a/platform/node/src/node_map.hpp +++ b/platform/node/src/node_map.hpp @@ -30,6 +30,7 @@ public: static NAN_METHOD(AddClass); static NAN_METHOD(SetLayoutProperty); static NAN_METHOD(SetPaintProperty); + static NAN_METHOD(SetFilter); static NAN_METHOD(DumpDebugLogs); static NAN_METHOD(QueryRenderedFeatures); diff --git a/platform/node/src/node_style_properties.hpp b/platform/node/src/node_style_properties.hpp index 1ad06068f3..0e3100207a 100644 --- a/platform/node/src/node_style_properties.hpp +++ b/platform/node/src/node_style_properties.hpp @@ -122,4 +122,28 @@ inline PropertySetters makePaintPropertySetters() { return result; } +inline bool setFilter(mbgl::style::Layer& layer, const mbgl::style::Filter& filter) { + using namespace mbgl::style; + + if (layer.is<FillLayer>()) { + layer.as<FillLayer>()->setFilter(filter); + return true; + } + if (layer.is<LineLayer>()) { + layer.as<LineLayer>()->setFilter(filter); + return true; + } + if (layer.is<SymbolLayer>()) { + layer.as<SymbolLayer>()->setFilter(filter); + return true; + } + if (layer.is<CircleLayer>()) { + layer.as<CircleLayer>()->setFilter(filter); + return true; + } + + Nan::ThrowTypeError("layer doesn't support filters"); + return false; +} + } diff --git a/platform/node/src/node_style_properties.hpp.ejs b/platform/node/src/node_style_properties.hpp.ejs index ebf45eb3cf..bfd3f74ca5 100644 --- a/platform/node/src/node_style_properties.hpp.ejs +++ b/platform/node/src/node_style_properties.hpp.ejs @@ -34,4 +34,20 @@ inline PropertySetters makePaintPropertySetters() { return result; } +inline bool setFilter(mbgl::style::Layer& layer, const mbgl::style::Filter& filter) { + using namespace mbgl::style; + +<% for (const layer of locals.layers) { -%> +<% if (layer.type !== 'raster' && layer.type !== 'background' && layer.type !== 'custom') { -%> + if (layer.is<<%- camelize(layer.type) %>Layer>()) { + layer.as<<%- camelize(layer.type) %>Layer>()->setFilter(filter); + return true; + } +<% } -%> +<% } -%> + + Nan::ThrowTypeError("layer doesn't support filters"); + return false; +} + } diff --git a/src/mbgl/style/conversion.cpp b/src/mbgl/style/conversion.cpp new file mode 100644 index 0000000000..e863e285c4 --- /dev/null +++ b/src/mbgl/style/conversion.cpp @@ -0,0 +1,25 @@ +#include <mbgl/style/conversion.hpp> + +namespace mbgl { +namespace style { +namespace conversion { + +Result<Value> normalizeFilterValue(const std::string& key, const optional<Value>& value) { + if (!value) { + return Error { "filter expression value must be a boolean, number, or string" }; + } else if (key != "$type") { + return *value; + } else if (*value == std::string("Point")) { + return Value(uint64_t(FeatureType::Point)); + } else if (*value == std::string("LineString")) { + return Value(uint64_t(FeatureType::LineString)); + } else if (*value == std::string("Polygon")) { + return Value(uint64_t(FeatureType::Polygon)); + } else { + return Error { "value for $type filter must be Point, LineString, or Polygon" }; + } +} + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp index 34f01c14c1..eddda5d3f2 100644 --- a/src/mbgl/style/parser.cpp +++ b/src/mbgl/style/parser.cpp @@ -9,6 +9,8 @@ #include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/layers/raster_layer.hpp> #include <mbgl/style/layers/background_layer.hpp> +#include <mbgl/style/rapidjson_conversion.hpp> +#include <mbgl/style/conversion.hpp> #include <mbgl/platform/log.hpp> @@ -275,7 +277,12 @@ void Parser::parseLayer(const std::string& id, const JSValue& value, std::unique } if (value.HasMember("filter")) { - impl->filter = parseFilter(value["filter"]); + conversion::Result<Filter> filter = conversion::convertFilter(value["filter"]); + if (filter.is<Filter>()) { + impl->filter = filter.get<Filter>(); + } else { + Log::Warning(Event::ParseStyle, filter.get<conversion::Error>().message); + } } if (value.HasMember("minzoom")) { @@ -326,172 +333,6 @@ void Parser::parseVisibility(Layer& layer, const JSValue& value) { impl.visibility = *enumValue; } -Value parseFeatureType(const Value& value) { - if (value == std::string("Point")) { - return Value(uint64_t(FeatureType::Point)); - } else if (value == std::string("LineString")) { - return Value(uint64_t(FeatureType::LineString)); - } else if (value == std::string("Polygon")) { - return Value(uint64_t(FeatureType::Polygon)); - } else { - Log::Warning(Event::ParseStyle, "value for $type filter must be Point, LineString, or Polygon"); - return Value(uint64_t(FeatureType::Unknown)); - } -} - -Value parseValue(const JSValue& value) { - switch (value.GetType()) { - case rapidjson::kNullType: - case rapidjson::kFalseType: - return false; - - case rapidjson::kTrueType: - return true; - - case rapidjson::kStringType: - return std::string { value.GetString(), value.GetStringLength() }; - - case rapidjson::kNumberType: - if (value.IsUint64()) return value.GetUint64(); - if (value.IsInt64()) return value.GetInt64(); - return value.GetDouble(); - - default: - return false; - } -} - -template <class Expression> -Filter parseUnaryFilter(const JSValue& value) { - Filter empty; - - if (value.Size() < 2) { - Log::Warning(Event::ParseStyle, "filter expression must have 2 elements"); - return empty; - } - - if (!value[1u].IsString()) { - Log::Warning(Event::ParseStyle, "filter expression key must be a string"); - return empty; - } - - Expression expression; - expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; - return expression; -} - -template <class Expression> -Filter parseBinaryFilter(const JSValue& value) { - Filter empty; - - if (value.Size() < 3) { - Log::Warning(Event::ParseStyle, "filter expression must have 3 elements"); - return empty; - } - - if (!value[1u].IsString()) { - Log::Warning(Event::ParseStyle, "filter expression key must be a string"); - return empty; - } - - Expression expression; - expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; - expression.value = parseValue(value[2u]); - - if (expression.key == "$type") { - expression.value = parseFeatureType(expression.value); - } - - return expression; -} - -template <class Expression> -Filter parseSetFilter(const JSValue& value) { - Filter empty; - - if (value.Size() < 2) { - Log::Warning(Event::ParseStyle, "filter expression must at least 2 elements"); - return empty; - } - - if (!value[1u].IsString()) { - Log::Warning(Event::ParseStyle, "filter expression key must be a string"); - return empty; - } - - Expression expression; - expression.key = { value[1u].GetString(), value[1u].GetStringLength() }; - for (rapidjson::SizeType i = 2; i < value.Size(); ++i) { - Value parsedValue = parseValue(value[i]); - if (expression.key == "$type") { - parsedValue = parseFeatureType(parsedValue); - } - expression.values.push_back(parsedValue); - } - return expression; -} - -template <class Expression> -Filter parseCompoundFilter(const JSValue& value) { - Expression expression; - for (rapidjson::SizeType i = 1; i < value.Size(); ++i) { - expression.filters.push_back(parseFilter(value[i])); - } - return expression; -} - -Filter parseFilter(const JSValue& value) { - Filter empty; - - if (!value.IsArray()) { - Log::Warning(Event::ParseStyle, "filter expression must be an array"); - return empty; - } - - if (value.Size() < 1) { - Log::Warning(Event::ParseStyle, "filter expression must have at least 1 element"); - return empty; - } - - if (!value[0u].IsString()) { - Log::Warning(Event::ParseStyle, "filter operator must be a string"); - return empty; - } - - std::string op = { value[0u].GetString(), value[0u].GetStringLength() }; - - if (op == "==") { - return parseBinaryFilter<EqualsFilter>(value); - } else if (op == "!=") { - return parseBinaryFilter<NotEqualsFilter>(value); - } else if (op == ">") { - return parseBinaryFilter<GreaterThanFilter>(value); - } else if (op == ">=") { - return parseBinaryFilter<GreaterThanEqualsFilter>(value); - } else if (op == "<") { - return parseBinaryFilter<LessThanFilter>(value); - } else if (op == "<=") { - return parseBinaryFilter<LessThanEqualsFilter>(value); - } else if (op == "in") { - return parseSetFilter<InFilter>(value); - } else if (op == "!in") { - return parseSetFilter<NotInFilter>(value); - } else if (op == "all") { - return parseCompoundFilter<AllFilter>(value); - } else if (op == "any") { - return parseCompoundFilter<AnyFilter>(value); - } else if (op == "none") { - return parseCompoundFilter<NoneFilter>(value); - } else if (op == "has") { - return parseUnaryFilter<HasFilter>(value); - } else if (op == "!has") { - return parseUnaryFilter<NotHasFilter>(value); - } else { - Log::Warning(Event::ParseStyle, "filter operator must be one of \"==\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"in\", \"!in\", \"all\", \"any\", \"none\", \"has\", or \"!has\""); - return empty; - } -} - std::vector<FontStack> Parser::fontStacks() const { std::set<FontStack> result; diff --git a/src/mbgl/style/parser.hpp b/src/mbgl/style/parser.hpp index 6dac6dedcd..30da0dd2b0 100644 --- a/src/mbgl/style/parser.hpp +++ b/src/mbgl/style/parser.hpp @@ -2,7 +2,6 @@ #include <mbgl/style/layer.hpp> #include <mbgl/style/source.hpp> -#include <mbgl/style/filter.hpp> #include <mbgl/util/rapidjson.hpp> #include <mbgl/util/font_stack.hpp> @@ -16,8 +15,6 @@ namespace mbgl { namespace style { -Filter parseFilter(const JSValue&); - class Parser { public: ~Parser(); diff --git a/src/mbgl/style/rapidjson_conversion.hpp b/src/mbgl/style/rapidjson_conversion.hpp index 93577ac8b2..1d9f88efa3 100644 --- a/src/mbgl/style/rapidjson_conversion.hpp +++ b/src/mbgl/style/rapidjson_conversion.hpp @@ -1,6 +1,7 @@ #pragma once #include <mbgl/util/rapidjson.hpp> +#include <mbgl/util/feature.hpp> namespace mbgl { namespace style { @@ -50,6 +51,28 @@ inline optional<std::string> toString(const JSValue& value) { return {{ value.GetString(), value.GetStringLength() }}; } +inline optional<Value> toValue(const JSValue& value) { + switch (value.GetType()) { + case rapidjson::kNullType: + case rapidjson::kFalseType: + return { false }; + + case rapidjson::kTrueType: + return { true }; + + case rapidjson::kStringType: + return { std::string { value.GetString(), value.GetStringLength() } }; + + case rapidjson::kNumberType: + if (value.IsUint64()) return { value.GetUint64() }; + if (value.IsInt64()) return { value.GetInt64() }; + return { value.GetDouble() }; + + default: + return {}; + } +} + } // namespace conversion } // namespace style } // namespace mbgl diff --git a/test/style/filter.cpp b/test/style/filter.cpp index 4a1010445e..fd763896a6 100644 --- a/test/style/filter.cpp +++ b/test/style/filter.cpp @@ -2,7 +2,8 @@ #include <mbgl/style/filter.hpp> #include <mbgl/style/filter_evaluator.hpp> -#include <mbgl/style/parser.hpp> +#include <mbgl/style/rapidjson_conversion.hpp> +#include <mbgl/style/conversion.hpp> #include <rapidjson/document.h> @@ -16,7 +17,7 @@ typedef std::multimap<std::string, mbgl::Value> Properties; Filter parse(const char * expression) { rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> doc; doc.Parse<0>(expression); - return parseFilter(doc); + return conversion::convertFilter(doc).get<Filter>(); } bool evaluate(const Filter& filter, const Properties& properties, FeatureType type = FeatureType::Unknown) { |