summaryrefslogtreecommitdiff
path: root/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-12-26 14:24:05 -0800
committerMinh Nguyễn <mxn@1ec5.org>2017-01-04 08:52:41 -0800
commite6132d248b54d202c3fa132b3084660a0bbe3c06 (patch)
treef6b98d23625169ded08d8f3b8965d3619f3fe2da /platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm
parent83309fd369c9623a1e2638f98f75206609d44258 (diff)
downloadqtlocation-mapboxgl-e6132d248b54d202c3fa132b3084660a0bbe3c06.tar.gz
[ios, macos] Rewrote predicate/filter conversion
When converting predicates to filters, symmetric comparison predicates can now compare a value to a key in addition to the usual key-to-value order. Added error checking for unhandled combinations like key-to-key. Fixed a crash converting a CONTAINS predicate into a filter. Added support for constant value expressions inside aggregate expressions. Allow sets as aggregate expressions just like arrays, except in BETWEEN predicates where order matters. Flatten NOT predicates into more specialized filters. When converting filters to predicates, use constant value expressions inside aggregate expressions. Convert to a BETWEEN predicate when possible. Replaced predicate round-tripping integration tests with systematic unit tests for converting in either direction, plus unit tests for round-tripping and symmetry. Refined exception names and messages. Realphabetized files in groups.
Diffstat (limited to 'platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm')
-rw-r--r--platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm53
1 files changed, 35 insertions, 18 deletions
diff --git a/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm b/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm
index 07114308c9..2697467198 100644
--- a/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm
@@ -18,32 +18,49 @@
{
switch (self.compoundPredicateType) {
case NSNotPredicateType: {
+ NSAssert(self.subpredicates.count <= 1, @"NOT predicate cannot have multiple subpredicates.");
+ NSPredicate *subpredicate = self.subpredicates.firstObject;
+ mbgl::style::Filter subfilter = subpredicate.mgl_filter;
- // Translate a nested NSComparisonPredicate with operator type NSInPredicateOperatorType into a flat mbgl::NotIn filter.
- NSArray<NSComparisonPredicate *> *comparisonPredicates = [self.subpredicates filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"class == %@", [NSComparisonPredicate class]]];
- NSArray<NSComparisonPredicate *> *notInPredicates = [comparisonPredicates filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSComparisonPredicate *_Nonnull predicate, NSDictionary<NSString *,id> * _Nullable bindings) {
- return predicate.predicateOperatorType == NSInPredicateOperatorType;
- }]];
+ // Convert NOT(!= nil) to NotHasFilter.
+ if (subfilter.is<mbgl::style::HasFilter>()) {
+ auto hasFilter = subfilter.get<mbgl::style::HasFilter>();
+ return mbgl::style::NotHasFilter { .key = hasFilter.key };
+ }
+
+ // Convert NOT(== nil) to HasFilter.
+ if (subfilter.is<mbgl::style::NotHasFilter>()) {
+ auto hasFilter = subfilter.get<mbgl::style::NotHasFilter>();
+ return mbgl::style::HasFilter { .key = hasFilter.key };
+ }
+
+ // Convert NOT(IN) or NOT(CONTAINS) to NotInFilter.
+ if (subfilter.is<mbgl::style::InFilter>()) {
+ auto inFilter = subfilter.get<mbgl::style::InFilter>();
+ mbgl::style::NotInFilter notInFilter;
+ notInFilter.key = inFilter.key;
+ notInFilter.values = inFilter.values;
+ return notInFilter;
+ }
- if (notInPredicates.count) {
- auto filter = mbgl::style::NotInFilter();
- filter.key = notInPredicates.firstObject.leftExpression.keyPath.UTF8String;
- filter.values = notInPredicates.firstObject.rightExpression.mgl_filterValues;
- return filter;
- } else {
- auto filter = mbgl::style::NoneFilter();
- filter.filters = [self mgl_subfilters];
- return filter;
+ // Convert NOT(), NOT(AND), NOT(NOT), NOT(==), etc. into NoneFilter.
+ mbgl::style::NoneFilter noneFilter;
+ if (subfilter.is<mbgl::style::AnyFilter>()) {
+ // Flatten NOT(OR).
+ noneFilter.filters = subfilter.get<mbgl::style::AnyFilter>().filters;
+ } else if (subpredicate) {
+ noneFilter.filters = { subfilter };
}
+ return noneFilter;
}
case NSAndPredicateType: {
- auto filter = mbgl::style::AllFilter();
- filter.filters = [self mgl_subfilters];
+ mbgl::style::AllFilter filter;
+ filter.filters = self.mgl_subfilters;
return filter;
}
case NSOrPredicateType: {
- auto filter = mbgl::style::AnyFilter();
- filter.filters = [self mgl_subfilters];
+ mbgl::style::AnyFilter filter;
+ filter.filters = self.mgl_subfilters;
return filter;
}
}