[ios, macos] Add more predicate operator to mbgl filter translations

Adds several new translations to prevent data loss.
This commit is contained in:
Jesse Bounds
2016-09-21 09:12:59 -07:00
committed by GitHub
parent 6fe621bbef
commit 1165a408fb
3 changed files with 113 additions and 20 deletions

View File

@@ -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];
}

View File

@@ -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 {};
}

View File

@@ -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"];