summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Bounds <jesse@rebounds.net>2016-09-21 09:12:59 -0700
committerGitHub <noreply@github.com>2016-09-21 09:12:59 -0700
commit1165a408fbee37a0892b07b5c35e1a36d7aa0063 (patch)
tree5ee4aa50d79ba712cf744af44255cb3490c92513
parent6fe621bbef43e6b73a53ca25a9df3d349cd84929 (diff)
downloadqtlocation-mapboxgl-1165a408fbee37a0892b07b5c35e1a36d7aa0063.tar.gz
[ios, macos] Add more predicate operator to mbgl filter translations
Adds several new translations to prevent data loss.
-rw-r--r--platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm54
-rw-r--r--platform/darwin/src/NSPredicate+MGLAdditions.mm22
-rw-r--r--platform/darwin/test/MGLFilterTests.mm57
3 files changed, 113 insertions, 20 deletions
diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
index ced6a1ac47..19c264aa40 100644
--- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
@@ -9,16 +9,34 @@
{
switch (self.predicateOperatorType) {
case NSEqualToPredicateOperatorType: {
- auto filter = mbgl::style::EqualsFilter();
- filter.key = self.leftExpression.keyPath.UTF8String;
- filter.value = self.rightExpression.mgl_filterValue;
- return filter;
+ if (self.rightExpression.constantValue)
+ {
+ auto filter = mbgl::style::EqualsFilter();
+ filter.key = self.leftExpression.keyPath.UTF8String;
+ filter.value = self.rightExpression.mgl_filterValue;
+ return filter;
+ }
+ else
+ {
+ auto filter = mbgl::style::NotHasFilter();
+ filter.key = self.leftExpression.keyPath.UTF8String;
+ return filter;
+ }
}
case NSNotEqualToPredicateOperatorType: {
- auto filter = mbgl::style::NotEqualsFilter();
- filter.key = self.leftExpression.keyPath.UTF8String;
- filter.value = self.rightExpression.mgl_filterValue;
- return filter;
+ if (self.rightExpression.constantValue)
+ {
+ auto filter = mbgl::style::NotEqualsFilter();
+ filter.key = self.leftExpression.keyPath.UTF8String;
+ filter.value = self.rightExpression.mgl_filterValue;
+ return filter;
+ }
+ else
+ {
+ auto filter = mbgl::style::HasFilter();
+ filter.key = self.leftExpression.keyPath.UTF8String;
+ return filter;
+ }
}
case NSGreaterThanPredicateOperatorType: {
auto filter = mbgl::style::GreaterThanFilter();
@@ -50,13 +68,29 @@
filter.values = self.rightExpression.mgl_filterValues;
return filter;
}
+ case NSContainsPredicateOperatorType: {
+ auto filter = mbgl::style::InFilter();
+ filter.key = [self.rightExpression.constantValue UTF8String];
+ filter.values = self.leftExpression.mgl_filterValues;
+ return filter;
+ }
+ case NSBetweenPredicateOperatorType: {
+ auto filter = mbgl::style::AllFilter();
+ auto gteFilter = mbgl::style::GreaterThanEqualsFilter();
+ gteFilter.key = self.leftExpression.keyPath.UTF8String;
+ gteFilter.value = self.rightExpression.mgl_filterValues[0];
+ filter.filters.push_back(gteFilter);
+ auto lteFilter = mbgl::style::LessThanEqualsFilter();
+ lteFilter.key = self.leftExpression.keyPath.UTF8String;
+ lteFilter.value = self.rightExpression.mgl_filterValues[1];
+ filter.filters.push_back(lteFilter);
+ return filter;
+ }
case NSMatchesPredicateOperatorType:
case NSLikePredicateOperatorType:
case NSBeginsWithPredicateOperatorType:
case NSEndsWithPredicateOperatorType:
case NSCustomSelectorPredicateOperatorType:
- case NSContainsPredicateOperatorType:
- case NSBetweenPredicateOperatorType:
[NSException raise:@"Unsupported operator type"
format:@"NSPredicateOperatorType:%lu is not supported.", (unsigned long)self.predicateOperatorType];
}
diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.mm b/platform/darwin/src/NSPredicate+MGLAdditions.mm
index 9c3f9c888c..64ad277e4d 100644
--- a/platform/darwin/src/NSPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSPredicate+MGLAdditions.mm
@@ -76,15 +76,11 @@ public:
}
NSPredicate* operator()(mbgl::style::HasFilter filter) {
- [NSException raise:@"Unsupported filter type"
- format:@"Cannot convert mbgl::style::HasFilter to NSPredicate"];
- return nil;
+ return [NSPredicate predicateWithFormat:@"%K != nil", @(filter.key.c_str())];
}
NSPredicate* operator()(mbgl::style::NotHasFilter filter) {
- [NSException raise:@"Unsupported filter type"
- format:@"Cannot convert mbgl::style::NotHasFilter to NSPredicate"];
- return nil;
+ return [NSPredicate predicateWithFormat:@"%K == nil", @(filter.key.c_str())];
}
};
@@ -93,8 +89,20 @@ public:
- (mbgl::style::Filter)mgl_filter
{
+ if ([self isEqual:[NSPredicate predicateWithValue:YES]])
+ {
+ auto filter = mbgl::style::AllFilter();
+ return filter;
+ }
+
+ if ([self isEqual:[NSPredicate predicateWithValue:NO]])
+ {
+ auto filter = mbgl::style::AnyFilter();
+ return filter;
+ }
+
[NSException raise:@"Not supported"
- format:@"NSPredicate doesn't implement ’-mgl_filter’. Try with NSComparisonPredicate or NSCompoundPredicate instead."];
+ format:@"Try with NSComparisonPredicate or NSCompoundPredicate instead."];
return {};
}
diff --git a/platform/darwin/test/MGLFilterTests.mm b/platform/darwin/test/MGLFilterTests.mm
index 513963ab7e..6fbe5f0157 100644
--- a/platform/darwin/test/MGLFilterTests.mm
+++ b/platform/darwin/test/MGLFilterTests.mm
@@ -3,6 +3,7 @@
#import "NSPredicate+MGLAdditions.h"
#import "MGLValueEvaluator.h"
+
@interface MGLFilterTests : MGLStyleLayerTests {
MGLGeoJSONSource *source;
MGLLineStyleLayer *layer;
@@ -42,8 +43,11 @@
NSPredicate *typePredicate = [NSPredicate predicateWithFormat:@"%K == %@", @"$type", @"Feature"];
NSPredicate *idPredicate = [NSPredicate predicateWithFormat:@"%K == %@", @"$id", @"1234123"];
NSPredicate *specialCharsPredicate = [NSPredicate predicateWithFormat:@"%K == %@", @"ty-’pè", @"sŒm-ethįng"];
- NSPredicate *booleanPredicate = [NSPredicate predicateWithFormat:@"%K != %@", @"cluster", [NSNumber numberWithBool:YES]];
- return @[equalPredicate,
+ NSPredicate *booleanPredicate = [NSPredicate predicateWithFormat:@"cluster != YES"];
+ NSPredicate *nilEqualsPredicate = [NSPredicate predicateWithFormat:@"type == %@", nil];
+ NSPredicate *nilNotEqualsPredicate = [NSPredicate predicateWithFormat:@"type != %@", nil];
+ return @[
+ equalPredicate,
notEqualPredicate,
greaterThanPredicate,
greaterThanOrEqualToPredicate,
@@ -55,7 +59,10 @@
typePredicate,
idPredicate,
specialCharsPredicate,
- booleanPredicate];
+ booleanPredicate,
+ nilEqualsPredicate,
+ nilNotEqualsPredicate
+ ];
}
- (void)testAllPredicates
@@ -67,6 +74,50 @@
[self.mapView.style addLayer:layer];
}
+- (void)testContainsPredicate
+{
+ // core does not have a "contains" filter but we can achieve the equivalent by creating an `mbgl::style::InFilter`
+ // and searching the value for the key
+ NSPredicate *expectedPredicate = [NSPredicate predicateWithFormat:@"park IN %@", @[@"park", @"neighbourhood"]];
+ NSPredicate *containsPredicate = [NSPredicate predicateWithFormat:@"%@ CONTAINS %@", @[@"park", @"neighbourhood"], @"park"];
+
+ layer.predicate = containsPredicate;
+ XCTAssertEqualObjects(layer.predicate, expectedPredicate);
+ [self.mapView.style addLayer:layer];
+}
+
+- (void)testBetweenPredicate
+{
+ // core does not have a "between" filter but we can achieve the equivalent by creating a set of greater than or equal / less than or equal
+ // filters for the lower and upper bounds (inclusive)
+ NSPredicate *expectedPredicate = [NSCompoundPredicate predicateWithFormat:@"%K >= 2 AND %K <= 3", @"stroke-width", @"stroke-width"];
+ NSPredicate *betweenPredicate = [NSPredicate predicateWithFormat:@"%K BETWEEN %@", @"stroke-width", @[@2.0, @3.0]];
+
+ layer.predicate = betweenPredicate;
+ XCTAssertEqualObjects(layer.predicate, expectedPredicate);
+ [self.mapView.style addLayer:layer];
+}
+
+- (void)testTruePredicate
+{
+ // This comes out of the class cluster as an NSTruePredicate and it is equal to `[NSPredicate predicateWithValue:YES]`
+ NSPredicate *truePredicate = [NSPredicate predicateWithFormat:@"TRUEPREDICATE"];
+
+ layer.predicate = truePredicate;
+ XCTAssertEqualObjects(layer.predicate.description, truePredicate.description);
+ [self.mapView.style addLayer:layer];
+}
+
+- (void)testFalsePredicate
+{
+ // This comes out of the class cluster as an NSFalsePredicate and it is equal to `[NSPredicate predicateWithValue:NO]`
+ NSPredicate *falsePredicate = [NSPredicate predicateWithFormat:@"FALSEPREDICATE"];
+
+ layer.predicate = falsePredicate;
+ XCTAssertEqualObjects(layer.predicate.description, falsePredicate.description);
+ [self.mapView.style addLayer:layer];
+}
+
- (void)testIntermittentEncoding
{
NSPredicate *specialCharsPredicate = [NSPredicate predicateWithFormat:@"%K == %@", @"ty-’pè", @"sŒm-ethįng"];