#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, NSArray * _Nonnull padding, BOOL * _Nonnull stop) { NSAssert([padding isKindOfClass:[NSArray class]], @"Stops should be NSArray"); NSNumber *top = padding[0]; NSNumber *left = padding[1]; NSNumber *bottom = padding[2]; NSNumber *right = padding[2]; auto pad = std::array({{top.floatValue, left.floatValue, bottom.floatValue, right.floatValue}}); stops.emplace_back(zoomKey.floatValue, pad); }]; return mbgl::style::Function>({{stops}}, _base.floatValue); } - (mbgl::style::PropertyValue >)mbgl_offsetPropertyValue { __block std::vector>> stops; [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSArray * _Nonnull offset, BOOL * _Nonnull stop) { NSAssert([offset isKindOfClass:[NSArray class]], @"Stops should be NSArray"); NSNumber *dx = offset[0]; NSNumber *dy = offset[1]; auto off = std::array({{dx.floatValue, dy.floatValue}}); stops.emplace_back(zoomKey.floatValue, off); }]; 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)] = @[@(stop.second[0]), @(stop.second[1])]; } 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)] = @[@(stop.second[0]), @(stop.second[1]), @(stop.second[2]), @(stop.second[3])]; } 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]; } @end