From d77a13eb7320722c48c8a18240adf99615c4b85f Mon Sep 17 00:00:00 2001 From: Fredrik Karlsson Date: Wed, 17 Aug 2016 13:38:02 +0200 Subject: [PATCH 1/2] [ios] Added support for filters (NSPredicate) [ios, macos] cleaned up filters [ios] added a filter example [ios] utest filters [ios, macos] nested predicates [ios] refactored [ios] filter -> NSPredicate [ios] fixed mbgl::Any/AllFilter -> NSPredicate [ios] translate nested mbgl::NotIn filters [ios] cleanup and added more utests [ios] fixed a bug in the None filter conversion and improved utests [ios, macos] doc [macos] added missing category [ios, macos] additional utests [ios, macos] updated documentation --- .../darwin/src/MGLBaseStyleLayer_Private.h | 2 + platform/darwin/src/MGLCircleStyleLayer.h | 8 + platform/darwin/src/MGLCircleStyleLayer.mm | 10 ++ platform/darwin/src/MGLFeature.mm | 51 +------ platform/darwin/src/MGLFillStyleLayer.h | 8 + platform/darwin/src/MGLFillStyleLayer.mm | 10 ++ platform/darwin/src/MGLLineStyleLayer.h | 8 + platform/darwin/src/MGLLineStyleLayer.mm | 10 ++ platform/darwin/src/MGLStyleLayer.h.ejs | 12 ++ platform/darwin/src/MGLStyleLayer.mm.ejs | 12 ++ platform/darwin/src/MGLSymbolStyleLayer.h | 8 + platform/darwin/src/MGLSymbolStyleLayer.mm | 10 ++ platform/darwin/src/MGLValueEvaluator.h | 49 +++++++ .../src/NSComparisonPredicate+MGLAdditions.h | 7 + .../src/NSComparisonPredicate+MGLAdditions.mm | 67 +++++++++ .../src/NSCompoundPredicate+MGLAdditions.h | 7 + .../src/NSCompoundPredicate+MGLAdditions.mm | 56 +++++++ .../darwin/src/NSExpression+MGLAdditions.h | 11 ++ .../darwin/src/NSExpression+MGLAdditions.mm | 43 ++++++ .../darwin/src/NSPredicate+MGLAdditions.h | 13 ++ .../darwin/src/NSPredicate+MGLAdditions.mm | 107 ++++++++++++++ platform/darwin/test/MGLFilterTests.mm | 137 ++++++++++++++++++ .../test/MGLStyleLayerTests.xib | 8 +- platform/darwin/test/amsterdam.geojson | 4 +- platform/ios/app/MBXViewController.m | 23 +++ platform/ios/ios.xcodeproj/project.pbxproj | 60 +++++++- platform/macos/app/MapDocument.m | 3 +- .../macos/macos.xcodeproj/project.pbxproj | 36 ++++- 28 files changed, 724 insertions(+), 56 deletions(-) create mode 100644 platform/darwin/src/MGLValueEvaluator.h create mode 100644 platform/darwin/src/NSComparisonPredicate+MGLAdditions.h create mode 100644 platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm create mode 100644 platform/darwin/src/NSCompoundPredicate+MGLAdditions.h create mode 100644 platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm create mode 100644 platform/darwin/src/NSExpression+MGLAdditions.h create mode 100644 platform/darwin/src/NSExpression+MGLAdditions.mm create mode 100644 platform/darwin/src/NSPredicate+MGLAdditions.h create mode 100644 platform/darwin/src/NSPredicate+MGLAdditions.mm create mode 100644 platform/darwin/test/MGLFilterTests.mm rename platform/{ios => darwin}/test/MGLStyleLayerTests.xib (92%) diff --git a/platform/darwin/src/MGLBaseStyleLayer_Private.h b/platform/darwin/src/MGLBaseStyleLayer_Private.h index e3d43906a4e..0cbb076b35d 100644 --- a/platform/darwin/src/MGLBaseStyleLayer_Private.h +++ b/platform/darwin/src/MGLBaseStyleLayer_Private.h @@ -1,5 +1,7 @@ #import "MGLBaseStyleLayer.h" +#import "NSPredicate+MGLAdditions.h" + @interface MGLBaseStyleLayer (MGLBaseStyleLayer_Private) - (void)update; diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h index 7d2ef05848b..e4430044ad2 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.h +++ b/platform/darwin/src/MGLCircleStyleLayer.h @@ -18,6 +18,14 @@ typedef NS_ENUM(NSUInteger, MGLCircleStyleLayerCirclePitchScale) { @interface MGLCircleStyleLayer : MGLBaseStyleLayer +/** + A predicate that corresponds to the layer's filter. + + The predicate's left expression must be a string that identifies a feature + property, or one of the special keys. + */ +@property (nonatomic, nullable) NSPredicate *predicate; + #pragma mark - Accessing the Paint Attributes /** diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm index 27be01505c6..6c038318ccc 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.mm +++ b/platform/darwin/src/MGLCircleStyleLayer.mm @@ -29,6 +29,16 @@ - (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier sourceIdenti return self; } +- (void)setPredicate:(NSPredicate *)predicate +{ + self.layer->setFilter(predicate.mgl_filter); +} + +- (NSPredicate *)predicate +{ + return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()]; +} + #pragma mark - Accessing the Paint Attributes - (void)setCircleRadius:(id )circleRadius { diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm index 3bf1e61153d..6d4f76a71d9 100644 --- a/platform/darwin/src/MGLFeature.mm +++ b/platform/darwin/src/MGLFeature.mm @@ -3,6 +3,7 @@ #import "MGLPointAnnotation.h" #import "MGLPolyline.h" #import "MGLPolygon.h" +#import "MGLValueEvaluator.h" #import "MGLMultiPoint_Private.h" @@ -113,51 +114,7 @@ - (id)attributeForKey:(NSString *)key { @end -/** - Recursively transforms a C++ type into the corresponding Foundation type. - */ -class PropertyValueEvaluator { -public: - id operator()(const mbgl::NullValue &) const { - return [NSNull null]; - } - - id operator()(const bool &value) const { - return value ? @YES : @NO; - } - - id operator()(const uint64_t &value) const { - return @(value); - } - - id operator()(const int64_t &value) const { - return @(value); - } - - id operator()(const double &value) const { - return @(value); - } - - id operator()(const std::string &value) const { - return @(value.c_str()); - } - - id operator()(const std::vector &values) const { - NSMutableArray *objects = [NSMutableArray arrayWithCapacity:values.size()]; - for (const auto &v : values) { - [objects addObject:mbgl::Value::visit(v, *this)]; - } - return objects; - } - - id operator()(const std::unordered_map &items) const { - NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithCapacity:items.size()]; - for (auto &item : items) { - attributes[@(item.first.c_str())] = mbgl::Value::visit(item.second, *this); - } - return attributes; - } -}; + /** Transforms an `mbgl::geometry::geometry` type into an instance of the @@ -253,14 +210,14 @@ static CLLocationCoordinate2D toLocationCoordinate2D(const mbgl::Point &point NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithCapacity:feature.properties.size()]; for (auto &pair : feature.properties) { auto &value = pair.second; - PropertyValueEvaluator evaluator; + ValueEvaluator evaluator; attributes[@(pair.first.c_str())] = mbgl::Value::visit(value, evaluator); } GeometryEvaluator evaluator; MGLShape *shape = mapbox::geometry::geometry::visit(feature.geometry, evaluator); if (feature.id) { - shape.identifier = mbgl::FeatureIdentifier::visit(*feature.id, PropertyValueEvaluator()); + shape.identifier = mbgl::FeatureIdentifier::visit(*feature.id, ValueEvaluator()); } shape.attributes = attributes; [shapes addObject:shape]; diff --git a/platform/darwin/src/MGLFillStyleLayer.h b/platform/darwin/src/MGLFillStyleLayer.h index c03e8ecae10..2d51f071e51 100644 --- a/platform/darwin/src/MGLFillStyleLayer.h +++ b/platform/darwin/src/MGLFillStyleLayer.h @@ -13,6 +13,14 @@ typedef NS_ENUM(NSUInteger, MGLFillStyleLayerFillTranslateAnchor) { @interface MGLFillStyleLayer : MGLBaseStyleLayer +/** + A predicate that corresponds to the layer's filter. + + The predicate's left expression must be a string that identifies a feature + property, or one of the special keys. + */ +@property (nonatomic, nullable) NSPredicate *predicate; + #pragma mark - Accessing the Paint Attributes /** diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm index 192235f69ee..c54ddba428c 100644 --- a/platform/darwin/src/MGLFillStyleLayer.mm +++ b/platform/darwin/src/MGLFillStyleLayer.mm @@ -29,6 +29,16 @@ - (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier sourceIdenti return self; } +- (void)setPredicate:(NSPredicate *)predicate +{ + self.layer->setFilter(predicate.mgl_filter); +} + +- (NSPredicate *)predicate +{ + return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()]; +} + #pragma mark - Accessing the Paint Attributes - (void)setFillAntialias:(id )fillAntialias { diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h index 435829c5021..5c2a3afc2e1 100644 --- a/platform/darwin/src/MGLLineStyleLayer.h +++ b/platform/darwin/src/MGLLineStyleLayer.h @@ -25,6 +25,14 @@ typedef NS_ENUM(NSUInteger, MGLLineStyleLayerLineTranslateAnchor) { @interface MGLLineStyleLayer : MGLBaseStyleLayer +/** + A predicate that corresponds to the layer's filter. + + The predicate's left expression must be a string that identifies a feature + property, or one of the special keys. + */ +@property (nonatomic, nullable) NSPredicate *predicate; + #pragma mark - Accessing the Layout Attributes /** diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm index ffb0d4e3946..ce9ad75f87a 100644 --- a/platform/darwin/src/MGLLineStyleLayer.mm +++ b/platform/darwin/src/MGLLineStyleLayer.mm @@ -29,6 +29,16 @@ - (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier sourceIdenti return self; } +- (void)setPredicate:(NSPredicate *)predicate +{ + self.layer->setFilter(predicate.mgl_filter); +} + +- (NSPredicate *)predicate +{ + return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()]; +} + #pragma mark - Accessing the Layout Attributes - (void)setLineCap:(id )lineCap { diff --git a/platform/darwin/src/MGLStyleLayer.h.ejs b/platform/darwin/src/MGLStyleLayer.h.ejs index 2b36a3067a8..8acda024c4d 100644 --- a/platform/darwin/src/MGLStyleLayer.h.ejs +++ b/platform/darwin/src/MGLStyleLayer.h.ejs @@ -35,6 +35,16 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(prope <% } -%> @interface MGL<%- camelize(type) %>StyleLayer : MGLBaseStyleLayer +<% if (type !== 'background' && type !== 'raster') { -%> +/** + A predicate that corresponds to the layer's filter. + + The predicate's left expression must be a string that identifies a feature + property, or one of the special keys. + */ +@property (nonatomic, nullable) NSPredicate *predicate; + +<% } -%> <% if (layoutProperties.length) { -%> #pragma mark - Accessing the Layout Attributes @@ -53,6 +63,7 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(prope <% } -%> <% } -%> +<% if (paintProperties.length) { -%> #pragma mark - Accessing the Paint Attributes <% for (const property of paintProperties) { -%> @@ -68,6 +79,7 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(prope */ @property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) <%- propertyType(property, false, type) %> <%- camelizeWithLeadingLowercase(property.name) %>; +<% } -%> <% } -%> @end diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs index c35d254cafa..4e59c3c6cb6 100644 --- a/platform/darwin/src/MGLStyleLayer.mm.ejs +++ b/platform/darwin/src/MGLStyleLayer.mm.ejs @@ -34,6 +34,18 @@ return self; } +<% if (type !== 'background' && type !== 'raster') { -%> +- (void)setPredicate:(NSPredicate *)predicate +{ + self.layer->setFilter(predicate.mgl_filter); +} + +- (NSPredicate *)predicate +{ + return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()]; +} + +<% } -%> <% if (layoutProperties.length) { -%> #pragma mark - Accessing the Layout Attributes diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h index ef88ff996ed..eacd158ddad 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.h +++ b/platform/darwin/src/MGLSymbolStyleLayer.h @@ -69,6 +69,14 @@ typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextTranslateAnchor) { @interface MGLSymbolStyleLayer : MGLBaseStyleLayer +/** + A predicate that corresponds to the layer's filter. + + The predicate's left expression must be a string that identifies a feature + property, or one of the special keys. + */ +@property (nonatomic, nullable) NSPredicate *predicate; + #pragma mark - Accessing the Layout Attributes /** diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm index 159e3c4d0bc..b0553ea4251 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ b/platform/darwin/src/MGLSymbolStyleLayer.mm @@ -29,6 +29,16 @@ - (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier sourceIdenti return self; } +- (void)setPredicate:(NSPredicate *)predicate +{ + self.layer->setFilter(predicate.mgl_filter); +} + +- (NSPredicate *)predicate +{ + return [NSPredicate mgl_predicateWithFilter:self.layer->getFilter()]; +} + #pragma mark - Accessing the Layout Attributes - (void)setSymbolPlacement:(id )symbolPlacement { diff --git a/platform/darwin/src/MGLValueEvaluator.h b/platform/darwin/src/MGLValueEvaluator.h new file mode 100644 index 00000000000..b53cdaa8d2f --- /dev/null +++ b/platform/darwin/src/MGLValueEvaluator.h @@ -0,0 +1,49 @@ +#import + +#import + +/** + Recursively transforms a C++ type into the corresponding Foundation type. + */ +class ValueEvaluator { +public: + id operator()(const mbgl::NullValue &) const { + return [NSNull null]; + } + + id operator()(const bool &value) const { + return value ? @YES : @NO; + } + + id operator()(const uint64_t &value) const { + return @(value); + } + + id operator()(const int64_t &value) const { + return @(value); + } + + id operator()(const double &value) const { + return @(value); + } + + id operator()(const std::string &value) const { + return @(value.c_str()); + } + + id operator()(const std::vector &values) const { + NSMutableArray *objects = [NSMutableArray arrayWithCapacity:values.size()]; + for (const auto &v : values) { + [objects addObject:mbgl::Value::visit(v, *this)]; + } + return objects; + } + + id operator()(const std::unordered_map &items) const { + NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithCapacity:items.size()]; + for (auto &item : items) { + attributes[@(item.first.c_str())] = mbgl::Value::visit(item.second, *this); + } + return attributes; + } +}; diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.h b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.h new file mode 100644 index 00000000000..2cd4dd1577a --- /dev/null +++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.h @@ -0,0 +1,7 @@ +#import + +#include + +@interface NSComparisonPredicate (MGLAdditions) + +@end diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm new file mode 100644 index 00000000000..ced6a1ac470 --- /dev/null +++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm @@ -0,0 +1,67 @@ +#import "NSComparisonPredicate+MGLAdditions.h" + +#import "NSPredicate+MGLAdditions.h" +#import "NSExpression+MGLAdditions.h" + +@implementation NSComparisonPredicate (MGLAdditions) + +- (mbgl::style::Filter)mgl_filter +{ + switch (self.predicateOperatorType) { + case NSEqualToPredicateOperatorType: { + auto filter = mbgl::style::EqualsFilter(); + filter.key = self.leftExpression.keyPath.UTF8String; + filter.value = self.rightExpression.mgl_filterValue; + return filter; + } + case NSNotEqualToPredicateOperatorType: { + auto filter = mbgl::style::NotEqualsFilter(); + filter.key = self.leftExpression.keyPath.UTF8String; + filter.value = self.rightExpression.mgl_filterValue; + return filter; + } + case NSGreaterThanPredicateOperatorType: { + auto filter = mbgl::style::GreaterThanFilter(); + filter.key = self.leftExpression.keyPath.UTF8String; + filter.value = self.rightExpression.mgl_filterValue; + return filter; + } + case NSGreaterThanOrEqualToPredicateOperatorType: { + auto filter = mbgl::style::GreaterThanEqualsFilter(); + filter.key = self.leftExpression.keyPath.UTF8String; + filter.value = self.rightExpression.mgl_filterValue; + return filter; + } + case NSLessThanPredicateOperatorType: { + auto filter = mbgl::style::LessThanFilter(); + filter.key = self.leftExpression.keyPath.UTF8String; + filter.value = self.rightExpression.mgl_filterValue; + return filter; + } + case NSLessThanOrEqualToPredicateOperatorType: { + auto filter = mbgl::style::LessThanEqualsFilter(); + filter.key = self.leftExpression.keyPath.UTF8String; + filter.value = self.rightExpression.mgl_filterValue; + return filter; + } + case NSInPredicateOperatorType: { + auto filter = mbgl::style::InFilter(); + filter.key = self.leftExpression.keyPath.UTF8String; + filter.values = self.rightExpression.mgl_filterValues; + 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]; + } + + return {}; +} + +@end diff --git a/platform/darwin/src/NSCompoundPredicate+MGLAdditions.h b/platform/darwin/src/NSCompoundPredicate+MGLAdditions.h new file mode 100644 index 00000000000..0f9909255d9 --- /dev/null +++ b/platform/darwin/src/NSCompoundPredicate+MGLAdditions.h @@ -0,0 +1,7 @@ +#import + +#include + +@interface NSCompoundPredicate (MGLAdditions) + +@end diff --git a/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm b/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm new file mode 100644 index 00000000000..07114308c9c --- /dev/null +++ b/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm @@ -0,0 +1,56 @@ +#import "NSCompoundPredicate+MGLAdditions.h" + +#import "NSPredicate+MGLAdditions.h" +#import "NSExpression+MGLAdditions.h" + +@implementation NSCompoundPredicate (MGLAdditions) + +- (std::vector)mgl_subfilters +{ + std::vectorfilters; + for (NSPredicate *predicate in self.subpredicates) { + filters.push_back(predicate.mgl_filter); + } + return filters; +} + +- (mbgl::style::Filter)mgl_filter +{ + switch (self.compoundPredicateType) { + case NSNotPredicateType: { + + // Translate a nested NSComparisonPredicate with operator type NSInPredicateOperatorType into a flat mbgl::NotIn filter. + NSArray *comparisonPredicates = [self.subpredicates filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"class == %@", [NSComparisonPredicate class]]]; + NSArray *notInPredicates = [comparisonPredicates filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSComparisonPredicate *_Nonnull predicate, NSDictionary * _Nullable bindings) { + return predicate.predicateOperatorType == NSInPredicateOperatorType; + }]]; + + 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; + } + } + case NSAndPredicateType: { + auto filter = mbgl::style::AllFilter(); + filter.filters = [self mgl_subfilters]; + return filter; + } + case NSOrPredicateType: { + auto filter = mbgl::style::AnyFilter(); + filter.filters = [self mgl_subfilters]; + return filter; + } + } + + [NSException raise:@"Compound predicate type not handled" + format:@""]; + return {}; +} + +@end diff --git a/platform/darwin/src/NSExpression+MGLAdditions.h b/platform/darwin/src/NSExpression+MGLAdditions.h new file mode 100644 index 00000000000..4e8c5ee0717 --- /dev/null +++ b/platform/darwin/src/NSExpression+MGLAdditions.h @@ -0,0 +1,11 @@ +#import + +#include + +@interface NSExpression (MGLAdditions) + +- (mbgl::Value)mgl_filterValue; + +- (std::vector)mgl_filterValues; + +@end diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm new file mode 100644 index 00000000000..5f1a1e765a3 --- /dev/null +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -0,0 +1,43 @@ +#import "NSExpression+MGLAdditions.h" + +@implementation NSExpression (MGLAdditions) + +- (std::vector)mgl_filterValues +{ + if ([self.constantValue isKindOfClass:NSArray.class]) { + NSArray *values = self.constantValue; + std::vectorconvertedValues; + for (id value in values) { + convertedValues.push_back([self mgl_convertedValueWithValue:value]); + } + return convertedValues; + } + [NSException raise:@"Values not handled" format:@""]; + return { }; +} + +- (mbgl::Value)mgl_filterValue +{ + return [self mgl_convertedValueWithValue:self.constantValue]; +} + +- (mbgl::Value)mgl_convertedValueWithValue:(id)value +{ + if ([value isKindOfClass:NSString.class]) { + return { std::string([(NSString *)value UTF8String]) }; + } else if ([value isKindOfClass:NSNumber.class]) { + NSNumber *number = (NSNumber *)value; + if((strcmp([number objCType], @encode(int))) == 0) { + return { number.intValue }; + } else if ((strcmp([number objCType], @encode(double))) == 0) { + return { number.doubleValue }; + } else if ((strcmp([number objCType], @encode(bool))) == 0) { + return { number.boolValue }; + } + } + [NSException raise:@"Value not handled" + format:@"Can’t convert %s:%@ to mbgl::Value", [value objCType], value]; + return { }; +} + +@end diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.h b/platform/darwin/src/NSPredicate+MGLAdditions.h new file mode 100644 index 00000000000..fd774dd58bf --- /dev/null +++ b/platform/darwin/src/NSPredicate+MGLAdditions.h @@ -0,0 +1,13 @@ +#import + +#import "NSExpression+MGLAdditions.h" +#include + +@interface NSPredicate (MGLAdditions) + +- (mbgl::style::Filter)mgl_filter; + ++ (instancetype)mgl_predicateWithFilter:(mbgl::style::Filter)filter; + +@end + diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.mm b/platform/darwin/src/NSPredicate+MGLAdditions.mm new file mode 100644 index 00000000000..9c3f9c888c6 --- /dev/null +++ b/platform/darwin/src/NSPredicate+MGLAdditions.mm @@ -0,0 +1,107 @@ +#import "NSPredicate+MGLAdditions.h" + +#import "MGLValueEvaluator.h" + +class FilterEvaluator { +public: + + NSArray* getPredicates(std::vector filters) { + NSMutableArray *predicates = [NSMutableArray arrayWithCapacity:filters.size()]; + for (auto filter : filters) { + [predicates addObject:mbgl::style::Filter::visit(filter, FilterEvaluator())]; + } + return predicates; + } + + NSArray* getValues(std::vector values) { + NSMutableArray *array = [NSMutableArray arrayWithCapacity:values.size()]; + for (auto value : values) { + [array addObject:mbgl::Value::visit(value, ValueEvaluator())]; + } + return array; + } + + NSPredicate* operator()(mbgl::style::NullFilter filter) { + return nil; + } + + NSPredicate* operator()(mbgl::style::EqualsFilter filter) { + return [NSPredicate predicateWithFormat:@"%K == %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; + } + + NSPredicate* operator()(mbgl::style::NotEqualsFilter filter) { + return [NSPredicate predicateWithFormat:@"%K != %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; + } + + NSPredicate* operator()(mbgl::style::GreaterThanFilter filter) { + return [NSPredicate predicateWithFormat:@"%K > %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; + } + + NSPredicate* operator()(mbgl::style::GreaterThanEqualsFilter filter) { + return [NSPredicate predicateWithFormat:@"%K >= %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; + } + + NSPredicate* operator()(mbgl::style::LessThanFilter filter) { + return [NSPredicate predicateWithFormat:@"%K < %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; + } + + NSPredicate* operator()(mbgl::style::LessThanEqualsFilter filter) { + return [NSPredicate predicateWithFormat:@"%K <= %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; + } + + NSPredicate* operator()(mbgl::style::InFilter filter) { + return [NSPredicate predicateWithFormat:@"%K IN %@", @(filter.key.c_str()), getValues(filter.values)]; + } + + NSPredicate* operator()(mbgl::style::NotInFilter filter) { + return [NSPredicate predicateWithFormat:@"NOT %K IN %@", @(filter.key.c_str()), getValues(filter.values)]; + } + + NSPredicate* operator()(mbgl::style::AnyFilter filter) { + return [NSCompoundPredicate orPredicateWithSubpredicates:getPredicates(filter.filters)]; + } + + NSPredicate* operator()(mbgl::style::AllFilter filter) { + return [NSCompoundPredicate andPredicateWithSubpredicates:getPredicates(filter.filters)]; + } + + NSPredicate* operator()(mbgl::style::NoneFilter filter) { + NSArray *predicates = getPredicates(filter.filters); + if (predicates.count > 1) { + NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates]; + return [NSCompoundPredicate notPredicateWithSubpredicate:predicate]; + } else { + return [NSCompoundPredicate notPredicateWithSubpredicate:predicates.firstObject]; + } + } + + NSPredicate* operator()(mbgl::style::HasFilter filter) { + [NSException raise:@"Unsupported filter type" + format:@"Cannot convert mbgl::style::HasFilter to NSPredicate"]; + return nil; + } + + NSPredicate* operator()(mbgl::style::NotHasFilter filter) { + [NSException raise:@"Unsupported filter type" + format:@"Cannot convert mbgl::style::NotHasFilter to NSPredicate"]; + return nil; + } + +}; + +@implementation NSPredicate (MGLAdditions) + +- (mbgl::style::Filter)mgl_filter +{ + [NSException raise:@"Not supported" + format:@"NSPredicate doesn't implement ’-mgl_filter’. Try with NSComparisonPredicate or NSCompoundPredicate instead."]; + return {}; +} + ++ (instancetype)mgl_predicateWithFilter:(mbgl::style::Filter)filter +{ + FilterEvaluator evaluator; + return mbgl::style::Filter::visit(filter, evaluator); +} + +@end diff --git a/platform/darwin/test/MGLFilterTests.mm b/platform/darwin/test/MGLFilterTests.mm new file mode 100644 index 00000000000..04cb82fac1d --- /dev/null +++ b/platform/darwin/test/MGLFilterTests.mm @@ -0,0 +1,137 @@ +#import "MGLStyleLayerTests.h" + +#import "NSPredicate+MGLAdditions.h" +#import "MGLValueEvaluator.h" + +@interface MGLFilterTests : MGLStyleLayerTests { + MGLGeoJSONSource *source; + MGLLineStyleLayer *layer; +} +@end + +@implementation MGLFilterTests + +- (void)setUp +{ + [super setUp]; + NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"]; + NSURL *url = [NSURL fileURLWithPath:filePath]; + NSData *geoJSONData = [NSData dataWithContentsOfURL:url]; + source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"test-source" geoJSONData:geoJSONData]; + [self.mapView.style addSource:source]; + layer = [[MGLLineStyleLayer alloc] initWithLayerIdentifier:@"test-layer" sourceIdentifier:@"test-source"]; +} + +- (void)tearDown +{ + [self.mapView.style removeLayer:layer]; + [self.mapView.style removeSource:source]; +} + +- (NSArray *)predicates +{ + NSPredicate *equalPredicate = [NSPredicate predicateWithFormat:@"type == 'neighbourhood'"]; + NSPredicate *notEqualPredicate = [NSPredicate predicateWithFormat:@"type != 'park'"]; + NSPredicate *greaterThanPredicate = [NSPredicate predicateWithFormat:@"%K > %@", @"stroke-width", @2.1]; + NSPredicate *greaterThanOrEqualToPredicate = [NSPredicate predicateWithFormat:@"%K >= %@", @"stroke-width", @2.1]; + NSPredicate *lessThanOrEqualToPredicate = [NSPredicate predicateWithFormat:@"%K <= %@", @"stroke-width", @2.1]; + NSPredicate *lessThanPredicate = [NSPredicate predicateWithFormat:@"%K < %@", @"stroke-width", @2.1]; + NSPredicate *inPredicate = [NSPredicate predicateWithFormat:@"type IN %@", @[@"park", @"neighbourhood"]]; + NSPredicate *notInPredicate = [NSPredicate predicateWithFormat:@"NOT (type IN %@)", @[@"park", @"neighbourhood"]]; + NSPredicate *inNotInPredicate = [NSPredicate predicateWithFormat:@"type IN %@ AND NOT (type IN %@)", @[@"park"], @[@"neighbourhood", @"test"]]; + 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"]; + return @[equalPredicate, + notEqualPredicate, + greaterThanPredicate, + greaterThanOrEqualToPredicate, + lessThanOrEqualToPredicate, + lessThanPredicate, + inPredicate, + notInPredicate, + inNotInPredicate, + typePredicate, + idPredicate, + specialCharsPredicate]; +} + +- (void)testAllPredicates +{ + for (NSPredicate *predicate in self.predicates) { + layer.predicate = predicate; + XCTAssertEqualObjects(layer.predicate, predicate); + } + [self.mapView.style addLayer:layer]; +} + +- (void)testIntermittentEncoding +{ + NSPredicate *specialCharsPredicate = [NSPredicate predicateWithFormat:@"%K == %@", @"ty-’pè", @"sŒm-ethįng"]; + layer.predicate = specialCharsPredicate; + + NSComparisonPredicate *getPredicate = (NSComparisonPredicate *)layer.predicate; + mbgl::style::EqualsFilter filter = layer.predicate.mgl_filter.get(); + + id objcKey = getPredicate.leftExpression.keyPath; + id cppKey = @(filter.key.c_str()); + id objcValue = mbgl::Value::visit(getPredicate.rightExpression.mgl_filterValue, ValueEvaluator()); + id cppValue = mbgl::Value::visit(filter.value, ValueEvaluator()); + + XCTAssertEqualObjects(objcKey, cppKey); + XCTAssertEqualObjects(objcValue, cppValue); + + [self.mapView.style addLayer:layer]; +} + +- (void)testNestedFilters +{ + NSPredicate *equalPredicate = [NSPredicate predicateWithFormat:@"type == 'neighbourhood'"]; + NSPredicate *notEqualPredicate = [NSPredicate predicateWithFormat:@"type != 'park'"]; + + NSPredicate *allPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[equalPredicate, notEqualPredicate]]; + NSPredicate *anyPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[equalPredicate, notEqualPredicate]]; + + layer.predicate = allPredicate; + XCTAssertEqualObjects(layer.predicate, allPredicate); + layer.predicate = anyPredicate; + XCTAssertEqualObjects(layer.predicate, anyPredicate); + + [self.mapView.style addLayer:layer]; +} + +- (void)testAndPredicates +{ + NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:self.predicates]; + layer.predicate = predicate; + XCTAssertEqualObjects(predicate, layer.predicate); + [self.mapView.style addLayer:layer]; +} + +- (void)testOrPredicates +{ + NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:self.predicates]; + layer.predicate = predicate; + XCTAssertEqualObjects(predicate, layer.predicate); + [self.mapView.style addLayer:layer]; +} + +- (void)testNotAndPredicates +{ + NSPredicate *predicates = [NSCompoundPredicate andPredicateWithSubpredicates:self.predicates]; + NSCompoundPredicate *predicate = [NSCompoundPredicate notPredicateWithSubpredicate:predicates]; + layer.predicate = predicate; + XCTAssertEqualObjects(predicate, layer.predicate); + [self.mapView.style addLayer:layer]; +} + +- (void)testNotOrPredicates +{ + NSPredicate *predicates = [NSCompoundPredicate orPredicateWithSubpredicates:self.predicates]; + NSCompoundPredicate *predicate = [NSCompoundPredicate notPredicateWithSubpredicate:predicates]; + layer.predicate = predicate; + XCTAssertEqualObjects(predicate, layer.predicate); + [self.mapView.style addLayer:layer]; +} + +@end diff --git a/platform/ios/test/MGLStyleLayerTests.xib b/platform/darwin/test/MGLStyleLayerTests.xib similarity index 92% rename from platform/ios/test/MGLStyleLayerTests.xib rename to platform/darwin/test/MGLStyleLayerTests.xib index a0947683295..23ad22e7e34 100644 --- a/platform/ios/test/MGLStyleLayerTests.xib +++ b/platform/darwin/test/MGLStyleLayerTests.xib @@ -1,7 +1,7 @@ - - + + - + @@ -15,7 +15,7 @@ - + diff --git a/platform/darwin/test/amsterdam.geojson b/platform/darwin/test/amsterdam.geojson index a0e28a8e9ec..a690f8c8aaf 100644 --- a/platform/darwin/test/amsterdam.geojson +++ b/platform/darwin/test/amsterdam.geojson @@ -162,7 +162,7 @@ "fill": "#555555", "fill-opacity": 0.5, "name": "Jordaan", - "type": "neighborhood", + "type": "neighbourhood", "description": "The Jordan was originally a working-class neighbourhood, and has now become a more upscale neighborhood. It is home to many art galleries, particularly for modern art, and is also dotted with speciality shops and restaurants. Markets are held regularly at Noordermarkt, the Westerstraat and Lindengracht." }, "geometry": { @@ -214,7 +214,7 @@ "fill": "#555555", "fill-opacity": 0.5, "name": "Prinseneiland", - "type": "neighborhood", + "type": "neighbourhood", "description": "Between 1610 and 1615 Prinseneiland was built as an extension of the harbor. Until the end of the 19th century this was an area with many wharfs, little industries and warehouses, related to the shipping trades. After the second World war the desolated area was discovered by many artists, who established their homes and studios in the vacant buildings. During the second half of the 20th century the old warehouses were transformed into apartments one after another, and new apartments were built. Nevertheless a lot of the atmosphere of the glorious past is still present in the old buildings and wooden drawbridges." }, "geometry": { diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 605d6b2da83..bfe3f22382e 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -79,6 +79,29 @@ - (void)viewDidLoad self.debugLoggingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"MGLMapboxMetricsDebugLoggingEnabled"]; } +- (void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView +{ + [mapView setCenterCoordinate:CLLocationCoordinate2DMake(52.36, 4.86) zoomLevel:12 animated:NO]; + +#warning DEBUG CODE + + NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"]; + NSURL *url = [NSURL fileURLWithPath:filePath]; + NSData *geoJSONData = [NSData dataWithContentsOfURL:url]; + MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"source" geoJSONData:geoJSONData]; + [self.mapView.style addSource:source]; + + MGLFillStyleLayer *parksLayer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"park-layer" sourceIdentifier:@"source"]; + parksLayer.fillColor = [UIColor redColor]; + parksLayer.predicate = [NSPredicate predicateWithFormat:@"name == 'Westerpark'"]; + [self.mapView.style addLayer:parksLayer]; + + MGLFillStyleLayer *singleParkLayer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"single-park-layer" sourceIdentifier:@"source"]; + singleParkLayer.fillColor = [UIColor greenColor]; + singleParkLayer.predicate = [NSPredicate predicateWithFormat:@"name == 'vondelpark'"]; + [self.mapView.style addLayer:singleParkLayer]; +} + - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index d3fc36732c6..24e5c16d965 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -37,6 +37,18 @@ 350098DD1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 350098DE1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */; }; 350098DF1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */; }; + 3510FFEA1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */; }; + 3510FFEB1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */; }; + 3510FFEC1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3510FFE91D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm */; }; + 3510FFED1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3510FFE91D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm */; }; + 3510FFF01D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3510FFEE1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h */; }; + 3510FFF11D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3510FFEE1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h */; }; + 3510FFF21D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3510FFEF1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm */; }; + 3510FFF31D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3510FFEF1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm */; }; + 3510FFF91D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3510FFF71D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h */; }; + 3510FFFA1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3510FFF71D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h */; }; + 3510FFFB1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3510FFF81D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm */; }; + 3510FFFC1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3510FFF81D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm */; }; 35136D391D42271A00C20EFD /* MGLBackgroundStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35136D381D42271A00C20EFD /* MGLBackgroundStyleLayer.mm */; }; 35136D3A1D42271A00C20EFD /* MGLBackgroundStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35136D381D42271A00C20EFD /* MGLBackgroundStyleLayer.mm */; }; 35136D3C1D42272500C20EFD /* MGLCircleStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35136D3B1D42272500C20EFD /* MGLCircleStyleLayer.mm */; }; @@ -116,6 +128,11 @@ 3593E5261D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E5251D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h */; }; 3593E5271D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E5251D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h */; }; 359F57461D2FDDA6005217F1 /* MGLUserLocationAnnotationView_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 359F57451D2FDBD5005217F1 /* MGLUserLocationAnnotationView_Private.h */; }; + 35B82BF81D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */; }; + 35B82BF91D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */; }; + 35B82BFA1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35B82BF71D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm */; }; + 35B82BFB1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35B82BF71D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm */; }; + 35B8E08C1D6C8B5100E768D2 /* MGLFilterTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35B8E08B1D6C8B5100E768D2 /* MGLFilterTests.mm */; }; 35CE61821D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35CE61801D4165D9004F2359 /* UIColor+MGLAdditions.h */; }; 35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35CE61801D4165D9004F2359 /* UIColor+MGLAdditions.h */; }; 35CE61841D4165D9004F2359 /* UIColor+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35CE61811D4165D9004F2359 /* UIColor+MGLAdditions.mm */; }; @@ -130,6 +147,8 @@ 35D13AC61D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35D13AC21D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm */; }; 35E0CFE61D3E501500188327 /* MGLStyle_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E0CFE51D3E501500188327 /* MGLStyle_Private.h */; }; 35E0CFE71D3E501500188327 /* MGLStyle_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E0CFE51D3E501500188327 /* MGLStyle_Private.h */; }; + 35E1A4D81D74336F007AA97F /* MGLValueEvaluator.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E1A4D71D74336F007AA97F /* MGLValueEvaluator.h */; }; + 35E1A4D91D74336F007AA97F /* MGLValueEvaluator.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E1A4D71D74336F007AA97F /* MGLValueEvaluator.h */; }; 35E208A71D24210F00EC9A46 /* MGLNSDataAdditionsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */; }; 35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */; }; 35E79F211D41266300957B9E /* MGLStyleLayer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */; }; @@ -474,6 +493,12 @@ 350098D71D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MGLStyleAttributeAdditions_Private.h"; sourceTree = ""; }; 350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MGLStyleAttributeAdditions.h"; sourceTree = ""; }; 350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSValue+MGLStyleAttributeAdditions.mm"; sourceTree = ""; }; + 3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSComparisonPredicate+MGLAdditions.h"; sourceTree = ""; }; + 3510FFE91D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSComparisonPredicate+MGLAdditions.mm"; sourceTree = ""; }; + 3510FFEE1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLAdditions.h"; sourceTree = ""; }; + 3510FFEF1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSExpression+MGLAdditions.mm"; sourceTree = ""; }; + 3510FFF71D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCompoundPredicate+MGLAdditions.h"; sourceTree = ""; }; + 3510FFF81D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSCompoundPredicate+MGLAdditions.mm"; sourceTree = ""; }; 35136D381D42271A00C20EFD /* MGLBackgroundStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLBackgroundStyleLayer.mm; sourceTree = ""; }; 35136D3B1D42272500C20EFD /* MGLCircleStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCircleStyleLayer.mm; sourceTree = ""; }; 35136D3E1D42273000C20EFD /* MGLLineStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLineStyleLayer.mm; sourceTree = ""; }; @@ -521,6 +546,9 @@ 3593E5201D529C29006D9365 /* MGLStyleAttribute.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttribute.mm; sourceTree = ""; }; 3593E5251D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+MGLStyleAttributeAdditions_Private.h"; sourceTree = ""; }; 359F57451D2FDBD5005217F1 /* MGLUserLocationAnnotationView_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLUserLocationAnnotationView_Private.h; sourceTree = ""; }; + 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPredicate+MGLAdditions.h"; sourceTree = ""; }; + 35B82BF71D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSPredicate+MGLAdditions.mm"; sourceTree = ""; }; + 35B8E08B1D6C8B5100E768D2 /* MGLFilterTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLFilterTests.mm; path = ../../darwin/test/MGLFilterTests.mm; sourceTree = ""; }; 35CE61801D4165D9004F2359 /* UIColor+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+MGLAdditions.h"; sourceTree = ""; }; 35CE61811D4165D9004F2359 /* UIColor+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UIColor+MGLAdditions.mm"; sourceTree = ""; }; 35D13AB51D3D15E300AFB4E0 /* MGLStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer.h; sourceTree = ""; }; @@ -528,6 +556,7 @@ 35D13AC11D3D19DD00AFB4E0 /* MGLFillStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFillStyleLayer.h; sourceTree = ""; }; 35D13AC21D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFillStyleLayer.mm; sourceTree = ""; }; 35E0CFE51D3E501500188327 /* MGLStyle_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyle_Private.h; sourceTree = ""; }; + 35E1A4D71D74336F007AA97F /* MGLValueEvaluator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLValueEvaluator.h; sourceTree = ""; }; 35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNSDataAdditionsTests.m; sourceTree = ""; }; 35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer_Private.h; sourceTree = ""; }; 36F1153B1D46080700878E1A /* libmbgl-core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-core.a"; path = "build/Debug-iphoneos/libmbgl-core.a"; sourceTree = ""; }; @@ -850,6 +879,7 @@ isa = PBXGroup; children = ( 3575798F1D513EF1000B822E /* Layers */, + 35B8E08B1D6C8B5100E768D2 /* MGLFilterTests.mm */, ); name = Styling; sourceTree = ""; @@ -1038,6 +1068,7 @@ DA8847EE1CBAFA5100AB86E3 /* MGLTypes.h */, DA8848111CBAFA6200AB86E3 /* MGLTypes.m */, DA8848911CBB049300AB86E3 /* reachability */, + 35E1A4D71D74336F007AA97F /* MGLValueEvaluator.h */, ); name = Foundation; path = ../darwin/src; @@ -1262,6 +1293,14 @@ DAED38621D62D0FC00D7640F /* NSURL+MGLAdditions.m */, DA35A2C71CCAAAD200E826B2 /* NSValue+MGLAdditions.h */, DA35A2C81CCAAAD200E826B2 /* NSValue+MGLAdditions.m */, + 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */, + 35B82BF71D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm */, + 3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */, + 3510FFE91D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm */, + 3510FFEE1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h */, + 3510FFEF1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm */, + 3510FFF71D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h */, + 3510FFF81D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm */, ); name = Categories; sourceTree = ""; @@ -1324,6 +1363,7 @@ 3593E5211D529C29006D9365 /* MGLStyleAttribute.h in Headers */, 35599DEB1D46F14E0048254D /* MGLStyleAttributeFunction.h in Headers */, 4018B1C91CDC288A00F666AF /* MGLAnnotationView_Private.h in Headers */, + 35E1A4D81D74336F007AA97F /* MGLValueEvaluator.h in Headers */, DA88482C1CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h in Headers */, 35D13AB71D3D15E300AFB4E0 /* MGLStyleLayer.h in Headers */, 354D42DC1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h in Headers */, @@ -1333,6 +1373,7 @@ 404326891D5B9B27007111BD /* MGLAnnotationContainerView_Private.h in Headers */, DA88483B1CBAFB8500AB86E3 /* MGLCalloutView.h in Headers */, 35E0CFE61D3E501500188327 /* MGLStyle_Private.h in Headers */, + 3510FFF01D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */, 353AFA141D65AB17005A69F4 /* NSDate+MGLAdditions.h in Headers */, DAB4F8301D63DD7600E27738 /* MGLBaseStyleLayer_Private.h in Headers */, 3593E5261D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h in Headers */, @@ -1347,13 +1388,14 @@ DA8847F01CBAFA5100AB86E3 /* MGLAnnotation.h in Headers */, DA88483E1CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */, 4018B1CA1CDC288E00F666AF /* MGLAnnotationView.h in Headers */, - 35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */, 350098C61D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h in Headers */, + 35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */, 353933FB1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h in Headers */, DA8847EF1CBAFA5100AB86E3 /* MGLAccountManager.h in Headers */, DA8848511CBAFB9800AB86E3 /* MGLAPIClient.h in Headers */, DA35A2C91CCAAAD200E826B2 /* NSValue+MGLAdditions.h in Headers */, 350098CF1D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h in Headers */, + 3510FFEA1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */, DA8848571CBAFB9800AB86E3 /* MGLMapboxEvents.h in Headers */, DA8848311CBAFA6200AB86E3 /* NSString+MGLAdditions.h in Headers */, 353933F81D3FB79F003F57D7 /* MGLLineStyleLayer.h in Headers */, @@ -1369,6 +1411,7 @@ DA88481E1CBAFA6200AB86E3 /* MGLMultiPoint_Private.h in Headers */, 3566C7661D4A77BA008152BC /* MGLGeoJSONSource.h in Headers */, 35CE61821D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */, + 35B82BF81D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h in Headers */, DA35A29E1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */, DA8847F71CBAFA5100AB86E3 /* MGLOverlay.h in Headers */, DA35A2B11CCA141D00E826B2 /* MGLCompassDirectionFormatter.h in Headers */, @@ -1395,6 +1438,7 @@ DA88481B1CBAFA6200AB86E3 /* MGLGeometry_Private.h in Headers */, 350098CA1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h in Headers */, 350098AF1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h in Headers */, + 3510FFF91D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */, DA88485C1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h in Headers */, DA8848871CBB033F00AB86E3 /* Fabric.h in Headers */, 350098D81D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */, @@ -1416,6 +1460,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 35B82BF91D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h in Headers */, DA35A2CA1CCAAAD200E826B2 /* NSValue+MGLAdditions.h in Headers */, 350098BC1D480108004B2AF0 /* MGLVectorSource.h in Headers */, 353933FC1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h in Headers */, @@ -1431,6 +1476,7 @@ DA35A29F1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */, DABFB8711CBE9A0F00D62B32 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */, DABFB8611CBE99E500D62B32 /* MGLMultiPoint.h in Headers */, + 3510FFF11D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */, 35E0CFE71D3E501500188327 /* MGLStyle_Private.h in Headers */, DAB4F8311D63DD7600E27738 /* MGLBaseStyleLayer_Private.h in Headers */, DABFB86D1CBE9A0F00D62B32 /* MGLAnnotationImage.h in Headers */, @@ -1446,9 +1492,12 @@ 350098C21D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h in Headers */, DABFB8691CBE99E500D62B32 /* MGLShape.h in Headers */, 350098CB1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h in Headers */, + 3510FFEB1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */, + 35E1A4D91D74336F007AA97F /* MGLValueEvaluator.h in Headers */, DABFB8701CBE9A0F00D62B32 /* MGLMapView+IBAdditions.h in Headers */, 353AFA151D65AB17005A69F4 /* NSDate+MGLAdditions.h in Headers */, 350098D91D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */, + 3510FFFA1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */, 35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */, 350098B01D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h in Headers */, DABFB8671CBE99E500D62B32 /* MGLPolygon.h in Headers */, @@ -1798,6 +1847,7 @@ 357579871D502AFE000B822E /* MGLLineStyleLayerTests.m in Sources */, 357579891D502B06000B822E /* MGLCircleStyleLayerTests.m in Sources */, DA35A2C51CCA9F8300E826B2 /* MGLClockDirectionFormatterTests.m in Sources */, + 35B8E08C1D6C8B5100E768D2 /* MGLFilterTests.mm in Sources */, 3575798B1D502B0C000B822E /* MGLBackgroundStyleLayerTests.m in Sources */, DA2E88621CC0382C00F24E7B /* MGLOfflinePackTests.m in Sources */, DA35A2AA1CCA058D00E826B2 /* MGLCoordinateFormatterTests.m in Sources */, @@ -1813,6 +1863,7 @@ buildActionMask = 2147483647; files = ( 35136D391D42271A00C20EFD /* MGLBackgroundStyleLayer.mm in Sources */, + 3510FFEC1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */, 350098D51D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm in Sources */, 3593E5231D529C29006D9365 /* MGLStyleAttribute.mm in Sources */, 350098B11D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm in Sources */, @@ -1852,11 +1903,13 @@ 35305D481D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */, DA8848291CBAFA6200AB86E3 /* MGLStyle.mm in Sources */, DA88481C1CBAFA6200AB86E3 /* MGLGeometry.mm in Sources */, + 3510FFF21D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm in Sources */, DA88481F1CBAFA6200AB86E3 /* MGLMultiPoint.mm in Sources */, DA88482B1CBAFA6200AB86E3 /* MGLTypes.m in Sources */, 4018B1C71CDC287F00F666AF /* MGLAnnotationView.mm in Sources */, DA88481D1CBAFA6200AB86E3 /* MGLMapCamera.mm in Sources */, DA8848261CBAFA6200AB86E3 /* MGLPolygon.mm in Sources */, + 35B82BFA1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */, DA8848521CBAFB9800AB86E3 /* MGLAPIClient.m in Sources */, DA8848301CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.m in Sources */, 353AFA161D65AB17005A69F4 /* NSDate+MGLAdditions.mm in Sources */, @@ -1865,6 +1918,7 @@ DA88482A1CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm in Sources */, 35136D3F1D42273000C20EFD /* MGLLineStyleLayer.mm in Sources */, DA88481A1CBAFA6200AB86E3 /* MGLAccountManager.m in Sources */, + 3510FFFB1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */, DA8848271CBAFA6200AB86E3 /* MGLPolyline.mm in Sources */, DA8848581CBAFB9800AB86E3 /* MGLMapboxEvents.m in Sources */, 35CE61841D4165D9004F2359 /* UIColor+MGLAdditions.mm in Sources */, @@ -1877,6 +1931,7 @@ buildActionMask = 2147483647; files = ( 35136D3A1D42271A00C20EFD /* MGLBackgroundStyleLayer.mm in Sources */, + 3510FFED1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */, 350098D61D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm in Sources */, 354B83991D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */, DAA4E4221CBB730400178DFB /* MGLPointAnnotation.m in Sources */, @@ -1916,11 +1971,13 @@ DA35A2A21CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */, 35305D491D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */, DAA4E42D1CBB730400178DFB /* MGLAnnotationImage.m in Sources */, + 3510FFF31D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm in Sources */, DAA4E4301CBB730400178DFB /* MGLLocationManager.m in Sources */, DAA4E4321CBB730400178DFB /* MGLMapView.mm in Sources */, DAA4E41E1CBB730400178DFB /* MGLMapCamera.mm in Sources */, 4018B1C81CDC287F00F666AF /* MGLAnnotationView.mm in Sources */, DAA4E4341CBB730400178DFB /* MGLFaux3DUserLocationAnnotationView.m in Sources */, + 35B82BFB1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */, DAA4E4311CBB730400178DFB /* MGLMapboxEvents.m in Sources */, DAA4E4231CBB730400178DFB /* MGLPolygon.mm in Sources */, 353AFA171D65AB17005A69F4 /* NSDate+MGLAdditions.mm in Sources */, @@ -1929,6 +1986,7 @@ DAA4E4211CBB730400178DFB /* MGLOfflineStorage.mm in Sources */, 35136D401D42273000C20EFD /* MGLLineStyleLayer.mm in Sources */, DAA4E42F1CBB730400178DFB /* MGLCompactCalloutView.m in Sources */, + 3510FFFC1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */, DAA4E4271CBB730400178DFB /* MGLTilePyramidOfflineRegion.mm in Sources */, DAA4E41C1CBB730400178DFB /* MGLAccountManager.m in Sources */, 35CE61851D4165D9004F2359 /* UIColor+MGLAdditions.mm in Sources */, diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 3bb8f5872e4..8d24b35b6ac 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -508,7 +508,8 @@ - (IBAction)manipulateStyle:(id)sender { [self.mapView.style addSource:source]; MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"test" sourceIdentifier:@"ams"]; - fillLayer.fillColor = [NSColor purpleColor]; + fillLayer.fillColor = [NSColor greenColor]; + fillLayer.predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"type", @"park"]; [self.mapView.style addLayer:fillLayer]; } diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index f53ec41f904..2fb0630ea81 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 3508EC641D749D39009B0EE4 /* NSExpression+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */; }; + 3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */; }; 352742781D4C220900A1ECE6 /* MGLStyleAttributeValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 352742771D4C220900A1ECE6 /* MGLStyleAttributeValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3527427C1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3527427A1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3527427D1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3527427B1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m */; }; @@ -21,6 +23,8 @@ 3527429F1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3527429C1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h */; }; 352742A01D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 3527429D1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h */; settings = {ATTRIBUTES = (Public, ); }; }; 352742A11D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3527429E1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm */; }; + 3529039B1D6C63B80002C7DF /* NSPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 352903991D6C63B80002C7DF /* NSPredicate+MGLAdditions.h */; }; + 3529039C1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3529039A1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm */; }; 3537CA741D3F93A600380318 /* MGLStyle_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3537CA731D3F93A600380318 /* MGLStyle_Private.h */; }; 3538AA231D542685008EC33D /* MGLBaseStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3538AA211D542685008EC33D /* MGLBaseStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3538AA241D542685008EC33D /* MGLBaseStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3538AA221D542685008EC33D /* MGLBaseStyleLayer.mm */; }; @@ -36,6 +40,10 @@ 3593E52A1D52A628006D9365 /* MGLStyleAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E5281D52A628006D9365 /* MGLStyleAttribute.h */; }; 3593E52B1D52A628006D9365 /* MGLStyleAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3593E5291D52A628006D9365 /* MGLStyleAttribute.mm */; }; 3593E52D1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E52C1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h */; }; + 35C5D8471D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35C5D8431D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h */; }; + 35C5D8481D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35C5D8441D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm */; }; + 35C5D8491D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35C5D8451D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h */; }; + 35C5D84A1D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35C5D8461D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm */; }; 35D65C5A1D65AD5500722C23 /* NSDate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */; }; 35D65C5B1D65AD5500722C23 /* NSDate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */; }; 52BECB0A1CC5A26F009CD791 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52BECB091CC5A26F009CD791 /* SystemConfiguration.framework */; }; @@ -207,6 +215,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLAdditions.h"; sourceTree = ""; }; + 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSExpression+MGLAdditions.mm"; sourceTree = ""; }; 352742771D4C220900A1ECE6 /* MGLStyleAttributeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeValue.h; sourceTree = ""; }; 3527427A1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+MGLStyleAttributeAdditions.h"; sourceTree = ""; }; 3527427B1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+MGLStyleAttributeAdditions.m"; sourceTree = ""; }; @@ -221,6 +231,8 @@ 3527429C1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeFunction_Private.h; sourceTree = ""; }; 3527429D1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeFunction.h; sourceTree = ""; }; 3527429E1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttributeFunction.mm; sourceTree = ""; }; + 352903991D6C63B80002C7DF /* NSPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPredicate+MGLAdditions.h"; sourceTree = ""; }; + 3529039A1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSPredicate+MGLAdditions.mm"; sourceTree = ""; }; 3537CA731D3F93A600380318 /* MGLStyle_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyle_Private.h; sourceTree = ""; }; 3538AA211D542685008EC33D /* MGLBaseStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLBaseStyleLayer.h; sourceTree = ""; }; 3538AA221D542685008EC33D /* MGLBaseStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLBaseStyleLayer.mm; sourceTree = ""; }; @@ -235,6 +247,11 @@ 3593E5281D52A628006D9365 /* MGLStyleAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttribute.h; sourceTree = ""; }; 3593E5291D52A628006D9365 /* MGLStyleAttribute.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttribute.mm; sourceTree = ""; }; 3593E52C1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+MGLStyleAttributeAdditions_Private.h"; sourceTree = ""; }; + 35C5D8431D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSComparisonPredicate+MGLAdditions.h"; sourceTree = ""; }; + 35C5D8441D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSComparisonPredicate+MGLAdditions.mm"; sourceTree = ""; }; + 35C5D8451D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCompoundPredicate+MGLAdditions.h"; sourceTree = ""; }; + 35C5D8461D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSCompoundPredicate+MGLAdditions.mm"; sourceTree = ""; }; + 35C5D84B1D6DD75B00E95907 /* MGLFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLFilterTests.m; path = ../../darwin/test/MGLFilterTests.m; sourceTree = ""; }; 35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+MGLAdditions.h"; sourceTree = ""; }; 35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDate+MGLAdditions.mm"; sourceTree = ""; }; 52BECB091CC5A26F009CD791 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; @@ -613,9 +630,10 @@ isa = PBXGroup; children = ( DA8F257C1D51C5F40010E6B5 /* Layers */, + 35C5D84B1D6DD75B00E95907 /* MGLFilterTests.m */, ); name = Styling; - path = ../../ios/test; + path = ../../darwin/test; sourceTree = ""; }; DA8F25B81D51D2280010E6B5 /* Foundation Templates */ = { @@ -692,9 +710,17 @@ children = ( DAE6C37D1CC31E2A00DB3429 /* NSBundle+MGLAdditions.h */, DAE6C37E1CC31E2A00DB3429 /* NSBundle+MGLAdditions.m */, + 35C5D8431D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h */, + 35C5D8441D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm */, + 35C5D8451D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h */, + 35C5D8461D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm */, 35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */, 35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */, DAE6C37F1CC31E2A00DB3429 /* NSException+MGLAdditions.h */, + 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */, + 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */, + 352903991D6C63B80002C7DF /* NSPredicate+MGLAdditions.h */, + 3529039A1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm */, DAE6C3801CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.h */, DAE6C3811CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.m */, DAE6C3821CC31E2A00DB3429 /* NSString+MGLAdditions.h */, @@ -821,6 +847,7 @@ files = ( 3593E52D1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h in Headers */, DA8F258F1D51CA600010E6B5 /* MGLRasterStyleLayer.h in Headers */, + 3508EC641D749D39009B0EE4 /* NSExpression+MGLAdditions.h in Headers */, DAE6C38D1CC31E2A00DB3429 /* MGLOfflineRegion_Private.h in Headers */, DA8F25AB1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions_Private.h in Headers */, DA8F259C1D51CB000010E6B5 /* MGLStyleAttributeValue_Private.h in Headers */, @@ -829,6 +856,7 @@ DAE6C3B61CC31EF300DB3429 /* MGLMapView_Private.h in Headers */, 3527428D1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.h in Headers */, DAE6C3B21CC31EF300DB3429 /* MGLAttributionButton.h in Headers */, + 35C5D8471D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h in Headers */, DAE6C3A31CC31E9400DB3429 /* MGLAnnotationImage.h in Headers */, DAE6C3A41CC31E9400DB3429 /* MGLMapView.h in Headers */, 352742A01D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h in Headers */, @@ -845,6 +873,7 @@ DAC2ABC51CC6D343006D18C4 /* MGLAnnotationImage_Private.h in Headers */, DAE6C35F1CC31E0400DB3429 /* MGLOfflinePack.h in Headers */, DAE6C39C1CC31E2A00DB3429 /* NSString+MGLAdditions.h in Headers */, + 3529039B1D6C63B80002C7DF /* NSPredicate+MGLAdditions.h in Headers */, DA8F25971D51CAC70010E6B5 /* MGLVectorSource.h in Headers */, DAE6C3861CC31E2A00DB3429 /* MGLGeometry_Private.h in Headers */, DAE6C3841CC31E2A00DB3429 /* MGLAccountManager_Private.h in Headers */, @@ -862,6 +891,7 @@ DA35A2A41CC9EB1A00E826B2 /* MGLCoordinateFormatter.h in Headers */, DA8F25B11D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */, 3593E52A1D52A628006D9365 /* MGLStyleAttribute.h in Headers */, + 35C5D8491D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h in Headers */, DAE6C3621CC31E0400DB3429 /* MGLOverlay.h in Headers */, DAE6C3651CC31E0400DB3429 /* MGLPolyline.h in Headers */, DAE6C39A1CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.h in Headers */, @@ -1083,6 +1113,7 @@ DAE6C38C1CC31E2A00DB3429 /* MGLOfflinePack.mm in Sources */, 35D65C5B1D65AD5500722C23 /* NSDate+MGLAdditions.mm in Sources */, DAE6C3B11CC31EF300DB3429 /* MGLAnnotationImage.m in Sources */, + 3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */, DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */, 355BA4EE1D41633E00CCC6D5 /* NSColor+MGLAdditions.mm in Sources */, DAE6C3B31CC31EF300DB3429 /* MGLAttributionButton.m in Sources */, @@ -1111,6 +1142,7 @@ DAE6C39B1CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.m in Sources */, DAE6C38F1CC31E2A00DB3429 /* MGLOfflineStorage.mm in Sources */, DAED38601D62CED700D7640F /* NSURL+MGLAdditions.m in Sources */, + 35C5D84A1D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm in Sources */, DAE6C3951CC31E2A00DB3429 /* MGLTilePyramidOfflineRegion.mm in Sources */, 3593E52B1D52A628006D9365 /* MGLStyleAttribute.mm in Sources */, DAE6C3851CC31E2A00DB3429 /* MGLAccountManager.m in Sources */, @@ -1120,10 +1152,12 @@ DAE6C3B51CC31EF300DB3429 /* MGLCompassCell.m in Sources */, DA8F25901D51CA600010E6B5 /* MGLRasterStyleLayer.mm in Sources */, DAD165751CF4CD7A001FF4B9 /* MGLShapeCollection.m in Sources */, + 35C5D8481D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm in Sources */, DA35A2AE1CCA091800E826B2 /* MGLCompassDirectionFormatter.m in Sources */, DA8F258C1D51CA540010E6B5 /* MGLLineStyleLayer.mm in Sources */, DA8F25AD1D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.mm in Sources */, DA8F25941D51CA750010E6B5 /* MGLSymbolStyleLayer.mm in Sources */, + 3529039C1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm in Sources */, DA8F25981D51CAC70010E6B5 /* MGLVectorSource.mm in Sources */, 352742A11D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm in Sources */, ); From 7e208c46cebe5b49d4b7ead9826bbe4229ebabd3 Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Thu, 1 Sep 2016 06:48:36 -0700 Subject: [PATCH 2/2] [ios] Check for bool value with char We convert NSNumbers (and NSStrings) to the appropriate mbgl value so that we can use NSPredicates to describe mbgl filters we want to apply to style layers at runtime. This change fixes an issue where the conversion from an NSNumber that represented a bool was not recognized as such. encode(bool) returns a 'c' or 'b' on 32 bit and 64 bit systems respectively and objCType of an NSNumber representing a bool always returns 'c'. Now the implementation checks for 'c' always and NSNumbers representing bool don't fall through and trigger the exception. --- platform/darwin/src/NSExpression+MGLAdditions.mm | 2 +- platform/darwin/test/MGLFilterTests.mm | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm index 5f1a1e765a3..129c9a740cf 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -31,7 +31,7 @@ @implementation NSExpression (MGLAdditions) return { number.intValue }; } else if ((strcmp([number objCType], @encode(double))) == 0) { return { number.doubleValue }; - } else if ((strcmp([number objCType], @encode(bool))) == 0) { + } else if ((strcmp([number objCType], @encode(char))) == 0) { return { number.boolValue }; } } diff --git a/platform/darwin/test/MGLFilterTests.mm b/platform/darwin/test/MGLFilterTests.mm index 04cb82fac1d..5b102e2e86f 100644 --- a/platform/darwin/test/MGLFilterTests.mm +++ b/platform/darwin/test/MGLFilterTests.mm @@ -42,6 +42,7 @@ - (void)tearDown 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, notEqualPredicate, greaterThanPredicate, @@ -53,7 +54,8 @@ - (void)tearDown inNotInPredicate, typePredicate, idPredicate, - specialCharsPredicate]; + specialCharsPredicate, + booleanPredicate]; } - (void)testAllPredicates