diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2017-01-16 11:38:35 -0800 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2017-01-16 11:38:35 -0800 |
commit | 7ef2843e6a62116667be6a2c12de085951fdd5ea (patch) | |
tree | 40eca249e044e2706efd1193d617e6eb8e59d708 /platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm | |
parent | 76301b252cbc4bc3ae1fc84322bcbcdbd26cae8a (diff) | |
parent | 13b97dd0cebffe36b187bdb74923910def6bd87b (diff) | |
download | qtlocation-mapboxgl-7ef2843e6a62116667be6a2c12de085951fdd5ea.tar.gz |
Merge branch 'release-ios-v3.4.0' into 1ec5-release-ios-v3.4.0-beta.7
Diffstat (limited to 'platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm')
-rw-r--r-- | platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm | 212 |
1 files changed, 153 insertions, 59 deletions
diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm index 19c264aa40..58b37fae0e 100644 --- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm +++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm @@ -7,95 +7,189 @@ - (mbgl::style::Filter)mgl_filter { + NSExpression *leftExpression = self.leftExpression; + NSExpression *rightExpression = self.rightExpression; + NSExpressionType leftType = leftExpression.expressionType; + NSExpressionType rightType = rightExpression.expressionType; + BOOL isReversed = ((leftType == NSConstantValueExpressionType || leftType == NSAggregateExpressionType) + && rightType == NSKeyPathExpressionType); switch (self.predicateOperatorType) { case NSEqualToPredicateOperatorType: { - 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; + mbgl::style::EqualsFilter eqFilter; + eqFilter.key = self.mgl_keyPath.UTF8String; + eqFilter.value = self.mgl_constantValue; + + // Convert == nil to NotHasFilter. + if (eqFilter.value.is<mbgl::NullValue>()) { + mbgl::style::NotHasFilter notHasFilter; + notHasFilter.key = eqFilter.key; + return notHasFilter; } + + return eqFilter; } case NSNotEqualToPredicateOperatorType: { - 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; + mbgl::style::NotEqualsFilter neFilter; + neFilter.key = self.mgl_keyPath.UTF8String; + neFilter.value = self.mgl_constantValue; + + // Convert != nil to HasFilter. + if (neFilter.value.is<mbgl::NullValue>()) { + mbgl::style::HasFilter hasFilter; + hasFilter.key = neFilter.key; + return hasFilter; } + + return neFilter; } case NSGreaterThanPredicateOperatorType: { - auto filter = mbgl::style::GreaterThanFilter(); - filter.key = self.leftExpression.keyPath.UTF8String; - filter.value = self.rightExpression.mgl_filterValue; - return filter; + if (isReversed) { + mbgl::style::LessThanFilter ltFilter; + ltFilter.key = self.mgl_keyPath.UTF8String; + ltFilter.value = self.mgl_constantValue; + return ltFilter; + } else { + mbgl::style::GreaterThanFilter gtFilter; + gtFilter.key = self.mgl_keyPath.UTF8String; + gtFilter.value = self.mgl_constantValue; + return gtFilter; + } } case NSGreaterThanOrEqualToPredicateOperatorType: { - auto filter = mbgl::style::GreaterThanEqualsFilter(); - filter.key = self.leftExpression.keyPath.UTF8String; - filter.value = self.rightExpression.mgl_filterValue; - return filter; + if (isReversed) { + mbgl::style::LessThanEqualsFilter lteFilter; + lteFilter.key = self.mgl_keyPath.UTF8String; + lteFilter.value = self.mgl_constantValue; + return lteFilter; + } else { + mbgl::style::GreaterThanEqualsFilter gteFilter; + gteFilter.key = self.mgl_keyPath.UTF8String; + gteFilter.value = self.mgl_constantValue; + return gteFilter; + } } case NSLessThanPredicateOperatorType: { - auto filter = mbgl::style::LessThanFilter(); - filter.key = self.leftExpression.keyPath.UTF8String; - filter.value = self.rightExpression.mgl_filterValue; - return filter; + if (isReversed) { + mbgl::style::GreaterThanFilter gtFilter; + gtFilter.key = self.mgl_keyPath.UTF8String; + gtFilter.value = self.mgl_constantValue; + return gtFilter; + } else { + mbgl::style::LessThanFilter ltFilter; + ltFilter.key = self.mgl_keyPath.UTF8String; + ltFilter.value = self.mgl_constantValue; + return ltFilter; + } } case NSLessThanOrEqualToPredicateOperatorType: { - auto filter = mbgl::style::LessThanEqualsFilter(); - filter.key = self.leftExpression.keyPath.UTF8String; - filter.value = self.rightExpression.mgl_filterValue; - return filter; + if (isReversed) { + mbgl::style::GreaterThanEqualsFilter gteFilter; + gteFilter.key = self.mgl_keyPath.UTF8String; + gteFilter.value = self.mgl_constantValue; + return gteFilter; + } else { + mbgl::style::LessThanEqualsFilter lteFilter; + lteFilter.key = self.mgl_keyPath.UTF8String; + lteFilter.value = self.mgl_constantValue; + return lteFilter; + } } case NSInPredicateOperatorType: { - auto filter = mbgl::style::InFilter(); - filter.key = self.leftExpression.keyPath.UTF8String; - filter.values = self.rightExpression.mgl_filterValues; - return filter; + if (isReversed) { + if (leftType == NSConstantValueExpressionType && [leftExpression.constantValue isKindOfClass:[NSString class]]) { + [NSException raise:NSInvalidArgumentException + format:@"CONTAINS not supported for string comparison."]; + } + [NSException raise:NSInvalidArgumentException + format:@"Predicate cannot compare values IN attribute."]; + } + mbgl::style::InFilter inFilter; + inFilter.key = leftExpression.keyPath.UTF8String; + inFilter.values = rightExpression.mgl_aggregateMBGLValue; + return inFilter; } case NSContainsPredicateOperatorType: { - auto filter = mbgl::style::InFilter(); - filter.key = [self.rightExpression.constantValue UTF8String]; - filter.values = self.leftExpression.mgl_filterValues; - return filter; + if (!isReversed) { + if (rightType == NSConstantValueExpressionType && [rightExpression.constantValue isKindOfClass:[NSString class]]) { + [NSException raise:NSInvalidArgumentException + format:@"IN not supported for string comparison."]; + } + [NSException raise:NSInvalidArgumentException + format:@"Predicate cannot compare attribute CONTAINS values."]; + } + mbgl::style::InFilter inFilter; + inFilter.key = rightExpression.keyPath.UTF8String; + inFilter.values = leftExpression.mgl_aggregateMBGLValue; + return inFilter; } 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; + if (isReversed) { + [NSException raise:NSInvalidArgumentException + format:@"Predicate cannot compare bounds BETWEEN attribute."]; + } + if (![rightExpression.constantValue isKindOfClass:[NSArray class]]) { + [NSException raise:NSInvalidArgumentException + format:@"Right side of BETWEEN predicate must be an array."]; // not NSSet + } + auto values = rightExpression.mgl_aggregateMBGLValue; + if (values.size() != 2) { + [NSException raise:NSInvalidArgumentException + format:@"Right side of BETWEEN predicate must have two items."]; + } + mbgl::style::AllFilter allFilter; + mbgl::style::GreaterThanEqualsFilter gteFilter; + gteFilter.key = leftExpression.keyPath.UTF8String; + gteFilter.value = values[0]; + allFilter.filters.push_back(gteFilter); + mbgl::style::LessThanEqualsFilter lteFilter; + lteFilter.key = leftExpression.keyPath.UTF8String; + lteFilter.value = values[1]; + allFilter.filters.push_back(lteFilter); + return allFilter; } case NSMatchesPredicateOperatorType: case NSLikePredicateOperatorType: case NSBeginsWithPredicateOperatorType: case NSEndsWithPredicateOperatorType: case NSCustomSelectorPredicateOperatorType: - [NSException raise:@"Unsupported operator type" + [NSException raise:NSInvalidArgumentException format:@"NSPredicateOperatorType:%lu is not supported.", (unsigned long)self.predicateOperatorType]; } return {}; } +- (NSString *)mgl_keyPath { + NSExpression *leftExpression = self.leftExpression; + NSExpression *rightExpression = self.rightExpression; + NSExpressionType leftType = leftExpression.expressionType; + NSExpressionType rightType = rightExpression.expressionType; + if (leftType == NSKeyPathExpressionType && rightType == NSConstantValueExpressionType) { + return leftExpression.keyPath; + } else if (leftType == NSConstantValueExpressionType && rightType == NSKeyPathExpressionType) { + return rightExpression.keyPath; + } + + [NSException raise:NSInvalidArgumentException + format:@"Comparison predicate must compare an attribute (as a key path) to a constant or vice versa."]; + return nil; +} + +- (mbgl::Value)mgl_constantValue { + NSExpression *leftExpression = self.leftExpression; + NSExpression *rightExpression = self.rightExpression; + NSExpressionType leftType = leftExpression.expressionType; + NSExpressionType rightType = rightExpression.expressionType; + mbgl::Value value; + if (leftType == NSKeyPathExpressionType && rightType == NSConstantValueExpressionType) { + value = rightExpression.mgl_constantMBGLValue; + } else if (leftType == NSConstantValueExpressionType && rightType == NSKeyPathExpressionType) { + value = leftExpression.mgl_constantMBGLValue; + } else { + [NSException raise:NSInvalidArgumentException + format:@"Comparison predicate must compare an attribute (as a key path) to a constant or vice versa."]; + } + return value; +} + @end |