#import "MGLStyleAttributeFunction.h" #import "MGLStyleLayer_Private.h" #import "MGLStyleAttributeValue_Private.h" #import "MGLStyleAttributeFunction_Private.h" @interface MGLStyleAttributeFunction() @end @implementation MGLStyleAttributeFunction - (instancetype)init { if (self = [super init]) { _base = @1; } return self; } - (BOOL)isFunction { return YES; } - (mbgl::style::PropertyValue)mbgl_colorPropertyValue { __block std::vector> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, MGLColor * _Nonnull color, BOOL * _Nonnull stop) { NSAssert([color isKindOfClass:[MGLColor class]], @"Stops should be colors"); stops.emplace_back(zoomKey.floatValue, color.mbgl_color); }]; return mbgl::style::Function({{stops}}, _base.floatValue); } - (mbgl::style::PropertyValue)mbgl_floatPropertyValue { __block std::vector> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSNumber * _Nonnull number, BOOL * _Nonnull stop) { NSAssert([number isKindOfClass:[NSNumber class]], @"Stops should be NSNumbers"); stops.emplace_back(zoomKey.floatValue, number.floatValue); }]; return mbgl::style::Function({{stops}}, _base.floatValue); } - (mbgl::style::PropertyValue)mbgl_boolPropertyValue { __block std::vector> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSNumber * _Nonnull number, BOOL * _Nonnull stop) { NSAssert([number isKindOfClass:[NSNumber class]], @"Stops should be NSNumbers"); stops.emplace_back(zoomKey.floatValue, number.boolValue); }]; return mbgl::style::Function({{stops}}, _base.floatValue); } - (mbgl::style::PropertyValue)mbgl_stringPropertyValue { __block std::vector> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSString * _Nonnull string, BOOL * _Nonnull stop) { NSAssert([string isKindOfClass:[NSString class]], @"Stops should be strings"); stops.emplace_back(zoomKey.floatValue, string.UTF8String); }]; return mbgl::style::Function({{stops}}, _base.floatValue); } - (mbgl::style::PropertyValue >)mbgl_stringArrayPropertyValue { __block std::vector>> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSArray * _Nonnull strings, BOOL * _Nonnull stop) { NSAssert([strings isKindOfClass:[NSArray class]], @"Stops should be NSArray"); std::vectorconvertedStrings; for (NSString *string in strings) { convertedStrings.emplace_back(string.UTF8String); } stops.emplace_back(zoomKey.floatValue, convertedStrings); }]; return mbgl::style::Function>({{stops}}, _base.floatValue); } - (mbgl::style::PropertyValue >)mbgl_numberArrayPropertyValue { __block std::vector>> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSArray * _Nonnull numbers, BOOL * _Nonnull stop) { NSAssert([numbers isKindOfClass:[NSArray class]], @"Stops should be NSArray"); std::vectorconvertedNumbers; for (NSNumber *number in numbers) { convertedNumbers.emplace_back(number.floatValue); } stops.emplace_back(zoomKey.floatValue, convertedNumbers); }]; return mbgl::style::Function>({{stops}}, _base.floatValue); } - (mbgl::style::PropertyValue >)mbgl_paddingPropertyValue { __block std::vector>> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSValue * _Nonnull padding, BOOL * _Nonnull stop) { NSAssert([padding isKindOfClass:[NSValue class]], @"Stops should be NSValue"); stops.emplace_back(zoomKey.floatValue, padding.mgl_paddingArrayValue); }]; return mbgl::style::Function>({{stops}}, _base.floatValue); } - (mbgl::style::PropertyValue >)mbgl_offsetPropertyValue { __block std::vector>> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSValue * _Nonnull offset, BOOL * _Nonnull stop) { NSAssert([offset isKindOfClass:[NSValue class]], @"Stops should be NSValue"); stops.emplace_back(zoomKey.floatValue, offset.mgl_offsetArrayValue); }]; return mbgl::style::Function>({{stops}}, _base.floatValue); } + (instancetype)functionWithColorPropertyValue:(mbgl::style::Function)property { MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; auto stops = property.getStops(); NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; for (auto stop : stops) { convertedStops[@(stop.first)] = [MGLColor mbgl_colorWithColor:stop.second]; } function.base = @(property.getBase()); function.stops = convertedStops; return function; } + (instancetype)functionWithNumberPropertyValue:(mbgl::style::Function)property { MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; auto stops = property.getStops(); NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; for (auto stop : stops) { convertedStops[@(stop.first)] = @(stop.second); } function.base = @(property.getBase()); function.stops = convertedStops; return function; } + (instancetype)functionWithBoolPropertyValue:(mbgl::style::Function)property { MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; auto stops = property.getStops(); NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; for (auto stop : stops) { convertedStops[@(stop.first)] = @(stop.second); } function.base = @(property.getBase()); function.stops = convertedStops; return function; } + (instancetype)functionWithStringPropertyValue:(mbgl::style::Function)property { MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; auto stops = property.getStops(); NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; for (auto stop : stops) { convertedStops[@(stop.first)] = @(stop.second.c_str()); } function.base = @(property.getBase()); function.stops = convertedStops; return function; } + (instancetype)functionWithOffsetPropertyValue:(mbgl::style::Function >)property { MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; auto stops = property.getStops(); NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; for (auto stop : stops) { convertedStops[@(stop.first)] = [NSValue mgl_valueWithOffsetArray:stop.second]; } function.base = @(property.getBase()); function.stops = convertedStops; return function; } + (instancetype)functionWithPaddingPropertyValue:(mbgl::style::Function >)property { MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; auto stops = property.getStops(); NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; for (auto stop : stops) { convertedStops[@(stop.first)] = [NSValue mgl_valueWithPaddingArray:stop.second]; } function.base = @(property.getBase()); function.stops = convertedStops; return function; } + (instancetype)functionWithStringArrayPropertyValue:(mbgl::style::Function >)property { MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; auto stops = property.getStops(); NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; for (auto stop : stops) { auto strings = stop.second; NSMutableArray *convertedStrings = [NSMutableArray arrayWithCapacity:strings.size()]; for (auto const& string: strings) { [convertedStrings addObject:@(string.c_str())]; } convertedStops[@(stop.first)] = convertedStrings; } function.base = @(property.getBase()); function.stops = convertedStops; return function; } + (instancetype)functionWithNumberArrayPropertyValue:(mbgl::style::Function >)property { MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; auto stops = property.getStops(); NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; for (auto stop : stops) { auto numbers = stop.second; NSMutableArray *convertedNumbers = [NSMutableArray arrayWithCapacity:numbers.size()]; for (auto const& number: numbers) { [convertedNumbers addObject:@(number)]; } convertedStops[@(stop.first)] = convertedNumbers; } function.base = @(property.getBase()); function.stops = convertedStops; return function; } - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, base = %@; stops = %@>", NSStringFromClass([self class]), (void *)self, self.base, self.stops]; } - (BOOL)isEqual:(MGLStyleAttributeFunction *)other { return ([other isKindOfClass:[self class]] && (other.base == self.base || [other.base isEqualToNumber:self.base]) && [other.stops isEqualToDictionary:self.stops]); } - (NSUInteger)hash { return self.base.hash + self.stops.hash; } @end