diff options
author | Fredrik Karlsson <bjorn.fredrik.karlsson@gmail.com> | 2016-08-17 13:38:02 +0200 |
---|---|---|
committer | Fredrik Karlsson <bjorn.fredrik.karlsson@gmail.com> | 2016-09-02 22:42:05 +0200 |
commit | d77a13eb7320722c48c8a18240adf99615c4b85f (patch) | |
tree | 1017781b310e434f943e4ad38b57f319ad7a3a58 | |
parent | 6a39cf5aaece81c7a531b12321dd503004cc45b8 (diff) | |
download | qtlocation-mapboxgl-d77a13eb7320722c48c8a18240adf99615c4b85f.tar.gz |
[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
28 files changed, 724 insertions, 56 deletions
diff --git a/platform/darwin/src/MGLBaseStyleLayer_Private.h b/platform/darwin/src/MGLBaseStyleLayer_Private.h index e3d43906a4..0cbb076b35 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 7d2ef05848..e4430044ad 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 <MGLStyleLayer> +/** + A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>. + + 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 27be01505c..6c038318cc 100644 --- a/platform/darwin/src/MGLCircleStyleLayer.mm +++ b/platform/darwin/src/MGLCircleStyleLayer.mm @@ -29,6 +29,16 @@ 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 <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)circleRadius { diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm index 3bf1e61153..6d4f76a71d 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 @@ @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<mbgl::Value> &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<std::string, mbgl::Value> &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 @@ NS_ARRAY_OF(MGLShape <MGLFeature> *) *MGLFeaturesFromMBGLFeatures(const std::vec 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<double> evaluator; MGLShape <MGLFeaturePrivate> *shape = mapbox::geometry::geometry<double>::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 c03e8ecae1..2d51f071e5 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 <MGLStyleLayer> +/** + A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>. + + 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 192235f69e..c54ddba428 100644 --- a/platform/darwin/src/MGLFillStyleLayer.mm +++ b/platform/darwin/src/MGLFillStyleLayer.mm @@ -29,6 +29,16 @@ 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 <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)fillAntialias { diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h index 435829c502..5c2a3afc2e 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 <MGLStyleLayer> +/** + A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>. + + 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 ffb0d4e394..ce9ad75f87 100644 --- a/platform/darwin/src/MGLLineStyleLayer.mm +++ b/platform/darwin/src/MGLLineStyleLayer.mm @@ -29,6 +29,16 @@ 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 <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineCap { diff --git a/platform/darwin/src/MGLStyleLayer.h.ejs b/platform/darwin/src/MGLStyleLayer.h.ejs index 2b36a3067a..8acda024c4 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 <MGLStyleLayer> +<% if (type !== 'background' && type !== 'raster') { -%> +/** + A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>. + + 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) { -%> @@ -69,6 +80,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 NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs index c35d254caf..4e59c3c6cb 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 ef88ff996e..eacd158dda 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 <MGLStyleLayer> +/** + A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>. + + 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 159e3c4d0b..b0553ea425 100644 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ b/platform/darwin/src/MGLSymbolStyleLayer.mm @@ -29,6 +29,16 @@ 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 <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)symbolPlacement { diff --git a/platform/darwin/src/MGLValueEvaluator.h b/platform/darwin/src/MGLValueEvaluator.h new file mode 100644 index 0000000000..b53cdaa8d2 --- /dev/null +++ b/platform/darwin/src/MGLValueEvaluator.h @@ -0,0 +1,49 @@ +#import <Foundation/Foundation.h> + +#import <mbgl/util/geometry.hpp> + +/** + 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<mbgl::Value> &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<std::string, mbgl::Value> &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 0000000000..2cd4dd1577 --- /dev/null +++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.h @@ -0,0 +1,7 @@ +#import <Foundation/Foundation.h> + +#include <mbgl/style/filter.hpp> + +@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 0000000000..ced6a1ac47 --- /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 0000000000..0f9909255d --- /dev/null +++ b/platform/darwin/src/NSCompoundPredicate+MGLAdditions.h @@ -0,0 +1,7 @@ +#import <Foundation/Foundation.h> + +#include <mbgl/style/filter.hpp> + +@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 0000000000..07114308c9 --- /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<mbgl::style::Filter>)mgl_subfilters +{ + std::vector<mbgl::style::Filter>filters; + 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<NSComparisonPredicate *> *comparisonPredicates = [self.subpredicates filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"class == %@", [NSComparisonPredicate class]]]; + NSArray<NSComparisonPredicate *> *notInPredicates = [comparisonPredicates filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSComparisonPredicate *_Nonnull predicate, NSDictionary<NSString *,id> * _Nullable bindings) { + return predicate.predicateOperatorType == NSInPredicateOperatorType; + }]]; + + 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 0000000000..4e8c5ee071 --- /dev/null +++ b/platform/darwin/src/NSExpression+MGLAdditions.h @@ -0,0 +1,11 @@ +#import <Foundation/Foundation.h> + +#include <mbgl/style/filter.hpp> + +@interface NSExpression (MGLAdditions) + +- (mbgl::Value)mgl_filterValue; + +- (std::vector<mbgl::Value>)mgl_filterValues; + +@end diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm new file mode 100644 index 0000000000..5f1a1e765a --- /dev/null +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -0,0 +1,43 @@ +#import "NSExpression+MGLAdditions.h" + +@implementation NSExpression (MGLAdditions) + +- (std::vector<mbgl::Value>)mgl_filterValues +{ + if ([self.constantValue isKindOfClass:NSArray.class]) { + NSArray *values = self.constantValue; + std::vector<mbgl::Value>convertedValues; + 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 0000000000..fd774dd58b --- /dev/null +++ b/platform/darwin/src/NSPredicate+MGLAdditions.h @@ -0,0 +1,13 @@ +#import <Foundation/Foundation.h> + +#import "NSExpression+MGLAdditions.h" +#include <mbgl/style/filter.hpp> + +@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 0000000000..9c3f9c888c --- /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<mbgl::style::Filter> 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<mbgl::Value> 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 0000000000..04cb82fac1 --- /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<NSPredicate *> *)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<mbgl::style::EqualsFilter>(); + + 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 index a094768329..23ad22e7e3 100644 --- a/platform/ios/test/MGLStyleLayerTests.xib +++ b/platform/darwin/test/MGLStyleLayerTests.xib @@ -1,7 +1,7 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11185.3" systemVersion="15G31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> +<?xml version="1.0" encoding="UTF-8"?> +<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="16A304a" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <dependencies> - <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11185.3"/> + <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/> </dependencies> <objects> <customObject id="-2" userLabel="File's Owner" customClass="MGLStyleLayerTests"> @@ -15,7 +15,7 @@ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <rect key="contentRect" x="196" y="240" width="256" height="256"/> - <rect key="screenRect" x="0.0" y="0.0" width="1280" height="777"/> + <rect key="screenRect" x="0.0" y="0.0" width="1920" height="1058"/> <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ"> <rect key="frame" x="0.0" y="0.0" width="256" height="256"/> <autoresizingMask key="autoresizingMask"/> diff --git a/platform/darwin/test/amsterdam.geojson b/platform/darwin/test/amsterdam.geojson index a0e28a8e9e..a690f8c8aa 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 605d6b2da8..bfe3f22382 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -79,6 +79,29 @@ static NSString * const MBXViewControllerAnnotationViewReuseIdentifer = @"MBXVie 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 d3fc36732c..24e5c16d96 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 = "<group>"; }; 350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; }; 350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSValue+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; }; + 3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSComparisonPredicate+MGLAdditions.h"; sourceTree = "<group>"; }; + 3510FFE91D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSComparisonPredicate+MGLAdditions.mm"; sourceTree = "<group>"; }; + 3510FFEE1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLAdditions.h"; sourceTree = "<group>"; }; + 3510FFEF1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSExpression+MGLAdditions.mm"; sourceTree = "<group>"; }; + 3510FFF71D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCompoundPredicate+MGLAdditions.h"; sourceTree = "<group>"; }; + 3510FFF81D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSCompoundPredicate+MGLAdditions.mm"; sourceTree = "<group>"; }; 35136D381D42271A00C20EFD /* MGLBackgroundStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLBackgroundStyleLayer.mm; sourceTree = "<group>"; }; 35136D3B1D42272500C20EFD /* MGLCircleStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCircleStyleLayer.mm; sourceTree = "<group>"; }; 35136D3E1D42273000C20EFD /* MGLLineStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLineStyleLayer.mm; sourceTree = "<group>"; }; @@ -521,6 +546,9 @@ 3593E5201D529C29006D9365 /* MGLStyleAttribute.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttribute.mm; sourceTree = "<group>"; }; 3593E5251D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; }; 359F57451D2FDBD5005217F1 /* MGLUserLocationAnnotationView_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLUserLocationAnnotationView_Private.h; sourceTree = "<group>"; }; + 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPredicate+MGLAdditions.h"; sourceTree = "<group>"; }; + 35B82BF71D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSPredicate+MGLAdditions.mm"; sourceTree = "<group>"; }; + 35B8E08B1D6C8B5100E768D2 /* MGLFilterTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLFilterTests.mm; path = ../../darwin/test/MGLFilterTests.mm; sourceTree = "<group>"; }; 35CE61801D4165D9004F2359 /* UIColor+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+MGLAdditions.h"; sourceTree = "<group>"; }; 35CE61811D4165D9004F2359 /* UIColor+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "UIColor+MGLAdditions.mm"; sourceTree = "<group>"; }; 35D13AB51D3D15E300AFB4E0 /* MGLStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer.h; sourceTree = "<group>"; }; @@ -528,6 +556,7 @@ 35D13AC11D3D19DD00AFB4E0 /* MGLFillStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFillStyleLayer.h; sourceTree = "<group>"; }; 35D13AC21D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFillStyleLayer.mm; sourceTree = "<group>"; }; 35E0CFE51D3E501500188327 /* MGLStyle_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyle_Private.h; sourceTree = "<group>"; }; + 35E1A4D71D74336F007AA97F /* MGLValueEvaluator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLValueEvaluator.h; sourceTree = "<group>"; }; 35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNSDataAdditionsTests.m; sourceTree = "<group>"; }; 35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer_Private.h; sourceTree = "<group>"; }; 36F1153B1D46080700878E1A /* libmbgl-core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-core.a"; path = "build/Debug-iphoneos/libmbgl-core.a"; sourceTree = "<group>"; }; @@ -850,6 +879,7 @@ isa = PBXGroup; children = ( 3575798F1D513EF1000B822E /* Layers */, + 35B8E08B1D6C8B5100E768D2 /* MGLFilterTests.mm */, ); name = Styling; sourceTree = "<group>"; @@ -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 = "<group>"; @@ -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 3bb8f5872e..8d24b35b6a 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -508,7 +508,8 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio [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 f53ec41f90..2fb0630ea8 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 = "<group>"; }; + 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSExpression+MGLAdditions.mm"; sourceTree = "<group>"; }; 352742771D4C220900A1ECE6 /* MGLStyleAttributeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeValue.h; sourceTree = "<group>"; }; 3527427A1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; }; 3527427B1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+MGLStyleAttributeAdditions.m"; sourceTree = "<group>"; }; @@ -221,6 +231,8 @@ 3527429C1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeFunction_Private.h; sourceTree = "<group>"; }; 3527429D1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeFunction.h; sourceTree = "<group>"; }; 3527429E1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttributeFunction.mm; sourceTree = "<group>"; }; + 352903991D6C63B80002C7DF /* NSPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPredicate+MGLAdditions.h"; sourceTree = "<group>"; }; + 3529039A1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSPredicate+MGLAdditions.mm"; sourceTree = "<group>"; }; 3537CA731D3F93A600380318 /* MGLStyle_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyle_Private.h; sourceTree = "<group>"; }; 3538AA211D542685008EC33D /* MGLBaseStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLBaseStyleLayer.h; sourceTree = "<group>"; }; 3538AA221D542685008EC33D /* MGLBaseStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLBaseStyleLayer.mm; sourceTree = "<group>"; }; @@ -235,6 +247,11 @@ 3593E5281D52A628006D9365 /* MGLStyleAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttribute.h; sourceTree = "<group>"; }; 3593E5291D52A628006D9365 /* MGLStyleAttribute.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttribute.mm; sourceTree = "<group>"; }; 3593E52C1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; }; + 35C5D8431D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSComparisonPredicate+MGLAdditions.h"; sourceTree = "<group>"; }; + 35C5D8441D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSComparisonPredicate+MGLAdditions.mm"; sourceTree = "<group>"; }; + 35C5D8451D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCompoundPredicate+MGLAdditions.h"; sourceTree = "<group>"; }; + 35C5D8461D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSCompoundPredicate+MGLAdditions.mm"; sourceTree = "<group>"; }; + 35C5D84B1D6DD75B00E95907 /* MGLFilterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLFilterTests.m; path = ../../darwin/test/MGLFilterTests.m; sourceTree = "<group>"; }; 35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+MGLAdditions.h"; sourceTree = "<group>"; }; 35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDate+MGLAdditions.mm"; sourceTree = "<group>"; }; 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 = "<group>"; }; 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 */, ); |