summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--benchmark/parse/filter.cpp34
-rw-r--r--include/mbgl/style/filter.hpp42
-rw-r--r--include/mbgl/style/filter_evaluator.hpp (renamed from src/mbgl/style/filter_evaluator.hpp)36
-rw-r--r--include/mbgl/util/geometry.hpp7
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp4
-rw-r--r--src/mbgl/style/bucket_parameters.cpp5
-rw-r--r--src/mbgl/tile/geometry_tile_data.hpp7
-rw-r--r--test/style/filter.cpp37
8 files changed, 74 insertions, 98 deletions
diff --git a/benchmark/parse/filter.cpp b/benchmark/parse/filter.cpp
index 7450fc7804..8beff3b308 100644
--- a/benchmark/parse/filter.cpp
+++ b/benchmark/parse/filter.cpp
@@ -13,32 +13,6 @@ using namespace mbgl;
typedef std::multimap<std::string, Value> Properties;
-class StubFeature : public GeometryTileFeature {
-public:
- inline StubFeature(const Properties& properties_, FeatureType type_)
- : properties(properties_), type(type_) {
- }
-
- optional<Value> getValue(const std::string& key) const override {
- auto it = properties.find(key);
- if (it == properties.end())
- return optional<Value>();
- return it->second;
- }
-
- FeatureType getType() const override {
- return type;
- }
-
- GeometryCollection getGeometries() const override {
- return GeometryCollection();
- }
-
-private:
- const Properties properties;
- FeatureType type;
-};
-
style::Filter parse(const char* expression) {
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> doc;
doc.Parse<0>(expression);
@@ -54,10 +28,14 @@ static void Parse_Filter(benchmark::State& state) {
static void Parse_EvaluateFilter(benchmark::State& state) {
const style::Filter filter = parse(R"FILTER(["==", "foo", "bar"])FILTER");
const Properties properties = { { "foo", std::string("bar") } };
- const StubFeature feature(properties, FeatureType::Unknown);
while (state.KeepRunning()) {
- style::Filter::visit(filter, style::FilterEvaluator{ feature });
+ filter(FeatureType::Unknown, [&] (const std::string& key) -> optional<Value> {
+ auto it = properties.find(key);
+ if (it == properties.end())
+ return {};
+ return it->second;
+ });
}
}
diff --git a/include/mbgl/style/filter.hpp b/include/mbgl/style/filter.hpp
index 9cf84f5e1d..6a5afb7b47 100644
--- a/include/mbgl/style/filter.hpp
+++ b/include/mbgl/style/filter.hpp
@@ -2,6 +2,7 @@
#include <mbgl/util/variant.hpp>
#include <mbgl/util/feature.hpp>
+#include <mbgl/util/geometry.hpp>
#include <string>
#include <vector>
@@ -9,22 +10,7 @@
namespace mbgl {
namespace style {
-typedef variant<
- class NullFilter,
- class EqualsFilter,
- class NotEqualsFilter,
- class LessThanFilter,
- class LessThanEqualsFilter,
- class GreaterThanFilter,
- class GreaterThanEqualsFilter,
- class InFilter,
- class NotInFilter,
- class AnyFilter,
- class AllFilter,
- class NoneFilter,
- class HasFilter,
- class NotHasFilter
- > Filter;
+class Filter;
class NullFilter {};
@@ -101,5 +87,29 @@ public:
std::string key;
};
+using FilterBase = variant<
+ class NullFilter,
+ class EqualsFilter,
+ class NotEqualsFilter,
+ class LessThanFilter,
+ class LessThanEqualsFilter,
+ class GreaterThanFilter,
+ class GreaterThanEqualsFilter,
+ class InFilter,
+ class NotInFilter,
+ class AnyFilter,
+ class AllFilter,
+ class NoneFilter,
+ class HasFilter,
+ class NotHasFilter>;
+
+class Filter : public FilterBase {
+public:
+ using FilterBase::FilterBase;
+
+ template <class PropertyAccessor>
+ bool operator()(FeatureType type, PropertyAccessor accessor) const;
+};
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/filter_evaluator.hpp b/include/mbgl/style/filter_evaluator.hpp
index 9d5919ced1..a458a2807b 100644
--- a/src/mbgl/style/filter_evaluator.hpp
+++ b/include/mbgl/style/filter_evaluator.hpp
@@ -1,17 +1,32 @@
#pragma once
#include <mbgl/style/filter.hpp>
-#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/util/geometry.hpp>
#include <type_traits>
namespace mbgl {
namespace style {
+/*
+ A visitor that evaluates a `Filter` for a given feature type and properties. For maximum
+ flexibility, it is templated on the PropertyAccessor type, which must be a callable type with
+ function signature `optional<Value> (const std::string&)`, returning the value for the given
+ key, if it exists.
+
+ Use via `Filter::operator()`. For example:
+
+ if (filter(feature.getType(), [&] (const std::string& key) { return feature.getValue(key); })) {
+ // matches the filter
+ } else {
+ // does not match
+ }
+*/
+template <class PropertyAccessor>
class FilterEvaluator {
public:
- FilterEvaluator(const GeometryTileFeature& feature_)
- : feature(feature_) {}
+ const FeatureType featureType;
+ const PropertyAccessor propertyAccessor;
bool operator()(const NullFilter&) const {
return true;
@@ -107,10 +122,10 @@ public:
}
private:
- optional<Value> getValue(const std::string& key) const {
- return key == "$type"
- ? optional<Value>(uint64_t(feature.getType()))
- : feature.getValue(key);
+ optional<Value> getValue(const std::string& key_) const {
+ return key_ == "$type"
+ ? optional<Value>(uint64_t(featureType))
+ : propertyAccessor(key_);
}
template <class Op>
@@ -155,9 +170,12 @@ private:
bool equal(const Value& lhs, const Value& rhs) const {
return compare(lhs, rhs, [] (const auto& lhs_, const auto& rhs_) { return lhs_ == rhs_; });
}
-
- const GeometryTileFeature& feature;
};
+template <class PropertyAccessor>
+inline bool Filter::operator()(FeatureType type, PropertyAccessor accessor) const {
+ return FilterBase::visit(*this, FilterEvaluator<PropertyAccessor> { type, accessor });
+}
+
} // namespace style
} // namespace mbgl
diff --git a/include/mbgl/util/geometry.hpp b/include/mbgl/util/geometry.hpp
index 6b9c332bf2..7fc2668c2c 100644
--- a/include/mbgl/util/geometry.hpp
+++ b/include/mbgl/util/geometry.hpp
@@ -5,6 +5,13 @@
namespace mbgl {
+enum class FeatureType : uint8_t {
+ Unknown = 0,
+ Point = 1,
+ LineString = 2,
+ Polygon = 3
+};
+
template <class T>
using Point = mapbox::geometry::point<T>;
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index e34aedb47e..496745dda1 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -119,9 +119,7 @@ void SymbolBucket::parseFeatures(const GeometryTileLayer& layer, const Filter& f
const GLsizei featureCount = static_cast<GLsizei>(layer.featureCount());
for (GLsizei i = 0; i < featureCount; i++) {
auto feature = layer.getFeature(i);
-
- FilterEvaluator evaluator(*feature);
- if (!Filter::visit(filter, evaluator))
+ if (!filter(feature->getType(), [&] (const auto& key) { return feature->getValue(key); }))
continue;
SymbolFeature ft;
diff --git a/src/mbgl/style/bucket_parameters.cpp b/src/mbgl/style/bucket_parameters.cpp
index 1a928dcecc..5bb08af873 100644
--- a/src/mbgl/style/bucket_parameters.cpp
+++ b/src/mbgl/style/bucket_parameters.cpp
@@ -10,11 +10,8 @@ void BucketParameters::eachFilteredFeature(const Filter& filter,
auto name = layer.getName();
for (std::size_t i = 0; !cancelled() && i < layer.featureCount(); i++) {
auto feature = layer.getFeature(i);
-
- FilterEvaluator evaluator(*feature);
- if (!Filter::visit(filter, evaluator))
+ if (!filter(feature->getType(), [&] (const auto& key) { return feature->getValue(key); }))
continue;
-
function(*feature, i, name);
}
}
diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp
index 753ba6b8a2..1dc22e0c55 100644
--- a/src/mbgl/tile/geometry_tile_data.hpp
+++ b/src/mbgl/tile/geometry_tile_data.hpp
@@ -17,13 +17,6 @@
namespace mbgl {
-enum class FeatureType : uint8_t {
- Unknown = 0,
- Point = 1,
- LineString = 2,
- Polygon = 3
-};
-
class CanonicalTileID;
// Normalized vector tile coordinates.
diff --git a/test/style/filter.cpp b/test/style/filter.cpp
index d28ee4a357..4a1010445e 100644
--- a/test/style/filter.cpp
+++ b/test/style/filter.cpp
@@ -3,7 +3,6 @@
#include <mbgl/style/filter.hpp>
#include <mbgl/style/filter_evaluator.hpp>
#include <mbgl/style/parser.hpp>
-#include <mbgl/tile/geometry_tile_data.hpp>
#include <rapidjson/document.h>
@@ -14,33 +13,6 @@ using namespace mbgl::style;
typedef std::multimap<std::string, mbgl::Value> Properties;
-class StubFeature : public GeometryTileFeature {
-public:
- inline StubFeature(Properties properties_, FeatureType type_)
- : properties(std::move(properties_))
- , type(type_)
- {}
-
- optional<Value> getValue(const std::string &key) const override {
- auto it = properties.find(key);
- if (it == properties.end())
- return optional<Value>();
- return it->second;
- }
-
- FeatureType getType() const override {
- return type;
- }
-
- GeometryCollection getGeometries() const override {
- return GeometryCollection();
- }
-
-private:
- const Properties properties;
- FeatureType type;
-};
-
Filter parse(const char * expression) {
rapidjson::GenericDocument<rapidjson::UTF8<>, rapidjson::CrtAllocator> doc;
doc.Parse<0>(expression);
@@ -48,9 +20,12 @@ Filter parse(const char * expression) {
}
bool evaluate(const Filter& filter, const Properties& properties, FeatureType type = FeatureType::Unknown) {
- StubFeature feature(properties, type);
- FilterEvaluator evaluator(feature);
- return Filter::visit(filter, evaluator);
+ return filter(type, [&] (const std::string& key) -> optional<Value> {
+ auto it = properties.find(key);
+ if (it == properties.end())
+ return {};
+ return it->second;
+ });
}
TEST(Filter, EqualsString) {