diff options
author | Lucas Wojciechowski <lucas@mapbox.com> | 2018-02-19 13:41:59 -0800 |
---|---|---|
committer | Lucas Wojciechowski <lucas@mapbox.com> | 2018-03-07 11:46:17 -0800 |
commit | 228ca2df0730ac394b95176d176504f17b4dc366 (patch) | |
tree | 0cbcce7c302da91744284df6fe5f93ebe7b5abc4 | |
parent | 9a51bc432489198f7aa238201ece0d01615402e6 (diff) | |
download | qtlocation-mapboxgl-228ca2df0730ac394b95176d176504f17b4dc366.tar.gz |
WIP
-rw-r--r-- | cmake/core-files.cmake | 1 | ||||
-rw-r--r-- | include/mbgl/style/filter.hpp | 3 | ||||
-rw-r--r-- | include/mbgl/style/filter_evaluator.hpp | 195 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/style/filter_evaluator.cpp | 170 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile_worker.cpp | 2 |
6 files changed, 200 insertions, 173 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index f24482e301..90f74ecf0e 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -376,6 +376,7 @@ set(MBGL_CORE_FILES src/mbgl/style/collection.hpp src/mbgl/style/custom_tile_loader.cpp src/mbgl/style/custom_tile_loader.hpp + src/mbgl/style/filter_evaluator.cpp src/mbgl/style/image.cpp src/mbgl/style/image_impl.cpp src/mbgl/style/image_impl.hpp diff --git a/include/mbgl/style/filter.hpp b/include/mbgl/style/filter.hpp index 9ab7e2e950..5bca3ed47d 100644 --- a/include/mbgl/style/filter.hpp +++ b/include/mbgl/style/filter.hpp @@ -278,8 +278,7 @@ public: template <class GeometryTileFeature> bool operator()(const GeometryTileFeature&) const; - template <class PropertyAccessor> - bool operator()(FeatureType type, optional<FeatureIdentifier> id, PropertyAccessor accessor, expression::EvaluationContext context) const; + bool operator()(expression::EvaluationContext context) const; }; } // namespace style diff --git a/include/mbgl/style/filter_evaluator.hpp b/include/mbgl/style/filter_evaluator.hpp index 3292ecbb16..7b883ef5fd 100644 --- a/include/mbgl/style/filter_evaluator.hpp +++ b/include/mbgl/style/filter_evaluator.hpp @@ -19,172 +19,35 @@ namespace style { // does not match } */ -template <class PropertyAccessor> class FilterEvaluator { public: - const FeatureType _featureType; - const optional<FeatureIdentifier> _featureIdentifier; - const PropertyAccessor _propertyAccessor; const expression::EvaluationContext context; - bool operator()(const NullFilter&) const { - return true; - } - - bool operator()(const EqualsFilter& filter) const { - optional<Value> actual = context.feature->getValue(filter.key); - return actual && equal(*actual, filter.value); - } - - bool operator()(const NotEqualsFilter& filter) const { - optional<Value> actual = context.feature->getValue(filter.key); - return !actual || !equal(*actual, filter.value); - } - - bool operator()(const LessThanFilter& filter) const { - optional<Value> actual = context.feature->getValue(filter.key); - return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ < rhs_; }); - } - - bool operator()(const LessThanEqualsFilter& filter) const { - optional<Value> actual = context.feature->getValue(filter.key); - return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ <= rhs_; }); - } - - bool operator()(const GreaterThanFilter& filter) const { - optional<Value> actual = context.feature->getValue(filter.key); - return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ > rhs_; }); - } - - bool operator()(const GreaterThanEqualsFilter& filter) const { - optional<Value> actual = context.feature->getValue(filter.key); - return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ >= rhs_; }); - } - - bool operator()(const InFilter& filter) const { - optional<Value> actual = context.feature->getValue(filter.key); - if (!actual) - return false; - for (const auto& v: filter.values) { - if (equal(*actual, v)) { - return true; - } - } - return false; - } - - bool operator()(const NotInFilter& filter) const { - optional<Value> actual = context.feature->getValue(filter.key); - if (!actual) - return true; - for (const auto& v: filter.values) { - if (equal(*actual, v)) { - return false; - } - } - return true; - } - - bool operator()(const AnyFilter& filter) const { - for (const auto& f: filter.filters) { - if (Filter::visit(f, *this)) { - return true; - } - } - return false; - } - - bool operator()(const AllFilter& filter) const { - for (const auto& f: filter.filters) { - if (!Filter::visit(f, *this)) { - return false; - } - } - return true; - } - - bool operator()(const NoneFilter& filter) const { - for (const auto& f: filter.filters) { - if (Filter::visit(f, *this)) { - return false; - } - } - return true; - } - - bool operator()(const HasFilter& filter) const { - return bool(context.feature->getValue(filter.key)); - } - - bool operator()(const NotHasFilter& filter) const { - return !context.feature->getValue(filter.key); - } - - - bool operator()(const TypeEqualsFilter& filter) const { - return context.feature->getType() == filter.value; - } - - bool operator()(const TypeNotEqualsFilter& filter) const { - return context.feature->getType() != filter.value; - } - - bool operator()(const TypeInFilter& filter) const { - for (const auto& v: filter.values) { - if (context.feature->getType() == v) { - return true; - } - } - return false; - } - - bool operator()(const TypeNotInFilter& filter) const { - for (const auto& v: filter.values) { - if (context.feature->getType() == v) { - return false; - } - } - return true; - } - - - bool operator()(const IdentifierEqualsFilter& filter) const { - return context.feature->getID() == filter.value; - } - - bool operator()(const IdentifierNotEqualsFilter& filter) const { - return context.feature->getID() != filter.value; - } - - bool operator()(const IdentifierInFilter& filter) const { - for (const auto& v: filter.values) { - if (context.feature->getID() == v) { - return true; - } - } - return false; - } - - bool operator()(const IdentifierNotInFilter& filter) const { - for (const auto& v: filter.values) { - if (context.feature->getID() == v) { - return false; - } - } - return true; - } - - bool operator()(const HasIdentifierFilter&) const { - return bool(context.feature->getID()); - } - - bool operator()(const NotHasIdentifierFilter&) const { - return !context.feature->getID(); - } - - bool operator()(const ExpressionFilter&) const { - return false; - } + bool operator()(const NullFilter&) const; + bool operator()(const EqualsFilter& filter) const; + bool operator()(const NotEqualsFilter& filter) const; + bool operator()(const LessThanFilter& filter) const; + bool operator()(const LessThanEqualsFilter& filter) const; + bool operator()(const GreaterThanFilter& filter) const; + bool operator()(const GreaterThanEqualsFilter& filter) const; + bool operator()(const InFilter& filter) const; + bool operator()(const NotInFilter& filter) const; + bool operator()(const AnyFilter& filter) const; + bool operator()(const AllFilter& filter) const; + bool operator()(const NoneFilter& filter) const; + bool operator()(const HasFilter& filter) const; + bool operator()(const NotHasFilter& filter) const; + bool operator()(const TypeEqualsFilter& filter) const; + bool operator()(const TypeNotEqualsFilter& filter) const; + bool operator()(const TypeInFilter& filter) const; + bool operator()(const TypeNotInFilter& filter) const; + bool operator()(const IdentifierEqualsFilter& filter) const; + bool operator()(const IdentifierNotEqualsFilter& filter) const; + bool operator()(const IdentifierInFilter& filter) const; + bool operator()(const IdentifierNotInFilter& filter) const; + bool operator()(const HasIdentifierFilter&) const; + bool operator()(const NotHasIdentifierFilter&) const; + bool operator()(const ExpressionFilter&) const; private: template <class Op> @@ -244,13 +107,7 @@ private: template <class GeometryTileFeature> bool Filter::operator()(const GeometryTileFeature& feature) const { - return operator()(feature.getType(), feature.getID(), [&] (const auto& key) { return feature.getValue(key); }, expression::EvaluationContext { &feature }); -} - -template <class PropertyAccessor> -// TODO add zoom & expression-compatible feature reference to this call - bool Filter::operator()(FeatureType type, optional<FeatureIdentifier> id, PropertyAccessor accessor, expression::EvaluationContext context) const { - return FilterBase::visit(*this, FilterEvaluator<PropertyAccessor> { type, id, accessor, context }); + return operator()(expression::EvaluationContext { &feature }); } } // namespace style diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 049c68a764..f455a9ddef 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -100,7 +100,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters, const size_t featureCount = sourceLayer->featureCount(); for (size_t i = 0; i < featureCount; ++i) { auto feature = sourceLayer->getFeature(i); - if (!leader.filter(feature->getType(), feature->getID(), [&] (const auto& key) { return feature->getValue(key); }, expression::EvaluationContext { feature.get() })) + if (!leader.filter(expression::EvaluationContext { feature.get() })) continue; SymbolFeature ft(std::move(feature)); diff --git a/src/mbgl/style/filter_evaluator.cpp b/src/mbgl/style/filter_evaluator.cpp new file mode 100644 index 0000000000..c1df1adc38 --- /dev/null +++ b/src/mbgl/style/filter_evaluator.cpp @@ -0,0 +1,170 @@ +#include <mbgl/style/filter.hpp> +#include <mbgl/style/filter_evaluator.hpp> +#include <mbgl/tile/geometry_tile_data.hpp> + +namespace mbgl { +namespace style { + +bool FilterEvaluator::operator()(const NullFilter&) const { + return true; +} + +bool FilterEvaluator::operator()(const EqualsFilter& filter) const { + optional<Value> actual = context.feature->getValue(filter.key); + return actual && equal(*actual, filter.value); +} + +bool FilterEvaluator::operator()(const NotEqualsFilter& filter) const { + optional<Value> actual = context.feature->getValue(filter.key); + return !actual || !equal(*actual, filter.value); +} + +bool FilterEvaluator::operator()(const LessThanFilter& filter) const { + optional<Value> actual = context.feature->getValue(filter.key); + return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ < rhs_; }); +} + +bool FilterEvaluator::operator()(const LessThanEqualsFilter& filter) const { + optional<Value> actual = context.feature->getValue(filter.key); + return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ <= rhs_; }); +} + +bool FilterEvaluator::operator()(const GreaterThanFilter& filter) const { + optional<Value> actual = context.feature->getValue(filter.key); + return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ > rhs_; }); +} + +bool FilterEvaluator::operator()(const GreaterThanEqualsFilter& filter) const { + optional<Value> actual = context.feature->getValue(filter.key); + return actual && compare(*actual, filter.value, [] (const auto& lhs_, const auto& rhs_) { return lhs_ >= rhs_; }); +} + +bool FilterEvaluator::operator()(const InFilter& filter) const { + optional<Value> actual = context.feature->getValue(filter.key); + if (!actual) + return false; + for (const auto& v: filter.values) { + if (equal(*actual, v)) { + return true; + } + } + return false; +} + +bool FilterEvaluator::operator()(const NotInFilter& filter) const { + optional<Value> actual = context.feature->getValue(filter.key); + if (!actual) + return true; + for (const auto& v: filter.values) { + if (equal(*actual, v)) { + return false; + } + } + return true; +} + +bool FilterEvaluator::operator()(const AnyFilter& filter) const { + for (const auto& f: filter.filters) { + if (Filter::visit(f, *this)) { + return true; + } + } + return false; +} + +bool FilterEvaluator::operator()(const AllFilter& filter) const { + for (const auto& f: filter.filters) { + if (!Filter::visit(f, *this)) { + return false; + } + } + return true; +} + +bool FilterEvaluator::operator()(const NoneFilter& filter) const { + for (const auto& f: filter.filters) { + if (Filter::visit(f, *this)) { + return false; + } + } + return true; +} + +bool FilterEvaluator::operator()(const HasFilter& filter) const { + return bool(context.feature->getValue(filter.key)); +} + +bool FilterEvaluator::operator()(const NotHasFilter& filter) const { + return !context.feature->getValue(filter.key); +} + +bool FilterEvaluator::operator()(const TypeEqualsFilter& filter) const { + return context.feature->getType() == filter.value; +} + +bool FilterEvaluator::operator()(const TypeNotEqualsFilter& filter) const { + return context.feature->getType() != filter.value; +} + +bool FilterEvaluator::operator()(const TypeInFilter& filter) const { + for (const auto& v: filter.values) { + if (context.feature->getType() == v) { + return true; + } + } + return false; +} + +bool FilterEvaluator::operator()(const TypeNotInFilter& filter) const { + for (const auto& v: filter.values) { + if (context.feature->getType() == v) { + return false; + } + } + return true; +} + +bool FilterEvaluator::operator()(const IdentifierEqualsFilter& filter) const { + return context.feature->getID() == filter.value; +} + +bool FilterEvaluator::operator()(const IdentifierNotEqualsFilter& filter) const { + return context.feature->getID() != filter.value; +} + +bool FilterEvaluator::operator()(const IdentifierInFilter& filter) const { + for (const auto& v: filter.values) { + if (context.feature->getID() == v) { + return true; + } + } + return false; +} + +bool FilterEvaluator::operator()(const IdentifierNotInFilter& filter) const { + for (const auto& v: filter.values) { + if (context.feature->getID() == v) { + return false; + } + } + return true; +} + +bool FilterEvaluator::operator()(const HasIdentifierFilter&) const { + return bool(context.feature->getID()); +} + +bool FilterEvaluator::operator()(const NotHasIdentifierFilter&) const { + return !context.feature->getID(); +} + +bool FilterEvaluator::operator()(const ExpressionFilter&) const { + return false; +} + +bool Filter::operator()(expression::EvaluationContext context) const { + return FilterBase::visit(*this, FilterEvaluator { context }); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index c80bd5ecd5..19e32a46bf 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -339,7 +339,7 @@ void GeometryTileWorker::redoLayout() { for (std::size_t i = 0; !obsolete && i < geometryLayer->featureCount(); i++) { std::unique_ptr<GeometryTileFeature> feature = geometryLayer->getFeature(i); - if (!filter(feature->getType(), feature->getID(), [&] (const auto& key) { return feature->getValue(key); }, expression::EvaluationContext { feature.get() })) + if (!filter(expression::EvaluationContext { feature.get() })) continue; GeometryCollection geometries = feature->getGeometries(); |