diff options
Diffstat (limited to 'platform/darwin/src')
191 files changed, 0 insertions, 29896 deletions
diff --git a/platform/darwin/src/MGLAccountManager.h b/platform/darwin/src/MGLAccountManager.h deleted file mode 100644 index d1983a4ddc..0000000000 --- a/platform/darwin/src/MGLAccountManager.h +++ /dev/null @@ -1,41 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLAccountManager` object provides a global way to set a Mapbox API access - token. - */ -MGL_EXPORT -@interface MGLAccountManager : NSObject - -#pragma mark Authorizing Access - -/** - The - <a href="https://docs.mapbox.com/help/glossary/access-token/">Mapbox access token</a> - used by all instances of `MGLMapView` in the current application. - - Mapbox-hosted vector tiles and styles require an API access token, which you - can obtain from the - <a href="https://www.mapbox.com/studio/account/tokens/">Mapbox account page</a>. - Access tokens associate requests to Mapbox’s vector tile and style APIs with - your Mapbox account. They also deter other developers from using your styles - without your permission. - - Setting this property to a value of `nil` has no effect. - - @note You must set the access token before attempting to load any Mapbox-hosted - style. Therefore, you should generally set it before creating an instance of - `MGLMapView`. The recommended way to set an access token is to add an entry - to your application’s Info.plist file with the key `MGLMapboxAccessToken` - and the type `String`. Alternatively, you may call this method from your - application delegate’s `-applicationDidFinishLaunching:` method. - */ -@property (class, assign, nullable) NSString *accessToken; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLAccountManager.m b/platform/darwin/src/MGLAccountManager.m deleted file mode 100644 index c37195967a..0000000000 --- a/platform/darwin/src/MGLAccountManager.m +++ /dev/null @@ -1,112 +0,0 @@ -#import "MGLAccountManager_Private.h" -#import "NSBundle+MGLAdditions.h" - -#if TARGET_OS_OSX -#import "NSProcessInfo+MGLAdditions.h" -#endif - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MGLMapboxEvents.h" -#import "MBXSKUToken.h" - -static NSString * const MGLAccountManagerExternalClassName = @"MBXAccounts"; -static NSString * const MGLAccountManagerExternalMethodName = @"skuToken"; -#endif - -NSString * const MGLMapboxAccountTypeKey = @"MGLMapboxAccountType"; - -@interface MGLAccountManager () - -@property (atomic) NSString *accessToken; -@property (nonatomic) NSURL *apiBaseURL; - -@end - -@implementation MGLAccountManager - -#pragma mark - Internal - -+ (void)load { - // Read the initial configuration from Info.plist. - NSString *accessToken = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLMapboxAccessToken"]; - if (accessToken.length) { - self.accessToken = accessToken; - } - - NSString *apiBaseURL = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLMapboxAPIBaseURL"]; - - // If apiBaseURL is not a valid URL, [NSURL URLWithString:] will be `nil`. - if (apiBaseURL.length && [NSURL URLWithString:apiBaseURL]) { - [self setAPIBaseURL:[NSURL URLWithString:apiBaseURL]]; - } -} - -+ (instancetype)sharedManager { -#if TARGET_OS_OSX - if (NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { - return nil; - } -#endif - - static dispatch_once_t onceToken; - static MGLAccountManager *_sharedManager; - void (^setupBlock)(void) = ^{ - dispatch_once(&onceToken, ^{ - _sharedManager = [[self alloc] init]; - }); - }; - if (![[NSThread currentThread] isMainThread]) { - dispatch_sync(dispatch_get_main_queue(), ^{ - setupBlock(); - }); - } else { - setupBlock(); - } - return _sharedManager; -} - -+ (void)setAccessToken:(NSString *)accessToken { - accessToken = [accessToken stringByTrimmingCharactersInSet: - [NSCharacterSet whitespaceAndNewlineCharacterSet]]; - if (!accessToken.length) { - return; - } - - [MGLAccountManager sharedManager].accessToken = accessToken; - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - dispatch_async(dispatch_get_main_queue(), ^{ - [MGLMapboxEvents setupWithAccessToken:accessToken]; - }); -#endif -} - -+ (NSString *)accessToken { - return [MGLAccountManager sharedManager].accessToken; -} - -+ (void)setAPIBaseURL:(NSURL *)apiBaseURL { - [MGLAccountManager sharedManager].apiBaseURL = apiBaseURL; -} - -+ (NSURL *)apiBaseURL { - return [MGLAccountManager sharedManager].apiBaseURL; -} - -#pragma mark - SKU Tokens - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - -+ (NSString *)skuToken { - Class mbx = NSClassFromString(MGLAccountManagerExternalClassName); - - if ([mbx respondsToSelector:NSSelectorFromString(MGLAccountManagerExternalMethodName)]) { - return (NSString *)[mbx valueForKeyPath:MGLAccountManagerExternalMethodName]; - } - - return MBXSKUToken.skuToken; -} - -#endif - -@end diff --git a/platform/darwin/src/MGLAccountManager_Private.h b/platform/darwin/src/MGLAccountManager_Private.h deleted file mode 100644 index 4bf7963182..0000000000 --- a/platform/darwin/src/MGLAccountManager_Private.h +++ /dev/null @@ -1,26 +0,0 @@ -#import "MGLAccountManager.h" - -NS_ASSUME_NONNULL_BEGIN - -/// NSUserDefaults key that controls developer account type -FOUNDATION_EXTERN NSString * const MGLMapboxAccountTypeKey; - -@interface MGLAccountManager (Private) - -/// Returns the shared instance of the `MGLAccountManager` class. -@property (class, nonatomic, readonly) MGLAccountManager *sharedManager; - -/// The current global access token. -@property (atomic, nullable) NSString *accessToken; - -/// The API base URL that is used to access Mapbox resources. The default base URL is `https://api.mapbox.com`. If `nil`, the Mapbox default base API URL is in use. -@property (atomic, readwrite, nullable) NSURL *apiBaseURL; - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -/// The current global SKU. -@property (class, atomic, readonly) NSString *skuToken; -#endif - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLAnnotation.h b/platform/darwin/src/MGLAnnotation.h deleted file mode 100644 index a8ac1e7e50..0000000000 --- a/platform/darwin/src/MGLAnnotation.h +++ /dev/null @@ -1,65 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> -#import <TargetConditionals.h> - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLAnnotation` protocol is used to provide annotation-related information - to a map view. To use this protocol, you adopt it in any custom objects that - store or represent annotation data. Each object then serves as the source of - information about a single map annotation and provides critical information, - such as the annotation’s location on the map. Annotation objects do not provide - the visual representation of the annotation but typically coordinate (in - conjunction with the map view’s delegate) the creation of an appropriate - objects to handle the display. - - An object that adopts this protocol must implement the `coordinate` property. - The other methods of this protocol are optional. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/annotation-models/"> - Annotation models</a> and <a href="https://docs.mapbox.com/ios/maps/examples/annotation-views/"> - Annotation views</a> examples to learn how to add objects that follow the - `MGLAnnotation` protocol. - */ -@protocol MGLAnnotation <NSObject> - -#pragma mark Position Attributes - -/** - The center point (specified as a map coordinate) of the annotation. (required) - (read-only) - */ -@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; - -@optional - -#pragma mark Title Attributes - -/** - The string containing the annotation’s title. - - Although this property is optional, if you support the selection of annotations - in your map view, you are expected to provide this property. This string is - displayed in the callout for the associated annotation. - */ -@property (nonatomic, readonly, copy, nullable) NSString *title; - -/** - The string containing the annotation’s subtitle. - - This string is displayed in the callout for the associated annotation. - */ -@property (nonatomic, readonly, copy, nullable) NSString *subtitle; - -#if !TARGET_OS_IPHONE - -/** The string containing the annotation’s tooltip. */ -@property (nonatomic, readonly, copy, nullable) NSString *toolTip; - -#endif - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLAttributedExpression.h b/platform/darwin/src/MGLAttributedExpression.h deleted file mode 100644 index ea298c7a44..0000000000 --- a/platform/darwin/src/MGLAttributedExpression.h +++ /dev/null @@ -1,87 +0,0 @@ -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** Options for `MGLAttributedExpression.attributes`. */ -typedef NSString * MGLAttributedExpressionKey NS_TYPED_ENUM; - -/** The font name string array expression used to format the text. */ -FOUNDATION_EXTERN MGL_EXPORT MGLAttributedExpressionKey const MGLFontNamesAttribute; - -/** The font scale number expression relative to `MGLSymbolStyleLayer.textFontSize` used to format the text. */ -FOUNDATION_EXTERN MGL_EXPORT MGLAttributedExpressionKey const MGLFontScaleAttribute; - -/** The font color expression used to format the text. */ -FOUNDATION_EXTERN MGL_EXPORT MGLAttributedExpressionKey const MGLFontColorAttribute; - -/** - An `MGLAttributedExpression` object associates text formatting attibutes (such as font size or - font names) to an `NSExpression`. - - ### Example - ```swift - let redColor = UIColor.red - let expression = NSExpression(forConstantValue: "Foo") - let attributes: [MGLAttributedExpressionKey: NSExpression] = [.fontNamesAttribute : NSExpression(forConstantValue: ["DIN Offc Pro Italic", - "Arial Unicode MS Regular"]), - .fontScaleAttribute: NSExpression(forConstantValue: 1.2), - .fontColorAttribute: NSExpression(forConstantValue: redColor)] - let attributedExpression = MGLAttributedExpression(expression, attributes:attributes) - ``` - - */ -MGL_EXPORT -@interface MGLAttributedExpression : NSObject - -/** - The expression content of the receiver as `NSExpression`. - */ -@property (strong, nonatomic) NSExpression *expression; - -#if TARGET_OS_IPHONE -/** - The formatting attributes dictionary. - Key | Value Type - --- | --- - `MGLFontNamesAttribute` | An `NSExpression` evaluating to an `NSString` array. - `MGLFontScaleAttribute` | An `NSExpression` evaluating to an `NSNumber` value. - `MGLFontColorAttribute` | An `NSExpression` evaluating to an `UIColor`. - - */ -@property (strong, nonatomic, readonly) NSDictionary<MGLAttributedExpressionKey, NSExpression *> *attributes; -#else -/** - The formatting attributes dictionary. - Key | Value Type - --- | --- - `MGLFontNamesAttribute` | An `NSExpression` evaluating to an `NSString` array. - `MGLFontScaleAttribute` | An `NSExpression` evaluating to an `NSNumber` value. - `MGLFontColorAttribute` | An `NSExpression` evaluating to an `NSColor` on macos. - */ -@property (strong, nonatomic, readonly) NSDictionary<MGLAttributedExpressionKey, NSExpression *> *attributes; -#endif - - -/** - Returns an `MGLAttributedExpression` object initialized with an expression and no attribute information. - */ -- (instancetype)initWithExpression:(NSExpression *)expression; - -/** - Returns an `MGLAttributedExpression` object initialized with an expression and text format attributes. - */ -- (instancetype)initWithExpression:(NSExpression *)expression attributes:(nonnull NSDictionary <MGLAttributedExpressionKey, NSExpression *> *)attrs; - -/** - Creates an `MGLAttributedExpression` object initialized with an expression and the format attributes for font names and font size. - */ -+ (instancetype)attributedExpression:(NSExpression *)expression fontNames:(nullable NSArray<NSString*> *)fontNames fontScale:(nullable NSNumber *)fontScale; - -/** - Creates an `MGLAttributedExpression` object initialized with an expression and the format attributes dictionary. - */ -+ (instancetype)attributedExpression:(NSExpression *)expression attributes:(nonnull NSDictionary <MGLAttributedExpressionKey, NSExpression *> *)attrs; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLAttributedExpression.m b/platform/darwin/src/MGLAttributedExpression.m deleted file mode 100644 index a34480a957..0000000000 --- a/platform/darwin/src/MGLAttributedExpression.m +++ /dev/null @@ -1,68 +0,0 @@ -#import "MGLAttributedExpression.h" -#import "MGLLoggingConfiguration_Private.h" - -const MGLAttributedExpressionKey MGLFontNamesAttribute = @"text-font"; -const MGLAttributedExpressionKey MGLFontScaleAttribute = @"font-scale"; -const MGLAttributedExpressionKey MGLFontColorAttribute = @"text-color"; - -@implementation MGLAttributedExpression - -- (instancetype)initWithExpression:(NSExpression *)expression { - self = [self initWithExpression:expression attributes:@{}]; - return self; -} - -+ (instancetype)attributedExpression:(NSExpression *)expression fontNames:(nullable NSArray<NSString *> *)fontNames fontScale:(nullable NSNumber *)fontScale { - MGLAttributedExpression *attributedExpression; - - NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; - - if (fontNames && fontNames.count > 0) { - attrs[MGLFontNamesAttribute] = [NSExpression expressionForConstantValue:fontNames]; - } - - if (fontScale) { - attrs[MGLFontScaleAttribute] = [NSExpression expressionForConstantValue:fontScale]; - } - - attributedExpression = [[self alloc] initWithExpression:expression attributes:attrs]; - return attributedExpression; -} - -+ (instancetype)attributedExpression:(NSExpression *)expression attributes:(nonnull NSDictionary<MGLAttributedExpressionKey, NSExpression *> *)attrs { - MGLAttributedExpression *attributedExpression; - - attributedExpression = [[self alloc] initWithExpression:expression attributes:attrs]; - - return attributedExpression; -} - -- (instancetype)initWithExpression:(NSExpression *)expression attributes:(nonnull NSDictionary<MGLAttributedExpressionKey, NSExpression *> *)attrs { - if (self = [super init]) - { - MGLLogInfo(@"Starting %@ initialization.", NSStringFromClass([self class])); - _expression = expression; - _attributes = attrs; - - MGLLogInfo(@"Finalizing %@ initialization.", NSStringFromClass([self class])); - } - return self; -} - -- (BOOL)isEqual:(id)object { - BOOL result = NO; - - if ([object isKindOfClass:[self class]]) { - MGLAttributedExpression *otherObject = object; - result = [self.expression isEqual:otherObject.expression] && - [_attributes isEqual:otherObject.attributes]; - } - - return result; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"MGLAttributedExpression<Expression: %@ Attributes: %@>", self.expression, self.attributes]; -} - -@end diff --git a/platform/darwin/src/MGLAttributionInfo.h b/platform/darwin/src/MGLAttributionInfo.h deleted file mode 100644 index 1de37c3b24..0000000000 --- a/platform/darwin/src/MGLAttributionInfo.h +++ /dev/null @@ -1,94 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreGraphics/CoreGraphics.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The attribution info is represented in the longest format available. - */ -typedef NS_ENUM(NSUInteger, MGLAttributionInfoStyle) { - /** - Specifies a short attribution info style. - */ - MGLAttributionInfoStyleShort = 1, - /** - Specifies a medium attribution info style. - */ - MGLAttributionInfoStyleMedium, - /** - Specifies a long attribution info style. - */ - MGLAttributionInfoStyleLong -}; - -/** - Information about an attribution statement, usually a copyright or trademark - statement, associated with a map content source. - */ -MGL_EXPORT -@interface MGLAttributionInfo : NSObject - -/** - Returns an initialized attribution info object with the given title and URL. - - @param title The attribution statement’s title. - @param URL A URL to more information about the entity named in the attribution. - @return An initialized attribution info object. - */ -- (instancetype)initWithTitle:(NSAttributedString *)title URL:(nullable NSURL *)URL; - -/** - The attribution statement’s attributed title text. - */ -@property (nonatomic) NSAttributedString *title; - -/** - The URL to more information about the entity named in the attribution. - - If this property is set, the attribution statement should be displayed as a - hyperlink or action button. Otherwise, if it is `nil`, the attribution - statement should be displayed as plain text. - */ -@property (nonatomic, nullable) NSURL *URL; - -/** - A Boolean value indicating whether the attribution statement is a shortcut to a - feedback tool. - - If this property is set, the statement should be treated as a way for the user - to provide feedback rather than an attribution statement. - */ -@property (nonatomic, getter=isFeedbackLink) BOOL feedbackLink; - -/** - Returns a copy of the `URL` property modified to account for the given center - coordinate and zoom level. - - @param centerCoordinate The map’s center coordinate. - @param zoomLevel The map’s zoom level. See the `MGLMapView.zoomLevel` property - for more information. - @return A modified URL containing a fragment that points to the specified - viewport. If the `feedbackLink` property is set to `NO`, this method returns - `nil`. - */ -- (nullable NSURL *)feedbackURLAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel; - -/** - Returns a copy of the current `title` formatted accordingly to `style`. - - Example: If the `style` property is set to `MGLAttributionInfoStyleShort` and the - `title` property is set to `OpenStreetMap`, then this method returns `OSM`. - - @param style The attribution info style. - - @return The `NSAttributedString` styled title. - */ -- (NSAttributedString *)titleWithStyle:(MGLAttributionInfoStyle)style; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLAttributionInfo.mm b/platform/darwin/src/MGLAttributionInfo.mm deleted file mode 100644 index 17d159f660..0000000000 --- a/platform/darwin/src/MGLAttributionInfo.mm +++ /dev/null @@ -1,279 +0,0 @@ -#import "MGLAttributionInfo_Private.h" - -#if TARGET_OS_IPHONE - #import <UIKit/UIKit.h> -#else - #import <Cocoa/Cocoa.h> -#endif - -#import "MGLAccountManager.h" -#import "MGLMapCamera.h" -#import "NSArray+MGLAdditions.h" -#import "NSBundle+MGLAdditions.h" -#import "NSString+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#include <string> - -@implementation MGLAttributionInfo - -+ (NSArray<MGLAttributionInfo *> *)attributionInfosFromHTMLString:(nullable NSString *)htmlString fontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { - if (!htmlString) { - return @[]; - } - - NSDictionary *options = @{ - NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, - NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding), - }; - // Apply a bogus, easily detectable style rule to any feedback link, since - // NSAttributedString doesn’t preserve the class attribute. - NSMutableString *css = [NSMutableString stringWithString: - @"html { font-family: -apple-system, -apple-system-font, sans-serif; }" - @".mapbox-improve-map { -webkit-text-stroke-width: 1000px; }"]; - if (fontSize) { - NSString *sizeRule = [NSString stringWithFormat:@"font-size: %.1fpx;", fontSize]; -#if !TARGET_OS_IPHONE - if (fontSize == [NSFont systemFontSizeForControlSize:NSMiniControlSize]) { - sizeRule = @"font: -webkit-mini-control"; - } else if (fontSize == [NSFont systemFontSizeForControlSize:NSSmallControlSize]) { - sizeRule = @"font: -webkit-small-control"; - } else if (fontSize == [NSFont systemFontSizeForControlSize:NSRegularControlSize]) { - sizeRule = @"font: -webkit-control"; - } -#endif - [css appendFormat:@"html { %@ }", sizeRule]; - } - if (linkColor) { - CGFloat red; - CGFloat green; - CGFloat blue; - CGFloat alpha; -#if !TARGET_OS_IPHONE - // CSS uses the sRGB color space. - if ([NSColor redColor].colorSpaceName == NSCalibratedRGBColorSpace) { - linkColor = [linkColor colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; - } else { - linkColor = [linkColor colorUsingColorSpace:[NSColorSpace sRGBColorSpace]]; - } -#endif - [linkColor getRed:&red green:&green blue:&blue alpha:&alpha]; - [css appendFormat: - @"a:link { color: rgba(%f%%, %f%%, %f%%, %f); }", - red * 100, green * 100, blue * 100, alpha]; - } - NSString *styledHTML = [NSString stringWithFormat:@"<style type='text/css'>%@</style>%@", css, htmlString]; - NSData *htmlData = [styledHTML dataUsingEncoding:NSUTF8StringEncoding]; - -#if TARGET_OS_IPHONE - __block NSMutableAttributedString *attributedString; - dispatch_block_t initialization = ^{ - // This initializer should be called from a global or main queue. https://developer.apple.com/documentation/foundation/nsattributedstring/1524613-initwithdata - attributedString = [[NSMutableAttributedString alloc] initWithData:htmlData - options:options - documentAttributes:nil - error:NULL]; - }; - - if (![[NSThread currentThread] isMainThread]) { - dispatch_sync(dispatch_get_main_queue(), initialization); - } else { - initialization(); - } -#else - NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithHTML:htmlData - options:options - documentAttributes:nil]; -#endif - - NSMutableArray *infos = [NSMutableArray array]; - [attributedString enumerateAttribute:NSLinkAttributeName - inRange:attributedString.mgl_wholeRange - options:0 - usingBlock: - ^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) { - MGLCAssert(!value || [value isKindOfClass:[NSURL class]], @"If present, URL attribute must be an NSURL."); - - // Detect feedback links by the bogus style rule applied above. - NSNumber *strokeWidth = [attributedString attribute:NSStrokeWidthAttributeName - atIndex:range.location - effectiveRange:NULL]; - BOOL isFeedbackLink = NO; - if ([strokeWidth floatValue] > 100) { - isFeedbackLink = YES; - [attributedString removeAttribute:NSStrokeWidthAttributeName range:range]; - } - - // Omit whitespace-only strings. - NSAttributedString *title = [[attributedString attributedSubstringFromRange:range] - mgl_attributedStringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - if (!title.length) { - return; - } - - // Remove the link, because it forces the text to be blue on macOS 10.12 - // and above. - NSMutableAttributedString *unlinkedTitle = [title mutableCopy]; - [unlinkedTitle removeAttribute:NSLinkAttributeName range:unlinkedTitle.mgl_wholeRange]; - - MGLAttributionInfo *info = [[MGLAttributionInfo alloc] initWithTitle:unlinkedTitle URL:value]; - info.feedbackLink = isFeedbackLink; - [infos addObject:info]; - }]; - return infos; -} - -+ (NSAttributedString *)attributedStringForAttributionInfos:(NSArray<MGLAttributionInfo *> *)attributionInfos { - NSMutableArray *titles = [NSMutableArray arrayWithCapacity:attributionInfos.count]; - for (MGLAttributionInfo *info in attributionInfos) { - NSMutableAttributedString *title = info.title.mutableCopy; - if (info.URL) { - [title addAttribute:NSLinkAttributeName value:info.URL range:title.mgl_wholeRange]; - } - [titles addObject:title]; - } - return [titles mgl_attributedComponentsJoinedByString:@" "]; -} - -- (instancetype)initWithTitle:(NSAttributedString *)title URL:(NSURL *)URL { - if (self = [super init]) { - _title = title; - _URL = URL; - } - return self; -} - -- (id)copyWithZone:(nullable NSZone *)zone -{ - MGLAttributionInfo *info = [[[self class] allocWithZone:zone] initWithTitle:_title - URL:_URL]; - info.feedbackLink = _feedbackLink; - - return info; -} - -- (nullable NSURL *)feedbackURLAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel { - return [self feedbackURLForStyleURL:nil atCenterCoordinate:centerCoordinate zoomLevel:zoomLevel direction:0 pitch:0]; -} - -- (nullable NSURL *)feedbackURLForStyleURL:(nullable NSURL *)styleURL atCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel direction:(CLLocationDirection)direction pitch:(CGFloat)pitch { - if (!self.feedbackLink) { - return nil; - } - - NSURLComponents *components = [NSURLComponents componentsWithString:@"https://apps.mapbox.com/feedback/"]; - components.fragment = [NSString stringWithFormat:@"/%.5f/%.5f/%.2f/%.1f/%i", - centerCoordinate.longitude, centerCoordinate.latitude, zoomLevel, - direction, (int)round(pitch)]; - - NSURLQueryItem *referrerQueryItem = [NSURLQueryItem queryItemWithName:@"referrer" - value:[NSBundle mgl_applicationBundleIdentifier]]; - NSMutableArray<NSURLQueryItem *> *queryItems = [NSMutableArray arrayWithObject:referrerQueryItem]; - if ([styleURL.scheme isEqualToString:@"mapbox"] && [styleURL.host isEqualToString:@"styles"]) { - NSArray<NSString *> *stylePathComponents = styleURL.pathComponents; - if (stylePathComponents.count >= 3) { - [queryItems addObjectsFromArray:@[ - [NSURLQueryItem queryItemWithName:@"owner" value:stylePathComponents[1]], - [NSURLQueryItem queryItemWithName:@"id" value:stylePathComponents[2]], - [NSURLQueryItem queryItemWithName:@"access_token" value:[MGLAccountManager accessToken]], - [NSURLQueryItem queryItemWithName:@"map_sdk_version" value:[NSBundle mgl_frameworkInfoDictionary][@"MGLSemanticVersionString"]], - ]]; - } - } - components.queryItems = queryItems; - - return components.URL; -} - -- (NSAttributedString *)titleWithStyle:(MGLAttributionInfoStyle)style -{ - NSString *openStreetMap = NSLocalizedStringWithDefaultValue(@"OSM_FULL_NAME", @"Foundation", nil, @"OpenStreetMap", @"OpenStreetMap full name attribution"); - NSString *OSM = NSLocalizedStringWithDefaultValue(@"OSM_SHORT_NAME", @"Foundation", nil, @"OSM", @"OpenStreetMap short name attribution"); - - NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithAttributedString:self.title]; - [title removeAttribute:NSUnderlineStyleAttributeName range:NSMakeRange(0, [title.string length])]; - - BOOL isAbbreviated = (style == MGLAttributionInfoStyleShort); - - if ([title.string rangeOfString:@"OpenStreetMap"].location != NSNotFound) { - [title.mutableString replaceOccurrencesOfString:@"OpenStreetMap" withString:isAbbreviated ? OSM : openStreetMap - options:NSCaseInsensitiveSearch - range:NSMakeRange(0, [title.mutableString length])]; - } - - return title; -} - -- (BOOL)isEqual:(id)object { - return [object isKindOfClass:[self class]] && [[object title] isEqual:self.title] && [[object URL] isEqual:self.URL]; -} - -- (NSUInteger)hash { - return self.title.hash + self.URL.hash; -} - -/** - Returns whether the given attribution info object overlaps with the receiver by - its plain text title. - - @return `NSOrderedAscending` if the given object is a superset of the receiver, - `NSOrderedDescending` if it is a subset of the receiver, or `NSOrderedSame` - if there is no overlap. - */ -- (NSComparisonResult)subsetCompare:(MGLAttributionInfo *)otherInfo { - NSString *title = self.title.string; - NSString *otherTitle = otherInfo.title.string; - if ([title containsString:otherTitle]) { - return NSOrderedDescending; - } - if ([otherTitle containsString:title]) { - return NSOrderedAscending; - } - return NSOrderedSame; -} - -@end - -@implementation NSMutableArray (MGLAttributionInfoAdditions) - -- (void)growArrayByAddingAttributionInfo:(MGLAttributionInfo *)info { - __block BOOL didInsertInfo = NO; - __block BOOL shouldAddInfo = YES; - [self enumerateObjectsUsingBlock:^(MGLAttributionInfo * _Nonnull existingInfo, NSUInteger idx, BOOL * _Nonnull stop) { - switch ([info subsetCompare:existingInfo]) { - case NSOrderedDescending: - // The existing info object is a subset of the one we’re adding. - // Replace the existing object the first time we find a subset; - // remove the existing object every time after that. - if (didInsertInfo) { - [self removeObjectAtIndex:idx]; - } else { - [self replaceObjectAtIndex:idx withObject:info]; - didInsertInfo = YES; - } - break; - - case NSOrderedAscending: - // The info object we’re adding is a subset of the existing one. - // Don’t add the object and stop looking. - shouldAddInfo = NO; - *stop = YES; - break; - - default: - break; - } - }]; - if (shouldAddInfo && !didInsertInfo) { - // No overlapping infos were found, so append the info object. - [self addObject:info]; - } -} - -- (void)growArrayByAddingAttributionInfosFromArray:(NSArray<MGLAttributionInfo *> *)infos { - for (MGLAttributionInfo *info in infos) { - [self growArrayByAddingAttributionInfo:info]; - } -} - -@end diff --git a/platform/darwin/src/MGLAttributionInfo_Private.h b/platform/darwin/src/MGLAttributionInfo_Private.h deleted file mode 100644 index 85c9ed796f..0000000000 --- a/platform/darwin/src/MGLAttributionInfo_Private.h +++ /dev/null @@ -1,65 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreGraphics/CoreGraphics.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLAttributionInfo.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLAttributionInfo (Private) - -/** - Parses and returns the attribution infos contained in the given HTML source - code string. - - @param htmlString The HTML source code to parse. - @param fontSize The default text size in points. - @param linkColor The default link color. - */ -+ (NSArray<MGLAttributionInfo *> *)attributionInfosFromHTMLString:(nullable NSString *)htmlString fontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; - -+ (NSAttributedString *)attributedStringForAttributionInfos:(NSArray<MGLAttributionInfo *> *)attributionInfos; - -/** - Returns a copy of the `URL` property modified to account for the given style - URL, center coordinate, and zoom level. - - @param styleURL The map’s style URL. - @param centerCoordinate The map’s center coordinate. - @param zoomLevel The map’s zoom level. See the `MGLMapView.zoomLevel` property - for more information. - @param direction The heading of the map, measured in degrees clockwise from - true north. - @param pitch Pitch toward the horizon measured in degrees, with 0 degrees - resulting in a two-dimensional map. - @return A modified URL containing a fragment that points to the specified - viewport. If the `feedbackLink` property is set to `NO`, this method returns - `nil`. - */ -- (nullable NSURL *)feedbackURLForStyleURL:(nullable NSURL *)styleURL atCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel direction:(CLLocationDirection)direction pitch:(CGFloat)pitch; - -@end - -@interface NSMutableArray (MGLAttributionInfoAdditions) - -/** - Adds the given attribution info object to the receiver as long as it isn’t - redundant to any object already in the receiver. Any existing object that is - redundant to the given object is replaced by the given object. - - @param info The info object to add to the receiver. - */ -- (void)growArrayByAddingAttributionInfo:(MGLAttributionInfo *)info; - -/** - Adds each of the given attribution info objects to the receiver as long as it - isn’t redundant to any object already in the receiver. Any existing object that - is redundant to the given object is replaced by the given object. - - @param infos An array of info objects to add to the receiver. - */ -- (void)growArrayByAddingAttributionInfosFromArray:(NSArray<MGLAttributionInfo *> *)infos; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.h b/platform/darwin/src/MGLBackgroundStyleLayer.h deleted file mode 100644 index 31755c8bad..0000000000 --- a/platform/darwin/src/MGLBackgroundStyleLayer.h +++ /dev/null @@ -1,149 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An `MGLBackgroundStyleLayer` is a style layer that covers the entire map. Use a - background style layer to configure a color or pattern to show below all other - map content. If the style’s other layers use the Mapbox Streets source, the - background style layer is responsible for drawing land, whereas the oceans and - other bodies of water are drawn by `MGLFillStyleLayer` objects. - - A background style layer is typically the bottommost layer in a style, because - it covers the entire map and can occlude any layers below it. You can therefore - access it by getting the last item in the `MGLStyle.layers` array. - - If the background style layer is transparent or omitted from the style, any - portion of the map view that does not show another style layer is transparent. - */ -MGL_EXPORT -@interface MGLBackgroundStyleLayer : MGLStyleLayer - -/** -Returns a background style layer initialized with an identifier. - -After initializing and configuring the style layer, add it to a map view’s -style using the `-[MGLStyle addLayer:]` or -`-[MGLStyle insertLayer:belowLayer:]` method. - -@param identifier A string that uniquely identifies the source in the style to -which it is added. -*/ -- (instancetype)initWithIdentifier:(NSString *)identifier; - -#pragma mark - Accessing the Paint Attributes - -#if TARGET_OS_IPHONE -/** - The color with which the background will be drawn. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `backgroundPattern` is set to - `nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *backgroundColor; -#else -/** - The color with which the background will be drawn. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `backgroundPattern` is set to - `nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *backgroundColor; -#endif - -/** - The transition affecting any changes to this layer’s `backgroundColor` property. - - This property corresponds to the `background-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition backgroundColorTransition; - -/** - The opacity at which the background will be drawn. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *backgroundOpacity; - -/** - The transition affecting any changes to this layer’s `backgroundOpacity` property. - - This property corresponds to the `background-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition backgroundOpacityTransition; - -/** - Name of image in style images to use for drawing an image background. For - seamless patterns, image width and height must be a factor of two (2, 4, 8, - ..., 512). - - You can set this property to an expression containing any of the following: - - * Constant string values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *backgroundPattern; - -/** - The transition affecting any changes to this layer’s `backgroundPattern` property. - - This property corresponds to the `background-pattern-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition backgroundPatternTransition; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.mm b/platform/darwin/src/MGLBackgroundStyleLayer.mm deleted file mode 100644 index 053e05c5c4..0000000000 --- a/platform/darwin/src/MGLBackgroundStyleLayer.mm +++ /dev/null @@ -1,146 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLBackgroundStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLBackgroundStyleLayer_Private.h" - -#include <mbgl/style/layers/background_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -@interface MGLBackgroundStyleLayer () - -@property (nonatomic, readonly) mbgl::style::BackgroundLayer *rawLayer; - -@end - -@implementation MGLBackgroundStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier -{ - MGLLogDebug(@"Initializing %@ with identifier: %@", NSStringFromClass([self class]), identifier); - auto layer = std::make_unique<mbgl::style::BackgroundLayer>(identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::BackgroundLayer *)rawLayer -{ - return (mbgl::style::BackgroundLayer *)super.rawLayer; -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setBackgroundColor:(NSExpression *)backgroundColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting backgroundColor: %@", backgroundColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(backgroundColor, false); - self.rawLayer->setBackgroundColor(mbglValue); -} - -- (NSExpression *)backgroundColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getBackgroundColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultBackgroundColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setBackgroundColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting backgroundColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setBackgroundColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)backgroundColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getBackgroundColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setBackgroundOpacity:(NSExpression *)backgroundOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting backgroundOpacity: %@", backgroundOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(backgroundOpacity, false); - self.rawLayer->setBackgroundOpacity(mbglValue); -} - -- (NSExpression *)backgroundOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getBackgroundOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultBackgroundOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setBackgroundOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting backgroundOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setBackgroundOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)backgroundOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getBackgroundOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setBackgroundPattern:(NSExpression *)backgroundPattern { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting backgroundPattern: %@", backgroundPattern); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::expression::Image>>(backgroundPattern, false); - self.rawLayer->setBackgroundPattern(mbglValue); -} - -- (NSExpression *)backgroundPattern { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getBackgroundPattern(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultBackgroundPattern(); - } - return MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toExpression(propertyValue); -} - -- (void)setBackgroundPatternTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting backgroundPatternTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setBackgroundPatternTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)backgroundPatternTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getBackgroundPatternTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -@end - -namespace mbgl { - -MGLStyleLayer* BackgroundStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLBackgroundStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLBackgroundStyleLayer_Private.h b/platform/darwin/src/MGLBackgroundStyleLayer_Private.h deleted file mode 100644 index b50a681b41..0000000000 --- a/platform/darwin/src/MGLBackgroundStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/background_layer_factory.hpp> - -namespace mbgl { - -class BackgroundStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::BackgroundLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h deleted file mode 100644 index e2b043a729..0000000000 --- a/platform/darwin/src/MGLCircleStyleLayer.h +++ /dev/null @@ -1,540 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLVectorStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Orientation of circle when map is pitched. - - Values of this type are used in the `MGLCircleStyleLayer.circlePitchAlignment` - property. - */ -typedef NS_ENUM(NSUInteger, MGLCirclePitchAlignment) { - /** - The circle is aligned to the plane of the map. - */ - MGLCirclePitchAlignmentMap, - /** - The circle is aligned to the plane of the viewport. - */ - MGLCirclePitchAlignmentViewport, -}; - -/** - Controls the scaling behavior of the circle when the map is pitched. - - Values of this type are used in the `MGLCircleStyleLayer.circleScaleAlignment` - property. - */ -typedef NS_ENUM(NSUInteger, MGLCircleScaleAlignment) { - /** - Circles are scaled according to their apparent distance to the camera. - */ - MGLCircleScaleAlignmentMap, - /** - Circles are not scaled. - */ - MGLCircleScaleAlignmentViewport, -}; - -/** - Controls the frame of reference for `MGLCircleStyleLayer.circleTranslation`. - - Values of this type are used in the `MGLCircleStyleLayer.circleTranslationAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLCircleTranslationAnchor) { - /** - The circle is translated relative to the map. - */ - MGLCircleTranslationAnchorMap, - /** - The circle is translated relative to the viewport. - */ - MGLCircleTranslationAnchorViewport, -}; - -/** - An `MGLCircleStyleLayer` is a style layer that renders one or more filled - circles on the map. - - Use a circle style layer to configure the visual appearance of point or point - collection features. These features can come from vector tiles loaded by an - `MGLVectorTileSource` object, or they can be `MGLPointAnnotation`, - `MGLPointFeature`, `MGLPointCollection`, or `MGLPointCollectionFeature` - instances in an `MGLShapeSource` or `MGLComputedShapeSource` object. - - A circle style layer renders circles whose radii are measured in screen units. - To display circles on the map whose radii correspond to real-world distances, - use many-sided regular polygons and configure their appearance using an - `MGLFillStyleLayer` object. - - You can access an existing circle style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new circle style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - #### Related examples - See the <a - href="https://docs.mapbox.com/ios/maps/examples/dds-circle-layer/">Data-driven - circles</a>, <a - href="https://docs.mapbox.com/ios/maps/examples/shape-collection/">Add multiple - shapes from a single shape source</a>, and <a - href="https://docs.mapbox.com/ios/maps/examples/clustering/">Cluster point - data</a> examples to learn how to add circles to your map using this style - layer. - - ### Example - - ```swift - let layer = MGLCircleStyleLayer(identifier: "circles", source: population) - layer.sourceLayerIdentifier = "population" - layer.circleColor = NSExpression(forConstantValue: UIColor.green) - layer.circleRadius = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.75, %@)", - [12: 2, - 22: 180]) - layer.circleOpacity = NSExpression(forConstantValue: 0.7) - layer.predicate = NSPredicate(format: "%K == %@", "marital-status", "married") - mapView.style?.addLayer(layer) - ``` - */ -MGL_EXPORT -@interface MGLCircleStyleLayer : MGLVectorStyleLayer - -/** - Returns a circle style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; - -#pragma mark - Accessing the Paint Attributes - -/** - Amount to blur the circle. 1 blurs the circle such that only the centerpoint is - full opacity. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleBlur; - -/** - The transition affecting any changes to this layer’s `circleBlur` property. - - This property corresponds to the `circle-blur-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition circleBlurTransition; - -#if TARGET_OS_IPHONE -/** - The fill color of the circle. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleColor; -#else -/** - The fill color of the circle. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleColor; -#endif - -/** - The transition affecting any changes to this layer’s `circleColor` property. - - This property corresponds to the `circle-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition circleColorTransition; - -/** - The opacity at which the circle will be drawn. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleOpacity; - -/** - The transition affecting any changes to this layer’s `circleOpacity` property. - - This property corresponds to the `circle-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition circleOpacityTransition; - -/** - Orientation of circle when map is pitched. - - The default value of this property is an expression that evaluates to - `viewport`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant `MGLCirclePitchAlignment` values - * Any of the following constant string values: - * `map`: The circle is aligned to the plane of the map. - * `viewport`: The circle is aligned to the plane of the viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *circlePitchAlignment; - -/** - Circle radius. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `5`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleRadius; - -/** - The transition affecting any changes to this layer’s `circleRadius` property. - - This property corresponds to the `circle-radius-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition circleRadiusTransition; - -/** - Controls the scaling behavior of the circle when the map is pitched. - - The default value of this property is an expression that evaluates to `map`. - Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-circle-pitch-scale"><code>circle-pitch-scale</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLCircleScaleAlignment` values - * Any of the following constant string values: - * `map`: Circles are scaled according to their apparent distance to the - camera. - * `viewport`: Circles are not scaled. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *circleScaleAlignment; - -@property (nonatomic, null_resettable) NSExpression *circlePitchScale __attribute__((unavailable("Use circleScaleAlignment instead."))); - -#if TARGET_OS_IPHONE -/** - The stroke color of the circle. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleStrokeColor; -#else -/** - The stroke color of the circle. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleStrokeColor; -#endif - -/** - The transition affecting any changes to this layer’s `circleStrokeColor` property. - - This property corresponds to the `circle-stroke-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition circleStrokeColorTransition; - -/** - The opacity of the circle's stroke. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleStrokeOpacity; - -/** - The transition affecting any changes to this layer’s `circleStrokeOpacity` property. - - This property corresponds to the `circle-stroke-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition circleStrokeOpacityTransition; - -/** - The width of the circle's stroke. Strokes are placed outside of the - `circleRadius`. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *circleStrokeWidth; - -/** - The transition affecting any changes to this layer’s `circleStrokeWidth` property. - - This property corresponds to the `circle-stroke-width-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition circleStrokeWidthTransition; - -#if TARGET_OS_IPHONE -/** - The geometry's offset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points downward. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-circle-translate"><code>circle-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *circleTranslation; -#else -/** - The geometry's offset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points upward. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-circle-translate"><code>circle-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *circleTranslation; -#endif - -/** - The transition affecting any changes to this layer’s `circleTranslation` property. - - This property corresponds to the `circle-translate-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition circleTranslationTransition; - -@property (nonatomic, null_resettable) NSExpression *circleTranslate __attribute__((unavailable("Use circleTranslation instead."))); - -/** - Controls the frame of reference for `circleTranslation`. - - The default value of this property is an expression that evaluates to `map`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `circleTranslation` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-circle-translate-anchor"><code>circle-translate-anchor</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLCircleTranslationAnchor` values - * Any of the following constant string values: - * `map`: The circle is translated relative to the map. - * `viewport`: The circle is translated relative to the viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *circleTranslationAnchor; - -@property (nonatomic, null_resettable) NSExpression *circleTranslateAnchor __attribute__((unavailable("Use circleTranslationAnchor instead."))); - -@end - -/** - Methods for wrapping an enumeration value for a style layer attribute in an - `MGLCircleStyleLayer` object and unwrapping its raw value. - */ -@interface NSValue (MGLCircleStyleLayerAdditions) - -#pragma mark Working with Circle Style Layer Attribute Values - -/** - Creates a new value object containing the given `MGLCirclePitchAlignment` enumeration. - - @param circlePitchAlignment The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLCirclePitchAlignment:(MGLCirclePitchAlignment)circlePitchAlignment; - -/** - The `MGLCirclePitchAlignment` enumeration representation of the value. - */ -@property (readonly) MGLCirclePitchAlignment MGLCirclePitchAlignmentValue; - -/** - Creates a new value object containing the given `MGLCircleScaleAlignment` enumeration. - - @param circleScaleAlignment The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLCircleScaleAlignment:(MGLCircleScaleAlignment)circleScaleAlignment; - -/** - The `MGLCircleScaleAlignment` enumeration representation of the value. - */ -@property (readonly) MGLCircleScaleAlignment MGLCircleScaleAlignmentValue; - -/** - Creates a new value object containing the given `MGLCircleTranslationAnchor` enumeration. - - @param circleTranslationAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLCircleTranslationAnchor:(MGLCircleTranslationAnchor)circleTranslationAnchor; - -/** - The `MGLCircleTranslationAnchor` enumeration representation of the value. - */ -@property (readonly) MGLCircleTranslationAnchor MGLCircleTranslationAnchorValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm deleted file mode 100644 index 6f82d85ce1..0000000000 --- a/platform/darwin/src/MGLCircleStyleLayer.mm +++ /dev/null @@ -1,477 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLCircleStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLCircleStyleLayer_Private.h" - -#include <mbgl/style/layers/circle_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLCirclePitchAlignment, { - { MGLCirclePitchAlignmentMap, "map" }, - { MGLCirclePitchAlignmentViewport, "viewport" }, - }); - - MBGL_DEFINE_ENUM(MGLCircleScaleAlignment, { - { MGLCircleScaleAlignmentMap, "map" }, - { MGLCircleScaleAlignmentViewport, "viewport" }, - }); - - MBGL_DEFINE_ENUM(MGLCircleTranslationAnchor, { - { MGLCircleTranslationAnchorMap, "map" }, - { MGLCircleTranslationAnchorViewport, "viewport" }, - }); - -} - -@interface MGLCircleStyleLayer () - -@property (nonatomic, readonly) mbgl::style::CircleLayer *rawLayer; - -@end - -@implementation MGLCircleStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::CircleLayer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::CircleLayer *)rawLayer -{ - return (mbgl::style::CircleLayer *)super.rawLayer; -} - -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -- (NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - - auto layerID = self.rawLayer->getSourceLayer(); - return layerID.empty() ? nil : @(layerID.c_str()); -} - -- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting sourceLayerIdentifier: %@", sourceLayerIdentifier); - - self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); -} - -- (void)setPredicate:(NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting predicate: %@", predicate); - - self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::Filter()); -} - -- (NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - - return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setCircleBlur:(NSExpression *)circleBlur { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleBlur: %@", circleBlur); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(circleBlur, true); - self.rawLayer->setCircleBlur(mbglValue); -} - -- (NSExpression *)circleBlur { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleBlur(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleBlur(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setCircleBlurTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleBlurTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setCircleBlurTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)circleBlurTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getCircleBlurTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setCircleColor:(NSExpression *)circleColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleColor: %@", circleColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(circleColor, true); - self.rawLayer->setCircleColor(mbglValue); -} - -- (NSExpression *)circleColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setCircleColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setCircleColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)circleColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getCircleColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setCircleOpacity:(NSExpression *)circleOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleOpacity: %@", circleOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(circleOpacity, true); - self.rawLayer->setCircleOpacity(mbglValue); -} - -- (NSExpression *)circleOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setCircleOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setCircleOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)circleOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getCircleOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setCirclePitchAlignment:(NSExpression *)circlePitchAlignment { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circlePitchAlignment: %@", circlePitchAlignment); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLCirclePitchAlignment>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::AlignmentType>>(circlePitchAlignment, false); - self.rawLayer->setCirclePitchAlignment(mbglValue); -} - -- (NSExpression *)circlePitchAlignment { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCirclePitchAlignment(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCirclePitchAlignment(); - } - return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLCirclePitchAlignment>().toExpression(propertyValue); -} - -- (void)setCircleRadius:(NSExpression *)circleRadius { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleRadius: %@", circleRadius); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(circleRadius, true); - self.rawLayer->setCircleRadius(mbglValue); -} - -- (NSExpression *)circleRadius { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleRadius(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleRadius(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setCircleRadiusTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleRadiusTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setCircleRadiusTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)circleRadiusTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getCircleRadiusTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setCircleScaleAlignment:(NSExpression *)circleScaleAlignment { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleScaleAlignment: %@", circleScaleAlignment); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::CirclePitchScaleType, NSValue *, mbgl::style::CirclePitchScaleType, MGLCircleScaleAlignment>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::CirclePitchScaleType>>(circleScaleAlignment, false); - self.rawLayer->setCirclePitchScale(mbglValue); -} - -- (NSExpression *)circleScaleAlignment { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCirclePitchScale(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCirclePitchScale(); - } - return MGLStyleValueTransformer<mbgl::style::CirclePitchScaleType, NSValue *, mbgl::style::CirclePitchScaleType, MGLCircleScaleAlignment>().toExpression(propertyValue); -} - -- (void)setCirclePitchScale:(NSExpression *)circlePitchScale { -} - -- (NSExpression *)circlePitchScale { - return self.circleScaleAlignment; -} - -- (void)setCircleStrokeColor:(NSExpression *)circleStrokeColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleStrokeColor: %@", circleStrokeColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(circleStrokeColor, true); - self.rawLayer->setCircleStrokeColor(mbglValue); -} - -- (NSExpression *)circleStrokeColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleStrokeColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleStrokeColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setCircleStrokeColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleStrokeColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setCircleStrokeColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)circleStrokeColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getCircleStrokeColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setCircleStrokeOpacity:(NSExpression *)circleStrokeOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleStrokeOpacity: %@", circleStrokeOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(circleStrokeOpacity, true); - self.rawLayer->setCircleStrokeOpacity(mbglValue); -} - -- (NSExpression *)circleStrokeOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleStrokeOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleStrokeOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setCircleStrokeOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleStrokeOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setCircleStrokeOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)circleStrokeOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getCircleStrokeOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setCircleStrokeWidth:(NSExpression *)circleStrokeWidth { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleStrokeWidth: %@", circleStrokeWidth); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(circleStrokeWidth, true); - self.rawLayer->setCircleStrokeWidth(mbglValue); -} - -- (NSExpression *)circleStrokeWidth { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleStrokeWidth(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleStrokeWidth(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setCircleStrokeWidthTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleStrokeWidthTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setCircleStrokeWidthTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)circleStrokeWidthTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getCircleStrokeWidthTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setCircleTranslation:(NSExpression *)circleTranslation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleTranslation: %@", circleTranslation); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 2>>>(circleTranslation, false); - self.rawLayer->setCircleTranslate(mbglValue); -} - -- (NSExpression *)circleTranslation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleTranslate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleTranslate(); - } - return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toExpression(propertyValue); -} - -- (void)setCircleTranslationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleTranslationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setCircleTranslateTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)circleTranslationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getCircleTranslateTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setCircleTranslate:(NSExpression *)circleTranslate { -} - -- (NSExpression *)circleTranslate { - return self.circleTranslation; -} - -- (void)setCircleTranslationAnchor:(NSExpression *)circleTranslationAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting circleTranslationAnchor: %@", circleTranslationAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLCircleTranslationAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::TranslateAnchorType>>(circleTranslationAnchor, false); - self.rawLayer->setCircleTranslateAnchor(mbglValue); -} - -- (NSExpression *)circleTranslationAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getCircleTranslateAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultCircleTranslateAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLCircleTranslationAnchor>().toExpression(propertyValue); -} - -- (void)setCircleTranslateAnchor:(NSExpression *)circleTranslateAnchor { -} - -- (NSExpression *)circleTranslateAnchor { - return self.circleTranslationAnchor; -} - -@end - -@implementation NSValue (MGLCircleStyleLayerAdditions) - -+ (NSValue *)valueWithMGLCirclePitchAlignment:(MGLCirclePitchAlignment)circlePitchAlignment { - return [NSValue value:&circlePitchAlignment withObjCType:@encode(MGLCirclePitchAlignment)]; -} - -- (MGLCirclePitchAlignment)MGLCirclePitchAlignmentValue { - MGLCirclePitchAlignment circlePitchAlignment; - [self getValue:&circlePitchAlignment]; - return circlePitchAlignment; -} - -+ (NSValue *)valueWithMGLCircleScaleAlignment:(MGLCircleScaleAlignment)circleScaleAlignment { - return [NSValue value:&circleScaleAlignment withObjCType:@encode(MGLCircleScaleAlignment)]; -} - -- (MGLCircleScaleAlignment)MGLCircleScaleAlignmentValue { - MGLCircleScaleAlignment circleScaleAlignment; - [self getValue:&circleScaleAlignment]; - return circleScaleAlignment; -} - -+ (NSValue *)valueWithMGLCircleTranslationAnchor:(MGLCircleTranslationAnchor)circleTranslationAnchor { - return [NSValue value:&circleTranslationAnchor withObjCType:@encode(MGLCircleTranslationAnchor)]; -} - -- (MGLCircleTranslationAnchor)MGLCircleTranslationAnchorValue { - MGLCircleTranslationAnchor circleTranslationAnchor; - [self getValue:&circleTranslationAnchor]; - return circleTranslationAnchor; -} - -@end - -namespace mbgl { - -MGLStyleLayer* CircleStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLCircleStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLCircleStyleLayer_Private.h b/platform/darwin/src/MGLCircleStyleLayer_Private.h deleted file mode 100644 index 788de6274f..0000000000 --- a/platform/darwin/src/MGLCircleStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/circle_layer_factory.hpp> - -namespace mbgl { - -class CircleStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::CircleLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLClockDirectionFormatter.h b/platform/darwin/src/MGLClockDirectionFormatter.h deleted file mode 100644 index 86a9452846..0000000000 --- a/platform/darwin/src/MGLClockDirectionFormatter.h +++ /dev/null @@ -1,46 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLClockDirectionFormatter` class provides properly formatted descriptions - of headings relative to the user, known as <i>clock positions</i>. For - example, a value of `90` may be formatted as “3 o’clock”, depending on the - locale. - - Use this class to create localized heading strings when displaying directions - relative to the user’s current location and heading. To format a direction - irrespective of the user’s orientation, use `MGLCompassDirectionFormatter` - instead. - */ -MGL_EXPORT -@interface MGLClockDirectionFormatter : NSFormatter - -/** - The unit style used by this formatter. - - This property defaults to `NSFormattingUnitStyleMedium`. - */ -@property (nonatomic) NSFormattingUnitStyle unitStyle; - -/** - Returns a clock position string for the provided value. - - @param direction The heading, measured in degrees, where 0° means “straight - ahead” and 90° means “directly to your right”. - @return The clock position string appropriately formatted for the receiver’s - locale. - */ -- (NSString *)stringFromDirection:(CLLocationDirection)direction; - -/** - This method is not supported for the `MGLDirectionFormatter` class. - */ -- (BOOL)getObjectValue:(out id __nullable * __nullable)obj forString:(NSString *)string errorDescription:(out NSString * __nullable * __nullable)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLClockDirectionFormatter.m b/platform/darwin/src/MGLClockDirectionFormatter.m deleted file mode 100644 index 922a1db9a2..0000000000 --- a/platform/darwin/src/MGLClockDirectionFormatter.m +++ /dev/null @@ -1,60 +0,0 @@ -#import "MGLClockDirectionFormatter.h" - -#import "NSBundle+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#define wrap(value, min, max) \ - (fmod((fmod((value - min), (max - min)) + (max - min)), (max - min)) + min) - -@implementation MGLClockDirectionFormatter { - NSNumberFormatter *_numberFormatter; -} - -- (instancetype)init { - if (self = [super init]) { - _unitStyle = NSFormattingUnitStyleMedium; - _numberFormatter = [[NSNumberFormatter alloc] init]; - _numberFormatter.numberStyle = NSNumberFormatterDecimalStyle; - } - return self; -} - -- (NSString *)stringFromDirection:(CLLocationDirection)direction { - NSInteger hour = round(wrap(direction, 0, 360) / 360 * 12); - if (hour == 0) { - hour = 12; - } - NSString *format; - switch (self.unitStyle) { - case NSFormattingUnitStyleShort: - format = NSLocalizedStringWithDefaultValue(@"CLOCK_FMT_SHORT", @"Foundation", nil, @"%@:00", @"Clock position format, short: {hours}:00"); - break; - - case NSFormattingUnitStyleMedium: - format = NSLocalizedStringWithDefaultValue(@"CLOCK_FMT_MEDIUM", @"Foundation", nil, @"%@ o’clock", @"Clock position format, medium: {hours} o’clock"); - - break; - - case NSFormattingUnitStyleLong: - format = NSLocalizedStringWithDefaultValue(@"CLOCK_FMT_LONG", @"Foundation", nil, @"%@ o’clock", @"Clock position format, long: {hours} o’clock"); - break; - - default: - break; - } - return [NSString stringWithFormat:format, [_numberFormatter stringFromNumber:@(hour)]]; -} - -- (nullable NSString *)stringForObjectValue:(id)obj { - if (![obj isKindOfClass:[NSValue class]]) { - return nil; - } - return [self stringFromDirection:[obj doubleValue]]; -} - -- (BOOL)getObjectValue:(out id __nullable * __nullable)obj forString:(NSString *)string errorDescription:(out NSString * __nullable * __nullable)error { - MGLAssert(NO, @"-getObjectValue:forString:errorDescription: has not been implemented"); - return NO; -} - -@end diff --git a/platform/darwin/src/MGLCluster.h b/platform/darwin/src/MGLCluster.h deleted file mode 100644 index 2b99119b26..0000000000 --- a/platform/darwin/src/MGLCluster.h +++ /dev/null @@ -1,53 +0,0 @@ -#import "MGLFoundation.h" - -@protocol MGLFeature; - -NS_ASSUME_NONNULL_BEGIN - -/** - An `NSUInteger` constant used to indicate an invalid cluster identifier. - This indicates a missing cluster feature. - */ -FOUNDATION_EXTERN MGL_EXPORT const NSUInteger MGLClusterIdentifierInvalid; - -/** - A protocol that feature subclasses (i.e. those already conforming to - the `MGLFeature` protocol) conform to if they represent clusters. - - Currently the only class that conforms to `MGLCluster` is - `MGLPointFeatureCluster` (a subclass of `MGLPointFeature`). - - To check if a feature is a cluster, check conformity to `MGLCluster`, for - example: - - ```swift - let shape = try! MGLShape(data: clusterShapeData, encoding: String.Encoding.utf8.rawValue) - - guard let pointFeature = shape as? MGLPointFeature else { - throw ExampleError.unexpectedFeatureType - } - - // Check for cluster conformance - guard let cluster = pointFeature as? MGLCluster else { - throw ExampleError.featureIsNotACluster - } - - // Currently the only supported class that conforms to `MGLCluster` is - // `MGLPointFeatureCluster` - guard cluster is MGLPointFeatureCluster else { - throw ExampleError.unexpectedFeatureType - } - ``` - */ -MGL_EXPORT -@protocol MGLCluster <MGLFeature> - -/** The identifier for the cluster. */ -@property (nonatomic, readonly) NSUInteger clusterIdentifier; - -/** The number of points within this cluster */ -@property (nonatomic, readonly) NSUInteger clusterPointCount; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLCompassDirectionFormatter.h b/platform/darwin/src/MGLCompassDirectionFormatter.h deleted file mode 100644 index b4a3087509..0000000000 --- a/platform/darwin/src/MGLCompassDirectionFormatter.h +++ /dev/null @@ -1,43 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLCompassDirectionFormatter` class provides properly formatted - descriptions of absolute headings. For example, a value of `90` may be - formatted as “east”, depending on the locale. - - Use this class to create localized heading strings when displaying directions - irrespective of the user’s current location. To format a direction relative to - the user’s current location, use `MGLClockDirectionFormatter` instead. - */ -MGL_EXPORT -@interface MGLCompassDirectionFormatter : NSFormatter - -/** - The unit style used by this formatter. - - This property defaults to `NSFormattingUnitStyleMedium`. - */ -@property (nonatomic) NSFormattingUnitStyle unitStyle; - -/** - Returns a heading string for the provided value. - - @param direction The heading, measured in degrees, where 0° means “due north” - and 90° means “due east”. - @return The heading string appropriately formatted for the formatter’s locale. - */ -- (NSString *)stringFromDirection:(CLLocationDirection)direction; - -/** - This method is not supported for the `MGLDirectionFormatter` class. - */ -- (BOOL)getObjectValue:(out id __nullable * __nullable)obj forString:(NSString *)string errorDescription:(out NSString * __nullable * __nullable)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLCompassDirectionFormatter.m b/platform/darwin/src/MGLCompassDirectionFormatter.m deleted file mode 100644 index 99de32b777..0000000000 --- a/platform/darwin/src/MGLCompassDirectionFormatter.m +++ /dev/null @@ -1,125 +0,0 @@ -#import "MGLCompassDirectionFormatter.h" - -#import "NSBundle+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#define wrap(value, min, max) \ - (fmod((fmod((value - min), (max - min)) + (max - min)), (max - min)) + min) - -@implementation MGLCompassDirectionFormatter - -- (instancetype)init { - if (self = [super init]) { - _unitStyle = NSFormattingUnitStyleMedium; - } - return self; -} - -- (NSString *)stringFromDirection:(CLLocationDirection)direction { - static NSArray<NSString *> *shortStrings; - static NSArray<NSString *> *longStrings; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - shortStrings = @[ - NSLocalizedStringWithDefaultValue(@"COMPASS_N_SHORT", @"Foundation", nil, @"N", @"North, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NbE_SHORT", @"Foundation", nil, @"NbE", @"North by east, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NNE_SHORT", @"Foundation", nil, @"NNE", @"North-northeast, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NEbN_SHORT", @"Foundation", nil, @"NEbN", @"Northeast by north, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NE_SHORT", @"Foundation", nil, @"NE", @"Northeast, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NEbE_SHORT", @"Foundation", nil, @"NEbE", @"Northeast by east, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_ENE_SHORT", @"Foundation", nil, @"ENE", @"East-northeast, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_EbN_SHORT", @"Foundation", nil, @"EbN", @"East by north, short"), - - NSLocalizedStringWithDefaultValue(@"COMPASS_E_SHORT", @"Foundation", nil, @"E", @"East, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_EbS_SHORT", @"Foundation", nil, @"EbS", @"East by south, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_ESE_SHORT", @"Foundation", nil, @"ESE", @"East-southeast, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SEbE_SHORT", @"Foundation", nil, @"SEbE", @"Southeast by east, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SE_SHORT", @"Foundation", nil, @"SE", @"Southeast, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SEbS_SHORT", @"Foundation", nil, @"SEbS", @"Southeast by south, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SSE_SHORT", @"Foundation", nil, @"SSE", @"South-southeast, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SbE_SHORT", @"Foundation", nil, @"SbE", @"South by east, short"), - - NSLocalizedStringWithDefaultValue(@"COMPASS_S_SHORT", @"Foundation", nil, @"S", @"South, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SbW_SHORT", @"Foundation", nil, @"SbW", @"South by west, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SSW_SHORT", @"Foundation", nil, @"SSW", @"South-southwest, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SWbS_SHORT", @"Foundation", nil, @"SWbS", @"Southwest by south, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SW_SHORT", @"Foundation", nil, @"SW", @"Southwest, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SWbW_SHORT", @"Foundation", nil, @"SWbW", @"Southwest by west, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_WSW_SHORT", @"Foundation", nil, @"WSW", @"West-southwest, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_WbS_SHORT", @"Foundation", nil, @"WbS", @"West by south, short"), - - NSLocalizedStringWithDefaultValue(@"COMPASS_W_SHORT", @"Foundation", nil, @"W", @"West, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_WbN_SHORT", @"Foundation", nil, @"WbN", @"West by north, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_WNW_SHORT", @"Foundation", nil, @"WNW", @"West-northwest, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NWbW_SHORT", @"Foundation", nil, @"NWbW", @"Northwest by west, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NW_SHORT", @"Foundation", nil, @"NW", @"Northwest, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NWbN_SHORT", @"Foundation", nil, @"NWbN", @"Northwest by north, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NNW_SHORT", @"Foundation", nil, @"NNW", @"North-northwest, short"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NbW_SHORT", @"Foundation", nil, @"NbW", @"North by west, short"), - ]; - - longStrings = @[ - NSLocalizedStringWithDefaultValue(@"COMPASS_N_LONG", @"Foundation", nil, @"north", @"North, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NbE_LONG", @"Foundation", nil, @"north by east", @"North by east, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NNE_LONG", @"Foundation", nil, @"north-northeast", @"North-northeast, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NEbN_LONG", @"Foundation", nil, @"northeast by north", @"Northeast by north, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NE_LONG", @"Foundation", nil, @"northeast", @"Northeast, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NEbE_LONG", @"Foundation", nil, @"northeast by east", @"Northeast by east, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_ENE_LONG", @"Foundation", nil, @"east-northeast", @"East-northeast, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_EbN_LONG", @"Foundation", nil, @"east by north", @"East by north, long"), - - NSLocalizedStringWithDefaultValue(@"COMPASS_E_LONG", @"Foundation", nil, @"east", @"East, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_EbS_LONG", @"Foundation", nil, @"east by south", @"East by south, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_ESE_LONG", @"Foundation", nil, @"east-southeast", @"East-southeast, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SEbE_LONG", @"Foundation", nil, @"southeast by east", @"Southeast by east, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SE_LONG", @"Foundation", nil, @"southeast", @"Southeast, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SEbS_LONG", @"Foundation", nil, @"southeast by south", @"Southeast by south, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SSE_LONG", @"Foundation", nil, @"south-southeast", @"South-southeast, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SbE_LONG", @"Foundation", nil, @"south by east", @"South by east, long"), - - NSLocalizedStringWithDefaultValue(@"COMPASS_S_LONG", @"Foundation", nil, @"south", @"South, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SbW_LONG", @"Foundation", nil, @"south by west", @"South by west, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SSW_LONG", @"Foundation", nil, @"south-southwest", @"South-southwest, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SWbS_LONG", @"Foundation", nil, @"southwest by south", @"Southwest by south, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SW_LONG", @"Foundation", nil, @"southwest", @"Southwest, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_SWbW_LONG", @"Foundation", nil, @"southwest by west", @"Southwest by west, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_WSW_LONG", @"Foundation", nil, @"west-southwest", @"West-southwest, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_WbS_LONG", @"Foundation", nil, @"west by south", @"West by south, long"), - - NSLocalizedStringWithDefaultValue(@"COMPASS_W_LONG", @"Foundation", nil, @"west", @"West, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_WbN_LONG", @"Foundation", nil, @"west by north", @"West by north, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_WNW_LONG", @"Foundation", nil, @"west-northwest", @"West-northwest, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NWbW_LONG", @"Foundation", nil, @"northwest by west", @"Northwest by west, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NW_LONG", @"Foundation", nil, @"northwest", @"Northwest, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NWbN_LONG", @"Foundation", nil, @"northwest by north", @"Northwest by north, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NNW_LONG", @"Foundation", nil, @"north-northwest", @"North-northwest, long"), - NSLocalizedStringWithDefaultValue(@"COMPASS_NbW_LONG", @"Foundation", nil, @"north by west", @"North by west, long"), - ]; - - MGLAssert(shortStrings.count == longStrings.count, @"Long and short compass direction string arrays must have the same size."); - }); - - NSInteger cardinalPoint = wrap(round(wrap(direction, 0, 360) / 360 * shortStrings.count), 0, shortStrings.count); - switch (self.unitStyle) { - case NSFormattingUnitStyleShort: - return shortStrings[cardinalPoint]; - - case NSFormattingUnitStyleMedium: - case NSFormattingUnitStyleLong: - return longStrings[cardinalPoint]; - } -} - -- (nullable NSString *)stringForObjectValue:(id)obj { - if (![obj isKindOfClass:[NSValue class]]) { - return nil; - } - return [self stringFromDirection:[obj doubleValue]]; -} - -- (BOOL)getObjectValue:(out id __nullable * __nullable)obj forString:(NSString *)string errorDescription:(out NSString * __nullable * __nullable)error { - MGLAssert(NO, @"-getObjectValue:forString:errorDescription: has not been implemented"); - return NO; -} - -@end diff --git a/platform/darwin/src/MGLComputedShapeSource.h b/platform/darwin/src/MGLComputedShapeSource.h deleted file mode 100644 index 84dc4801a7..0000000000 --- a/platform/darwin/src/MGLComputedShapeSource.h +++ /dev/null @@ -1,167 +0,0 @@ -#import "MGLFoundation.h" -#import "MGLGeometry.h" -#import "MGLTypes.h" -#import "MGLShapeSource.h" - -NS_ASSUME_NONNULL_BEGIN - -@protocol MGLFeature; - -/** - An `NSNumber` object containing a Boolean value; specifies whether the shape of - an `MGLComputedShapeSource` should be wrapped to accomodate coordinates with - longitudes beyond −180 and 180. The default value is `NO`. - - Setting this option to `YES` affects rendering performance. - - This option is used with the `MGLComputedShapeSource` class; it is ignored when - creating an `MGLShapeSource` object. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionWrapsCoordinates; - -/** - An `NSNumber` object containing a Boolean value; specifies whether the shape of - an `MGLComputedShapeSource` should be clipped at the edge of each tile. The - default value is `NO`. - - Setting this option to `YES` affects rendering performance. Use this option to - clip `MGLPolyline`s and `MGLPolygon`s at tile boundaries without artifacts. - - This option is used with the `MGLComputedShapeSource` class; it is ignored when - creating an `MGLShapeSource` object. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClipsCoordinates; - -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLInvalidDatasourceException; - -/** - Data source for `MGLComputedShapeSource`. This protocol defines two optional methods for fetching - data, one based on tile coordinates, and one based on a bounding box. Classes that implement this - protocol must implement one, and only one of the methods. Methods on this protocol will not be - called on main thread, they will be called on the caller's `requestQueue`. - */ -@protocol MGLComputedShapeSourceDataSource <NSObject> - -@optional -/** - Fetch features for a tile. This method will not be invoked on the main queue, it - will be invoked on the caller's `requestQueue`. - @param x Tile X coordinate. - @param y Tile Y coordinate. - @param zoomLevel Tile zoom level. - */ -- (NSArray<MGLShape <MGLFeature> *>*)featuresInTileAtX:(NSUInteger)x y:(NSUInteger)y zoomLevel:(NSUInteger)zoomLevel; - -/** - Fetch features for a tile. This method will not be invoked on the main queue, it - will be invoked on the caller's `requestQueue`. - @param bounds The bounds to fetch data for. - @param zoomLevel Tile zoom level. - */ -- (NSArray<MGLShape <MGLFeature> *>*)featuresInCoordinateBounds:(MGLCoordinateBounds)bounds zoomLevel:(NSUInteger)zoomLevel; - -@end - -/** - `MGLComputedShapeSource` is a map content source that supplies vector shapes, - one tile at a time, to be shown on the map on demand. You implement a class - conforming to the `MGLComputedShapeSourceDataSource` protocol that returns - instances of `MGLShape` or `MGLFeature`, then add a computed shape source to an - `MGLStyle` object along with an `MGLVectorStyleLayer` object. The vector style - layer defines the appearance of any content supplied by the computed shape - source. - - `MGLComputedShapeSource` is similar to `MGLShapeSource` but is optimized for - data sets that change dynamically or are too large to fit completely in memory. - It is also useful for data that is divided into tiles in a format other than - <a href="https://www.mapbox.com/vector-tiles/">Mapbox Vector Tiles</a>. For - <a href="http://geojson.org/">GeoJSON</a> data, use the `MGLShapeSource` class. - For static tiles or Mapbox Vector Tiles, use the `MGLVectorTileSource` class. - - You can add and remove sources dynamically using methods such as - `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`. This class - cannot be represented in a style JSON file; you must add it ot the style at - runtime. - */ -MGL_EXPORT -@interface MGLComputedShapeSource : MGLSource - -/** - Returns a custom shape data source initialized with an identifier, and a - dictionary of options for the source according to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">style - specification</a>. - - This class supports the following options: - `MGLShapeSourceOptionMinimumZoomLevel`, `MGLShapeSourceOptionMaximumZoomLevel`, - `MGLShapeSourceOptionBuffer`, - `MGLShapeSourceOptionSimplificationTolerance`, - `MGLShapeSourceOptionWrapsCoordinates`, and - `MGLShapeSourceOptionClipsCoordinates`. Shapes provided by a computed - shape source cannot be clustered. - - @param identifier A string that uniquely identifies the source. - @param options An `NSDictionary` of options for this source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier options:(nullable NSDictionary<MGLShapeSourceOption, id> *)options NS_DESIGNATED_INITIALIZER; - -/** - Returns a custom shape data source initialized with an identifier, data source, and a - dictionary of options for the source according to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">style - specification</a>. - - This class supports the following options: - `MGLShapeSourceOptionMinimumZoomLevel`, `MGLShapeSourceOptionMaximumZoomLevel`, - `MGLShapeSourceOptionBuffer`, - `MGLShapeSourceOptionSimplificationTolerance`, - `MGLShapeSourceOptionWrapsCoordinates`, and - `MGLShapeSourceOptionClipsCoordinates`. Shapes provided by a computed shape - source cannot be clustered. - - @param identifier A string that uniquely identifies the source. - @param options An `NSDictionary` of options for this source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier dataSource:(id<MGLComputedShapeSourceDataSource>)dataSource options:(nullable NSDictionary<MGLShapeSourceOption, id> *)options; - -/** - Invalidates all the features and properties intersecting with or contained in - the specified bounds. New fetch requests will immediately be invoked on the - `MGLComputedShapeSourceDataSource`. - @param bounds Coordinate bounds to invalidate. - */ -- (void) invalidateBounds:(MGLCoordinateBounds)bounds; - -/** - Invalidates all the feautres and properties of a given tile. A new fetch request - will immediately be invoked on the `MGLComputedShapeSourceDataSource`. - @param x Tile X coordinate. - @param y Tile Y coordinate. - @param zoomLevel Tile zoom level. - */ -- (void) invalidateTileAtX:(NSUInteger)x y:(NSUInteger)y zoomLevel:(NSUInteger)zoomLevel; - -/** - Set a new set of features for a tile. This method can be invkoed from background threads. - For best performance, use this method only to update tiles that have already been requested - through `MGLComputedShapeSourceDataSource.` - @param features Features for the tile. - @param x Tile X coordinate. - @param y Tile Y coordinate. - @param zoomLevel Tile zoom level. - */ -- (void) setFeatures:(NSArray<MGLShape <MGLFeature> *>*)features inTileAtX:(NSUInteger)x y:(NSUInteger)y zoomLevel:(NSUInteger)zoomLevel; - -/** - An object that implements the `MGLComputedShapeSourceDataSource` protocol that will be queried for tile data. - */ -@property (nonatomic, weak, nullable) id<MGLComputedShapeSourceDataSource> dataSource; - -/** - A queue that calls to the data source will be made on. - */ -@property (nonatomic, readonly) NSOperationQueue *requestQueue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLComputedShapeSource.mm b/platform/darwin/src/MGLComputedShapeSource.mm deleted file mode 100644 index ceb83b3740..0000000000 --- a/platform/darwin/src/MGLComputedShapeSource.mm +++ /dev/null @@ -1,249 +0,0 @@ -#import "MGLComputedShapeSource_Private.h" - -#import "MGLMapView_Private.h" -#import "MGLSource_Private.h" -#import "MGLShape_Private.h" -#import "MGLGeometry_Private.h" -#import "MGLShapeCollection.h" - -#include <mbgl/map/map.hpp> -#include <mbgl/style/sources/custom_geometry_source.hpp> -#include <mbgl/tile/tile_id.hpp> -#include <mbgl/util/geojson.hpp> - -const MGLExceptionName MGLInvalidDatasourceException = @"MGLInvalidDatasourceException"; - -const MGLShapeSourceOption MGLShapeSourceOptionWrapsCoordinates = @"MGLShapeSourceOptionWrapsCoordinates"; -const MGLShapeSourceOption MGLShapeSourceOptionClipsCoordinates = @"MGLShapeSourceOptionClipsCoordinates"; - -mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDictionary(NSDictionary<MGLShapeSourceOption, id> *options) { - mbgl::style::CustomGeometrySource::Options sourceOptions; - - if (NSNumber *value = options[MGLShapeSourceOptionMinimumZoomLevel]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionMinimumZoomLevel must be an NSNumber."]; - } - sourceOptions.zoomRange.min = value.integerValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionMaximumZoomLevel]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionMaximumZoomLevel must be an NSNumber."]; - } - sourceOptions.zoomRange.max = value.integerValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionBuffer]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionBuffer must be an NSNumber."]; - } - sourceOptions.tileOptions.buffer = value.integerValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionSimplificationTolerance]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionSimplificationTolerance must be an NSNumber."]; - } - sourceOptions.tileOptions.tolerance = value.doubleValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionWrapsCoordinates]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionWrapsCoordinates must be an NSNumber."]; - } - sourceOptions.tileOptions.wrap = value.boolValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionClipsCoordinates]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionClipsCoordinates must be an NSNumber."]; - } - sourceOptions.tileOptions.clip = value.boolValue; - } - - return sourceOptions; -} - -@interface MGLComputedShapeSource () { - std::unique_ptr<mbgl::style::CustomGeometrySource> _pendingSource; -} - -@property (nonatomic, readwrite) NSDictionary *options; -@property (nonatomic, assign) BOOL dataSourceImplementsFeaturesForTile; -@property (nonatomic, assign) BOOL dataSourceImplementsFeaturesForBounds; - -@end - -@interface MGLComputedShapeSourceFetchOperation : NSOperation - -@property (nonatomic, readonly) uint8_t z; -@property (nonatomic, readonly) uint32_t x; -@property (nonatomic, readonly) uint32_t y; -@property (nonatomic, assign) BOOL dataSourceImplementsFeaturesForTile; -@property (nonatomic, assign) BOOL dataSourceImplementsFeaturesForBounds; -@property (nonatomic, weak, nullable) id<MGLComputedShapeSourceDataSource> dataSource; -@property (nonatomic, nullable) mbgl::style::CustomGeometrySource *rawSource; - -- (instancetype)initForSource:(MGLComputedShapeSource*)source tile:(const mbgl::CanonicalTileID&)tileId; - -@end - -@implementation MGLComputedShapeSourceFetchOperation - -- (instancetype)initForSource:(MGLComputedShapeSource*)source tile:(const mbgl::CanonicalTileID&)tileID { - self = [super init]; - _z = tileID.z; - _x = tileID.x; - _y = tileID.y; - _dataSourceImplementsFeaturesForTile = source.dataSourceImplementsFeaturesForTile; - _dataSourceImplementsFeaturesForBounds = source.dataSourceImplementsFeaturesForBounds; - _dataSource = source.dataSource; - mbgl::style::CustomGeometrySource *rawSource = static_cast<mbgl::style::CustomGeometrySource *>(source.rawSource); - _rawSource = rawSource; - return self; -} - -- (void)main { - if ([self isCancelled]) { - return; - } - - NSArray<MGLShape <MGLFeature> *> *data; - if(!self.dataSource) { - data = nil; - } else if(self.dataSourceImplementsFeaturesForTile) { - data = [self.dataSource featuresInTileAtX:self.x - y:self.y - zoomLevel:self.z]; - } else { - mbgl::CanonicalTileID tileID = mbgl::CanonicalTileID(self.z, self.x, self.y); - mbgl::LatLngBounds tileBounds = mbgl::LatLngBounds(tileID); - data = [self.dataSource featuresInCoordinateBounds:MGLCoordinateBoundsFromLatLngBounds(tileBounds) - zoomLevel:self.z]; - } - - if(![self isCancelled]) { - mbgl::FeatureCollection featureCollection; - featureCollection.reserve(data.count); - for (MGLShape <MGLFeature> * feature in data) { - if ([feature isMemberOfClass:[MGLShapeCollection class]]) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSLog(@"MGLShapeCollection initialized with MGLFeatures will not retain attributes." - @"Use MGLShapeCollectionFeature to retain attributes instead." - @"This will be logged only once."); - }); - } - mbgl::GeoJSONFeature geoJsonObject = [feature geoJSONObject].get<mbgl::GeoJSONFeature>(); - featureCollection.push_back(geoJsonObject); - } - const auto geojson = mbgl::GeoJSON{featureCollection}; - if(![self isCancelled] && self.rawSource) { - self.rawSource->setTileData(mbgl::CanonicalTileID(self.z, self.x, self.y), geojson); - } - } -} - -- (void)cancel { - [super cancel]; - self.rawSource = NULL; -} - -@end - -@implementation MGLComputedShapeSource - -- (instancetype)initWithIdentifier:(NSString *)identifier options:(NSDictionary<MGLShapeSourceOption, id> *)options { - NSOperationQueue *requestQueue = [[NSOperationQueue alloc] init]; - requestQueue.name = [NSString stringWithFormat:@"mgl.MGLComputedShapeSource.%@", identifier]; - requestQueue.qualityOfService = NSQualityOfServiceUtility; - requestQueue.maxConcurrentOperationCount = 4; - - auto sourceOptions = MBGLCustomGeometrySourceOptionsFromDictionary(options); - sourceOptions.fetchTileFunction = ^void(const mbgl::CanonicalTileID& tileID) { - NSOperation *operation = [[MGLComputedShapeSourceFetchOperation alloc] initForSource:self tile:tileID]; - [requestQueue addOperation:operation]; - }; - - sourceOptions.cancelTileFunction = ^void(const mbgl::CanonicalTileID& tileID) { - for (MGLComputedShapeSourceFetchOperation *operation in requestQueue.operations) { - if (operation.x == tileID.x && operation.y == tileID.y && operation.z == tileID.z) { - [operation cancel]; - } - } - }; - - auto source = std::make_unique<mbgl::style::CustomGeometrySource>(identifier.UTF8String, sourceOptions); - - if (self = [super initWithPendingSource:std::move(source)]) { - _requestQueue = requestQueue; - } - return self; -} - -- (instancetype)initWithIdentifier:(NSString *)identifier dataSource:(id<MGLComputedShapeSourceDataSource>)dataSource options:(NSDictionary<MGLShapeSourceOption, id> *)options { - if (self = [self initWithIdentifier:identifier options:options]) { - [self setDataSource:dataSource]; - } - return self; -} - -- (void)dealloc { - [self.requestQueue cancelAllOperations]; -} - -- (void)setFeatures:(NSArray<MGLShape <MGLFeature> *>*)features inTileAtX:(NSUInteger)x y:(NSUInteger)y zoomLevel:(NSUInteger)zoomLevel { - MGLAssertStyleSourceIsValid(); - mbgl::CanonicalTileID tileID = mbgl::CanonicalTileID((uint8_t)zoomLevel, (uint32_t)x, (uint32_t)y); - mbgl::FeatureCollection featureCollection; - featureCollection.reserve(features.count); - for (MGLShape <MGLFeature> * feature in features) { - mbgl::GeoJSONFeature geoJsonObject = [feature geoJSONObject].get<mbgl::GeoJSONFeature>(); - featureCollection.push_back(geoJsonObject); - if ([feature isMemberOfClass:[MGLShapeCollection class]]) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSLog(@"MGLShapeCollection initialized with MGLFeatures will not retain attributes." - @"Use MGLShapeCollectionFeature to retain attributes instead." - @"This will be logged only once."); - }); - } - } - const auto geojson = mbgl::GeoJSON{featureCollection}; - static_cast<mbgl::style::CustomGeometrySource *>(self.rawSource)->setTileData(tileID, geojson); -} - -- (void)setDataSource:(id<MGLComputedShapeSourceDataSource>)dataSource { - [self.requestQueue cancelAllOperations]; - // Check which method the datasource implements, to avoid having to check for each tile - self.dataSourceImplementsFeaturesForTile = [dataSource respondsToSelector:@selector(featuresInTileAtX:y:zoomLevel:)]; - self.dataSourceImplementsFeaturesForBounds = [dataSource respondsToSelector:@selector(featuresInCoordinateBounds:zoomLevel:)]; - - if (!self.dataSourceImplementsFeaturesForBounds && !self.dataSourceImplementsFeaturesForTile) { - [NSException raise:MGLInvalidDatasourceException - format:@"Datasource does not implement any MGLComputedShapeSourceDataSource methods"]; - } else if (self.dataSourceImplementsFeaturesForBounds && self.dataSourceImplementsFeaturesForTile) { - [NSException raise:MGLInvalidDatasourceException - format:@"Datasource implements multiple MGLComputedShapeSourceDataSource methods"]; - } - - _dataSource = dataSource; -} - -- (void) invalidateBounds:(MGLCoordinateBounds)bounds { - MGLAssertStyleSourceIsValid(); - ((mbgl::style::CustomGeometrySource *)self.rawSource)->invalidateRegion(MGLLatLngBoundsFromCoordinateBounds(bounds)); -} - -- (void) invalidateTileAtX:(NSUInteger)x y:(NSUInteger)y zoomLevel:(NSUInteger)z { - MGLAssertStyleSourceIsValid(); - ((mbgl::style::CustomGeometrySource *)self.rawSource)->invalidateTile(mbgl::CanonicalTileID(z, (unsigned int)x, (unsigned int)y)); -} - -@end diff --git a/platform/darwin/src/MGLComputedShapeSource_Private.h b/platform/darwin/src/MGLComputedShapeSource_Private.h deleted file mode 100644 index ec075e4bd7..0000000000 --- a/platform/darwin/src/MGLComputedShapeSource_Private.h +++ /dev/null @@ -1,12 +0,0 @@ -#import "MGLFoundation.h" -#import "MGLTypes.h" -#import "MGLComputedShapeSource.h" - -#include <mbgl/style/sources/custom_geometry_source.hpp> - -NS_ASSUME_NONNULL_BEGIN - -MGL_EXPORT -mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDictionary(NSDictionary<MGLShapeSourceOption, id> *options); - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLConversion.h b/platform/darwin/src/MGLConversion.h deleted file mode 100644 index 3f7ffdd0c1..0000000000 --- a/platform/darwin/src/MGLConversion.h +++ /dev/null @@ -1,159 +0,0 @@ -#include <mbgl/style/conversion_impl.hpp> - -NS_ASSUME_NONNULL_BEGIN - -namespace mbgl { -namespace style { -namespace conversion { - -// A wrapper class for `id`, so as not to confuse ARC. -class Holder { -public: - Holder(const id v) : value(v) {} - const id value; -}; - -template <> -class ConversionTraits<Holder> { -public: - static bool isUndefined(const Holder& holder) { - const id value = holder.value; - return !value || value == [NSNull null]; - } - - static bool isArray(const Holder& holder) { - const id value = holder.value; - return [value isKindOfClass:[NSArray class]]; - } - - static bool isObject(const Holder& holder) { - const id value = holder.value; - return [value isKindOfClass:[NSDictionary class]]; - } - - static std::size_t arrayLength(const Holder& holder) { - const id value = holder.value; - NSCAssert([value isKindOfClass:[NSArray class]], @"Value must be an NSArray for getLength()."); - NSArray *array = value; - auto length = [array count]; - NSCAssert(length <= std::numeric_limits<size_t>::max(), @"Array length out of bounds."); - return length; - } - - static Holder arrayMember(const Holder& holder, std::size_t i) { - const id value = holder.value; - NSCAssert([value isKindOfClass:[NSArray class]], @"Value must be an NSArray for get(int)."); - NSCAssert(i < NSUIntegerMax, @"Index must be less than NSUIntegerMax"); - return {[value objectAtIndex: i]}; - } - - static optional<Holder> objectMember(const Holder& holder, const char *key) { - const id value = holder.value; - NSCAssert([value isKindOfClass:[NSDictionary class]], @"Value must be an NSDictionary for get(string)."); - NSObject *member = [value objectForKey: @(key)]; - if (member && member != [NSNull null]) { - return {member}; - } else { - return {}; - } - } - -// Compiler is wrong about `Fn` parameter missing a nullability specifier. -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnullability-completeness" - template <class Fn> - static optional<Error> eachMember(const Holder& holder, Fn&& visit) { -#pragma clang diagnostic pop - [holder.value enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - auto result = visit(std::string(static_cast<const char *>([key UTF8String])), obj); - if (result) { - *stop = YES; - } - }]; - return {}; - } - - static optional<bool> toBool(const Holder& holder) { - const id value = holder.value; - if (_isBool(value)) { - return ((NSNumber *)value).boolValue; - } else { - return {}; - } - } - - static optional<float> toNumber(const Holder& holder) { - const id value = holder.value; - if (_isNumber(value)) { - return ((NSNumber *)value).floatValue; - } else { - return {}; - } - } - - static optional<double> toDouble(const Holder& holder) { - const id value = holder.value; - if (_isNumber(value)) { - return ((NSNumber *)value).doubleValue; - } else { - return {}; - } - } - - static optional<std::string> toString(const Holder& holder) { - const id value = holder.value; - if (_isString(value)) { - return std::string(static_cast<const char *>([value UTF8String])); - } else { - return {}; - } - } - - static optional<mbgl::Value> toValue(const Holder& holder) { - const id value = holder.value; - if (isUndefined(value)) { - return {}; - } else if (_isBool(value)) { - return { *toBool(holder) }; - } else if ( _isString(value)) { - return { *toString(holder) }; - } else if (_isNumber(value)) { - return { *toDouble(holder) }; - } else { - return {}; - } - } - - static optional<GeoJSON> toGeoJSON(const Holder&, Error& error) { - error = { "toGeoJSON not implemented" }; - return {}; - } - -private: - static bool _isBool(const id value) { - if (![value isKindOfClass:[NSNumber class]]) return false; - // char: 32-bit boolean - // BOOL: 64-bit boolean - NSNumber *number = value; - return ((strcmp([number objCType], @encode(char)) == 0) || - (strcmp([number objCType], @encode(BOOL)) == 0)); - } - - static bool _isNumber(const id value) { - return [value isKindOfClass:[NSNumber class]] && !_isBool(value); - } - - static bool _isString(const id value) { - return [value isKindOfClass:[NSString class]]; - } -}; - -inline Convertible makeConvertible(const id value) { - return Convertible(Holder(value)); -} - -} // namespace conversion -} // namespace style -} // namespace mbgl - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLCoordinateFormatter.h b/platform/darwin/src/MGLCoordinateFormatter.h deleted file mode 100644 index 63f0de8f19..0000000000 --- a/platform/darwin/src/MGLCoordinateFormatter.h +++ /dev/null @@ -1,56 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLCoordinateFormatter` class provides properly formatted descriptions of - geographic coordinate pairs. Use this class to create localized coordinate - strings when displaying location information to users. - */ -MGL_EXPORT -@interface MGLCoordinateFormatter : NSFormatter - -/** - Determines whether the output may contain minutes of arc when nonzero. - - The default value of this property is `YES`, causing the receiver to include - minutes of arc in its output. If `allowsSeconds` is `YES`, this property is - ignored and the output always includes minutes of arc. - */ -@property (nonatomic) BOOL allowsMinutes; - -/** - Determines whether the output may contain seconds of arc when nonzero. - - The default value of this property is `YES`, causing the receiver to include - seconds of arc in its output. - */ -@property (nonatomic) BOOL allowsSeconds; - -/** - The unit style used by this formatter. - - The default value of this property is `NSFormattingUnitStyleMedium`. - */ -@property (nonatomic) NSFormattingUnitStyle unitStyle; - -/** - Returns a coordinate string for the provided value. - - @param coordinate The coordinate’s value. - @return The coordinate string appropriately formatted for the formatter’s - locale. - */ -- (NSString *)stringFromCoordinate:(CLLocationCoordinate2D)coordinate; - -/** - This method is not supported for the `MGLCoordinateFormatter` class. - */ -- (BOOL)getObjectValue:(out id __nullable * __nullable)obj forString:(NSString *)string errorDescription:(out NSString * __nullable * __nullable)error; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLCoordinateFormatter.m b/platform/darwin/src/MGLCoordinateFormatter.m deleted file mode 100644 index aba34e470d..0000000000 --- a/platform/darwin/src/MGLCoordinateFormatter.m +++ /dev/null @@ -1,127 +0,0 @@ -#import "MGLCoordinateFormatter.h" - -#import "NSBundle+MGLAdditions.h" -#import "NSValue+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -@implementation MGLCoordinateFormatter - -- (instancetype)init { - if (self = [super init]) { - _allowsMinutes = YES; - _allowsSeconds = YES; - _unitStyle = NSFormattingUnitStyleMedium; - } - return self; -} - -- (NSString *)stringFromCoordinate:(CLLocationCoordinate2D)coordinate { - NSString *positiveLatitudeFormat; - NSString *negativeLatitudeFormat; - NSString *positiveLongitudeFormat; - NSString *negativeLongitudeFormat; - NSString *stringFormat; - switch (self.unitStyle) { - case NSFormattingUnitStyleShort: - positiveLatitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_N_SHORT", @"Foundation", nil, @"%@N", @"North latitude format, short: {latitude}"); - negativeLatitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_S_SHORT", @"Foundation", nil, @"%@S", @"South latitude format, short: {latitude}"); - positiveLongitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_E_SHORT", @"Foundation", nil, @"%@E", @"East longitude format, short: {longitude}"); - negativeLongitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_W_SHORT", @"Foundation", nil, @"%@W", @"West longitude format, short: {longitude}"); - stringFormat = NSLocalizedStringWithDefaultValue(@"COORD_FMT_SHORT", @"Foundation", nil, @"%@, %@", @"Coordinate pair format, short: {latitude}, {longitude}"); - break; - - case NSFormattingUnitStyleMedium: - positiveLatitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_N_MEDIUM", @"Foundation", nil, @"%@ north", @"North latitude format, medium: {latitude}"); - negativeLatitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_S_MEDIUM", @"Foundation", nil, @"%@ south", @"South latitude format, medium: {latitude}"); - positiveLongitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_E_MEDIUM", @"Foundation", nil, @"%@ east", @"East longitude format, medium: {longitude}"); - negativeLongitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_W_MEDIUM", @"Foundation", nil, @"%@ west", @"West longitude format, medium: {longitude}"); - stringFormat = NSLocalizedStringWithDefaultValue(@"COORD_FMT_MEDIUM", @"Foundation", nil, @"%@, %@", @"Coordinate pair format, medium: {latitude}, {longitude}"); - break; - - case NSFormattingUnitStyleLong: - positiveLatitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_N_LONG", @"Foundation", nil, @"%@ north", @"North latitude format, long: {latitude}"); - negativeLatitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_S_LONG", @"Foundation", nil, @"%@ south", @"South latitude format, long: {latitude}"); - positiveLongitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_E_LONG", @"Foundation", nil, @"%@ east", @"East longitude format, long: {longitude}"); - negativeLongitudeFormat = NSLocalizedStringWithDefaultValue(@"COORD_W_LONG", @"Foundation", nil, @"%@ west", @"West longitude format, long: {longitude}"); - stringFormat = NSLocalizedStringWithDefaultValue(@"COORD_FMT_LONG", @"Foundation", nil, @"%@ by %@", @"Coordinate pair format, long: {latitude}, {longitude}"); - break; - } - NSString *latitudeString = [self stringFromLocationDegrees:coordinate.latitude - positiveFormat:positiveLatitudeFormat - negativeFormat:negativeLatitudeFormat]; - NSString *longitudeString = [self stringFromLocationDegrees:coordinate.longitude - positiveFormat:positiveLongitudeFormat - negativeFormat:negativeLongitudeFormat]; - return [NSString stringWithFormat:stringFormat, latitudeString, longitudeString]; -} - -- (NSString *)stringFromLocationDegrees:(CLLocationDegrees)degrees positiveFormat:(NSString *)positiveFormat negativeFormat:(NSString *)negativeFormat { - CLLocationDegrees minutes = (fabs(degrees) - floor(fabs(degrees))) * 60; - CLLocationDegrees seconds = (minutes - floor(minutes)) * 60; - - NSString *degreesFormat; - NSString *minutesFormat; - NSString *secondsFormat; - NSString *degreesMinutesFormat; - NSString *degreesMinutesSecondsFormat; - switch (self.unitStyle) { - case NSFormattingUnitStyleShort: - degreesFormat = NSLocalizedStringWithDefaultValue(@"COORD_DEG_SHORT", @"Foundation", nil, @"%d°", @"Degrees format, short: {degrees}"); - minutesFormat = NSLocalizedStringWithDefaultValue(@"COORD_MIN_SHORT", @"Foundation", nil, @"%d′", @"Minutes format, short: {minutes}"); - secondsFormat = NSLocalizedStringWithDefaultValue(@"COORD_SEC_SHORT", @"Foundation", nil, @"%d″", @"Seconds format, short: {seconds}"); - degreesMinutesFormat = NSLocalizedStringWithDefaultValue(@"COORD_DM_SHORT", @"Foundation", nil, @"%@%@", @"Coordinate format, short: {degrees}{minutes}"); - degreesMinutesSecondsFormat = NSLocalizedStringWithDefaultValue(@"COORD_DMS_SHORT", @"Foundation", nil, @"%@%@%@", @"Coordinate format, short: {degrees}{minutes}{seconds}"); - break; - - case NSFormattingUnitStyleMedium: - degreesFormat = NSLocalizedStringWithDefaultValue(@"COORD_DEG_MEDIUM", @"Foundation", nil, @"%d°", @"Degrees format, medium: {degrees}"); - minutesFormat = NSLocalizedStringWithDefaultValue(@"COORD_MIN_MEDIUM", @"Foundation", nil, @"%d′", @"Minutes format, medium: {minutes}"); - secondsFormat = NSLocalizedStringWithDefaultValue(@"COORD_SEC_MEDIUM", @"Foundation", nil, @"%d″", @"Seconds format, medium: {seconds}"); - degreesMinutesFormat = NSLocalizedStringWithDefaultValue(@"COORD_DM_MEDIUM", @"Foundation", nil, @"%@%@", @"Coordinate format, medium: {degrees}{minutes}"); - degreesMinutesSecondsFormat = NSLocalizedStringWithDefaultValue(@"COORD_DMS_MEDIUM", @"Foundation", nil, @"%@%@%@", @"Coordinate format, medium: {degrees}{minutes}{seconds}"); - break; - - case NSFormattingUnitStyleLong: - degreesFormat = NSLocalizedStringWithDefaultValue(@"COORD_DEG_LONG", @"Foundation", nil, @"%d degree(s)", @"Degrees format, long"); - minutesFormat = NSLocalizedStringWithDefaultValue(@"COORD_MIN_LONG", @"Foundation", nil, @"%d minute(s)", @"Minutes format, long"); - secondsFormat = NSLocalizedStringWithDefaultValue(@"COORD_SEC_LONG", @"Foundation", nil, @"%d second(s)", @"Seconds format, long"); - degreesMinutesFormat = NSLocalizedStringWithDefaultValue(@"COORD_DM_LONG", @"Foundation", nil, @"%@ and %@", @"Coordinate format, long: {degrees}{minutes}"); - degreesMinutesSecondsFormat = NSLocalizedStringWithDefaultValue(@"COORD_DMS_LONG", @"Foundation", nil, @"%@, %@, and %@", @"Coordinate format, long: {degrees}{minutes}{seconds}"); - break; - } - - NSString *degreesString = [NSString stringWithFormat:degreesFormat, (int)floor(fabs(degrees))]; - - NSString *string; - if (trunc(seconds) > 0 && self.allowsSeconds) { - NSString *minutesString = [NSString stringWithFormat:minutesFormat, (int)floor(minutes)]; - NSString *secondsString = [NSString stringWithFormat:secondsFormat, (int)round(seconds)]; - string = [NSString stringWithFormat:degreesMinutesSecondsFormat, - degreesString, minutesString, secondsString]; - } else if (trunc(minutes) > 0 && self.allowsMinutes) { - NSString *minutesString = [NSString stringWithFormat:minutesFormat, (int)round(minutes)]; - string = [NSString stringWithFormat:degreesMinutesFormat, - degreesString, minutesString]; - } else { - string = [NSString stringWithFormat:degreesFormat, (int)round(fabs(degrees))]; - } - - if (degrees == 0) { - return string; - } - return [NSString stringWithFormat:degrees > 0 ? positiveFormat : negativeFormat, string]; -} - -- (nullable NSString *)stringForObjectValue:(id)obj { - if (![obj isKindOfClass:[NSValue class]]) { - return nil; - } - return [self stringFromCoordinate:[obj MGLCoordinateValue]]; -} - -- (BOOL)getObjectValue:(out id __nullable * __nullable)obj forString:(NSString *)string errorDescription:(out NSString * __nullable * __nullable)error { - MGLAssert(NO, @"-getObjectValue:forString:errorDescription: has not been implemented"); - return NO; -} - -@end diff --git a/platform/darwin/src/MGLDistanceFormatter.h b/platform/darwin/src/MGLDistanceFormatter.h deleted file mode 100644 index 46aad9a940..0000000000 --- a/platform/darwin/src/MGLDistanceFormatter.h +++ /dev/null @@ -1,26 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - `MGLDistanceFormatter` implements a formatter object meant to be used for - geographic distances. The user’s current locale will be used by default - but it can be overriden by changing the locale property of the numberFormatter. - */ -MGL_EXPORT -@interface MGLDistanceFormatter : NSLengthFormatter - -/** - Returns a localized formatted string for the provided distance. - - @param distance The distance, measured in meters. - @return A localized formatted distance string including units. - */ -- (NSString *)stringFromDistance:(CLLocationDistance)distance; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLDistanceFormatter.m b/platform/darwin/src/MGLDistanceFormatter.m deleted file mode 100644 index a7a2f9c9e1..0000000000 --- a/platform/darwin/src/MGLDistanceFormatter.m +++ /dev/null @@ -1,35 +0,0 @@ -#import "MGLDistanceFormatter.h" - -@interface MGLDistanceFormatter() -@end - -@implementation MGLDistanceFormatter - -static const CLLocationDistance METERS_PER_MILE = 1609.344; -static const double YARDS_PER_MILE = 1760.0; -static const double FEET_PER_MILE = YARDS_PER_MILE * 3.0; - -- (NSString *)stringFromDistance:(CLLocationDistance)distance { - double miles = distance / METERS_PER_MILE; - double feet = miles * FEET_PER_MILE; - - NSLengthFormatterUnit unit = NSLengthFormatterUnitMillimeter; - [self unitStringFromMeters:distance usedUnit:&unit]; - - self.numberFormatter.roundingIncrement = @0.25; - - if (unit == NSLengthFormatterUnitYard) { - if (miles > 0.2) { - unit = NSLengthFormatterUnitMile; - return [self stringFromValue:miles unit:unit]; - } else { - unit = NSLengthFormatterUnitFoot; - self.numberFormatter.roundingIncrement = @1; - return [self stringFromValue:feet unit:unit]; - } - } else { - return [self stringFromMeters:distance]; - } -} - -@end diff --git a/platform/darwin/src/MGLFeature.h b/platform/darwin/src/MGLFeature.h deleted file mode 100644 index 3f3526102e..0000000000 --- a/platform/darwin/src/MGLFeature.h +++ /dev/null @@ -1,300 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLPolyline.h" -#import "MGLPolygon.h" -#import "MGLPointAnnotation.h" -#import "MGLPointCollection.h" -#import "MGLShapeCollection.h" -#import "MGLCluster.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLFeature` protocol is used to provide details about geographic features - contained in an `MGLShapeSource` or `MGLVectorTileSource` object. Each concrete - subclass of `MGLShape` in turn has a subclass that conforms to this protocol. A - feature object associates a shape with an optional identifier and attributes. - - You can add custom data to display on the map by creating feature objects and - adding them to an `MGLShapeSource` using the - `-[MGLShapeSource initWithIdentifier:shape:options:]` method or - `MGLShapeSource.shape` property. - - In addition to adding data to the map, you can also extract data from the map: - `-[MGLMapView visibleFeaturesAtPoint:]` and related methods return feature - objects that correspond to features in the source. This enables you to inspect - the properties of features in vector tiles loaded by `MGLVectorTileSource` - objects. You also reuse these feature objects as overlay annotations. - - While it is possible to add `MGLFeature`-conforming objects to the map as - annotations using `-[MGLMapView addAnnotations:]` and related methods, doing so - has trade-offs: - - - Features added as annotations will not have `identifier` or `attributes` - properties when used with feature querying. - - - Features added as annotations become interactive. Taps and selection can be - handled in `-[MGLMapViewDelegate mapView:didSelectAnnotation:]`. - */ -@protocol MGLFeature <MGLAnnotation> - -/** - An object that uniquely identifies the feature in its containing content - source. - - You can configure an `MGLVectorStyleLayer` object to include or exclude a - specific feature in an `MGLShapeSource` or `MGLVectorTileSource`. In the - `MGLVectorStyleLayer.predicate` property, compare the special `$id` attribute - to the feature’s identifier. - - In vector tiles loaded by `MGLVectorTileSource` objects, the identifier - corresponds to the - <a href="https://github.com/mapbox/vector-tile-spec/tree/master/2.1#42-features">feature identifier</a> - (`id`). If the source does not specify the feature’s identifier, the value of - this property is `nil`. If specified, the identifier may be an integer, - floating-point number, or string. These data types are mapped to instances of - the following Foundation classes: - - <table> - <thead> - <tr><th>In the tile source</th><th>This property</th></tr> - </thead> - <tbody> - <tr><td>Integer</td> <td><code>NSNumber</code> (use the <code>unsignedLongLongValue</code> or <code>longLongValue</code> property)</td></tr> - <tr><td>Floating-point number</td> <td><code>NSNumber</code> (use the <code>doubleValue</code> property)</td></tr> - <tr><td>String</td> <td><code>NSString</code></td></tr> - </tbody> - </table> - - For details about the identifiers used in most Mapbox-provided styles, consult - the - <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets</a> - layer reference. - - The identifier should be set before adding the feature to an `MGLShapeSource` - object; setting it afterwards has no effect on the map’s contents. While it is - possible to change this value on feature instances obtained from - `-[MGLMapView visibleFeaturesAtPoint:]` and related methods, doing so likewise - has no effect on the map’s contents. - */ -@property (nonatomic, copy, nullable) id identifier; - -/** - A dictionary of attributes for this feature. - - You can configure an `MGLVectorStyleLayer` object to include or exclude a - specific feature in an `MGLShapeSource` or `MGLVectorTileSource`. In the - `MGLVectorStyleLayer.predicate` property, compare a key of the attribute - dictionary to the value you want to include. For example, if you want an - `MGLLineStyleLayer` object to display only important features, you might assign - a value above 50 to the important features’ `importance` attribute, then set - `MGLVectorStyleLayer.predicate` to an `NSPredicate` with the format - `importance > 50`. - - You can also configure many layout and paint attributes of an `MGLStyleLayer` - object to match the value of an attribute in this dictionary whenever it - renders this feature. For example, if you display features in an - `MGLShapeSource` using an `MGLCircleStyleLayer`, you can assign a `halfway` - attribute to each of the source’s features, then set - `MGLCircleStyleLayer.circleRadius` to an expression for the key path `halfway`. - - The `MGLSymbolStyleLayer.text` and `MGLSymbolStyleLayer.iconImageName` - properties allow you to use attributes yet another way. For example, to label - features in an `MGLShapeSource` object by their names, you can assign a `name` - attribute to each of the source’s features, then set - `MGLSymbolStyleLayer.text` to an expression for the constant string value - `{name}`. See the - <a href="../predicates-and-expressions.html">Predicates and Expressions</a> - guide for more information about expressions. - - In vector tiles loaded by `MGLVectorTileSource` objects, the keys and values of - each feature’s attribute dictionary are determined by the source. Each - attribute name is a string, while each attribute value may be a null value, - Boolean value, integer, floating-point number, or string. These data types are - mapped to instances of the following Foundation classes: - - <table> - <thead> - <tr><th>In the tile source</th><th>In this dictionary</th></tr> - </thead> - <tbody> - <tr><td>Null</td> <td><code>NSNull</code></td></tr> - <tr><td>Boolean</td> <td><code>NSNumber</code> (use the <code>boolValue</code> property)</td></tr> - <tr><td>Integer</td> <td><code>NSNumber</code> (use the <code>unsignedLongLongValue</code> or <code>longLongValue</code> property)</td></tr> - <tr><td>Floating-point number</td> <td><code>NSNumber</code> (use the <code>doubleValue</code> property)</td></tr> - <tr><td>String</td> <td><code>NSString</code></td></tr> - </tbody> - </table> - - For details about the attribute names and values found in Mapbox-provided - vector tile sources, consult the - <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets</a> - and - <a href="https://www.mapbox.com/vector-tiles/mapbox-terrain/">Mapbox Terrain</a> - layer references. - - When adding a feature to an `MGLShapeSource`, use the same Foundation types - listed above for each attribute value. In addition to the Foundation types, you - may also set an attribute to an `NSColor` (macOS) or `UIColor` (iOS), which - will be converted into its - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#types-color">CSS string representation</a> - when the feature is added to an `MGLShapeSource`. This can be convenient when - using the attribute to supply a value for a color-typed layout or paint - attribute via a key path expression. - - Note that while it is possible to change this value on feature - instances obtained from `-[MGLMapView visibleFeaturesAtPoint:]` and related - methods, there will be no effect on the map. Setting this value can be useful - when the feature instance is used to initialize an `MGLShapeSource` and that - source is added to the map and styled. - */ -@property (nonatomic, copy) NSDictionary<NSString *, id> *attributes; - -/** - Returns the feature attribute for the given attribute name. - - See the `attributes` property’s documentation for details on keys and values - associated with this method. - */ -- (nullable id)attributeForKey:(NSString *)key; - -/** - Returns a dictionary that can be serialized as a GeoJSON Feature representation - of an instance of an `MGLFeature` subclass. - - The dictionary includes a `geometry` key corresponding to the receiver’s - underlying geometry data, a `properties` key corresponding to the receiver’s - `attributes` property, and an `id` key corresponding to the receiver’s - `identifier` property. - */ -- (NSDictionary<NSString *, id> *)geoJSONDictionary; - -@end - -/** - An `MGLEmptyFeature` object associates an empty shape with an optional - identifier and attributes. - */ -MGL_EXPORT -@interface MGLEmptyFeature : MGLShape <MGLFeature> -@end - -/** - An `MGLPointFeature` object associates a point shape with an optional - identifier and attributes. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/runtime-multiple-annotations/"> - Dynamically style interactive points</a> example to learn how to initialize - `MGLPointFeature` objects and add them to your map. - */ -MGL_EXPORT -@interface MGLPointFeature : MGLPointAnnotation <MGLFeature> -@end - -/** - An `MGLPointFeatureCluster` object associates a point shape (with an optional - identifier and attributes) and represents a point cluster. - - @see `MGLCluster` - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/clustering/"> - Clustering point data</a> example to learn how to initialize - clusters and add them to your map. - */ -MGL_EXPORT -@interface MGLPointFeatureCluster : MGLPointFeature <MGLCluster> -@end - -/** - An `MGLPolylineFeature` object associates a polyline shape with an optional - identifier and attributes. - - A polyline feature is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.1.4">LineString</a> - feature in GeoJSON. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/line-geojson/"> - Add a line annotation from GeoJSON</a> example to learn how to initialize an - `MGLPolylineFeature` and add it to an `MGLMapView` object. - */ -MGL_EXPORT -@interface MGLPolylineFeature : MGLPolyline <MGLFeature> -@end - -/** - An `MGLPolygonFeature` object associates a polygon shape with an optional - identifier and attributes. - */ -MGL_EXPORT -@interface MGLPolygonFeature : MGLPolygon <MGLFeature> -@end - -/** - An `MGLPointCollectionFeature` object associates a point collection with an - optional identifier and attributes. - - A point collection feature is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.1.3">MultiPoint</a> - feature in GeoJSON. - */ -MGL_EXPORT -@interface MGLPointCollectionFeature : MGLPointCollection <MGLFeature> -@end - -// https://github.com/mapbox/mapbox-gl-native/issues/7473 -@compatibility_alias MGLMultiPointFeature MGLPointCollectionFeature; - -/** - An `MGLMultiPolylineFeature` object associates a multipolyline shape with an - optional identifier and attributes. - - A multipolyline feature is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.1.5">MultiLineString</a> - feature in GeoJSON. - */ -MGL_EXPORT -@interface MGLMultiPolylineFeature : MGLMultiPolyline <MGLFeature> -@end - -/** - An `MGLMultiPolygonFeature` object associates a multipolygon shape with an - optional identifier and attributes. - */ -MGL_EXPORT -@interface MGLMultiPolygonFeature : MGLMultiPolygon <MGLFeature> -@end - -/** - An `MGLShapeCollectionFeature` object associates a shape collection with an - optional identifier and attributes. - - `MGLShapeCollectionFeature` is most commonly used to add multiple shapes to a - single `MGLShapeSource`. Configure the appearance of an `MGLSource`’s shape - collection collectively using an `MGLSymbolStyleLayer` object, or use multiple - instances of `MGLCircleStyleLayer`, `MGLFillStyleLayer`, and - `MGLLineStyleLayer` to configure the appearance of each kind of shape inside - the collection. - - A shape collection feature is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.3">feature collection</a> - in GeoJSON. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/shape-collection/"> - Add multiple shapes from a single shape source</a> example to learn how to - add shape data to your map using an `MGLShapeCollectionFeature` object. - */ -MGL_EXPORT -@interface MGLShapeCollectionFeature : MGLShapeCollection <MGLFeature> - -@property (nonatomic, copy, readonly) NSArray<MGLShape<MGLFeature> *> *shapes; - -+ (instancetype)shapeCollectionWithShapes:(NSArray<MGLShape<MGLFeature> *> *)shapes; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm deleted file mode 100644 index df6b1bffea..0000000000 --- a/platform/darwin/src/MGLFeature.mm +++ /dev/null @@ -1,542 +0,0 @@ -#import "MGLFoundation_Private.h" -#import "MGLFeature_Private.h" -#import "MGLCluster.h" - -#import "MGLPointAnnotation.h" -#import "MGLPolyline.h" -#import "MGLPolygon.h" -#import "MGLValueEvaluator.h" - -#import "MGLShape_Private.h" -#import "MGLPointCollection_Private.h" -#import "MGLPolyline_Private.h" -#import "MGLPolygon_Private.h" - -#import "NSDictionary+MGLAdditions.h" -#import "NSArray+MGLAdditions.h" -#import "NSExpression+MGLPrivateAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#import <mbgl/util/geometry.hpp> -#import <mbgl/style/conversion/geojson.hpp> -#import <mapbox/feature.hpp> - -// Cluster constants -static NSString * const MGLClusterIdentifierKey = @"cluster_id"; -static NSString * const MGLClusterCountKey = @"point_count"; -const NSUInteger MGLClusterIdentifierInvalid = NSUIntegerMax; - -@interface MGLEmptyFeature () -@end - -@implementation MGLEmptyFeature - -@synthesize identifier; -@synthesize attributes = _attributes; - -MGL_DEFINE_FEATURE_INIT_WITH_CODER(); -MGL_DEFINE_FEATURE_ENCODE(); -MGL_DEFINE_FEATURE_IS_EQUAL(); -MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); - -- (id)attributeForKey:(NSString *)key { - MGLLogDebug(@"Retrieving attributeForKey: %@", key); - return self.attributes[key]; -} - -- (NSDictionary *)geoJSONDictionary { - return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier); -} - -- (mbgl::GeoJSON)geoJSONObject { - return mbglFeature({[self geometryObject]}, identifier, self.attributes); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; identifier = %@, attributes = %@>", - NSStringFromClass([self class]), (void *)self, - self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier, - self.attributes.count ? self.attributes : @"none"]; -} - -@end - -@interface MGLPointFeature () -@end - -@implementation MGLPointFeature - -@synthesize identifier; -@synthesize attributes = _attributes; - -MGL_DEFINE_FEATURE_INIT_WITH_CODER(); -MGL_DEFINE_FEATURE_ENCODE(); -MGL_DEFINE_FEATURE_IS_EQUAL(); -MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); - -- (id)attributeForKey:(NSString *)key { - MGLLogDebug(@"Retrieving attributeForKey: %@", key); - return self.attributes[key]; -} - -- (NSDictionary *)geoJSONDictionary { - return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier); -} - -- (mbgl::GeoJSON)geoJSONObject { - return mbglFeature({[self geometryObject]}, identifier, self.attributes); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; identifier = %@, coordinate = %f, %f, attributes = %@>", - NSStringFromClass([self class]), (void *)self, - self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier, - self.coordinate.latitude, self.coordinate.longitude, - self.attributes.count ? self.attributes : @"none"]; -} - -@end - -@implementation MGLPointFeatureCluster - -- (NSUInteger)clusterIdentifier { - NSNumber *clusterNumber = MGL_OBJC_DYNAMIC_CAST([self attributeForKey:MGLClusterIdentifierKey], NSNumber); - MGLAssert(clusterNumber, @"Clusters should have a cluster_id"); - - if (!clusterNumber) { - return MGLClusterIdentifierInvalid; - } - - NSUInteger clusterIdentifier = [clusterNumber unsignedIntegerValue]; - MGLAssert(clusterIdentifier <= UINT32_MAX, @"Cluster identifiers are 32bit"); - - return clusterIdentifier; -} - -- (NSUInteger)clusterPointCount { - NSNumber *count = MGL_OBJC_DYNAMIC_CAST([self attributeForKey:MGLClusterCountKey], NSNumber); - MGLAssert(count, @"Clusters should have a point_count"); - - return [count unsignedIntegerValue]; -} -@end - - -@interface MGLPolylineFeature () -@end - -@implementation MGLPolylineFeature - -@synthesize identifier; -@synthesize attributes = _attributes; - -MGL_DEFINE_FEATURE_INIT_WITH_CODER(); -MGL_DEFINE_FEATURE_ENCODE(); -MGL_DEFINE_FEATURE_IS_EQUAL(); -MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); - -- (id)attributeForKey:(NSString *)key { - MGLLogDebug(@"Retrieving attributeForKey: %@", key); - return self.attributes[key]; -} - -- (NSDictionary *)geoJSONDictionary { - return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier); -} - -- (mbgl::GeoJSON)geoJSONObject { - return mbglFeature({[self geometryObject]}, identifier, self.attributes); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; identifier = %@, count = %lu, bounds = %@, attributes = %@>", - NSStringFromClass([self class]), (void *)self, - self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier, - (unsigned long)[self pointCount], - MGLStringFromCoordinateBounds(self.overlayBounds), - self.attributes.count ? self.attributes : @"none"]; -} - -@end - -@interface MGLPolygonFeature () -@end - -@implementation MGLPolygonFeature - -@synthesize identifier; -@synthesize attributes = _attributes; - -MGL_DEFINE_FEATURE_INIT_WITH_CODER(); -MGL_DEFINE_FEATURE_ENCODE(); -MGL_DEFINE_FEATURE_IS_EQUAL(); -MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); - -- (id)attributeForKey:(NSString *)key { - MGLLogDebug(@"Retrieving attributeForKey: %@", key); - return self.attributes[key]; -} - -- (NSDictionary *)geoJSONDictionary { - return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier); -} - -- (mbgl::GeoJSON)geoJSONObject { - return mbglFeature({[self geometryObject]}, identifier, self.attributes); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; identifier = %@, count = %lu, bounds = %@, attributes = %@>", - NSStringFromClass([self class]), (void *)self, - self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier, - (unsigned long)[self pointCount], - MGLStringFromCoordinateBounds(self.overlayBounds), - self.attributes.count ? self.attributes : @"none"]; -} - -@end - -@interface MGLPointCollectionFeature () -@end - -@implementation MGLPointCollectionFeature - -@synthesize identifier; -@synthesize attributes = _attributes; - -MGL_DEFINE_FEATURE_INIT_WITH_CODER(); -MGL_DEFINE_FEATURE_ENCODE(); -MGL_DEFINE_FEATURE_IS_EQUAL(); -MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); - -- (id)attributeForKey:(NSString *)key { - MGLLogDebug(@"Retrieving attributeForKey: %@", key); - return self.attributes[key]; -} - -- (NSDictionary *)geoJSONDictionary { - return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier); -} - -- (mbgl::GeoJSON)geoJSONObject { - return mbglFeature({[self geometryObject]}, identifier, self.attributes); -} - -@end - -@interface MGLMultiPolylineFeature () -@end - -@implementation MGLMultiPolylineFeature - -@synthesize identifier; -@synthesize attributes = _attributes; - -MGL_DEFINE_FEATURE_INIT_WITH_CODER(); -MGL_DEFINE_FEATURE_ENCODE(); -MGL_DEFINE_FEATURE_IS_EQUAL(); -MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); - -- (id)attributeForKey:(NSString *)key { - MGLLogDebug(@"Retrieving attributeForKey: %@", key); - return self.attributes[key]; -} - -- (NSDictionary *)geoJSONDictionary { - return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier); -} - -- (mbgl::GeoJSON)geoJSONObject { - return mbglFeature({[self geometryObject]}, identifier, self.attributes); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; identifier = %@, count = %lu, bounds = %@, attributes = %@>", - NSStringFromClass([self class]), (void *)self, - self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier, - (unsigned long)self.polylines.count, - MGLStringFromCoordinateBounds(self.overlayBounds), - self.attributes.count ? self.attributes : @"none"]; -} - -@end - -@interface MGLMultiPolygonFeature () -@end - -@implementation MGLMultiPolygonFeature - -@synthesize identifier; -@synthesize attributes = _attributes; - -MGL_DEFINE_FEATURE_INIT_WITH_CODER(); -MGL_DEFINE_FEATURE_ENCODE(); -MGL_DEFINE_FEATURE_IS_EQUAL(); -MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); - -- (id)attributeForKey:(NSString *)key { - MGLLogDebug(@"Retrieving attributeForKey: %@", key); - return self.attributes[key]; -} - -- (NSDictionary *)geoJSONDictionary { - return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier); -} - -- (mbgl::GeoJSON)geoJSONObject { - return mbglFeature({[self geometryObject]}, identifier, self.attributes); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; identifier = %@, count = %lu, bounds = %@, attributes = %@>", - NSStringFromClass([self class]), (void *)self, - self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier, - (unsigned long)self.polygons.count, - MGLStringFromCoordinateBounds(self.overlayBounds), - self.attributes.count ? self.attributes : @"none"]; -} - -@end - -@interface MGLShapeCollectionFeature () -@end - -@implementation MGLShapeCollectionFeature - -@synthesize identifier; -@synthesize attributes = _attributes; - -@dynamic shapes; - -+ (instancetype)shapeCollectionWithShapes:(NSArray<MGLShape<MGLFeature> *> *)shapes { - return [super shapeCollectionWithShapes:shapes]; -} - -MGL_DEFINE_FEATURE_INIT_WITH_CODER(); -MGL_DEFINE_FEATURE_ENCODE(); -MGL_DEFINE_FEATURE_IS_EQUAL(); -MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); - -- (id)attributeForKey:(NSString *)key { - return self.attributes[key]; -} - -- (NSDictionary *)geoJSONDictionary { - return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier); -} - -- (mbgl::GeoJSON)geoJSONObject { - mbgl::FeatureCollection featureCollection; - featureCollection.reserve(self.shapes.count); - for (MGLShape <MGLFeature> *feature in self.shapes) { - auto geoJSONObject = feature.geoJSONObject; - MGLAssert(geoJSONObject.is<mbgl::GeoJSONFeature>(), @"Feature collection must only contain features."); - featureCollection.push_back(geoJSONObject.get<mbgl::GeoJSONFeature>()); - } - return featureCollection; -} - -@end - -/** - Transforms an `mbgl::geometry::geometry` type into an instance of the - corresponding Objective-C geometry class. - */ -template <typename T> -class GeometryEvaluator { -private: - const mbgl::PropertyMap *shared_properties; - -public: - GeometryEvaluator(const mbgl::PropertyMap *properties = nullptr): - shared_properties(properties) - {} - - MGLShape <MGLFeature> * operator()(const mbgl::EmptyGeometry &) const { - MGLEmptyFeature *feature = [[MGLEmptyFeature alloc] init]; - return feature; - } - - MGLShape <MGLFeature> * operator()(const mbgl::Point<T> &geometry) const { - Class pointFeatureClass = [MGLPointFeature class]; - - // If we're dealing with a cluster, we should change the class type. - // This could be generic and build the subclass at runtime if it turns - // out we need to support more than point clusters. - if (shared_properties) { - auto clusterIt = shared_properties->find("cluster"); - if (clusterIt != shared_properties->end()) { - auto clusterValue = clusterIt->second; - if (clusterValue.template is<bool>()) { - if (clusterValue.template get<bool>()) { - pointFeatureClass = [MGLPointFeatureCluster class]; - } - } - } - } - - MGLPointFeature *feature = [[pointFeatureClass alloc] init]; - feature.coordinate = toLocationCoordinate2D(geometry); - return feature; - } - - MGLShape <MGLFeature> * operator()(const mbgl::LineString<T> &geometry) const { - std::vector<CLLocationCoordinate2D> coordinates = toLocationCoordinates2D(geometry); - return [MGLPolylineFeature polylineWithCoordinates:&coordinates[0] count:coordinates.size()]; - } - - MGLShape <MGLFeature> * operator()(const mbgl::Polygon<T> &geometry) const { - return toShape<MGLPolygonFeature>(geometry); - } - - MGLShape <MGLFeature> * operator()(const mbgl::MultiPoint<T> &geometry) const { - std::vector<CLLocationCoordinate2D> coordinates = toLocationCoordinates2D(geometry); - return [[MGLPointCollectionFeature alloc] initWithCoordinates:&coordinates[0] count:coordinates.size()]; - } - - MGLShape <MGLFeature> * operator()(const mbgl::MultiLineString<T> &geometry) const { - NSMutableArray *polylines = [NSMutableArray arrayWithCapacity:geometry.size()]; - for (auto &lineString : geometry) { - std::vector<CLLocationCoordinate2D> coordinates = toLocationCoordinates2D(lineString); - MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:&coordinates[0] count:coordinates.size()]; - [polylines addObject:polyline]; - } - - return [MGLMultiPolylineFeature multiPolylineWithPolylines:polylines]; - } - - MGLShape <MGLFeature> * operator()(const mbgl::MultiPolygon<T> &geometry) const { - NSMutableArray *polygons = [NSMutableArray arrayWithCapacity:geometry.size()]; - for (auto &polygon : geometry) { - [polygons addObject:toShape(polygon)]; - } - - return [MGLMultiPolygonFeature multiPolygonWithPolygons:polygons]; - } - - MGLShape <MGLFeature> * operator()(const mapbox::geometry::geometry_collection<T> &collection) const { - NSMutableArray *shapes = [NSMutableArray arrayWithCapacity:collection.size()]; - for (auto &geometry : collection) { - // This is very much like the transformation that happens in MGLFeaturesFromMBGLFeatures(), but these are raw geometries with no associated feature IDs or attributes. - MGLShape <MGLFeature> *shape = mapbox::geometry::geometry<T>::visit(geometry, *this); - [shapes addObject:shape]; - } - return [MGLShapeCollectionFeature shapeCollectionWithShapes:shapes]; - } - -private: - static CLLocationCoordinate2D toLocationCoordinate2D(const mbgl::Point<T> &point) { - return CLLocationCoordinate2DMake(point.y, point.x); - } - - static std::vector<CLLocationCoordinate2D> toLocationCoordinates2D(const std::vector<mbgl::Point<T>> &points) { - std::vector<CLLocationCoordinate2D> coordinates; - coordinates.reserve(points.size()); - std::transform(points.begin(), points.end(), std::back_inserter(coordinates), toLocationCoordinate2D); - return coordinates; - } - - template<typename U = MGLPolygon> - static U *toShape(const mbgl::Polygon<T> &geometry) { - auto &linearRing = geometry.front(); - std::vector<CLLocationCoordinate2D> coordinates = toLocationCoordinates2D(linearRing); - NSMutableArray *innerPolygons; - if (geometry.size() > 1) { - innerPolygons = [NSMutableArray arrayWithCapacity:geometry.size() - 1]; - for (auto iter = geometry.begin() + 1; iter != geometry.end(); iter++) { - auto &innerRing = *iter; - std::vector<CLLocationCoordinate2D> innerCoordinates = toLocationCoordinates2D(innerRing); - MGLPolygon *innerPolygon = [MGLPolygon polygonWithCoordinates:&innerCoordinates[0] count:innerCoordinates.size()]; - [innerPolygons addObject:innerPolygon]; - } - } - - return [U polygonWithCoordinates:&coordinates[0] count:coordinates.size() interiorPolygons:innerPolygons]; - } -}; - -template <typename T> -class GeoJSONEvaluator { -public: - MGLShape <MGLFeature> * operator()(const mbgl::Geometry<T> &geometry) const { - GeometryEvaluator<T> evaluator; - MGLShape <MGLFeature> *shape = mapbox::geometry::geometry<T>::visit(geometry, evaluator); - return shape; - } - - MGLShape <MGLFeature> * operator()(const mbgl::GeoJSONFeature &feature) const { - MGLShape <MGLFeature> *shape = (MGLShape <MGLFeature> *)MGLFeatureFromMBGLFeature(feature); - return shape; - } - - MGLShape <MGLFeature> * operator()(const mbgl::FeatureCollection &collection) const { - NSMutableArray *shapes = [NSMutableArray arrayWithCapacity:collection.size()]; - for (const auto &feature : collection) { - [shapes addObject:MGLFeatureFromMBGLFeature(feature)]; - } - return [MGLShapeCollectionFeature shapeCollectionWithShapes:shapes]; - } -}; - -NSArray<MGLShape <MGLFeature> *> *MGLFeaturesFromMBGLFeatures(const std::vector<mbgl::Feature> &features) { - NSMutableArray *shapes = [NSMutableArray arrayWithCapacity:features.size()]; - for (const auto &feature : features) { - [shapes addObject:MGLFeatureFromMBGLFeature(static_cast<mbgl::GeoJSONFeature>(feature))]; - } - return shapes; -} - -NSArray<MGLShape <MGLFeature> *> *MGLFeaturesFromMBGLFeatures(const std::vector<mbgl::GeoJSONFeature> &features) { - NSMutableArray *shapes = [NSMutableArray arrayWithCapacity:features.size()]; - for (const auto &feature : features) { - [shapes addObject:MGLFeatureFromMBGLFeature(feature)]; - } - return shapes; -} - -id <MGLFeature> MGLFeatureFromMBGLFeature(const mbgl::GeoJSONFeature &feature) { - NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithCapacity:feature.properties.size()]; - for (auto &pair : feature.properties) { - auto &value = pair.second; - ValueEvaluator evaluator; - attributes[@(pair.first.c_str())] = mbgl::Value::visit(value, evaluator); - } - GeometryEvaluator<double> evaluator(&feature.properties); - MGLShape <MGLFeature> *shape = mapbox::geometry::geometry<double>::visit(feature.geometry, evaluator); - if (!feature.id.is<mapbox::feature::null_value_t>()) { - shape.identifier = mbgl::FeatureIdentifier::visit(feature.id, ValueEvaluator()); - } - shape.attributes = attributes; - - return shape; -} - -MGLShape* MGLShapeFromGeoJSON(const mapbox::geojson::geojson &geojson) { - GeoJSONEvaluator<double> evaluator; - MGLShape *shape = mapbox::geojson::geojson::visit(geojson, evaluator); - return shape; -} - -mbgl::GeoJSONFeature mbglFeature(mbgl::GeoJSONFeature feature, id identifier, NSDictionary *attributes) -{ - if (identifier) { - NSExpression *identifierExpression = [NSExpression expressionForConstantValue:identifier]; - feature.id = [identifierExpression mgl_featureIdentifier]; - } - feature.properties = [attributes mgl_propertyMap]; - return feature; -} - -NSDictionary<NSString *, id> *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier) { - NSMutableDictionary *feature = [@{@"type": @"Feature", - @"properties": attributes, - @"geometry": geometry} mutableCopy]; - feature[@"id"] = identifier; - return [feature copy]; -} diff --git a/platform/darwin/src/MGLFeature_Private.h b/platform/darwin/src/MGLFeature_Private.h deleted file mode 100644 index 599633dd31..0000000000 --- a/platform/darwin/src/MGLFeature_Private.h +++ /dev/null @@ -1,85 +0,0 @@ -#import "MGLFoundation.h" -#import "MGLFeature.h" -#import "MGLShape.h" - -#import <mbgl/util/geo.hpp> -#import <mbgl/util/feature.hpp> -#import <mbgl/style/conversion/geojson.hpp> - -NS_ASSUME_NONNULL_BEGIN - -/** - Returns an array of `MGLFeature` objects converted from the given vector of - vector tile features. - */ -MGL_EXPORT -NSArray<MGLShape <MGLFeature> *> *MGLFeaturesFromMBGLFeatures(const std::vector<mbgl::Feature> &features); - -/** - Returns an array of `MGLFeature` objects converted from the given vector of - vector tile features. - */ -MGL_EXPORT -NSArray<MGLShape <MGLFeature> *> *MGLFeaturesFromMBGLFeatures(const std::vector<mbgl::GeoJSONFeature> &features); - -/** - Returns an `MGLFeature` object converted from the given mbgl::GeoJSONFeature - */ -MGL_EXPORT -id <MGLFeature> MGLFeatureFromMBGLFeature(const mbgl::GeoJSONFeature &feature); - -/** - Returns an `MGLShape` representing the given geojson. The shape can be - a feature, a collection of features, or a geometry. - */ -MGLShape* MGLShapeFromGeoJSON(const mapbox::geojson::geojson &geojson); - -/** - Takes an `mbgl::GeoJSONFeature` object, an identifer, and attributes dictionary and - returns the feature object with converted `mbgl::FeatureIdentifier` and - `mbgl::PropertyMap` properties. - */ -mbgl::GeoJSONFeature mbglFeature(mbgl::GeoJSONFeature feature, id identifier, NSDictionary * attributes); - -/** - Returns an `NSDictionary` representation of an `MGLFeature`. - */ -NSDictionary<NSString *, id> *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier); - -NS_ASSUME_NONNULL_END - -#define MGL_DEFINE_FEATURE_INIT_WITH_CODER() \ - - (instancetype)initWithCoder:(NSCoder *)decoder { \ - if (self = [super initWithCoder:decoder]) { \ - NSSet<Class> *identifierClasses = [NSSet setWithArray:@[[NSString class], [NSNumber class]]]; \ - identifier = [decoder decodeObjectOfClasses:identifierClasses forKey:@"identifier"]; \ - _attributes = [decoder decodeObjectOfClass:[NSDictionary class] forKey:@"attributes"]; \ - } \ - return self; \ - } - -#define MGL_DEFINE_FEATURE_ENCODE() \ - - (void)encodeWithCoder:(NSCoder *)coder { \ - [super encodeWithCoder:coder]; \ - [coder encodeObject:identifier forKey:@"identifier"]; \ - [coder encodeObject:_attributes forKey:@"attributes"]; \ - } - -#define MGL_DEFINE_FEATURE_IS_EQUAL() \ - - (BOOL)isEqual:(id)other { \ - if (other == self) return YES; \ - if (![other isKindOfClass:[self class]]) return NO; \ - __typeof(self) otherFeature = other; \ - return [super isEqual:other] && [self geoJSONObject] == [otherFeature geoJSONObject]; \ - } \ - - (NSUInteger)hash { \ - return [super hash] + [[self geoJSONDictionary] hash]; \ - } - -#define MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER() \ - - (NSDictionary *) attributes { \ - if (!_attributes) { \ - return @{}; \ - } \ - return _attributes; \ - } diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer.h b/platform/darwin/src/MGLFillExtrusionStyleLayer.h deleted file mode 100644 index adb215c413..0000000000 --- a/platform/darwin/src/MGLFillExtrusionStyleLayer.h +++ /dev/null @@ -1,388 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLVectorStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Controls the frame of reference for - `MGLFillExtrusionStyleLayer.fillExtrusionTranslation`. - - Values of this type are used in the `MGLFillExtrusionStyleLayer.fillExtrusionTranslationAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLFillExtrusionTranslationAnchor) { - /** - The fill extrusion is translated relative to the map. - */ - MGLFillExtrusionTranslationAnchorMap, - /** - The fill extrusion is translated relative to the viewport. - */ - MGLFillExtrusionTranslationAnchorViewport, -}; - -/** - An `MGLFillExtrusionStyleLayer` is a style layer that renders one or more 3D - extruded polygons on the map. - - Use a fill-extrusion style layer to configure the visual appearance of polygon - or multipolygon features. These features can come from vector tiles loaded by - an `MGLVectorTileSource` object, or they can be `MGLPolygon`, - `MGLPolygonFeature`, `MGLMultiPolygon`, or `MGLMultiPolygonFeature` instances - in an `MGLShapeSource` or `MGLComputedShapeSource` object. - - You can access an existing fill-extrusion style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new fill-extrusion style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/extrusions/">Display - 3D buildings</a> example to learn how to add and style 3D layers on a map. - - ### Example - - ```swift - let layer = MGLFillExtrusionStyleLayer(identifier: "buildings", source: buildings) - layer.sourceLayerIdentifier = "building" - layer.fillExtrusionHeight = NSExpression(forKeyPath: "height") - layer.fillExtrusionBase = NSExpression(forKeyPath: "min_height") - layer.predicate = NSPredicate(format: "extrude == 'true'") - mapView.style?.addLayer(layer) - ``` - */ -MGL_EXPORT -@interface MGLFillExtrusionStyleLayer : MGLVectorStyleLayer - -/** - Returns a fill-extrusion style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; - -#pragma mark - Accessing the Paint Attributes - -/** - The height with which to extrude the base of this layer. Must be less than or - equal to `fillExtrusionHeight`. - - This property is measured in meters. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `fillExtrusionHeight` is - non-`nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionBase; - -/** - The transition affecting any changes to this layer’s `fillExtrusionBase` property. - - This property corresponds to the `fill-extrusion-base-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillExtrusionBaseTransition; - -#if TARGET_OS_IPHONE -/** - The base color of this layer. The extrusion's surfaces will be shaded - differently based on this color in combination with the `light` settings. If - this color is specified with an alpha component, the alpha component will be - ignored; use `fillExtrusionOpacity` to set layer opacityco. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `fillExtrusionPattern` is set to - `nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionColor; -#else -/** - The base color of this layer. The extrusion's surfaces will be shaded - differently based on this color in combination with the `light` settings. If - this color is specified with an alpha component, the alpha component will be - ignored; use `fillExtrusionOpacity` to set layer opacityco. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `fillExtrusionPattern` is set to - `nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionColor; -#endif - -/** - The transition affecting any changes to this layer’s `fillExtrusionColor` property. - - This property corresponds to the `fill-extrusion-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillExtrusionColorTransition; - -/** - Whether to apply a vertical gradient to the sides of a fill-extrusion layer. If - true, sides will be shaded slightly darker farther down. - - The default value of this property is an expression that evaluates to `YES`. - Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-extrusion-vertical-gradient"><code>fill-extrusion-vertical-gradient</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionHasVerticalGradient; - -@property (nonatomic, null_resettable) NSExpression *fillExtrusionVerticalGradient __attribute__((unavailable("Use fillExtrusionHasVerticalGradient instead."))); - -/** - The height with which to extrude this layer. - - This property is measured in meters. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionHeight; - -/** - The transition affecting any changes to this layer’s `fillExtrusionHeight` property. - - This property corresponds to the `fill-extrusion-height-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillExtrusionHeightTransition; - -/** - The opacity of the entire fill extrusion layer. This is rendered on a - per-layer, not per-feature, basis, and data-driven styling is not available. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionOpacity; - -/** - The transition affecting any changes to this layer’s `fillExtrusionOpacity` property. - - This property corresponds to the `fill-extrusion-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillExtrusionOpacityTransition; - -/** - Name of image in style images to use for drawing image fill-extrusions. For - seamless patterns, image width and height must be a factor of two (2, 4, 8, - ..., 512). - - You can set this property to an expression containing any of the following: - - * Constant string values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionPattern; - -/** - The transition affecting any changes to this layer’s `fillExtrusionPattern` property. - - This property corresponds to the `fill-extrusion-pattern-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillExtrusionPatternTransition; - -#if TARGET_OS_IPHONE -/** - The geometry's offset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points downward. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-extrusion-translate"><code>fill-extrusion-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionTranslation; -#else -/** - The geometry's offset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points upward. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-extrusion-translate"><code>fill-extrusion-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionTranslation; -#endif - -/** - The transition affecting any changes to this layer’s `fillExtrusionTranslation` property. - - This property corresponds to the `fill-extrusion-translate-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillExtrusionTranslationTransition; - -@property (nonatomic, null_resettable) NSExpression *fillExtrusionTranslate __attribute__((unavailable("Use fillExtrusionTranslation instead."))); - -/** - Controls the frame of reference for `fillExtrusionTranslation`. - - The default value of this property is an expression that evaluates to `map`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `fillExtrusionTranslation` is - non-`nil`. Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-extrusion-translate-anchor"><code>fill-extrusion-translate-anchor</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLFillExtrusionTranslationAnchor` values - * Any of the following constant string values: - * `map`: The fill extrusion is translated relative to the map. - * `viewport`: The fill extrusion is translated relative to the viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *fillExtrusionTranslationAnchor; - -@property (nonatomic, null_resettable) NSExpression *fillExtrusionTranslateAnchor __attribute__((unavailable("Use fillExtrusionTranslationAnchor instead."))); - -@end - -/** - Methods for wrapping an enumeration value for a style layer attribute in an - `MGLFillExtrusionStyleLayer` object and unwrapping its raw value. - */ -@interface NSValue (MGLFillExtrusionStyleLayerAdditions) - -#pragma mark Working with Fill extrusion Style Layer Attribute Values - -/** - Creates a new value object containing the given `MGLFillExtrusionTranslationAnchor` enumeration. - - @param fillExtrusionTranslationAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLFillExtrusionTranslationAnchor:(MGLFillExtrusionTranslationAnchor)fillExtrusionTranslationAnchor; - -/** - The `MGLFillExtrusionTranslationAnchor` enumeration representation of the value. - */ -@property (readonly) MGLFillExtrusionTranslationAnchor MGLFillExtrusionTranslationAnchorValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer.mm b/platform/darwin/src/MGLFillExtrusionStyleLayer.mm deleted file mode 100644 index ed6cd58460..0000000000 --- a/platform/darwin/src/MGLFillExtrusionStyleLayer.mm +++ /dev/null @@ -1,363 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLFillExtrusionStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLFillExtrusionStyleLayer_Private.h" - -#include <mbgl/style/layers/fill_extrusion_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLFillExtrusionTranslationAnchor, { - { MGLFillExtrusionTranslationAnchorMap, "map" }, - { MGLFillExtrusionTranslationAnchorViewport, "viewport" }, - }); - -} - -@interface MGLFillExtrusionStyleLayer () - -@property (nonatomic, readonly) mbgl::style::FillExtrusionLayer *rawLayer; - -@end - -@implementation MGLFillExtrusionStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::FillExtrusionLayer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::FillExtrusionLayer *)rawLayer -{ - return (mbgl::style::FillExtrusionLayer *)super.rawLayer; -} - -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -- (NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - - auto layerID = self.rawLayer->getSourceLayer(); - return layerID.empty() ? nil : @(layerID.c_str()); -} - -- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting sourceLayerIdentifier: %@", sourceLayerIdentifier); - - self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); -} - -- (void)setPredicate:(NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting predicate: %@", predicate); - - self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::Filter()); -} - -- (NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - - return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setFillExtrusionBase:(NSExpression *)fillExtrusionBase { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionBase: %@", fillExtrusionBase); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(fillExtrusionBase, true); - self.rawLayer->setFillExtrusionBase(mbglValue); -} - -- (NSExpression *)fillExtrusionBase { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillExtrusionBase(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillExtrusionBase(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setFillExtrusionBaseTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionBaseTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillExtrusionBaseTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillExtrusionBaseTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionBaseTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillExtrusionColor:(NSExpression *)fillExtrusionColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionColor: %@", fillExtrusionColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(fillExtrusionColor, true); - self.rawLayer->setFillExtrusionColor(mbglValue); -} - -- (NSExpression *)fillExtrusionColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillExtrusionColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillExtrusionColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setFillExtrusionColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillExtrusionColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillExtrusionColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillExtrusionHasVerticalGradient:(NSExpression *)fillExtrusionHasVerticalGradient { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionHasVerticalGradient: %@", fillExtrusionHasVerticalGradient); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(fillExtrusionHasVerticalGradient, false); - self.rawLayer->setFillExtrusionVerticalGradient(mbglValue); -} - -- (NSExpression *)fillExtrusionHasVerticalGradient { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillExtrusionVerticalGradient(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillExtrusionVerticalGradient(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setFillExtrusionVerticalGradient:(NSExpression *)fillExtrusionVerticalGradient { -} - -- (NSExpression *)fillExtrusionVerticalGradient { - return self.fillExtrusionHasVerticalGradient; -} - -- (void)setFillExtrusionHeight:(NSExpression *)fillExtrusionHeight { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionHeight: %@", fillExtrusionHeight); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(fillExtrusionHeight, true); - self.rawLayer->setFillExtrusionHeight(mbglValue); -} - -- (NSExpression *)fillExtrusionHeight { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillExtrusionHeight(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillExtrusionHeight(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setFillExtrusionHeightTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionHeightTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillExtrusionHeightTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillExtrusionHeightTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionHeightTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillExtrusionOpacity:(NSExpression *)fillExtrusionOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionOpacity: %@", fillExtrusionOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(fillExtrusionOpacity, false); - self.rawLayer->setFillExtrusionOpacity(mbglValue); -} - -- (NSExpression *)fillExtrusionOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillExtrusionOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillExtrusionOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setFillExtrusionOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillExtrusionOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillExtrusionOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillExtrusionPattern:(NSExpression *)fillExtrusionPattern { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionPattern: %@", fillExtrusionPattern); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::expression::Image>>(fillExtrusionPattern, true); - self.rawLayer->setFillExtrusionPattern(mbglValue); -} - -- (NSExpression *)fillExtrusionPattern { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillExtrusionPattern(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillExtrusionPattern(); - } - return MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toExpression(propertyValue); -} - -- (void)setFillExtrusionPatternTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionPatternTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillExtrusionPatternTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillExtrusionPatternTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionPatternTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillExtrusionTranslation:(NSExpression *)fillExtrusionTranslation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionTranslation: %@", fillExtrusionTranslation); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 2>>>(fillExtrusionTranslation, false); - self.rawLayer->setFillExtrusionTranslate(mbglValue); -} - -- (NSExpression *)fillExtrusionTranslation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillExtrusionTranslate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillExtrusionTranslate(); - } - return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toExpression(propertyValue); -} - -- (void)setFillExtrusionTranslationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionTranslationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillExtrusionTranslateTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillExtrusionTranslationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillExtrusionTranslateTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillExtrusionTranslate:(NSExpression *)fillExtrusionTranslate { -} - -- (NSExpression *)fillExtrusionTranslate { - return self.fillExtrusionTranslation; -} - -- (void)setFillExtrusionTranslationAnchor:(NSExpression *)fillExtrusionTranslationAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillExtrusionTranslationAnchor: %@", fillExtrusionTranslationAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillExtrusionTranslationAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::TranslateAnchorType>>(fillExtrusionTranslationAnchor, false); - self.rawLayer->setFillExtrusionTranslateAnchor(mbglValue); -} - -- (NSExpression *)fillExtrusionTranslationAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillExtrusionTranslateAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillExtrusionTranslateAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillExtrusionTranslationAnchor>().toExpression(propertyValue); -} - -- (void)setFillExtrusionTranslateAnchor:(NSExpression *)fillExtrusionTranslateAnchor { -} - -- (NSExpression *)fillExtrusionTranslateAnchor { - return self.fillExtrusionTranslationAnchor; -} - -@end - -@implementation NSValue (MGLFillExtrusionStyleLayerAdditions) - -+ (NSValue *)valueWithMGLFillExtrusionTranslationAnchor:(MGLFillExtrusionTranslationAnchor)fillExtrusionTranslationAnchor { - return [NSValue value:&fillExtrusionTranslationAnchor withObjCType:@encode(MGLFillExtrusionTranslationAnchor)]; -} - -- (MGLFillExtrusionTranslationAnchor)MGLFillExtrusionTranslationAnchorValue { - MGLFillExtrusionTranslationAnchor fillExtrusionTranslationAnchor; - [self getValue:&fillExtrusionTranslationAnchor]; - return fillExtrusionTranslationAnchor; -} - -@end - -namespace mbgl { - -MGLStyleLayer* FillExtrusionStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLFillExtrusionStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLFillExtrusionStyleLayer_Private.h b/platform/darwin/src/MGLFillExtrusionStyleLayer_Private.h deleted file mode 100644 index 2525b044af..0000000000 --- a/platform/darwin/src/MGLFillExtrusionStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/fill_extrusion_layer_factory.hpp> - -namespace mbgl { - -class FillExtrusionStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::FillExtrusionLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLFillStyleLayer.h b/platform/darwin/src/MGLFillStyleLayer.h deleted file mode 100644 index b6f0e9bd06..0000000000 --- a/platform/darwin/src/MGLFillStyleLayer.h +++ /dev/null @@ -1,371 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLVectorStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Controls the frame of reference for `MGLFillStyleLayer.fillTranslation`. - - Values of this type are used in the `MGLFillStyleLayer.fillTranslationAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLFillTranslationAnchor) { - /** - The fill is translated relative to the map. - */ - MGLFillTranslationAnchorMap, - /** - The fill is translated relative to the viewport. - */ - MGLFillTranslationAnchorViewport, -}; - -/** - An `MGLFillStyleLayer` is a style layer that renders one or more filled (and - optionally stroked) polygons on the map. - - Use a fill style layer to configure the visual appearance of polygon or - multipolygon features. These features can come from vector tiles loaded by an - `MGLVectorTileSource` object, or they can be `MGLPolygon`, `MGLPolygonFeature`, - `MGLMultiPolygon`, or `MGLMultiPolygonFeature` instances in an `MGLShapeSource` - or `MGLComputedShapeSource` object. - - You can access an existing fill style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new fill style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - #### Related examples - See the <a - href="https://docs.mapbox.com/ios/maps/examples/select-layer/">Select a feature - within a layer</a> example to learn how to use a `TERNARY` expression to modify - the `fillOpacity` of an `MGLFillStyleLayer` object. See the <a - href="https://docs.mapbox.com/ios/maps/examples/fill-pattern/">Add a pattern to - a polygon</a> example to learn how to use an image to add pattern to the - features styled by a `MGLFillStyleLayer`. - - ### Example - - ```swift - let layer = MGLFillStyleLayer(identifier: "parks", source: parks) - layer.sourceLayerIdentifier = "parks" - layer.fillColor = NSExpression(forConstantValue: UIColor.green) - layer.predicate = NSPredicate(format: "type == %@", "national-park") - mapView.style?.addLayer(layer) - ``` - */ -MGL_EXPORT -@interface MGLFillStyleLayer : MGLVectorStyleLayer - -/** - Returns a fill style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; - -#pragma mark - Accessing the Paint Attributes - -/** - Whether or not the fill should be antialiased. - - The default value of this property is an expression that evaluates to `YES`. - Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-antialias"><code>fill-antialias</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable, getter=isFillAntialiased) NSExpression *fillAntialiased; - -@property (nonatomic, null_resettable) NSExpression *fillAntialias __attribute__((unavailable("Use fillAntialiased instead."))); - -#if TARGET_OS_IPHONE -/** - The color of the filled part of this layer. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `fillPattern` is set to `nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillColor; -#else -/** - The color of the filled part of this layer. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `fillPattern` is set to `nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillColor; -#endif - -/** - The transition affecting any changes to this layer’s `fillColor` property. - - This property corresponds to the `fill-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillColorTransition; - -/** - The opacity of the entire fill layer. In contrast to the `fillColor`, this - value will also affect the 1pt stroke around the fill, if the stroke is used. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillOpacity; - -/** - The transition affecting any changes to this layer’s `fillOpacity` property. - - This property corresponds to the `fill-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillOpacityTransition; - -#if TARGET_OS_IPHONE -/** - The outline color of the fill. Matches the value of `fillColor` if unspecified. - - This property is only applied to the style if `fillPattern` is set to `nil`, - and `fillAntialiased` is set to an expression that evaluates to `YES`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillOutlineColor; -#else -/** - The outline color of the fill. Matches the value of `fillColor` if unspecified. - - This property is only applied to the style if `fillPattern` is set to `nil`, - and `fillAntialiased` is set to an expression that evaluates to `YES`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillOutlineColor; -#endif - -/** - The transition affecting any changes to this layer’s `fillOutlineColor` property. - - This property corresponds to the `fill-outline-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillOutlineColorTransition; - -/** - Name of image in sprite to use for drawing image fills. For seamless patterns, - image width and height must be a factor of two (2, 4, 8, ..., 512). Note that - zoom-dependent expressions will be evaluated only at integer zoom levels. - - You can set this property to an expression containing any of the following: - - * Constant string values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *fillPattern; - -/** - The transition affecting any changes to this layer’s `fillPattern` property. - - This property corresponds to the `fill-pattern-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillPatternTransition; - -#if TARGET_OS_IPHONE -/** - The geometry's offset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points downward. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-translate"><code>fill-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *fillTranslation; -#else -/** - The geometry's offset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points upward. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-translate"><code>fill-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *fillTranslation; -#endif - -/** - The transition affecting any changes to this layer’s `fillTranslation` property. - - This property corresponds to the `fill-translate-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition fillTranslationTransition; - -@property (nonatomic, null_resettable) NSExpression *fillTranslate __attribute__((unavailable("Use fillTranslation instead."))); - -/** - Controls the frame of reference for `fillTranslation`. - - The default value of this property is an expression that evaluates to `map`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `fillTranslation` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-fill-translate-anchor"><code>fill-translate-anchor</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLFillTranslationAnchor` values - * Any of the following constant string values: - * `map`: The fill is translated relative to the map. - * `viewport`: The fill is translated relative to the viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *fillTranslationAnchor; - -@property (nonatomic, null_resettable) NSExpression *fillTranslateAnchor __attribute__((unavailable("Use fillTranslationAnchor instead."))); - -@end - -/** - Methods for wrapping an enumeration value for a style layer attribute in an - `MGLFillStyleLayer` object and unwrapping its raw value. - */ -@interface NSValue (MGLFillStyleLayerAdditions) - -#pragma mark Working with Fill Style Layer Attribute Values - -/** - Creates a new value object containing the given `MGLFillTranslationAnchor` enumeration. - - @param fillTranslationAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLFillTranslationAnchor:(MGLFillTranslationAnchor)fillTranslationAnchor; - -/** - The `MGLFillTranslationAnchor` enumeration representation of the value. - */ -@property (readonly) MGLFillTranslationAnchor MGLFillTranslationAnchorValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm deleted file mode 100644 index d8c5516f3a..0000000000 --- a/platform/darwin/src/MGLFillStyleLayer.mm +++ /dev/null @@ -1,330 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLFillStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLFillStyleLayer_Private.h" - -#include <mbgl/style/layers/fill_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLFillTranslationAnchor, { - { MGLFillTranslationAnchorMap, "map" }, - { MGLFillTranslationAnchorViewport, "viewport" }, - }); - -} - -@interface MGLFillStyleLayer () - -@property (nonatomic, readonly) mbgl::style::FillLayer *rawLayer; - -@end - -@implementation MGLFillStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::FillLayer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::FillLayer *)rawLayer -{ - return (mbgl::style::FillLayer *)super.rawLayer; -} - -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -- (NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - - auto layerID = self.rawLayer->getSourceLayer(); - return layerID.empty() ? nil : @(layerID.c_str()); -} - -- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting sourceLayerIdentifier: %@", sourceLayerIdentifier); - - self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); -} - -- (void)setPredicate:(NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting predicate: %@", predicate); - - self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::Filter()); -} - -- (NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - - return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setFillAntialiased:(NSExpression *)fillAntialiased { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillAntialiased: %@", fillAntialiased); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(fillAntialiased, false); - self.rawLayer->setFillAntialias(mbglValue); -} - -- (NSExpression *)isFillAntialiased { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillAntialias(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillAntialias(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setFillAntialias:(NSExpression *)fillAntialias { -} - -- (NSExpression *)fillAntialias { - return self.isFillAntialiased; -} - -- (void)setFillColor:(NSExpression *)fillColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillColor: %@", fillColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(fillColor, true); - self.rawLayer->setFillColor(mbglValue); -} - -- (NSExpression *)fillColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setFillColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillOpacity:(NSExpression *)fillOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillOpacity: %@", fillOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(fillOpacity, true); - self.rawLayer->setFillOpacity(mbglValue); -} - -- (NSExpression *)fillOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setFillOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillOutlineColor:(NSExpression *)fillOutlineColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillOutlineColor: %@", fillOutlineColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(fillOutlineColor, true); - self.rawLayer->setFillOutlineColor(mbglValue); -} - -- (NSExpression *)fillOutlineColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillOutlineColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillOutlineColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setFillOutlineColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillOutlineColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillOutlineColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillOutlineColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillOutlineColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillPattern:(NSExpression *)fillPattern { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillPattern: %@", fillPattern); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::expression::Image>>(fillPattern, true); - self.rawLayer->setFillPattern(mbglValue); -} - -- (NSExpression *)fillPattern { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillPattern(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillPattern(); - } - return MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toExpression(propertyValue); -} - -- (void)setFillPatternTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillPatternTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillPatternTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillPatternTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillPatternTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillTranslation:(NSExpression *)fillTranslation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillTranslation: %@", fillTranslation); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 2>>>(fillTranslation, false); - self.rawLayer->setFillTranslate(mbglValue); -} - -- (NSExpression *)fillTranslation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillTranslate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillTranslate(); - } - return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toExpression(propertyValue); -} - -- (void)setFillTranslationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillTranslationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setFillTranslateTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)fillTranslationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getFillTranslateTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setFillTranslate:(NSExpression *)fillTranslate { -} - -- (NSExpression *)fillTranslate { - return self.fillTranslation; -} - -- (void)setFillTranslationAnchor:(NSExpression *)fillTranslationAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting fillTranslationAnchor: %@", fillTranslationAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillTranslationAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::TranslateAnchorType>>(fillTranslationAnchor, false); - self.rawLayer->setFillTranslateAnchor(mbglValue); -} - -- (NSExpression *)fillTranslationAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getFillTranslateAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultFillTranslateAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLFillTranslationAnchor>().toExpression(propertyValue); -} - -- (void)setFillTranslateAnchor:(NSExpression *)fillTranslateAnchor { -} - -- (NSExpression *)fillTranslateAnchor { - return self.fillTranslationAnchor; -} - -@end - -@implementation NSValue (MGLFillStyleLayerAdditions) - -+ (NSValue *)valueWithMGLFillTranslationAnchor:(MGLFillTranslationAnchor)fillTranslationAnchor { - return [NSValue value:&fillTranslationAnchor withObjCType:@encode(MGLFillTranslationAnchor)]; -} - -- (MGLFillTranslationAnchor)MGLFillTranslationAnchorValue { - MGLFillTranslationAnchor fillTranslationAnchor; - [self getValue:&fillTranslationAnchor]; - return fillTranslationAnchor; -} - -@end - -namespace mbgl { - -MGLStyleLayer* FillStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLFillStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLFillStyleLayer_Private.h b/platform/darwin/src/MGLFillStyleLayer_Private.h deleted file mode 100644 index 01f8b16f32..0000000000 --- a/platform/darwin/src/MGLFillStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/fill_layer_factory.hpp> - -namespace mbgl { - -class FillStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::FillLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLForegroundStyleLayer.h b/platform/darwin/src/MGLForegroundStyleLayer.h deleted file mode 100644 index 7e05023ef1..0000000000 --- a/platform/darwin/src/MGLForegroundStyleLayer.h +++ /dev/null @@ -1,36 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -@class MGLSource; - -/** - `MGLForegroundStyleLayer` is an abstract superclass for style layers whose - content is defined by an `MGLSource` object. - - Create instances of `MGLRasterStyleLayer`, `MGLHillshadeStyleLayer`, and the - concrete subclasses of `MGLVectorStyleLayer` in order to use - `MGLForegroundStyleLayer`'s methods. Do not create instances of - `MGLForegroundStyleLayer` directly, and do not create your own subclasses of - this class. - */ -MGL_EXPORT -@interface MGLForegroundStyleLayer : MGLStyleLayer - -#pragma mark Initializing a Style Layer - -- (instancetype)init __attribute__((unavailable("Use -init methods of concrete subclasses instead."))); - -#pragma mark Specifying a Style Layer’s Content - -/** - Identifier of the source from which the receiver obtains the data to style. - */ -@property (nonatomic, readonly, nullable) NSString *sourceIdentifier; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLForegroundStyleLayer.mm b/platform/darwin/src/MGLForegroundStyleLayer.mm deleted file mode 100644 index eaa5e83e59..0000000000 --- a/platform/darwin/src/MGLForegroundStyleLayer.mm +++ /dev/null @@ -1,26 +0,0 @@ -#import "MGLForegroundStyleLayer.h" -#import "MGLStyleLayer_Private.h" - -@implementation MGLForegroundStyleLayer - -- (NSString *)sourceIdentifier { - [NSException raise:MGLAbstractClassException - format:@"MGLForegroundStyleLayer is an abstract class"]; - return nil; -} - -- (NSString *)description { - if (self.rawLayer) { - return [NSString stringWithFormat: - @"<%@: %p; identifier = %@; sourceIdentifier = %@; visible = %@>", - NSStringFromClass([self class]), (void *)self, self.identifier, - self.sourceIdentifier, self.visible ? @"YES" : @"NO"]; - } - else { - return [NSString stringWithFormat: - @"<%@: %p; identifier = %@; sourceIdentifier = <unknown>; visible = NO>", - NSStringFromClass([self class]), (void *)self, self.identifier]; - } -} - -@end diff --git a/platform/darwin/src/MGLFoundation.h b/platform/darwin/src/MGLFoundation.h deleted file mode 100644 index 3400c63979..0000000000 --- a/platform/darwin/src/MGLFoundation.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#import <Foundation/Foundation.h> - -#define MGL_EXPORT __attribute__((visibility ("default"))) diff --git a/platform/darwin/src/MGLFoundation.mm b/platform/darwin/src/MGLFoundation.mm deleted file mode 100644 index 5cda1dced3..0000000000 --- a/platform/darwin/src/MGLFoundation.mm +++ /dev/null @@ -1,6 +0,0 @@ -#import "MGLFoundation_Private.h" - -/// Initializes the run loop shim that lives on the main thread. -void MGLInitializeRunLoop() { - static mbgl::util::RunLoop runLoop; -} diff --git a/platform/darwin/src/MGLFoundation_Private.h b/platform/darwin/src/MGLFoundation_Private.h deleted file mode 100644 index db81bde3de..0000000000 --- a/platform/darwin/src/MGLFoundation_Private.h +++ /dev/null @@ -1,19 +0,0 @@ -#import "MGLFoundation.h" - -#include <mbgl/util/run_loop.hpp> - -void MGLInitializeRunLoop(); - -/* Using a compound statement (GNU Extension, supported by clang) */ -#define MGL_OBJC_DYNAMIC_CAST(object, type) \ - ({ \ - __typeof__( object ) temp##__LINE__ = (object); \ - (type *)([temp##__LINE__ isKindOfClass:[type class]] ? temp##__LINE__ : nil); \ - }) - -#define MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(object, proto) \ - ({ \ - __typeof__( object ) temp##__LINE__ = (object); \ - (id< proto >)([temp##__LINE__ conformsToProtocol:@protocol( proto )] ? temp##__LINE__ : nil); \ - }) - diff --git a/platform/darwin/src/MGLGeometry.h b/platform/darwin/src/MGLGeometry.h deleted file mode 100644 index 397cf2a112..0000000000 --- a/platform/darwin/src/MGLGeometry.h +++ /dev/null @@ -1,243 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> -#import <CoreGraphics/CoreGraphics.h> - -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** Defines the area spanned by an `MGLCoordinateBounds`. */ -typedef struct __attribute__((objc_boxable)) MGLCoordinateSpan { - /** Latitudes spanned by an `MGLCoordinateBounds`. */ - CLLocationDegrees latitudeDelta; - /** Longitudes spanned by an `MGLCoordinateBounds`. */ - CLLocationDegrees longitudeDelta; -} MGLCoordinateSpan; - -/* Defines a point on the map in Mercator projection for a specific zoom level. */ -typedef struct __attribute__((objc_boxable)) MGLMapPoint { - /** X coordinate representing a longitude in Mercator projection. */ - CGFloat x; - /** Y coordinate representing a latitide in Mercator projection. */ - CGFloat y; - /** Zoom level at which the X and Y coordinates are valid. */ - CGFloat zoomLevel; -} MGLMapPoint; - -/* Defines a 4x4 matrix. */ -typedef struct MGLMatrix4 { - double m00, m01, m02, m03; - double m10, m11, m12, m13; - double m20, m21, m22, m23; - double m30, m31, m32, m33; -} MGLMatrix4; - -/** - Creates a new `MGLCoordinateSpan` from the given latitudinal and longitudinal - deltas. - */ -NS_INLINE MGLCoordinateSpan MGLCoordinateSpanMake(CLLocationDegrees latitudeDelta, CLLocationDegrees longitudeDelta) { - MGLCoordinateSpan span; - span.latitudeDelta = latitudeDelta; - span.longitudeDelta = longitudeDelta; - return span; -} - -/** - Creates a new `MGLMapPoint` from the given X and Y coordinates, and zoom level. - */ -NS_INLINE MGLMapPoint MGLMapPointMake(CGFloat x, CGFloat y, CGFloat zoomLevel) { - MGLMapPoint point; - point.x = x; - point.y = y; - point.zoomLevel = zoomLevel; - return point; -} - -/** - Returns `YES` if the two coordinate spans represent the same latitudinal change - and the same longitudinal change. - */ -NS_INLINE BOOL MGLCoordinateSpanEqualToCoordinateSpan(MGLCoordinateSpan span1, MGLCoordinateSpan span2) { - return (span1.latitudeDelta == span2.latitudeDelta && - span1.longitudeDelta == span2.longitudeDelta); -} - -/** An area of zero width and zero height. */ -FOUNDATION_EXTERN MGL_EXPORT const MGLCoordinateSpan MGLCoordinateSpanZero; - -/** A rectangular area as measured on a two-dimensional map projection. */ -typedef struct __attribute__((objc_boxable)) MGLCoordinateBounds { - /** Coordinate at the southwest corner. */ - CLLocationCoordinate2D sw; - /** Coordinate at the northeast corner. */ - CLLocationCoordinate2D ne; -} MGLCoordinateBounds; - -/** - A quadrilateral area as measured on a two-dimensional map projection. - `MGLCoordinateQuad` differs from `MGLCoordinateBounds` in that it allows - representation of non-axis aligned bounds and non-rectangular quadrilaterals. - The coordinates are described in counter clockwise order from top left. - */ -typedef struct MGLCoordinateQuad { - /** Coordinate at the top left corner. */ - CLLocationCoordinate2D topLeft; - /** Coordinate at the bottom left corner. */ - CLLocationCoordinate2D bottomLeft; - /** Coordinate at the bottom right corner. */ - CLLocationCoordinate2D bottomRight; - /** Coordinate at the top right corner. */ - CLLocationCoordinate2D topRight; -} MGLCoordinateQuad; - - -/** - Creates a new `MGLCoordinateBounds` structure from the given southwest and - northeast coordinates. - */ -NS_INLINE MGLCoordinateBounds MGLCoordinateBoundsMake(CLLocationCoordinate2D sw, CLLocationCoordinate2D ne) { - MGLCoordinateBounds bounds; - bounds.sw = sw; - bounds.ne = ne; - return bounds; -} - -/** - Creates a new `MGLCoordinateQuad` structure from the given top left, - bottom left, bottom right, and top right coordinates. - */ -NS_INLINE MGLCoordinateQuad MGLCoordinateQuadMake(CLLocationCoordinate2D topLeft, CLLocationCoordinate2D bottomLeft, CLLocationCoordinate2D bottomRight, CLLocationCoordinate2D topRight) { - MGLCoordinateQuad quad; - quad.topLeft = topLeft; - quad.bottomLeft = bottomLeft; - quad.bottomRight = bottomRight; - quad.topRight = topRight; - return quad; -} - -/** - Creates a new `MGLCoordinateQuad` structure from the given `MGLCoordinateBounds`. - The returned quad uses the bounds' northeast coordinate as the top right, and the - southwest coordinate at the bottom left. - */ -NS_INLINE MGLCoordinateQuad MGLCoordinateQuadFromCoordinateBounds(MGLCoordinateBounds bounds) { - MGLCoordinateQuad quad; - quad.topLeft = CLLocationCoordinate2DMake(bounds.ne.latitude, bounds.sw.longitude); - quad.bottomLeft = bounds.sw; - quad.bottomRight = CLLocationCoordinate2DMake(bounds.sw.latitude, bounds.ne.longitude); - quad.topRight = bounds.ne; - return quad; -} - -/** Returns `YES` if the two coordinate bounds are equal to each other. */ -NS_INLINE BOOL MGLCoordinateBoundsEqualToCoordinateBounds(MGLCoordinateBounds bounds1, MGLCoordinateBounds bounds2) { - return (bounds1.sw.latitude == bounds2.sw.latitude && - bounds1.sw.longitude == bounds2.sw.longitude && - bounds1.ne.latitude == bounds2.ne.latitude && - bounds1.ne.longitude == bounds2.ne.longitude); -} - -/** Returns `YES` if the two coordinate bounds intersect. */ -NS_INLINE BOOL MGLCoordinateBoundsIntersectsCoordinateBounds(MGLCoordinateBounds bounds1, MGLCoordinateBounds bounds2) { - return (bounds1.ne.latitude > bounds2.sw.latitude && - bounds1.sw.latitude < bounds2.ne.latitude && - bounds1.ne.longitude > bounds2.sw.longitude && - bounds1.sw.longitude < bounds2.ne.longitude); -} - -/** - Returns `YES` if the coordinate is within the coordinate bounds. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/constraining-gestures/"> - Restrict map panning to an area</a> example to learn how to use - `MGLCoordinateInCoordinateBounds` to determine if a point is within, or - intersects, a given bounding box. - */ -NS_INLINE BOOL MGLCoordinateInCoordinateBounds(CLLocationCoordinate2D coordinate, MGLCoordinateBounds bounds) { - return (coordinate.latitude >= bounds.sw.latitude && - coordinate.latitude <= bounds.ne.latitude && - coordinate.longitude >= bounds.sw.longitude && - coordinate.longitude <= bounds.ne.longitude); -} - -/** Returns the area spanned by the coordinate bounds. */ -NS_INLINE MGLCoordinateSpan MGLCoordinateBoundsGetCoordinateSpan(MGLCoordinateBounds bounds) { - return MGLCoordinateSpanMake(bounds.ne.latitude - bounds.sw.latitude, - bounds.ne.longitude - bounds.sw.longitude); -} - -/** - Returns a coordinate bounds with southwest and northeast coordinates that are - offset from those of the source bounds. - */ -NS_INLINE MGLCoordinateBounds MGLCoordinateBoundsOffset(MGLCoordinateBounds bounds, MGLCoordinateSpan offset) { - MGLCoordinateBounds offsetBounds = bounds; - offsetBounds.sw.latitude += offset.latitudeDelta; - offsetBounds.sw.longitude += offset.longitudeDelta; - offsetBounds.ne.latitude += offset.latitudeDelta; - offsetBounds.ne.longitude += offset.longitudeDelta; - return offsetBounds; -} - -/** - Returns `YES` if the coordinate bounds covers no area. - - @note A bounds may be empty but have a non-zero coordinate span (e.g., when its - northeast point lies due north of its southwest point). - */ -NS_INLINE BOOL MGLCoordinateBoundsIsEmpty(MGLCoordinateBounds bounds) { - MGLCoordinateSpan span = MGLCoordinateBoundsGetCoordinateSpan(bounds); - return span.latitudeDelta == 0 || span.longitudeDelta == 0; -} - -/** Returns a formatted string for the given coordinate bounds. */ -NS_INLINE NSString *MGLStringFromCoordinateBounds(MGLCoordinateBounds bounds) { - return [NSString stringWithFormat:@"{ sw = {%.1f, %.1f}, ne = {%.1f, %.1f}}", - bounds.sw.latitude, bounds.sw.longitude, - bounds.ne.latitude, bounds.ne.longitude]; -} - -/** Returns a formatted string for the given coordinate quad. */ -NS_INLINE NSString *MGLStringFromCoordinateQuad(MGLCoordinateQuad quad) { - return [NSString stringWithFormat:@"{ topleft = {%.1f, %.1f}, bottomleft = {%.1f, %.1f}}, bottomright = {%.1f, %.1f}, topright = {%.1f, %.1f}", - quad.topLeft.latitude, quad.topLeft.longitude, - quad.bottomLeft.latitude, quad.bottomLeft.longitude, - quad.bottomRight.latitude, quad.bottomRight.longitude, - quad.topRight.latitude, quad.topRight.longitude]; -} - -/** Returns radians, converted from degrees. */ -NS_INLINE CGFloat MGLRadiansFromDegrees(CLLocationDegrees degrees) { - return (CGFloat)(degrees * M_PI) / 180; -} - -/** Returns degrees, converted from radians. */ -NS_INLINE CLLocationDegrees MGLDegreesFromRadians(CGFloat radians) { - return radians * 180 / M_PI; -} - -/** Returns Mercator projection of a WGS84 coordinate at the specified zoom level. */ -FOUNDATION_EXTERN MGL_EXPORT MGLMapPoint MGLMapPointForCoordinate(CLLocationCoordinate2D coordinate, double zoomLevel); - - -/** Converts a map zoom level to a camera altitude. - - @param zoomLevel The zoom level to convert. - @param pitch The camera pitch, measured in degrees. - @param latitude The latitude of the point at the center of the viewport. - @param size The size of the viewport. - @return An altitude measured in meters. */ -FOUNDATION_EXTERN MGL_EXPORT CLLocationDistance MGLAltitudeForZoomLevel(double zoomLevel, CGFloat pitch, CLLocationDegrees latitude, CGSize size); - -/** Converts a camera altitude to a map zoom level. - - @param altitude The altitude to convert, measured in meters. - @param pitch The camera pitch, measured in degrees. - @param latitude The latitude of the point at the center of the viewport. - @param size The size of the viewport. - @return A zero-based zoom level. */ -FOUNDATION_EXTERN MGL_EXPORT double MGLZoomLevelForAltitude(CLLocationDistance altitude, CGFloat pitch, CLLocationDegrees latitude, CGSize size); - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLGeometry.mm b/platform/darwin/src/MGLGeometry.mm deleted file mode 100644 index c6fb5a5fc2..0000000000 --- a/platform/darwin/src/MGLGeometry.mm +++ /dev/null @@ -1,122 +0,0 @@ -#import "MGLGeometry_Private.h" - -#import "MGLFoundation.h" - -#import <mbgl/util/projection.hpp> - -#if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR -#import <Cocoa/Cocoa.h> -#endif - -/** Vertical field of view, measured in degrees, for determining the altitude - of the viewpoint. - - TransformState::getProjMatrix() has a variable vertical field of view that - defaults to 2 arctan ⅓ rad ≈ 36.9° but MapKit uses a vertical field of view of 30°. - flyTo() assumes a field of view of 2 arctan ½ rad. */ -const CLLocationDegrees MGLAngularFieldOfView = 30; - -const MGLCoordinateSpan MGLCoordinateSpanZero = {0, 0}; - -CGRect MGLExtendRect(CGRect rect, CGPoint point) { - if (point.x < rect.origin.x) { - rect.size.width += rect.origin.x - point.x; - rect.origin.x = point.x; - } - if (point.x > rect.origin.x + rect.size.width) { - rect.size.width += point.x - (rect.origin.x + rect.size.width); - } - if (point.y < rect.origin.y) { - rect.size.height += rect.origin.y - point.y; - rect.origin.y = point.y; - } - if (point.y > rect.origin.y + rect.size.height) { - rect.size.height += point.y - (rect.origin.y + rect.size.height); - } - return rect; -} - -mbgl::LatLng MGLLatLngFromLocationCoordinate2D(CLLocationCoordinate2D coordinate) { - try { - return mbgl::LatLng(coordinate.latitude, coordinate.longitude); - } catch (std::domain_error &error) { - [NSException raise:NSInvalidArgumentException format:@"%s", error.what()]; - return {}; - } -} - -CLLocationDistance MGLAltitudeForZoomLevel(double zoomLevel, CGFloat pitch, CLLocationDegrees latitude, CGSize size) { - CLLocationDistance metersPerPixel = mbgl::Projection::getMetersPerPixelAtLatitude(latitude, zoomLevel); - CLLocationDistance metersTall = metersPerPixel * size.height; - CLLocationDistance altitude = metersTall / 2 / std::tan(MGLRadiansFromDegrees(MGLAngularFieldOfView) / 2.); - return altitude * std::sin(M_PI_2 - MGLRadiansFromDegrees(pitch)) / std::sin(M_PI_2); -} - -double MGLZoomLevelForAltitude(CLLocationDistance altitude, CGFloat pitch, CLLocationDegrees latitude, CGSize size) { - CLLocationDistance eyeAltitude = altitude / std::sin(M_PI_2 - MGLRadiansFromDegrees(pitch)) * std::sin(M_PI_2); - CLLocationDistance metersTall = eyeAltitude * 2 * std::tan(MGLRadiansFromDegrees(MGLAngularFieldOfView) / 2.); - CLLocationDistance metersPerPixel = metersTall / size.height; - CGFloat mapPixelWidthAtZoom = std::cos(MGLRadiansFromDegrees(latitude)) * mbgl::util::M2PI * mbgl::util::EARTH_RADIUS_M / metersPerPixel; - return ::log2(mapPixelWidthAtZoom / mbgl::util::tileSize); -} - -MGLRadianDistance MGLDistanceBetweenRadianCoordinates(MGLRadianCoordinate2D from, MGLRadianCoordinate2D to) { - double a = pow(sin((to.latitude - from.latitude) / 2), 2) - + pow(sin((to.longitude - from.longitude) / 2), 2) * cos(from.latitude) * cos(to.latitude); - - return 2 * atan2(sqrt(a), sqrt(1 - a)); -} - -MGLRadianDirection MGLRadianCoordinatesDirection(MGLRadianCoordinate2D from, MGLRadianCoordinate2D to) { - double a = sin(to.longitude - from.longitude) * cos(to.latitude); - double b = cos(from.latitude) * sin(to.latitude) - - sin(from.latitude) * cos(to.latitude) * cos(to.longitude - from.longitude); - return atan2(a, b); -} - -MGLRadianCoordinate2D MGLRadianCoordinateAtDistanceFacingDirection(MGLRadianCoordinate2D coordinate, - MGLRadianDistance distance, - MGLRadianDirection direction) { - double otherLatitude = asin(sin(coordinate.latitude) * cos(distance) - + cos(coordinate.latitude) * sin(distance) * cos(direction)); - double otherLongitude = coordinate.longitude + atan2(sin(direction) * sin(distance) * cos(coordinate.latitude), - cos(distance) - sin(coordinate.latitude) * sin(otherLatitude)); - return MGLRadianCoordinate2DMake(otherLatitude, otherLongitude); -} - -CLLocationDirection MGLDirectionBetweenCoordinates(CLLocationCoordinate2D firstCoordinate, CLLocationCoordinate2D secondCoordinate) { - // Ported from https://github.com/mapbox/turf-swift/blob/857e2e8060678ef4a7a9169d4971b0788fdffc37/Turf/Turf.swift#L23-L31 - MGLRadianCoordinate2D firstRadianCoordinate = MGLRadianCoordinateFromLocationCoordinate(firstCoordinate); - MGLRadianCoordinate2D secondRadianCoordinate = MGLRadianCoordinateFromLocationCoordinate(secondCoordinate); - - CGFloat a = sin(secondRadianCoordinate.longitude - firstRadianCoordinate.longitude) * cos(secondRadianCoordinate.latitude); - CGFloat b = (cos(firstRadianCoordinate.latitude) * sin(secondRadianCoordinate.latitude) - - sin(firstRadianCoordinate.latitude) * cos(secondRadianCoordinate.latitude) * cos(secondRadianCoordinate.longitude - firstRadianCoordinate.longitude)); - MGLRadianDirection radianDirection = atan2(a, b); - return radianDirection * 180 / M_PI; -} - -CGPoint MGLPointRounded(CGPoint point) { -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - CGFloat scaleFactor = [UIScreen mainScreen].nativeScale; -#elif TARGET_OS_MAC - CGFloat scaleFactor = [NSScreen mainScreen].backingScaleFactor; -#endif - return CGPointMake(round(point.x * scaleFactor) / scaleFactor, round(point.y * scaleFactor) / scaleFactor); -} - -MGLMapPoint MGLMapPointForCoordinate(CLLocationCoordinate2D coordinate, double zoomLevel) { - mbgl::Point<double> projectedCoordinate = mbgl::Projection::project(MGLLatLngFromLocationCoordinate2D(coordinate), std::pow(2.0, zoomLevel)); - return MGLMapPointMake(projectedCoordinate.x, projectedCoordinate.y, zoomLevel); -} - -MGLMatrix4 MGLMatrix4Make(std::array<double, 16> array) { - MGLMatrix4 mat4 = { - .m00 = array[0], .m01 = array[1], .m02 = array[2], .m03 = array[3], - .m10 = array[4], .m11 = array[5], .m12 = array[6], .m13 = array[7], - .m20 = array[8], .m21 = array[9], .m22 = array[10], .m23 = array[11], - .m30 = array[12], .m31 = array[13], .m32 = array[14], .m33 = array[15] - }; - return mat4; -} - diff --git a/platform/darwin/src/MGLGeometry_Private.h b/platform/darwin/src/MGLGeometry_Private.h deleted file mode 100644 index a89a382c5e..0000000000 --- a/platform/darwin/src/MGLGeometry_Private.h +++ /dev/null @@ -1,152 +0,0 @@ -#import "MGLGeometry.h" - -#import <TargetConditionals.h> -#if TARGET_OS_IPHONE - #import <UIKit/UIKit.h> -#endif - -#import <mbgl/util/geo.hpp> -#import <mbgl/util/geometry.hpp> - -#import <array> -typedef double MGLLocationRadians; -typedef double MGLRadianDistance; -typedef double MGLRadianDirection; - -/** Defines the coordinate by a `MGLRadianCoordinate2D`. */ -typedef struct MGLRadianCoordinate2D { - MGLLocationRadians latitude; - MGLLocationRadians longitude; -} MGLRadianCoordinate2D; - -/** - Creates a new `MGLRadianCoordinate2D` from the given latitudinal and longitudinal. - */ -NS_INLINE MGLRadianCoordinate2D MGLRadianCoordinate2DMake(MGLLocationRadians latitude, MGLLocationRadians longitude) { - MGLRadianCoordinate2D radianCoordinate; - radianCoordinate.latitude = latitude; - radianCoordinate.longitude = longitude; - return radianCoordinate; -} - -/// Returns the smallest rectangle that contains both the given rectangle and -/// the given point. -CGRect MGLExtendRect(CGRect rect, CGPoint point); - -#if TARGET_OS_IPHONE -NS_INLINE NSString *MGLStringFromSize(CGSize size) { - return NSStringFromCGSize(size); -} -#else -NS_INLINE NSString *MGLStringFromSize(NSSize size) { - return NSStringFromSize(size); -} -#endif - -NS_INLINE NSString *MGLStringFromCLLocationCoordinate2D(CLLocationCoordinate2D coordinate) { - return [NSString stringWithFormat:@"(lat: %f, lon: %f)", coordinate.latitude, coordinate.longitude]; -} - -mbgl::LatLng MGLLatLngFromLocationCoordinate2D(CLLocationCoordinate2D coordinate); - -NS_INLINE mbgl::Point<double> MGLPointFromLocationCoordinate2D(CLLocationCoordinate2D coordinate) { - return mbgl::Point<double>(coordinate.longitude, coordinate.latitude); -} - -NS_INLINE CLLocationCoordinate2D MGLLocationCoordinate2DFromPoint(mbgl::Point<double> point) { - return CLLocationCoordinate2DMake(point.y, point.x); -} - -NS_INLINE CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng) { - return CLLocationCoordinate2DMake(latLng.latitude(), latLng.longitude()); -} - -NS_INLINE MGLCoordinateBounds MGLCoordinateBoundsFromLatLngBounds(mbgl::LatLngBounds latLngBounds) { - return MGLCoordinateBoundsMake(MGLLocationCoordinate2DFromLatLng(latLngBounds.southwest()), - MGLLocationCoordinate2DFromLatLng(latLngBounds.northeast())); -} - -NS_INLINE mbgl::LatLngBounds MGLLatLngBoundsFromCoordinateBounds(MGLCoordinateBounds coordinateBounds) { - return mbgl::LatLngBounds::hull(MGLLatLngFromLocationCoordinate2D(coordinateBounds.sw), - MGLLatLngFromLocationCoordinate2D(coordinateBounds.ne)); -} - -NS_INLINE std::array<mbgl::LatLng, 4> MGLLatLngArrayFromCoordinateQuad(MGLCoordinateQuad quad) { - return { MGLLatLngFromLocationCoordinate2D(quad.topLeft), - MGLLatLngFromLocationCoordinate2D(quad.topRight), - MGLLatLngFromLocationCoordinate2D(quad.bottomRight), - MGLLatLngFromLocationCoordinate2D(quad.bottomLeft) }; -} - -NS_INLINE MGLCoordinateQuad MGLCoordinateQuadFromLatLngArray(std::array<mbgl::LatLng, 4> quad) { - return { MGLLocationCoordinate2DFromLatLng(quad[0]), - MGLLocationCoordinate2DFromLatLng(quad[3]), - MGLLocationCoordinate2DFromLatLng(quad[2]), - MGLLocationCoordinate2DFromLatLng(quad[1]) }; -} - -/** - YES if the coordinate is valid or NO if it is not. - Considers extended coordinates. - */ -NS_INLINE BOOL MGLLocationCoordinate2DIsValid(CLLocationCoordinate2D coordinate) { - return (coordinate.latitude <= 90.0 && - coordinate.latitude >= -90.0 && - coordinate.longitude <= 360.0 && - coordinate.longitude >= -360.0); -} - -#if TARGET_OS_IPHONE - #define MGLEdgeInsets UIEdgeInsets - #define MGLEdgeInsetsMake UIEdgeInsetsMake -#else - #define MGLEdgeInsets NSEdgeInsets - #define MGLEdgeInsetsMake NSEdgeInsetsMake -#endif - -NS_INLINE mbgl::EdgeInsets MGLEdgeInsetsFromNSEdgeInsets(MGLEdgeInsets insets) { - return { insets.top, insets.left, insets.bottom, insets.right }; -} - -/// Returns the combination of two edge insets. -NS_INLINE MGLEdgeInsets MGLEdgeInsetsInsetEdgeInset(MGLEdgeInsets base, MGLEdgeInsets inset) { - return MGLEdgeInsetsMake(base.top + inset.top, - base.left + inset.left, - base.bottom + inset.bottom, - base.right + inset.right); -} - -/** Returns MGLRadianCoordinate2D, converted from CLLocationCoordinate2D. */ -NS_INLINE MGLRadianCoordinate2D MGLRadianCoordinateFromLocationCoordinate(CLLocationCoordinate2D locationCoordinate) { - return MGLRadianCoordinate2DMake(MGLRadiansFromDegrees(locationCoordinate.latitude), - MGLRadiansFromDegrees(locationCoordinate.longitude)); -} - -/** - Returns the distance in radians given two coordinates. - */ -MGLRadianDistance MGLDistanceBetweenRadianCoordinates(MGLRadianCoordinate2D from, MGLRadianCoordinate2D to); - -/** - Returns direction in radians given two coordinates. - */ -MGLRadianDirection MGLRadianCoordinatesDirection(MGLRadianCoordinate2D from, MGLRadianCoordinate2D to); - -/** - Returns a coordinate at a given distance and direction away from coordinate. - */ -MGLRadianCoordinate2D MGLRadianCoordinateAtDistanceFacingDirection(MGLRadianCoordinate2D coordinate, - MGLRadianDistance distance, - MGLRadianDirection direction); - -/** - Returns the direction from one coordinate to another. - */ -CLLocationDirection MGLDirectionBetweenCoordinates(CLLocationCoordinate2D firstCoordinate, CLLocationCoordinate2D secondCoordinate); - -/** - Returns a point with coordinates rounded to the nearest logical pixel. - */ -CGPoint MGLPointRounded(CGPoint point); - -MGLMatrix4 MGLMatrix4Make(std::array<double, 16> mat); diff --git a/platform/darwin/src/MGLHeatmapStyleLayer.h b/platform/darwin/src/MGLHeatmapStyleLayer.h deleted file mode 100644 index 3c6dfbc296..0000000000 --- a/platform/darwin/src/MGLHeatmapStyleLayer.h +++ /dev/null @@ -1,220 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLVectorStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An `MGLHeatmapStyleLayer` is a style layer that renders a <a - href="https://en.wikipedia.org/wiki/Heat_map">heatmap</a>. - - A heatmap visualizes the spatial distribution of a large, dense set of point - data, using color to avoid cluttering the map with individual points at low - zoom levels. The points are weighted by an attribute you specify. Use a heatmap - style layer in conjunction with point or point collection features. These - features can come from vector tiles loaded by an `MGLVectorTileSource` object, - or they can be `MGLPointAnnotation`, `MGLPointFeature`, `MGLPointCollection`, - or `MGLPointCollectionFeature` instances in an `MGLShapeSource` or - `MGLComputedShapeSource` object. - - Consider accompanying a heatmap style layer with an `MGLCircleStyleLayer` or - `MGLSymbolStyleLayer` at high zoom levels. If you are unsure whether the point - data in an `MGLShapeSource` is dense enough to warrant a heatmap, you can - alternatively cluster the source using the `MGLShapeSourceOptionClustered` - option and render the data using an `MGLCircleStyleLayer` or - `MGLSymbolStyleLayer`. - - You can access an existing heatmap style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new heatmap style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - #### Related examples - See the <a - href="https://docs.mapbox.com/ios/maps/examples/heatmap-example/">Create a - heatmap layer</a> example to learn how to add this style layer to your map. - - ### Example - - ```swift - let layer = MGLHeatmapStyleLayer(identifier: "earthquake-heat", source: earthquakes) - layer.heatmapWeight = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:(magnitude, 'linear', nil, %@)", - [0: 0, - 6: 1]) - layer.heatmapIntensity = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)", - [0: 1, - 9: 3]) - mapView.style?.addLayer(layer) - ``` - */ -MGL_EXPORT -@interface MGLHeatmapStyleLayer : MGLVectorStyleLayer - -/** - Returns a heatmap style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; - -#pragma mark - Accessing the Paint Attributes - -#if TARGET_OS_IPHONE -/** - The color of each screen point based on its density value in a heatmap. This - property is normally set to an interpolation or step expression with the - `$heatmapDensity` value as its input. - - The default value of this property is an expression that evaluates to a rainbow - color scale from blue to red. Set this property to `nil` to reset it to the - default value. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$heatmapDensity` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *heatmapColor; -#else -/** - The color of each screen point based on its density value in a heatmap. This - property is normally set to an interpolation or step expression with the - `$heatmapDensity` value as its input. - - The default value of this property is an expression that evaluates to a rainbow - color scale from blue to red. Set this property to `nil` to reset it to the - default value. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$heatmapDensity` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *heatmapColor; -#endif - -/** - Similar to `heatmapWeight` but controls the intensity of the heatmap globally. - Primarily used for adjusting the heatmap based on zoom level. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *heatmapIntensity; - -/** - The transition affecting any changes to this layer’s `heatmapIntensity` property. - - This property corresponds to the `heatmap-intensity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition heatmapIntensityTransition; - -/** - The global opacity at which the heatmap layer will be drawn. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *heatmapOpacity; - -/** - The transition affecting any changes to this layer’s `heatmapOpacity` property. - - This property corresponds to the `heatmap-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition heatmapOpacityTransition; - -/** - Radius of influence of one heatmap point in points. Increasing the value makes - the heatmap smoother, but less detailed. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `30`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 1 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *heatmapRadius; - -/** - The transition affecting any changes to this layer’s `heatmapRadius` property. - - This property corresponds to the `heatmap-radius-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition heatmapRadiusTransition; - -/** - A measure of how much an individual point contributes to the heatmap. A value - of 10 would be equivalent to having 10 points of weight 1 in the same spot. - Especially useful when combined with clustering. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *heatmapWeight; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLHeatmapStyleLayer.mm b/platform/darwin/src/MGLHeatmapStyleLayer.mm deleted file mode 100644 index 41d9597dd7..0000000000 --- a/platform/darwin/src/MGLHeatmapStyleLayer.mm +++ /dev/null @@ -1,220 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLHeatmapStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLHeatmapStyleLayer_Private.h" - -#include <mbgl/style/layers/heatmap_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -@interface MGLHeatmapStyleLayer () - -@property (nonatomic, readonly) mbgl::style::HeatmapLayer *rawLayer; - -@end - -@implementation MGLHeatmapStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::HeatmapLayer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::HeatmapLayer *)rawLayer -{ - return (mbgl::style::HeatmapLayer *)super.rawLayer; -} - -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -- (NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - - auto layerID = self.rawLayer->getSourceLayer(); - return layerID.empty() ? nil : @(layerID.c_str()); -} - -- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting sourceLayerIdentifier: %@", sourceLayerIdentifier); - - self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); -} - -- (void)setPredicate:(NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting predicate: %@", predicate); - - self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::Filter()); -} - -- (NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - - return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setHeatmapColor:(NSExpression *)heatmapColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting heatmapColor: %@", heatmapColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::ColorRampPropertyValue>(heatmapColor); - self.rawLayer->setHeatmapColor(mbglValue); -} - -- (NSExpression *)heatmapColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHeatmapColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHeatmapColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setHeatmapIntensity:(NSExpression *)heatmapIntensity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting heatmapIntensity: %@", heatmapIntensity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(heatmapIntensity, false); - self.rawLayer->setHeatmapIntensity(mbglValue); -} - -- (NSExpression *)heatmapIntensity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHeatmapIntensity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHeatmapIntensity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setHeatmapIntensityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting heatmapIntensityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setHeatmapIntensityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)heatmapIntensityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHeatmapIntensityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setHeatmapOpacity:(NSExpression *)heatmapOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting heatmapOpacity: %@", heatmapOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(heatmapOpacity, false); - self.rawLayer->setHeatmapOpacity(mbglValue); -} - -- (NSExpression *)heatmapOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHeatmapOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHeatmapOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setHeatmapOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting heatmapOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setHeatmapOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)heatmapOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHeatmapOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setHeatmapRadius:(NSExpression *)heatmapRadius { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting heatmapRadius: %@", heatmapRadius); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(heatmapRadius, true); - self.rawLayer->setHeatmapRadius(mbglValue); -} - -- (NSExpression *)heatmapRadius { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHeatmapRadius(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHeatmapRadius(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setHeatmapRadiusTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting heatmapRadiusTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setHeatmapRadiusTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)heatmapRadiusTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHeatmapRadiusTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setHeatmapWeight:(NSExpression *)heatmapWeight { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting heatmapWeight: %@", heatmapWeight); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(heatmapWeight, true); - self.rawLayer->setHeatmapWeight(mbglValue); -} - -- (NSExpression *)heatmapWeight { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHeatmapWeight(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHeatmapWeight(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -@end - -namespace mbgl { - -MGLStyleLayer* HeatmapStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLHeatmapStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLHeatmapStyleLayer_Private.h b/platform/darwin/src/MGLHeatmapStyleLayer_Private.h deleted file mode 100644 index 407036cedf..0000000000 --- a/platform/darwin/src/MGLHeatmapStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/heatmap_layer_factory.hpp> - -namespace mbgl { - -class HeatmapStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::HeatmapLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLHillshadeStyleLayer.h b/platform/darwin/src/MGLHillshadeStyleLayer.h deleted file mode 100644 index 1cf3797321..0000000000 --- a/platform/darwin/src/MGLHillshadeStyleLayer.h +++ /dev/null @@ -1,324 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLForegroundStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Direction of light source when map is rotated. - - Values of this type are used in the `MGLHillshadeStyleLayer.hillshadeIlluminationAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLHillshadeIlluminationAnchor) { - /** - The hillshade illumination is relative to the north direction. - */ - MGLHillshadeIlluminationAnchorMap, - /** - The hillshade illumination is relative to the top of the viewport. - */ - MGLHillshadeIlluminationAnchorViewport, -}; - -/** - An `MGLHillshadeStyleLayer` is a style layer that renders raster <a - href="https://en.wikipedia.org/wiki/Digital_elevation_model">digital elevation - model</a> (DEM) tiles on the map. - - Use a hillshade style layer to configure the color parameters of raster tiles - loaded by an `MGLRasterDEMSource` object. For example, you could use a - hillshade style layer to render <a - href="https://docs.mapbox.com/help/troubleshooting/access-elevation-data/#mapbox-terrain-rgb">Mapbox - Terrain-RGB</a> data. - - To display posterized hillshading based on vector shapes, as with the <a - href="https://www.mapbox.com/vector-tiles/mapbox-terrain/">Mapbox Terrain</a> - source, use an `MGLVectorTileSource` object in conjunction with several - `MGLFillStyleLayer` objects. - - You can access an existing hillshade style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new hillshade style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - ### Example - - ```swift - let layer = MGLHillshadeStyleLayer(identifier: "hills", source: source) - layer.hillshadeExaggeration = NSExpression(forConstantValue: 0.6) - if let canalShadowLayer = mapView.style?.layer(withIdentifier: "waterway-river-canal-shadow") { - mapView.style?.insertLayer(layer, below: canalShadowLayer) - } - ``` - */ -MGL_EXPORT -@interface MGLHillshadeStyleLayer : MGLForegroundStyleLayer - -/** - Returns a hillshade style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; - -#pragma mark - Accessing the Paint Attributes - -#if TARGET_OS_IPHONE -/** - The shading color used to accentuate rugged terrain like sharp cliffs and - gorges. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeAccentColor; -#else -/** - The shading color used to accentuate rugged terrain like sharp cliffs and - gorges. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeAccentColor; -#endif - -/** - The transition affecting any changes to this layer’s `hillshadeAccentColor` property. - - This property corresponds to the `hillshade-accent-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition hillshadeAccentColorTransition; - -/** - Intensity of the hillshade - - The default value of this property is an expression that evaluates to the float - `0.5`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeExaggeration; - -/** - The transition affecting any changes to this layer’s `hillshadeExaggeration` property. - - This property corresponds to the `hillshade-exaggeration-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition hillshadeExaggerationTransition; - -#if TARGET_OS_IPHONE -/** - The shading color of areas that faces towards the light source. - - The default value of this property is an expression that evaluates to - `UIColor.whiteColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeHighlightColor; -#else -/** - The shading color of areas that faces towards the light source. - - The default value of this property is an expression that evaluates to - `NSColor.whiteColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeHighlightColor; -#endif - -/** - The transition affecting any changes to this layer’s `hillshadeHighlightColor` property. - - This property corresponds to the `hillshade-highlight-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition hillshadeHighlightColorTransition; - -/** - Direction of light source when map is rotated. - - The default value of this property is an expression that evaluates to - `viewport`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant `MGLHillshadeIlluminationAnchor` values - * Any of the following constant string values: - * `map`: The hillshade illumination is relative to the north direction. - * `viewport`: The hillshade illumination is relative to the top of the - viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeIlluminationAnchor; - -/** - The direction of the light source used to generate the hillshading with 0 as - the top of the viewport if `hillshadeIlluminationAnchor` is set to - `MGLHillshadeIlluminationAnchorViewport` and due north if - `hillshadeIlluminationAnchor` is set to `MGLHillshadeIlluminationAnchorMap`. - - The default value of this property is an expression that evaluates to the float - `335`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 359 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeIlluminationDirection; - -#if TARGET_OS_IPHONE -/** - The shading color of areas that face away from the light source. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeShadowColor; -#else -/** - The shading color of areas that face away from the light source. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *hillshadeShadowColor; -#endif - -/** - The transition affecting any changes to this layer’s `hillshadeShadowColor` property. - - This property corresponds to the `hillshade-shadow-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition hillshadeShadowColorTransition; - -@end - -/** - Methods for wrapping an enumeration value for a style layer attribute in an - `MGLHillshadeStyleLayer` object and unwrapping its raw value. - */ -@interface NSValue (MGLHillshadeStyleLayerAdditions) - -#pragma mark Working with Hillshade Style Layer Attribute Values - -/** - Creates a new value object containing the given `MGLHillshadeIlluminationAnchor` enumeration. - - @param hillshadeIlluminationAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLHillshadeIlluminationAnchor:(MGLHillshadeIlluminationAnchor)hillshadeIlluminationAnchor; - -/** - The `MGLHillshadeIlluminationAnchor` enumeration representation of the value. - */ -@property (readonly) MGLHillshadeIlluminationAnchor MGLHillshadeIlluminationAnchorValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLHillshadeStyleLayer.mm b/platform/darwin/src/MGLHillshadeStyleLayer.mm deleted file mode 100644 index 6bb167d43d..0000000000 --- a/platform/darwin/src/MGLHillshadeStyleLayer.mm +++ /dev/null @@ -1,245 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLHillshadeStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLHillshadeStyleLayer_Private.h" - -#include <mbgl/style/layers/hillshade_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLHillshadeIlluminationAnchor, { - { MGLHillshadeIlluminationAnchorMap, "map" }, - { MGLHillshadeIlluminationAnchorViewport, "viewport" }, - }); - -} - -@interface MGLHillshadeStyleLayer () - -@property (nonatomic, readonly) mbgl::style::HillshadeLayer *rawLayer; - -@end - -@implementation MGLHillshadeStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::HillshadeLayer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::HillshadeLayer *)rawLayer -{ - return (mbgl::style::HillshadeLayer *)super.rawLayer; -} - -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setHillshadeAccentColor:(NSExpression *)hillshadeAccentColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeAccentColor: %@", hillshadeAccentColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(hillshadeAccentColor, false); - self.rawLayer->setHillshadeAccentColor(mbglValue); -} - -- (NSExpression *)hillshadeAccentColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHillshadeAccentColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHillshadeAccentColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setHillshadeAccentColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeAccentColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setHillshadeAccentColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)hillshadeAccentColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeAccentColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setHillshadeExaggeration:(NSExpression *)hillshadeExaggeration { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeExaggeration: %@", hillshadeExaggeration); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(hillshadeExaggeration, false); - self.rawLayer->setHillshadeExaggeration(mbglValue); -} - -- (NSExpression *)hillshadeExaggeration { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHillshadeExaggeration(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHillshadeExaggeration(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setHillshadeExaggerationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeExaggerationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setHillshadeExaggerationTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)hillshadeExaggerationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeExaggerationTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setHillshadeHighlightColor:(NSExpression *)hillshadeHighlightColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeHighlightColor: %@", hillshadeHighlightColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(hillshadeHighlightColor, false); - self.rawLayer->setHillshadeHighlightColor(mbglValue); -} - -- (NSExpression *)hillshadeHighlightColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHillshadeHighlightColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHillshadeHighlightColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setHillshadeHighlightColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeHighlightColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setHillshadeHighlightColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)hillshadeHighlightColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeHighlightColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setHillshadeIlluminationAnchor:(NSExpression *)hillshadeIlluminationAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeIlluminationAnchor: %@", hillshadeIlluminationAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::HillshadeIlluminationAnchorType, NSValue *, mbgl::style::HillshadeIlluminationAnchorType, MGLHillshadeIlluminationAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::HillshadeIlluminationAnchorType>>(hillshadeIlluminationAnchor, false); - self.rawLayer->setHillshadeIlluminationAnchor(mbglValue); -} - -- (NSExpression *)hillshadeIlluminationAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHillshadeIlluminationAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHillshadeIlluminationAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::HillshadeIlluminationAnchorType, NSValue *, mbgl::style::HillshadeIlluminationAnchorType, MGLHillshadeIlluminationAnchor>().toExpression(propertyValue); -} - -- (void)setHillshadeIlluminationDirection:(NSExpression *)hillshadeIlluminationDirection { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeIlluminationDirection: %@", hillshadeIlluminationDirection); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(hillshadeIlluminationDirection, false); - self.rawLayer->setHillshadeIlluminationDirection(mbglValue); -} - -- (NSExpression *)hillshadeIlluminationDirection { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHillshadeIlluminationDirection(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHillshadeIlluminationDirection(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setHillshadeShadowColor:(NSExpression *)hillshadeShadowColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeShadowColor: %@", hillshadeShadowColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(hillshadeShadowColor, false); - self.rawLayer->setHillshadeShadowColor(mbglValue); -} - -- (NSExpression *)hillshadeShadowColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getHillshadeShadowColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultHillshadeShadowColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setHillshadeShadowColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting hillshadeShadowColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setHillshadeShadowColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)hillshadeShadowColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeShadowColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -@end - -@implementation NSValue (MGLHillshadeStyleLayerAdditions) - -+ (NSValue *)valueWithMGLHillshadeIlluminationAnchor:(MGLHillshadeIlluminationAnchor)hillshadeIlluminationAnchor { - return [NSValue value:&hillshadeIlluminationAnchor withObjCType:@encode(MGLHillshadeIlluminationAnchor)]; -} - -- (MGLHillshadeIlluminationAnchor)MGLHillshadeIlluminationAnchorValue { - MGLHillshadeIlluminationAnchor hillshadeIlluminationAnchor; - [self getValue:&hillshadeIlluminationAnchor]; - return hillshadeIlluminationAnchor; -} - -@end - -namespace mbgl { - -MGLStyleLayer* HillshadeStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLHillshadeStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLHillshadeStyleLayer_Private.h b/platform/darwin/src/MGLHillshadeStyleLayer_Private.h deleted file mode 100644 index 4c427f2137..0000000000 --- a/platform/darwin/src/MGLHillshadeStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/hillshade_layer_factory.hpp> - -namespace mbgl { - -class HillshadeStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::HillshadeLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLImageSource.h b/platform/darwin/src/MGLImageSource.h deleted file mode 100644 index 66acd39e85..0000000000 --- a/platform/darwin/src/MGLImageSource.h +++ /dev/null @@ -1,99 +0,0 @@ -#import "MGLSource.h" - -#import "MGLFoundation.h" -#import "MGLTypes.h" -#import "MGLGeometry.h" - -NS_ASSUME_NONNULL_BEGIN - -MGL_EXPORT -/** - `MGLImageSource` is a content source that is used for a georeferenced raster - image to be shown on the map. The georeferenced image scales and rotates as the - user zooms and rotates the map. Images may also be used as icons or patterns - in a style layer. To register an image for use as an icon or pattern, - use the `-[MGLStyle setImage:forName:]` method. To configure a point - annotation’s image, use the `MGLAnnotationImage` class. - - The geographic location of the raster image content, supplied with - `MGLCoordinateQuad`, can be non-axis aligned. - `MGLImageSource` supports raster content from `NSURL`, `NSImage` (macOS), or - `UIImage` (iOS). - An image source is added to an `MGLStyle` object along with one or more - `MGLRasterStyleLayer` objects. Use a raster style layer to control the - appearance of content supplied by the image source. - - Each - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-image"><code>image</code></a> - source defined by the style JSON file is represented at runtime by an - `MGLImageSource` object that you can use to initialize new style layers. You - can also add and remove sources dynamically using methods such as - `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`. - - ### Example - - ```swift - let coordinates = MGLCoordinateQuad( - topLeft: CLLocationCoordinate2D(latitude: 46.437, longitude: -80.425), - bottomLeft: CLLocationCoordinate2D(latitude: 37.936, longitude: -80.425), - bottomRight: CLLocationCoordinate2D(latitude: 37.936, longitude: -71.516), - topRight: CLLocationCoordinate2D(latitude: 46.437, longitude: -71.516)) - let source = MGLImageSource(identifier: "radar", coordinateQuad: coordinates, url: URL(string: "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif")!) - mapView.style?.addSource(source) - ``` - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/image-source/"> - Add an image</a> example to learn how to add an image to your map using - `MGLImageSource`. - */ -MGL_EXPORT -@interface MGLImageSource : MGLSource - -#pragma mark Initializing a Source - -/** - Returns a georeferenced image source with an identifier, coordinates and a URL. - - @param identifier A string that uniquely identifies the source. - @param coordinateQuad the top left, top right, bottom right, and bottom left coordinates for the image. - @param url An HTTP(S) URL, absolute file URL, or local file URL relative to the - current application’s resource bundle. - @return An initialized shape source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad URL:(NSURL *)url; - -/** - Returns a georeferenced image source with an identifier, coordinates and an image. - - @param identifier A string that uniquely identifies the source. - @param coordinateQuad The top left, top right, bottom right, and bottom left coordinates for the image. - @param image The image to display for the source. - @return An initialized shape source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad image:(MGLImage *)image; - -#pragma mark Accessing a Source’s Content - -/** - The URL to the source image. - - If the receiver was initialized using `-initWithIdentifier:coordinateQuad:image:` or - the `image` property is set, this property is set to `nil`. - */ -@property (nonatomic, copy, nullable)NSURL *URL; - -/** - The source image. - - If the receiver was initialized using `-initWithIdentifier:coordinateQuad:URL:` or if the `URL` property is set, this property is set to `nil`. - */ -@property (nonatomic, retain, nullable)MGLImage *image; - -/** - The coordinates at which the corners of the source image will be placed. - */ -@property (nonatomic) MGLCoordinateQuad coordinates; -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLImageSource.mm b/platform/darwin/src/MGLImageSource.mm deleted file mode 100644 index 2d2f090079..0000000000 --- a/platform/darwin/src/MGLImageSource.mm +++ /dev/null @@ -1,112 +0,0 @@ -#import "MGLImageSource.h" - -#import "MGLGeometry_Private.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLSource_Private.h" -#import "MGLTileSource_Private.h" -#import "NSURL+MGLAdditions.h" -#if TARGET_OS_IPHONE - #import "UIImage+MGLAdditions.h" -#else - #import "NSImage+MGLAdditions.h" -#endif - -#include <mbgl/style/sources/image_source.hpp> -#include <mbgl/util/premultiply.hpp> - -@interface MGLImageSource () -- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad NS_DESIGNATED_INITIALIZER; - -@property (nonatomic, readonly) mbgl::style::ImageSource *rawSource; - -@end - -@implementation MGLImageSource - -- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad { - - const auto coordsArray = MGLLatLngArrayFromCoordinateQuad(coordinateQuad); - auto source = std::make_unique<mbgl::style::ImageSource>(identifier.UTF8String, coordsArray); - return self = [super initWithPendingSource:std::move(source)]; -} - - -- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad URL:(NSURL *)url { - self = [self initWithIdentifier:identifier coordinateQuad: coordinateQuad]; - self.URL = url; - return self; -} - - -- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad image:(MGLImage *)image { - self = [self initWithIdentifier:identifier coordinateQuad: coordinateQuad]; - self.image = image; - - return self; -} - -- (NSURL *)URL { - MGLAssertStyleSourceIsValid(); - auto url = self.rawSource->getURL(); - return url ? [NSURL URLWithString:@(url->c_str())] : nil; -} - -- (void)setURL:(NSURL *)url { - MGLAssertStyleSourceIsValid(); - if (url) { - self.rawSource->setURL(url.mgl_URLByStandardizingScheme.absoluteString.UTF8String); - _image = nil; - } else { - self.image = nullptr; - } -} - -- (void)setImage:(MGLImage *)image { - MGLAssertStyleSourceIsValid(); - if (image != nullptr) { - self.rawSource->setImage(image.mgl_premultipliedImage); - } else { - self.rawSource->setImage(mbgl::PremultipliedImage({0,0})); - } - _image = image; -} - -- (MGLCoordinateQuad)coordinates { - MGLAssertStyleSourceIsValid(); - return MGLCoordinateQuadFromLatLngArray(self.rawSource->getCoordinates()); -} - -- (void)setCoordinates: (MGLCoordinateQuad)coordinateQuad { - MGLAssertStyleSourceIsValid(); - self.rawSource->setCoordinates(MGLLatLngArrayFromCoordinateQuad(coordinateQuad)); -} - -- (NSString *)description { - if (self.rawSource) { - return [NSString stringWithFormat:@"<%@: %p; identifier = %@; coordinates = %@; URL = %@; image = %@>", - NSStringFromClass([self class]), (void *)self, self.identifier, - MGLStringFromCoordinateQuad(self.coordinates), - self.URL, - self.image]; - } - else { - return [NSString stringWithFormat:@"<%@: %p; identifier = %@; coordinates = <unknown>; URL = <unknown>; image = %@>", - NSStringFromClass([self class]), (void *)self, self.identifier, self.image]; - } -} - -- (mbgl::style::ImageSource *)rawSource { - return (mbgl::style::ImageSource *)super.rawSource; -} - -- (NSString *)attributionHTMLString { - if (!self.rawSource) { - MGLAssert(0, @"Source with identifier `%@` was invalidated after a style change", self.identifier); - return nil; - } - - auto attribution = self.rawSource->getAttribution(); - return attribution ? @(attribution->c_str()) : nil; -} - -@end diff --git a/platform/darwin/src/MGLLight.h b/platform/darwin/src/MGLLight.h deleted file mode 100644 index 281fcc5c6e..0000000000 --- a/platform/darwin/src/MGLLight.h +++ /dev/null @@ -1,242 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" -#import "MGLStyleValue.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Whether extruded geometries are lit relative to the map or viewport. - */ -typedef NS_ENUM(NSUInteger, MGLLightAnchor) { - /** - The position of the light source is aligned to the rotation of the map. - */ - MGLLightAnchorMap, - /** - The position of the light source is aligned to the rotation of the - viewport. - */ - MGLLightAnchorViewport, -}; - -/** - A structure containing information about the position of the light source - relative to lit geometries. - */ -typedef struct __attribute__((objc_boxable)) MGLSphericalPosition { - /** Distance from the center of the base of an object to its light. */ - CGFloat radial; - /** Position of the light relative to 0° (0° when `MGLLight.anchor` is set to viewport corresponds - to the top of the viewport, or 0° when `MGLLight.anchor` is set to map corresponds to due north, - and degrees proceed clockwise). */ - CLLocationDirection azimuthal; - /** Indicates the height of the light (from 0°, directly above, to 180°, directly below). */ - CLLocationDirection polar; -} MGLSphericalPosition; - -/** - Creates a new `MGLSphericalPosition` from the given radial, azimuthal, polar. - - @param radial The radial coordinate. - @param azimuthal The azimuthal angle. - @param polar The polar angle. - - @return Returns a `MGLSphericalPosition` struct containing the position attributes. - */ -NS_INLINE MGLSphericalPosition MGLSphericalPositionMake(CGFloat radial, CLLocationDirection azimuthal, CLLocationDirection polar) { - MGLSphericalPosition position; - position.radial = radial; - position.azimuthal = azimuthal; - position.polar = polar; - - return position; -} - -/** - An `MGLLight` object represents the light source for extruded geometries in - `MGLStyle`. - - ### Example - ```swift - let light = MGLLight() - let position = MGLSphericalPosition(radial: 5, azimuthal: 180, polar: 80) - light.position = NSExpression(forConstantValue: NSValue(mglSphericalPosition: position)) - light.anchor = NSExpression(forConstantValue: "map") - mapView.style?.light = light - ``` - - #### Related examples - See the <a - href="https://docs.mapbox.com/ios/maps/examples/light-example/">Adjust light of - 3D buildings</a> to learn how to create and modify the light source for 3D - geometries. - */ -MGL_EXPORT -@interface MGLLight : NSObject - -/** - Whether extruded geometries are lit relative to the map or viewport. - - The default value of this property is an expression that evaluates to - `viewport`. - - You can set this property to an expression containing any of the following: - - * Constant `MGLAnchor` values - * Any of the following constant string values: - * `map`: The position of the light source is aligned to the rotation of the - map. - * `viewport`: The position of the light source is aligned to the rotation of - the viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - - This property corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-js/style-spec/#light-anchor"><code>anchor</code></a> - light property in the Mapbox Style Specification. - */ -@property (nonatomic) NSExpression *anchor; - -/** - Position of the `MGLLight` source relative to lit (extruded) geometries, in a - `MGLSphericalPosition` struct [radial coordinate, azimuthal angle, polar angle] - where radial indicates the distance from the center of the base of an object to - its light, azimuthal indicates the position of the light relative to 0° (0° - when `MGLLight.anchor` is set to `MGLLightAnchorViewport` corresponds to the - top of the viewport, or 0° when `MGLLight.anchor` is set to `MGLLightAnchorMap` - corresponds to due north, and degrees proceed clockwise), and polar indicates - the height of the light (from 0°, directly above, to 180°, directly below). - - The default value of this property is an expression that evaluates to an - `MGLSphericalPosition` struct set to 1.15 radial, 210 azimuthal and 30 polar. - - You can set this property to an expression containing any of the following: - - * Constant `MGLSphericalPosition` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - - This property corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-js/style-spec/#light-position"><code>position</code></a> - light property in the Mapbox Style Specification. - - #### Related examples - See the <a - href="https://docs.mapbox.com/ios/maps/examples/light-example/">Adjust light of - 3D buildings</a> example to learn how to create and modify the position of - value of an `MGLLight` object for 3D geometries. - */ -@property (nonatomic) NSExpression *position; - -/** - The transition affecting any changes to this layer’s `position` property. - - This property corresponds to the `position-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition positionTransition; - -#if TARGET_OS_IPHONE -/** - Color tint for lighting extruded geometries. - - The default value of this property is an expression that evaluates to - `UIColor.whiteColor`. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - - This property corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-js/style-spec/#light-color"><code>color</code></a> - light property in the Mapbox Style Specification. - */ -@property (nonatomic) NSExpression *color; -#else -/** - Color tint for lighting extruded geometries. - - The default value of this property is an expression that evaluates to - `NSColor.whiteColor`. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - - This property corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-js/style-spec/#light-color"><code>color</code></a> - light property in the Mapbox Style Specification. - */ -@property (nonatomic) NSExpression *color; -#endif - -/** - The transition affecting any changes to this layer’s `color` property. - - This property corresponds to the `color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition colorTransition; - -/** - Intensity of lighting (on a scale from 0 to 1). Higher numbers will present as - more extreme contrast. - - The default value of this property is an expression that evaluates to the float - `0.5`. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - - This property corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-js/style-spec/#light-intensity"><code>intensity</code></a> - light property in the Mapbox Style Specification. - */ -@property (nonatomic) NSExpression *intensity; - -/** - The transition affecting any changes to this layer’s `intensity` property. - - This property corresponds to the `intensity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition intensityTransition; - - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLLight.h.ejs b/platform/darwin/src/MGLLight.h.ejs deleted file mode 100644 index 30efef7937..0000000000 --- a/platform/darwin/src/MGLLight.h.ejs +++ /dev/null @@ -1,105 +0,0 @@ -<% - const properties = locals.properties; - const type = locals.type; - const doc = locals.doc; --%> -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" -#import "MGLStyleValue.h" - -NS_ASSUME_NONNULL_BEGIN - -<% for (const property of properties) { -%> -<% if (property.type == "enum") { -%> -/** -<%- propertyDoc(property.name, property, type, 'enum').wrap(80, 1) %> - */ -typedef NS_ENUM(NSUInteger, MGLLight<%- camelize(property.name) %>) { -<% for (const value in property.values) { -%> - /** -<%- propertyDoc(property.name, property.values[value], type, 'enum').wrap(80, 4+1) %> - */ - MGLLightAnchor<%- camelize(value) %>, -<% } -%> -}; -<% } -%> -<% } -%> - -/** - A structure containing information about the position of the light source - relative to lit geometries. - */ -typedef struct __attribute__((objc_boxable)) MGLSphericalPosition { - /** Distance from the center of the base of an object to its light. */ - CGFloat radial; - /** Position of the light relative to 0° (0° when `MGLLight.anchor` is set to viewport corresponds - to the top of the viewport, or 0° when `MGLLight.anchor` is set to map corresponds to due north, - and degrees proceed clockwise). */ - CLLocationDirection azimuthal; - /** Indicates the height of the light (from 0°, directly above, to 180°, directly below). */ - CLLocationDirection polar; -} MGLSphericalPosition; - -/** - Creates a new `MGLSphericalPosition` from the given radial, azimuthal, polar. - - @param radial The radial coordinate. - @param azimuthal The azimuthal angle. - @param polar The polar angle. - - @return Returns a `MGLSphericalPosition` struct containing the position attributes. - */ -NS_INLINE MGLSphericalPosition MGLSphericalPositionMake(CGFloat radial, CLLocationDirection azimuthal, CLLocationDirection polar) { - MGLSphericalPosition position; - position.radial = radial; - position.azimuthal = azimuthal; - position.polar = polar; - - return position; -} - -/** - <%- doc.wrap(80, 1) %> - */ -MGL_EXPORT -@interface MGLLight : NSObject -<% if (properties.length) { -%> - -<% for (const property of properties) { -%> -/** -<%- propertyDoc(property.name, property, type, 'light').wrap(80, 1) %> - - This property corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-js/style-spec/#light-<%- originalPropertyName(property) %>"><code><%- originalPropertyName(property) %></code></a> - light property in the Mapbox Style Specification. -<% if (property.examples) { -%> - - #### Related examples -<%- propertyExample(property).wrap(80, 1) %> -<% } -%> - */ -@property (nonatomic<% if (property.getter) { %>, getter=<%- objCGetter(property) -%><% } %>) NSExpression *<%- camelizeWithLeadingLowercase(property.name) %>; - -<% if (property.transition) { -%> -/** - The transition affecting any changes to this layer’s `<%- camelizeWithLeadingLowercase(property.name) %>` property. - - This property corresponds to the `<%- originalPropertyName(property) %>-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition <%- camelizeWithLeadingLowercase(property.name) %>Transition; - -<% } -%> -<% if (property.original) { -%> -@property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) NSExpression *<%- camelizeWithLeadingLowercase(originalPropertyName(property)) %> __attribute__((unavailable("Use <%- camelizeWithLeadingLowercase(property.name) %> instead."))); - -<% } -%> -<% } -%> -<% } -%> - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLLight.mm b/platform/darwin/src/MGLLight.mm deleted file mode 100644 index b7566d57a4..0000000000 --- a/platform/darwin/src/MGLLight.mm +++ /dev/null @@ -1,133 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -// test - -#import "MGLLight.h" - -#import "MGLTypes.h" -#import "MGLStyleValue_Private.h" -#import "NSValue+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#import <mbgl/style/light.hpp> -#import <mbgl/style/types.hpp> - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLLightAnchor, { - { MGLLightAnchorMap, "map" }, - { MGLLightAnchorViewport, "viewport" }, - }); - -} - -@interface MGLLight() - -@end - -@implementation MGLLight - -- (instancetype)initWithMBGLLight:(const mbgl::style::Light *)mbglLight -{ - if (self = [super init]) { - MGLLogInfo(@"Initializing %@.", NSStringFromClass([self class])); - auto anchor = mbglLight->getAnchor(); - NSExpression *anchorExpression; - if (anchor.isUndefined()) { - mbgl::style::PropertyValue<mbgl::style::LightAnchorType> defaultAnchor = mbglLight->getDefaultAnchor(); - anchorExpression = MGLStyleValueTransformer<mbgl::style::LightAnchorType, NSValue *, mbgl::style::LightAnchorType, MGLLightAnchor>().toExpression(defaultAnchor); - } else { - anchorExpression = MGLStyleValueTransformer<mbgl::style::LightAnchorType, NSValue *, mbgl::style::LightAnchorType, MGLLightAnchor>().toExpression(anchor); - } - - _anchor = anchorExpression; - - auto positionValue = mbglLight->getPosition(); - if (positionValue.isUndefined()) { - _position = MGLStyleValueTransformer<mbgl::style::Position, NSValue *>().toExpression(mbglLight->getDefaultPosition()); - } else { - _position = MGLStyleValueTransformer<mbgl::style::Position, NSValue *>().toExpression(positionValue); - } - _positionTransition = MGLTransitionFromOptions(mbglLight->getPositionTransition()); - auto colorValue = mbglLight->getColor(); - if (colorValue.isUndefined()) { - _color = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(mbglLight->getDefaultColor()); - } else { - _color = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(colorValue); - } - _colorTransition = MGLTransitionFromOptions(mbglLight->getColorTransition()); - auto intensityValue = mbglLight->getIntensity(); - if (intensityValue.isUndefined()) { - _intensity = MGLStyleValueTransformer<float, NSNumber *>().toExpression(mbglLight->getDefaultIntensity()); - } else { - _intensity = MGLStyleValueTransformer<float, NSNumber *>().toExpression(intensityValue); - } - _intensityTransition = MGLTransitionFromOptions(mbglLight->getIntensityTransition()); - } - - return self; -} - -- (mbgl::style::Light)mbglLight -{ - mbgl::style::Light mbglLight; - auto anchor = MGLStyleValueTransformer<mbgl::style::LightAnchorType, NSValue *, mbgl::style::LightAnchorType, MGLLightAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::LightAnchorType>>(self.anchor, false); - mbglLight.setAnchor(anchor); - - auto position = MGLStyleValueTransformer<mbgl::style::Position, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::Position>>(self.position, false); - mbglLight.setPosition(position); - - mbglLight.setPositionTransition(MGLOptionsFromTransition(self.positionTransition)); - - auto color = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(self.color, false); - mbglLight.setColor(color); - - mbglLight.setColorTransition(MGLOptionsFromTransition(self.colorTransition)); - - auto intensity = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(self.intensity, false); - mbglLight.setIntensity(intensity); - - mbglLight.setIntensityTransition(MGLOptionsFromTransition(self.intensityTransition)); - - - return mbglLight; -} - - - -- (void)setAnchor:(NSExpression *)anchor { - MGLLogDebug(@"Setting anchor: %@", anchor); - _anchor = anchor; -} - -- (void)setPosition:(NSExpression *)position { - MGLLogDebug(@"Setting position: %@", position); - _position = position; -} - -- (void)setPositionTransition:(MGLTransition)transition { - MGLLogDebug(@"Setting positionTransition: %@", MGLStringFromMGLTransition(transition)); - _positionTransition = transition; -} - -- (void)setColor:(NSExpression *)color { - MGLLogDebug(@"Setting color: %@", color); - _color = color; -} - -- (void)setColorTransition:(MGLTransition)transition { - MGLLogDebug(@"Setting colorTransition: %@", MGLStringFromMGLTransition(transition)); - _colorTransition = transition; -} - -- (void)setIntensity:(NSExpression *)intensity { - MGLLogDebug(@"Setting intensity: %@", intensity); - _intensity = intensity; -} - -- (void)setIntensityTransition:(MGLTransition)transition { - MGLLogDebug(@"Setting intensityTransition: %@", MGLStringFromMGLTransition(transition)); - _intensityTransition = transition; -} - -@end diff --git a/platform/darwin/src/MGLLight.mm.ejs b/platform/darwin/src/MGLLight.mm.ejs deleted file mode 100644 index e4e455d354..0000000000 --- a/platform/darwin/src/MGLLight.mm.ejs +++ /dev/null @@ -1,120 +0,0 @@ -<% - const properties = locals.properties; --%> -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -// test - -#import "MGLLight.h" - -#import "MGLTypes.h" -#import "MGLStyleValue_Private.h" -#import "NSValue+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#import <mbgl/style/light.hpp> -#import <mbgl/style/types.hpp> - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLLightAnchor, { -<% for (const property of properties) { -%> -<% if (property.type == "enum") { -%> -<% for (const value in property.values) { -%> - { MGLLightAnchor<%- camelize(value) %>, "<%- value %>" }, -<% } -%> -<% } -%> -<% } -%> - }); - -} - -@interface MGLLight() - -@end - -@implementation MGLLight - -- (instancetype)initWithMBGLLight:(const mbgl::style::Light *)mbglLight -{ - if (self = [super init]) { - MGLLogInfo(@"Initializing %@.", NSStringFromClass([self class])); -<% if (properties.length) { -%> -<% for (const property of properties) { -%> -<% if (property.type == "enum") { -%> - auto <%- camelizeWithLeadingLowercase(property.name) -%> = mbglLight->get<%- camelize(property.name) -%>(); - NSExpression *<%- camelizeWithLeadingLowercase(property.name) -%>Expression; - if (<%- camelizeWithLeadingLowercase(property.name) -%>.isUndefined()) { - mbgl::style::PropertyValue<mbgl::style::Light<%- camelize(property.name) -%>Type> default<%- camelize(property.name) -%> = mbglLight->getDefault<%- camelize(property.name) -%>(); - <%- camelizeWithLeadingLowercase(property.name) -%>Expression = MGLStyleValueTransformer<mbgl::style::LightAnchorType, NSValue *, mbgl::style::Light<%- camelize(property.name) -%>Type, MGLLight<%- camelize(property.name) -%>>().toExpression(default<%- camelize(property.name) -%>); - } else { - <%- camelizeWithLeadingLowercase(property.name) -%>Expression = MGLStyleValueTransformer<mbgl::style::Light<%- camelize(property.name) -%>Type, NSValue *, mbgl::style::Light<%- camelize(property.name) -%>Type, MGLLight<%- camelize(property.name) -%>>().toExpression(<%- camelizeWithLeadingLowercase(property.name) -%>); - } - - _<%- camelizeWithLeadingLowercase(property.name) -%> = <%- camelizeWithLeadingLowercase(property.name) -%>Expression; - -<% if (property.transition) { -%> - _<%- camelizeWithLeadingLowercase(property.name) -%>Transition = MGLTransitionFromOptions(mbglLight->get<%- camelize(property.name) -%>Transition()); - -<% } -%> -<% } else {-%> - auto <%- camelizeWithLeadingLowercase(property.name) -%>Value = mbglLight->get<%- camelize(property.name) -%>(); - if (<%- camelizeWithLeadingLowercase(property.name) -%>Value.isUndefined()) { - _<%- camelizeWithLeadingLowercase(property.name) -%> = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toExpression(mbglLight->getDefault<%- camelize(property.name) -%>()); - } else { - _<%- camelizeWithLeadingLowercase(property.name) -%> = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toExpression(<%- camelizeWithLeadingLowercase(property.name) -%>Value); - } -<% if (property.transition) { -%> - _<%- camelizeWithLeadingLowercase(property.name) -%>Transition = MGLTransitionFromOptions(mbglLight->get<%- camelize(property.name) -%>Transition()); -<% } -%> -<% } -%> -<% } -%> -<% } -%> - } - - return self; -} - -- (mbgl::style::Light)mbglLight -{ - mbgl::style::Light mbglLight; -<% if (properties.length) { -%> -<% for (const property of properties) { -%> -<% if (property.type == "enum") { -%> - auto <%- camelizeWithLeadingLowercase(property.name) -%> = MGLStyleValueTransformer<mbgl::style::Light<%- camelize(property.name) -%>Type, NSValue *, mbgl::style::Light<%- camelize(property.name) -%>Type, MGLLight<%- camelize(property.name) -%>>().toPropertyValue<mbgl::style::PropertyValue<<%- valueTransformerArguments(property)[0] %>>>(self.<%- camelizeWithLeadingLowercase(property.name) -%>, false); - mbglLight.set<%- camelize(property.name) -%>(<%- camelizeWithLeadingLowercase(property.name) -%>); - -<% } else {-%> - auto <%- camelizeWithLeadingLowercase(property.name) -%> = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue<mbgl::style::PropertyValue<<%- valueTransformerArguments(property)[0] %>>>(self.<%- camelizeWithLeadingLowercase(property.name) -%>, false); - mbglLight.set<%- camelize(property.name) -%>(<%- camelizeWithLeadingLowercase(property.name) -%>); - -<% } -%> -<% if (property.transition) { -%> - mbglLight.set<%- camelize(property.name) -%>Transition(MGLOptionsFromTransition(self.<%- camelizeWithLeadingLowercase(property.name) -%>Transition)); - -<% } -%> -<% } -%> -<% } -%> - - return mbglLight; -} - -<% if (properties.length) { -%> - -<% for (const property of properties) { -%> - -- (void)set<%- camelize(property.name) %>:(NSExpression *)<%- objCName(property) %> { - MGLLogDebug(@"Setting <%- objCName(property) %>: %@", <%- objCName(property) %>); - _<%- objCName(property) %> = <%- objCName(property) %>; -} -<% if (property["transition"]) { -%> - -- (void)set<%- camelize(property.name) %>Transition:(MGLTransition)transition { - MGLLogDebug(@"Setting <%- objCName(property) %>Transition: %@", MGLStringFromMGLTransition(transition)); - _<%- objCName(property) %>Transition = transition; -} -<% } -%> -<% } -%> -<% } -%> - -@end diff --git a/platform/darwin/src/MGLLight_Private.h b/platform/darwin/src/MGLLight_Private.h deleted file mode 100644 index dbc29c1eff..0000000000 --- a/platform/darwin/src/MGLLight_Private.h +++ /dev/null @@ -1,23 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLLight.h" - -namespace mbgl { - namespace style { - class Light; - } -} - -@interface MGLLight (Private) - -/** - Initializes and returns a `MGLLight` associated with a style's light. - */ -- (instancetype)initWithMBGLLight:(const mbgl::style::Light *)mbglLight; - -/** - Returns an `mbgl::style::Light` representation of the `MGLLight`. - */ -- (mbgl::style::Light)mbglLight; - -@end diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h deleted file mode 100644 index 3400f7e75b..0000000000 --- a/platform/darwin/src/MGLLineStyleLayer.h +++ /dev/null @@ -1,671 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLVectorStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The display of line endings. - - Values of this type are used in the `MGLLineStyleLayer.lineCap` - property. - */ -typedef NS_ENUM(NSUInteger, MGLLineCap) { - /** - A cap with a squared-off end which is drawn to the exact endpoint of the - line. - */ - MGLLineCapButt, - /** - A cap with a rounded end which is drawn beyond the endpoint of the line at - a radius of one-half of the line's width and centered on the endpoint of - the line. - */ - MGLLineCapRound, - /** - A cap with a squared-off end which is drawn beyond the endpoint of the line - at a distance of one-half of the line's width. - */ - MGLLineCapSquare, -}; - -/** - The display of lines when joining. - - Values of this type are used in the `MGLLineStyleLayer.lineJoin` - property. - */ -typedef NS_ENUM(NSUInteger, MGLLineJoin) { - /** - A join with a squared-off end which is drawn beyond the endpoint of the - line at a distance of one-half of the line's width. - */ - MGLLineJoinBevel, - /** - A join with a rounded end which is drawn beyond the endpoint of the line at - a radius of one-half of the line's width and centered on the endpoint of - the line. - */ - MGLLineJoinRound, - /** - A join with a sharp, angled corner which is drawn with the outer sides - beyond the endpoint of the path until they meet. - */ - MGLLineJoinMiter, -}; - -/** - Controls the frame of reference for `MGLLineStyleLayer.lineTranslation`. - - Values of this type are used in the `MGLLineStyleLayer.lineTranslationAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLLineTranslationAnchor) { - /** - The line is translated relative to the map. - */ - MGLLineTranslationAnchorMap, - /** - The line is translated relative to the viewport. - */ - MGLLineTranslationAnchorViewport, -}; - -/** - An `MGLLineStyleLayer` is a style layer that renders one or more stroked - polylines on the map. - - Use a line style layer to configure the visual appearance of polyline or - multipolyline features. These features can come from vector tiles loaded by an - `MGLVectorTileSource` object, or they can be `MGLPolyline`, - `MGLPolylineFeature`, `MGLMultiPolyline`, or `MGLMultiPolylineFeature` - instances in an `MGLShapeSource` or `MGLComputedShapeSource` object. - - You can access an existing line style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new line style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - #### Related examples - See the <a - href="https://docs.mapbox.com/ios/maps/examples/shape-collection/">Add multiple - shapes from a single shape source</a> example to learn how to add a line to - your map using this style layer. See the <a - href="https://docs.mapbox.com/ios/maps/examples/runtime-add-line/">Add a line - style layer from GeoJSON</a> example to learn how to add and style line data to - an `MGLMapView` object at runtime. - - ### Example - - ```swift - let layer = MGLLineStyleLayer(identifier: "trails-path", source: trails) - layer.sourceLayerIdentifier = "trails" - layer.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.5, %@)", - [14: 2, - 18: 20]) - layer.lineColor = NSExpression(forConstantValue: UIColor.brown) - layer.lineCap = NSExpression(forConstantValue: "round") - layer.predicate = NSPredicate(format: "%K == %@", "trail-type", "mountain-biking") - mapView.style?.addLayer(layer) - ``` - */ -MGL_EXPORT -@interface MGLLineStyleLayer : MGLVectorStyleLayer - -/** - Returns a line style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; - -#pragma mark - Accessing the Layout Attributes - -/** - The display of line endings. - - The default value of this property is an expression that evaluates to `butt`. - Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant `MGLLineCap` values - * Any of the following constant string values: - * `butt`: A cap with a squared-off end which is drawn to the exact endpoint - of the line. - * `round`: A cap with a rounded end which is drawn beyond the endpoint of the - line at a radius of one-half of the line's width and centered on the endpoint - of the line. - * `square`: A cap with a squared-off end which is drawn beyond the endpoint - of the line at a distance of one-half of the line's width. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineCap; - -/** - The display of lines when joining. - - The default value of this property is an expression that evaluates to `miter`. - Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant `MGLLineJoin` values - * Any of the following constant string values: - * `bevel`: A join with a squared-off end which is drawn beyond the endpoint - of the line at a distance of one-half of the line's width. - * `round`: A join with a rounded end which is drawn beyond the endpoint of - the line at a radius of one-half of the line's width and centered on the - endpoint of the line. - * `miter`: A join with a sharp, angled corner which is drawn with the outer - sides beyond the endpoint of the path until they meet. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *lineJoin; - -/** - Used to automatically convert miter joins to bevel joins for sharp angles. - - The default value of this property is an expression that evaluates to the float - `2`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `lineJoin` is set to an - expression that evaluates to `miter`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineMiterLimit; - -/** - Used to automatically convert round joins to miter joins for shallow angles. - - The default value of this property is an expression that evaluates to the float - `1.05`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `lineJoin` is set to an - expression that evaluates to `round`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineRoundLimit; - -#pragma mark - Accessing the Paint Attributes - -/** - Blur applied to the line, in points. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *lineBlur; - -/** - The transition affecting any changes to this layer’s `lineBlur` property. - - This property corresponds to the `line-blur-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition lineBlurTransition; - -#if TARGET_OS_IPHONE -/** - The color with which the line will be drawn. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `linePattern` is set to `nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *lineColor; -#else -/** - The color with which the line will be drawn. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `linePattern` is set to `nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *lineColor; -#endif - -/** - The transition affecting any changes to this layer’s `lineColor` property. - - This property corresponds to the `line-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition lineColorTransition; - -/** - Specifies the lengths of the alternating dashes and gaps that form the dash - pattern. The lengths are later scaled by the line width. To convert a dash - length to points, multiply the length by the current line width. Note that - GeoJSON sources with `lineMetrics: true` specified won't render dashed lines to - the expected scale. Also note that zoom-dependent expressions will be evaluated - only at integer zoom levels. - - This property is measured in line widths. - - This property is only applied to the style if `linePattern` is set to `nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-line-dasharray"><code>line-dasharray</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant array values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineDashPattern; - -/** - The transition affecting any changes to this layer’s `lineDashPattern` property. - - This property corresponds to the `line-dasharray-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition lineDashPatternTransition; - -@property (nonatomic, null_resettable) NSExpression *lineDasharray __attribute__((unavailable("Use lineDashPattern instead."))); - -/** - Draws a line casing outside of a line's actual path. Value indicates the width - of the inner gap. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *lineGapWidth; - -/** - The transition affecting any changes to this layer’s `lineGapWidth` property. - - This property corresponds to the `line-gap-width-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition lineGapWidthTransition; - -#if TARGET_OS_IPHONE -/** - The color gradient with which the line will be drawn. This property only has an - effect on lines defined by an `MGLShapeSource` whose - `MGLShapeSourceOptionLineDistanceMetrics` option is set to `YES`. - - This property is only applied to the style if `lineDasharray` is set to `nil`, - and `linePattern` is set to `nil`, and the data source requirements are met. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$lineProgress` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineGradient; -#else -/** - The color gradient with which the line will be drawn. This property only has an - effect on lines defined by an `MGLShapeSource` whose - `MGLShapeSourceOptionLineDistanceMetrics` option is set to `YES`. - - This property is only applied to the style if `lineDasharray` is set to `nil`, - and `linePattern` is set to `nil`, and the data source requirements are met. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$lineProgress` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineGradient; -#endif - -/** - The line's offset. For linear features, a positive value offsets the line to - the right, relative to the direction of the line, and a negative value to the - left. For polygon features, a positive value results in an inset, and a - negative value results in an outset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *lineOffset; - -/** - The transition affecting any changes to this layer’s `lineOffset` property. - - This property corresponds to the `line-offset-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition lineOffsetTransition; - -/** - The opacity at which the line will be drawn. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *lineOpacity; - -/** - The transition affecting any changes to this layer’s `lineOpacity` property. - - This property corresponds to the `line-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition lineOpacityTransition; - -/** - Name of image in style images to use for drawing image lines. For seamless - patterns, image width must be a factor of two (2, 4, 8, ..., 512). - - You can set this property to an expression containing any of the following: - - * Constant string values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *linePattern; - -/** - The transition affecting any changes to this layer’s `linePattern` property. - - This property corresponds to the `line-pattern-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition linePatternTransition; - -#if TARGET_OS_IPHONE -/** - The geometry's offset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points downward. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-line-translate"><code>line-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineTranslation; -#else -/** - The geometry's offset. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points upward. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-line-translate"><code>line-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineTranslation; -#endif - -/** - The transition affecting any changes to this layer’s `lineTranslation` property. - - This property corresponds to the `line-translate-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition lineTranslationTransition; - -@property (nonatomic, null_resettable) NSExpression *lineTranslate __attribute__((unavailable("Use lineTranslation instead."))); - -/** - Controls the frame of reference for `lineTranslation`. - - The default value of this property is an expression that evaluates to `map`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `lineTranslation` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-line-translate-anchor"><code>line-translate-anchor</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLLineTranslationAnchor` values - * Any of the following constant string values: - * `map`: The line is translated relative to the map. - * `viewport`: The line is translated relative to the viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *lineTranslationAnchor; - -@property (nonatomic, null_resettable) NSExpression *lineTranslateAnchor __attribute__((unavailable("Use lineTranslationAnchor instead."))); - -/** - Stroke thickness. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *lineWidth; - -/** - The transition affecting any changes to this layer’s `lineWidth` property. - - This property corresponds to the `line-width-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition lineWidthTransition; - -@end - -/** - Methods for wrapping an enumeration value for a style layer attribute in an - `MGLLineStyleLayer` object and unwrapping its raw value. - */ -@interface NSValue (MGLLineStyleLayerAdditions) - -#pragma mark Working with Line Style Layer Attribute Values - -/** - Creates a new value object containing the given `MGLLineCap` enumeration. - - @param lineCap The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLLineCap:(MGLLineCap)lineCap; - -/** - The `MGLLineCap` enumeration representation of the value. - */ -@property (readonly) MGLLineCap MGLLineCapValue; - -/** - Creates a new value object containing the given `MGLLineJoin` enumeration. - - @param lineJoin The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLLineJoin:(MGLLineJoin)lineJoin; - -/** - The `MGLLineJoin` enumeration representation of the value. - */ -@property (readonly) MGLLineJoin MGLLineJoinValue; - -/** - Creates a new value object containing the given `MGLLineTranslationAnchor` enumeration. - - @param lineTranslationAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLLineTranslationAnchor:(MGLLineTranslationAnchor)lineTranslationAnchor; - -/** - The `MGLLineTranslationAnchor` enumeration representation of the value. - */ -@property (readonly) MGLLineTranslationAnchor MGLLineTranslationAnchorValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm deleted file mode 100644 index 62d778a6f3..0000000000 --- a/platform/darwin/src/MGLLineStyleLayer.mm +++ /dev/null @@ -1,568 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLLineStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLLineStyleLayer_Private.h" - -#include <mbgl/style/layers/line_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLLineCap, { - { MGLLineCapButt, "butt" }, - { MGLLineCapRound, "round" }, - { MGLLineCapSquare, "square" }, - }); - - MBGL_DEFINE_ENUM(MGLLineJoin, { - { MGLLineJoinBevel, "bevel" }, - { MGLLineJoinRound, "round" }, - { MGLLineJoinMiter, "miter" }, - }); - - MBGL_DEFINE_ENUM(MGLLineTranslationAnchor, { - { MGLLineTranslationAnchorMap, "map" }, - { MGLLineTranslationAnchorViewport, "viewport" }, - }); - -} - -@interface MGLLineStyleLayer () - -@property (nonatomic, readonly) mbgl::style::LineLayer *rawLayer; - -@end - -@implementation MGLLineStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::LineLayer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::LineLayer *)rawLayer -{ - return (mbgl::style::LineLayer *)super.rawLayer; -} - -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -- (NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - - auto layerID = self.rawLayer->getSourceLayer(); - return layerID.empty() ? nil : @(layerID.c_str()); -} - -- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting sourceLayerIdentifier: %@", sourceLayerIdentifier); - - self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); -} - -- (void)setPredicate:(NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting predicate: %@", predicate); - - self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::Filter()); -} - -- (NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - - return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; -} - -#pragma mark - Accessing the Layout Attributes - -- (void)setLineCap:(NSExpression *)lineCap { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineCap: %@", lineCap); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::LineCapType, NSValue *, mbgl::style::LineCapType, MGLLineCap>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::LineCapType>>(lineCap, false); - self.rawLayer->setLineCap(mbglValue); -} - -- (NSExpression *)lineCap { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineCap(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineCap(); - } - return MGLStyleValueTransformer<mbgl::style::LineCapType, NSValue *, mbgl::style::LineCapType, MGLLineCap>().toExpression(propertyValue); -} - -- (void)setLineJoin:(NSExpression *)lineJoin { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineJoin: %@", lineJoin); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::LineJoinType, NSValue *, mbgl::style::LineJoinType, MGLLineJoin>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::LineJoinType>>(lineJoin, true); - self.rawLayer->setLineJoin(mbglValue); -} - -- (NSExpression *)lineJoin { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineJoin(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineJoin(); - } - return MGLStyleValueTransformer<mbgl::style::LineJoinType, NSValue *, mbgl::style::LineJoinType, MGLLineJoin>().toExpression(propertyValue); -} - -- (void)setLineMiterLimit:(NSExpression *)lineMiterLimit { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineMiterLimit: %@", lineMiterLimit); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(lineMiterLimit, false); - self.rawLayer->setLineMiterLimit(mbglValue); -} - -- (NSExpression *)lineMiterLimit { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineMiterLimit(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineMiterLimit(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setLineRoundLimit:(NSExpression *)lineRoundLimit { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineRoundLimit: %@", lineRoundLimit); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(lineRoundLimit, false); - self.rawLayer->setLineRoundLimit(mbglValue); -} - -- (NSExpression *)lineRoundLimit { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineRoundLimit(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineRoundLimit(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setLineBlur:(NSExpression *)lineBlur { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineBlur: %@", lineBlur); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(lineBlur, true); - self.rawLayer->setLineBlur(mbglValue); -} - -- (NSExpression *)lineBlur { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineBlur(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineBlur(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setLineBlurTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineBlurTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLineBlurTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)lineBlurTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLineBlurTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setLineColor:(NSExpression *)lineColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineColor: %@", lineColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(lineColor, true); - self.rawLayer->setLineColor(mbglValue); -} - -- (NSExpression *)lineColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setLineColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLineColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)lineColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLineColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setLineDashPattern:(NSExpression *)lineDashPattern { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineDashPattern: %@", lineDashPattern); - - auto mbglValue = MGLStyleValueTransformer<std::vector<float>, NSArray<NSNumber *> *, float>().toPropertyValue<mbgl::style::PropertyValue<std::vector<float>>>(lineDashPattern, false); - self.rawLayer->setLineDasharray(mbglValue); -} - -- (NSExpression *)lineDashPattern { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineDasharray(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineDasharray(); - } - return MGLStyleValueTransformer<std::vector<float>, NSArray<NSNumber *> *, float>().toExpression(propertyValue); -} - -- (void)setLineDashPatternTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineDashPatternTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLineDasharrayTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)lineDashPatternTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLineDasharrayTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setLineDasharray:(NSExpression *)lineDasharray { -} - -- (NSExpression *)lineDasharray { - return self.lineDashPattern; -} - -- (void)setLineGapWidth:(NSExpression *)lineGapWidth { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineGapWidth: %@", lineGapWidth); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(lineGapWidth, true); - self.rawLayer->setLineGapWidth(mbglValue); -} - -- (NSExpression *)lineGapWidth { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineGapWidth(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineGapWidth(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setLineGapWidthTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineGapWidthTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLineGapWidthTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)lineGapWidthTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLineGapWidthTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setLineGradient:(NSExpression *)lineGradient { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineGradient: %@", lineGradient); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::ColorRampPropertyValue>(lineGradient); - self.rawLayer->setLineGradient(mbglValue); -} - -- (NSExpression *)lineGradient { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineGradient(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineGradient(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setLineOffset:(NSExpression *)lineOffset { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineOffset: %@", lineOffset); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(lineOffset, true); - self.rawLayer->setLineOffset(mbglValue); -} - -- (NSExpression *)lineOffset { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineOffset(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineOffset(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setLineOffsetTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineOffsetTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLineOffsetTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)lineOffsetTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLineOffsetTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setLineOpacity:(NSExpression *)lineOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineOpacity: %@", lineOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(lineOpacity, true); - self.rawLayer->setLineOpacity(mbglValue); -} - -- (NSExpression *)lineOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setLineOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLineOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)lineOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLineOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setLinePattern:(NSExpression *)linePattern { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting linePattern: %@", linePattern); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::expression::Image>>(linePattern, true); - self.rawLayer->setLinePattern(mbglValue); -} - -- (NSExpression *)linePattern { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLinePattern(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLinePattern(); - } - return MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toExpression(propertyValue); -} - -- (void)setLinePatternTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting linePatternTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLinePatternTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)linePatternTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLinePatternTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setLineTranslation:(NSExpression *)lineTranslation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineTranslation: %@", lineTranslation); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 2>>>(lineTranslation, false); - self.rawLayer->setLineTranslate(mbglValue); -} - -- (NSExpression *)lineTranslation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineTranslate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineTranslate(); - } - return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toExpression(propertyValue); -} - -- (void)setLineTranslationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineTranslationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLineTranslateTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)lineTranslationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLineTranslateTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setLineTranslate:(NSExpression *)lineTranslate { -} - -- (NSExpression *)lineTranslate { - return self.lineTranslation; -} - -- (void)setLineTranslationAnchor:(NSExpression *)lineTranslationAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineTranslationAnchor: %@", lineTranslationAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLLineTranslationAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::TranslateAnchorType>>(lineTranslationAnchor, false); - self.rawLayer->setLineTranslateAnchor(mbglValue); -} - -- (NSExpression *)lineTranslationAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineTranslateAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineTranslateAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLLineTranslationAnchor>().toExpression(propertyValue); -} - -- (void)setLineTranslateAnchor:(NSExpression *)lineTranslateAnchor { -} - -- (NSExpression *)lineTranslateAnchor { - return self.lineTranslationAnchor; -} - -- (void)setLineWidth:(NSExpression *)lineWidth { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineWidth: %@", lineWidth); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(lineWidth, true); - self.rawLayer->setLineWidth(mbglValue); -} - -- (NSExpression *)lineWidth { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getLineWidth(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultLineWidth(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setLineWidthTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting lineWidthTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setLineWidthTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)lineWidthTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getLineWidthTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -@end - -@implementation NSValue (MGLLineStyleLayerAdditions) - -+ (NSValue *)valueWithMGLLineCap:(MGLLineCap)lineCap { - return [NSValue value:&lineCap withObjCType:@encode(MGLLineCap)]; -} - -- (MGLLineCap)MGLLineCapValue { - MGLLineCap lineCap; - [self getValue:&lineCap]; - return lineCap; -} - -+ (NSValue *)valueWithMGLLineJoin:(MGLLineJoin)lineJoin { - return [NSValue value:&lineJoin withObjCType:@encode(MGLLineJoin)]; -} - -- (MGLLineJoin)MGLLineJoinValue { - MGLLineJoin lineJoin; - [self getValue:&lineJoin]; - return lineJoin; -} - -+ (NSValue *)valueWithMGLLineTranslationAnchor:(MGLLineTranslationAnchor)lineTranslationAnchor { - return [NSValue value:&lineTranslationAnchor withObjCType:@encode(MGLLineTranslationAnchor)]; -} - -- (MGLLineTranslationAnchor)MGLLineTranslationAnchorValue { - MGLLineTranslationAnchor lineTranslationAnchor; - [self getValue:&lineTranslationAnchor]; - return lineTranslationAnchor; -} - -@end - -namespace mbgl { - -MGLStyleLayer* LineStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLLineStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLLineStyleLayer_Private.h b/platform/darwin/src/MGLLineStyleLayer_Private.h deleted file mode 100644 index b4c7b3ee7c..0000000000 --- a/platform/darwin/src/MGLLineStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/line_layer_factory.hpp> - -namespace mbgl { - -class LineStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::LineLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLLocationManager.h b/platform/darwin/src/MGLLocationManager.h deleted file mode 100644 index ecb9192981..0000000000 --- a/platform/darwin/src/MGLLocationManager.h +++ /dev/null @@ -1,203 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -NS_ASSUME_NONNULL_BEGIN - -@protocol MGLLocationManagerDelegate; - -/** - The `MGLLocationManager` protocol defines a set of methods that a class must - implement in order to serve as the location manager of an `MGLMapView`. A location - manager is responsible for notifying the map view about location-related events, - such as a change in the user’s location. This protocol is similar to the - Core Location framework’s `CLLocationManager` class, but your implementation - does not need to be based on `CLLocationManager`. - - To receive location updates from an object that conforms to the `MGLLocationManager` - protocol, use the optional methods available in the `MGLLocationManagerDelegate` protocol. - */ -@protocol MGLLocationManager <NSObject> - -@optional - -#pragma mark Configuring Location Update Precision - -/** - Specifies the minimum distance (measured in meters) a device must move horizontally - before a location update is generated. - - The default value of this property is `kCLDistanceFilterNone` when `MGLMapView` uses its - default location manager. - - @see `CLLocationManager.distanceFilter` - */ -- (CLLocationDistance)distanceFilter; - -/** - Sets the minimum update distance in meters. - @param distanceFilter The distance filter in meters. - */ -- (void)setDistanceFilter:(CLLocationDistance) distanceFilter; - -/** - Specifies the accuracy of the location data. - - The default value is `kCLLocationAccuracyBest` when `MGLMapView` uses its - default location manager. - - @note Determining a location with greater accuracy requires more time and more power. - - @see `CLLocationManager.desiredAccuracy` - */ -- (CLLocationAccuracy)desiredAccuracy; - -/** - Sets the desired location accuracy. - - @param desiredAccuracy The desired location accuracy. - */ -- (void)setDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy; - -/** - Specifies the type of user activity associated with the location updates. - - The location manager uses this property as a cue to determine when location updates - may be automatically paused. - - The default value is `CLActivityTypeOther` when `MGLMapView` uses its - default location manager. - - @see `CLLocationManager.activityType` - */ -- (CLActivityType)activityType; - -/** - Sets the type of user activity associated with the location updates. - - @param activityType The location's manager activity type. - */ -- (void)setActivityType:(CLActivityType)activityType; - -@required - -/** - The delegate to receive location updates. - - Do not set the location manager’s delegate yourself. `MGLMapView` sets this property - after the location manager becomes `MGLMapView`’s location manager. - */ -@property (nonatomic, weak) id<MGLLocationManagerDelegate> delegate; - -#pragma mark Requesting Authorization for Location Services - -/** - Returns the current localization authorization status. - - @see `+[CLLocationManger authorizationStatus]` - */ -@property (nonatomic, readonly) CLAuthorizationStatus authorizationStatus; - -/** - Requests permission to use the location services whenever the app is running. - */ -- (void)requestAlwaysAuthorization; - -/** - Requests permission to use the location services while the app is in - the foreground. - */ -- (void)requestWhenInUseAuthorization; - -#pragma mark Initiating Location Updates - -/** - Starts the generation of location updates that reports the user's current location. - */ -- (void)startUpdatingLocation; - -/** - Stops the generation of location updates. - */ -- (void)stopUpdatingLocation; - -#pragma mark Initiating Heading Updates - -/** - Specifies a physical device orientation. - */ -@property (nonatomic) CLDeviceOrientation headingOrientation; - -/** - Starts the generation of heading updates that reports the user's current hading. - */ -- (void)startUpdatingHeading; - -/** - Stops the generation of heading updates. - */ -- (void)stopUpdatingHeading; - -/** - Dissmisses immediately the heading calibration view from screen. - */ -- (void)dismissHeadingCalibrationDisplay; - -@end - -/** - The `MGLLocationManagerDelegate` protocol defines a set of methods that respond - to location updates from an `MGLLocationManager` object that is serving as the - location manager of an `MGLMapView`. - */ -@protocol MGLLocationManagerDelegate <NSObject> - -#pragma mark Responding to Location Updates - -/** - Notifies the delegate with the new location data. - - @param manager The location manager reporting the update. - @param locations An array of `CLLocation` objects in chronological order, - with the last object representing the most recent location. This array - contains multiple `CLLocation` objects when `MGLMapView` uses its - default location manager. - */ -- (void)locationManager:(id<MGLLocationManager>)manager - didUpdateLocations:(NSArray<CLLocation *> *)locations; - -#pragma mark Responding to Heading Updates - -/** - Notifies the delegate with the new heading data. - - @param manager The location manager reporting the update. - @param newHeading The new heading update. - */ -- (void)locationManager:(id<MGLLocationManager>)manager - didUpdateHeading:(CLHeading *)newHeading; - -/** - Asks the delegate if the calibration alert should be displayed. - - @param manager The location manager reporting the calibration. - */ -- (BOOL)locationManagerShouldDisplayHeadingCalibration:(id<MGLLocationManager>)manager; - -#pragma mark Responding to Location Updates Errors - -/** - Notifies the delegate that the location manager was unable to retrieve - location updates. - - @param manager The location manager reporting the error. - @param error An error object containing the error code that indicates - why the location manager failed. - */ -- (void)locationManager:(id<MGLLocationManager>)manager - didFailWithError:(nonnull NSError *)error; - -@optional - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLLocationManager.m b/platform/darwin/src/MGLLocationManager.m deleted file mode 100644 index 29e3ccaa30..0000000000 --- a/platform/darwin/src/MGLLocationManager.m +++ /dev/null @@ -1,116 +0,0 @@ -#import "MGLLocationManager_Private.h" - -@interface MGLCLLocationManager()<CLLocationManagerDelegate> - -@property (nonatomic) CLLocationManager *locationManager; - -@end - -@implementation MGLCLLocationManager - -- (instancetype)init -{ - if (self = [super init]) { - _locationManager = [[CLLocationManager alloc] init]; - _locationManager.delegate = self; - } - return self; -} - -@synthesize delegate; - -- (void)setHeadingOrientation:(CLDeviceOrientation)headingOrientation -{ - self.locationManager.headingOrientation = headingOrientation; -} - -- (CLDeviceOrientation)headingOrientation -{ - return self.locationManager.headingOrientation; -} - -- (void)setDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy { - self.locationManager.desiredAccuracy = desiredAccuracy; -} - -- (CLLocationAccuracy)desiredAccuracy { - return self.locationManager.desiredAccuracy; -} - -- (CLAuthorizationStatus)authorizationStatus { - return [CLLocationManager authorizationStatus]; -} - -- (void)setActivityType:(CLActivityType)activityType { - self.locationManager.activityType = activityType; -} - -- (CLActivityType)activityType { - return self.locationManager.activityType; -} - -- (void)dismissHeadingCalibrationDisplay { - [self.locationManager dismissHeadingCalibrationDisplay]; -} - -- (void)requestAlwaysAuthorization { - [self.locationManager requestAlwaysAuthorization]; -} - -- (void)requestWhenInUseAuthorization { - [self.locationManager requestWhenInUseAuthorization]; -} - -- (void)startUpdatingHeading { - [self.locationManager startUpdatingHeading]; -} - -- (void)startUpdatingLocation { - [self.locationManager startUpdatingLocation]; -} - -- (void)stopUpdatingHeading { - [self.locationManager stopUpdatingHeading]; -} - -- (void)stopUpdatingLocation { - [self.locationManager stopUpdatingLocation]; -} - -- (void)dealloc -{ - [self.locationManager stopUpdatingLocation]; - [self.locationManager stopUpdatingHeading]; - self.locationManager.delegate = nil; - self.delegate = nil; -} - -#pragma mark - CLLocationManagerDelegate - -- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { - if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateLocations:)]) { - [self.delegate locationManager:self didUpdateLocations:locations]; - } -} - -- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { - if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateHeading:)]) { - [self.delegate locationManager:self didUpdateHeading:newHeading]; - } -} - -- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager { - if ([self.delegate respondsToSelector:@selector(locationManagerShouldDisplayHeadingCalibration:)]) { - return [self.delegate locationManagerShouldDisplayHeadingCalibration:self]; - } - - return NO; -} - -- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { - if ([self.delegate respondsToSelector:@selector(locationManager:didFailWithError:)]) { - [self.delegate locationManager:self didFailWithError:error]; - } -} - -@end diff --git a/platform/darwin/src/MGLLocationManager_Private.h b/platform/darwin/src/MGLLocationManager_Private.h deleted file mode 100644 index 4f09405e71..0000000000 --- a/platform/darwin/src/MGLLocationManager_Private.h +++ /dev/null @@ -1,5 +0,0 @@ -#import "MGLLocationManager.h" - -@interface MGLCLLocationManager : NSObject<MGLLocationManager> - -@end diff --git a/platform/darwin/src/MGLLoggingConfiguration.h b/platform/darwin/src/MGLLoggingConfiguration.h deleted file mode 100644 index 2445078584..0000000000 --- a/platform/darwin/src/MGLLoggingConfiguration.h +++ /dev/null @@ -1,99 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" - -#ifndef MGL_LOGGING_DISABLED - #ifndef MGL_LOGGING_ENABLE_DEBUG - #ifndef NDEBUG - #define MGL_LOGGING_ENABLE_DEBUG 1 - #endif - #endif - -NS_ASSUME_NONNULL_BEGIN - -/** - Constants indicating the message's logging level. - */ -typedef NS_ENUM(NSInteger, MGLLoggingLevel) { - /** - None-level won't print any messages. - */ - MGLLoggingLevelNone = 0, - /** - Fault-level messages contain system-level error information. - */ - MGLLoggingLevelFault, - /** - Error-level messages contain information that is intended to aid in process-level - errors. - */ - MGLLoggingLevelError, - /** - Warning-level messages contain warning information for potential risks. - */ - MGLLoggingLevelWarning, - /** - Info-level messages contain information that may be helpful for flow tracing - but is not essential. - */ - MGLLoggingLevelInfo, - /** - Debug-level messages contain information that may be helpful for troubleshooting - specific problems. - */ -#if MGL_LOGGING_ENABLE_DEBUG - MGLLoggingLevelDebug, -#endif - /** - Verbose-level will print all messages. - */ - MGLLoggingLevelVerbose, -}; - -/** - A block to be called once `loggingLevel` is set to a higher value than `MGLLoggingLevelNone`. - - @param loggingLevel The message logging level. - @param filePath The description of the file and method for the calling message. - @param line The line where the message is logged. - @param message The logging message. - */ -typedef void (^MGLLoggingBlockHandler)(MGLLoggingLevel loggingLevel, NSString *filePath, NSUInteger line, NSString *message); - -/** - The `MGLLoggingConfiguration` object provides a global way to set this SDK logging levels - and logging handler. - */ -MGL_EXPORT -@interface MGLLoggingConfiguration : NSObject - -/** - The handler this SDK uses to log messages. - - If this property is set to nil or if no custom handler is provided this property - is set to the default handler. - - The default handler uses `os_log` and `NSLog` for iOS 10+ and iOS < 10 respectively. - */ -@property (nonatomic, copy, null_resettable) MGLLoggingBlockHandler handler; - -/** - The logging level. - - The default value is `MGLLoggingLevelNone`. - - Setting this property includes logging levels less than or equal to the setted value. - */ -@property (assign, nonatomic) MGLLoggingLevel loggingLevel; - -/** - Returns the shared logging object. - */ -@property (class, nonatomic, readonly) MGLLoggingConfiguration *sharedConfiguration; - -- (MGLLoggingBlockHandler)handler UNAVAILABLE_ATTRIBUTE; - -@end - -NS_ASSUME_NONNULL_END -#endif diff --git a/platform/darwin/src/MGLLoggingConfiguration.mm b/platform/darwin/src/MGLLoggingConfiguration.mm deleted file mode 100644 index 75d2439365..0000000000 --- a/platform/darwin/src/MGLLoggingConfiguration.mm +++ /dev/null @@ -1,161 +0,0 @@ -#include <mbgl/util/logging.hpp> -#include <mbgl/util/enum.hpp> - -#import "MGLLoggingConfiguration_Private.h" - -#ifndef MGL_LOGGING_DISABLED -#if __has_builtin(__builtin_os_log_format) -#import <os/log.h> -#endif - -namespace mbgl { - -class MGLCoreLoggingObserver : public Log :: Observer { -public: - //Return true not print messages at core level, and filter at platform level. - bool onRecord(EventSeverity severity, Event event, int64_t code, const std::string& msg) override{ - - NSString *message = [NSString stringWithFormat:@"[event]:%s [code]:%lld [message]:%@", Enum<Event>::toString(event), code, [NSString stringWithCString:msg.c_str() encoding:NSUTF8StringEncoding]]; - switch (severity) { - case EventSeverity::Debug: - MGLLogDebug(message); - break; - case EventSeverity::Info: - MGLLogInfo(message); - break; - case EventSeverity::Warning: - MGLLogWarning(message); - break; - case EventSeverity::Error: - MGLLogError(message); - break; - } - return true; - } -}; -} - -@implementation MGLLoggingConfiguration -{ - std::unique_ptr<mbgl::MGLCoreLoggingObserver> _coreLoggingObserver; -} - -+ (instancetype)sharedConfiguration { - static dispatch_once_t once; - static id sharedConfiguration; - dispatch_once(&once, ^{ - sharedConfiguration = [[self alloc] init]; - ((MGLLoggingConfiguration *)sharedConfiguration).handler = nil; - }); - return sharedConfiguration; -} - -- (id)init{ - if(self = [super init]){ - mbgl::Log::setObserver(std::make_unique<mbgl::MGLCoreLoggingObserver>()); - } - return self; -} - -- (void)setHandler:(void (^)(MGLLoggingLevel, NSString *, NSUInteger, NSString *))handler { - - if (!handler) { - _handler = [self defaultBlockHandler]; - } else { - _handler = handler; - } -} - -- (void)logCallingFunction:(const char *)callingFunction functionLine:(NSUInteger)functionLine messageType:(MGLLoggingLevel)type format:(id)messageFormat, ... { - va_list formatList; - va_start(formatList, messageFormat); - NSString *formattedMessage = [[NSString alloc] initWithFormat:messageFormat arguments:formatList]; - va_end(formatList); - - _handler(type, @(callingFunction), functionLine, formattedMessage); - -} - -- (MGLLoggingBlockHandler)defaultBlockHandler { - MGLLoggingBlockHandler mapboxHandler = ^(MGLLoggingLevel level, NSString *fileName, NSUInteger line, NSString *message) { - - if (@available(iOS 10.0, macOS 10.12.0, *)) { - static dispatch_once_t once; - static os_log_t info_log; -#if MGL_LOGGING_ENABLE_DEBUG - static os_log_t debug_log; -#endif - static os_log_t error_log; - static os_log_t fault_log; - static os_log_type_t log_types[] = { OS_LOG_TYPE_DEFAULT, - OS_LOG_TYPE_INFO, -#if MGL_LOGGING_ENABLE_DEBUG - OS_LOG_TYPE_DEBUG, -#endif - OS_LOG_TYPE_ERROR, - OS_LOG_TYPE_FAULT }; - dispatch_once(&once, ^ { - info_log = os_log_create("com.mapbox.Mapbox", "INFO"); -#if MGL_LOGGING_ENABLE_DEBUG - debug_log = os_log_create("com.mapbox.Mapbox", "DEBUG"); -#endif - error_log = os_log_create("com.mapbox.Mapbox", "ERROR"); - fault_log = os_log_create("com.mapbox.Mapbox", "FAULT"); - }); - - os_log_t mapbox_log; - switch (level) { - case MGLLoggingLevelInfo: - case MGLLoggingLevelWarning: - mapbox_log = info_log; - break; -#if MGL_LOGGING_ENABLE_DEBUG - case MGLLoggingLevelDebug: - mapbox_log = debug_log; - break; -#endif - case MGLLoggingLevelError: - mapbox_log = error_log; - break; - case MGLLoggingLevelFault: - mapbox_log = fault_log; - break; - case MGLLoggingLevelNone: - default: - break; - } - - os_log_type_t logType = log_types[level]; - os_log_with_type(mapbox_log, logType, "%@ - %lu: %@", fileName, (unsigned long)line, message); - } else { - NSString *category; - switch (level) { - case MGLLoggingLevelInfo: - case MGLLoggingLevelWarning: - category = @"INFO"; - break; -#if MGL_LOGGING_ENABLE_DEBUG - case MGLLoggingLevelDebug: - category = @"DEBUG"; - break; -#endif - case MGLLoggingLevelError: - category = @"ERROR"; - break; - case MGLLoggingLevelFault: - category = @"FAULT"; - break; - case MGLLoggingLevelNone: - default: - break; - } - - NSLog(@"[%@] %@ - %lu: %@", category, fileName, (unsigned long)line, message); - } - }; - - return mapboxHandler; -} - -@end -#endif diff --git a/platform/darwin/src/MGLLoggingConfiguration_Private.h b/platform/darwin/src/MGLLoggingConfiguration_Private.h deleted file mode 100644 index 40b4df440d..0000000000 --- a/platform/darwin/src/MGLLoggingConfiguration_Private.h +++ /dev/null @@ -1,67 +0,0 @@ -#import "MGLLoggingConfiguration.h" - -NS_INLINE NSString *MGLStringFromBOOL(BOOL value) { - return value ? @"YES" : @"NO"; -} - -#if TARGET_OS_OSX -NS_INLINE NSString *MGLStringFromNSEdgeInsets(NSEdgeInsets insets) { - return [NSString stringWithFormat:@"{ top: %f, left: %f, bottom: %f, right: %f", insets.top, insets.left, insets.bottom, insets.right]; -} -#endif - -#ifdef MGL_LOGGING_DISABLED - -#define MGLLogInfo(...) -#define MGLLogDebug(...) -#define MGLLogWarning(...) -#define MGLLogError(...) -#define MGLLogFault(...) - -#else - -#if MGL_LOGGING_ENABLE_DEBUG - #define MGLLogDebug(message, ...) MGLLogWithType(MGLLoggingLevelDebug, __PRETTY_FUNCTION__, __LINE__, message, ##__VA_ARGS__) -#else - #define MGLLogDebug(...) -#endif - -#define MGLLogInfo(message, ...) MGLLogWithType(MGLLoggingLevelInfo, __PRETTY_FUNCTION__, __LINE__, message, ##__VA_ARGS__) -#define MGLLogWarning(message, ...) MGLLogWithType(MGLLoggingLevelWarning, __PRETTY_FUNCTION__, __LINE__, message, ##__VA_ARGS__) -#define MGLLogError(message, ...) MGLLogWithType(MGLLoggingLevelError, __PRETTY_FUNCTION__, __LINE__, message, ##__VA_ARGS__) -#define MGLLogFault(message, ...) MGLLogWithType(MGLLoggingLevelFault, __PRETTY_FUNCTION__, __LINE__, message, ##__VA_ARGS__) - -#endif - -#define MGLAssert(expression, message, ...) \ - __extension__({ \ - if (__builtin_expect(!(expression), 0)) { \ - MGLLogFault(message, ##__VA_ARGS__); \ - } \ - NSAssert(expression, message, ##__VA_ARGS__); \ - }) -#define MGLCAssert(expression, message, ...) \ - __extension__({ \ - if (__builtin_expect(!(expression), 0)) { \ - MGLLogFault(message, ##__VA_ARGS__); \ - } \ - NSCAssert(expression, message, ##__VA_ARGS__); \ - }) - - -#ifndef MGL_LOGGING_DISABLED - -#define MGLLogWithType(type, function, line, message, ...) \ -{ \ - if ([MGLLoggingConfiguration sharedConfiguration].loggingLevel != MGLLoggingLevelNone && type <= [MGLLoggingConfiguration sharedConfiguration].loggingLevel) \ - { \ - [[MGLLoggingConfiguration sharedConfiguration] logCallingFunction:function functionLine:line messageType:type format:(message), ##__VA_ARGS__]; \ - } \ -} - -@interface MGLLoggingConfiguration (Private) - -- (void)logCallingFunction:(const char *)callingFunction functionLine:(NSUInteger)functionLine messageType:(MGLLoggingLevel)type format:(id)messageFormat, ...; - -@end -#endif diff --git a/platform/darwin/src/MGLMapCamera.h b/platform/darwin/src/MGLMapCamera.h deleted file mode 100644 index c0e40bc33b..0000000000 --- a/platform/darwin/src/MGLMapCamera.h +++ /dev/null @@ -1,152 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreGraphics/CoreGraphics.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An `MGLMapCamera` object represents a viewpoint from which the user observes - some point on an `MGLMapView`. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/camera-animation/"> - Camera animation</a> example to learn how to create a camera that rotates - around a central point. See the <a href="https://docs.mapbox.com/ios/maps/examples/constraining-gestures/"> - Restrict map panning to an area</a> example to learn how to restrict map - panning using `MGLMapViewDelegate`'s -`-mapView:shouldChangeFromCamera:toCamera:` method. - */ -MGL_EXPORT -@interface MGLMapCamera : NSObject <NSSecureCoding, NSCopying> - -/** Coordinate at the center of the map view. */ -@property (nonatomic) CLLocationCoordinate2D centerCoordinate; - -/** Heading measured in degrees clockwise from true north. */ -@property (nonatomic) CLLocationDirection heading; - -/** - Pitch toward the horizon measured in degrees, with 0 degrees resulting in a - two-dimensional map. - */ -@property (nonatomic) CGFloat pitch; - -/** - The altitude (measured in meters) above the map at which the camera is - situated. - - The altitude is the distance from the viewpoint to the map, perpendicular to - the map plane. This property does not account for physical elevation. - - This property’s value may be less than that of the `viewingDistance` property. - Setting this property automatically updates the `viewingDistance` property - based on the `pitch` property’s current value. - */ -@property (nonatomic) CLLocationDistance altitude; - -/** - The straight-line distance from the viewpoint to the `centerCoordinate`. - - Setting this property automatically updates the `altitude` property based on - the `pitch` property’s current value. - */ -@property (nonatomic) CLLocationDistance viewingDistance; - -/** Returns a new camera with all properties set to 0. */ -+ (instancetype)camera; - -/** - Returns a new camera based on information about the camera’s viewpoint - and focus point. - - @param centerCoordinate The geographic coordinate on which the map should be - centered. - @param eyeCoordinate The geometric coordinate at which the camera should be - situated. - @param eyeAltitude The altitude (measured in meters) above the map at which the - camera should be situated. The altitude may be less than the distance from - the camera’s viewpoint to the camera’s focus point. - */ -+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - fromEyeCoordinate:(CLLocationCoordinate2D)eyeCoordinate - eyeAltitude:(CLLocationDistance)eyeAltitude; - -/** - Returns a new camera with the given distance, pitch, and heading. - - This method interprets the distance as a straight-line distance from the - viewpoint to the center coordinate. To specify the altitude of the viewpoint, - use the `-cameraLookingAtCenterCoordinate:altitude:pitch:heading:` method. - - @param centerCoordinate The geographic coordinate on which the map should be - centered. - @param distance The straight-line distance from the viewpoint to the - `centerCoordinate`. - @param pitch The viewing angle of the camera, measured in degrees. A value of - `0` results in a camera pointed straight down at the map. Angles greater - than `0` result in a camera angled toward the horizon. - @param heading The camera’s heading, measured in degrees clockwise from true - north. A value of `0` means that the top edge of the map view corresponds to - true north. The value `90` means the top of the map is pointing due east. - The value `180` means the top of the map points due south, and so on. - */ -+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - acrossDistance:(CLLocationDistance)distance - pitch:(CGFloat)pitch - heading:(CLLocationDirection)heading; - -/** - Returns a new camera with the given altitude, pitch, and heading. - - @param centerCoordinate The geographic coordinate on which the map should be - centered. - @param altitude The altitude (measured in meters) above the map at which the - camera should be situated. The altitude may be less than the distance from - the camera’s viewpoint to the camera’s focus point. - @param pitch The viewing angle of the camera, measured in degrees. A value of - `0` results in a camera pointed straight down at the map. Angles greater - than `0` result in a camera angled toward the horizon. - @param heading The camera’s heading, measured in degrees clockwise from true - north. A value of `0` means that the top edge of the map view corresponds to - true north. The value `90` means the top of the map is pointing due east. - The value `180` means the top of the map points due south, and so on. - */ -+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - altitude:(CLLocationDistance)altitude - pitch:(CGFloat)pitch - heading:(CLLocationDirection)heading; - -/** - @note This initializer incorrectly interprets the `distance` parameter. To - specify the straight-line distance from the viewpoint to `centerCoordinate`, - use the `-cameraLookingAtCenterCoordinate:acrossDistance:pitch:heading:` - method. To specify the altitude of the viewpoint, use the - `-cameraLookingAtCenterCoordinate:altitude:pitch:heading:` method, which has - the same behavior as this initializer. - */ -+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - fromDistance:(CLLocationDistance)distance - pitch:(CGFloat)pitch - heading:(CLLocationDirection)heading -__attribute__((deprecated("Use -cameraLookingAtCenterCoordinate:acrossDistance:pitch:heading: " - "or -cameraLookingAtCenterCoordinate:altitude:pitch:heading:."))); - -/** - Returns a Boolean value indicating whether the given camera is functionally - equivalent to the receiver. - - Unlike `-isEqual:`, this method returns `YES` if the difference between the - coordinates, altitudes, pitches, or headings of the two camera objects is - negligible. - - @param otherCamera The camera with which to compare the receiver. - @return A Boolean value indicating whether the two cameras are functionally - equivalent. - */ -- (BOOL)isEqualToMapCamera:(MGLMapCamera *)otherCamera; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLMapCamera.mm b/platform/darwin/src/MGLMapCamera.mm deleted file mode 100644 index 0f5dd558a8..0000000000 --- a/platform/darwin/src/MGLMapCamera.mm +++ /dev/null @@ -1,196 +0,0 @@ -#import "MGLMapCamera.h" -#import "MGLGeometry_Private.h" -#import "MGLLoggingConfiguration_Private.h" - -#import <CoreLocation/CoreLocation.h> - -#include <mbgl/math/wrap.hpp> - -BOOL MGLEqualFloatWithAccuracy(CGFloat left, CGFloat right, CGFloat accuracy) -{ - return MAX(left, right) - MIN(left, right) <= accuracy; -} - -@implementation MGLMapCamera - -+ (BOOL)supportsSecureCoding -{ - return YES; -} - -+ (instancetype)camera -{ - return [[self alloc] init]; -} - -+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - fromEyeCoordinate:(CLLocationCoordinate2D)eyeCoordinate - eyeAltitude:(CLLocationDistance)eyeAltitude -{ - CLLocationDirection heading = -1; - CGFloat pitch = -1; - if (CLLocationCoordinate2DIsValid(centerCoordinate) && CLLocationCoordinate2DIsValid(eyeCoordinate)) { - heading = MGLDirectionBetweenCoordinates(eyeCoordinate, centerCoordinate); - - CLLocation *centerLocation = [[CLLocation alloc] initWithLatitude:centerCoordinate.latitude - longitude:centerCoordinate.longitude]; - CLLocation *eyeLocation = [[CLLocation alloc] initWithLatitude:eyeCoordinate.latitude - longitude:eyeCoordinate.longitude]; - CLLocationDistance groundDistance = [eyeLocation distanceFromLocation:centerLocation]; - CGFloat radianPitch = atan2(eyeAltitude, groundDistance); - pitch = mbgl::util::wrap(90 - MGLDegreesFromRadians(radianPitch), 0.0, 360.0); - } - - return [[self alloc] initWithCenterCoordinate:centerCoordinate - altitude:eyeAltitude - pitch:pitch - heading:heading]; -} - -+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - acrossDistance:(CLLocationDistance)distance - pitch:(CGFloat)pitch - heading:(CLLocationDirection)heading -{ - // Angle at the viewpoint formed by the straight lines running perpendicular - // to the ground and toward the center coordinate. - CLLocationDirection eyeAngle = 90 - pitch; - CLLocationDistance altitude = distance * sin(MGLRadiansFromDegrees(eyeAngle)); - - return [[self alloc] initWithCenterCoordinate:centerCoordinate - altitude:altitude - pitch:pitch - heading:heading]; -} - -+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - altitude:(CLLocationDistance)altitude - pitch:(CGFloat)pitch - heading:(CLLocationDirection)heading -{ - return [[self alloc] initWithCenterCoordinate:centerCoordinate - altitude:altitude - pitch:pitch - heading:heading]; -} - -+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - fromDistance:(CLLocationDistance)distance - pitch:(CGFloat)pitch - heading:(CLLocationDirection)heading -{ - // TODO: Remove this compatibility shim in favor of `-cameraLookingAtCenterCoordinate:acrossDistance:pitch:heading:. - // https://github.com/mapbox/mapbox-gl-native/issues/12943 - return [MGLMapCamera cameraLookingAtCenterCoordinate:centerCoordinate - altitude:distance - pitch:pitch - heading:heading]; -} - -- (instancetype)initWithCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - altitude:(CLLocationDistance)altitude - pitch:(CGFloat)pitch - heading:(CLLocationDirection)heading -{ - MGLLogDebug(@"Initializing withCenterCoordinate: %@ altitude: %.0fm pitch: %f° heading: %f°", MGLStringFromCLLocationCoordinate2D(centerCoordinate), altitude, pitch, heading); - if (self = [super init]) - { - _centerCoordinate = centerCoordinate; - _altitude = altitude; - _pitch = pitch; - _heading = heading; - } - return self; -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder -{ - MGLLogInfo(@"Initialiazing with coder."); - if (self = [super init]) - { - _centerCoordinate = CLLocationCoordinate2DMake([coder decodeDoubleForKey:@"centerLatitude"], - [coder decodeDoubleForKey:@"centerLongitude"]); - _altitude = [coder decodeDoubleForKey:@"altitude"]; - _pitch = [coder decodeDoubleForKey:@"pitch"]; - _heading = [coder decodeDoubleForKey:@"heading"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - [coder encodeDouble:_centerCoordinate.latitude forKey:@"centerLatitude"]; - [coder encodeDouble:_centerCoordinate.longitude forKey:@"centerLongitude"]; - [coder encodeDouble:_altitude forKey:@"altitude"]; - [coder encodeDouble:_pitch forKey:@"pitch"]; - [coder encodeDouble:_heading forKey:@"heading"]; -} - -- (id)copyWithZone:(nullable NSZone *)zone -{ - return [[[self class] allocWithZone:zone] initWithCenterCoordinate:_centerCoordinate - altitude:_altitude - pitch:_pitch - heading:_heading]; -} - -+ (NSSet<NSString *> *)keyPathsForValuesAffectingViewingDistance { - return [NSSet setWithObjects:@"altitude", @"pitch", nil]; -} - -- (CLLocationDistance)viewingDistance { - CLLocationDirection eyeAngle = 90 - self.pitch; - return self.altitude / sin(MGLRadiansFromDegrees(eyeAngle)); -} - -- (void)setViewingDistance:(CLLocationDistance)distance { - MGLLogDebug(@"Setting viewingDistance: %f", distance); - CLLocationDirection eyeAngle = 90 - self.pitch; - self.altitude = distance * sin(MGLRadiansFromDegrees(eyeAngle)); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; centerCoordinate = %f, %f; altitude = %.0fm; heading = %.0f°; pitch = %.0f°>", - NSStringFromClass([self class]), (void *)self, _centerCoordinate.latitude, _centerCoordinate.longitude, _altitude, _heading, _pitch]; -} - -- (BOOL)isEqual:(id)other -{ - if ( ! [other isKindOfClass:[self class]]) - { - return NO; - } - if (other == self) - { - return YES; - } - - MGLMapCamera *otherCamera = other; - return (_centerCoordinate.latitude == otherCamera.centerCoordinate.latitude - && _centerCoordinate.longitude == otherCamera.centerCoordinate.longitude - && _altitude == otherCamera.altitude - && _pitch == otherCamera.pitch && _heading == otherCamera.heading); -} - -- (BOOL)isEqualToMapCamera:(MGLMapCamera *)otherCamera -{ - if (otherCamera == self) - { - return YES; - } - - return (MGLEqualFloatWithAccuracy(_centerCoordinate.latitude, otherCamera.centerCoordinate.latitude, 1e-6) - && MGLEqualFloatWithAccuracy(_centerCoordinate.longitude, otherCamera.centerCoordinate.longitude, 1e-6) - && MGLEqualFloatWithAccuracy(_altitude, otherCamera.altitude, 1e-6) - && MGLEqualFloatWithAccuracy(_pitch, otherCamera.pitch, 1) - && MGLEqualFloatWithAccuracy(_heading, otherCamera.heading, 1)); -} - -- (NSUInteger)hash -{ - return (@(_centerCoordinate.latitude).hash + @(_centerCoordinate.longitude).hash - + @(_altitude).hash + @(_pitch).hash + @(_heading).hash); -} - -@end diff --git a/platform/darwin/src/MGLMapSnapshotter.h b/platform/darwin/src/MGLMapSnapshotter.h deleted file mode 100644 index 98c8e8a375..0000000000 --- a/platform/darwin/src/MGLMapSnapshotter.h +++ /dev/null @@ -1,281 +0,0 @@ -#import <Foundation/Foundation.h> -#import "MGLTypes.h" -#import "MGLGeometry.h" -#import "MGLMapCamera.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An overlay that is placed within a `MGLMapSnapshot`. - To access this object, use `-[MGLMapSnapshotter startWithOverlayHandler:completionHandler:]`. - */ - -MGL_EXPORT -@interface MGLMapSnapshotOverlay : NSObject - -/** - The current `CGContext` that snapshot is drawing within. You may use this context - to perform additional custom drawing. - */ -@property (nonatomic, readonly) CGContextRef context; - -#if TARGET_OS_IPHONE -/** - Converts the specified map coordinate to a point in the coordinate space of the - context. - */ -- (CGPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate; - -/** - Converts the specified context point to a map coordinate. - */ -- (CLLocationCoordinate2D)coordinateForPoint:(CGPoint)point; - -#else -/** - Converts the specified map coordinate to a point in the coordinate space of the - context. - */ -- (NSPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate; - -/** - Converts the specified context point to a map coordinate. - */ -- (CLLocationCoordinate2D)coordinateForPoint:(NSPoint)point; -#endif - -@end - -/** -A block provided during the snapshot drawing process, enabling the ability to -draw custom overlays rendered with Core Graphics. - - @param snapshotOverlay The `MGLMapSnapshotOverlay` provided during snapshot drawing. - */ -typedef void (^MGLMapSnapshotOverlayHandler)(MGLMapSnapshotOverlay * snapshotOverlay); - -/** - The options to use when creating images with the `MGLMapSnapshotter`. - */ -MGL_EXPORT -@interface MGLMapSnapshotOptions : NSObject - -/** - Creates a set of options with the minimum required information. - - @param styleURL URL of the map style to snapshot. The URL may be a full HTTP or - HTTPS URL, a Mapbox style URL - (`mapbox://styles/{user}/{style}`), or a path to a local file relative to - the application’s resource path. Specify `nil` for the default style. - @param size The image size. - */ -- (instancetype)initWithStyleURL:(nullable NSURL *)styleURL camera:(MGLMapCamera *)camera size:(CGSize)size; - -#pragma mark - Configuring the Map - -/** - URL of the map style to snapshot. - */ -@property (nonatomic, readonly) NSURL *styleURL; - -/** - The zoom level. - - The default zoom level is 0. If this property is non-zero and the camera - property is non-nil, the camera’s altitude is ignored in favor of this - property’s value. - */ -@property (nonatomic) double zoomLevel; - -/** - A camera representing the viewport visible in the snapshot. - - If this property is non-nil and the `coordinateBounds` property is set to a - non-empty coordinate bounds, the camera’s center coordinate and altitude are - ignored in favor of the `coordinateBounds` property. - */ -@property (nonatomic) MGLMapCamera *camera; - -/** - The coordinate rectangle that encompasses the bounds to capture. - - If this property is non-empty and the camera property is non-nil, the camera’s - center coordinate and altitude are ignored in favor of this property’s value. - */ -@property (nonatomic) MGLCoordinateBounds coordinateBounds; - -#pragma mark - Configuring the Image - -/** - The size of the output image, measured in points. - - */ -@property (nonatomic, readonly) CGSize size; - -/** - The scale of the output image. Defaults to the main screen scale. - - The minimum scale is 1. - */ -@property (nonatomic) CGFloat scale; - -@end - -/** - An image generated by a snapshotter object. - */ -MGL_EXPORT -@interface MGLMapSnapshot : NSObject - -#if TARGET_OS_IPHONE -/** - Converts the specified map coordinate to a point in the coordinate space of the - image. - */ -- (CGPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate; - -/** - Converts the specified image point to a map coordinate. - */ -- (CLLocationCoordinate2D)coordinateForPoint:(CGPoint)point; - -/** - The image of the map’s content. - */ -@property (nonatomic, readonly) UIImage *image; -#else -/** - Converts the specified map coordinate to a point in the coordinate space of the - image. - */ -- (NSPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate; - -/** - Converts the specified image point to a map coordinate. - */ -- (CLLocationCoordinate2D)coordinateForPoint:(NSPoint)point; - - -/** - The image of the map’s content. - */ -@property (nonatomic, readonly) NSImage *image; -#endif - -@end - -/** - A block to processes the result or error of a snapshot request. - - @param snapshot The `MGLMapSnapshot` that was generated or `nil` if an error - occurred. - @param error The error that occured or `nil` when successful. - */ -typedef void (^MGLMapSnapshotCompletionHandler)(MGLMapSnapshot* _Nullable snapshot, NSError* _Nullable error); - -/** - An `MGLMapSnapshotter` generates static raster images of the map. Each snapshot - image depicts a portion of a map defined by an `MGLMapSnapshotOptions` object - you provide. The snapshotter generates an `MGLMapSnapshot` object - asynchronously, passing it into a completion handler once tiles and other - resources needed for the snapshot are finished loading. - - You can change the snapshotter’s options at any time and reuse the snapshotter - for multiple distinct snapshots; however, the snapshotter can only generate one - snapshot at a time. If you need to generate multiple snapshots concurrently, - create multiple snapshotter objects. - - For an interactive map, use the `MGLMapView` class. Both `MGLMapSnapshotter` - and `MGLMapView` are compatible with offline packs managed by the - `MGLOfflineStorage` class. - - From a snapshot, you can obtain an image and convert geographic coordinates to - the image’s coordinate space in order to superimpose markers and overlays. If - you do not need offline map functionality, you can use the `Snapshot` class in - [MapboxStatic.swift](https://github.com/mapbox/MapboxStatic.swift/) to generate - static map images with overlays. - - ### Example - - ```swift - let camera = MGLMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.7184, longitude: -122.4365), altitude: 100, pitch: 20, heading: 0) - - let options = MGLMapSnapshotOptions(styleURL: MGLStyle.satelliteStreetsStyleURL, camera: camera, size: CGSize(width: 320, height: 480)) - options.zoomLevel = 10 - - let snapshotter = MGLMapSnapshotter(options: options) - snapshotter.start { (snapshot, error) in - if let error = error { - fatalError(error.localizedDescription) - } - - image = snapshot?.image - } - ``` - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/map-snapshotter/"> - Create a static map snapshot</a> example to learn how to use the - `MGLMapSnapshotter` to generate a static image based on an `MGLMapView` - object's style, camera, and view bounds. - */ -MGL_EXPORT -@interface MGLMapSnapshotter : NSObject - -- (instancetype)init NS_UNAVAILABLE; - -/** - Initializes and returns a map snapshotter object that produces snapshots - according to the given options. - - @param options The options to use when generating a map snapshot. - @return An initialized map snapshotter. - */ -- (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options NS_DESIGNATED_INITIALIZER; - -/** - Starts the snapshot creation and executes the specified block with the result. - - @param completionHandler The block to handle the result in. - */ -- (void)startWithCompletionHandler:(MGLMapSnapshotCompletionHandler)completionHandler; - -/** - Starts the snapshot creation and executes the specified block with the result - on the specified queue. - - @param queue The queue to handle the result on. - @param completionHandler The block to handle the result in. - */ -- (void)startWithQueue:(dispatch_queue_t)queue completionHandler:(MGLMapSnapshotCompletionHandler)completionHandler; - -/** - Starts the snapshot creation and executes the specified blocks with the result - on the specified queue. Use this option if you want to add custom drawing on top of the - resulting `MGLMapSnapShot`. - @param overlayHandler The block to handle manipulation of the `MGLMapSnapshotter`'s `CGContext`. - @param completionHandler The block to handle the result in. - */ -- (void)startWithOverlayHandler:(MGLMapSnapshotOverlayHandler)overlayHandler completionHandler:(MGLMapSnapshotCompletionHandler)completionHandler; - -/** - Cancels the snapshot creation request, if any. - - Once you call this method, you cannot resume the snapshot. In order to obtain - the snapshot, create a new `MGLMapSnapshotter` object. - */ -- (void)cancel; - -/** - The options to use when generating a map snapshot. - */ -@property (nonatomic) MGLMapSnapshotOptions *options; - -/** - Indicates whether a snapshot is currently being generated. - */ -@property (nonatomic, readonly, getter=isLoading) BOOL loading; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm deleted file mode 100644 index f3e9e7a41e..0000000000 --- a/platform/darwin/src/MGLMapSnapshotter.mm +++ /dev/null @@ -1,752 +0,0 @@ -#import "MGLMapSnapshotter.h" - -#import <mbgl/actor/actor.hpp> -#import <mbgl/actor/scheduler.hpp> -#import <mbgl/util/geo.hpp> -#import <mbgl/map/map_options.hpp> -#import <mbgl/map/map_snapshotter.hpp> -#import <mbgl/map/camera.hpp> -#import <mbgl/storage/resource_options.hpp> -#import <mbgl/util/string.hpp> - -#import "MGLOfflineStorage_Private.h" -#import "MGLGeometry_Private.h" -#import "NSBundle+MGLAdditions.h" -#import "MGLStyle.h" -#import "MGLAttributionInfo_Private.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLRendererConfiguration.h" -#import "MGLMapSnapshotter_Private.h" - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MGLMapboxEvents.h" -#endif - -#if TARGET_OS_IPHONE -#import "UIImage+MGLAdditions.h" -#else -#import "NSImage+MGLAdditions.h" -#import <CoreGraphics/CoreGraphics.h> -#import <QuartzCore/QuartzCore.h> -#endif - -const CGPoint MGLLogoImagePosition = CGPointMake(8, 8); -const CGFloat MGLSnapshotterMinimumPixelSize = 64; - - -@interface MGLMapSnapshotOverlay() <MGLMapSnapshotProtocol> -@property (nonatomic, assign) CGFloat scale; -- (instancetype)initWithContext:(CGContextRef)context scale:(CGFloat)scale pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn latLngForFn:(mbgl::MapSnapshotter::LatLngForFn)latLngForFn; - -@end - -@implementation MGLMapSnapshotOverlay { - mbgl::MapSnapshotter::PointForFn _pointForFn; - mbgl::MapSnapshotter::LatLngForFn _latLngForFn; -} - -- (instancetype) initWithContext:(CGContextRef)context scale:(CGFloat)scale pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn latLngForFn:(mbgl::MapSnapshotter::LatLngForFn)latLngForFn { - self = [super init]; - if (self) { - _context = context; - _scale = scale; - _pointForFn = pointForFn; - _latLngForFn = latLngForFn; - } - - return self; -} - -#if TARGET_OS_IPHONE - -- (CGPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate -{ - mbgl::ScreenCoordinate sc = _pointForFn(MGLLatLngFromLocationCoordinate2D(coordinate)); - return CGPointMake(sc.x, sc.y); -} - -- (CLLocationCoordinate2D)coordinateForPoint:(CGPoint)point -{ - mbgl::LatLng latLng = _latLngForFn(mbgl::ScreenCoordinate(point.x, point.y)); - return MGLLocationCoordinate2DFromLatLng(latLng); -} - -#else - -- (NSPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate -{ - mbgl::ScreenCoordinate sc = _pointForFn(MGLLatLngFromLocationCoordinate2D(coordinate)); - CGFloat height = ((CGFloat)CGBitmapContextGetHeight(self.context))/self.scale; - return NSMakePoint(sc.x, height - sc.y); -} - -- (CLLocationCoordinate2D)coordinateForPoint:(NSPoint)point -{ - CGFloat height = ((CGFloat)CGBitmapContextGetHeight(self.context))/self.scale; - auto screenCoord = mbgl::ScreenCoordinate(point.x, height - point.y); - mbgl::LatLng latLng = _latLngForFn(screenCoord); - return MGLLocationCoordinate2DFromLatLng(latLng); -} - -#endif -@end - -@implementation MGLMapSnapshotOptions - -- (instancetype _Nonnull)initWithStyleURL:(nullable NSURL *)styleURL camera:(MGLMapCamera *)camera size:(CGSize)size -{ - MGLLogDebug(@"Initializing withStyleURL: %@ camera: %@ size: %@", styleURL, camera, MGLStringFromSize(size)); - self = [super init]; - if (self) - { - if ( !styleURL) - { - styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion]; - } - _styleURL = styleURL; - _size = size; - _camera = camera; -#if TARGET_OS_IPHONE - _scale = [UIScreen mainScreen].scale; -#else - _scale = [NSScreen mainScreen].backingScaleFactor; -#endif - } - return self; -} - -@end - -@interface MGLMapSnapshot() <MGLMapSnapshotProtocol> -- (instancetype)initWithImage:(nullable MGLImage *)image scale:(CGFloat)scale pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn latLngForFn:(mbgl::MapSnapshotter::LatLngForFn)latLngForFn; - -@property (nonatomic) CGFloat scale; -@end - -@implementation MGLMapSnapshot { - mbgl::MapSnapshotter::PointForFn _pointForFn; - mbgl::MapSnapshotter::LatLngForFn _latLngForFn; -} - -- (instancetype)initWithImage:(nullable MGLImage *)image scale:(CGFloat)scale pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn latLngForFn:(mbgl::MapSnapshotter::LatLngForFn)latLngForFn -{ - self = [super init]; - if (self) { - _pointForFn = pointForFn; - _latLngForFn = latLngForFn; - _scale = scale; - _image = image; - } - return self; -} - -#if TARGET_OS_IPHONE - -- (CGPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate -{ - mbgl::ScreenCoordinate sc = _pointForFn(MGLLatLngFromLocationCoordinate2D(coordinate)); - return CGPointMake(sc.x, sc.y); -} - -- (CLLocationCoordinate2D)coordinateForPoint:(CGPoint)point -{ - mbgl::LatLng latLng = _latLngForFn(mbgl::ScreenCoordinate(point.x, point.y)); - return MGLLocationCoordinate2DFromLatLng(latLng); -} - -#else - -- (NSPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate -{ - mbgl::ScreenCoordinate sc = _pointForFn(MGLLatLngFromLocationCoordinate2D(coordinate)); - return NSMakePoint(sc.x, self.image.size.height - sc.y); -} - -- (CLLocationCoordinate2D)coordinateForPoint:(NSPoint)point -{ - auto screenCoord = mbgl::ScreenCoordinate(point.x, self.image.size.height - point.y); - mbgl::LatLng latLng = _latLngForFn(screenCoord); - return MGLLocationCoordinate2DFromLatLng(latLng); -} - -#endif - -@end - -@interface MGLMapSnapshotter() -@property (nonatomic) BOOL cancelled; -@property (nonatomic) BOOL terminated; -@property (nonatomic) dispatch_queue_t resultQueue; -@property (nonatomic, copy) MGLMapSnapshotCompletionHandler completion; -+ (void)completeWithErrorCode:(MGLErrorCode)errorCode description:(nonnull NSString*)description onQueue:(dispatch_queue_t)queue completion:(MGLMapSnapshotCompletionHandler)completion; -@end - -@implementation MGLMapSnapshotter { - std::unique_ptr<mbgl::MapSnapshotter> _mbglMapSnapshotter; - std::unique_ptr<mbgl::Actor<mbgl::MapSnapshotter::Callback>> _snapshotCallback; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - - if (_completion) { - MGLAssert(_snapshotCallback, @"Snapshot in progress - there should be a valid callback"); - - [MGLMapSnapshotter completeWithErrorCode:MGLErrorCodeSnapshotFailed - description:@"MGLMapSnapshotter deallocated prior to snapshot completion." - onQueue:_resultQueue - completion:_completion]; - } -} - - -- (instancetype)init { - NSAssert(NO, @"Please use -[MGLMapSnapshotter initWithOptions:]"); - [super doesNotRecognizeSelector:_cmd]; - return nil; -} - -- (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options -{ - MGLLogDebug(@"Initializing withOptions: %@", options); - self = [super init]; - if (self) { - [self setOptions:options]; -#if TARGET_OS_IPHONE - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil]; -#else - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:NSApplicationWillTerminateNotification object:nil]; -#endif -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [MGLMapboxEvents pushTurnstileEvent]; -#endif - } - return self; -} - -- (void)applicationWillTerminate:(NSNotification *)notification -{ - if (self.completion) { - [self cancel]; - } - - _mbglMapSnapshotter.reset(); - _snapshotCallback.reset(); - - self.terminated = YES; -} - -- (void)startWithCompletionHandler:(MGLMapSnapshotCompletionHandler)completion -{ - MGLLogDebug(@"Starting withCompletionHandler: %@", completion); - [self startWithQueue:dispatch_get_main_queue() completionHandler:completion]; -} - -- (void)startWithQueue:(dispatch_queue_t)queue completionHandler:(MGLMapSnapshotCompletionHandler)completionHandler { - [self startWithQueue:queue overlayHandler:nil completionHandler:completionHandler]; -} - -- (void)startWithOverlayHandler:(MGLMapSnapshotOverlayHandler)overlayHandler completionHandler:(MGLMapSnapshotCompletionHandler)completion { - [self startWithQueue:dispatch_get_main_queue() overlayHandler:overlayHandler completionHandler:completion]; -} - -- (void)startWithQueue:(dispatch_queue_t)queue overlayHandler:(MGLMapSnapshotOverlayHandler)overlayHandler completionHandler:(MGLMapSnapshotCompletionHandler)completion -{ - if (!mbgl::Scheduler::GetCurrent()) { - [NSException raise:NSInvalidArgumentException - format:@"startWithQueue:completionHandler: must be called from a thread with an active run loop."]; - } - - if (self.completion) { - // Consider replacing this exception with an error passed to the completion block. - [NSException raise:NSInternalInconsistencyException - format:@"Already started this snapshotter."]; - } - - if (self.terminated) { - [NSException raise:NSInternalInconsistencyException - format:@"Starting a snapshotter after application termination is not supported."]; - } - - self.completion = completion; - self.resultQueue = queue; - self.cancelled = NO; - - __weak __typeof__(self) weakSelf = self; - // mbgl::Scheduler::GetCurrent() scheduler means "run callback on current (ie UI/main) thread" - // capture weakSelf to avoid retain cycle if callback is never called (ie snapshot cancelled) - - _snapshotCallback = std::make_unique<mbgl::Actor<mbgl::MapSnapshotter::Callback>>( - *mbgl::Scheduler::GetCurrent(), - [=](std::exception_ptr mbglError, mbgl::PremultipliedImage image, mbgl::MapSnapshotter::Attributions attributions, mbgl::MapSnapshotter::PointForFn pointForFn, mbgl::MapSnapshotter::LatLngForFn latLngForFn) { - - __typeof__(self) strongSelf = weakSelf; - // If self had died, _snapshotCallback would have been destroyed and this block would not be executed - MGLCAssert(strongSelf, @"Snapshot callback executed after being destroyed."); - - if (!strongSelf.completion) - return; - - if (mbglError) { - NSString *description = @(mbgl::util::toString(mbglError).c_str()); - NSDictionary *userInfo = @{NSLocalizedDescriptionKey: description}; - NSError *error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeSnapshotFailed userInfo:userInfo]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - // Dispatch to result queue - dispatch_async(queue, ^{ - strongSelf.completion(nil, error); - strongSelf.completion = nil; - }); - - } else { -#if TARGET_OS_IPHONE - MGLImage *mglImage = [[MGLImage alloc] initWithMGLPremultipliedImage:std::move(image) scale:strongSelf.options.scale]; -#else - MGLImage *mglImage = [[MGLImage alloc] initWithMGLPremultipliedImage:std::move(image)]; - mglImage.size = NSMakeSize(mglImage.size.width / strongSelf.options.scale, - mglImage.size.height / strongSelf.options.scale); -#endif - - [strongSelf drawAttributedSnapshot:attributions snapshotImage:mglImage pointForFn:pointForFn latLngForFn:latLngForFn overlayHandler:overlayHandler]; - } - strongSelf->_snapshotCallback = NULL; - - }); - - // Launches snapshot on background Thread owned by mbglMapSnapshotter - // _snapshotCallback->self() is an ActorRef: if the callback is destroyed, further messages - // to the callback are just no-ops - _mbglMapSnapshotter->snapshot(_snapshotCallback->self()); -} - -+ (MGLImage*)drawAttributedSnapshotWorker:(mbgl::MapSnapshotter::Attributions)attributions snapshotImage:(MGLImage *)mglImage pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn latLngForFn:(mbgl::MapSnapshotter::LatLngForFn)latLngForFn scale:(CGFloat)scale size:(CGSize)size overlayHandler:(MGLMapSnapshotOverlayHandler)overlayHandler { - - NSArray<MGLAttributionInfo *>* attributionInfo = [MGLMapSnapshotter generateAttributionInfos:attributions]; - -#if TARGET_OS_IPHONE - MGLAttributionInfoStyle attributionInfoStyle = MGLAttributionInfoStyleLong; - for (NSUInteger styleValue = MGLAttributionInfoStyleLong; styleValue >= MGLAttributionInfoStyleShort; styleValue--) { - attributionInfoStyle = (MGLAttributionInfoStyle)styleValue; - CGSize attributionSize = [MGLMapSnapshotter attributionSizeWithLogoStyle:attributionInfoStyle sourceAttributionStyle:attributionInfoStyle attributionInfo:attributionInfo]; - if (attributionSize.width <= mglImage.size.width) { - break; - } - } - - UIImage *logoImage = [MGLMapSnapshotter logoImageWithStyle:attributionInfoStyle]; - CGSize attributionBackgroundSize = [MGLMapSnapshotter attributionTextSizeWithStyle:attributionInfoStyle attributionInfo:attributionInfo]; - - CGRect logoImageRect = CGRectMake(MGLLogoImagePosition.x, mglImage.size.height - (MGLLogoImagePosition.y + logoImage.size.height), logoImage.size.width, logoImage.size.height); - CGPoint attributionOrigin = CGPointMake(mglImage.size.width - 10 - attributionBackgroundSize.width, - logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2) + 1); - if (!logoImage) { - CGSize defaultLogoSize = [MGLMapSnapshotter mapboxLongStyleLogo].size; - logoImageRect = CGRectMake(0, mglImage.size.height - (MGLLogoImagePosition.y + defaultLogoSize.height), 0, defaultLogoSize.height); - attributionOrigin = CGPointMake(10, logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2) + 1); - } - - CGRect attributionBackgroundFrame = CGRectMake(attributionOrigin.x, - attributionOrigin.y, - attributionBackgroundSize.width, - attributionBackgroundSize.height); - CGPoint attributionTextPosition = CGPointMake(attributionBackgroundFrame.origin.x + 10, - attributionBackgroundFrame.origin.y - 1); - - CGRect cropRect = CGRectMake(attributionBackgroundFrame.origin.x * mglImage.scale, - attributionBackgroundFrame.origin.y * mglImage.scale, - attributionBackgroundSize.width * mglImage.scale, - attributionBackgroundSize.height * mglImage.scale); - - - UIGraphicsBeginImageContextWithOptions(mglImage.size, NO, scale); - - [mglImage drawInRect:CGRectMake(0, 0, mglImage.size.width, mglImage.size.height)]; - - CGContextRef currentContext = UIGraphicsGetCurrentContext(); - - if (currentContext && overlayHandler) { - MGLMapSnapshotOverlay *snapshotOverlay = [[MGLMapSnapshotOverlay alloc] initWithContext:currentContext - scale:scale - pointForFn:pointForFn - latLngForFn:latLngForFn]; - CGContextSaveGState(snapshotOverlay.context); - overlayHandler(snapshotOverlay); - CGContextRestoreGState(snapshotOverlay.context); - currentContext = UIGraphicsGetCurrentContext(); - } - - if (!currentContext && overlayHandler) { - // If the current context has been corrupted by the user, - // return nil so we can generate an error later. - return nil; - } - - [logoImage drawInRect:logoImageRect]; - - UIImage *currentImage = UIGraphicsGetImageFromCurrentImageContext(); - CGImageRef attributionImageRef = CGImageCreateWithImageInRect([currentImage CGImage], cropRect); - UIImage *attributionImage = [UIImage imageWithCGImage:attributionImageRef]; - CGImageRelease(attributionImageRef); - - CIImage *ciAttributionImage = [[CIImage alloc] initWithCGImage:attributionImage.CGImage]; - - UIImage *blurredAttributionBackground = [MGLMapSnapshotter blurredAttributionBackground:ciAttributionImage]; - - [blurredAttributionBackground drawInRect:attributionBackgroundFrame]; - - [MGLMapSnapshotter drawAttributionTextWithStyle:attributionInfoStyle origin:attributionTextPosition attributionInfo:attributionInfo]; - - UIImage *compositedImage = UIGraphicsGetImageFromCurrentImageContext(); - - UIGraphicsEndImageContext(); - - return compositedImage; - -#else - - NSSize targetSize = NSMakeSize(size.width, size.height); - NSRect targetFrame = NSMakeRect(0, 0, targetSize.width, targetSize.height); - - MGLAttributionInfoStyle attributionInfoStyle = MGLAttributionInfoStyleLong; - for (NSUInteger styleValue = MGLAttributionInfoStyleLong; styleValue >= MGLAttributionInfoStyleShort; styleValue--) { - attributionInfoStyle = (MGLAttributionInfoStyle)styleValue; - CGSize attributionSize = [MGLMapSnapshotter attributionSizeWithLogoStyle:attributionInfoStyle sourceAttributionStyle:attributionInfoStyle attributionInfo:attributionInfo]; - if (attributionSize.width <= mglImage.size.width) { - break; - } - } - - NSImage *logoImage = [MGLMapSnapshotter logoImageWithStyle:attributionInfoStyle]; - CGSize attributionBackgroundSize = [MGLMapSnapshotter attributionTextSizeWithStyle:attributionInfoStyle attributionInfo:attributionInfo]; - NSImage *sourceImage = mglImage; - - CGRect logoImageRect = CGRectMake(MGLLogoImagePosition.x, MGLLogoImagePosition.y, logoImage.size.width, logoImage.size.height); - CGPoint attributionOrigin = CGPointMake(targetFrame.size.width - 10 - attributionBackgroundSize.width, - MGLLogoImagePosition.y + 1); - if (!logoImage) { - CGSize defaultLogoSize = [MGLMapSnapshotter mapboxLongStyleLogo].size; - logoImageRect = CGRectMake(0, MGLLogoImagePosition.y, 0, defaultLogoSize.height); - attributionOrigin = CGPointMake(10, attributionOrigin.y); - } - - CGRect attributionBackgroundFrame = CGRectMake(attributionOrigin.x, - attributionOrigin.y, - attributionBackgroundSize.width, - attributionBackgroundSize.height); - CGPoint attributionTextPosition = CGPointMake(attributionBackgroundFrame.origin.x + 10, - logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2)); - - - NSImage *compositedImage = nil; - NSImageRep *sourceImageRep = [sourceImage bestRepresentationForRect:targetFrame - context:nil - hints:nil]; - compositedImage = [[NSImage alloc] initWithSize:targetSize]; - - [compositedImage lockFocus]; - - [sourceImageRep drawInRect: targetFrame]; - - NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; - if (currentContext && overlayHandler) { - MGLMapSnapshotOverlay *snapshotOverlay = [[MGLMapSnapshotOverlay alloc] initWithContext:currentContext.CGContext - scale:scale - pointForFn:pointForFn - latLngForFn:latLngForFn]; - [currentContext saveGraphicsState]; - overlayHandler(snapshotOverlay); - [currentContext restoreGraphicsState]; - currentContext = [NSGraphicsContext currentContext]; - } - - if (!currentContext && overlayHandler) { - // If the current context has been corrupted by the user, - // return nil so we can generate an error later. - return nil; - } - - if (logoImage) { - [logoImage drawInRect:logoImageRect]; - } - - NSBitmapImageRep *attributionBackground = [[NSBitmapImageRep alloc] initWithFocusedViewRect:attributionBackgroundFrame]; - - CIImage *attributionBackgroundImage = [[CIImage alloc] initWithCGImage:[attributionBackground CGImage]]; - - NSImage *blurredAttributionBackground = [MGLMapSnapshotter blurredAttributionBackground:attributionBackgroundImage]; - - [blurredAttributionBackground drawInRect:attributionBackgroundFrame]; - - [MGLMapSnapshotter drawAttributionTextWithStyle:attributionInfoStyle origin:attributionTextPosition attributionInfo:attributionInfo]; - - [compositedImage unlockFocus]; - - return compositedImage; -#endif -} - -- (void)drawAttributedSnapshot:(mbgl::MapSnapshotter::Attributions)attributions snapshotImage:(MGLImage *)mglImage pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn latLngForFn:(mbgl::MapSnapshotter::LatLngForFn)latLngForFn overlayHandler:(MGLMapSnapshotOverlayHandler)overlayHandler { - - // Process image watermark in a work queue - dispatch_queue_t workQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - dispatch_queue_t resultQueue = self.resultQueue; - - // Capture scale and size by value to avoid accessing self from another thread - CGFloat scale = self.options.scale; - CGSize size = self.options.size; - - // pointForFn is a copyable std::function that captures state by value: see MapSnapshotter::Impl::snapshot - __weak __typeof__(self) weakself = self; - - dispatch_async(workQueue, ^{ - // Call a class method to ensure we're not accidentally capturing self - MGLImage *compositedImage = [MGLMapSnapshotter drawAttributedSnapshotWorker:attributions snapshotImage:mglImage pointForFn:pointForFn latLngForFn:latLngForFn scale:scale size:size overlayHandler:overlayHandler]; - - // Dispatch result to origin queue - dispatch_async(resultQueue, ^{ - __typeof__(self) strongself = weakself; - - if (strongself.completion) { - - if (!compositedImage) { - NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Failed to generate composited snapshot."}; - NSError *error = [NSError errorWithDomain:MGLErrorDomain - code:MGLErrorCodeSnapshotFailed - userInfo:userInfo]; - - strongself.completion(nil, error); - strongself.completion = nil; - } else { - MGLMapSnapshot* snapshot = [[MGLMapSnapshot alloc] initWithImage:compositedImage - scale:scale - pointForFn:pointForFn - latLngForFn:latLngForFn]; - strongself.completion(snapshot, nil); - strongself.completion = nil; - } - } - }); - }); -} - -+ (NSArray<MGLAttributionInfo *>*) generateAttributionInfos:(mbgl::MapSnapshotter::Attributions)attributions { - NSMutableArray *infos = [NSMutableArray array]; - -#if TARGET_OS_IPHONE - CGFloat fontSize = [UIFont smallSystemFontSize]; - UIColor *attributeFontColor = [UIColor blackColor]; -#else - CGFloat fontSize = [NSFont systemFontSizeForControlSize:NSMiniControlSize]; - NSColor *attributeFontColor = [NSColor blackColor]; -#endif - for (auto attribution = attributions.begin(); attribution != attributions.end(); ++attribution) { - NSString *attributionHTMLString = @(attribution->c_str()); - NSArray *tileSetInfos = [MGLAttributionInfo attributionInfosFromHTMLString:attributionHTMLString - fontSize:fontSize - linkColor:attributeFontColor]; - [infos growArrayByAddingAttributionInfosFromArray:tileSetInfos]; - } - return infos; -} - -+ (void)drawAttributionTextWithStyle:(MGLAttributionInfoStyle)attributionInfoStyle origin:(CGPoint)origin attributionInfo:(NSArray<MGLAttributionInfo *>*)attributionInfo -{ - for (MGLAttributionInfo *info in attributionInfo) { - if (info.isFeedbackLink) { - continue; - } - NSAttributedString *attribution = [info titleWithStyle:attributionInfoStyle]; - [attribution drawAtPoint:origin]; - - origin.x += [attribution size].width + 10; - } -} - -+ (MGLImage *)blurredAttributionBackground:(CIImage *)backgroundImage -{ - CGAffineTransform transform = CGAffineTransformIdentity; - CIFilter *clamp = [CIFilter filterWithName:@"CIAffineClamp"]; - [clamp setValue:backgroundImage forKey:kCIInputImageKey]; - [clamp setValue:[NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)] forKey:@"inputTransform"]; - - CIFilter *attributionBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"]; - [attributionBlurFilter setValue:[clamp outputImage] forKey:kCIInputImageKey]; - [attributionBlurFilter setValue:@10 forKey:kCIInputRadiusKey]; - - CIFilter *attributionColorFilter = [CIFilter filterWithName:@"CIColorControls"]; - [attributionColorFilter setValue:[attributionBlurFilter outputImage] forKey:kCIInputImageKey]; - [attributionColorFilter setValue:@(0.1) forKey:kCIInputBrightnessKey]; - - CIImage *blurredImage = attributionColorFilter.outputImage; - - CIContext *ctx = [CIContext contextWithOptions:nil]; - CGImageRef cgimg = [ctx createCGImage:blurredImage fromRect:[backgroundImage extent]]; - MGLImage *image; - -#if TARGET_OS_IPHONE - image = [UIImage imageWithCGImage:cgimg]; -#else - image = [[NSImage alloc] initWithCGImage:cgimg size:[backgroundImage extent].size]; -#endif - - CGImageRelease(cgimg); - return image; -} - -+ (MGLImage *)logoImageWithStyle:(MGLAttributionInfoStyle)style -{ - MGLImage *logoImage; - switch (style) { - case MGLAttributionInfoStyleLong: - logoImage = [MGLMapSnapshotter mapboxLongStyleLogo]; - break; - case MGLAttributionInfoStyleMedium: -#if TARGET_OS_IPHONE - logoImage = [UIImage imageNamed:@"mapbox_helmet" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil]; -#else - logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox_helmet" ofType:@"pdf"]]; -#endif - break; - case MGLAttributionInfoStyleShort: - logoImage = nil; - break; - } - return logoImage; -} - -+ (MGLImage *)mapboxLongStyleLogo -{ - MGLImage *logoImage; -#if TARGET_OS_IPHONE - logoImage =[UIImage imageNamed:@"mapbox" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil]; -#else - logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox" ofType:@"pdf"]]; -#endif - return logoImage; -} - -+ (CGSize)attributionSizeWithLogoStyle:(MGLAttributionInfoStyle)logoStyle sourceAttributionStyle:(MGLAttributionInfoStyle)attributionStyle attributionInfo:(NSArray<MGLAttributionInfo *>*)attributionInfo -{ - MGLImage *logoImage = [self logoImageWithStyle:logoStyle]; - - CGSize attributionBackgroundSize = [MGLMapSnapshotter attributionTextSizeWithStyle:attributionStyle attributionInfo:attributionInfo]; - - CGSize attributionSize = CGSizeZero; - - if (logoImage) { - attributionSize.width = MGLLogoImagePosition.x + logoImage.size.width + 10; - } - attributionSize.width = attributionSize.width + 10 + attributionBackgroundSize.width + 10; - attributionSize.height = MAX(logoImage.size.height, attributionBackgroundSize.height); - - return attributionSize; -} - -+ (CGSize)attributionTextSizeWithStyle:(MGLAttributionInfoStyle)attributionStyle attributionInfo:(NSArray<MGLAttributionInfo *>*)attributionInfo -{ - CGSize attributionBackgroundSize = CGSizeMake(10, 0); - for (MGLAttributionInfo *info in attributionInfo) { - if (info.isFeedbackLink) { - continue; - } - CGSize attributionSize = [info titleWithStyle:attributionStyle].size; - attributionBackgroundSize.width += attributionSize.width + 10; - attributionBackgroundSize.height = MAX(attributionSize.height, attributionBackgroundSize.height); - } - - return attributionBackgroundSize; -} - -- (void)cancel -{ - MGLLogInfo(@"Cancelling snapshotter."); - self.cancelled = YES; - - if (_snapshotCallback) { - [MGLMapSnapshotter completeWithErrorCode:MGLErrorCodeSnapshotFailed - description:[NSString stringWithFormat:@"MGLMapSnapshotter cancelled from %s", __PRETTY_FUNCTION__] - onQueue:self.resultQueue - completion:self.completion]; - self.completion = nil; - } - - _snapshotCallback.reset(); - _mbglMapSnapshotter.reset(); -} - -+ (void)completeWithErrorCode:(MGLErrorCode)errorCode description:(nonnull NSString*)description onQueue:(dispatch_queue_t)queue completion:(MGLMapSnapshotCompletionHandler)completion { - // The snapshot hasn't completed, so we should alert the caller - if (completion && queue) { - dispatch_async(queue, ^{ - NSDictionary *userInfo = @{NSLocalizedDescriptionKey: description}; - NSError *error = [NSError errorWithDomain:MGLErrorDomain - code:errorCode - userInfo:userInfo]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - completion(NULL, error); - }); - } -} - -- (void)setOptions:(MGLMapSnapshotOptions *)options -{ - if (_terminated) { - [NSException raise:NSInternalInconsistencyException - format:@"Calling MGLMapSnapshotter.options after application termination is not supported."]; - } - - MGLLogDebug(@"Setting options: %@", options); - - if (_completion) { - [self cancel]; - } - - _cancelled = NO; - _options = options; - - auto mbglFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglFileSource]; - - std::string styleURL = std::string([options.styleURL.absoluteString UTF8String]); - std::pair<bool, std::string> style = std::make_pair(false, styleURL); - - // Size; taking into account the minimum texture size for OpenGL ES - // For non retina screens the ratio is 1:1 MGLSnapshotterMinimumPixelSize - mbgl::Size size = { - static_cast<uint32_t>(MAX(options.size.width, MGLSnapshotterMinimumPixelSize)), - static_cast<uint32_t>(MAX(options.size.height, MGLSnapshotterMinimumPixelSize)) - }; - - float pixelRatio = MAX(options.scale, 1); - - // Camera options - mbgl::CameraOptions cameraOptions; - if (CLLocationCoordinate2DIsValid(options.camera.centerCoordinate)) { - cameraOptions.center = MGLLatLngFromLocationCoordinate2D(options.camera.centerCoordinate); - } - cameraOptions.bearing = MAX(0, options.camera.heading); - cameraOptions.zoom = MAX(0, options.zoomLevel); - cameraOptions.pitch = MAX(0, options.camera.pitch); - - // Region - mbgl::optional<mbgl::LatLngBounds> coordinateBounds; - if (!MGLCoordinateBoundsIsEmpty(options.coordinateBounds)) { - coordinateBounds = MGLLatLngBoundsFromCoordinateBounds(options.coordinateBounds); - } - - // App-global configuration - MGLRendererConfiguration* config = [MGLRendererConfiguration currentConfiguration]; - - mbgl::ResourceOptions resourceOptions; - resourceOptions.withCachePath([[MGLOfflineStorage sharedOfflineStorage] mbglCachePath]) - .withAssetPath([NSBundle mainBundle].resourceURL.path.UTF8String); - - // Create the snapshotter - _mbglMapSnapshotter = std::make_unique<mbgl::MapSnapshotter>( - style, size, pixelRatio, cameraOptions, coordinateBounds, config.localFontFamilyName, resourceOptions); -} - -@end diff --git a/platform/darwin/src/MGLMapSnapshotter_Private.h b/platform/darwin/src/MGLMapSnapshotter_Private.h deleted file mode 100644 index 205e51a6de..0000000000 --- a/platform/darwin/src/MGLMapSnapshotter_Private.h +++ /dev/null @@ -1,14 +0,0 @@ -#import "MGLMapSnapshotter.h" - -@protocol MGLMapSnapshotProtocol <NSObject> - -#if TARGET_OS_IPHONE -- (CGPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate; -- (CLLocationCoordinate2D)coordinateForPoint:(CGPoint)point; - -#else -- (NSPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate; -- (CLLocationCoordinate2D)coordinateForPoint:(NSPoint)point; -#endif - -@end diff --git a/platform/darwin/src/MGLMultiPoint.h b/platform/darwin/src/MGLMultiPoint.h deleted file mode 100644 index ee9eb530a4..0000000000 --- a/platform/darwin/src/MGLMultiPoint.h +++ /dev/null @@ -1,167 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" -#import "MGLShape.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLMultiPoint` class is an abstract superclass used to define shapes - composed of multiple vertices. - - Create instances of `MGLPolyline` or `MGLPolygon` in order to use - properties of `MGLMultiPoint`. Do not create instances of `MGLMultiPoint` - directly and do not create your own subclasses of this class. You can use - the method and properties of this class to access information about the - vertices of the line or polygon. - - Do not confuse `MGLMultiPoint` with `MGLPointCollection`, which represents a - collection of related but disconnected points. - */ -MGL_EXPORT -@interface MGLMultiPoint : MGLShape - -/** - The array of vertices associated with the shape. - - This C array is a pointer to a structure inside the multipoint object, which - may have a lifetime shorter than the multipoint object and will certainly not - have a longer lifetime. Therefore, you should copy the C array if it needs to - be stored outside of the memory context in which you use this property. - */ -@property (nonatomic, readonly) CLLocationCoordinate2D *coordinates NS_RETURNS_INNER_POINTER; - -/** The number of vertices in the shape. */ -@property (nonatomic, readonly) NSUInteger pointCount; - -/** - Retrieves the vertices of part of the shape. - - @param coords On input, you must provide a C array of `CLLocationCoordinate2D` - structures large enough to hold the desired number of coordinates. On - output, this structure contains the requested coordinate data. - @param range The range of vertices you want. The `location` field indicates - the first vertex you are requesting, with `0` being the first vertex, `1` - being the second vertex, and so on. The `length` field indicates the number - of vertices you want. The array in `coords` must be large enough to - accommodate the number of requested coordinates. - */ -- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range; - -/** - Sets the shape’s vertices to the given C array of vertices. - - @param coords The array of coordinates defining the shape. The data in this - array is copied to the shape’s `coordinates` property. - @param count The number of coordinates from the `coords` array. - */ -- (void)setCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -/** - Inserts the given vertices into the shape. - - If the shape is currently visible on the map as an annotation, it is redrawn - immediately. If the shape is part of an `MGLShapeSource` object, you must - explicitly set the `MGLShapeSource.shape` property in order for any style - layers that use the source to be redrawn. - - @param coords The array of coordinates to insert into the shape. The data in - this array is copied to the shape’s `coordinates` property. - @param count The number of items in the `coords` array. - @param index The zero-based index at which the first coordinate in `coords` - will appear in the `coordinates` property. - */ -- (void)insertCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count atIndex:(NSUInteger)index; - -/** - Appends the given vertices to the shape. - - If the shape is currently visible on the map as an annotation, it is redrawn - immediately. If the shape is part of an `MGLShapeSource` object, you must - explicitly set the `MGLShapeSource.shape` property in order for any style - layers that use the source to be redrawn. - - @param coords The array of coordinates to add to the shape. The data in this - array is copied to the shape’s `coordinates` property. - @param count The number of items in the `coords` array. - */ -- (void)appendCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -/** - Replaces the vertices at the given range in the shape with the same number of - vertices from a given C array. - - If the shape is currently visible on the map as an annotation, it is redrawn - immediately. If the shape is part of an `MGLShapeSource` object, you must - explicitly set the `MGLShapeSource.shape` property in order for any style - layers that use the source to be redrawn. - - The number of coordinates in `coords` must be equal to the length of `range`. - If you want to insert or delete one or more vertices, use the - `-replaceCoordinatesInRange:withCoordinates:count:` method. - - If `range` extends beyond the shape’s `coordinates` property, an - `NSRangeException` is raised. If you want to append new vertices to the shape, - use the `-appendCoordinates:count:` method. - - @param range The range of vertices to replace. The `location` field indicates - the first vertex you are replacing, with `0` being the first vertex, `1` - being the second vertex, and so on. The `length` field indicates the number - of vertices to replace. - @param coords The array of coordinates defining part of the shape. The data in - this array is copied to the shape’s `coordinates` property. - */ -- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(const CLLocationCoordinate2D *)coords; - -/** - Replaces the vertices at the given range in the shape with the specified number - of vertices from a given C array. - - If the shape is currently visible on the map as an annotation, it is redrawn - immediately. If the shape is part of an `MGLShapeSource` object, you must - explicitly set the `MGLShapeSource.shape` property in order for any style - layers that use the source to be redrawn. - - If `count` is greater than the `length` field of `range`, some vertices will - effectively be inserted into the shape. On the other hand, if `count` is less - than the `length` field of `range`, some vertices will effectively be removed. - - If `range` extends beyond the shape’s `coordinates` property, an - `NSRangeException` is raised. If you want to append new vertices to the shape, - use the `-appendCoordinates:count:` method. - - @param range The range of vertices to replace. The `location` field indicates - the first vertex you are replacing, with `0` being the first vertex, `1` - being the second vertex, and so on. The `length` field indicates the number - of vertices to replace. - @param coords The array of coordinates defining part of the shape. The data in - this array is copied to the shape’s `coordinates` property. - @param count The number of coordinates from the `coords` array to insert in - place of the coordinates in `range`. The sum of `range`’s length and this - count must not exceed the number of items currently in the `coordinates` - property. - */ -- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -/** - Removes the vertices at the given range from the shape. - - If the shape is currently visible on the map as an annotation, it is redrawn - immediately. If the shape is part of an `MGLShapeSource` object, you must - explicitly set the `MGLShapeSource.shape` property in order for any style - layers that use the source to be redrawn. - - If `range` extends beyond the shape’s `coordinates` property, an - `NSRangeException` is raised. - - @param range The range of vertices to remove. The `location` field indicates - the first vertex you are removing, with `0` being the first vertex, `1` - being the second vertex, and so on. The `length` field indicates the number - of vertices to remove. - */ -- (void)removeCoordinatesInRange:(NSRange)range; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm deleted file mode 100644 index 19aacaea43..0000000000 --- a/platform/darwin/src/MGLMultiPoint.mm +++ /dev/null @@ -1,204 +0,0 @@ -#import "MGLMultiPoint_Private.h" -#import "MGLGeometry_Private.h" -#import "MGLShape_Private.h" -#import "NSCoder+MGLAdditions.h" -#import "MGLTypes.h" -#import "MGLLoggingConfiguration_Private.h" - -@implementation MGLMultiPoint -{ - mbgl::optional<mbgl::LatLngBounds> _bounds; - std::vector<CLLocationCoordinate2D> _coordinates; -} - -- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count -{ - MGLLogDebug(@"Initializing with %lu coordinates.", (unsigned long) count); - self = [super init]; - - if (self) - { - if (!count) { - [NSException raise:NSInvalidArgumentException - format:@"A multipoint must have at least one vertex."]; - } - _coordinates = { coords, coords + count }; - } - - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder -{ - MGLLogInfo(@"Initializing with coder."); - if (self = [super initWithCoder:decoder]) { - _coordinates = [decoder mgl_decodeLocationCoordinates2DForKey:@"coordinates"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - [super encodeWithCoder:coder]; - [coder mgl_encodeLocationCoordinates2D:_coordinates forKey:@"coordinates"]; -} - -- (BOOL)isEqual:(id)other -{ - if (self == other) return YES; - if (![other isKindOfClass:[MGLMultiPoint class]]) return NO; - - MGLMultiPoint *otherMultipoint = other; - return ([super isEqual:otherMultipoint] - && _coordinates == otherMultipoint->_coordinates); -} - -- (NSUInteger)hash -{ - NSUInteger hash = [super hash]; - for (auto coord : _coordinates) { - hash += @(coord.latitude+coord.longitude).hash; - } - return hash; -} - -- (CLLocationCoordinate2D)coordinate -{ - MGLAssert([self pointCount] > 0, @"A multipoint must have coordinates"); - return _coordinates.at(0); -} - -- (NSUInteger)pointCount -{ - return _coordinates.size(); -} - -+ (NSSet<NSString *> *)keyPathsForValuesAffectingPointCount -{ - return [NSSet setWithObjects:@"coordinates", nil]; -} - -- (CLLocationCoordinate2D *)coordinates -{ - return _coordinates.data(); -} - -- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range -{ - if (range.location + range.length > [self pointCount]) - { - [NSException raise:NSRangeException - format:@"Invalid coordinate range %@ extends beyond current coordinate count of %ld", - NSStringFromRange(range), (unsigned long)[self pointCount]]; - } - - std::copy(_coordinates.begin() + range.location, _coordinates.begin() + NSMaxRange(range), coords); -} - -- (void)setCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count { - MGLLogDebug(@"Setting: %lu coordinates.", (unsigned long)count); - if (!count) { - [NSException raise:NSInvalidArgumentException - format:@"A multipoint must have at least one vertex."]; - } - - [self willChangeValueForKey:@"coordinates"]; - _coordinates = { coords, coords + count }; - _bounds = {}; - [self didChangeValueForKey:@"coordinates"]; -} - -- (void)insertCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count atIndex:(NSUInteger)index { - MGLLogDebug(@"Inserting %lu coordinates at index %lu.", (unsigned long)count, (unsigned long)index); - if (!count) { - return; - } - - if (index > _coordinates.size()) { - [NSException raise:NSRangeException - format:@"Invalid index %lu for existing coordinate count %ld", - (unsigned long)index, (unsigned long)[self pointCount]]; - } - - [self willChangeValueForKey:@"coordinates"]; - _coordinates.insert(_coordinates.begin() + index, count, *coords); - _bounds = {}; - [self didChangeValueForKey:@"coordinates"]; -} - -- (void)appendCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count -{ - MGLLogDebug(@"Appending %lu coordinates.", (unsigned long)count); - [self insertCoordinates:coords count:count atIndex:_coordinates.size()]; -} - -- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(const CLLocationCoordinate2D *)coords -{ - MGLLogDebug(@"Replacing coordinates in range: %@", NSStringFromRange(range)); - [self replaceCoordinatesInRange:range withCoordinates:coords count:range.length]; -} - -- (void)replaceCoordinatesInRange:(NSRange)range withCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count { - MGLLogDebug(@"Replacing %lu coordinates in range %@.", (unsigned long)count, NSStringFromRange(range)); - if (!count && !range.length) { - return; - } - - if (NSMaxRange(range) > _coordinates.size()) { - [NSException raise:NSRangeException - format:@"Invalid range %@ for existing coordinate count %ld", - NSStringFromRange(range), (unsigned long)[self pointCount]]; - } - - [self willChangeValueForKey:@"coordinates"]; - std::copy(coords, coords + MIN(count, range.length), _coordinates.begin() + range.location); - if (count >= range.length) { - _coordinates.insert(_coordinates.begin() + NSMaxRange(range), coords, coords + count - range.length); - } else { - _coordinates.erase(_coordinates.begin() + range.location + count, _coordinates.begin() + NSMaxRange(range)); - } - _bounds = {}; - [self didChangeValueForKey:@"coordinates"]; -} - -- (void)removeCoordinatesInRange:(NSRange)range { - MGLLogDebug(@"Removing coordinatesInRange: %@", NSStringFromRange(range)); - CLLocationCoordinate2D coords; - [self replaceCoordinatesInRange:range withCoordinates:&coords count:0]; -} - -- (MGLCoordinateBounds)overlayBounds -{ - if (!_bounds) { - mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty(); - for (auto coordinate : _coordinates) { - if (!MGLLocationCoordinate2DIsValid(coordinate)) { - bounds = mbgl::LatLngBounds::empty(); - break; - } - bounds.extend(MGLLatLngFromLocationCoordinate2D(coordinate)); - } - _bounds = bounds; - } - return MGLCoordinateBoundsFromLatLngBounds(*_bounds); -} - -- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds -{ - return MGLCoordinateBoundsIntersectsCoordinateBounds(self.overlayBounds, overlayBounds); -} - -- (mbgl::Annotation)annotationObjectWithDelegate:(__unused id <MGLMultiPointDelegate>)delegate -{ - MGLAssert(NO, @"Cannot add an annotation from an instance of %@", NSStringFromClass([self class])); - return mbgl::SymbolAnnotation(mbgl::Point<double>()); -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>", - NSStringFromClass([self class]), (void *)self, (unsigned long)[self pointCount], - MGLStringFromCoordinateBounds(self.overlayBounds)]; -} - -@end diff --git a/platform/darwin/src/MGLMultiPoint_Private.h b/platform/darwin/src/MGLMultiPoint_Private.h deleted file mode 100644 index a9b4b72ca5..0000000000 --- a/platform/darwin/src/MGLMultiPoint_Private.h +++ /dev/null @@ -1,46 +0,0 @@ -#import "MGLMultiPoint.h" - -#import "MGLGeometry.h" - -#import <mbgl/annotation/annotation.hpp> -#import <mbgl/util/feature.hpp> -#import <vector> - -#import <CoreGraphics/CoreGraphics.h> -#import <CoreLocation/CoreLocation.h> - -NS_ASSUME_NONNULL_BEGIN - -@class MGLPolygon; -@class MGLPolyline; - -@protocol MGLMultiPointDelegate; - -@interface MGLMultiPoint (Private) - -- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count; -- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds; - -/** Constructs a shape annotation object, asking the delegate for style values. */ -- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate; - -@end - -/** An object that tells the MGLMultiPoint instance how to style itself. */ -@protocol MGLMultiPointDelegate <NSObject> - -/** Returns the fill alpha value for the given annotation. */ -- (double)alphaForShapeAnnotation:(MGLShape *)annotation; - -/** Returns the stroke color object for the given annotation. */ -- (mbgl::Color)strokeColorForShapeAnnotation:(MGLShape *)annotation; - -/** Returns the fill color object for the given annotation. */ -- (mbgl::Color)fillColorForPolygonAnnotation:(MGLPolygon *)annotation; - -/** Returns the stroke width object for the given annotation. */ -- (CGFloat)lineWidthForPolylineAnnotation:(MGLPolyline *)annotation; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLNetworkConfiguration.h b/platform/darwin/src/MGLNetworkConfiguration.h deleted file mode 100644 index 6c56050aae..0000000000 --- a/platform/darwin/src/MGLNetworkConfiguration.h +++ /dev/null @@ -1,37 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLNetworkConfiguration` object provides a global way to set a base - `NSURLSessionConfiguration`, and other resources. - */ -MGL_EXPORT -@interface MGLNetworkConfiguration : NSObject - -/** - Returns the shared instance of the `MGLNetworkConfiguration` class. - */ -@property (class, nonatomic, readonly) MGLNetworkConfiguration *sharedManager; - -/** - The session configuration object that is used by the `NSURLSession` objects - in this SDK. - - If this property is set to nil or if no session configuration is provided this property - is set to the default session configuration. - - Assign this object before instantiating any `MGLMapView` object. - - @note: `NSURLSession` objects store a copy of this configuration. Any further changes - to mutable properties on this configuration object passed to a session’s initializer - will not affect the behavior of that session. - - */ -@property (atomic, strong, null_resettable) NSURLSessionConfiguration *sessionConfiguration; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLNetworkConfiguration.m b/platform/darwin/src/MGLNetworkConfiguration.m deleted file mode 100644 index 0e5046e7a3..0000000000 --- a/platform/darwin/src/MGLNetworkConfiguration.m +++ /dev/null @@ -1,162 +0,0 @@ -#import "MGLNetworkConfiguration_Private.h" - -#include <mbgl/storage/reachability.h> - -static NSString * const MGLStartTime = @"start_time"; -static NSString * const MGLResourceType = @"resource_type"; -NSString * const kMGLDownloadPerformanceEvent = @"mobile.performance_trace"; - -@interface MGLNetworkConfiguration () - -@property (strong) NSURLSessionConfiguration *sessionConfig; -@property (nonatomic, strong) NSMutableDictionary<NSString *, NSDictionary*> *events; -@property (nonatomic, weak) id<MGLNetworkConfigurationMetricsDelegate> metricsDelegate; -@property (nonatomic) dispatch_queue_t eventsQueue; - -@end - -@implementation MGLNetworkConfiguration - -- (instancetype)init { - if (self = [super init]) { - self.sessionConfiguration = nil; - _events = [NSMutableDictionary dictionary]; - _eventsQueue = dispatch_queue_create("com.mapbox.network-configuration", DISPATCH_QUEUE_CONCURRENT); - } - - return self; -} - -+ (instancetype)sharedManager { - static dispatch_once_t onceToken; - static MGLNetworkConfiguration *_sharedManager; - dispatch_once(&onceToken, ^{ - _sharedManager = [[self alloc] init]; - }); - - return _sharedManager; -} - -- (void)setSessionConfiguration:(NSURLSessionConfiguration *)sessionConfiguration { - @synchronized (self) { - if (sessionConfiguration == nil) { - _sessionConfig = [self defaultSessionConfiguration]; - } else { - _sessionConfig = sessionConfiguration; - } - } -} - -- (NSURLSessionConfiguration *)sessionConfiguration { - NSURLSessionConfiguration *sessionConfig = nil; - @synchronized (self) { - sessionConfig = _sessionConfig; - } - return sessionConfig; -} - -- (NSURLSessionConfiguration *)defaultSessionConfiguration { - NSURLSessionConfiguration* sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; - - sessionConfiguration.timeoutIntervalForResource = 30; - sessionConfiguration.HTTPMaximumConnectionsPerHost = 8; - sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; - sessionConfiguration.URLCache = nil; - - return sessionConfiguration; -} - -- (void)startDownloadEvent:(NSString *)urlString type:(NSString *)resourceType { - if (urlString && ![self eventDictionaryForKey:urlString]) { - NSDate *startDate = [NSDate date]; - [self setEventDictionary:@{ MGLStartTime: startDate, MGLResourceType: resourceType } forKey:urlString]; - } -} - -- (void)stopDownloadEventForResponse:(NSURLResponse *)response { - [self sendEventForURLResponse:response withAction:nil]; -} - -- (void)cancelDownloadEventForResponse:(NSURLResponse *)response { - [self sendEventForURLResponse:response withAction:@"cancel"]; -} - -- (void)sendEventForURLResponse:(NSURLResponse *)response withAction:(NSString *)action -{ - if ([response isKindOfClass:[NSURLResponse class]]) { - NSString *urlString = response.URL.relativePath; - if (urlString && [self eventDictionaryForKey:urlString]) { - NSDictionary *eventAttributes = [self eventAttributesForURL:response withAction:action]; - [self removeEventDictionaryForKey:urlString]; - - dispatch_async(dispatch_get_main_queue(), ^{ - [self.metricsDelegate networkConfiguration:self didGenerateMetricEvent:eventAttributes]; - }); - } - } - -} - -- (NSDictionary *)eventAttributesForURL:(NSURLResponse *)response withAction:(NSString *)action -{ - NSString *urlString = response.URL.relativePath; - NSDictionary *parameters = [self eventDictionaryForKey:urlString]; - NSDate *startDate = [parameters objectForKey:MGLStartTime]; - NSDate *endDate = [NSDate date]; - NSTimeInterval elapsedTime = [endDate timeIntervalSinceDate:startDate]; - NSDateFormatter* iso8601Formatter = [[NSDateFormatter alloc] init]; - iso8601Formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ"; - NSString *createdDate = [iso8601Formatter stringFromDate:[NSDate date]]; - - NSMutableArray *attributes = [NSMutableArray array]; - [attributes addObject:@{ @"name" : @"requestUrl" , @"value" : urlString }]; - [attributes addObject:@{ @"name" : MGLResourceType , @"value" : [parameters objectForKey:MGLResourceType] }]; - - if ([response isKindOfClass:[NSHTTPURLResponse class]]) { - NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode]; - [attributes addObject:@{ @"name" : @"responseCode", @"value" : @(responseCode)}]; - } - - BOOL isWIFIOn = [[MGLReachability reachabilityWithHostName:response.URL.host] isReachableViaWiFi]; - [attributes addObject:@{ @"name" : @"wifiOn", @"value" : @(isWIFIOn)}]; - - if (action) { - [attributes addObject:@{ @"name" : @"action" , @"value" : action }]; - } - - double elapsedTimeInMS = elapsedTime * 1000.0; - - return @{ - @"event" : kMGLDownloadPerformanceEvent, - @"created" : createdDate, - @"sessionId" : [NSUUID UUID].UUIDString, - @"counters" : @[ @{ @"name" : @"elapsedMS" , @"value" : @(elapsedTimeInMS) } ], - @"attributes" : attributes - }; -} - -#pragma mark - Events dictionary access - -- (nullable NSDictionary*)eventDictionaryForKey:(nonnull NSString*)key { - __block NSDictionary *dictionary; - - dispatch_sync(self.eventsQueue, ^{ - dictionary = [self.events objectForKey:key]; - }); - - return dictionary; -} - -- (void)setEventDictionary:(nonnull NSDictionary*)dictionary forKey:(nonnull NSString*)key { - dispatch_barrier_async(self.eventsQueue, ^{ - [self.events setObject:dictionary forKey:key]; - }); -} - -- (void)removeEventDictionaryForKey:(nonnull NSString*)key { - dispatch_barrier_async(self.eventsQueue, ^{ - [self.events removeObjectForKey:key]; - }); -} - -@end diff --git a/platform/darwin/src/MGLNetworkConfiguration_Private.h b/platform/darwin/src/MGLNetworkConfiguration_Private.h deleted file mode 100644 index 06f5c7d1b5..0000000000 --- a/platform/darwin/src/MGLNetworkConfiguration_Private.h +++ /dev/null @@ -1,25 +0,0 @@ -#import "MGLNetworkConfiguration.h" - -NS_ASSUME_NONNULL_BEGIN - -@class MGLNetworkConfiguration; -@protocol MGLNetworkConfigurationMetricsDelegate <NSObject> - -- (void)networkConfiguration:(MGLNetworkConfiguration *)networkConfiguration didGenerateMetricEvent:(NSDictionary *)metricEvent; - -@end - -extern NSString * const kMGLDownloadPerformanceEvent; - -@interface MGLNetworkConfiguration (Private) - -@property (nonatomic, strong) NSMutableDictionary<NSString*, NSDictionary*> *events; -@property (nonatomic, weak) id<MGLNetworkConfigurationMetricsDelegate> metricsDelegate; - -- (void)startDownloadEvent:(NSString *)urlString type:(NSString *)resourceType; -- (void)stopDownloadEventForResponse:(NSURLResponse *)response; -- (void)cancelDownloadEventForResponse:(NSURLResponse *)response; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLNetworkIntegrationManager.h b/platform/darwin/src/MGLNetworkIntegrationManager.h deleted file mode 100644 index 2c929e16f8..0000000000 --- a/platform/darwin/src/MGLNetworkIntegrationManager.h +++ /dev/null @@ -1,8 +0,0 @@ -#import <Foundation/Foundation.h> -#include <mbgl/interface/native_apple_interface.h> - -@interface MGLNetworkIntegrationManager : NSObject <MGLNativeNetworkDelegate> - -+ (MGLNetworkIntegrationManager *)sharedManager; - -@end diff --git a/platform/darwin/src/MGLNetworkIntegrationManager.m b/platform/darwin/src/MGLNetworkIntegrationManager.m deleted file mode 100644 index 79c7f15156..0000000000 --- a/platform/darwin/src/MGLNetworkIntegrationManager.m +++ /dev/null @@ -1,54 +0,0 @@ -#import "MGLNetworkIntegrationManager.h" - -#import "MGLLoggingConfiguration_Private.h" -#import "MGLNetworkConfiguration_Private.h" - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MGLAccountManager_Private.h" -#endif - -@implementation MGLNetworkIntegrationManager - -static MGLNetworkIntegrationManager *instance = nil; - -+ (MGLNetworkIntegrationManager *)sharedManager { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - instance = [[MGLNetworkIntegrationManager alloc] init]; - }); - return instance; -} - -#pragma mark - MGLNativeAppleInterfaceManager delegate - - -- (NSURLSessionConfiguration *)sessionConfiguration { - return [MGLNetworkConfiguration sharedManager].sessionConfiguration; -} - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -- (NSString *)skuToken { - return MGLAccountManager.skuToken; -} -#endif - -- (void)startDownloadEvent:(NSString *)event type:(NSString *)type { - [[MGLNetworkConfiguration sharedManager] startDownloadEvent:event type:@"tile"]; -} - -- (void)cancelDownloadEventForResponse:(NSURLResponse *)response { - [[MGLNetworkConfiguration sharedManager] cancelDownloadEventForResponse:response]; -} - -- (void)stopDownloadEventForResponse:(NSURLResponse *)response { - [[MGLNetworkConfiguration sharedManager] stopDownloadEventForResponse:response]; -} - -- (void)debugLog:(NSString *)format, ... { - MGLLogDebug(format); -} - -- (void)errorLog:(NSString *)format, ... { - MGLLogError(format); -} - -@end diff --git a/platform/darwin/src/MGLOfflinePack.h b/platform/darwin/src/MGLOfflinePack.h deleted file mode 100644 index 3dcb5b7abe..0000000000 --- a/platform/darwin/src/MGLOfflinePack.h +++ /dev/null @@ -1,203 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLTypes.h" -#import "MGLOfflineRegion.h" - -NS_ASSUME_NONNULL_BEGIN - -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLInvalidOfflinePackException; - -/** - The state an offline pack is currently in. - */ -typedef NS_ENUM (NSInteger, MGLOfflinePackState) { - /** - It is unknown whether the pack is inactive, active, or complete. - - This is the initial state of a pack. The state of a pack becomes known by - the time the shared `MGLOfflineStorage` object sends the first - `MGLOfflinePackProgressChangedNotification` about the pack. For inactive - packs, you must explicitly request a progress update using the - `-[MGLOfflinePack requestProgress]` method. - - An invalid pack always has a state of `MGLOfflinePackStateInvalid`, never - `MGLOfflinePackStateUnknown`. - */ - MGLOfflinePackStateUnknown = 0, - /** - The pack is incomplete and is not currently downloading. - - This is the initial state of a pack that is created using the - `-[MGLOfflineStorage addPackForRegion:withContext:completionHandler:]` - method, as well as after the `-[MGLOfflinePack suspend]` method is - called. - */ - MGLOfflinePackStateInactive = 1, - /** - The pack is incomplete and is currently downloading. - - This is the state of a pack after the `-[MGLOfflinePack resume]` method is - called. - */ - MGLOfflinePackStateActive = 2, - /** - The pack has downloaded to completion. - */ - MGLOfflinePackStateComplete = 3, - /** - The pack has been removed using the - `-[MGLOfflineStorage removePack:withCompletionHandler:]` method. Sending - any message to the pack will raise an exception. - */ - MGLOfflinePackStateInvalid = 4, -}; - -/** - A structure containing information about an offline pack’s current download - progress. - */ -typedef struct __attribute__((objc_boxable)) MGLOfflinePackProgress { - /** - The number of resources, including tiles, that have been completely - downloaded and are ready to use offline. - */ - uint64_t countOfResourcesCompleted; - /** - The cumulative size of the downloaded resources on disk, including tiles, - measured in bytes. - */ - uint64_t countOfBytesCompleted; - /** - The number of tiles that have been completely downloaded and are ready - to use offline. - */ - uint64_t countOfTilesCompleted; - /** - The cumulative size of the downloaded tiles on disk, measured in bytes. - */ - uint64_t countOfTileBytesCompleted; - /** - The minimum number of resources that must be downloaded in order to view - the pack’s full region without any omissions. - - At the beginning of a download, this count is a lower bound; the number of - expected resources may increase as the download progresses. - */ - uint64_t countOfResourcesExpected; - /** - The maximum number of resources that must be downloaded in order to view - the pack’s full region without any omissions. - - At the beginning of a download, when the exact number of required resources - is unknown, this field is set to `UINT64_MAX`. Thus this count is always an - upper bound. - */ - uint64_t maximumResourcesExpected; -} MGLOfflinePackProgress; - -/** - An `MGLOfflinePack` represents a collection of resources necessary for viewing - a region offline to a local database. - - To create an instance of `MGLOfflinePack`, use the - `+[MGLOfflineStorage addPackForRegion:withContext:completionHandler:]` method. - A pack created using `-[MGLOfflinePack init]` is immediately invalid. - - ### Example - ```swift - MGLOfflineStorage.shared.addPack(for: region, withContext: context) { (pack, error) in - guard let pack = pack else { - // If adding the pack fails, log an error to console. - print("Error:", error?.localizedDescription ?? "unknown error adding pack at \(#file)(\(#line)) in \(#function)") - return - } - - // Start an MGLOfflinePack download - pack.resume() - } - ``` - */ -MGL_EXPORT -@interface MGLOfflinePack : NSObject - -/** - The region for which the pack manages resources. - */ -@property (nonatomic, readonly) id <MGLOfflineRegion> region; - -/** - Arbitrary data stored alongside the downloaded resources. - - The context typically holds application-specific information for identifying - the pack, such as a user-selected name. - */ -@property (nonatomic, readonly) NSData *context; - -/** - The pack’s current state. - - The state of an inactive or completed pack is computed lazily and is set to - `MGLOfflinePackStateUnknown` by default. To request the pack’s status, use the - `-requestProgress` method. To get notified when the state becomes known and - when it changes, observe KVO change notifications on this pack’s `state` key - path. Alternatively, you can add an observer for - `MGLOfflinePackProgressChangedNotification`s about this pack that come from the - default notification center. - */ -@property (nonatomic, readonly) MGLOfflinePackState state; - -/** - The pack’s current progress. - - The progress of an inactive or completed pack is computed lazily, and all its - fields are set to 0 by default. To request the pack’s progress, use the - `-requestProgress` method. To get notified when the progress becomes - known and when it changes, observe KVO change notifications on this pack’s - `state` key path. Alternatively, you can add an observer for - `MGLOfflinePackProgressChangedNotification`s about this pack that come from the - default notification center. - */ -@property (nonatomic, readonly) MGLOfflinePackProgress progress; - -/** - Resumes downloading if the pack is inactive. - - When a pack resumes after being suspended, it may begin by iterating over the - already downloaded resources. As a result, the `progress` structure’s - `countOfResourcesCompleted` field may revert to 0 before rapidly returning to - the level of progress at the time the pack was suspended. - - To temporarily suspend downloading, call the `-suspend` method. - */ -- (void)resume; - -/** - Temporarily stops downloading if the pack is active. - - A pack suspends asynchronously, so some network requests may be sent after this - method is called. Regardless, the `progress` property will not be updated until - `-resume` is called. - - If the pack previously reached a higher level of progress before being - suspended, it may wait to suspend until it returns to that level. - - To resume downloading, call the `-resume` method. - */ -- (void)suspend; - -/** - Request an asynchronous update to the pack’s `state` and `progress` properties. - - The state and progress of an inactive or completed pack are computed lazily. If - you need the state or progress of a pack whose `state` property is currently - set to `MGLOfflinePackStateUnknown`, observe KVO change notifications on this - pack’s `state` key path, then call this method. Alternatively, you can add an - observer for `MGLOfflinePackProgressChangedNotification` about this pack that - come from the default notification center. - */ -- (void)requestProgress; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOfflinePack.mm b/platform/darwin/src/MGLOfflinePack.mm deleted file mode 100644 index edee549744..0000000000 --- a/platform/darwin/src/MGLOfflinePack.mm +++ /dev/null @@ -1,282 +0,0 @@ -#import "MGLOfflinePack_Private.h" - -#import "MGLOfflineStorage_Private.h" -#import "MGLOfflineRegion_Private.h" -#import "MGLTilePyramidOfflineRegion.h" -#import "MGLTilePyramidOfflineRegion_Private.h" -#import "MGLShapeOfflineRegion.h" -#import "MGLShapeOfflineRegion_Private.h" -#import "MGLLoggingConfiguration_Private.h" - -#import "NSValue+MGLAdditions.h" - -#include <mbgl/map/map_options.hpp> -#include <mbgl/storage/database_file_source.hpp> - -const MGLExceptionName MGLInvalidOfflinePackException = @"MGLInvalidOfflinePackException"; - -/** - Assert that the current offline pack is valid. - - This macro should be used at the beginning of any public-facing instance method - of `MGLOfflinePack`. For private methods, an assertion is more appropriate. - */ -#define MGLAssertOfflinePackIsValid() \ - do { \ - if (_state == MGLOfflinePackStateInvalid) { \ - [NSException raise:MGLInvalidOfflinePackException \ - format: \ - @"-[MGLOfflineStorage removePack:withCompletionHandler:] has been called " \ - @"on this instance of MGLOfflinePack, rendering it invalid. It is an " \ - @"error to send any message to this pack."]; \ - } \ - } while (NO); - -@interface MGLTilePyramidOfflineRegion () <MGLOfflineRegion_Private, MGLTilePyramidOfflineRegion_Private> -@end - -@interface MGLShapeOfflineRegion () <MGLOfflineRegion_Private, MGLShapeOfflineRegion_Private> -@end - -class MBGLOfflineRegionObserver : public mbgl::OfflineRegionObserver { -public: - MBGLOfflineRegionObserver(MGLOfflinePack *pack_) : pack(pack_) {} - - void statusChanged(mbgl::OfflineRegionStatus status) override; - void responseError(mbgl::Response::Error error) override; - void mapboxTileCountLimitExceeded(uint64_t limit) override; - -private: - __weak MGLOfflinePack *pack = nullptr; -}; - -@interface MGLOfflinePack () - -@property (nonatomic, nullable, readwrite) mbgl::OfflineRegion *mbglOfflineRegion; -@property (nonatomic, readwrite) MGLOfflinePackProgress progress; - -@end - -@implementation MGLOfflinePack { - BOOL _isSuspending; - std::shared_ptr<mbgl::DatabaseFileSource> _mbglDatabaseFileSource; -} - -- (instancetype)init { - MGLLogInfo(@"Calling this initializer is not allowed."); - if (self = [super init]) { - _state = MGLOfflinePackStateInvalid; - NSLog(@"%s called; did you mean to call +[MGLOfflineStorage addPackForRegion:withContext:completionHandler:] instead?", __PRETTY_FUNCTION__); - } - return self; -} - -- (instancetype)initWithMBGLRegion:(mbgl::OfflineRegion *)region { - if (self = [super init]) { - _mbglOfflineRegion = region; - _state = MGLOfflinePackStateUnknown; - - _mbglDatabaseFileSource = [[MGLOfflineStorage sharedOfflineStorage] mbglDatabaseFileSource]; - _mbglDatabaseFileSource->setOfflineRegionObserver(*_mbglOfflineRegion, std::make_unique<MBGLOfflineRegionObserver>(self)); - } - return self; -} - -- (void)dealloc { - MGLAssert(_state == MGLOfflinePackStateInvalid, @"MGLOfflinePack was not invalided prior to deallocation."); -} - -- (id <MGLOfflineRegion>)region { - MGLAssertOfflinePackIsValid(); - - const mbgl::OfflineRegionDefinition ®ionDefinition = _mbglOfflineRegion->getDefinition(); - MGLAssert([MGLTilePyramidOfflineRegion conformsToProtocol:@protocol(MGLOfflineRegion_Private)], @"MGLTilePyramidOfflineRegion should conform to MGLOfflineRegion_Private."); - MGLAssert([MGLShapeOfflineRegion conformsToProtocol:@protocol(MGLOfflineRegion_Private)], @"MGLShapeOfflineRegion should conform to MGLOfflineRegion_Private."); - - - - return regionDefinition.match( - [&] (const mbgl::OfflineTilePyramidRegionDefinition def){ - return (id <MGLOfflineRegion>)[[MGLTilePyramidOfflineRegion alloc] initWithOfflineRegionDefinition:def]; - }, - [&] (const mbgl::OfflineGeometryRegionDefinition& def){ - return (id <MGLOfflineRegion>)[[MGLShapeOfflineRegion alloc] initWithOfflineRegionDefinition:def]; - }); -} - -- (NSData *)context { - MGLAssertOfflinePackIsValid(); - - const mbgl::OfflineRegionMetadata &metadata = _mbglOfflineRegion->getMetadata(); - return [NSData dataWithBytes:&metadata[0] length:metadata.size()]; -} - -- (void)resume { - MGLLogInfo(@"Resuming pack download."); - MGLAssertOfflinePackIsValid(); - - self.state = MGLOfflinePackStateActive; - - _mbglDatabaseFileSource->setOfflineRegionDownloadState(*_mbglOfflineRegion, mbgl::OfflineRegionDownloadState::Active); -} - -- (void)suspend { - MGLLogInfo(@"Suspending pack download."); - MGLAssertOfflinePackIsValid(); - - if (self.state == MGLOfflinePackStateActive) { - self.state = MGLOfflinePackStateInactive; - _isSuspending = YES; - } - - _mbglDatabaseFileSource->setOfflineRegionDownloadState(*_mbglOfflineRegion, mbgl::OfflineRegionDownloadState::Inactive); -} - -- (void)invalidate { - MGLLogInfo(@"Invalidating pack."); - MGLAssert(_state != MGLOfflinePackStateInvalid, @"Cannot invalidate an already invalid offline pack."); - MGLAssert(self.mbglOfflineRegion, @"Should have a valid region"); - - @synchronized (self) { - self.state = MGLOfflinePackStateInvalid; - if (self.mbglOfflineRegion) { - _mbglDatabaseFileSource->setOfflineRegionObserver(*self.mbglOfflineRegion, nullptr); - } - self.mbglOfflineRegion = nil; - } -} - -- (void)setState:(MGLOfflinePackState)state { - MGLLogDebug(@"Setting state: %ld", (long)state); - if (!self.mbglOfflineRegion) { - // A progress update has arrived after the call to - // -[MGLOfflineStorage removePack:withCompletionHandler:] but before the - // removal is complete and the completion handler is called. - MGLAssert(_state == MGLOfflinePackStateInvalid, @"A valid MGLOfflinePack has no mbgl::OfflineRegion."); - return; - } - - MGLAssert(_state != MGLOfflinePackStateInvalid, @"Cannot change the state of an invalid offline pack."); - - if (!_isSuspending || state != MGLOfflinePackStateActive) { - _isSuspending = NO; - _state = state; - } -} - -- (void)requestProgress { - MGLLogInfo(@"Requesting pack progress."); - MGLAssertOfflinePackIsValid(); - - __weak MGLOfflinePack *weakSelf = self; - _mbglDatabaseFileSource->getOfflineRegionStatus(*_mbglOfflineRegion, [&, weakSelf](mbgl::expected<mbgl::OfflineRegionStatus, std::exception_ptr> status) { - if (status) { - mbgl::OfflineRegionStatus checkedStatus = *status; - dispatch_async(dispatch_get_main_queue(), ^{ - MGLOfflinePack *strongSelf = weakSelf; - [strongSelf offlineRegionStatusDidChange:checkedStatus]; - }); - } - }); -} - -- (void)offlineRegionStatusDidChange:(mbgl::OfflineRegionStatus)status { - MGLAssert(_state != MGLOfflinePackStateInvalid, @"Cannot change update progress of an invalid offline pack."); - - switch (status.downloadState) { - case mbgl::OfflineRegionDownloadState::Inactive: - self.state = status.complete() ? MGLOfflinePackStateComplete : MGLOfflinePackStateInactive; - break; - - case mbgl::OfflineRegionDownloadState::Active: - self.state = MGLOfflinePackStateActive; - break; - } - - if (_isSuspending) { - return; - } - - MGLOfflinePackProgress progress; - progress.countOfResourcesCompleted = status.completedResourceCount; - progress.countOfBytesCompleted = status.completedResourceSize; - progress.countOfTilesCompleted = status.completedTileCount; - progress.countOfTileBytesCompleted = status.completedTileSize; - progress.countOfResourcesExpected = status.requiredResourceCount; - progress.maximumResourcesExpected = status.requiredResourceCountIsPrecise ? status.requiredResourceCount : UINT64_MAX; - self.progress = progress; - - NSDictionary *userInfo = @{MGLOfflinePackUserInfoKeyState: @(self.state), - MGLOfflinePackUserInfoKeyProgress: [NSValue valueWithMGLOfflinePackProgress:progress]}; - - NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter]; - [noteCenter postNotificationName:MGLOfflinePackProgressChangedNotification - object:self - userInfo:userInfo]; -} - -- (void)didReceiveError:(NSError *)error { - MGLLogError(@"Error: %@", error.localizedDescription); - MGLLogInfo(@"Notifying about pack error."); - - NSDictionary *userInfo = @{ MGLOfflinePackUserInfoKeyError: error }; - NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter]; - [noteCenter postNotificationName:MGLOfflinePackErrorNotification - object:self - userInfo:userInfo]; -} - -- (void)didReceiveMaximumAllowedMapboxTiles:(uint64_t)limit { - MGLLogInfo(@"Notifying reached maximum allowed Mapbox tiles: %lu", (unsigned long)limit); - NSDictionary *userInfo = @{ MGLOfflinePackUserInfoKeyMaximumCount: @(limit) }; - NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter]; - [noteCenter postNotificationName:MGLOfflinePackMaximumMapboxTilesReachedNotification - object:self - userInfo:userInfo]; -} - -NSError *MGLErrorFromResponseError(mbgl::Response::Error error) { - NSInteger errorCode = MGLErrorCodeUnknown; - switch (error.reason) { - case mbgl::Response::Error::Reason::NotFound: - errorCode = MGLErrorCodeNotFound; - break; - - case mbgl::Response::Error::Reason::Server: - errorCode = MGLErrorCodeBadServerResponse; - break; - - case mbgl::Response::Error::Reason::Connection: - errorCode = MGLErrorCodeConnectionFailed; - break; - - default: - break; - } - return [NSError errorWithDomain:MGLErrorDomain code:errorCode userInfo:@{ - NSLocalizedFailureReasonErrorKey: @(error.message.c_str()) - }]; -} - -@end - -void MBGLOfflineRegionObserver::statusChanged(mbgl::OfflineRegionStatus status) { - __weak MGLOfflinePack *weakPack = pack; - dispatch_async(dispatch_get_main_queue(), ^{ - [weakPack offlineRegionStatusDidChange:status]; - }); -} - -void MBGLOfflineRegionObserver::responseError(mbgl::Response::Error error) { - __weak MGLOfflinePack *weakPack = pack; - dispatch_async(dispatch_get_main_queue(), ^{ - [weakPack didReceiveError:MGLErrorFromResponseError(error)]; - }); -} - -void MBGLOfflineRegionObserver::mapboxTileCountLimitExceeded(uint64_t limit) { - __weak MGLOfflinePack *weakPack = pack; - dispatch_async(dispatch_get_main_queue(), ^{ - [weakPack didReceiveMaximumAllowedMapboxTiles:limit]; - }); -} diff --git a/platform/darwin/src/MGLOfflinePack_Private.h b/platform/darwin/src/MGLOfflinePack_Private.h deleted file mode 100644 index ea3fb2da99..0000000000 --- a/platform/darwin/src/MGLOfflinePack_Private.h +++ /dev/null @@ -1,23 +0,0 @@ -#import "MGLOfflinePack.h" - -#include <mbgl/storage/offline.hpp> - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLOfflinePack (Private) - -@property (nonatomic, nullable) mbgl::OfflineRegion *mbglOfflineRegion; - -@property (nonatomic, readwrite) MGLOfflinePackState state; - -- (instancetype)initWithMBGLRegion:(mbgl::OfflineRegion *)region; - -/** - Invalidates the pack and ensures that no future progress update can ever - revalidate it. This method must be called before the pack is deallocated. - */ -- (void)invalidate; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOfflineRegion.h b/platform/darwin/src/MGLOfflineRegion.h deleted file mode 100644 index f873424c93..0000000000 --- a/platform/darwin/src/MGLOfflineRegion.h +++ /dev/null @@ -1,37 +0,0 @@ -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -/** - An object conforming to the `MGLOfflineRegion` protocol determines which - resources are required by an `MGLOfflinePack` object. - */ -@protocol MGLOfflineRegion <NSObject> - -/** - URL of the style whose resources are required for offline viewing. - - In addition to the JSON stylesheet, different styles may require different font - glyphs, sprite sheets, and other resources. - - The URL may be a full HTTP or HTTPS URL or a Mapbox - style URL (`mapbox://styles/{user}/{style}`). - */ -@property (nonatomic, readonly) NSURL *styleURL; - -/** - Specifies whether to include ideographic glyphs in downloaded font data. - Ideographic glyphs make up the majority of downloaded font data, but - it is possible to configure the renderer to use locally installed fonts - instead of relying on fonts downloaded as part of the offline pack. - See `MGLIdeographicFontFamilyName` setting. Also, for regions outside of - China, Japan, and Korea, these glyphs will rarely appear for non-CJK users. - - By default, this property is set to `NO`, so that the offline pack will - include ideographic glyphs. - */ -@property (nonatomic) BOOL includesIdeographicGlyphs; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOfflineRegion_Private.h b/platform/darwin/src/MGLOfflineRegion_Private.h deleted file mode 100644 index 75a023bcbb..0000000000 --- a/platform/darwin/src/MGLOfflineRegion_Private.h +++ /dev/null @@ -1,24 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLOfflineRegion.h" - -#include <mbgl/storage/offline.hpp> - -NS_ASSUME_NONNULL_BEGIN - -@protocol MGLOfflineRegion_Private <MGLOfflineRegion> - -/** - Creates and returns a C++ offline region definition corresponding to the - receiver. - */ -- (const mbgl::OfflineRegionDefinition)offlineRegionDefinition; - -/** - Attributes to be passed into the offline download start event - */ -@property (nonatomic, readonly) NSDictionary *offlineStartEventAttributes; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOfflineStorage.h b/platform/darwin/src/MGLOfflineStorage.h deleted file mode 100644 index d093bb938a..0000000000 --- a/platform/darwin/src/MGLOfflineStorage.h +++ /dev/null @@ -1,474 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -@class MGLOfflinePack; -@protocol MGLOfflineRegion; -@protocol MGLOfflineStorageDelegate; - -/** - Posted by the shared `MGLOfflineStorage` object when an `MGLOfflinePack` - object’s progress changes. The progress may change due to a resource being - downloaded or because the pack discovers during the download that more - resources are required for offline viewing. This notification is posted - whenever any field in the `progress` property changes. - - The `object` is the `MGLOfflinePack` object whose progress changed. The - `userInfo` dictionary contains the pack’s current state in the - `MGLOfflinePackUserInfoKeyState` key and details about the pack’s current - progress in the `MGLOfflinePackUserInfoKeyProgress` key. You may also consult - the `MGLOfflinePack.state` and `MGLOfflinePack.progress` properties, which - provide the same values. - - If you only need to observe changes in a particular pack’s progress, you can - alternatively observe KVO change notifications to the pack’s `progress` key - path. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/offline-pack/"> - Download an offline map</a> example to learn how to calculate the progress - of an offline download. - */ -FOUNDATION_EXTERN MGL_EXPORT const NSNotificationName MGLOfflinePackProgressChangedNotification; - -/** - Posted by the shared `MGLOfflineStorage` object whenever an `MGLOfflinePack` - object encounters an error while downloading. The error may be recoverable and - may not warrant the user’s attention. For example, the pack’s implementation - may attempt to re-request failed resources based on an exponential backoff - strategy or upon the restoration of network access. - - The `object` is the `MGLOfflinePack` object that encountered the error. The - `userInfo` dictionary contains the error object in the - `MGLOfflinePackUserInfoKeyError` key. - */ -FOUNDATION_EXTERN MGL_EXPORT const NSNotificationName MGLOfflinePackErrorNotification; - -/** - Posted by the shared `MGLOfflineStorage` object when the maximum number of - Mapbox-hosted tiles has been downloaded and stored on the current device. - - The `object` is the `MGLOfflinePack` object that reached the tile limit in the - course of downloading. The `userInfo` dictionary contains the tile limit in the - `MGLOfflinePackUserInfoKeyMaximumCount` key. - - Once this limit is reached, no instance of `MGLOfflinePack` can download - additional tiles from Mapbox APIs until already downloaded tiles are removed by - calling the `-[MGLOfflineStorage removePack:withCompletionHandler:]` method. - */ -FOUNDATION_EXTERN MGL_EXPORT const NSNotificationName MGLOfflinePackMaximumMapboxTilesReachedNotification; - -/** - A key in the `userInfo` property of a notification posted by `MGLOfflinePack`. - */ -typedef NSString *MGLOfflinePackUserInfoKey NS_EXTENSIBLE_STRING_ENUM; - -/** - The key for an `NSNumber` object that indicates an offline pack’s current - state. This key is used in the `userInfo` dictionary of an - `MGLOfflinePackProgressChangedNotification` notification. Call `-integerValue` - on the object to receive the `MGLOfflinePackState`-typed state. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyState; - -/** - The key for an `NSValue` object that indicates an offline pack’s current - progress. This key is used in the `userInfo` dictionary of an - `MGLOfflinePackProgressChangedNotification` notification. Call - `-MGLOfflinePackProgressValue` on the object to receive the - `MGLOfflinePackProgress`-typed progress. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyProgress; - -/** - The key for an `NSError` object that is encountered in the course of - downloading an offline pack. This key is used in the `userInfo` dictionary of - an `MGLOfflinePackErrorNotification` notification. The error’s domain is - `MGLErrorDomain`. See `MGLErrorCode` for possible error codes. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyError; - -/** - The key for an `NSNumber` object that indicates the maximum number of - Mapbox-hosted tiles that may be downloaded and stored on the current device. - This key is used in the `userInfo` dictionary of an - `MGLOfflinePackMaximumMapboxTilesReachedNotification` notification. Call - `-unsignedLongLongValue` on the object to receive the `uint64_t`-typed tile - limit. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyMaximumCount; - -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLUnsupportedRegionTypeException; - -/** - A block to be called once an offline pack has been completely created and - added. - - An application typically calls the `-resume` method on the pack inside this - completion handler to begin the download. - - @param pack Contains a pointer to the newly added pack, or `nil` if there was - an error creating or adding the pack. - @param error Contains a pointer to an error object (if any) indicating why the - pack could not be created or added. - */ -typedef void (^MGLOfflinePackAdditionCompletionHandler)(MGLOfflinePack * _Nullable pack, NSError * _Nullable error); - -/** - A block to be called once an offline pack has been completely invalidated and - removed. - - Avoid any references to the pack inside this completion handler: by the time - this completion handler is executed, the pack has become invalid, and any - messages passed to it will raise an exception. - - @param error Contains a pointer to an error object (if any) indicating why the - pack could not be invalidated or removed. - */ -typedef void (^MGLOfflinePackRemovalCompletionHandler)(NSError * _Nullable error); - -/** - A block to be called once the contents of a file are copied into the current packs. - - @param fileURL The file URL of the offline database containing the offline packs - that were copied. - @param packs An array of all known offline packs, or `nil` if there was an error - creating or adding the pack. - @param error A pointer to an error object (if any) indicating why the pack could - not be created or added. - */ -typedef void (^MGLBatchedOfflinePackAdditionCompletionHandler)(NSURL *fileURL, NSArray<MGLOfflinePack *> * _Nullable packs, NSError * _Nullable error); - -/** - The type of resource that is requested. - */ -typedef NS_ENUM(NSUInteger, MGLResourceKind) { - /** Unknown type */ - MGLResourceKindUnknown, - /** Style sheet JSON file */ - MGLResourceKindStyle, - /** TileJSON file as specified in https://www.mapbox.com/mapbox-gl-js/style-spec/#root-sources */ - MGLResourceKindSource, - /** A vector or raster tile as described in the style sheet at - https://www.mapbox.com/mapbox-gl-js/style-spec/#sources */ - MGLResourceKindTile, - /** Signed distance field glyphs for text rendering. These are the URLs specified in the style - in https://www.mapbox.com/mapbox-gl-js/style-spec/#root-glyphs */ - MGLResourceKindGlyphs, - /** Image part of a sprite sheet. It is constructed of the prefix in - https://www.mapbox.com/mapbox-gl-js/style-spec/#root-sprite and a PNG file extension. */ - MGLResourceKindSpriteImage, - /** JSON part of a sprite sheet. It is constructed of the prefix in - https://www.mapbox.com/mapbox-gl-js/style-spec/#root-sprite and a JSON file extension. */ - MGLResourceKindSpriteJSON, - /** Image data for a georeferenced image source. **/ - MGLResourceKindImage, -}; - -/** - MGLOfflineStorage implements a singleton (shared object) that manages offline - packs and ambient caching. All of this class’s instance methods are asynchronous, - reflecting the fact that offline resources are stored in a database. The shared - object maintains a canonical collection of offline packs in its `packs` property. - - Mapbox resources downloaded via this API are subject to separate Vector Tile and - Raster Tile API pricing and are not included in the Maps SDK’s “unlimited” requests. - See <a href="https://www.mapbox.com/pricing/">our pricing page</a> for more - information. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/offline-pack/"> - Download an offline map</a> example to learn how to create and register an - offline pack for a defined region. - */ -MGL_EXPORT -@interface MGLOfflineStorage : NSObject - -/** - Returns the shared offline storage object. - */ -@property (class, nonatomic, readonly) MGLOfflineStorage *sharedOfflineStorage; - -#pragma mark - Adding Contents of File - -/** - Adds the offline packs located at the given file path to offline storage. - - The file must be a valid offline region database bundled with the application - or downloaded separately. - - The resulting packs are added or updated to the shared offline storage object’s `packs` - property, then the `completion` block is executed. - - @param filePath A string representation of the file path. The file path must be - writable as schema updates may be perfomed. - @param completion The completion handler to call once the contents of the given - file has been added to offline storage. This handler is executed asynchronously - on the main queue. - */ -- (void)addContentsOfFile:(NSString *)filePath withCompletionHandler:(nullable MGLBatchedOfflinePackAdditionCompletionHandler)completion; - -/** - Adds the offline packs located at the given URL to offline storage. - - The file must be a valid offline region database bundled with the application - or downloaded separately. - - The resulting packs are added or updated to the shared offline storage object’s `packs` - property, then the `completion` block is executed. - - @param fileURL A file URL specifying the file to add. URL should be a valid system path. - The file URL must be writable as schema updates may be performed. - @param completion The completion handler to call once the contents of the given - file has been added to offline storage. This handler is executed asynchronously - on the main queue. - */ -- (void)addContentsOfURL:(NSURL *)fileURL withCompletionHandler:(nullable MGLBatchedOfflinePackAdditionCompletionHandler)completion; - -#pragma mark - Accessing the Delegate - -/** - The receiver’s delegate. - - An offline storage object sends messages to its delegate to allow it to - transform URLs before they are requested from the internet. This can be used - add or remove custom parameters, or reroute certain requests to other servers - or endpoints. - */ -@property(nonatomic, weak, nullable) IBOutlet id<MGLOfflineStorageDelegate> delegate; - -#pragma mark - Managing Offline Packs - -/** - An array of all known offline packs, in the order in which they were created. - - This property is set to `nil`, indicating that the receiver does not yet know - the existing packs, for an undefined amount of time starting from the moment - the shared offline storage object is initialized until the packs are fetched - from the database. After that point, this property is always non-nil, but it - may be empty to indicate that no packs are present. - - To detect when the shared offline storage object has finished loading its - `packs` property, observe KVO change notifications on the `packs` key path. - The initial load results in an `NSKeyValueChangeSetting` change. - */ -@property (nonatomic, strong, readonly, nullable) NSArray<MGLOfflinePack *> *packs; - -/** - Creates and registers an offline pack that downloads the resources needed to - use the given region offline. - - The resulting pack is added to the shared offline storage object’s `packs` - property, then the `completion` block is executed with that pack passed in. - - The pack has an initial state of `MGLOfflinePackStateInactive`. To begin - downloading resources, call `-[MGLOfflinePack resume]` on the pack from within - the completion handler. To monitor download progress, add an observer for - `MGLOfflinePackProgressChangedNotification`s about that pack. - - To detect when any call to this method results in a new pack, observe KVO - change notifications on the shared offline storage object’s `packs` key path. - Additions to that array result in an `NSKeyValueChangeInsertion` change. - - @param region A region to download. - @param context Arbitrary data to store alongside the downloaded resources. - @param completion The completion handler to call once the pack has been added. - This handler is executed asynchronously on the main queue. - */ -- (void)addPackForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(nullable MGLOfflinePackAdditionCompletionHandler)completion; - -/** - Unregisters the given offline pack and allows resources that are no longer - required by any remaining packs to be potentially freed. - - As soon as this method is called on a pack, the pack becomes invalid; any - attempt to send it a message will result in an exception being thrown. If an - error occurs and the pack cannot be removed, do not attempt to reuse the pack - object. Instead, if you need continued access to the pack, suspend all packs - and use the `-reloadPacks` method to obtain valid pointers to all the packs. - - To detect when any call to this method results in a pack being removed, observe - KVO change notifications on the shared offline storage object’s `packs` key - path. Removals from that array result in an `NSKeyValueChangeRemoval` change. - - When you remove an offline pack, any resources that are required by that pack, - but not other packs, become eligible for deletion from offline storage. Because - the backing store used for offline storage is also used as a general purpose - cache for map resources, such resources may not be immediately removed if the - implementation determines that they remain useful for general performance of - the map. - - @param pack The offline pack to remove. - @param completion The completion handler to call once the pack has been - removed. This handler is executed asynchronously on the main queue. - */ -- (void)removePack:(MGLOfflinePack *)pack withCompletionHandler:(nullable MGLOfflinePackRemovalCompletionHandler)completion; - -/** - Invalidates the specified offline pack. This method checks that the tiles - in the specified offline pack match those from the server. Local tiles that - do not match the latest version on the server are updated. - - This is more efficient than deleting the offline pack and downloading it - again. If the data stored locally matches that on the server, new data will - not be downloaded. - - @param pack The offline pack to be invalidated. - @param completion The completion handler to call once the pack has been - removed. This handler is executed asynchronously on the main queue. - */ - -- (void)invalidatePack:(MGLOfflinePack *)pack withCompletionHandler:(void (^)(NSError * _Nullable))completion; -/** - Forcibly, asynchronously reloads the `packs` property. At some point after this - method is called, the pointer values of the `MGLOfflinePack` objects in the - `packs` property change, even if the underlying data for these packs has not - changed. If this method is called while a pack is actively downloading, the - behavior is undefined. - - You typically do not need to call this method. - - To detect when the shared offline storage object has finished reloading its - `packs` property, observe KVO change notifications on the `packs` key path. - A reload results in an `NSKeyValueChangeSetting` change. - */ -- (void)reloadPacks; - -/** - Sets the maximum number of Mapbox-hosted tiles that may be downloaded and - stored on the current device. - - Once this limit is reached, an - `MGLOfflinePackMaximumMapboxTilesReachedNotification` is posted for every - attempt to download additional tiles until already downloaded tiles are removed - by calling the `-removePack:withCompletionHandler:` method. - - @param maximumCount The maximum number of tiles allowed to be downloaded. - */ -- (void)setMaximumAllowedMapboxTiles:(uint64_t)maximumCount; - -/** - The cumulative size, measured in bytes, of all downloaded resources on disk. - - The returned value includes all resources, including tiles, whether downloaded - as part of an offline pack or due to caching during normal use of `MGLMapView`. - */ -@property (nonatomic, readonly) unsigned long long countOfBytesCompleted; - - -#pragma mark - Managing Ambient Cache - -/** - Sets the maximum ambient cache size in bytes. The default maximum cache - size is 50 MB. To disable ambient caching, set the maximum ambient cache size - to `0`. Setting the maximum ambient cache size does not impact the maximum size - of offline packs. - - While this method does not limit the space available to offline packs, - data in offline packs count towards this limit. If the maximum ambient - cache size is set to 30 MB and 20 MB of offline packs are downloaded, - there may be only 10 MB reserved for the ambient cache. - - This method should be called before the map and map style have been loaded. - - This method is potentially expensive, as the database will trim cached data - in order to prevent the ambient cache from being larger than the - specified amount. - - @param cacheSize The maximum size in bytes for the ambient cache. - @param completion The completion handler to call once the maximum ambient cache size - has been set. This handler is executed synchronously on the main queue. - */ - -- (void)setMaximumAmbientCacheSize:(NSUInteger)cacheSize withCompletionHandler:(void (^)(NSError *_Nullable error))completion; - -/** - Invalidates the ambient cache. This method checks that the tiles in the - ambient cache match those from the server. If the local tiles do not match - those on the server, they are re-downloaded. - - This is recommended over clearing the cache or resetting the database - because valid local tiles will not be downloaded again. - - Resources shared with offline packs will not be affected by this method. - - @param completion The completion handler to call once the ambient cache has - been revalidated. This handler is executed asynchronously on the main queue. - */ - -- (void)invalidateAmbientCacheWithCompletionHandler:(void (^)(NSError *_Nullable error))completion; - -/** - Clears the ambient cache by deleting resources. This method does not - affect resources shared with offline regions. - - @param completion The completion handler to call once resources from - the ambient cache have been cleared. This handler is executed - asynchronously on the main queue. - */ - -- (void)clearAmbientCacheWithCompletionHandler:(void (^)(NSError *_Nullable error))completion; - -/** - Deletes the existing database, which includes both the ambient cache and offline packs, - then reinitializes it. - - You typically do not need to call this method. - - @param completion The completion handler to call once the pack has database has - been reset. This handler is executed asynchronously on the main queue. - */ - -- (void)resetDatabaseWithCompletionHandler:(void (^)(NSError *_Nullable error))completion; - -/** - Inserts the provided resource into the ambient cache. - - This method mimics the caching that would take place if the equivalent resource - were requested in the process of map rendering. Use this method to pre-warm the - cache with resources you know will be requested. - - This method is asynchronous; the data may not be immediately available for - in-progress requests, though subsequent requests should have access to the - cached data. - - @param data Response data to store for this resource. The data is expected to - be uncompressed; internally, the cache will compress data as necessary. - @param url The URL at which the data can normally be found. - @param modified The date the resource was last modified. - @param expires The date after which the resource is no longer valid. - @param eTag An HTTP entity tag. - @param mustRevalidate A Boolean value indicating whether the data is still - usable past the expiration date. - */ -- (void)preloadData:(NSData *)data forURL:(NSURL *)url modificationDate:(nullable NSDate *)modified expirationDate:(nullable NSDate *)expires eTag:(nullable NSString *)eTag mustRevalidate:(BOOL)mustRevalidate NS_SWIFT_NAME(preload(_:for:modifiedOn:expiresOn:eTag:mustRevalidate:)); - -- (void)putResourceWithUrl:(NSURL *)url data:(NSData *)data modified:(nullable NSDate *)modified expires:(nullable NSDate *)expires etag:(nullable NSString *)etag mustRevalidate:(BOOL)mustRevalidate __attribute__((deprecated("", "-preloadData:forURL:modificationDate:expirationDate:eTag:mustRevalidate:"))); - -@end - -/** - The `MGLOfflineStorageDelegate` protocol defines methods that a delegate of an - `MGLOfflineStorage` object can optionally implement to transform various types - of URLs before downloading them via the internet. - */ -@protocol MGLOfflineStorageDelegate <NSObject> - -/** - Sent whenever a URL needs to be transformed. - - @param storage The storage object processing the download. - @param kind The kind of URL to be transformed. - @param url The original URL to be transformed. - @return A URL that will now be downloaded. - */ -- (NSURL *)offlineStorage:(MGLOfflineStorage *)storage - URLForResourceOfKind:(MGLResourceKind)kind - withURL:(NSURL *)url; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm deleted file mode 100644 index 4c71286b79..0000000000 --- a/platform/darwin/src/MGLOfflineStorage.mm +++ /dev/null @@ -1,652 +0,0 @@ -#import "MGLOfflineStorage_Private.h" - -#import "MGLFoundation_Private.h" -#import "MGLAccountManager_Private.h" -#import "MGLGeometry_Private.h" -#import "MGLOfflinePack_Private.h" -#import "MGLOfflineRegion_Private.h" -#import "MGLTilePyramidOfflineRegion.h" -#import "MGLShapeOfflineRegion.h" -#import "NSBundle+MGLAdditions.h" -#import "NSValue+MGLAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MMEConstants.h" -#import "MGLMapboxEvents.h" -#endif - -#include <mbgl/actor/actor.hpp> -#include <mbgl/actor/scheduler.hpp> -#include <mbgl/storage/file_source_manager.hpp> -#include <mbgl/storage/resource_options.hpp> -#include <mbgl/storage/resource_transform.hpp> -#include <mbgl/util/chrono.hpp> -#include <mbgl/util/run_loop.hpp> -#include <mbgl/util/string.hpp> - -#include <memory> - -static NSString * const MGLOfflineStorageFileName = @"cache.db"; -static NSString * const MGLOfflineStorageFileName3_2_0_beta_1 = @"offline.db"; - -const NSNotificationName MGLOfflinePackProgressChangedNotification = @"MGLOfflinePackProgressChanged"; -const NSNotificationName MGLOfflinePackErrorNotification = @"MGLOfflinePackError"; -const NSNotificationName MGLOfflinePackMaximumMapboxTilesReachedNotification = @"MGLOfflinePackMaximumMapboxTilesReached"; - -const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyState = @"State"; -const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyProgress = @"Progress"; -const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyError = @"Error"; -const MGLOfflinePackUserInfoKey MGLOfflinePackUserInfoKeyMaximumCount = @"MaximumCount"; - -const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegionTypeException"; - -@interface MGLOfflineStorage () - -@property (nonatomic, strong, readwrite) NSMutableArray<MGLOfflinePack *> *packs; -@property (nonatomic) std::shared_ptr<mbgl::DatabaseFileSource> mbglDatabaseFileSource; -@property (nonatomic) std::shared_ptr<mbgl::FileSource> mbglOnlineFileSource; -@property (nonatomic) std::shared_ptr<mbgl::FileSource> mbglFileSource; -@property (nonatomic) std::string mbglCachePath; -@property (nonatomic, getter=isPaused) BOOL paused; -@end - -@implementation MGLOfflineStorage { - std::unique_ptr<mbgl::Actor<mbgl::ResourceTransform::TransformCallback>> _mbglResourceTransform; -} - -+ (instancetype)sharedOfflineStorage { - static dispatch_once_t onceToken; - static MGLOfflineStorage *sharedOfflineStorage; - dispatch_once(&onceToken, ^{ - sharedOfflineStorage = [[self alloc] init]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[NSNotificationCenter defaultCenter] addObserver:sharedOfflineStorage selector:@selector(unpauseFileSource:) name:UIApplicationWillEnterForegroundNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:sharedOfflineStorage selector:@selector(pauseFileSource:) name:UIApplicationDidEnterBackgroundNotification object:nil]; -#endif - [sharedOfflineStorage reloadPacks]; - }); - - return sharedOfflineStorage; -} - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -- (void)pauseFileSource:(__unused NSNotification *)notification { - if (self.isPaused) { - return; - } - _mbglFileSource->pause(); - self.paused = YES; -} - -- (void)unpauseFileSource:(__unused NSNotification *)notification { - if (!self.isPaused) { - return; - } - _mbglFileSource->resume(); - self.paused = NO; -} -#endif - -- (void)setDelegate:(id<MGLOfflineStorageDelegate>)newValue { - MGLLogDebug(@"Setting delegate: %@", newValue); - _delegate = newValue; - if ([self.delegate respondsToSelector:@selector(offlineStorage:URLForResourceOfKind:withURL:)]) { - _mbglResourceTransform = std::make_unique<mbgl::Actor<mbgl::ResourceTransform::TransformCallback>>(*mbgl::Scheduler::GetCurrent(), [offlineStorage = self](auto kind_, const std::string& url_, mbgl::ResourceTransform::FinishedCallback cb) { - NSURL* url = - [NSURL URLWithString:[[NSString alloc] initWithBytes:url_.data() - length:url_.length() - encoding:NSUTF8StringEncoding]]; - MGLResourceKind kind = MGLResourceKindUnknown; - switch (kind_) { - case mbgl::Resource::Kind::Tile: - kind = MGLResourceKindTile; - break; - case mbgl::Resource::Kind::Glyphs: - kind = MGLResourceKindGlyphs; - break; - case mbgl::Resource::Kind::Style: - kind = MGLResourceKindStyle; - break; - case mbgl::Resource::Kind::Source: - kind = MGLResourceKindSource; - break; - case mbgl::Resource::Kind::SpriteImage: - kind = MGLResourceKindSpriteImage; - break; - case mbgl::Resource::Kind::SpriteJSON: - kind = MGLResourceKindSpriteJSON; - break; - case mbgl::Resource::Kind::Image: - kind = MGLResourceKindImage; - break; - case mbgl::Resource::Kind::Unknown: - kind = MGLResourceKindUnknown; - break; - - } - url = [offlineStorage.delegate offlineStorage:offlineStorage - URLForResourceOfKind:kind - withURL:url]; - cb(url.absoluteString.UTF8String); - }); - - _mbglOnlineFileSource->setResourceTransform({[actorRef = _mbglResourceTransform->self()](auto kind_, const std::string& url_, mbgl::ResourceTransform::FinishedCallback cb_){ - actorRef.invoke(&mbgl::ResourceTransform::TransformCallback::operator(), kind_, url_, std::move(cb_)); - }}); - } else { - _mbglResourceTransform.reset(); - _mbglOnlineFileSource->setResourceTransform({}); - } -} - -/** - Returns the file URL to the offline cache, with the option to omit the private - subdirectory for legacy (v3.2.0 - v3.2.3) migration purposes. - - The cache is located in a directory specific to the application, so that packs - downloaded by other applications don’t count toward this application’s limits. - - The cache is located at: - ~/Library/Application Support/tld.app.bundle.id/.mapbox/cache.db - - The subdirectory-less cache was located at: - ~/Library/Application Support/tld.app.bundle.id/cache.db - */ -+ (NSURL *)cacheURLIncludingSubdirectory:(BOOL)useSubdirectory { - NSURL *cacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory - inDomain:NSUserDomainMask - appropriateForURL:nil - create:YES - error:nil]; - NSString *bundleIdentifier = [NSBundle mgl_applicationBundleIdentifier]; - if (!bundleIdentifier) { - // There’s no main bundle identifier when running in a unit test bundle. - bundleIdentifier = [[NSUUID UUID] UUIDString]; - } - cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:bundleIdentifier]; - if (useSubdirectory) { - cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:@".mapbox"]; - } - [[NSFileManager defaultManager] createDirectoryAtURL:cacheDirectoryURL - withIntermediateDirectories:YES - attributes:nil - error:nil]; - if (useSubdirectory) { - // Avoid backing up the offline cache onto iCloud, because it can be - // redownloaded. Ideally, we’d even put the ambient cache in Caches, so - // it can be reclaimed by the system when disk space runs low. But - // unfortunately it has to live in the same file as offline resources. - [cacheDirectoryURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:NULL]; - } - return [cacheDirectoryURL URLByAppendingPathComponent:MGLOfflineStorageFileName]; -} - -/** - Returns the absolute path to the location where v3.2.0-beta.1 placed the - offline cache. - */ -+ (NSString *)legacyCachePath { -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - // ~/Documents/offline.db - NSArray *legacyPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *legacyCachePath = [legacyPaths.firstObject stringByAppendingPathComponent:MGLOfflineStorageFileName3_2_0_beta_1]; -#elif TARGET_OS_MAC - // ~/Library/Caches/tld.app.bundle.id/offline.db - NSString *bundleIdentifier = [NSBundle mgl_applicationBundleIdentifier]; - NSURL *legacyCacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory - inDomain:NSUserDomainMask - appropriateForURL:nil - create:NO - error:nil]; - legacyCacheDirectoryURL = [legacyCacheDirectoryURL URLByAppendingPathComponent:bundleIdentifier]; - NSURL *legacyCacheURL = [legacyCacheDirectoryURL URLByAppendingPathComponent:MGLOfflineStorageFileName3_2_0_beta_1]; - NSString *legacyCachePath = legacyCacheURL ? legacyCacheURL.path : @""; -#endif - return legacyCachePath; -} - -- (instancetype)init { - MGLInitializeRunLoop(); - - if (self = [super init]) { - NSURL *cacheURL = [[self class] cacheURLIncludingSubdirectory:YES]; - NSString *cachePath = cacheURL.path ?: @""; - - // Move the offline cache from v3.2.0-beta.1 to a location that can also - // be used for ambient caching. - if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath]) { - NSString *legacyCachePath = [[self class] legacyCachePath]; - [[NSFileManager defaultManager] moveItemAtPath:legacyCachePath toPath:cachePath error:NULL]; - } - - // Move the offline file cache from v3.2.x path to a subdirectory that - // can be reliably excluded from backups. - if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath]) { - NSURL *subdirectorylessCacheURL = [[self class] cacheURLIncludingSubdirectory:NO]; - [[NSFileManager defaultManager] moveItemAtPath:subdirectorylessCacheURL.path toPath:cachePath error:NULL]; - } - - _mbglCachePath = cachePath.UTF8String; - mbgl::ResourceOptions options; - options.withCachePath(_mbglCachePath) - .withAssetPath([NSBundle mainBundle].resourceURL.path.UTF8String); - _mbglFileSource = mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::ResourceLoader, options); - _mbglOnlineFileSource = mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::Network, options); - _mbglDatabaseFileSource = std::static_pointer_cast<mbgl::DatabaseFileSource>(std::shared_ptr<mbgl::FileSource>(mbgl::FileSourceManager::get()->getFileSource(mbgl::FileSourceType::Database, options))); - - // Observe for changes to the API base URL (and find out the current one). - [[MGLAccountManager sharedManager] addObserver:self - forKeyPath:@"apiBaseURL" - options:(NSKeyValueObservingOptionInitial | - NSKeyValueObservingOptionNew) - context:NULL]; - - // Observe for changes to the global access token (and find out the current one). - [[MGLAccountManager sharedManager] addObserver:self - forKeyPath:@"accessToken" - options:(NSKeyValueObservingOptionInitial | - NSKeyValueObservingOptionNew) - context:NULL]; - } - return self; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [[MGLAccountManager sharedManager] removeObserver:self forKeyPath:@"apiBaseURL"]; - [[MGLAccountManager sharedManager] removeObserver:self forKeyPath:@"accessToken"]; - - for (MGLOfflinePack *pack in self.packs) { - [pack invalidate]; - } -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context { - // Synchronize the file source’s access token with the global one in MGLAccountManager. - if ([keyPath isEqualToString:@"accessToken"] && object == [MGLAccountManager sharedManager]) { - NSString *accessToken = change[NSKeyValueChangeNewKey]; - if (![accessToken isKindOfClass:[NSNull class]]) { - _mbglOnlineFileSource->setProperty(mbgl::ACCESS_TOKEN_KEY, accessToken.UTF8String); - } - } else if ([keyPath isEqualToString:@"apiBaseURL"] && object == [MGLAccountManager sharedManager]) { - NSURL *apiBaseURL = change[NSKeyValueChangeNewKey]; - if ([apiBaseURL isKindOfClass:[NSNull class]]) { - _mbglFileSource->setProperty(mbgl::API_BASE_URL_KEY, mbgl::util::API_BASE_URL); - } else { - _mbglFileSource->setProperty(mbgl::API_BASE_URL_KEY, apiBaseURL.absoluteString.UTF8String); - } - } else { - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - } -} - -#pragma mark Offline merge methods - -- (void)addContentsOfFile:(NSString *)filePath withCompletionHandler:(MGLBatchedOfflinePackAdditionCompletionHandler)completion { - MGLLogDebug(@"Adding contentsOfFile: %@ completionHandler: %@", filePath, completion); - NSURL *fileURL = [NSURL fileURLWithPath:filePath]; - - [self addContentsOfURL:fileURL withCompletionHandler:completion]; - -} - -- (void)addContentsOfURL:(NSURL *)fileURL withCompletionHandler:(MGLBatchedOfflinePackAdditionCompletionHandler)completion { - MGLLogDebug(@"Adding contentsOfURL: %@ completionHandler: %@", fileURL, completion); - NSFileManager *fileManager = [NSFileManager defaultManager]; - - if (!fileURL.isFileURL) { - [NSException raise:NSInvalidArgumentException format:@"%@ must be a valid file path", fileURL.absoluteString]; - } - if (![fileManager isWritableFileAtPath:fileURL.path]) { - [NSException raise:NSInvalidArgumentException format:@"The file path: %@ must be writable", fileURL.absoluteString]; - } - - __weak MGLOfflineStorage *weakSelf = self; - [self _addContentsOfFile:fileURL.path withCompletionHandler:^(NSArray<MGLOfflinePack *> * _Nullable packs, NSError * _Nullable error) { - if (packs) { - NSMutableDictionary *packsByIdentifier = [NSMutableDictionary dictionary]; - - MGLOfflineStorage *strongSelf = weakSelf; - for (MGLOfflinePack *pack in packs) { - [packsByIdentifier setObject:pack forKey:@(pack.mbglOfflineRegion->getID())]; - } - - id mutablePacks = [strongSelf mutableArrayValueForKey:@"packs"]; - NSMutableIndexSet *replaceIndexSet = [NSMutableIndexSet indexSet]; - NSMutableArray *replacePacksArray = [NSMutableArray array]; - [strongSelf.packs enumerateObjectsUsingBlock:^(MGLOfflinePack * _Nonnull pack, NSUInteger idx, BOOL * _Nonnull stop) { - MGLOfflinePack *newPack = packsByIdentifier[@(pack.mbglOfflineRegion->getID())]; - if (newPack) { - MGLOfflinePack *previousPack = [mutablePacks objectAtIndex:idx]; - [previousPack invalidate]; - [replaceIndexSet addIndex:idx]; - [replacePacksArray addObject:[packsByIdentifier objectForKey:@(newPack.mbglOfflineRegion->getID())]]; - [packsByIdentifier removeObjectForKey:@(newPack.mbglOfflineRegion->getID())]; - } - - }]; - - if (replaceIndexSet.count > 0) { - [mutablePacks replaceObjectsAtIndexes:replaceIndexSet withObjects:replacePacksArray]; - } - - [mutablePacks addObjectsFromArray:packsByIdentifier.allValues]; - } - if (completion) { - completion(fileURL, packs, error); - } - }]; -} - -- (void)_addContentsOfFile:(NSString *)filePath withCompletionHandler:(void (^)(NSArray<MGLOfflinePack *> * _Nullable packs, NSError * _Nullable error))completion { - _mbglDatabaseFileSource->mergeOfflineRegions(std::string(static_cast<const char *>([filePath UTF8String])), [&, completion, filePath](mbgl::expected<mbgl::OfflineRegions, std::exception_ptr> result) { - NSError *error; - NSMutableArray *packs; - if (!result) { - NSString *description = [NSString stringWithFormat:NSLocalizedStringWithDefaultValue(@"ADD_FILE_CONTENTS_FAILED_DESC", @"Foundation", nil, @"Unable to add offline packs from the file at %@.", @"User-friendly error description"), filePath]; - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeModifyingOfflineStorageFailed - userInfo:@{ - NSLocalizedDescriptionKey: description, - NSLocalizedFailureReasonErrorKey: @(mbgl::util::toString(result.error()).c_str()) - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } else { - auto& regions = result.value(); - packs = [NSMutableArray arrayWithCapacity:regions.size()]; - for (auto ®ion : regions) { - MGLOfflinePack *pack = [[MGLOfflinePack alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(region))]; - [packs addObject:pack]; - } - } - if (completion) { - dispatch_async(dispatch_get_main_queue(), [&, completion, error, packs](void) { - completion(packs, error); - }); - } - }); -} - -#pragma mark Pack management methods - -- (void)addPackForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflinePackAdditionCompletionHandler)completion { - MGLLogDebug(@"Adding packForRegion: %@ contextLength: %lu completionHandler: %@", region, (unsigned long)context.length, completion); - __weak MGLOfflineStorage *weakSelf = self; - [self _addPackForRegion:region withContext:context completionHandler:^(MGLOfflinePack * _Nullable pack, NSError * _Nullable error) { - pack.state = MGLOfflinePackStateInactive; - MGLOfflineStorage *strongSelf = weakSelf; - [[strongSelf mutableArrayValueForKey:@"packs"] addObject:pack]; - if (completion) { - completion(pack, error); - } - - #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - NSMutableDictionary *offlineDownloadStartEventAttributes = [NSMutableDictionary dictionaryWithObject:MMEventTypeOfflineDownloadStart forKey:MMEEventKeyEvent]; - - if ([region conformsToProtocol:@protocol(MGLOfflineRegion_Private)]) { - NSDictionary *regionAttributes = ((id<MGLOfflineRegion_Private>)region).offlineStartEventAttributes; - [offlineDownloadStartEventAttributes addEntriesFromDictionary:regionAttributes]; - } - - [MGLMapboxEvents pushEvent:MMEventTypeOfflineDownloadStart withAttributes:offlineDownloadStartEventAttributes]; - #endif - }]; -} - -- (void)_addPackForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflinePackAdditionCompletionHandler)completion { - if (![region conformsToProtocol:@protocol(MGLOfflineRegion_Private)]) { - [NSException raise:MGLUnsupportedRegionTypeException - format:@"Regions of type %@ are unsupported.", NSStringFromClass([region class])]; - return; - } - - const mbgl::OfflineRegionDefinition regionDefinition = [(id <MGLOfflineRegion_Private>)region offlineRegionDefinition]; - mbgl::OfflineRegionMetadata metadata(context.length); - [context getBytes:&metadata[0] length:metadata.size()]; - _mbglDatabaseFileSource->createOfflineRegion(regionDefinition, metadata, [&, completion](mbgl::expected<mbgl::OfflineRegion, std::exception_ptr> mbglOfflineRegion) { - NSError *error; - if (!mbglOfflineRegion) { - NSString *errorDescription = @(mbgl::util::toString(mbglOfflineRegion.error()).c_str()); - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeModifyingOfflineStorageFailed userInfo:errorDescription ? @{ - NSLocalizedDescriptionKey: errorDescription, - } : nil]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } - if (completion) { - MGLOfflinePack *pack = mbglOfflineRegion ? [[MGLOfflinePack alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(mbglOfflineRegion.value()))] : nil; - dispatch_async(dispatch_get_main_queue(), [&, completion, error, pack](void) { - completion(pack, error); - }); - } - }); -} - -- (void)removePack:(MGLOfflinePack *)pack withCompletionHandler:(MGLOfflinePackRemovalCompletionHandler)completion { - MGLLogDebug(@"Removing pack: %@ completionHandler: %@", pack, completion); - [[self mutableArrayValueForKey:@"packs"] removeObject:pack]; - [self _removePack:pack withCompletionHandler:^(NSError * _Nullable error) { - if (completion) { - completion(error); - } - }]; -} - -- (void)_removePack:(MGLOfflinePack *)pack withCompletionHandler:(MGLOfflinePackRemovalCompletionHandler)completion { - mbgl::OfflineRegion *mbglOfflineRegion = pack.mbglOfflineRegion; - - [pack invalidate]; - - if (!mbglOfflineRegion) { - MGLAssert(pack.state == MGLOfflinePackStateInvalid, @"State should be invalid"); - completion(nil); - return; - } - - _mbglDatabaseFileSource->deleteOfflineRegion(std::move(*mbglOfflineRegion), [&, completion](std::exception_ptr exception) { - NSError *error; - if (exception) { - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeModifyingOfflineStorageFailed userInfo:@{ - NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()), - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } - if (completion) { - dispatch_async(dispatch_get_main_queue(), [&, completion, error](void) { - completion(error); - }); - } - }); - -} - -- (void)invalidatePack:(MGLOfflinePack *)pack withCompletionHandler:(void (^)(NSError * _Nullable))completion { - mbgl::OfflineRegion& region = *pack.mbglOfflineRegion; - NSError *error; - if (!pack.mbglOfflineRegion) { - completion(nil); - return; - } - - _mbglDatabaseFileSource->invalidateOfflineRegion(region, [&](std::exception_ptr exception) { - if (exception) { - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeModifyingOfflineStorageFailed userInfo:@{ - NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()), - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } - }); - if (completion) { - dispatch_async(dispatch_get_main_queue(), [&, completion, error](void) { - completion(error); - }); - } -} - -- (void)reloadPacks { - MGLLogInfo(@"Reloading packs."); - [self getPacksWithCompletionHandler:^(NSArray<MGLOfflinePack *> *packs, __unused NSError * _Nullable error) { - for (MGLOfflinePack *pack in self.packs) { - [pack invalidate]; - } - self.packs = [packs mutableCopy]; - }]; -} - -- (void)getPacksWithCompletionHandler:(void (^)(NSArray<MGLOfflinePack *> *packs, NSError * _Nullable error))completion { - _mbglDatabaseFileSource->listOfflineRegions([&, completion](mbgl::expected<mbgl::OfflineRegions, std::exception_ptr> result) { - NSError *error; - NSMutableArray *packs; - if (!result) { - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeUnknown userInfo:@{ - NSLocalizedDescriptionKey: @(mbgl::util::toString(result.error()).c_str()), - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } else { - auto& regions = result.value(); - packs = [NSMutableArray arrayWithCapacity:regions.size()]; - for (auto ®ion : regions) { - MGLOfflinePack *pack = [[MGLOfflinePack alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(region))]; - [packs addObject:pack]; - } - } - if (completion) { - dispatch_async(dispatch_get_main_queue(), [&, completion, error, packs](void) { - completion(packs, error); - }); - } - }); -} - -- (void)setMaximumAllowedMapboxTiles:(uint64_t)maximumCount { - MGLLogDebug(@"Setting maximumAllowedMapboxTiles: %lu", (unsigned long)maximumCount); - _mbglDatabaseFileSource->setOfflineMapboxTileCountLimit(maximumCount); -} - -#pragma mark - Ambient Cache management - -- (void)setMaximumAmbientCacheSize:(NSUInteger)cacheSize withCompletionHandler:(void (^)(NSError * _Nullable))completion { - _mbglDatabaseFileSource->setMaximumAmbientCacheSize(cacheSize, [&, completion](std::exception_ptr exception) { - NSError *error; - if (completion) { - if (exception) { - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeModifyingOfflineStorageFailed userInfo:@{ - NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()), - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } - dispatch_sync(dispatch_get_main_queue(), ^ { - completion(error); - }); - } - }); -} - -- (void)invalidateAmbientCacheWithCompletionHandler:(void (^)(NSError *_Nullable))completion { - _mbglDatabaseFileSource->invalidateAmbientCache([&, completion](std::exception_ptr exception){ - NSError *error; - if (completion) { - if (exception) { - // Convert std::exception_ptr to an NSError. - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeModifyingOfflineStorageFailed userInfo:@{ - NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()), - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } - dispatch_async(dispatch_get_main_queue(), ^ { - completion(error); - }); - } - }); -} - -- (void)clearAmbientCacheWithCompletionHandler:(void (^)(NSError *_Nullable error))completion { - _mbglDatabaseFileSource->clearAmbientCache([&, completion](std::exception_ptr exception){ - NSError *error; - if (completion) { - if (exception) { - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeModifyingOfflineStorageFailed userInfo:@{ - NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()), - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } - dispatch_async(dispatch_get_main_queue(), [&, completion, error](void) { - completion(error); - }); - } - }); -} - -- (void)resetDatabaseWithCompletionHandler:(void (^)(NSError *_Nullable error))completion { - _mbglDatabaseFileSource->resetDatabase([&, completion](std::exception_ptr exception) { - NSError *error; - if (completion) { - if (exception) { - error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeUnknown userInfo:@{ - NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()), - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:error]; -#endif - } - dispatch_async(dispatch_get_main_queue(), ^{ - completion(error); - }); - } - }); -} -#pragma mark - - -- (unsigned long long)countOfBytesCompleted { - NSURL *cacheURL = [[self class] cacheURLIncludingSubdirectory:YES]; - NSString *cachePath = cacheURL.path; - if (!cachePath) { - return 0; - } - - NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:cachePath error:NULL]; - return attributes.fileSize; -} - -- (void)preloadData:(NSData *)data forURL:(NSURL *)url modificationDate:(nullable NSDate *)modified expirationDate:(nullable NSDate *)expires eTag:(nullable NSString *)eTag mustRevalidate:(BOOL)mustRevalidate { - mbgl::Resource resource(mbgl::Resource::Kind::Unknown, url.absoluteString.UTF8String); - mbgl::Response response; - response.data = std::make_shared<std::string>(static_cast<const char*>(data.bytes), data.length); - response.mustRevalidate = mustRevalidate; - - if (eTag) { - response.etag = std::string(eTag.UTF8String); - } - - if (modified) { - response.modified = mbgl::Timestamp() + std::chrono::duration_cast<mbgl::Seconds>(MGLDurationFromTimeInterval(modified.timeIntervalSince1970)); - } - - if (expires) { - response.expires = mbgl::Timestamp() + std::chrono::duration_cast<mbgl::Seconds>(MGLDurationFromTimeInterval(expires.timeIntervalSince1970)); - } - - _mbglDatabaseFileSource->put(resource, response); -} - -- (void)putResourceWithUrl:(NSURL *)url data:(NSData *)data modified:(nullable NSDate *)modified expires:(nullable NSDate *)expires etag:(nullable NSString *)etag mustRevalidate:(BOOL)mustRevalidate { - [self preloadData:data forURL:url modificationDate:modified expirationDate:expires eTag:etag mustRevalidate:mustRevalidate]; -} - -@end diff --git a/platform/darwin/src/MGLOfflineStorage_Private.h b/platform/darwin/src/MGLOfflineStorage_Private.h deleted file mode 100644 index c01163e766..0000000000 --- a/platform/darwin/src/MGLOfflineStorage_Private.h +++ /dev/null @@ -1,36 +0,0 @@ -#import "MGLOfflineStorage.h" - -#import "MGLOfflinePack.h" - -#include <mbgl/storage/online_file_source.hpp> -#include <mbgl/storage/database_file_source.hpp> - -#include <memory> - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLOfflineStorage (Private) - -/** - The shared database file source object owned by the shared offline storage object. - */ -@property (nonatomic) std::shared_ptr<mbgl::DatabaseFileSource> mbglDatabaseFileSource; - -/** - The shared online file source object owned by the shared offline storage object. - */ -@property (nonatomic) std::shared_ptr<mbgl::FileSource> mbglOnlineFileSource; - -/** - The shared resource loader file source object owned by the shared offline storage object. - */ -@property (nonatomic) std::shared_ptr<mbgl::FileSource> mbglFileSource; - -/** - The shared offline cache path. - */ -@property (nonatomic) std::string mbglCachePath; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.h b/platform/darwin/src/MGLOpenGLStyleLayer.h deleted file mode 100644 index fd82a4a69d..0000000000 --- a/platform/darwin/src/MGLOpenGLStyleLayer.h +++ /dev/null @@ -1,51 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> -#import <QuartzCore/QuartzCore.h> - -#import "MGLFoundation.h" -#import "MGLStyleValue.h" -#import "MGLStyleLayer.h" -#import "MGLGeometry.h" - -NS_ASSUME_NONNULL_BEGIN - -@class MGLMapView; -@class MGLStyle; - -typedef struct MGLStyleLayerDrawingContext { - CGSize size; - CLLocationCoordinate2D centerCoordinate; - double zoomLevel; - CLLocationDirection direction; - CGFloat pitch; - CGFloat fieldOfView; - MGLMatrix4 projectionMatrix; -} MGLStyleLayerDrawingContext; - -MGL_EXPORT -@interface MGLOpenGLStyleLayer : MGLStyleLayer - -@property (nonatomic, weak, readonly) MGLStyle *style; - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#if TARGET_OS_IPHONE -@property (nonatomic, readonly) EAGLContext *context; -#else -@property (nonatomic, readonly) CGLContextObj context; -#endif -#pragma clang diagnostic pop - -- (instancetype)initWithIdentifier:(NSString *)identifier; - -- (void)didMoveToMapView:(MGLMapView *)mapView; - -- (void)willMoveFromMapView:(MGLMapView *)mapView; - -- (void)drawInMapView:(MGLMapView *)mapView withContext:(MGLStyleLayerDrawingContext)context; - -- (void)setNeedsDisplay; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.mm b/platform/darwin/src/MGLOpenGLStyleLayer.mm deleted file mode 100644 index 8c9e4b02a2..0000000000 --- a/platform/darwin/src/MGLOpenGLStyleLayer.mm +++ /dev/null @@ -1,206 +0,0 @@ -#import "MGLOpenGLStyleLayer.h" -#import "MGLOpenGLStyleLayer_Private.h" - -#import "MGLMapView_Private.h" -#import "MGLStyle_Private.h" -#import "MGLStyleLayer_Private.h" -#import "MGLGeometry_Private.h" - -#include <mbgl/gl/custom_layer.hpp> -#include <mbgl/math/wrap.hpp> - -class MGLOpenGLLayerHost : public mbgl::style::CustomLayerHost { -public: - MGLOpenGLLayerHost(MGLOpenGLStyleLayer *styleLayer) { - layerRef = styleLayer; - layer = nil; - } - - void initialize() { - if (layerRef == nil) return; - else if (layer == nil) layer = layerRef; - - [layer didMoveToMapView:layer.style.mapView]; - } - - void render(const mbgl::style::CustomLayerRenderParameters ¶ms) { - if(!layer) return; - - MGLStyleLayerDrawingContext drawingContext = { - .size = CGSizeMake(params.width, params.height), - .centerCoordinate = CLLocationCoordinate2DMake(params.latitude, params.longitude), - .zoomLevel = params.zoom, - .direction = mbgl::util::wrap(params.bearing, 0., 360.), - .pitch = static_cast<CGFloat>(params.pitch), - .fieldOfView = static_cast<CGFloat>(params.fieldOfView), - .projectionMatrix = MGLMatrix4Make(params.projectionMatrix) - }; - [layer drawInMapView:layer.style.mapView withContext:drawingContext]; - } - - void contextLost() {} - - void deinitialize() { - if (layer == nil) return; - - [layer willMoveFromMapView:layer.style.mapView]; - layerRef = layer; - layer = nil; - } -private: - __weak MGLOpenGLStyleLayer * layerRef; - MGLOpenGLStyleLayer * layer = nil; -}; - -/** - An `MGLOpenGLStyleLayer` is a style layer that is rendered by OpenGL code that - you provide. - - By default, this class does nothing. You can subclass this class to provide - custom OpenGL drawing code that is run on each frame of the map. Your subclass - should override the `-didMoveToMapView:`, `-willMoveFromMapView:`, and - `-drawInMapView:withContext:` methods. - - You can access an existing OpenGL style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new OpenGL style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - @warning This API is undocumented and therefore unsupported. It may change at - any time without notice. - */ -@interface MGLOpenGLStyleLayer () - -@property (nonatomic, readonly) mbgl::style::CustomLayer *rawLayer; - -/** - The style currently containing the layer. - - If the layer is not currently part of any style, this property is - set to `nil`. - */ -@property (nonatomic, weak, readwrite) MGLStyle *style; - -@end - -@implementation MGLOpenGLStyleLayer - -/** - Returns an OpenGL style layer object initialized with the given identifier. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the layer in the style to - which it is added. - @return An initialized OpenGL style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier { - auto layer = std::make_unique<mbgl::style::CustomLayer>(identifier.UTF8String, - std::make_unique<MGLOpenGLLayerHost>(self)); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::CustomLayer *)rawLayer { - return (mbgl::style::CustomLayer *)super.rawLayer; -} - -#if TARGET_OS_IPHONE -- (EAGLContext *)context { - return self.style.mapView.context; -} -#else -- (CGLContextObj)context { - return self.style.mapView.context; -} -#endif - -#pragma mark - Adding to and removing from a map view -- (void)addToStyle:(MGLStyle *)style belowLayer:(MGLStyleLayer *)otherLayer { - self.style = style; - self.style.openGLLayers[self.identifier] = self; - [super addToStyle:style belowLayer:otherLayer]; -} - -- (void)removeFromStyle:(MGLStyle *)style { - [super removeFromStyle:style]; - self.style.openGLLayers[self.identifier] = nil; - self.style = nil; -} - -/** - Called immediately after a layer is added to a map view’s style. - - This method is intended to be overridden in a subclass. You can use this method - to perform any setup work before the layer is used to draw a frame. For - example, you might use this method to compile an OpenGL shader. The default - implementation of this method does nothing. - - Any resource acquired in this method must be released in - `-willMoveFromMapView:`. - - @param mapView The map view to whose style the layer has been added. - */ -- (void)didMoveToMapView:(MGLMapView *)mapView { - -} - -/** - Called immediately before a layer is removed from a map view’s style. - - This method is intended to be overridden in a subclass. You can use this method - to perform any teardown work once the layer has drawn its last frame and is - about to be removed from the style. The default implementation of this method - does nothing. - - This method may be called even if `-didMoveToMapView:` has not been called. - - @param mapView The map view from whose style the layer is about to be removed. - */ -- (void)willMoveFromMapView:(MGLMapView *)mapView { - -} - -/** - Called each time the layer needs to draw a new frame in a map view. - - This method is intended to be overridden in a subclass. You can use this method - to draw the layer’s content. The default implementation of this method does - nothing. - - Your implementation should not make any assumptions about the OpenGL state, - other than that the current OpenGL context is active. It may make changes to - the OpenGL state. It is not required to reset values such as the depth mask, - stencil mask, or corresponding test flags to their original values. - - Be sure to draw your fragments with a <var>z</var> value of 1 to take advantage - of the opaque fragment culling, in case the style contains any opaque layers - above this layer. - - @param mapView The map view to which the layer draws. - @param context A context structure with information defining the frame to draw. - */ -- (void)drawInMapView:(MGLMapView *)mapView withContext:(MGLStyleLayerDrawingContext)context { - -} - -/** - Forces the map view associated with this style to redraw the receiving layer, - causing the `-drawInMapView:withContext:` method to be called. - */ -- (void)setNeedsDisplay { - [self.style.mapView setNeedsRerender]; -} - -@end - -namespace mbgl { - -MGLStyleLayer* OpenGLStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLOpenGLStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl - diff --git a/platform/darwin/src/MGLOpenGLStyleLayer_Private.h b/platform/darwin/src/MGLOpenGLStyleLayer_Private.h deleted file mode 100644 index 15dd6bf816..0000000000 --- a/platform/darwin/src/MGLOpenGLStyleLayer_Private.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/gl/custom_layer_factory.hpp> - -namespace mbgl { - -class OpenGLStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::CustomLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLOverlay.h b/platform/darwin/src/MGLOverlay.h deleted file mode 100644 index 7706b741e2..0000000000 --- a/platform/darwin/src/MGLOverlay.h +++ /dev/null @@ -1,57 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLAnnotation.h" -#import "MGLGeometry.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The `MGLOverlay` protocol defines a specific type of annotation that represents - both a point and an area on a map. Overlay objects are essentially data objects - that contain the geographic data needed to represent the map area. Overlays can - take the form of a polyline or polygon. - - You use overlays to layer more sophisticated content on top of a map view. For - example, you could use an overlay to show the boundaries of a national park or - trace a bus route along city streets. This SDK defines several concrete classes - that conform to this protocol and define standard shapes. - */ -@protocol MGLOverlay <MGLAnnotation> - -/** - A coordinate representing the overlay. (required) (read-only) - */ -@property (nonatomic, readonly) CLLocationCoordinate2D coordinate; - -/** - The cooordinate rectangle that encompasses the overlay. (required) (read-only) - - This property contains the smallest rectangle that completely encompasses the - overlay. Implementers of this protocol must set this area when implementing - their overlay class, and after setting it, you must not change it. - - If this overlay spans the antimeridian, its bounds may extend west of −180 degrees - longitude or east of 180 degrees longitude. For example, an overlay covering the - Pacific Ocean from Tokyo to San Francisco might have a bounds extending - from (35.68476, −220.24257) to (37.78428, −122.41310). - */ -@property (nonatomic, readonly) MGLCoordinateBounds overlayBounds; - -/** - Returns a Boolean indicating whether the specified rectangle intersects the - receiver’s shape. - - You can implement this method to provide more specific bounds checking for an - overlay. If you do not implement it, the bounding rectangle is used to detect - intersections. - - @param overlayBounds The rectangle to intersect with the receiver’s area. - @return `YES` if any part of the map rectangle intersects the receiver’s shape - or `NO` if it does not. - */ -- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLPointAnnotation.h b/platform/darwin/src/MGLPointAnnotation.h deleted file mode 100644 index 27562f0df0..0000000000 --- a/platform/darwin/src/MGLPointAnnotation.h +++ /dev/null @@ -1,55 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" -#import "MGLShape.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An `MGLPointAnnotation` object represents a one-dimensional shape located at a - single geographical coordinate. Depending on how it is used, an - `MGLPointAnnotation` object is known as a point annotation or point shape. For - example, you could use a point shape to represent a city at low zoom levels, an - address at high zoom levels, or the location of a long press gesture. - - You can add point shapes to the map by adding them to an `MGLShapeSource` - object. Configure the appearance of an `MGLShapeSource`’s or - `MGLVectorTileSource`’s point shapes collectively using an `MGLCircleStyleLayer` or - `MGLSymbolStyleLayer` object. - - For more interactivity, add a selectable point annotation to a map view using - the `-[MGLMapView addAnnotation:]` method. Alternatively, define your own model - class that conforms to the `MGLAnnotation` protocol. Configure a point - annotation’s appearance using - `-[MGLMapViewDelegate mapView:imageForAnnotation:]` or - `-[MGLMapViewDelegate mapView:viewForAnnotation:]` (iOS only). A point - annotation’s `MGLShape.title` and `MGLShape.subtitle` properties define the - default content of the annotation’s callout (on iOS) or popover (on macOS). - - To group multiple related points together in one shape, use an - `MGLPointCollection` or `MGLShapeCollection` object. To access - a point’s attributes, use an `MGLPointFeature` object. - - A point shape is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.1.2">Point</a> geometry - in GeoJSON. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/marker/"> - Mark a place on the map with an annotation</a>, <a href="https://docs.mapbox.com/ios/maps/examples/marker-image/"> - Mark a place on the map with an image</a>, and <a href="https://docs.mapbox.com/ios/maps/examples/default-callout/"> - Default callout usage</a> examples to learn how to add `MGLPointAnnotation` - objects to your map. - */ -MGL_EXPORT -@interface MGLPointAnnotation : MGLShape - -/** - The coordinate point of the shape, specified as a latitude and longitude. - */ -@property (nonatomic, assign) CLLocationCoordinate2D coordinate; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLPointAnnotation.mm b/platform/darwin/src/MGLPointAnnotation.mm deleted file mode 100644 index 233bef0a0f..0000000000 --- a/platform/darwin/src/MGLPointAnnotation.mm +++ /dev/null @@ -1,72 +0,0 @@ -#import "MGLPointAnnotation.h" - -#import "MGLShape_Private.h" -#import "NSCoder+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#import <mbgl/util/geometry.hpp> - - -@implementation MGLPointAnnotation - -@synthesize coordinate; - -+ (BOOL)supportsSecureCoding -{ - return YES; -} - -- (instancetype)initWithCoder:(NSCoder *)coder -{ - MGLLogInfo(@"Initializing with coder."); - if (self = [super initWithCoder:coder]) { - self.coordinate = [coder decodeMGLCoordinateForKey:@"coordinate"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - [super encodeWithCoder:coder]; - [coder encodeMGLCoordinate:coordinate forKey:@"coordinate"]; -} - -- (BOOL)isEqual:(id)other -{ - if (other == self) return YES; - if (![other isKindOfClass:[MGLPointAnnotation class]]) return NO; - - MGLPointAnnotation *otherAnnotation = other; - return ([super isEqual:other] - && self.coordinate.latitude == otherAnnotation.coordinate.latitude - && self.coordinate.longitude == otherAnnotation.coordinate.longitude); -} - -- (NSUInteger)hash -{ - return [super hash] + @(self.coordinate.latitude).hash + @(self.coordinate.longitude).hash; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; title = %@; subtitle = %@; coordinate = %f, %f>", - NSStringFromClass([self class]), (void *)self, - self.title ? [NSString stringWithFormat:@"\"%@\"", self.title] : self.title, - self.subtitle ? [NSString stringWithFormat:@"\"%@\"", self.subtitle] : self.subtitle, - coordinate.latitude, coordinate.longitude]; -} - -- (NSDictionary *)geoJSONDictionary -{ - return @{@"type": @"Point", - @"coordinates": @[@(self.coordinate.longitude), @(self.coordinate.latitude)]}; -} - -- (mbgl::Geometry<double>)geometryObject -{ - mbgl::Point<double> point = { self.coordinate.longitude, self.coordinate.latitude }; - return point; -} - -@end - diff --git a/platform/darwin/src/MGLPointCollection.h b/platform/darwin/src/MGLPointCollection.h deleted file mode 100644 index 65ce95cb0f..0000000000 --- a/platform/darwin/src/MGLPointCollection.h +++ /dev/null @@ -1,65 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" -#import "MGLOverlay.h" -#import "MGLShape.h" - -/** - An `MGLPointCollection` object represents a shape consisting of one or more - disconnected vertices, specified as `CLLocationCoordinate2D` instances. The - points in the collection may be related but are not connected spatially. For - example, you could use a point collection to represent all the trees in an - orchard. - - You can add point collections to the map by adding them to an `MGLShapeSource` - object. Configure the appearance of an `MGLShapeSource`’s or - `MGLVectorTileSource`’s point collections collectively using an - `MGLCircleStyleLayer` or `MGLSymbolStyleLayer` object. To access a point - collection’s attributes, use an `MGLPointCollectionFeature` object. - - You cannot add an `MGLPointCollection` object directly to a map view as an - annotation. However, you can create individual `MGLPointAnnotation` objects - from the `coordinates` array and add those annotation objects to the map view - using the `-[MGLMapView addAnnotations:]` method. - - A point collection is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.1.3">MultiPoint</a> - geometry in GeoJSON. Do not confuse `MGLPointCollection` with `MGLMultiPoint`, - the abstract superclass of `MGLPolyline` and `MGLPolygon`. - */ -MGL_EXPORT -@interface MGLPointCollection : MGLShape <MGLOverlay> - -/** - Creates and returns a `MGLPointCollection` object from the specified set of - coordinates. - - @param coords The array of coordinates defining the shape. The data in this - array is copied to the new object. - @param count The number of items in the `coords` array. - @return A new point collection object. - */ -+ (instancetype)pointCollectionWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -/** The array of coordinates associated with the shape. */ -@property (nonatomic, readonly) CLLocationCoordinate2D *coordinates NS_RETURNS_INNER_POINTER; - -/** The number of coordinates associated with the shape. */ -@property (nonatomic, readonly) NSUInteger pointCount; - -/** - Retrieves one or more coordinates associated with the shape. - - @param coords On input, you must provide a C array of structures large enough - to hold the desired number of coordinates. On output, this structure - contains the requested coordinate data. - @param range The range of points you want. The `location` field indicates the - first point you are requesting, with `0` being the first point, `1` being - the second point, and so on. The `length` field indicates the number of - points you want. The array in _`coords`_ must be large enough to accommodate - the number of requested coordinates. - */ -- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range; - -@end diff --git a/platform/darwin/src/MGLPointCollection.mm b/platform/darwin/src/MGLPointCollection.mm deleted file mode 100644 index 6e056712f7..0000000000 --- a/platform/darwin/src/MGLPointCollection.mm +++ /dev/null @@ -1,136 +0,0 @@ -#import "MGLPointCollection_Private.h" -#import "MGLGeometry_Private.h" -#import "NSArray+MGLAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#import <mbgl/util/geojson.hpp> -#import <mbgl/util/geometry.hpp> - -NS_ASSUME_NONNULL_BEGIN - -@implementation MGLPointCollection -{ - mbgl::optional<mbgl::LatLngBounds> _bounds; - std::vector<CLLocationCoordinate2D> _coordinates; -} - -+ (instancetype)pointCollectionWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count -{ - return [[self alloc] initWithCoordinates:coords count:count]; -} - -- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count -{ - MGLLogDebug(@"Initializing with %lu coordinates.", (unsigned long)count); - self = [super init]; - if (self) - { - _coordinates = { coords, coords + count }; - } - return self; -} - -- (nullable instancetype)initWithCoder:(NSCoder *)decoder { - MGLLogInfo(@"Initializing with coder.O"); - if (self = [super initWithCoder:decoder]) { - NSArray *coordinates = [decoder decodeObjectOfClass:[NSArray class] forKey:@"coordinates"]; - _coordinates = [coordinates mgl_coordinates]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder { - [super encodeWithCoder:coder]; - [coder encodeObject:[NSArray mgl_coordinatesFromCoordinates:_coordinates] forKey:@"coordinates"]; -} - -- (BOOL)isEqual:(id)other { - if (self == other) return YES; - if (![other isKindOfClass:[MGLPointCollection class]]) return NO; - - MGLPointCollection *otherCollection = (MGLPointCollection *)other; - return ([super isEqual:other] - && ((![self geoJSONDictionary] && ![otherCollection geoJSONDictionary]) || [[self geoJSONDictionary] isEqualToDictionary:[otherCollection geoJSONDictionary]])); -} - -- (MGLCoordinateBounds)overlayBounds { - if (!_bounds) { - mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty(); - for (auto coordinate : _coordinates) { - if (!MGLLocationCoordinate2DIsValid(coordinate)) { - bounds = mbgl::LatLngBounds::empty(); - break; - } - bounds.extend(MGLLatLngFromLocationCoordinate2D(coordinate)); - } - _bounds = bounds; - } - return MGLCoordinateBoundsFromLatLngBounds(*_bounds); -} - -- (NSUInteger)pointCount -{ - return _coordinates.size(); -} - -- (CLLocationCoordinate2D *)coordinates -{ - return _coordinates.data(); -} - -- (CLLocationCoordinate2D)coordinate -{ - MGLAssert([self pointCount] > 0, @"A multipoint must have coordinates"); - return _coordinates.at(0); -} - -- (void)getCoordinates:(CLLocationCoordinate2D *)coords range:(NSRange)range -{ - if (range.location + range.length > [self pointCount]) - { - [NSException raise:NSRangeException - format:@"Invalid coordinate range %@ extends beyond current coordinate count of %ld", - NSStringFromRange(range), (unsigned long)[self pointCount]]; - } - - std::copy(_coordinates.begin() + range.location, _coordinates.begin() + NSMaxRange(range), coords); -} - -- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds -{ - return MGLCoordinateBoundsIntersectsCoordinateBounds(self.overlayBounds, overlayBounds); -} - -- (mbgl::Geometry<double>)geometryObject -{ - mbgl::MultiPoint<double> multiPoint; - multiPoint.reserve(self.pointCount); - for (NSUInteger i = 0; i < self.pointCount; i++) - { - multiPoint.push_back(mbgl::Point<double>(self.coordinates[i].longitude, self.coordinates[i].latitude)); - } - return multiPoint; -} - -- (NSDictionary *)geoJSONDictionary -{ - NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount]; - for (NSUInteger index = 0; index < self.pointCount; index++) { - CLLocationCoordinate2D coordinate = self.coordinates[index]; - [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; - } - - return @{@"type": @"MultiPoint", - @"coordinates": coordinates}; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>", - NSStringFromClass([self class]), (void *)self, (unsigned long)[self pointCount], - MGLStringFromCoordinateBounds(self.overlayBounds)]; -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLPointCollection_Private.h b/platform/darwin/src/MGLPointCollection_Private.h deleted file mode 100644 index fc1c33fe4c..0000000000 --- a/platform/darwin/src/MGLPointCollection_Private.h +++ /dev/null @@ -1,11 +0,0 @@ -#import "MGLPointCollection.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLPointCollection (Private) - -- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLPolygon.h b/platform/darwin/src/MGLPolygon.h deleted file mode 100644 index 900e43334e..0000000000 --- a/platform/darwin/src/MGLPolygon.h +++ /dev/null @@ -1,129 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" -#import "MGLMultiPoint.h" -#import "MGLOverlay.h" - -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An `MGLPolygon` object represents a closed shape consisting of four or more - vertices, specified as `CLLocationCoordinate2D` instances, and the edges that - connect them. For example, you could use a polygon shape to represent a - building, a lake, or an area you want to highlight. - - You can add polygon shapes to the map by adding them to an `MGLShapeSource` - object. Configure the appearance of an `MGLShapeSource`’s or - `MGLVectorTileSource`’s polygons collectively using an `MGLFillStyleLayer` or - `MGLSymbolStyleLayer` object. To access a polygon’s attributes, use an - `MGLPolygonFeature` object. - - Alternatively, you can add a polygon overlay directly to a map view using the - `-[MGLMapView addAnnotation:]` or `-[MGLMapView addOverlay:]` method. Configure - a polygon overlay’s appearance using - `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` and - `-[MGLMapViewDelegate mapView:fillColorForPolygonAnnotation:]`. - - The vertices are automatically connected in the order in which you provide - them. You should close the polygon by specifying the same - `CLLocationCoordinate2D` as the first and last vertices; otherwise, the - polygon’s fill may not cover the area you expect it to. To avoid filling the - space within the shape, give the polygon a transparent fill or use an - `MGLPolyline` object. - - A polygon may have one or more interior polygons, or holes, that you specify as - `MGLPolygon` objects with the `+polygonWithCoordinates:count:interiorPolygons:` - method. For example, if a polygon represents a lake, it could exclude an island - within the lake using an interior polygon. Interior polygons may not themselves - have interior polygons. To represent a shape that includes a polygon within a - hole or, more generally, to group multiple polygons together in one shape, use - an `MGLMultiPolygon` or `MGLShapeCollection` object. - - To make the polygon straddle the antimeridian, specify some longitudes less - than −180 degrees or greater than 180 degrees. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/polygon/"> - Add a polygon annotation</a> example to learn how to initialize an - `MGLPolygon` object from an array of coordinates. - */ -MGL_EXPORT -@interface MGLPolygon : MGLMultiPoint <MGLOverlay> - -/** - The array of polygons nested inside the receiver. - - The area occupied by any interior polygons is excluded from the overall shape. - Interior polygons should not overlap. An interior polygon should not have - interior polygons of its own. - - If there are no interior polygons, the value of this property is `nil`. - */ -@property (nonatomic, nullable, readonly) NSArray<MGLPolygon *> *interiorPolygons; - -/** - Creates and returns an `MGLPolygon` object from the specified set of - coordinates. - - @param coords The array of coordinates defining the shape. The data in this - array is copied to the new object. - @param count The number of items in the `coords` array. - @return A new polygon object. - */ -+ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -/** - Creates and returns an `MGLPolygon` object from the specified set of - coordinates and interior polygons. - - @param coords The array of coordinates defining the shape. The data in this - array is copied to the new object. - @param count The number of items in the `coords` array. - @param interiorPolygons An array of `MGLPolygon` objects that define regions - excluded from the overall shape. If this array is `nil` or empty, the shape - is considered to have no interior polygons. - @return A new polygon object. - */ -+ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(nullable NSArray<MGLPolygon *> *)interiorPolygons; - -@end - -/** - An `MGLMultiPolygon` object represents a shape consisting of one or more - polygons that do not overlap. For example, you could use a multipolygon shape - to represent the body of land that consists of an island surrounded by an - atoll: the inner island would be one `MGLPolygon` object, while the surrounding - atoll would be another. You could also use a multipolygon shape to represent a - group of disconnected but related buildings. - - You can add multipolygon shapes to the map by adding them to an - `MGLShapeSource` object. Configure the appearance of an `MGLShapeSource`’s or - `MGLVectorTileSource`’s multipolygons collectively using an `MGLFillStyleLayer` - or `MGLSymbolStyleLayer` object. - - You cannot add an `MGLMultiPolygon` object directly to a map view using - `-[MGLMapView addAnnotation:]` or `-[MGLMapView addOverlay:]`. However, you can - add the `polygons` array’s items as overlays individually. - */ -MGL_EXPORT -@interface MGLMultiPolygon : MGLShape <MGLOverlay> - -/** - An array of polygons forming the multipolygon. - */ -@property (nonatomic, copy, readonly) NSArray<MGLPolygon *> *polygons; - -/** - Creates and returns a multipolygon object consisting of the given polygons. - - @param polygons The array of polygons defining the shape. - @return A new multipolygon object. - */ -+ (instancetype)multiPolygonWithPolygons:(NSArray<MGLPolygon *> *)polygons; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm deleted file mode 100644 index 52bff01b20..0000000000 --- a/platform/darwin/src/MGLPolygon.mm +++ /dev/null @@ -1,240 +0,0 @@ -#import "MGLPolygon_Private.h" - -#import "MGLMultiPoint_Private.h" -#import "MGLGeometry_Private.h" -#import "MGLLoggingConfiguration_Private.h" - -#import "MGLFeature.h" - -#import <mbgl/util/geojson.hpp> -#import <mapbox/polylabel.hpp> - -@implementation MGLPolygon - -@dynamic overlayBounds; - -+ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count { - return [self polygonWithCoordinates:coords count:count interiorPolygons:nil]; -} - -+ (instancetype)polygonWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(NSArray<MGLPolygon *> *)interiorPolygons { - return [[self alloc] initWithCoordinates:coords count:count interiorPolygons:interiorPolygons]; -} - -- (instancetype)initWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count interiorPolygons:(NSArray<MGLPolygon *> *)interiorPolygons { - MGLLogDebug(@"Initializing with %lu coordinates and %lu interiorPolygons.", (unsigned long)count, (unsigned long)interiorPolygons); - if (self = [super initWithCoordinates:coords count:count]) { - if (interiorPolygons.count) { - _interiorPolygons = interiorPolygons; - } - } - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder { - MGLLogInfo(@"Initializng with coder."); - self = [super initWithCoder:decoder]; - if (self) { - _interiorPolygons = [decoder decodeObjectOfClass:[NSArray class] forKey:@"interiorPolygons"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder { - [super encodeWithCoder:coder]; - [coder encodeObject:self.interiorPolygons forKey:@"interiorPolygons"]; -} - -- (BOOL)isEqual:(id)other { - if (self == other) return YES; - if (![other isKindOfClass:[MGLPolygon class]]) return NO; - - MGLPolygon *otherPolygon = (MGLPolygon *)other; - return ([super isEqual:otherPolygon] && - [[self geoJSONDictionary] isEqualToDictionary:[otherPolygon geoJSONDictionary]]); -} - -- (NSUInteger)hash { - return [super hash] + [[self geoJSONDictionary] hash]; -} - -- (CLLocationCoordinate2D)coordinate { - // pole of inaccessibility - auto poi = mapbox::polylabel([self polygon]); - - return MGLLocationCoordinate2DFromPoint(poi); -} - -- (mbgl::LinearRing<double>)ring { - NSUInteger count = self.pointCount; - CLLocationCoordinate2D *coordinates = self.coordinates; - - mbgl::LinearRing<double> result; - result.reserve(self.pointCount); - for (NSUInteger i = 0; i < count; i++) { - result.push_back(mbgl::Point<double>(coordinates[i].longitude, coordinates[i].latitude)); - } - return result; -} - -- (mbgl::Polygon<double>)polygon { - mbgl::Polygon<double> geometry; - geometry.push_back(self.ring); - for (MGLPolygon *polygon in self.interiorPolygons) { - geometry.push_back(polygon.ring); - } - return geometry; -} - -- (mbgl::Geometry<double>)geometryObject { - return [self polygon]; -} - -- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate { - - mbgl::FillAnnotation annotation { [self polygon] }; - annotation.opacity = { static_cast<float>([delegate alphaForShapeAnnotation:self]) }; - annotation.outlineColor = { [delegate strokeColorForShapeAnnotation:self] }; - annotation.color = { [delegate fillColorForPolygonAnnotation:self] }; - - return annotation; -} - -- (NSDictionary *)geoJSONDictionary { - return @{@"type": @"Polygon", - @"coordinates": self.mgl_coordinates}; -} - -- (NSArray<id> *)mgl_coordinates { - NSMutableArray *coordinates = [NSMutableArray array]; - - NSMutableArray *exteriorRing = [NSMutableArray array]; - for (NSUInteger index = 0; index < self.pointCount; index++) { - CLLocationCoordinate2D coordinate = self.coordinates[index]; - [exteriorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; - } - [coordinates addObject:exteriorRing]; - - for (MGLPolygon *interiorPolygon in self.interiorPolygons) { - NSMutableArray *interiorRing = [NSMutableArray array]; - for (NSUInteger index = 0; index < interiorPolygon.pointCount; index++) { - CLLocationCoordinate2D coordinate = interiorPolygon.coordinates[index]; - [interiorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; - } - [coordinates addObject:interiorRing]; - } - - return [coordinates copy]; -} - -@end - -@interface MGLMultiPolygon () - -@property (nonatomic, copy, readwrite) NSArray<MGLPolygon *> *polygons; - -@end - -@implementation MGLMultiPolygon { - MGLCoordinateBounds _overlayBounds; -} - -@synthesize overlayBounds = _overlayBounds; - -+ (instancetype)multiPolygonWithPolygons:(NSArray<MGLPolygon *> *)polygons { - return [[self alloc] initWithPolygons:polygons]; -} - -- (instancetype)initWithPolygons:(NSArray<MGLPolygon *> *)polygons { - MGLLogDebug(@"Initializing with %lu polygons.", (unsigned long)polygons.count); - if (self = [super init]) { - _polygons = polygons; - - mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty(); - - for (MGLPolygon *polygon in _polygons) { - bounds.extend(MGLLatLngBoundsFromCoordinateBounds(polygon.overlayBounds)); - } - _overlayBounds = MGLCoordinateBoundsFromLatLngBounds(bounds); - } - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder { - MGLLogInfo(@"Initializing with coder."); - if (self = [super initWithCoder:decoder]) { - _polygons = [decoder decodeObjectOfClass:[NSArray class] forKey:@"polygons"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder { - [super encodeWithCoder:coder]; - [coder encodeObject:_polygons forKey:@"polygons"]; -} - -- (BOOL)isEqual:(id)other { - if (self == other) return YES; - if (![other isKindOfClass:[MGLMultiPolygon class]]) return NO; - - MGLMultiPolygon *otherMultiPolygon = other; - return [super isEqual:other] - && [self.polygons isEqualToArray:otherMultiPolygon.polygons]; -} - -- (NSUInteger)hash { - NSUInteger hash = [super hash]; - for (MGLPolygon *polygon in self.polygons) { - hash += [polygon hash]; - } - return hash; -} - -- (CLLocationCoordinate2D)coordinate { - MGLPolygon *firstPolygon = self.polygons.firstObject; - - return firstPolygon.coordinate; -} - -- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds { - return MGLCoordinateBoundsIntersectsCoordinateBounds(_overlayBounds, overlayBounds); -} - -- (mbgl::MultiPolygon<double>)multiPolygon { - mbgl::MultiPolygon<double> multiPolygon; - multiPolygon.reserve(self.polygons.count); - for (MGLPolygon *polygon in self.polygons) { - mbgl::Polygon<double> geometry; - geometry.push_back(polygon.ring); - for (MGLPolygon *interiorPolygon in polygon.interiorPolygons) { - geometry.push_back(interiorPolygon.ring); - } - multiPolygon.push_back(geometry); - } - return multiPolygon; -} - -- (mbgl::Geometry<double>)geometryObject { - return [self multiPolygon]; -} - -- (NSDictionary *)geoJSONDictionary { - NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.polygons.count]; - for (MGLPolygonFeature *feature in self.polygons) { - [coordinates addObject: feature.mgl_coordinates]; - } - return @{@"type": @"MultiPolygon", - @"coordinates": coordinates}; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; title = %@, subtitle: = %@, count = %lu; bounds = %@>", - NSStringFromClass([self class]), (void *)self, - self.title ? [NSString stringWithFormat:@"\"%@\"", self.title] : self.title, - self.subtitle ? [NSString stringWithFormat:@"\"%@\"", self.subtitle] : self.subtitle, - (unsigned long)self.polygons.count, - MGLStringFromCoordinateBounds(self.overlayBounds)]; -} - -@end diff --git a/platform/darwin/src/MGLPolygon_Private.h b/platform/darwin/src/MGLPolygon_Private.h deleted file mode 100644 index b006f2d77f..0000000000 --- a/platform/darwin/src/MGLPolygon_Private.h +++ /dev/null @@ -1,11 +0,0 @@ -#import "MGLPolygon.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLPolygon (Private) - -- (NSArray<id> *)mgl_coordinates; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLPolyline.h b/platform/darwin/src/MGLPolyline.h deleted file mode 100644 index 9efaea24ff..0000000000 --- a/platform/darwin/src/MGLPolyline.h +++ /dev/null @@ -1,112 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import "MGLFoundation.h" -#import "MGLMultiPoint.h" -#import "MGLOverlay.h" - -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An `MGLPolyline` object represents a shape consisting of two or more vertices, - specified as `CLLocationCoordinate2D` instances, and the line segments that - connect them. For example, you could use an polyline to represent a road or the - path along which something moves. - - You can add polyline shapes to the map by adding them to an `MGLShapeSource` - object. Configure the appearance of an `MGLShapeSource`’s or - `MGLVectorTileSource`’s polylines collectively using an `MGLLineStyleLayer` or - `MGLSymbolStyleLayer` object. To access a polyline’s attributes, use an - `MGLPolylineFeature` object. - - Alternatively, you can add a polyline overlay directly to a map view using the - `-[MGLMapView addAnnotation:]` or `-[MGLMapView addOverlay:]` method. Configure - a polyline overlay’s appearance using - `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` and - `-[MGLMapViewDelegate mapView:lineWidthForPolylineAnnotation:]`. - - The vertices are automatically connected in the order in which you provide - them. The first and last vertices are not connected to each other, but you can - specify the same `CLLocationCoordinate2D` as the first and last vertices in - order to close the polyline. To fill the space within the shape, use an - `MGLPolygon` object. To group multiple polylines together in one shape, use an - `MGLMultiPolyline` or `MGLShapeCollection` object. - - To make the polyline go across the antimeridian or international date line, - specify some longitudes less than −180 degrees or greater than 180 degrees. - For example, a polyline that stretches from Tokyo to San Francisco would have - coordinates of (35.68476, -220.24257) and (37.78428, -122.41310). - - ```swift - let coordinates = [ - CLLocationCoordinate2D(latitude: 35.68476, longitude: -220.24257), - CLLocationCoordinate2D(latitude: 37.78428, longitude: -122.41310) - ] - let polyline = MGLPolyline(coordinates: coordinates, count: UInt(coordinates.count)) - ``` - - A polyline is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.1.4">LineString</a> - geometry in GeoJSON. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/annotation-models/"> - Annotation models</a> example to learn how to add an `MGLPolyine` object to - your map. - */ -MGL_EXPORT -@interface MGLPolyline : MGLMultiPoint <MGLOverlay> - -/** - Creates and returns an `MGLPolyline` object from the specified set of - coordinates. - - @param coords The array of coordinates defining the shape. The data in this - array is copied to the new object. - @param count The number of items in the `coords` array. - @return A new polyline object. - */ -+ (instancetype)polylineWithCoordinates:(const CLLocationCoordinate2D *)coords count:(NSUInteger)count; - -@end - -/** - An `MGLMultiPolyline` object represents a shape consisting of one or more - polylines. For example, you could use a multipolyline shape to represent both - sides of a divided highway (dual carriageway), excluding the median (central - reservation): each carriageway would be a distinct `MGLPolyline` object. - - You can add multipolyline shapes to the map by adding them to an - `MGLShapeSource` object. Configure the appearance of an `MGLShapeSource`’s or - `MGLVectorTileSource`’s multipolylines collectively using an - `MGLLineStyleLayer` or `MGLSymbolStyleLayer` object. - - You cannot add an `MGLMultiPolyline` object directly to a map view using - `-[MGLMapView addAnnotation:]` or `-[MGLMapView addOverlay:]`. However, you can - add the `polylines` array’s items as overlays individually. - - A multipolyline is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.1.5">MultiLineString</a> - geometry in GeoJSON. - */ -MGL_EXPORT -@interface MGLMultiPolyline : MGLShape <MGLOverlay> - -/** - An array of polygons forming the multipolyline. - */ -@property (nonatomic, copy, readonly) NSArray<MGLPolyline *> *polylines; - -/** - Creates and returns a multipolyline object consisting of the given polylines. - - @param polylines The array of polylines defining the shape. - @return A new multipolyline object. - */ -+ (instancetype)multiPolylineWithPolylines:(NSArray<MGLPolyline *> *)polylines; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm deleted file mode 100644 index 25c540b527..0000000000 --- a/platform/darwin/src/MGLPolyline.mm +++ /dev/null @@ -1,228 +0,0 @@ -#import "MGLPolyline_Private.h" - -#import "MGLMultiPoint_Private.h" -#import "MGLGeometry_Private.h" - -#import "MGLFeature.h" -#import "MGLLoggingConfiguration_Private.h" - -#import <mbgl/util/geojson.hpp> -#import <mapbox/polylabel.hpp> - -@implementation MGLPolyline - -@dynamic overlayBounds; - -+ (instancetype)polylineWithCoordinates:(const CLLocationCoordinate2D *)coords - count:(NSUInteger)count -{ - return [[self alloc] initWithCoordinates:coords count:count]; -} - -- (mbgl::LineString<double>)lineString { - NSUInteger count = self.pointCount; - CLLocationCoordinate2D *coordinates = self.coordinates; - - mbgl::LineString<double> geometry; - geometry.reserve(self.pointCount); - for (NSUInteger i = 0; i < count; i++) { - geometry.push_back(mbgl::Point<double>(coordinates[i].longitude, coordinates[i].latitude)); - } - - return geometry; -} - -- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate { - mbgl::LineAnnotation annotation { [self lineString] }; - annotation.opacity = { static_cast<float>([delegate alphaForShapeAnnotation:self]) }; - annotation.color = { [delegate strokeColorForShapeAnnotation:self] }; - annotation.width = { static_cast<float>([delegate lineWidthForPolylineAnnotation:self]) }; - - return annotation; -} - -- (mbgl::Geometry<double>)geometryObject { - return [self lineString]; -} - -- (NSDictionary *)geoJSONDictionary { - return @{@"type": @"LineString", - @"coordinates": self.mgl_coordinates}; -} - -- (NSArray<id> *)mgl_coordinates { - NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount]; - for (NSUInteger index = 0; index < self.pointCount; index++) { - CLLocationCoordinate2D coordinate = self.coordinates[index]; - [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]]; - } - return [coordinates copy]; -} - -- (BOOL)isEqual:(id)other { - return self == other || ([other isKindOfClass:[MGLPolyline class]] && [super isEqual:other]); -} - -- (CLLocationCoordinate2D)coordinate { - NSUInteger count = self.pointCount; - MGLAssert(count > 0, @"Polyline must have coordinates"); - - CLLocationCoordinate2D *coordinates = self.coordinates; - CLLocationDistance middle = [self length] / 2.0; - CLLocationDistance traveled = 0.0; - - if (count > 1 || middle > traveled) { - for (NSUInteger i = 0; i < count; i++) { - - // Avoid a heap buffer overflow when there are only two coordinates. - NSUInteger nextIndex = (i + 1 == count) ? 0 : 1; - - MGLRadianCoordinate2D from = MGLRadianCoordinateFromLocationCoordinate(coordinates[i]); - MGLRadianCoordinate2D to = MGLRadianCoordinateFromLocationCoordinate(coordinates[i + nextIndex]); - - if (traveled >= middle) { - double overshoot = middle - traveled; - if (overshoot == 0) { - return coordinates[i]; - } - to = MGLRadianCoordinateFromLocationCoordinate(coordinates[i - 1]); - CLLocationDirection direction = [self direction:from to:to] - 180; - MGLRadianCoordinate2D otherCoordinate = MGLRadianCoordinateAtDistanceFacingDirection(from, - overshoot/mbgl::util::EARTH_RADIUS_M, - MGLRadiansFromDegrees(direction)); - return CLLocationCoordinate2DMake(MGLDegreesFromRadians(otherCoordinate.latitude), - MGLDegreesFromRadians(otherCoordinate.longitude)); - } - - traveled += (MGLDistanceBetweenRadianCoordinates(from, to) * mbgl::util::EARTH_RADIUS_M); - } - } - - return coordinates[count - 1]; -} - -- (CLLocationDistance)length -{ - CLLocationDistance length = 0.0; - - NSUInteger count = self.pointCount; - CLLocationCoordinate2D *coordinates = self.coordinates; - - for (NSUInteger i = 0; i < count - 1; i++) { - length += (MGLDistanceBetweenRadianCoordinates(MGLRadianCoordinateFromLocationCoordinate(coordinates[i]), MGLRadianCoordinateFromLocationCoordinate(coordinates[i + 1])) * mbgl::util::EARTH_RADIUS_M); - } - - return length; -} - -- (CLLocationDirection)direction:(MGLRadianCoordinate2D)from to:(MGLRadianCoordinate2D)to -{ - return MGLDegreesFromRadians(MGLRadianCoordinatesDirection(from, to)); -} - -@end - -@interface MGLMultiPolyline () - -@property (nonatomic, copy, readwrite) NSArray<MGLPolyline *> *polylines; - -@end - -@implementation MGLMultiPolyline { - MGLCoordinateBounds _overlayBounds; -} - -@synthesize overlayBounds = _overlayBounds; - -+ (instancetype)multiPolylineWithPolylines:(NSArray<MGLPolyline *> *)polylines { - return [[self alloc] initWithPolylines:polylines]; -} - -- (instancetype)initWithPolylines:(NSArray<MGLPolyline *> *)polylines { - MGLLogDebug(@"Initializing with %lu polylines.", (unsigned long)polylines.count); - if (self = [super init]) { - _polylines = polylines; - - mbgl::LatLngBounds bounds = mbgl::LatLngBounds::empty(); - - for (MGLPolyline *polyline in _polylines) { - bounds.extend(MGLLatLngBoundsFromCoordinateBounds(polyline.overlayBounds)); - } - _overlayBounds = MGLCoordinateBoundsFromLatLngBounds(bounds); - } - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder { - MGLLogInfo(@"Initializing with coder."); - if (self = [super initWithCoder:decoder]) { - _polylines = [decoder decodeObjectOfClass:[NSArray class] forKey:@"polylines"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder { - [super encodeWithCoder:coder]; - [coder encodeObject:_polylines forKey:@"polylines"]; -} - -- (BOOL)isEqual:(id)other -{ - if (self == other) return YES; - if (![other isKindOfClass:[MGLMultiPolyline class]]) return NO; - - MGLMultiPolyline *otherMultipoline = other; - return ([super isEqual:otherMultipoline] - && [self.polylines isEqualToArray:otherMultipoline.polylines]); -} - -- (NSUInteger)hash { - NSUInteger hash = [super hash]; - for (MGLPolyline *polyline in self.polylines) { - hash += [polyline hash]; - } - return hash; -} - -- (CLLocationCoordinate2D)coordinate { - MGLPolyline *polyline = self.polylines.firstObject; - CLLocationCoordinate2D *coordinates = polyline.coordinates; - MGLAssert([polyline pointCount] > 0, @"Polyline must have coordinates"); - CLLocationCoordinate2D firstCoordinate = coordinates[0]; - - return firstCoordinate; -} - -- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds { - return MGLCoordinateBoundsIntersectsCoordinateBounds(_overlayBounds, overlayBounds); -} - -- (mbgl::Geometry<double>)geometryObject { - mbgl::MultiLineString<double> multiLineString; - multiLineString.reserve(self.polylines.count); - for (MGLPolyline *polyline in self.polylines) { - multiLineString.push_back([polyline lineString]); - } - return multiLineString; -} - -- (NSDictionary *)geoJSONDictionary { - NSMutableArray *coordinates = [NSMutableArray array]; - for (MGLPolylineFeature *feature in self.polylines) { - [coordinates addObject: feature.mgl_coordinates]; - } - return @{@"type": @"MultiLineString", - @"coordinates": coordinates}; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; title = %@, subtitle: = %@, count = %lu; bounds = %@>", - NSStringFromClass([self class]), (void *)self, - self.title ? [NSString stringWithFormat:@"\"%@\"", self.title] : self.title, - self.subtitle ? [NSString stringWithFormat:@"\"%@\"", self.subtitle] : self.subtitle, - (unsigned long)self.polylines.count, - MGLStringFromCoordinateBounds(self.overlayBounds)]; -} - -@end diff --git a/platform/darwin/src/MGLPolyline_Private.h b/platform/darwin/src/MGLPolyline_Private.h deleted file mode 100644 index ff4fabaa78..0000000000 --- a/platform/darwin/src/MGLPolyline_Private.h +++ /dev/null @@ -1,12 +0,0 @@ -#import "MGLPolyline.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLPolyline (Private) - -- (NSArray<id> *)mgl_coordinates; - -@end - -NS_ASSUME_NONNULL_END - diff --git a/platform/darwin/src/MGLRasterDEMSource.h b/platform/darwin/src/MGLRasterDEMSource.h deleted file mode 100644 index 18ad802564..0000000000 --- a/platform/darwin/src/MGLRasterDEMSource.h +++ /dev/null @@ -1,50 +0,0 @@ -#import "MGLFoundation.h" - -#import "MGLRasterTileSource.h" - -/** - An `NSNumber` object containing an unsigned integer that specifies the encoding - formula for raster-dem tilesets. The integer corresponds to one of - the constants described in `MGLDEMEncoding`. - - The default value for this option is `MGLDEMEncodingMapbox`. - - This option cannot be represented in a TileJSON or style JSON file. It is used - with the `MGLRasterDEMSource` class and is ignored when creating an - `MGLRasterTileSource` or `MGLVectorTileSource` object. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionDEMEncoding; - -/** - `MGLRasterDEMSource` is a map content source that supplies rasterized - <a href="https://en.wikipedia.org/wiki/Digital_elevation_model">digital elevation model</a> - (DEM) tiles to be shown on the map. The location of and metadata about the - tiles are defined either by an option dictionary or by an external file that - conforms to the - <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>. - A raster DEM source is added to an `MGLStyle` object along with one or more - `MGLHillshadeStyleLayer` objects. Use a hillshade style layer to control the - appearance of content supplied by the raster DEM source. - - Each - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-raster-dem"><code>raster-dem</code></a> - source defined by the style JSON file is represented at runtime by an - `MGLRasterDEMSource` object that you can use to initialize new style layers. - You can also add and remove sources dynamically using methods such as - `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`. - - Currently, raster DEM sources only support the format used by - <a href="https://docs.mapbox.com/help/troubleshooting/access-elevation-data/#mapbox-terrain-rgb">Mapbox Terrain-RGB</a>. - - ### Example - - ```swift - let terrainRGBURL = URL(string: "mapbox://mapbox.terrain-rgb")! - let source = MGLRasterDEMSource(identifier: "hills", configurationURL: terrainRGBURL) - mapView.style?.addSource(source) - ``` - */ -MGL_EXPORT -@interface MGLRasterDEMSource : MGLRasterTileSource - -@end diff --git a/platform/darwin/src/MGLRasterDEMSource.mm b/platform/darwin/src/MGLRasterDEMSource.mm deleted file mode 100644 index 753499ff94..0000000000 --- a/platform/darwin/src/MGLRasterDEMSource.mm +++ /dev/null @@ -1,16 +0,0 @@ -#import "MGLRasterDEMSource.h" - -#import "MGLRasterTileSource_Private.h" -#import "NSURL+MGLAdditions.h" - -#import <mbgl/style/sources/raster_dem_source.hpp> - -@implementation MGLRasterDEMSource - -- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier urlOrTileset:(mbgl::variant<std::string, mbgl::Tileset>)urlOrTileset tileSize:(uint16_t)tileSize { - auto source = std::make_unique<mbgl::style::RasterDEMSource>(identifier.UTF8String, - urlOrTileset, - tileSize); - return source; -} -@end diff --git a/platform/darwin/src/MGLRasterStyleLayer.h b/platform/darwin/src/MGLRasterStyleLayer.h deleted file mode 100644 index 87cf5be1b8..0000000000 --- a/platform/darwin/src/MGLRasterStyleLayer.h +++ /dev/null @@ -1,347 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLForegroundStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - The resampling/interpolation method to use for overscaling, also known as - texture magnification filter - - Values of this type are used in the `MGLRasterStyleLayer.rasterResamplingMode` - property. - */ -typedef NS_ENUM(NSUInteger, MGLRasterResamplingMode) { - /** - (Bi)linear filtering interpolates point values using the weighted average - of the four closest original source points creating a smooth but blurry - look when overscaled - */ - MGLRasterResamplingModeLinear, - /** - Nearest neighbor filtering interpolates point values using the nearest - original source point creating a sharp but pointated look when overscaled - */ - MGLRasterResamplingModeNearest, -}; - -/** - An `MGLRasterStyleLayer` is a style layer that renders georeferenced raster - imagery on the map, especially raster tiles. - - Use a raster style layer to configure the color parameters of raster tiles - loaded by an `MGLRasterTileSource` object or raster images loaded by an - `MGLImageSource` object. For example, you could use a raster style layer to - render <a href="https://www.mapbox.com/satellite/">Mapbox Satellite</a> - imagery, a <a - href="https://docs.mapbox.com/help/glossary/tileset/#raster-tilesets">raster - tile set</a> uploaded to Mapbox Studio, or a raster map authored in <a - href="https://tilemill-project.github.io/tilemill/">TileMill</a>, the classic - Mapbox Editor, or Mapbox Studio Classic. - - Raster images may also be used as icons or patterns in a style layer. To - register an image for use as an icon or pattern, use the `-[MGLStyle - setImage:forName:]` method. To configure a point annotation’s image, use the - `MGLAnnotationImage` class. - - You can access an existing raster style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new raster style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/image-source/">Add - an image</a> and <a - href="https://docs.mapbox.com/ios/maps/examples/source-custom-raster/">Add - raster imagery</a> examples to learn how to add imagery with this style layer. - - ### Example - - ```swift - let layer = MGLRasterStyleLayer(identifier: "clouds", source: source) - layer.rasterOpacity = NSExpression(forConstantValue: 0.5) - mapView.style?.addLayer(layer) - ``` - */ -MGL_EXPORT -@interface MGLRasterStyleLayer : MGLForegroundStyleLayer - -/** - Returns a raster style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; - -#pragma mark - Accessing the Paint Attributes - -/** - Increase or reduce the brightness of the image. The value is the maximum - brightness. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-raster-brightness-max"><code>raster-brightness-max</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *maximumRasterBrightness; - -/** - The transition affecting any changes to this layer’s `maximumRasterBrightness` property. - - This property corresponds to the `raster-brightness-max-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition maximumRasterBrightnessTransition; - -@property (nonatomic, null_resettable) NSExpression *rasterBrightnessMax __attribute__((unavailable("Use maximumRasterBrightness instead."))); - -/** - Increase or reduce the brightness of the image. The value is the minimum - brightness. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-raster-brightness-min"><code>raster-brightness-min</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *minimumRasterBrightness; - -/** - The transition affecting any changes to this layer’s `minimumRasterBrightness` property. - - This property corresponds to the `raster-brightness-min-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition minimumRasterBrightnessTransition; - -@property (nonatomic, null_resettable) NSExpression *rasterBrightnessMin __attribute__((unavailable("Use minimumRasterBrightness instead."))); - -/** - Increase or reduce the contrast of the image. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between −1 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *rasterContrast; - -/** - The transition affecting any changes to this layer’s `rasterContrast` property. - - This property corresponds to the `raster-contrast-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition rasterContrastTransition; - -/** - Fade duration when a new tile is added. - - This property is measured in milliseconds. - - The default value of this property is an expression that evaluates to the float - `300`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *rasterFadeDuration; - -/** - Rotates hues around the color wheel. - - This property is measured in degrees. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-raster-hue-rotate"><code>raster-hue-rotate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *rasterHueRotation; - -/** - The transition affecting any changes to this layer’s `rasterHueRotation` property. - - This property corresponds to the `raster-hue-rotate-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition rasterHueRotationTransition; - -@property (nonatomic, null_resettable) NSExpression *rasterHueRotate __attribute__((unavailable("Use rasterHueRotation instead."))); - -/** - The opacity at which the image will be drawn. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *rasterOpacity; - -/** - The transition affecting any changes to this layer’s `rasterOpacity` property. - - This property corresponds to the `raster-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition rasterOpacityTransition; - -/** - The resampling/interpolation method to use for overscaling, also known as - texture magnification filter - - The default value of this property is an expression that evaluates to `linear`. - Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-raster-resampling"><code>raster-resampling</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLRasterResamplingMode` values - * Any of the following constant string values: - * `linear`: (Bi)linear filtering interpolates pixel values using the weighted - average of the four closest original source pixels creating a smooth but blurry - look when overscaled - * `nearest`: Nearest neighbor filtering interpolates pixel values using the - nearest original source pixel creating a sharp but pixelated look when - overscaled - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *rasterResamplingMode; - -@property (nonatomic, null_resettable) NSExpression *rasterResampling __attribute__((unavailable("Use rasterResamplingMode instead."))); - -/** - Increase or reduce the saturation of the image. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between −1 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *rasterSaturation; - -/** - The transition affecting any changes to this layer’s `rasterSaturation` property. - - This property corresponds to the `raster-saturation-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition rasterSaturationTransition; - -@end - -/** - Methods for wrapping an enumeration value for a style layer attribute in an - `MGLRasterStyleLayer` object and unwrapping its raw value. - */ -@interface NSValue (MGLRasterStyleLayerAdditions) - -#pragma mark Working with Raster Style Layer Attribute Values - -/** - Creates a new value object containing the given `MGLRasterResamplingMode` enumeration. - - @param rasterResamplingMode The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLRasterResamplingMode:(MGLRasterResamplingMode)rasterResamplingMode; - -/** - The `MGLRasterResamplingMode` enumeration representation of the value. - */ -@property (readonly) MGLRasterResamplingMode MGLRasterResamplingModeValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLRasterStyleLayer.mm b/platform/darwin/src/MGLRasterStyleLayer.mm deleted file mode 100644 index 2198d441d1..0000000000 --- a/platform/darwin/src/MGLRasterStyleLayer.mm +++ /dev/null @@ -1,339 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLRasterStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLRasterStyleLayer_Private.h" - -#include <mbgl/style/layers/raster_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLRasterResamplingMode, { - { MGLRasterResamplingModeLinear, "linear" }, - { MGLRasterResamplingModeNearest, "nearest" }, - }); - -} - -@interface MGLRasterStyleLayer () - -@property (nonatomic, readonly) mbgl::style::RasterLayer *rawLayer; - -@end - -@implementation MGLRasterStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::RasterLayer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::RasterLayer *)rawLayer -{ - return (mbgl::style::RasterLayer *)super.rawLayer; -} - -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setMaximumRasterBrightness:(NSExpression *)maximumRasterBrightness { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting maximumRasterBrightness: %@", maximumRasterBrightness); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(maximumRasterBrightness, false); - self.rawLayer->setRasterBrightnessMax(mbglValue); -} - -- (NSExpression *)maximumRasterBrightness { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getRasterBrightnessMax(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultRasterBrightnessMax(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setMaximumRasterBrightnessTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting maximumRasterBrightnessTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setRasterBrightnessMaxTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)maximumRasterBrightnessTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getRasterBrightnessMaxTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setRasterBrightnessMax:(NSExpression *)rasterBrightnessMax { -} - -- (NSExpression *)rasterBrightnessMax { - return self.maximumRasterBrightness; -} - -- (void)setMinimumRasterBrightness:(NSExpression *)minimumRasterBrightness { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting minimumRasterBrightness: %@", minimumRasterBrightness); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(minimumRasterBrightness, false); - self.rawLayer->setRasterBrightnessMin(mbglValue); -} - -- (NSExpression *)minimumRasterBrightness { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getRasterBrightnessMin(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultRasterBrightnessMin(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setMinimumRasterBrightnessTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting minimumRasterBrightnessTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setRasterBrightnessMinTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)minimumRasterBrightnessTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getRasterBrightnessMinTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setRasterBrightnessMin:(NSExpression *)rasterBrightnessMin { -} - -- (NSExpression *)rasterBrightnessMin { - return self.minimumRasterBrightness; -} - -- (void)setRasterContrast:(NSExpression *)rasterContrast { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterContrast: %@", rasterContrast); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(rasterContrast, false); - self.rawLayer->setRasterContrast(mbglValue); -} - -- (NSExpression *)rasterContrast { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getRasterContrast(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultRasterContrast(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setRasterContrastTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterContrastTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setRasterContrastTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)rasterContrastTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getRasterContrastTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setRasterFadeDuration:(NSExpression *)rasterFadeDuration { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterFadeDuration: %@", rasterFadeDuration); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(rasterFadeDuration, false); - self.rawLayer->setRasterFadeDuration(mbglValue); -} - -- (NSExpression *)rasterFadeDuration { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getRasterFadeDuration(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultRasterFadeDuration(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setRasterHueRotation:(NSExpression *)rasterHueRotation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterHueRotation: %@", rasterHueRotation); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(rasterHueRotation, false); - self.rawLayer->setRasterHueRotate(mbglValue); -} - -- (NSExpression *)rasterHueRotation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getRasterHueRotate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultRasterHueRotate(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setRasterHueRotationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterHueRotationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setRasterHueRotateTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)rasterHueRotationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getRasterHueRotateTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setRasterHueRotate:(NSExpression *)rasterHueRotate { -} - -- (NSExpression *)rasterHueRotate { - return self.rasterHueRotation; -} - -- (void)setRasterOpacity:(NSExpression *)rasterOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterOpacity: %@", rasterOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(rasterOpacity, false); - self.rawLayer->setRasterOpacity(mbglValue); -} - -- (NSExpression *)rasterOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getRasterOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultRasterOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setRasterOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setRasterOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)rasterOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getRasterOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setRasterResamplingMode:(NSExpression *)rasterResamplingMode { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterResamplingMode: %@", rasterResamplingMode); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::RasterResamplingType, NSValue *, mbgl::style::RasterResamplingType, MGLRasterResamplingMode>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::RasterResamplingType>>(rasterResamplingMode, false); - self.rawLayer->setRasterResampling(mbglValue); -} - -- (NSExpression *)rasterResamplingMode { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getRasterResampling(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultRasterResampling(); - } - return MGLStyleValueTransformer<mbgl::style::RasterResamplingType, NSValue *, mbgl::style::RasterResamplingType, MGLRasterResamplingMode>().toExpression(propertyValue); -} - -- (void)setRasterResampling:(NSExpression *)rasterResampling { -} - -- (NSExpression *)rasterResampling { - return self.rasterResamplingMode; -} - -- (void)setRasterSaturation:(NSExpression *)rasterSaturation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterSaturation: %@", rasterSaturation); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(rasterSaturation, false); - self.rawLayer->setRasterSaturation(mbglValue); -} - -- (NSExpression *)rasterSaturation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getRasterSaturation(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultRasterSaturation(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setRasterSaturationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting rasterSaturationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setRasterSaturationTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)rasterSaturationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getRasterSaturationTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -@end - -@implementation NSValue (MGLRasterStyleLayerAdditions) - -+ (NSValue *)valueWithMGLRasterResamplingMode:(MGLRasterResamplingMode)rasterResamplingMode { - return [NSValue value:&rasterResamplingMode withObjCType:@encode(MGLRasterResamplingMode)]; -} - -- (MGLRasterResamplingMode)MGLRasterResamplingModeValue { - MGLRasterResamplingMode rasterResamplingMode; - [self getValue:&rasterResamplingMode]; - return rasterResamplingMode; -} - -@end - -namespace mbgl { - -MGLStyleLayer* RasterStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLRasterStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLRasterStyleLayer_Private.h b/platform/darwin/src/MGLRasterStyleLayer_Private.h deleted file mode 100644 index 7b123ed888..0000000000 --- a/platform/darwin/src/MGLRasterStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/raster_layer_factory.hpp> - -namespace mbgl { - -class RasterStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::RasterLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLRasterTileSource.h b/platform/darwin/src/MGLRasterTileSource.h deleted file mode 100644 index a8d0a470e0..0000000000 --- a/platform/darwin/src/MGLRasterTileSource.h +++ /dev/null @@ -1,139 +0,0 @@ -#import <CoreGraphics/CoreGraphics.h> - -#import "MGLFoundation.h" -#import "MGLTileSource.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An `NSNumber` object containing a floating-point number that specifies the - width and height (measured in points) at which the map displays each raster - image tile when the map’s zoom level is an integer. The raster tile source - scales its images up or down when the map’s zoom level falls between two - integers. - - The default value for this option is 512. Version 4 of the - <a href="https://docs.mapbox.com/api/maps/#raster-tiles">Mapbox Raster Tiles API</a> - requires a value of 256, as do many third-party tile servers, so consult your - provider’s documentation for the correct value. - - This option is only applicable to `MGLRasterTileSource` objects; it is ignored - when initializing `MGLVectorTileSource` objects. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionTileSize; - -/** - `MGLRasterTileSource` is a map content source that supplies raster image tiles - to be shown on the map. The location of and metadata about the tiles are - defined either by an option dictionary or by an external file that conforms to - the - <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>. - A raster tile source is added to an `MGLStyle` object along with one or more - `MGLRasterStyleLayer` objects. Use a raster style layer to control the - appearance of content supplied by the raster tile source. - - Each - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-raster"><code>raster</code></a> - source defined by the style JSON file is represented at runtime by an - `MGLRasterTileSource` object that you can use to initialize new style layers. You - can also add and remove sources dynamically using methods such as - `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`. - - ### Example - - ```swift - let source = MGLRasterTileSource(identifier: "clouds", tileURLTemplates: ["https://example.com/raster-tiles/{z}/{x}/{y}.png"], options: [ - .minimumZoomLevel: 9, - .maximumZoomLevel: 16, - .tileSize: 512, - .attributionInfos: [ - MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "https://mapbox.com")) - ] - ]) - mapView.style?.addSource(source) - ``` - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/source-custom-raster/"> - Add raster imagery</a> example to learn how to add a `MGLRasterStyleLayer` - to your map using an `MGLRasterTileSource`. - */ -MGL_EXPORT -@interface MGLRasterTileSource : MGLTileSource - -#pragma mark Initializing a Source - -/** - Returns a raster tile source initialized with an identifier and configuration - URL. - - After initializing and configuring the source, add it to a map view’s style - using the `-[MGLStyle addSource:]` method. - - The URL may be a full HTTP or HTTPS URL or, for tilesets hosted by Mapbox, a - Mapbox URL indicating a tileset ID (`mapbox://<tilesetid>`). The URL should - point to a JSON file that conforms to the - <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>. - - If a Mapbox URL is specified, this source uses a tile size of 256. For all - other tilesets, the default value is 512. (See the - `MGLTileSourceOptionTileSize` documentation for more information about tile - sizes.) If you need to use a tile size other than the default, use the - `-initWithIdentifier:configurationURL:tileSize:` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param configurationURL A URL to a TileJSON configuration file describing the - source’s contents and other metadata. - @return An initialized raster tile source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL; - -/** - Returns a raster tile source initialized with an identifier, configuration URL, - and tile size. - - After initializing and configuring the source, add it to a map view’s style - using the `-[MGLStyle addSource:]` method. - - The URL may be a full HTTP or HTTPS URL or, for tilesets hosted by Mapbox, a - Mapbox URL indicating a tileset ID (`mapbox://<tilesetid>`). The URL should - point to a JSON file that conforms to the - <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param configurationURL A URL to a TileJSON configuration file describing the - source’s contents and other metadata. - @param tileSize The width and height (measured in points) of each tiled image - in the raster tile source. See the `MGLTileSourceOptionTileSize` - documentation for details. - @return An initialized raster tile source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize NS_DESIGNATED_INITIALIZER; - -/** - Returns a raster tile source initialized an identifier, tile URL templates, and - options. - - Tile URL templates are strings that specify the URLs of the raster tile images - to load. See the “<a href="../tile-url-templates.html">Tile URL Templates</a>” - guide for information about the format of a tile URL template. - - After initializing and configuring the source, add it to a map view’s style - using the `-[MGLStyle addSource:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param tileURLTemplates An array of tile URL template strings. Only the first - string is used; any additional strings are ignored. - @param options A dictionary containing configuration options. See - `MGLTileSourceOption` for available keys and values. Pass in `nil` to use - the default values. - @return An initialized tile source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray<NSString *> *)tileURLTemplates options:(nullable NSDictionary<MGLTileSourceOption, id> *)options NS_DESIGNATED_INITIALIZER; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLRasterTileSource.mm b/platform/darwin/src/MGLRasterTileSource.mm deleted file mode 100644 index 80b21cc7dd..0000000000 --- a/platform/darwin/src/MGLRasterTileSource.mm +++ /dev/null @@ -1,85 +0,0 @@ -#import "MGLRasterTileSource_Private.h" - -#import "MGLLoggingConfiguration_Private.h" -#import "MGLMapView_Private.h" -#import "MGLSource_Private.h" -#import "MGLTileSource_Private.h" -#import "NSURL+MGLAdditions.h" - -#include <mbgl/map/map.hpp> -#include <mbgl/style/sources/raster_source.hpp> - -const MGLTileSourceOption MGLTileSourceOptionTileSize = @"MGLTileSourceOptionTileSize"; - -static const CGFloat MGLRasterTileSourceClassicTileSize = 256; -static const CGFloat MGLRasterTileSourceRetinaTileSize = 512; - -@interface MGLRasterTileSource () - -@property (nonatomic, readonly) mbgl::style::RasterSource *rawSource; - -@end - -@implementation MGLRasterTileSource - -- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL { - // The style specification default is 512, but 256 is the expected value for - // any tile set that would be accessed through a mapbox: URL and therefore - // any tile URL that this option currently affects. - BOOL isMapboxURL = ([configurationURL.scheme isEqualToString:@"mapbox"] - && [configurationURL.host containsString:@"."] - && (!configurationURL.path.length || [configurationURL.path isEqualToString:@"/"])); - CGFloat tileSize = isMapboxURL ? MGLRasterTileSourceClassicTileSize : MGLRasterTileSourceRetinaTileSize; - return [self initWithIdentifier:identifier configurationURL:configurationURL tileSize:tileSize]; -} - -- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize { - NSString *configurationURLString = configurationURL.mgl_URLByStandardizingScheme.absoluteString; - auto source = [self pendingSourceWithIdentifier:identifier urlOrTileset:configurationURLString.UTF8String tileSize:uint16_t(round(tileSize))]; - return self = [super initWithPendingSource:std::move(source)]; -} - -- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier urlOrTileset:(mbgl::variant<std::string, mbgl::Tileset>)urlOrTileset tileSize:(uint16_t)tileSize { - auto source = std::make_unique<mbgl::style::RasterSource>(identifier.UTF8String, - urlOrTileset, - tileSize); - return source; -} - -- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray<NSString *> *)tileURLTemplates options:(nullable NSDictionary<MGLTileSourceOption, id> *)options { - mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options); - - uint16_t tileSize = MGLRasterTileSourceRetinaTileSize; - if (NSNumber *tileSizeNumber = options[MGLTileSourceOptionTileSize]) { - if (![tileSizeNumber isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionTileSize must be set to an NSNumber."]; - } - tileSize = static_cast<uint16_t>(round(tileSizeNumber.doubleValue)); - } - - auto source = [self pendingSourceWithIdentifier:identifier urlOrTileset:tileSet tileSize:tileSize]; - return self = [super initWithPendingSource:std::move(source)]; -} - -- (mbgl::style::RasterSource *)rawSource { - return (mbgl::style::RasterSource *)super.rawSource; -} - -- (NSURL *)configurationURL { - MGLAssertStyleSourceIsValid(); - auto url = self.rawSource->getURL(); - return url ? [NSURL URLWithString:@(url->c_str())] : nil; -} - -- (NSString *)attributionHTMLString { - if (!self.rawSource) { - MGLAssert(0, @"Source with identifier `%@` was invalidated after a style change", self.identifier); - return nil; - } - - auto attribution = self.rawSource->getAttribution(); - return attribution ? @(attribution->c_str()) : nil; -} - -@end diff --git a/platform/darwin/src/MGLRasterTileSource_Private.h b/platform/darwin/src/MGLRasterTileSource_Private.h deleted file mode 100644 index 55f342c7ff..0000000000 --- a/platform/darwin/src/MGLRasterTileSource_Private.h +++ /dev/null @@ -1,23 +0,0 @@ -#import "MGLRasterTileSource.h" - -#include <memory> -#include <mbgl/util/variant.hpp> - -namespace mbgl { - class Tileset; - namespace style { - class RasterSource; - } -} - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLRasterTileSource (Private) - -@property (nonatomic, readonly, nullable) mbgl::style::RasterSource *rawSource; - -- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier urlOrTileset:(mbgl::variant<std::string, mbgl::Tileset>)urlOrTileset tileSize:(uint16_t)tileSize; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLRendererConfiguration.h b/platform/darwin/src/MGLRendererConfiguration.h deleted file mode 100644 index 0c539f86f1..0000000000 --- a/platform/darwin/src/MGLRendererConfiguration.h +++ /dev/null @@ -1,54 +0,0 @@ -#import "MGLFoundation.h" -#import <Foundation/Foundation.h> - -#include <mbgl/util/optional.hpp> - -NS_ASSUME_NONNULL_BEGIN - -/** - The MGLRendererConfiguration object represents configuration values for the - renderer. - */ -MGL_EXPORT -@interface MGLRendererConfiguration : NSObject - -/** Returns an instance of the current renderer configuration. */ -@property (class, nonatomic, readonly) MGLRendererConfiguration *currentConfiguration; - -/** The scale factor to use. - - Based on the native scale where available, otherwise the standard screen scale. */ -@property (nonatomic, readonly) const float scaleFactor; - -/** The name of the font family to use for client-side text rendering of CJK ideographs. - - Set MGLIdeographicFontFamilyName in your containing application's Info.plist to - font family name(s) that will be available at run time, such as “PingFang TC” - or “Marker Felt”. This plist key accepts: - - - A string value of a single font family name. - - - An array of font family names. Fonts will be used in the defined order, - eventually falling back to default system font if none are available. - - - A boolean value NO to disable client-side rendering of CJK glyphs — - remote fonts specified in your style will be used instead. - */ -@property (nonatomic, readonly) mbgl::optional<std::string> localFontFamilyName; - -/** - A Boolean value indicating whether symbol layers may enable per-source symbol - collision detection. - - Set `MGLCollisionBehaviorPre4_0` in your containing app's Info.plist or by using - `[[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"MGLCollisionBehaviorPre4_0"]`. - If both are set, the value from `NSUserDefaults` takes priority. - - Setting this property to `YES` in the plist results in symbol layers only running - collision detection against other symbol layers that are part of the same source. - */ -@property (nonatomic, readonly) BOOL perSourceCollisions; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLRendererConfiguration.mm b/platform/darwin/src/MGLRendererConfiguration.mm deleted file mode 100644 index 136dc929a6..0000000000 --- a/platform/darwin/src/MGLRendererConfiguration.mm +++ /dev/null @@ -1,119 +0,0 @@ -#import "MGLRendererConfiguration.h" -#import "MGLOfflineStorage_Private.h" -#import "MGLFoundation_Private.h" - -#if TARGET_OS_IPHONE -#import <UIKit/UIKit.h> -#else -#import <AppKit/AppKit.h> -#endif - -static NSString * const MGLCollisionBehaviorPre4_0Key = @"MGLCollisionBehaviorPre4_0"; -static NSString * const MGLIdeographicFontFamilyNameKey = @"MGLIdeographicFontFamilyName"; - -@interface MGLRendererConfiguration () -@property (nonatomic, readwrite) BOOL perSourceCollisions; -@end - - -@implementation MGLRendererConfiguration - -+ (instancetype)currentConfiguration { - return [[self alloc] init]; -} - -- (instancetype)init { - return [self initWithPropertyDictionary:[[NSBundle mainBundle] infoDictionary]]; -} - -- (instancetype)initWithPropertyDictionary:(nonnull NSDictionary *)properties { - self = [super init]; - - if (self) { - // Set the collision behaviour. A value set in `NSUserDefaults.standardUserDefaults` - // should override anything in the application's info.plist - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - - if ([defaults objectForKey:MGLCollisionBehaviorPre4_0Key]) { - _perSourceCollisions = [defaults boolForKey:MGLCollisionBehaviorPre4_0Key]; - } - else { - id collisionBehaviourValue = properties[MGLCollisionBehaviorPre4_0Key]; - - NSNumber *collisionBehaviourNumber = MGL_OBJC_DYNAMIC_CAST(collisionBehaviourValue, NSNumber); - - if (collisionBehaviourNumber) { - _perSourceCollisions = collisionBehaviourNumber.boolValue; - } else { - // Also support NSString to correspond with the behavior of `-[NSUserDefaults boolForKey:]` - NSString *collisionBehaviourString = MGL_OBJC_DYNAMIC_CAST(collisionBehaviourValue, NSString); - - if (collisionBehaviourString) { - _perSourceCollisions = collisionBehaviourString.boolValue; - } - } - } - } - - return self; -} - -- (const float)scaleFactor { -#if TARGET_OS_IPHONE - return [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale]; -#else - return [NSScreen mainScreen].backingScaleFactor; -#endif -} - -- (mbgl::optional<std::string>)localFontFamilyName { - return [self _localFontFamilyNameWithPropertyDictionary:[[NSBundle mainBundle] infoDictionary]]; -} - -- (mbgl::optional<std::string>)_localFontFamilyNameWithPropertyDictionary:(nonnull NSDictionary *)properties { - - std::string systemFontFamilyName; -#if TARGET_OS_IPHONE - systemFontFamilyName = std::string([[UIFont systemFontOfSize:0 weight:UIFontWeightRegular].familyName UTF8String]); -#else - systemFontFamilyName = std::string([[NSFont systemFontOfSize:0 weight:NSFontWeightRegular].familyName UTF8String]); -#endif - - id fontFamilyName = properties[MGLIdeographicFontFamilyNameKey]; - - if([fontFamilyName isKindOfClass:[NSNumber class]] && ![fontFamilyName boolValue]) - { - return mbgl::optional<std::string>(); - } - else if([fontFamilyName isKindOfClass:[NSString class]]) - { - BOOL isValidFont = NO; -#if TARGET_OS_IPHONE - if([[UIFont familyNames] containsObject:fontFamilyName]){ - isValidFont = YES; - } -#else - if([[[NSFontManager sharedFontManager] availableFontFamilies] containsObject:fontFamilyName]){ - isValidFont = YES; - } -#endif - return (fontFamilyName && isValidFont) ? std::string([fontFamilyName UTF8String]) : systemFontFamilyName; - } - // Ability to specify an array of fonts for fallbacks for `localIdeographicFontFamily` - else if ([fontFamilyName isKindOfClass:[NSArray class]]){ - for(NSString *name in fontFamilyName){ -#if TARGET_OS_IPHONE - if([[UIFont familyNames] containsObject:name]){ - return std::string([name UTF8String]); - } -#else - if([[[NSFontManager sharedFontManager] availableFontFamilies] containsObject:name]){ - return std::string([name UTF8String]); - } -#endif - } - } - return systemFontFamilyName; -} - -@end diff --git a/platform/darwin/src/MGLRendererFrontend.h b/platform/darwin/src/MGLRendererFrontend.h deleted file mode 100644 index e2b8260fd1..0000000000 --- a/platform/darwin/src/MGLRendererFrontend.h +++ /dev/null @@ -1,75 +0,0 @@ -#include <mbgl/gfx/backend_scope.hpp> -#include <mbgl/renderer/renderer.hpp> -#include <mbgl/renderer/renderer_frontend.hpp> -#include <mbgl/gfx/renderer_backend.hpp> -#include <mbgl/util/async_task.hpp> -#include <mbgl/util/optional.hpp> - - -/** - The RenderFrontend is passed to the Map to facilitate rendering in a platform - dependent way. - */ -class MGLRenderFrontend : public mbgl::RendererFrontend -{ -public: - MGLRenderFrontend(std::unique_ptr<mbgl::Renderer> renderer_, MGLMapView* nativeView_, mbgl::gfx::RendererBackend& mbglBackend_, bool async = false) - : renderer(std::move(renderer_)) - , nativeView(nativeView_) - , mbglBackend(mbglBackend_) { - if (async) { - asyncInvalidate.emplace([&]() { - [nativeView setNeedsRerender]; - }); - } - } - - void reset() override { - if (renderer) { - renderer.reset(); - } - } - - void update(std::shared_ptr<mbgl::UpdateParameters> updateParameters_) override { - updateParameters = std::move(updateParameters_); - if (asyncInvalidate) { - asyncInvalidate->send(); - } else { - [nativeView setNeedsRerender]; - } - } - - void setObserver(mbgl::RendererObserver& observer) override { - if (!renderer) return; - renderer->setObserver(&observer); - } - - void render() { - if (!renderer || !updateParameters) return; - - mbgl::gfx::BackendScope guard { mbglBackend, mbgl::gfx::BackendScope::ScopeType::Implicit }; - - // onStyleImageMissing might be called during a render. The user implemented method - // could trigger a call to MGLRenderFrontend#update which overwrites `updateParameters`. - // Copy the shared pointer here so that the parameters aren't destroyed while `render(...)` is - // still using them. - auto updateParameters_ = updateParameters; - renderer->render(updateParameters_); - } - - mbgl::Renderer* getRenderer() { - return renderer.get(); - } - - void reduceMemoryUse() { - if (!renderer) return; - renderer->reduceMemoryUse(); - } - -private: - std::unique_ptr<mbgl::Renderer> renderer; - __weak MGLMapView *nativeView = nullptr; - mbgl::gfx::RendererBackend& mbglBackend; - std::shared_ptr<mbgl::UpdateParameters> updateParameters; - mbgl::optional<mbgl::util::AsyncTask> asyncInvalidate; -}; diff --git a/platform/darwin/src/MGLSDKMetricsManager.h b/platform/darwin/src/MGLSDKMetricsManager.h deleted file mode 100644 index 49b3391a72..0000000000 --- a/platform/darwin/src/MGLSDKMetricsManager.h +++ /dev/null @@ -1,79 +0,0 @@ -#import <Foundation/Foundation.h> -#import "MGLFoundation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - :nodoc: - The metrics type used to handle metrics events. - */ -typedef NS_ENUM(NSUInteger, MGLMetricType) { - /** :nodoc: - Metric that measures performance. - */ - MGLMetricTypePerformance = 0, -}; - -FOUNDATION_EXTERN MGL_EXPORT NSString* MGLStringFromMetricType(MGLMetricType metricType); - -@class MGLMetricsManager; - -/** - :nodoc: - The `MGLMetricsManagerDelegate` protocol defines a set of methods that you - can use to receive metric events. - */ -@protocol MGLMetricsManagerDelegate <NSObject> - -/** - :nodoc: - Asks the delegate whether the metrics manager should handle metric events. - - @param metricsManager The metrics manager object. - @param metricType The metric type event. - */ -- (BOOL)metricsManager:(MGLMetricsManager *)metricsManager shouldHandleMetric:(MGLMetricType)metricType; - -/** - :nodoc: - Asks the delegate to handle metric events. - - @param metricsManager The metrics manager object. - @param metricType The metric type event. - @param attributes The metric attributes. - */ -- (void)metricsManager:(MGLMetricsManager *)metricsManager didCollectMetric:(MGLMetricType)metricType withAttributes:(NSDictionary *)attributes; - -@end - -/** - :nodoc: - The `MGLMetricsManager` object provides a single poin to collect SDK metrics - such as tile download latency. - */ -MGL_EXPORT -@interface MGLMetricsManager : NSObject - -/** - :nodoc: - Returns the shared metrics manager object. - */ -@property (class, nonatomic, readonly) MGLMetricsManager *sharedManager; - -/** - :nodoc: - The metrics manager delegate that will recieve metric events. - */ -@property (nonatomic, weak) id<MGLMetricsManagerDelegate> delegate; - -#if TARGET_OS_IOS -/** - :nodoc: - Sends metric events to Mapbox. - */ -- (void)pushMetric:(MGLMetricType)metricType withAttributes:(NSDictionary *)attributes; -#endif - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLSDKMetricsManager.m b/platform/darwin/src/MGLSDKMetricsManager.m deleted file mode 100644 index 0ef9ecda10..0000000000 --- a/platform/darwin/src/MGLSDKMetricsManager.m +++ /dev/null @@ -1,134 +0,0 @@ -#import "MGLSDKMetricsManager_Private.h" -#import "MGLNetworkConfiguration_Private.h" -#if TARGET_OS_IOS -#import "MGLMapboxEvents.h" -#import <mach-o/arch.h> -#import <sys/utsname.h> -#import <UIKit/UIKit.h> -#endif - -NSString* MGLStringFromMetricType(MGLMetricType metricType) { - NSString *eventName; - - switch (metricType) { - case MGLMetricTypePerformance: - eventName = kMGLDownloadPerformanceEvent; - break; - } - return eventName; -} - -// Taken verbatim from NXFreeArchInfo header documentation -#if TARGET_OS_IOS -static void MGLFreeArchInfo(const NXArchInfo *x) -{ - const NXArchInfo *p; - - p = NXGetAllArchInfos(); - while(p->name != NULL){ - if(x == p) - return; - p++; - } - free((char *)x->description); - free((NXArchInfo *)x); -} -#endif - -@interface MGLMetricsManager() <MGLNetworkConfigurationMetricsDelegate> - -@property (strong, nonatomic) NSDictionary *metadata; - -@end - -@implementation MGLMetricsManager - -+ (instancetype)sharedManager -{ - static dispatch_once_t once; - static MGLMetricsManager *sharedConfiguration; - dispatch_once(&once, ^{ - sharedConfiguration = [[self alloc] init]; - [MGLNetworkConfiguration sharedManager].metricsDelegate = sharedConfiguration; -#if TARGET_OS_IOS - UIDevice *currentDevice = [UIDevice currentDevice]; - - NSString *osVersion = currentDevice.systemVersion; - - NSString *screenSize = [NSString stringWithFormat:@"%.fx%.f", [UIScreen mainScreen].bounds.size.width, - [UIScreen mainScreen].bounds.size.height]; - - NSLocale *currentLocale = [NSLocale currentLocale]; - - NSString *country = [currentLocale objectForKey:NSLocaleCountryCode] ?: @"unknown"; - - NSString *device = deviceName(); - - NSString *abi = @"unknown"; - - { - const NXArchInfo *localArchInfo = NXGetLocalArchInfo(); - - if (localArchInfo) { - abi = @(localArchInfo->description); - - NSProcessInfo *processInfo = [NSProcessInfo processInfo]; - - // Although NXFreeArchInfo appears to be weakly linked, it does - // not have the weak_import attribute, so check the OS version. - if (&NXFreeArchInfo && [processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){10, 0, 0}]) { - NXFreeArchInfo(localArchInfo); - } else { - MGLFreeArchInfo(localArchInfo); - } - } - } - - NSString *ram = [NSString stringWithFormat:@"%llu", [NSProcessInfo processInfo].physicalMemory]; - - NSString *os = currentDevice.systemName; - - sharedConfiguration.metadata = @{ @"version" : osVersion, - @"screenSize" : screenSize, - @"country" : country, - @"device" : device, - @"abi" : abi, - @"brand" : @"Apple", - @"ram" : ram, - @"os" : os - }; -#endif - }); - return sharedConfiguration; -} - -- (void)handleMetricsEvent:(MGLMetricType)metricType withAttributes:(NSDictionary *)attributes { - if ([self.delegate metricsManager:self shouldHandleMetric:metricType]) { - [self.delegate metricsManager:self didCollectMetric:metricType withAttributes:attributes]; - } -} - -#if TARGET_OS_IOS -- (void)pushMetric:(MGLMetricType)metricType withAttributes:(NSDictionary *)attributes { - NSString *eventName = MGLStringFromMetricType(metricType); - NSMutableDictionary *mutableAttributes = [NSMutableDictionary dictionaryWithDictionary:attributes]; - [mutableAttributes setObject:self.metadata forKey:@"metadata"]; - - [MGLMapboxEvents pushEvent:eventName withAttributes:mutableAttributes]; -} - -NSString* deviceName() -{ - struct utsname systemInfo; - uname(&systemInfo); - - return [NSString stringWithCString:systemInfo.machine - encoding:NSUTF8StringEncoding]; -} -#endif - -- (void)networkConfiguration:(MGLNetworkConfiguration *)networkConfiguration didGenerateMetricEvent:(NSDictionary *)metricEvent { - [self handleMetricsEvent:MGLMetricTypePerformance withAttributes:metricEvent]; -} - -@end diff --git a/platform/darwin/src/MGLSDKMetricsManager_Private.h b/platform/darwin/src/MGLSDKMetricsManager_Private.h deleted file mode 100644 index a3cdfca794..0000000000 --- a/platform/darwin/src/MGLSDKMetricsManager_Private.h +++ /dev/null @@ -1,11 +0,0 @@ -#import "MGLSDKMetricsManager.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLMetricsManager (Private) - -- (void)handleMetricsEvent:(MGLMetricType)metricType withAttributes:(NSDictionary *)attributes; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShape.h b/platform/darwin/src/MGLShape.h deleted file mode 100644 index 6954045fd7..0000000000 --- a/platform/darwin/src/MGLShape.h +++ /dev/null @@ -1,115 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLAnnotation.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - `MGLShape` is an abstract class that represents a shape or annotation. Shapes - constitute the content of a map — not only the overlays atop the map, but also - the content that forms the base map. - - Create instances of `MGLPointAnnotation`, `MGLPointCollection`, `MGLPolyline`, - `MGLMultiPolyline`, `MGLPolygon`, `MGLMultiPolygon`, or `MGLShapeCollection` in - order to use `MGLShape`'s methods. Do not create instances of `MGLShape` - directly, and do not create your own subclasses of this class. The shape - classes correspond to the - <a href="https://tools.ietf.org/html/rfc7946#section-3.1">Geometry</a> object - types in the GeoJSON standard, but some have nonstandard names for backwards - compatibility. - - Although you do not create instances of this class directly, you can use its - `+[MGLShape shapeWithData:encoding:error:]` factory method to create one of the - concrete subclasses of `MGLShape` noted above from GeoJSON data. To access a - shape’s attributes, use the corresponding `MGLFeature` class instead. - - You can add shapes to the map by adding them to an `MGLShapeSource` object. - Configure the appearance of an `MGLShapeSource`’s or `MGLVectorTileSource`’s - shapes collectively using a concrete instance of `MGLVectorStyleLayer`. - Alternatively, you can add some kinds of shapes directly to a map view as - annotations or overlays. - */ -MGL_EXPORT -@interface MGLShape : NSObject <MGLAnnotation, NSSecureCoding> - -#pragma mark Creating a Shape - -/** - Returns an `MGLShape` object initialized with the given data interpreted as a - string containing a GeoJSON object. - - If the GeoJSON object is a geometry, the returned value is a kind of - `MGLShape`. If it is a feature object, the returned value is a kind of - `MGLShape` that conforms to the `MGLFeature` protocol. If it is a feature - collection object, the returned value is an instance of - `MGLShapeCollectionFeature`. - - ### Example - - ```swift - let url = mainBundle.url(forResource: "amsterdam", withExtension: "geojson")! - let data = try! Data(contentsOf: url) - let feature = try! MGLShape(data: data, encoding: String.Encoding.utf8.rawValue) as! MGLShapeCollectionFeature - ``` - - @param data String data containing GeoJSON source code. - @param encoding The encoding used by `data`. - @param outError Upon return, if an error has occurred, a pointer to an - `NSError` object describing the error. Pass in `NULL` to ignore any error. - @return An `MGLShape` object representation of `data`, or `nil` if `data` could - not be parsed as valid GeoJSON source code. If `nil`, `outError` contains an - `NSError` object describing the problem. - */ -+ (nullable MGLShape *)shapeWithData:(NSData *)data encoding:(NSStringEncoding)encoding error:(NSError * _Nullable *)outError; - -#pragma mark Accessing the Shape Attributes - -/** - The title of the shape annotation. - - The default value of this property is `nil`. - - This property is ignored when the shape is used in an `MGLShapeSource`. To name - a shape used in a shape source, create an `MGLFeature` and add an attribute to - the `MGLFeature.attributes` property. - */ -@property (nonatomic, copy, nullable) NSString *title; - -/** - The subtitle of the shape annotation. The default value of this property is - `nil`. - - This property is ignored when the shape is used in an `MGLShapeSource`. To - provide additional information about a shape used in a shape source, create an - `MGLFeature` and add an attribute to the `MGLFeature.attributes` property. - */ -@property (nonatomic, copy, nullable) NSString *subtitle; - -#if !TARGET_OS_IPHONE - -/** - The tooltip of the shape annotation. - - The default value of this property is `nil`. - - This property is ignored when the shape is used in an `MGLShapeSource`. - */ -@property (nonatomic, copy, nullable) NSString *toolTip; - -#endif - -#pragma mark Creating GeoJSON Data - -/** - Returns the GeoJSON string representation of the shape encapsulated in a data - object. - - @param encoding The string encoding to use. - @return A data object containing the shape’s GeoJSON string representation. - */ -- (NSData *)geoJSONDataUsingEncoding:(NSStringEncoding)encoding; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShape.mm b/platform/darwin/src/MGLShape.mm deleted file mode 100644 index 4ed546a3d2..0000000000 --- a/platform/darwin/src/MGLShape.mm +++ /dev/null @@ -1,121 +0,0 @@ -#import "MGLShape_Private.h" - -#import "MGLFeature_Private.h" - -#import "NSString+MGLAdditions.h" -#import "MGLTypes.h" - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MMEEventsManager.h" -#endif - -#import <mbgl/util/geo.hpp> - -bool operator==(const CLLocationCoordinate2D lhs, const CLLocationCoordinate2D rhs) { - return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude; -} - -@implementation MGLShape - -+ (nullable MGLShape *)shapeWithData:(NSData *)data encoding:(NSStringEncoding)encoding error:(NSError * _Nullable *)outError { - NSString *string = [[NSString alloc] initWithData:data encoding:encoding]; - if (!string) { - if (outError) { - *outError = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeUnknown userInfo:nil]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:*outError]; -#endif - } - return nil; - } - - try { - const auto geojson = mapbox::geojson::parse(string.UTF8String); - return MGLShapeFromGeoJSON(geojson); - } catch (std::runtime_error &err) { - if (outError) { - *outError = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeUnknown userInfo:@{ - NSLocalizedFailureReasonErrorKey: @(err.what()), - }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:*outError]; -#endif - } - return nil; - } -} - -- (mbgl::GeoJSON)geoJSONObject { - return self.geometryObject; -} - -- (mbgl::Geometry<double>)geometryObject { - [NSException raise:MGLAbstractClassException - format:@"MGLShape is an abstract class"]; - return mbgl::Point<double>(); -} - -- (NSData *)geoJSONDataUsingEncoding:(NSStringEncoding)encoding { - auto geometry = self.geoJSONObject; - NSString *string = @(mapbox::geojson::stringify(geometry).c_str()); - return [string dataUsingEncoding:NSUTF8StringEncoding]; -} - -+ (BOOL)supportsSecureCoding -{ - return YES; -} - -- (instancetype)initWithCoder:(NSCoder *)coder -{ - if (self = [super init]) { - _title = [coder decodeObjectOfClass:[NSString class] forKey:@"title"]; - _subtitle = [coder decodeObjectOfClass:[NSString class] forKey:@"subtitle"]; -#if !TARGET_OS_IPHONE - _toolTip = [coder decodeObjectOfClass:[NSString class] forKey:@"toolTip"]; -#endif - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - [coder encodeObject:_title forKey:@"title"]; - [coder encodeObject:_subtitle forKey:@"subtitle"]; -#if !TARGET_OS_IPHONE - [coder encodeObject:_toolTip forKey:@"toolTip"]; -#endif -} - -- (BOOL)isEqual:(id)other -{ - if (other == self) { return YES; } - id <MGLAnnotation> annotation = other; - -#if TARGET_OS_IPHONE - return ((!_title && ![annotation title]) || [_title isEqualToString:[annotation title]]) - && ((!_subtitle && ![annotation subtitle]) || [_subtitle isEqualToString:[annotation subtitle]]); -#else - return ((!_title && ![annotation title]) || [_title isEqualToString:[annotation title]]) - && ((!_subtitle && ![annotation subtitle]) || [_subtitle isEqualToString:[annotation subtitle]]) - && ((!_toolTip && ![annotation toolTip]) || [_toolTip isEqualToString:[annotation toolTip]]); -#endif -} - -- (NSUInteger)hash -{ - NSUInteger hash = _title.hash + _subtitle.hash; -#if !TARGET_OS_IPHONE - hash += _toolTip.hash; -#endif - return hash; -} - -- (CLLocationCoordinate2D)coordinate -{ - [NSException raise:MGLAbstractClassException - format:@"MGLShape is an abstract class"]; - return kCLLocationCoordinate2DInvalid; -} - -@end diff --git a/platform/darwin/src/MGLShapeCollection.h b/platform/darwin/src/MGLShapeCollection.h deleted file mode 100644 index 08f3276496..0000000000 --- a/platform/darwin/src/MGLShapeCollection.h +++ /dev/null @@ -1,56 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLShape.h" - -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An `MGLShapeCollection` object represents a shape consisting of zero or more - distinct but related shapes that are instances of `MGLShape`. The constituent - shapes can be a mixture of different kinds of shapes. - - `MGLShapeCollection` is most commonly used to add multiple shapes to a single - `MGLShapeSource`. Configure the appearance of an `MGLShapeSource`’s or - `MGLVectorTileSource`’s shape collection collectively using an - `MGLSymbolStyleLayer` object, or use multiple instances of - `MGLCircleStyleLayer`, `MGLFillStyleLayer`, and `MGLLineStyleLayer` to - configure the appearance of each kind of shape inside the collection. - - You cannot add an `MGLShapeCollection` object directly to a map view as an - annotation. However, you can create individual `MGLPointAnnotation`, - `MGLPolyline`, and `MGLPolygon` objects from the `shapes` array and add those - annotation objects to the map view using the `-[MGLMapView addAnnotations:]` - method. - - To represent a collection of point, polyline, or polygon shapes, it may be more - convenient to use an `MGLPointCollection`, `MGLMultiPolyline`, or - `MGLMultiPolygon` object, respectively. To access a shape collection’s - attributes, use the corresponding `MGLFeature` object. - - A shape collection is known as a - <a href="https://tools.ietf.org/html/rfc7946#section-3.1.8">GeometryCollection</a> - geometry in GeoJSON. - */ -MGL_EXPORT -@interface MGLShapeCollection : MGLShape - -/** - An array of shapes forming the shape collection. - */ -@property (nonatomic, copy, readonly) NSArray<MGLShape *> *shapes; - -/** - Creates and returns a shape collection consisting of the given shapes. - - @param shapes The array of shapes defining the shape collection. The data in - this array is copied to the new object. - @return A new shape collection object. - */ -+ (instancetype)shapeCollectionWithShapes:(NSArray<MGLShape *> *)shapes; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShapeCollection.mm b/platform/darwin/src/MGLShapeCollection.mm deleted file mode 100644 index 5a0ef03340..0000000000 --- a/platform/darwin/src/MGLShapeCollection.mm +++ /dev/null @@ -1,80 +0,0 @@ -#import "MGLShapeCollection.h" - -#import "MGLShape_Private.h" -#import "MGLFeature.h" -#import "MGLLoggingConfiguration_Private.h" - -#import <mbgl/style/conversion/geojson.hpp> - -@implementation MGLShapeCollection - -+ (instancetype)shapeCollectionWithShapes:(NSArray<MGLShape *> *)shapes { - return [[self alloc] initWithShapes:shapes]; -} - -- (instancetype)initWithShapes:(NSArray<MGLShape *> *)shapes { - MGLLogDebug(@"Initializing with %lu shapes.", (unsigned long)shapes.count); - if (self = [super init]) { - _shapes = shapes.copy; - } - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)decoder { - MGLLogInfo(@"Initializing with coder."); - if (self = [super initWithCoder:decoder]) { - _shapes = [decoder decodeObjectOfClass:[NSArray class] forKey:@"shapes"]; - } - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder { - [super encodeWithCoder:coder]; - [coder encodeObject:_shapes forKey:@"shapes"]; -} - -- (BOOL)isEqual:(id)other { - if (self == other) return YES; - if (![other isKindOfClass:[MGLShapeCollection class]]) return NO; - - MGLShapeCollection *otherShapeCollection = other; - return [super isEqual:otherShapeCollection] - && [_shapes isEqualToArray:otherShapeCollection.shapes]; -} - -- (NSUInteger)hash { - NSUInteger hash = [super hash]; - for (MGLShape *shape in _shapes) { - hash += [shape hash]; - } - return hash; -} - -- (CLLocationCoordinate2D)coordinate { - return _shapes.firstObject.coordinate; -} - -- (NSDictionary *)geoJSONDictionary { - return @{@"type": @"GeometryCollection", - @"geometries": [self geometryCollection]}; -} - -- (NSArray *)geometryCollection { - NSMutableArray *geometries = [[NSMutableArray alloc] initWithCapacity:self.shapes.count]; - for (id shape in self.shapes) { - NSDictionary *geometry = [shape geoJSONDictionary]; - [geometries addObject:geometry]; - } - return [geometries copy]; -} - -- (mbgl::Geometry<double>)geometryObject { - mapbox::geojson::geometry_collection collection; - collection.reserve(self.shapes.count); - for (MGLShape *shape in self.shapes) { - collection.push_back([shape geometryObject]); - } - return collection; -} - -@end diff --git a/platform/darwin/src/MGLShapeOfflineRegion.h b/platform/darwin/src/MGLShapeOfflineRegion.h deleted file mode 100644 index 7e871067b6..0000000000 --- a/platform/darwin/src/MGLShapeOfflineRegion.h +++ /dev/null @@ -1,86 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLOfflineRegion.h" -#import "MGLShape.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An offline region defined by a style URL, geographic shape, and - range of zoom levels. - - ### Example - ```swift - var coordinates = [ - CLLocationCoordinate2D(latitude: 45.522585, longitude: -122.685699), - CLLocationCoordinate2D(latitude: 45.534611, longitude: -122.708873), - CLLocationCoordinate2D(latitude: 45.530883, longitude: -122.678833) - ] - - let triangle = MGLPolygon(coordinates: &coordinates, count: UInt(coordinates.count)) - let region = MGLShapeOfflineRegion(styleURL: MGLStyle.lightStyleURL, shape: triangle, fromZoomLevel: 11, toZoomLevel: 14) - let context = "Triangle Region".data(using: .utf8) - MGLOfflineStorage.shared.addPack(for: region, withContext: context!) - ``` - - This class requires fewer resources than MGLTilePyramidOfflineRegion - for irregularly shaped regions. - */ -MGL_EXPORT -@interface MGLShapeOfflineRegion : NSObject <MGLOfflineRegion, NSSecureCoding, NSCopying> - -/** - The shape for the geographic region covered by the downloaded - tiles. - */ -@property (nonatomic, readonly) MGLShape *shape; - -/** - The minimum zoom level for which to download tiles and other resources. - - For more information about zoom levels, `-[MGLMapView zoomLevel]`. - */ -@property (nonatomic, readonly) double minimumZoomLevel; - -/** - The maximum zoom level for which to download tiles and other resources. - - For more information about zoom levels, `-[MGLMapView zoomLevel]`. - */ -@property (nonatomic, readonly) double maximumZoomLevel; - -- (instancetype)init NS_UNAVAILABLE; - -/** - Initializes a newly created offline region with the given style URL, geometry, - and range of zoom levels. - - This is the designated initializer for `MGLShapeOfflineRegion`. - - @param styleURL URL of the map style for which to download resources. The URL - may be a full HTTP or HTTPS URL or a Mapbox - style URL (`mapbox://styles/{user}/{style}`). Specify `nil` for the default style. - Relative file URLs cannot be used as offline style URLs. To download the - online resources required by a local style, specify a URL to an online copy - of the style. - @param shape The shape of the geographic region to be covered by - the downloaded tiles. - @param minimumZoomLevel The minimum zoom level to be covered by the downloaded - tiles. This parameter should be set to at least 0 but no greater than the - value of the `maximumZoomLevel` parameter. For each required tile source, if - this parameter is set to a value less than the tile source’s minimum zoom - level, the download covers zoom levels down to the tile source’s minimum - zoom level. - @param maximumZoomLevel The maximum zoom level to be covered by the downloaded - tiles. This parameter should be set to at least the value of the - `minimumZoomLevel` parameter. For each required tile source, if this - parameter is set to a value greater than the tile source’s minimum zoom - level, the download covers zoom levels up to the tile source’s maximum zoom - level. - */ -- (instancetype)initWithStyleURL:(nullable NSURL *)styleURL shape:(MGLShape *)shape fromZoomLevel:(double)minimumZoomLevel toZoomLevel:(double)maximumZoomLevel NS_DESIGNATED_INITIALIZER; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShapeOfflineRegion.mm b/platform/darwin/src/MGLShapeOfflineRegion.mm deleted file mode 100644 index b4f4b5e92a..0000000000 --- a/platform/darwin/src/MGLShapeOfflineRegion.mm +++ /dev/null @@ -1,150 +0,0 @@ -#import "MGLShapeOfflineRegion.h" - -#if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR - #import <Cocoa/Cocoa.h> -#else - #import <UIKit/UIKit.h> -#endif - -#import "MGLOfflineRegion_Private.h" -#import "MGLShapeOfflineRegion_Private.h" -#import "MGLFeature_Private.h" -#import "MGLShape_Private.h" -#import "MGLStyle.h" -#import "MGLLoggingConfiguration_Private.h" - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MMEConstants.h" -#endif - -@interface MGLShapeOfflineRegion () <MGLOfflineRegion_Private, MGLShapeOfflineRegion_Private> - -@end - -@implementation MGLShapeOfflineRegion { - NSURL *_styleURL; -} - -@synthesize styleURL = _styleURL; -@synthesize includesIdeographicGlyphs = _includesIdeographicGlyphs; - --(NSDictionary *)offlineStartEventAttributes { - return @{ - #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - MMEEventKeyShapeForOfflineRegion: @"shaperegion", - MMEEventKeyMinZoomLevel: @(self.minimumZoomLevel), - MMEEventKeyMaxZoomLevel: @(self.maximumZoomLevel), - MMEEventKeyStyleURL: self.styleURL.absoluteString ?: [NSNull null] - #endif - }; -} - -+ (BOOL)supportsSecureCoding { - return YES; -} - -- (instancetype)init { - MGLLogInfo(@"Calling this initializer is not allowed."); - [NSException raise:@"Method unavailable" - format: - @"-[MGLShapeOfflineRegion init] is unavailable. " - @"Use -initWithStyleURL:shape:fromZoomLevel:toZoomLevel: instead."]; - return nil; -} - -- (instancetype)initWithStyleURL:(NSURL *)styleURL shape:(MGLShape *)shape fromZoomLevel:(double)minimumZoomLevel toZoomLevel:(double)maximumZoomLevel { - MGLLogDebug(@"Initializing styleURL: %@ shape: %@ fromZoomLevel: %f toZoomLevel: %f", styleURL, shape, minimumZoomLevel, maximumZoomLevel); - if (self = [super init]) { - if (!styleURL) { - styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion]; - } - - if (!styleURL.scheme) { - [NSException raise:@"Invalid style URL" format: - @"%@ does not support setting a relative file URL as the style URL. " - @"To download the online resources required by this style, " - @"specify a URL to an online copy of this style. " - @"For Mapbox-hosted styles, use the mapbox: scheme.", - NSStringFromClass([self class])]; - } - - _styleURL = styleURL; - _shape = shape; - _minimumZoomLevel = minimumZoomLevel; - _maximumZoomLevel = maximumZoomLevel; - _includesIdeographicGlyphs = NO; - } - return self; -} - -- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineGeometryRegionDefinition &)definition { - NSURL *styleURL = [NSURL URLWithString:@(definition.styleURL.c_str())]; - MGLShape *shape = MGLShapeFromGeoJSON(definition.geometry); - MGLShapeOfflineRegion* result = [self initWithStyleURL:styleURL shape:shape fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom]; - result.includesIdeographicGlyphs = definition.includeIdeographs; - return result; -} - -- (const mbgl::OfflineRegionDefinition)offlineRegionDefinition { -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale]; -#elif TARGET_OS_MAC - const float scaleFactor = [NSScreen mainScreen].backingScaleFactor; -#endif - return mbgl::OfflineGeometryRegionDefinition(_styleURL.absoluteString.UTF8String, - _shape.geometryObject, - _minimumZoomLevel, _maximumZoomLevel, - scaleFactor, _includesIdeographicGlyphs); -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder { - MGLLogInfo(@"Initializing with coder."); - NSURL *styleURL = [coder decodeObjectForKey:@"styleURL"]; - MGLShape * shape = [coder decodeObjectForKey:@"shape"]; - double minimumZoomLevel = [coder decodeDoubleForKey:@"minimumZoomLevel"]; - double maximumZoomLevel = [coder decodeDoubleForKey:@"maximumZoomLevel"]; - - MGLShapeOfflineRegion* result = [self initWithStyleURL:styleURL shape:shape fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel]; - result.includesIdeographicGlyphs = [coder decodeBoolForKey:@"includesIdeographicGlyphs"]; - return result; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - [coder encodeObject:_styleURL forKey:@"styleURL"]; - [coder encodeObject:_shape forKey:@"shape"]; - [coder encodeDouble:_maximumZoomLevel forKey:@"maximumZoomLevel"]; - [coder encodeDouble:_minimumZoomLevel forKey:@"minimumZoomLevel"]; - [coder encodeBool:_includesIdeographicGlyphs forKey:@"includesIdeographicGlyphs"]; -} - -- (id)copyWithZone:(nullable NSZone *)zone { - MGLShapeOfflineRegion* result = [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL shape:_shape fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel]; - result.includesIdeographicGlyphs = _includesIdeographicGlyphs; - return result; -} - -- (BOOL)isEqual:(id)other { - if (other == self) { - return YES; - } - if (![other isKindOfClass:[self class]]) { - return NO; - } - - MGLShapeOfflineRegion *otherRegion = other; - return (_minimumZoomLevel == otherRegion->_minimumZoomLevel - && _maximumZoomLevel == otherRegion->_maximumZoomLevel - && _shape.geometryObject == otherRegion->_shape.geometryObject - && [_styleURL isEqual:otherRegion->_styleURL] - && _includesIdeographicGlyphs == otherRegion->_includesIdeographicGlyphs); -} - -- (NSUInteger)hash { - return (_styleURL.hash - + _shape.hash - + @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash - + @(_includesIdeographicGlyphs).hash); -} - -@end diff --git a/platform/darwin/src/MGLShapeOfflineRegion_Private.h b/platform/darwin/src/MGLShapeOfflineRegion_Private.h deleted file mode 100644 index 2ab44ad405..0000000000 --- a/platform/darwin/src/MGLShapeOfflineRegion_Private.h +++ /dev/null @@ -1,22 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLOfflineRegion.h" - -#include <mbgl/storage/offline.hpp> - -NS_ASSUME_NONNULL_BEGIN - -@protocol MGLShapeOfflineRegion_Private <MGLOfflineRegion> - -/** - Initializes and returns an offline region backed by the given C++ region - definition object. - - @param definition A reference to an offline region definition backing the - offline region. - */ -- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineGeometryRegionDefinition &)definition; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShapeSource.h b/platform/darwin/src/MGLShapeSource.h deleted file mode 100644 index 675c219300..0000000000 --- a/platform/darwin/src/MGLShapeSource.h +++ /dev/null @@ -1,400 +0,0 @@ -#import "MGLFoundation.h" -#import "MGLTypes.h" -#import "MGLSource.h" - -NS_ASSUME_NONNULL_BEGIN - -@protocol MGLFeature; -@class MGLPointFeature; -@class MGLPointFeatureCluster; -@class MGLShape; - -/** - Options for `MGLShapeSource` objects. - */ -typedef NSString *MGLShapeSourceOption NS_STRING_ENUM; - -/** - An `NSNumber` object containing a Boolean enabling or disabling clustering. - If the `shape` property contains point shapes, setting this option to - `YES` clusters the points by radius into groups. The default value is `NO`. - - This option corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-cluster"><code>cluster</code></a> - source property in the Mapbox Style Specification. - - This option only affects point features within an `MGLShapeSource` object; it - is ignored when creating an `MGLComputedShapeSource` object. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/clustering/">Cluster point data</a> and <a href="https://docs.mapbox.com/ios/maps/examples/clustering-with-images/">Use images to cluster point data</a> examples to learn how to cluster point data with this `MGLShapeSourceOption`. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClustered; - -/** - An `NSNumber` object containing an integer; specifies the radius of each - cluster if clustering is enabled. A value of 512 produces a radius equal to - the width of a tile. The default value is 50. - - This option only affects point features within an `MGLShapeSource` object; it - is ignored when creating an `MGLComputedShapeSource` object. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClusterRadius; - -/** - An `NSDictionary` object where the key is an `NSString`. The dictionary key will - be the feature attribute key. The resulting attribute value is - aggregated from the clustered points. The dictionary value is an `NSArray` - consisting of two `NSExpression` objects. - - The first object determines how the attribute values are accumulated from the - cluster points. It is an `NSExpression` with an expression function that accepts - two or more arguments, such as `sum` or `max`. The arguments should be - `featureAccumulated` and the previously defined feature attribute key. The - resulting value is assigned to the specified attribute key. - - The second `NSExpression` in the array determines which - attribute values are accessed from individual features within a cluster. - - ```swift - let firstExpression = NSExpression(format: "sum:({$featureAccumulated, sumValue})") - let secondExpression = NSExpression(forKeyPath: "magnitude") - let clusterPropertiesDictionary = ["sumValue" : [firstExpression, secondExpression]] - - let options : [MGLShapeSourceOption : Any] = [.clustered : true, - .clusterProperties: clusterPropertiesDictionary] - ``` - - This option corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-clusterProperties"><code>clusterProperties</code></a> - source property in the Mapbox Style Specification. - - This option only affects point features within an `MGLShapeSource` object; it - is ignored when creating an `MGLComputedShapeSource` object. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClusterProperties; -/** - An `NSNumber` object containing an integer; specifies the maximum zoom level at - which to cluster points if clustering is enabled. Defaults to one zoom level - less than the value of `MGLShapeSourceOptionMaximumZoomLevel` so that, at the - maximum zoom level, the shapes are not clustered. - - This option corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-clusterMaxZoom"><code>clusterMaxZoom</code></a> - source property in the Mapbox Style Specification. - - This option only affects point features within an `MGLShapeSource` object; it - is ignored when creating an `MGLComputedShapeSource` object. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevelForClustering; - -/** - An `NSNumber` object containing an integer; specifies the minimum zoom level at - which to create vector tiles. The default value is 0. - - This option corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-minzoom"><code>minzoom</code></a> - source property in the Mapbox Style Specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionMinimumZoomLevel; - -/** - An `NSNumber` object containing an integer; specifies the maximum zoom level at - which to create vector tiles. A greater value produces greater detail at high - zoom levels. The default value is 18. - - This option corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-maxzoom"><code>maxzoom</code></a> - source property in the Mapbox Style Specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevel; - -/** - An `NSNumber` object containing an integer; specifies the size of the tile - buffer on each side. A value of 0 produces no buffer. A value of 512 produces a - buffer as wide as the tile itself. Larger values produce fewer rendering - artifacts near tile edges and slower performance. The default value is 128. - - This option corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-buffer"><code>buffer</code></a> - source property in the Mapbox Style Specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionBuffer; - -/** - An `NSNumber` object containing a double; specifies the Douglas-Peucker - simplification tolerance. A greater value produces simpler geometries and - improves performance. The default value is 0.375. - - This option corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson-tolerance"><code>tolerance</code></a> - source property in the Mapbox Style Specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance; - -/** - An `NSNumber` object containing a Boolean enabling or disabling calculating line distance metrics. - - Set this property to `YES` in order for the `MGLLineStyleLayer.lineGradient` property to have its intended effect. - The default value is `NO`. - - This option corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#sources-geojson-lineMetrics"><code>lineMetrics</code></a> - source property in the Mapbox Style Specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionLineDistanceMetrics; - -/** - `MGLShapeSource` is a map content source that supplies vector shapes to be - shown on the map. The shapes may be instances of `MGLShape` or `MGLFeature`, - or they may be defined by local or external - <a href="http://geojson.org/">GeoJSON</a> code. A shape source is added to an - `MGLStyle` object along with an `MGLVectorStyleLayer` object. The vector style - layer defines the appearance of any content supplied by the shape source. You - can update a shape source by setting its `shape` or `URL` property. - - `MGLShapeSource` is optimized for data sets that change dynamically and fit - completely in memory. For large data sets that do not fit completely in memory, - use the `MGLComputedShapeSource` or `MGLVectorTileSource` class. - - Each - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson"><code>geojson</code></a> - source defined by the style JSON file is represented at runtime by an - `MGLShapeSource` object that you can use to refine the map’s content and - initialize new style layers. You can also add and remove sources dynamically - using methods such as `-[MGLStyle addSource:]` and - `-[MGLStyle sourceWithIdentifier:]`. - - Any vector style layer initialized with a shape source should have a `nil` - value in its `sourceLayerIdentifier` property. - - ### Example - - ```swift - var coordinates: [CLLocationCoordinate2D] = [ - CLLocationCoordinate2D(latitude: 37.77, longitude: -122.42), - CLLocationCoordinate2D(latitude: 38.91, longitude: -77.04), - ] - let polyline = MGLPolylineFeature(coordinates: &coordinates, count: UInt(coordinates.count)) - let source = MGLShapeSource(identifier: "lines", features: [polyline], options: nil) - mapView.style?.addSource(source) - ``` - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/clustering/">Cluster point data</a>, <a href="https://docs.mapbox.com/ios/maps/examples/clustering-with-images/">Use images to cluster point data</a>, and <a href="https://docs.mapbox.com/ios/maps/examples/live-data/">Add live data</a> examples to learn how to add data to your map using this `MGLSource` object. - */ -MGL_EXPORT -@interface MGLShapeSource : MGLSource - -#pragma mark Initializing a Source - -/** - Returns a shape source with an identifier, URL, and dictionary of options for - the source. - - This class supports the following options: `MGLShapeSourceOptionClustered`, - `MGLShapeSourceOptionClusterRadius`, - `MGLShapeSourceOptionMaximumZoomLevelForClustering`, - `MGLShapeSourceOptionMinimumZoomLevel`, `MGLShapeSourceOptionMaximumZoomLevel`, - `MGLShapeSourceOptionBuffer`, and - `MGLShapeSourceOptionSimplificationTolerance`. Shapes provided by a shape - source are not clipped or wrapped automatically. - - @param identifier A string that uniquely identifies the source. - @param url An HTTP(S) URL, absolute file URL, or local file URL relative to the - current application’s resource bundle. - @param options An `NSDictionary` of options for this source. - @return An initialized shape source. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/live-data/"> - Add live data</a> example to learn how to add live data to your map by - updating the an `MGLShapeSource` object's `URL` property. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(nullable NSDictionary<MGLShapeSourceOption, id> *)options NS_DESIGNATED_INITIALIZER; - -/** - Returns a shape source with an identifier, a shape, and dictionary of options - for the source. - - This class supports the following options: `MGLShapeSourceOptionClustered`, - `MGLShapeSourceOptionClusterRadius`, - `MGLShapeSourceOptionMaximumZoomLevelForClustering`, - `MGLShapeSourceOptionMinimumZoomLevel`, `MGLShapeSourceOptionMaximumZoomLevel`, - `MGLShapeSourceOptionBuffer`, and - `MGLShapeSourceOptionSimplificationTolerance`. Shapes provided by a shape - source are not clipped or wrapped automatically. - - To specify attributes about the shape, use an instance of an `MGLShape` - subclass that conforms to the `MGLFeature` protocol, such as `MGLPointFeature`. - To include multiple shapes in the source, use an `MGLShapeCollection` or - `MGLShapeCollectionFeature` object, or use the - `-initWithIdentifier:features:options:` or - `-initWithIdentifier:shapes:options:` methods. - - To create a shape from GeoJSON source code, use the - `+[MGLShape shapeWithData:encoding:error:]` method. - - @param identifier A string that uniquely identifies the source. - @param shape A concrete subclass of `MGLShape` - @param options An `NSDictionary` of options for this source. - @return An initialized shape source. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/runtime-animate-line/"> - Animate a line</a> example to learn how to animate line data by continously - updating an `MGLShapeSource`'s `shape` attribute. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(nullable NSDictionary<MGLShapeSourceOption, id> *)options NS_DESIGNATED_INITIALIZER; - -/** - Returns a shape source with an identifier, an array of features, and a dictionary - of options for the source. - - This class supports the following options: `MGLShapeSourceOptionClustered`, - `MGLShapeSourceOptionClusterRadius`, - `MGLShapeSourceOptionMaximumZoomLevelForClustering`, - `MGLShapeSourceOptionMinimumZoomLevel`, `MGLShapeSourceOptionMaximumZoomLevel`, - `MGLShapeSourceOptionBuffer`, and - `MGLShapeSourceOptionSimplificationTolerance`. Shapes provided by a shape - source are not clipped or wrapped automatically. - - Unlike `-initWithIdentifier:shapes:options:`, this method accepts `MGLFeature` - instances, such as `MGLPointFeature` objects, whose attributes you can use when - applying a predicate to `MGLVectorStyleLayer` or configuring a style layer’s - appearance. - - To create a shape from GeoJSON source code, use the - `+[MGLShape shapeWithData:encoding:error:]` method. - - @param identifier A string that uniquely identifies the source. - @param features An array of objects that conform to the MGLFeature protocol. - @param options An `NSDictionary` of options for this source. - @return An initialized shape source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier features:(NSArray<MGLShape<MGLFeature> *> *)features options:(nullable NSDictionary<MGLShapeSourceOption, id> *)options; - -/** - Returns a shape source with an identifier, an array of shapes, and a dictionary of - options for the source. - - This class supports the following options: `MGLShapeSourceOptionClustered`, - `MGLShapeSourceOptionClusterRadius`, - `MGLShapeSourceOptionMaximumZoomLevelForClustering`, - `MGLShapeSourceOptionMinimumZoomLevel`, `MGLShapeSourceOptionMaximumZoomLevel`, - `MGLShapeSourceOptionBuffer`, and - `MGLShapeSourceOptionSimplificationTolerance`. Shapes provided by a shape - source are not clipped or wrapped automatically. - - Any `MGLFeature` instance passed into this initializer is treated as an ordinary - shape, causing any attributes to be inaccessible to an `MGLVectorStyleLayer` when - evaluating a predicate or configuring certain layout or paint attributes. To - preserve the attributes associated with each feature, use the - `-initWithIdentifier:features:options:` method instead. - - To create a shape from GeoJSON source code, use the - `+[MGLShape shapeWithData:encoding:error:]` method. - - @param identifier A string that uniquely identifies the source. - @param shapes An array of shapes; each shape is a member of a concrete subclass of MGLShape. - @param options An `NSDictionary` of options for this source. - @return An initialized shape source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier shapes:(NSArray<MGLShape *> *)shapes options:(nullable NSDictionary<MGLShapeSourceOption, id> *)options; - -#pragma mark Accessing a Source’s Content - -/** - The contents of the source. A shape can represent a GeoJSON geometry, a - feature, or a collection of features. - - If the receiver was initialized using `-initWithIdentifier:URL:options:`, this - property is set to `nil`. This property is unavailable until the receiver is - passed into `-[MGLStyle addSource:]`. - - You can get/set the shapes within a collection via this property. Actions must - be performed on the application's main thread. - */ -@property (nonatomic, copy, nullable) MGLShape *shape; - -/** - The URL to the GeoJSON document that specifies the contents of the source. - - If the receiver was initialized using `-initWithIdentifier:shape:options:`, - this property is set to `nil`. - */ -@property (nonatomic, copy, nullable) NSURL *URL; - -/** - Returns an array of map features for this source, filtered by the given - predicate. - - Each object in the returned array represents a feature for the current style - and provides access to attributes specified via the `shape` property. - - Features come from tiled GeoJSON data that is converted to tiles internally, - so feature geometries are clipped at tile boundaries and features - may appear duplicated across tiles. For example, suppose this source contains a - long polyline representing a road. The resulting array includes those parts of - the road that lie within the map tiles that the source has loaded, even if the - road extends into other tiles. The portion of the road within each map tile is - included individually. - - Returned features may not necessarily be visible to the user at the time they - are loaded: the style may lack a layer that draws the features in question. To - obtain only _visible_ features, use the - `-[MGLMapView visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:predicate:]` - or - `-[MGLMapView visibleFeaturesInRect:inStyleLayersWithIdentifiers:predicate:]` - method. - - @param predicate A predicate to filter the returned features. Use `nil` to - include all features in the source. - @return An array of objects conforming to the `MGLFeature` protocol that - represent features in the source that match the predicate. - */ -- (NSArray<id <MGLFeature>> *)featuresMatchingPredicate:(nullable NSPredicate *)predicate; - -/** - Returns an array of map features that are the leaves of the specified cluster. - ("Leaves" are the original points that belong to the cluster.) - - This method supports pagination; you supply an offset (number of features to skip) - and a maximum number of features to return. - - @param cluster An object of type `MGLPointFeatureCluster` (that conforms to the `MGLCluster` protocol). - @param offset Number of features to skip. - @param limit The maximum number of features to return - - @return An array of objects that conform to the `MGLFeature` protocol. - */ -- (NSArray<id <MGLFeature>> *)leavesOfCluster:(MGLPointFeatureCluster *)cluster offset:(NSUInteger)offset limit:(NSUInteger)limit; - -/** - Returns an array of map features that are the immediate children of the specified - cluster *on the next zoom level*. The may include features that also conform to - the `MGLCluster` protocol (currently only objects of type `MGLPointFeatureCluster`). - - @param cluster An object of type `MGLPointFeatureCluster` (that conforms to the `MGLCluster` protocol). - - @return An array of objects that conform to the `MGLFeature` protocol. - - @note The returned array may contain the `cluster` that was passed in, if the next - zoom level doesn't match the zoom level for expanding that cluster. See - `-[MGLShapeSource zoomLevelForExpandingCluster:]`. - */ -- (NSArray<id<MGLFeature>> *)childrenOfCluster:(MGLPointFeatureCluster *)cluster; - -/** - Returns the zoom level at which the given cluster expands. - - @param cluster An object of type `MGLPointFeatureCluster` (that conforms to the `MGLCluster` protocol). - - @return Zoom level. This should be >= 0; any negative return value should be - considered an error. - */ -- (double)zoomLevelForExpandingCluster:(MGLPointFeatureCluster *)cluster; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm deleted file mode 100644 index 2590865ac2..0000000000 --- a/platform/darwin/src/MGLShapeSource.mm +++ /dev/null @@ -1,355 +0,0 @@ -#import "MGLFoundation_Private.h" -#import "MGLShapeSource_Private.h" - -#import "MGLLoggingConfiguration_Private.h" -#import "MGLStyle_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLMapView_Private.h" -#import "MGLSource_Private.h" -#import "MGLFeature_Private.h" -#import "MGLShape_Private.h" -#import "MGLCluster.h" - -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSURL+MGLAdditions.h" - -#include <mbgl/map/map.hpp> -#include <mbgl/style/sources/geojson_source.hpp> -#include <mbgl/renderer/renderer.hpp> - -const MGLShapeSourceOption MGLShapeSourceOptionBuffer = @"MGLShapeSourceOptionBuffer"; -const MGLShapeSourceOption MGLShapeSourceOptionClusterRadius = @"MGLShapeSourceOptionClusterRadius"; -const MGLShapeSourceOption MGLShapeSourceOptionClustered = @"MGLShapeSourceOptionClustered"; -const MGLShapeSourceOption MGLShapeSourceOptionClusterProperties = @"MGLShapeSourceOptionClusterProperties"; -const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevel = @"MGLShapeSourceOptionMaximumZoomLevel"; -const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevelForClustering = @"MGLShapeSourceOptionMaximumZoomLevelForClustering"; -const MGLShapeSourceOption MGLShapeSourceOptionMinimumZoomLevel = @"MGLShapeSourceOptionMinimumZoomLevel"; -const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLShapeSourceOptionSimplificationTolerance"; -const MGLShapeSourceOption MGLShapeSourceOptionLineDistanceMetrics = @"MGLShapeSourceOptionLineDistanceMetrics"; - -mbgl::Immutable<mbgl::style::GeoJSONOptions> MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShapeSourceOption, id> *options) { - auto geoJSONOptions = mbgl::makeMutable<mbgl::style::GeoJSONOptions>(); - - if (NSNumber *value = options[MGLShapeSourceOptionMinimumZoomLevel]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionMaximumZoomLevel must be an NSNumber."]; - } - geoJSONOptions->minzoom = value.integerValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionMaximumZoomLevel]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionMaximumZoomLevel must be an NSNumber."]; - } - geoJSONOptions->maxzoom = value.integerValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionBuffer]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionBuffer must be an NSNumber."]; - } - geoJSONOptions->buffer = value.integerValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionSimplificationTolerance]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionSimplificationTolerance must be an NSNumber."]; - } - geoJSONOptions->tolerance = value.doubleValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionClusterRadius]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionClusterRadius must be an NSNumber."]; - } - geoJSONOptions->clusterRadius = value.integerValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionMaximumZoomLevelForClustering]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionMaximumZoomLevelForClustering must be an NSNumber."]; - } - geoJSONOptions->clusterMaxZoom = value.integerValue; - } - - if (NSNumber *value = options[MGLShapeSourceOptionClustered]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionClustered must be an NSNumber."]; - } - geoJSONOptions->cluster = value.boolValue; - } - - if (NSDictionary *value = options[MGLShapeSourceOptionClusterProperties]) { - if (![value isKindOfClass:[NSDictionary<NSString *, NSArray *> class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionClusterProperties must be an NSDictionary with an NSString as a key and an array containing two NSExpression objects as a value."]; - } - - NSEnumerator *stringEnumerator = [value keyEnumerator]; - NSString *key; - - while (key = [stringEnumerator nextObject]) { - NSArray *expressionsArray = value[key]; - if (![expressionsArray isKindOfClass:[NSArray class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionClusterProperties dictionary member value must be an array containing two objects."]; - } - // Check that the array has 2 values. One should be a the reduce expression and one should be the map expression. - if ([expressionsArray count] != 2) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionClusterProperties member value requires array of two objects."]; - } - - // reduceExpression should be a valid NSExpression - NSExpression *reduceExpression = expressionsArray[0]; - if (![reduceExpression isKindOfClass:[NSExpression class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionClusterProperties array value requires two expression objects."]; - } - auto reduce = MGLClusterPropertyFromNSExpression(reduceExpression); - if (!reduce) { - [NSException raise:NSInvalidArgumentException - format:@"Failed to convert MGLShapeSourceOptionClusterProperties reduce expression."]; - } - - // mapExpression should be a valid NSExpression - NSExpression *mapExpression = expressionsArray[1]; - if (![mapExpression isKindOfClass:[NSExpression class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionClusterProperties member value must contain a valid NSExpression."]; - } - auto map = MGLClusterPropertyFromNSExpression(mapExpression); - if (!map) { - [NSException raise:NSInvalidArgumentException - format:@"Failed to convert MGLShapeSourceOptionClusterProperties map expression."]; - } - - std::string keyString = std::string([key UTF8String]); - - geoJSONOptions->clusterProperties.emplace(keyString, std::make_pair(std::move(map), std::move(reduce))); - } - } - - if (NSNumber *value = options[MGLShapeSourceOptionLineDistanceMetrics]) { - if (![value isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLShapeSourceOptionLineDistanceMetrics must be an NSNumber."]; - } - geoJSONOptions->lineMetrics = value.boolValue; - } - - return geoJSONOptions; -} - -@interface MGLShapeSource () - -@property (nonatomic, readwrite) NSDictionary *options; -@property (nonatomic, readonly) mbgl::style::GeoJSONSource *rawSource; - -@end - -@implementation MGLShapeSource - -- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(NSDictionary<NSString *, id> *)options { - auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options); - auto source = std::make_unique<mbgl::style::GeoJSONSource>(identifier.UTF8String, std::move(geoJSONOptions)); - if (self = [super initWithPendingSource:std::move(source)]) { - self.URL = url; - } - return self; -} - -- (instancetype)initWithIdentifier:(NSString *)identifier shape:(nullable MGLShape *)shape options:(NSDictionary<MGLShapeSourceOption, id> *)options { - auto geoJSONOptions = MGLGeoJSONOptionsFromDictionary(options); - auto source = std::make_unique<mbgl::style::GeoJSONSource>(identifier.UTF8String, std::move(geoJSONOptions)); - if (self = [super initWithPendingSource:std::move(source)]) { - if ([shape isMemberOfClass:[MGLShapeCollection class]]) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSLog(@"MGLShapeCollection initialized with MGLFeatures will not retain attributes." - @"Use MGLShapeCollectionFeature to retain attributes instead." - @"This will be logged only once."); - }); - } - self.shape = shape; - } - return self; -} - -- (instancetype)initWithIdentifier:(NSString *)identifier features:(NSArray<MGLShape<MGLFeature> *> *)features options:(nullable NSDictionary<MGLShapeSourceOption, id> *)options { - for (id <MGLFeature> feature in features) { - if (![feature conformsToProtocol:@protocol(MGLFeature)]) { - [NSException raise:NSInvalidArgumentException format:@"The object %@ included in the features argument does not conform to the MGLFeature protocol.", feature]; - } - } - MGLShapeCollectionFeature *shapeCollectionFeature = [MGLShapeCollectionFeature shapeCollectionWithShapes:features]; - return [self initWithIdentifier:identifier shape:shapeCollectionFeature options:options]; -} - -- (instancetype)initWithIdentifier:(NSString *)identifier shapes:(NSArray<MGLShape *> *)shapes options:(nullable NSDictionary<MGLShapeSourceOption, id> *)options { - MGLShapeCollection *shapeCollection = [MGLShapeCollection shapeCollectionWithShapes:shapes]; - return [self initWithIdentifier:identifier shape:shapeCollection options:options]; -} - -- (mbgl::style::GeoJSONSource *)rawSource { - return (mbgl::style::GeoJSONSource *)super.rawSource; -} - -- (NSURL *)URL { - MGLAssertStyleSourceIsValid(); - auto url = self.rawSource->getURL(); - return url ? [NSURL URLWithString:@(url->c_str())] : nil; -} - -- (void)setURL:(NSURL *)url { - MGLAssertStyleSourceIsValid(); - if (url) { - self.rawSource->setURL(url.mgl_URLByStandardizingScheme.absoluteString.UTF8String); - _shape = nil; - } else { - self.shape = nil; - } -} - -- (void)setShape:(MGLShape *)shape { - MGLAssertStyleSourceIsValid(); - self.rawSource->setGeoJSON({ shape.geoJSONObject }); - _shape = shape; -} - -- (NSString *)description { - if (self.rawSource) { - return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; shape = %@>", - NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.shape]; - } - else { - return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = <unknown>; shape = %@>", - NSStringFromClass([self class]), (void *)self, self.identifier, self.shape]; - } -} - -- (NSArray<id <MGLFeature>> *)featuresMatchingPredicate:(nullable NSPredicate *)predicate { - MGLAssertStyleSourceIsValid(); - mbgl::optional<mbgl::style::Filter> optionalFilter; - if (predicate) { - optionalFilter = predicate.mgl_filter; - } - - std::vector<mbgl::Feature> features; - if (self.mapView) { - features = self.mapView.renderer->querySourceFeatures(self.rawSource->getID(), { {}, optionalFilter }); - } - return MGLFeaturesFromMBGLFeatures(features); -} - -#pragma mark - MGLCluster management - -- (mbgl::optional<mbgl::FeatureExtensionValue>)featureExtensionValueOfCluster:(MGLShape<MGLCluster> *)cluster extension:(std::string)extension options:(const std::map<std::string, mbgl::Value>)options { - MGLAssertStyleSourceIsValid(); - mbgl::optional<mbgl::FeatureExtensionValue> extensionValue; - - // Check parameters - if (!self.rawSource || !self.mapView || !cluster) { - return extensionValue; - } - - auto geoJSON = [cluster geoJSONObject]; - - if (!geoJSON.is<mbgl::GeoJSONFeature>()) { - MGLAssert(0, @"cluster geoJSON object is not a feature."); - return extensionValue; - } - - auto clusterFeature = geoJSON.get<mbgl::GeoJSONFeature>(); - - extensionValue = self.mapView.renderer->queryFeatureExtensions(self.rawSource->getID(), - clusterFeature, - "supercluster", - extension, - options); - return extensionValue; -} - -- (NSArray<id <MGLFeature>> *)leavesOfCluster:(MGLPointFeatureCluster *)cluster offset:(NSUInteger)offset limit:(NSUInteger)limit { - const std::map<std::string, mbgl::Value> options = { - { "limit", static_cast<uint64_t>(limit) }, - { "offset", static_cast<uint64_t>(offset) } - }; - - auto featureExtension = [self featureExtensionValueOfCluster:cluster extension:"leaves" options:options]; - - if (!featureExtension) { - return @[]; - } - - if (!featureExtension->is<mbgl::FeatureCollection>()) { - return @[]; - } - - std::vector<mbgl::GeoJSONFeature> leaves = featureExtension->get<mbgl::FeatureCollection>(); - return MGLFeaturesFromMBGLFeatures(leaves); -} - -- (NSArray<id <MGLFeature>> *)childrenOfCluster:(MGLPointFeatureCluster *)cluster { - auto featureExtension = [self featureExtensionValueOfCluster:cluster extension:"children" options:{}]; - - if (!featureExtension) { - return @[]; - } - - if (!featureExtension->is<mbgl::FeatureCollection>()) { - return @[]; - } - - std::vector<mbgl::GeoJSONFeature> leaves = featureExtension->get<mbgl::FeatureCollection>(); - return MGLFeaturesFromMBGLFeatures(leaves); -} - -- (double)zoomLevelForExpandingCluster:(MGLPointFeatureCluster *)cluster { - auto featureExtension = [self featureExtensionValueOfCluster:cluster extension:"expansion-zoom" options:{}]; - - if (!featureExtension) { - return -1.0; - } - - if (!featureExtension->is<mbgl::Value>()) { - return -1.0; - } - - auto value = featureExtension->get<mbgl::Value>(); - if (value.is<uint64_t>()) { - auto zoom = value.get<uint64_t>(); - return static_cast<double>(zoom); - } - - return -1.0; -} - -- (void)debugRecursiveLogForFeature:(id <MGLFeature>)feature indent:(NSUInteger)indent { - NSString *description = feature.description; - - // Want our recursive log on a single line - NSString *log = [description stringByReplacingOccurrencesOfString:@"\\s+" - withString:@" " - options:NSRegularExpressionSearch - range:NSMakeRange(0, description.length)]; - - printf("%*s%s\n", (int)indent, "", log.UTF8String); - - MGLPointFeatureCluster *cluster = MGL_OBJC_DYNAMIC_CAST(feature, MGLPointFeatureCluster); - - if (cluster) { - for (id <MGLFeature> child in [self childrenOfCluster:cluster]) { - [self debugRecursiveLogForFeature:child indent:indent + 4]; - } - } -} - -@end diff --git a/platform/darwin/src/MGLShapeSource_Private.h b/platform/darwin/src/MGLShapeSource_Private.h deleted file mode 100644 index 940c80a17d..0000000000 --- a/platform/darwin/src/MGLShapeSource_Private.h +++ /dev/null @@ -1,33 +0,0 @@ -#import "MGLFoundation.h" -#import "MGLShapeSource.h" - -#include <mbgl/util/immutable.hpp> - -NS_ASSUME_NONNULL_BEGIN - -namespace mbgl { - namespace style { - struct GeoJSONOptions; - } -} - -MGL_EXPORT -mbgl::Immutable<mbgl::style::GeoJSONOptions> MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShapeSourceOption, id> *options); - -@interface MGLShapeSource (Private) - -/** - :nodoc: - Debug log showing structure of an `MGLFeature`. This method recurses in the case - that the feature conforms to `MGLCluster`. This method is used for testing and - should be considered experimental, likely to be removed or changed in future - releases. - - @param feature An object that conforms to the `MGLFeature` protocol. - @param indent Used during recursion. Specify 0. - */ - -- (void)debugRecursiveLogForFeature:(id<MGLFeature>)feature indent:(NSUInteger)indent; -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLShape_Private.h b/platform/darwin/src/MGLShape_Private.h deleted file mode 100644 index 9821d49176..0000000000 --- a/platform/darwin/src/MGLShape_Private.h +++ /dev/null @@ -1,26 +0,0 @@ -#import "MGLShape.h" - -#import <mbgl/util/geojson.hpp> -#import <mbgl/util/geometry.hpp> -#import <mbgl/util/geo.hpp> - -bool operator==(const CLLocationCoordinate2D lhs, const CLLocationCoordinate2D rhs); - -@interface MGLShape (Private) - -/** - Returns an `mbgl::GeoJSON` representation of the `MGLShape`. - */ -- (mbgl::GeoJSON)geoJSONObject; - -/** - Returns an `mbgl::Geometry<double>` representation of the `MGLShape`. - */ -- (mbgl::Geometry<double>)geometryObject; - -/** - Returns a dictionary with the GeoJSON geometry member object. - */ -- (NSDictionary *)geoJSONDictionary; - -@end diff --git a/platform/darwin/src/MGLSource.h b/platform/darwin/src/MGLSource.h deleted file mode 100644 index dc92e652e8..0000000000 --- a/platform/darwin/src/MGLSource.h +++ /dev/null @@ -1,56 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLInvalidStyleSourceException; - -/** - `MGLSource` is an abstract base class for map content sources. A map content - source supplies content to be shown on the map. A source is added to an - `MGLStyle` object along with an `MGLForegroundStyleLayer` object. The - foreground style layer defines the appearance of any content supplied by the - source. - - Each source defined by the style JSON file is represented at runtime by an - `MGLSource` object that you can use to refine the map’s content. You can also - add and remove sources dynamically using methods such as - `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`. - - Create instances of `MGLShapeSource`, `MGLComputedShapeSource`, - `MGLImageSource`, and the concrete subclasses of `MGLTileSource` - (`MGLVectorTileSource` and `MGLRasterTileSource`) in order to use `MGLSource`’s - properties and methods. Do not create instances of `MGLSource` directly, and do - not create your own subclasses of this class. - */ -MGL_EXPORT -@interface MGLSource : NSObject - -#pragma mark Initializing a Source - -- (instancetype)init __attribute__((unavailable("Use -initWithIdentifier: instead."))); - -/** - Returns a source initialized with an identifier. - - After initializing and configuring the source, add it to a map view’s style - using the `-[MGLStyle addSource:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @return An initialized source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier; - -#pragma mark Identifying a Source - -/** - A string that uniquely identifies the source in the style to which it is added. - */ -@property (nonatomic, copy) NSString *identifier; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm deleted file mode 100644 index 1d7b46e1cc..0000000000 --- a/platform/darwin/src/MGLSource.mm +++ /dev/null @@ -1,120 +0,0 @@ -#import "MGLSource_Private.h" -#import "MGLStyle_Private.h" -#import "MGLMapView_Private.h" -#import "NSBundle+MGLAdditions.h" - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MMEEventsManager.h" -#endif - -#include <mbgl/style/style.hpp> -#include <mbgl/map/map.hpp> -#include <mbgl/style/source.hpp> - -const MGLExceptionName MGLInvalidStyleSourceException = @"MGLInvalidStyleSourceException"; - -@interface MGLSource () - -// Even though this class is abstract, MGLStyle uses it to represent some -// special internal source types like mbgl::AnnotationSource. -@property (nonatomic, readonly) mbgl::style::Source *rawSource; - -@property (nonatomic, readonly, weak) MGLMapView *mapView; - -@end - -@implementation MGLSource { - std::unique_ptr<mbgl::style::Source> _pendingSource; - mapbox::base::WeakPtr<mbgl::style::Source> _weakSource; -} - - -- (instancetype)initWithIdentifier:(NSString *)identifier -{ - if (self = [super init]) { - _identifier = [identifier copy]; - } - return self; -} - -- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource mapView:(MGLMapView *)mapView { - NSString *identifier = @(rawSource->getID().c_str()); - if (self = [self initWithIdentifier:identifier]) { - _weakSource = rawSource->makeWeakPtr(); - rawSource->peer = SourceWrapper { self }; - _mapView = mapView; - } - return self; -} - -- (mbgl::style::Source *)rawSource -{ - return _weakSource.get(); -} - -- (instancetype)initWithPendingSource:(std::unique_ptr<mbgl::style::Source>)pendingSource { - if (self = [self initWithRawSource:pendingSource.get() mapView:nil]) { - _pendingSource = std::move(pendingSource); - } - return self; -} - -- (void)addToMapView:(MGLMapView *)mapView { - if (_pendingSource == nullptr) { - [NSException raise:MGLRedundantSourceException - format:@"This instance %@ was already added to %@. Adding the same source instance " \ - "to the style more than once is invalid.", self, mapView.style]; - } - - _mapView = mapView; - _mapView.style.rawStyle->addSource(std::move(_pendingSource)); -} - -- (BOOL)removeFromMapView:(MGLMapView *)mapView error:(NSError * __nullable * __nullable)outError { - MGLAssertStyleSourceIsValid(); - BOOL removed = NO; - - if (self.rawSource == mapView.style.rawStyle->getSource(self.identifier.UTF8String)) { - - auto removedSource = mapView.style.rawStyle->removeSource(self.identifier.UTF8String); - - if (removedSource) { - removed = YES; - _pendingSource = std::move(removedSource); - _mapView = nil; - } else if (outError) { - NSString *localizedDescription = [NSString stringWithFormat: - NSLocalizedStringWithDefaultValue(@"REMOVE_SRC_FAIL_IN_USE_FMT", @"Foundation", nil, @"The source “%@” can’t be removed while it is in use.", @"User-friendly error description; first placeholder is the source’s identifier"), - self.identifier]; - - *outError = [NSError errorWithDomain:MGLErrorDomain - code:MGLErrorCodeSourceIsInUseCannotRemove - userInfo:@{ NSLocalizedDescriptionKey : localizedDescription }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:*outError]; -#endif - - } - } else if (outError) { - // TODO: Consider raising an exception here - NSString *localizedDescription = [NSString stringWithFormat: - NSLocalizedStringWithDefaultValue(@"REMOVE_SRC_FAIL_MISMATCH_FMT", @"Foundation", nil, @"The source can’t be removed because its identifier, “%@”, belongs to a different source in this style.", @"User-friendly error description"), - self.identifier]; - - *outError = [NSError errorWithDomain:MGLErrorDomain - code:MGLErrorCodeSourceIdentifierMismatch - userInfo:@{ NSLocalizedDescriptionKey : localizedDescription }]; -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - [[MMEEventsManager sharedManager] reportError:*outError]; -#endif - } - - return removed; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"<%@: %p; identifier = %@>", - NSStringFromClass([self class]), (void *)self, self.identifier]; -} - -@end diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h deleted file mode 100644 index 4a7c31694d..0000000000 --- a/platform/darwin/src/MGLSource_Private.h +++ /dev/null @@ -1,89 +0,0 @@ -#import "MGLSource.h" - -#include <memory> - - -NS_ASSUME_NONNULL_BEGIN - -namespace mbgl { - namespace style { - class Source; - } -} - -// A struct to be stored in the `peer` member of mbgl::style::Source, in order to implement -// object identity. We don't store a MGLSource pointer directly because that doesn't -// interoperate with ARC. The inner pointer is weak in order to avoid a reference cycle for -// "pending" MGLSources, which have a strong owning pointer to the mbgl::style::Source. -struct SourceWrapper { - __weak MGLSource *source; -}; - -/** - Assert that the style source is valid. - - This macro should be used at the beginning of any public-facing instance method - of `MGLSource` and its subclasses. For private methods, an assertion is more appropriate. - */ -#define MGLAssertStyleSourceIsValid() \ -do { \ - if (!self.rawSource) { \ - [NSException raise:MGLInvalidStyleSourceException \ - format:@"This source got invalidated after the style change"]; \ - } \ -} while (NO); - -@class MGLMapView; - -@interface MGLSource (Private) - -/** - Initializes and returns a source with a raw pointer to the backing store, - associated with a style. - */ -- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource mapView:(nullable MGLMapView *)mapView; - -/** - Initializes and returns a source with an owning pointer to the backing store, - unassociated from a style. - */ -- (instancetype)initWithPendingSource:(std::unique_ptr<mbgl::style::Source>)pendingSource; - -/** - A raw pointer to the mbgl object, which is always initialized, either to the - value returned by `mbgl::Map getSource`, or for independently created objects, - to the pointer value held in `pendingSource`. In the latter case, this raw - pointer value stays even after ownership of the object is transferred via - `mbgl::Map addSource`. - */ -@property (nonatomic, readonly) mbgl::style::Source *rawSource; - -/** - The map view whose style currently contains the source. - If the source is not currently part of any map view’s style, this property is - set to `nil`. - */ -@property (nonatomic, readonly, weak) MGLMapView *mapView; - -/** - Adds the mbgl source that this object represents to the mbgl map. - Once a mbgl source is added, ownership of the object is transferred to the - `mbgl::Map` and this object no longer has an active unique_ptr reference to the - `mbgl::Source`. If this object's mbgl source is in that state, the mbgl source - can still be changed but the changes will not be visible until the `MGLSource` - is added back to the map via `-[MGLStyle addSource:]` and styled with a - `MGLLayer`. - */ -- (void)addToMapView:(MGLMapView *)mapView; - -/** - Removes the mbgl source that this object represents from the mbgl map. - When a mbgl source is removed, ownership of the object is transferred back - to the `MGLSource` instance and the unique_ptr reference is valid again. It is - safe to add the source back to the style after it is removed. - */ -- (BOOL)removeFromMapView:(MGLMapView *)mapView error:(NSError * __nullable * __nullable)outError; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h deleted file mode 100644 index ac5f749920..0000000000 --- a/platform/darwin/src/MGLStyle.h +++ /dev/null @@ -1,542 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLStyleLayer.h" - -#import "MGLTypes.h" - -@class MGLSource; -@class MGLLight; - -NS_ASSUME_NONNULL_BEGIN - -/** - A version number identifying the default version of the Mapbox Streets style - obtained through the `MGLStyle.streetsStyleURL` method. This version number may also be - passed into the `+[MGLStyle streetsStyleURLWithVersion:]` method. - - The value of this constant generally corresponds to the latest released version - as of the date on which this SDK was published. You can use this constant to - ascertain the style used by `MGLMapView` and `MGLTilePyramidOfflineRegion` when - no style URL is specified. Consult the - <a href="https://docs.mapbox.com/api/maps/#styles">Mapbox Styles API documentation</a> - for the most up-to-date style versioning information. - - @warning The value of this constant may change in a future release of the SDK. - If you use any feature that depends on a specific aspect of a default style - — for instance, the minimum zoom level that includes roads — you may use the - current value of this constant or the underlying style URL, but do not use - the constant itself. Such details may change significantly from version to - version. - */ -static MGL_EXPORT const NSInteger MGLStyleDefaultVersion = 11; - -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLInvalidStyleURLException; -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLRedundantLayerException; -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLRedundantLayerIdentifierException; -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLRedundantSourceException; -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLRedundantSourceIdentifierException; - -/** - The proxy object for the current map style. - - MGLStyle provides a set of convenience methods for changing Mapbox - default styles using `MGLMapView.styleURL`. - <a href="https://www.mapbox.com/maps/">Learn more about Mapbox default styles</a>. - - It is also possible to directly manipulate the current map style - via `MGLMapView.style` by updating the style's data sources or layers. - - @note Wait until the map style has finished loading before modifying a map's - style via any of the `MGLStyle` instance methods below. You can use the - `-[MGLMapViewDelegate mapView:didFinishLoadingStyle:]` or - `-[MGLMapViewDelegate mapViewDidFinishLoadingMap:]` methods as indicators - that it's safe to modify the map's style. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/default-styles/"> - Default styles</a> example to learn how to initialize an `MGLMapView` object - with a Mapbox default style using `MGLStyle`'s class methods. - */ -MGL_EXPORT -@interface MGLStyle : NSObject - -#pragma mark Accessing Default Styles - -/** - Returns the URL to the current version of the - <a href="https://www.mapbox.com/maps/streets/">Mapbox Streets</a> style as of - publication. - - Streets is a general-purpose style with detailed road and transit networks. - - `MGLMapView` and `MGLTilePyramidOfflineRegion` use Mapbox Streets when no style - is specified explicitly. - - @warning The return value may change in a future release of the SDK. If you use - any feature that depends on a specific aspect of a default style — for - instance, the minimum zoom level that includes roads — use the - `+streetsStyleURLWithVersion:` method instead. Such details may change - significantly from version to version. - */ -@property (class, nonatomic, readonly) NSURL *streetsStyleURL; - -/** - Returns the URL to the given version of the - <a href="https://www.mapbox.com/maps/streets/">Mapbox Streets</a> style. - - Streets is a general-purpose style with detailed road and transit networks. - - `MGLMapView` and `MGLTilePyramidOfflineRegion` use Mapbox Streets when no style - is specified explicitly. - - @param version A specific version of the style. - */ -+ (NSURL *)streetsStyleURLWithVersion:(NSInteger)version; - -/** - Returns the URL to the current version of the - <a href="https://www.mapbox.com/maps/outdoors/">Mapbox Outdoors</a> style as of - publication. - - Outdoors is a general-purpose style tailored to outdoor activities. - - @warning The return value may change in a future release of the SDK. If you use - any feature that depends on a specific aspect of a default style — for - instance, the minimum zoom level that includes roads — use the - `+outdoorsStyleURLWithVersion:` method instead. Such details may change - significantly from version to version. - */ -@property (class, nonatomic, readonly) NSURL *outdoorsStyleURL; - -/** - Returns the URL to the given version of the - <a href="https://www.mapbox.com/maps/outdoors/">Mapbox Outdoors</a> style. - - Outdoors is a general-purpose style tailored to outdoor activities. - - @param version A specific version of the style. - */ -+ (NSURL *)outdoorsStyleURLWithVersion:(NSInteger)version; - -/** - Returns the URL to the current version of the - <a href="https://www.mapbox.com/maps/light-dark/">Mapbox Light</a> style. - - Light is a subtle, light-colored backdrop for data visualizations. - - @warning The return value may change in a future release of the SDK. If you use - any feature that depends on a specific aspect of a default style — for - instance, the minimum zoom level that includes roads — use the - `+lightStyleURLWithVersion:` method instead. Such details may change - significantly from version to version. - */ -@property (class, nonatomic, readonly) NSURL *lightStyleURL; - -/** - Returns the URL to the given version of the - <a href="https://www.mapbox.com/maps/light-dark/">Mapbox Light</a> style as of - publication. - - Light is a subtle, light-colored backdrop for data visualizations. - - @param version A specific version of the style. - */ -+ (NSURL *)lightStyleURLWithVersion:(NSInteger)version; - -/** - Returns the URL to the current version of the - <a href="https://www.mapbox.com/maps/light-dark/">Mapbox Dark</a> style. - - Dark is a subtle, dark-colored backdrop for data visualizations. - - @warning The return value may change in a future release of the SDK. If you use - any feature that depends on a specific aspect of a default style — for - instance, the minimum zoom level that includes roads — use the - `+darkStyleURLWithVersion:` method instead. Such details may change - significantly from version to version. - */ -@property (class, nonatomic, readonly) NSURL *darkStyleURL; - -/** - Returns the URL to the given version of the - <a href="https://www.mapbox.com/maps/light-dark/">Mapbox Dark</a> style as of - publication. - - Dark is a subtle, dark-colored backdrop for data visualizations. - - @param version A specific version of the style. - */ -+ (NSURL *)darkStyleURLWithVersion:(NSInteger)version; - -/** - Returns the URL to the current version of the - <a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite</a> style. - - Satellite is high-resolution satellite and aerial imagery. - - @warning The return value may change in a future release of the SDK. If you use - any feature that depends on a specific aspect of a default style — for - instance, the raster tile sets included in the style — use the - `+satelliteStyleURLWithVersion:` method instead. Such details may change - significantly from version to version. - - #### Related example - See the <a href="https://docs.mapbox.com/ios/maps/examples/satellite-style/"> - Satellite styles</a> example to learn how to initialize a map with the Mapbox - Satellite style. - */ -@property (class, nonatomic, readonly) NSURL *satelliteStyleURL; - -/** - Returns the URL to the given version of the - <a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite</a> style as - of publication. - - Satellite is high-resolution satellite and aerial imagery. - - @param version A specific version of the style. - */ -+ (NSURL *)satelliteStyleURLWithVersion:(NSInteger)version; - -/** - Returns the URL to the current version of the - <a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite Streets</a> - style as of publication. - - Satellite Streets combines the high-resolution satellite and aerial imagery of - Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox - Streets. - - @warning The return value may change in a future release of the SDK. If you use - any feature that depends on a specific aspect of a default style — for - instance, the minimum zoom level that includes roads — use the - `+satelliteStreetsStyleURLWithVersion:` method instead. Such details may - change significantly from version to version. - - #### Related example - See the <a href="https://docs.mapbox.com/ios/maps/examples/satellite-style/"> - Satellite styles</a> example to learn how to initialize a map with the Mapbox - Satellite Streets style. - */ -@property (class, nonatomic, readonly) NSURL *satelliteStreetsStyleURL; - -/** - Returns the URL to the given version of the - <a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite Streets</a> - style. - - Satellite Streets combines the high-resolution satellite and aerial imagery of - Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox - Streets. - - @param version A specific version of the style. - */ -+ (NSURL *)satelliteStreetsStyleURLWithVersion:(NSInteger)version; - -#pragma mark Accessing Metadata About the Style - -/** - The name of the style. - - You can customize the style’s name in Mapbox Studio. - */ -@property (readonly, copy, nullable) NSString *name; - -#pragma mark Managing Sources - -/** - A set containing the style’s sources. - */ -@property (nonatomic, strong) NSSet<__kindof MGLSource *> *sources; - -/** - Values describing animated transitions to changes on a style's individual - paint properties. - */ -@property (nonatomic) MGLTransition transition; - -/** - A boolean value indicating whether label placement transitions are enabled. - - The default value of this property is `YES`. - */ -@property (nonatomic, assign) BOOL performsPlacementTransitions; - -/** - Returns a source with the given identifier in the current style. - - @note Source identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set the - style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids source identifer name changes that will occur in the default - style’s sources over time. - - @return An instance of a concrete subclass of `MGLSource` associated with the - given identifier, or `nil` if the current style contains no such source. - */ -- (nullable MGLSource *)sourceWithIdentifier:(NSString *)identifier; - -/** - Adds a new source to the current style. - - @note Adding the same source instance more than once will result in a - `MGLRedundantSourceException`. Reusing the same source identifier, even with - different source instances, will result in a - `MGLRedundantSourceIdentifierException`. - - @note Sources should be added in - `-[MGLMapViewDelegate mapView:didFinishLoadingStyle:]` or - `-[MGLMapViewDelegate mapViewDidFinishLoadingMap:]` to ensure that the map - has loaded the style and is ready to accept a new source. - - @param source The source to add to the current style. - */ -- (void)addSource:(MGLSource *)source; - -/** - Removes a source from the current style. - - @note Source identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set the - style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids source identifer name changes that will occur in the default - style’s sources over time. - - @param source The source to remove from the current style. - */ -- (void)removeSource:(MGLSource *)source; - -/** - Removes a source from the current style. - - @note Source identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set the - style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids source identifer name changes that will occur in the default - style’s sources over time. - - @param source The source to remove from the current style. - @param outError Upon return, if an error has occurred, a pointer to an `NSError` - object describing the error. Pass in `NULL` to ignore any error. - - @return `YES` if `source` was removed successfully. If `NO`, `outError` contains - an `NSError` object describing the problem. - */ -- (BOOL)removeSource:(MGLSource *)source error:(NSError * __nullable * __nullable)outError; - - -#pragma mark Managing Style Layers - -/** - The layers included in the style, arranged according to their back-to-front - ordering on the screen. - */ -@property (nonatomic, strong) NSArray<__kindof MGLStyleLayer *> *layers; - -/** - Returns a style layer with the given identifier in the current style. - - @note Layer identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set - the style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids layer identifer name changes that will occur in the default - style’s layers over time. - - @return An instance of a concrete subclass of `MGLStyleLayer` associated with - the given identifier, or `nil` if the current style contains no such style - layer. - */ -- (nullable MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier; - -/** - Adds a new layer on top of existing layers. - - @note Adding the same layer instance more than once will result in a - `MGLRedundantLayerException`. Reusing the same layer identifer, even with - different layer instances, will also result in an exception. - - @note Layers should be added in - `-[MGLMapViewDelegate mapView:didFinishLoadingStyle:]` or - `-[MGLMapViewDelegate mapViewDidFinishLoadingMap:]` to ensure that the map - has loaded the style and is ready to accept a new layer. - - @param layer The layer object to add to the map view. This object must be an - instance of a concrete subclass of `MGLStyleLayer`. - */ -- (void)addLayer:(MGLStyleLayer *)layer; - -/** - Inserts a new layer into the style at the given index. - - @note Adding the same layer instance more than once will result in a - `MGLRedundantLayerException`. Reusing the same layer identifer, even with - different layer instances, will also result in an exception. - - @note Layers should be added in - `-[MGLMapViewDelegate mapView:didFinishLoadingStyle:]` or - `-[MGLMapViewDelegate mapViewDidFinishLoadingMap:]` to ensure that the map - has loaded the style and is ready to accept a new layer. - - @param layer The layer to insert. - @param index The index at which to insert the layer. An index of 0 would send - the layer to the back; an index equal to the number of objects in the - `layers` property would bring the layer to the front. - */ -- (void)insertLayer:(MGLStyleLayer *)layer atIndex:(NSUInteger)index; - -/** - Inserts a new layer below another layer. - - @note Layer identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set - the style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids layer identifer name changes that will occur in the default - style’s layers over time. - - Inserting the same layer instance more than once will result in a - `MGLRedundantLayerException`. Reusing the same layer identifer, even with - different layer instances, will also result in an exception. - - @param layer The layer to insert. - @param sibling An existing layer in the style. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/shape-collection/"> - Add multiple shapes from a single shape source</a> example to learn how to - add a layer to your map below an existing layer. - */ -- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)sibling; - -/** - Inserts a new layer above another layer. - - @note Layer identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set - the style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids layer identifer name changes that will occur in the default - style’s layers over time. - - Inserting the same layer instance more than once will result in a - `MGLRedundantLayerException`. Reusing the same layer identifer, even with - different layer instances, will also result in an exception. - - @param layer The layer to insert. - @param sibling An existing layer in the style. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/image-source/"> - Add an image</a> example to learn how to add a layer to your map above an - existing layer. - */ -- (void)insertLayer:(MGLStyleLayer *)layer aboveLayer:(MGLStyleLayer *)sibling; - -/** - Removes a layer from the map view. - - @note Layer identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set - the style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids layer identifer name changes that will occur in the default - style’s layers over time. - - @param layer The layer object to remove from the map view. This object - must conform to the `MGLStyleLayer` protocol. - */ -- (void)removeLayer:(MGLStyleLayer *)layer; - -#pragma mark Managing a Style’s Images - -/** - Returns the image associated with the given name in the style. - - @note Names and their associated images are not guaranteed to exist across - styles or different versions of the same style. Applications that use this - API must first set the style URL to an explicitly versioned style using a - convenience method like `+[MGLStyle outdoorsStyleURLWithVersion:]`, - `MGLMapView`’s “Style URL” inspectable in Interface Builder, or a manually - constructed `NSURL`. This approach also avoids image name changes that will - occur in the default style over time. - - @param name The name associated with the image you want to obtain. - @return The image associated with the given name, or `nil` if no image is - associated with that name. - */ -- (nullable MGLImage *)imageForName:(NSString *)name; - -/** - Adds or overrides an image used by the style’s layers. - - To use an image in a style layer, give it a unique name using this method, then - set the `iconImageName` property of an `MGLSymbolStyleLayer` object to that - name. - - @param image The image for the name. - @param name The name of the image to set to the style. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/clustering-with-images/"> - Use images to cluster point data</a> and <a href="https://docs.mapbox.com/ios/maps/examples/clustering/"> - Cluster point data</a> examples to learn how to add images to your map using - an `MGLStyle` object. - */ -- (void)setImage:(MGLImage *)image forName:(NSString *)name; - -/** - Removes a name and its associated image from the style. - - @note Names and their associated images are not guaranteed to exist across - styles or different versions of the same style. Applications that use this - API must first set the style URL to an explicitly versioned style using a - convenience method like `+[MGLStyle outdoorsStyleURLWithVersion:]`, - `MGLMapView`’s “Style URL” inspectable in Interface Builder, or a manually - constructed `NSURL`. This approach also avoids image name changes that will - occur in the default style over time. - - @param name The name of the image to remove. - */ -- (void)removeImageForName:(NSString *)name; - - -#pragma mark Managing the Style's Light - -/** - Provides global light source for the style. - */ -@property (nonatomic, strong) MGLLight *light; - -#pragma mark Localizing Map Content - -/** - Attempts to localize labels in the style into the given locale. - - This method automatically modifies the text property of any symbol style layer - in the style whose source is the - <a href="https://www.mapbox.com/vector-tiles/mapbox-streets-v8/#overview">Mapbox Streets source</a>. - On iOS, the user can set the system’s preferred language in Settings, General - Settings, Language & Region. On macOS, the user can set the system’s preferred - language in the Language & Region pane of System Preferences. - - @param locale The locale into which labels should be localized. To use the - system’s preferred language, if supported, specify `nil`. To use the local - language, specify a locale with the identifier `mul`. - */ -- (void)localizeLabelsIntoLocale:(nullable NSLocale *)locale; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm deleted file mode 100644 index 6a496dc3c0..0000000000 --- a/platform/darwin/src/MGLStyle.mm +++ /dev/null @@ -1,636 +0,0 @@ -#import "MGLStyle_Private.h" - -#import "MGLMapView_Private.h" -#import "MGLStyleLayer.h" -#import "MGLStyleLayer_Private.h" -#import "MGLFillStyleLayer.h" -#import "MGLFillExtrusionStyleLayer.h" -#import "MGLLineStyleLayer.h" -#import "MGLCircleStyleLayer.h" -#import "MGLSymbolStyleLayer.h" -#import "MGLHeatmapStyleLayer.h" -#import "MGLHillshadeStyleLayer.h" -#import "MGLRasterStyleLayer.h" -#import "MGLBackgroundStyleLayer.h" -#import "MGLOpenGLStyleLayer.h" -#import "MGLStyleLayerManager.h" - -#import "MGLSource.h" -#import "MGLSource_Private.h" -#import "MGLLight_Private.h" -#import "MGLTileSource_Private.h" -#import "MGLVectorTileSource_Private.h" -#import "MGLRasterTileSource.h" -#import "MGLRasterDEMSource.h" -#import "MGLShapeSource.h" -#import "MGLImageSource.h" - -#import "MGLAttributionInfo_Private.h" -#import "MGLLoggingConfiguration_Private.h" - -#include <mbgl/map/map.hpp> -#include <mbgl/util/default_styles.hpp> -#include <mbgl/style/style.hpp> -#include <mbgl/style/image.hpp> -#include <mbgl/style/light.hpp> -#include <mbgl/style/sources/geojson_source.hpp> -#include <mbgl/style/sources/vector_source.hpp> -#include <mbgl/style/sources/raster_source.hpp> -#include <mbgl/style/sources/raster_dem_source.hpp> -#include <mbgl/style/sources/image_source.hpp> - -#import "NSDate+MGLAdditions.h" - -#if TARGET_OS_IPHONE - #import "UIImage+MGLAdditions.h" -#else - #import "NSImage+MGLAdditions.h" -#endif - -const MGLExceptionName MGLInvalidStyleURLException = @"MGLInvalidStyleURLException"; -const MGLExceptionName MGLRedundantLayerException = @"MGLRedundantLayerException"; -const MGLExceptionName MGLRedundantLayerIdentifierException = @"MGLRedundantLayerIdentifierException"; -const MGLExceptionName MGLRedundantSourceException = @"MGLRedundantSourceException"; -const MGLExceptionName MGLRedundantSourceIdentifierException = @"MGLRedundantSourceIdentifierException"; - -/** - Model class for localization changes. - */ -@interface MGLTextLanguage: NSObject -@property (strong, nonatomic) NSString *originalTextField; -@property (strong, nonatomic) NSString *updatedTextField; - -- (instancetype)initWithTextLanguage:(NSString *)originalTextField updatedTextField:(NSString *)updatedTextField; - -@end - -@implementation MGLTextLanguage -- (instancetype)initWithTextLanguage:(NSString *)originalTextField updatedTextField:(NSString *)updatedTextField -{ - if (self = [super init]) { - _originalTextField = originalTextField; - _updatedTextField = updatedTextField; - } - return self; -} -@end - -@interface MGLStyle() - -@property (nonatomic, readonly, weak) MGLMapView *mapView; -@property (nonatomic, readonly) mbgl::style::Style *rawStyle; -@property (readonly, copy, nullable) NSURL *URL; -@property (nonatomic, readwrite, strong) NSMutableDictionary<NSString *, MGLOpenGLStyleLayer *> *openGLLayers; -@property (nonatomic) NSMutableDictionary<NSString *, NSDictionary<NSObject *, MGLTextLanguage *> *> *localizedLayersByIdentifier; - -@end - -@implementation MGLStyle - -#pragma mark Default style URLs - -/// @param name The style’s marketing name, written in lower camelCase. -/// @param fileName The last path component in the style’s URL, excluding the version suffix. -#define MGL_DEFINE_STYLE(name, fileName) \ - static NSURL *MGLStyleURL_##name; \ - + (NSURL *)name##StyleURL { \ - static dispatch_once_t onceToken; \ - dispatch_once(&onceToken, ^{ \ - MGLStyleURL_##name = [self name##StyleURLWithVersion:mbgl::util::default_styles::name.currentVersion]; \ - }); \ - return MGLStyleURL_##name; \ - } \ - \ - + (NSURL *)name##StyleURL##WithVersion:(NSInteger)version { \ - return [NSURL URLWithString:[@"mapbox://styles/mapbox/" #fileName "-v" stringByAppendingFormat:@"%li", (long)version]]; \ - } - -MGL_DEFINE_STYLE(streets, streets) -MGL_DEFINE_STYLE(outdoors, outdoors) -MGL_DEFINE_STYLE(light, light) -MGL_DEFINE_STYLE(dark, dark) -MGL_DEFINE_STYLE(satellite, satellite) -MGL_DEFINE_STYLE(satelliteStreets, satellite-streets) - -// Make sure all the styles listed in mbgl::util::default_styles::orderedStyles -// are defined above and also declared in MGLStyle.h. -static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - "mbgl::util::default_styles::orderedStyles and MGLStyle have different numbers of styles."); - -#pragma mark - - -- (instancetype)initWithRawStyle:(mbgl::style::Style *)rawStyle mapView:(MGLMapView *)mapView { - MGLLogInfo(@"Initializing %@ with mapView: %@", NSStringFromClass([self class]), mapView); - if (self = [super init]) { - _mapView = mapView; - _rawStyle = rawStyle; - _openGLLayers = [NSMutableDictionary dictionary]; - _localizedLayersByIdentifier = [NSMutableDictionary dictionary]; - MGLLogDebug(@"Initializing with style name: %@ mapView: %@", self.name, mapView); - } - return self; -} - -- (NSURL *)URL { - return [NSURL URLWithString:@(self.rawStyle->getURL().c_str())]; -} - -- (NSString *)name { - std::string name = self.rawStyle->getName(); - return name.empty() ? nil : @(name.c_str()); -} - -#pragma mark Sources - -- (NSSet<__kindof MGLSource *> *)sources { - auto rawSources = self.rawStyle->getSources(); - NSMutableSet<__kindof MGLSource *> *sources = [NSMutableSet setWithCapacity:rawSources.size()]; - for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) { - MGLSource *source = [self sourceFromMBGLSource:*rawSource]; - [sources addObject:source]; - } - return sources; -} - -- (void)setSources:(NSSet<__kindof MGLSource *> *)sources { - MGLLogDebug(@"Setting: %lu sources", sources.count); - for (MGLSource *source in self.sources) { - [self removeSource:source]; - } - for (MGLSource *source in sources) { - [self addSource:source]; - } -} - -- (NSUInteger)countOfSources { - return self.rawStyle->getSources().size(); -} - -- (MGLSource *)memberOfSources:(MGLSource *)object { - return [self sourceWithIdentifier:object.identifier]; -} - -- (MGLSource *)sourceWithIdentifier:(NSString *)identifier -{ - MGLLogDebug(@"Querying source with identifier: %@", identifier); - auto rawSource = self.rawStyle->getSource(identifier.UTF8String); - - return rawSource ? [self sourceFromMBGLSource:rawSource] : nil; -} - -- (MGLSource *)sourceFromMBGLSource:(mbgl::style::Source *)rawSource { - if (MGLSource *source = rawSource->peer.has_value() ? rawSource->peer.get<SourceWrapper>().source : nil) { - return source; - } - - // TODO: Fill in options specific to the respective source classes - // https://github.com/mapbox/mapbox-gl-native/issues/6584 - if (auto vectorSource = rawSource->as<mbgl::style::VectorSource>()) { - return [[MGLVectorTileSource alloc] initWithRawSource:vectorSource mapView:self.mapView]; - } else if (auto geoJSONSource = rawSource->as<mbgl::style::GeoJSONSource>()) { - return [[MGLShapeSource alloc] initWithRawSource:geoJSONSource mapView:self.mapView]; - } else if (auto rasterSource = rawSource->as<mbgl::style::RasterSource>()) { - return [[MGLRasterTileSource alloc] initWithRawSource:rasterSource mapView:self.mapView]; - } else if (auto rasterDEMSource = rawSource->as<mbgl::style::RasterDEMSource>()) { - return [[MGLRasterDEMSource alloc] initWithRawSource:rasterDEMSource mapView:self.mapView]; - } else if (auto imageSource = rawSource->as<mbgl::style::ImageSource>()) { - return [[MGLImageSource alloc] initWithRawSource:imageSource mapView:self.mapView]; - } else { - return [[MGLSource alloc] initWithRawSource:rawSource mapView:self.mapView]; - } -} - -- (void)addSource:(MGLSource *)source -{ - MGLLogDebug(@"Adding source: %@", source); - if (!source.rawSource) { - [NSException raise:NSInvalidArgumentException format: - @"The source %@ cannot be added to the style. " - @"Make sure the source was created as a member of a concrete subclass of MGLSource.", - source]; - } - - try { - [source addToMapView:self.mapView]; - } catch (std::runtime_error & err) { - [NSException raise:MGLRedundantSourceIdentifierException format:@"%s", err.what()]; - } -} - -- (void)removeSource:(MGLSource *)source -{ - [self removeSource:source error:nil]; -} - -- (BOOL)removeSource:(MGLSource *)source error:(NSError * __nullable * __nullable)outError { - MGLLogDebug(@"Removing source: %@", source); - - if (!source.rawSource) { - NSString *errorMessage = [NSString stringWithFormat: - @"The source %@ cannot be removed from the style. " - @"Make sure the source was created as a member of a concrete subclass of MGLSource." - @"Automatic re-addition of sources after style changes is not currently supported.", - source]; - - if (outError) { - *outError = [NSError errorWithDomain:MGLErrorDomain - code:MGLErrorCodeSourceCannotBeRemovedFromStyle - userInfo:@{ NSLocalizedDescriptionKey : errorMessage }]; - return NO; - } - else { - [NSException raise:NSInvalidArgumentException format:@"%@", errorMessage]; - } - } - - return [source removeFromMapView:self.mapView error:outError]; -} - - -- (nullable NSArray<MGLAttributionInfo *> *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { - // It’d be incredibly convenient to use -sources here, but this operation - // depends on the sources being sorted in ascending order by creation, as - // with the std::vector used in mbgl. - auto rawSources = self.rawStyle->getSources(); - NSMutableArray *infos = [NSMutableArray arrayWithCapacity:rawSources.size()]; - for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) { - MGLTileSource *source = (MGLTileSource *)[self sourceFromMBGLSource:*rawSource]; - if (![source isKindOfClass:[MGLTileSource class]]) { - continue; - } - - NSArray *tileSetInfos = [source attributionInfosWithFontSize:fontSize linkColor:linkColor]; - [infos growArrayByAddingAttributionInfosFromArray:tileSetInfos]; - } - return infos; -} - -#pragma mark Style layers - -- (NSArray<__kindof MGLStyleLayer *> *)layers -{ - auto layers = self.rawStyle->getLayers(); - NSMutableArray<__kindof MGLStyleLayer *> *styleLayers = [NSMutableArray arrayWithCapacity:layers.size()]; - for (auto layer : layers) { - MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer]; - [styleLayers addObject:styleLayer]; - } - return styleLayers; -} - -- (void)setLayers:(NSArray<__kindof MGLStyleLayer *> *)layers { - MGLLogDebug(@"Setting: %lu layers", layers.count); - for (MGLStyleLayer *layer in self.layers) { - [self removeLayer:layer]; - } - for (MGLStyleLayer *layer in layers) { - [self addLayer:layer]; - } -} - -- (NSUInteger)countOfLayers -{ - return self.rawStyle->getLayers().size(); -} - -- (MGLStyleLayer *)objectInLayersAtIndex:(NSUInteger)index -{ - auto layers = self.rawStyle->getLayers(); - if (index >= layers.size()) { - [NSException raise:NSRangeException - format:@"No style layer at index %lu.", (unsigned long)index]; - return nil; - } - auto layer = layers.at(index); - return [self layerFromMBGLLayer:layer]; -} - -- (void)getLayers:(MGLStyleLayer **)buffer range:(NSRange)inRange -{ - auto layers = self.rawStyle->getLayers(); - if (NSMaxRange(inRange) > layers.size()) { - [NSException raise:NSRangeException - format:@"Style layer range %@ is out of bounds.", NSStringFromRange(inRange)]; - } - NSUInteger i = 0; - for (auto layer = *(layers.rbegin() + inRange.location); i < inRange.length; ++layer, ++i) { - MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer]; - buffer[i] = styleLayer; - } -} - -- (void)insertObject:(MGLStyleLayer *)styleLayer inLayersAtIndex:(NSUInteger)index -{ - if (!styleLayer.rawLayer) { - [NSException raise:NSInvalidArgumentException format: - @"The style layer %@ cannot be inserted into the style. " - @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", - styleLayer]; - } - auto layers = self.rawStyle->getLayers(); - if (index > layers.size()) { - [NSException raise:NSRangeException - format:@"Cannot insert style layer at out-of-bounds index %lu.", (unsigned long)index]; - } else if (index == 0) { - try { - MGLStyleLayer *sibling = layers.size() ? [self layerFromMBGLLayer:layers.at(0)] : nil; - [styleLayer addToStyle:self belowLayer:sibling]; - } catch (const std::runtime_error & err) { - [NSException raise:MGLRedundantLayerIdentifierException format:@"%s", err.what()]; - } - } else { - try { - MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index)]; - [styleLayer addToStyle:self belowLayer:sibling]; - } catch (std::runtime_error & err) { - [NSException raise:MGLRedundantLayerIdentifierException format:@"%s", err.what()]; - } - } -} - -- (void)removeObjectFromLayersAtIndex:(NSUInteger)index -{ - auto layers = self.rawStyle->getLayers(); - if (index >= layers.size()) { - [NSException raise:NSRangeException - format:@"Cannot remove style layer at out-of-bounds index %lu.", (unsigned long)index]; - } - auto layer = layers.at(index); - MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer]; - [styleLayer removeFromStyle:self]; -} - -- (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)rawLayer -{ - NSParameterAssert(rawLayer); - - if (MGLStyleLayer *layer = rawLayer->peer.has_value() ? rawLayer->peer.get<LayerWrapper>().layer : nil) { - return layer; - } - - return mbgl::LayerManagerDarwin::get()->createPeer(rawLayer); -} - -- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier -{ - MGLLogDebug(@"Querying layerWithIdentifier: %@", identifier); - auto mbglLayer = self.rawStyle->getLayer(identifier.UTF8String); - return mbglLayer ? [self layerFromMBGLLayer:mbglLayer] : nil; -} - -- (void)removeLayer:(MGLStyleLayer *)layer -{ - MGLLogDebug(@"Removing layer: %@", layer); - if (!layer.rawLayer) { - [NSException raise:NSInvalidArgumentException format: - @"The style layer %@ cannot be removed from the style. " - @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", - layer]; - } - [self willChangeValueForKey:@"layers"]; - [layer removeFromStyle:self]; - [self didChangeValueForKey:@"layers"]; -} - -- (void)addLayer:(MGLStyleLayer *)layer -{ - MGLLogDebug(@"Adding layer: %@", layer); - if (!layer.rawLayer) { - [NSException raise:NSInvalidArgumentException format: - @"The style layer %@ cannot be added to the style. " - @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", - layer]; - } - [self willChangeValueForKey:@"layers"]; - try { - [layer addToStyle:self belowLayer:nil]; - } catch (std::runtime_error & err) { - [NSException raise:MGLRedundantLayerIdentifierException format:@"%s", err.what()]; - } - [self didChangeValueForKey:@"layers"]; -} - -- (void)insertLayer:(MGLStyleLayer *)layer atIndex:(NSUInteger)index { - [self insertObject:layer inLayersAtIndex:index]; -} - -- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)sibling -{ - MGLLogDebug(@"Inseting layer: %@ belowLayer: %@", layer, sibling); - if (!layer.rawLayer) { - [NSException raise:NSInvalidArgumentException - format: - @"The style layer %@ cannot be added to the style. " - @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", - layer]; - } - if (!sibling.rawLayer) { - [NSException raise:NSInvalidArgumentException - format: - @"A style layer cannot be placed below %@ in the style. " - @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].", - sibling]; - } - [self willChangeValueForKey:@"layers"]; - try { - [layer addToStyle:self belowLayer:sibling]; - } catch (std::runtime_error & err) { - [NSException raise:MGLRedundantLayerIdentifierException format:@"%s", err.what()]; - } - [self didChangeValueForKey:@"layers"]; -} - -- (void)insertLayer:(MGLStyleLayer *)layer aboveLayer:(MGLStyleLayer *)sibling { - MGLLogDebug(@"Inseting layer: %@ aboveLayer: %@", layer, sibling); - if (!layer.rawLayer) { - [NSException raise:NSInvalidArgumentException - format: - @"The style layer %@ cannot be added to the style. " - @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", - layer]; - } - if (!sibling.rawLayer) { - [NSException raise:NSInvalidArgumentException - format: - @"A style layer cannot be placed above %@ in the style. " - @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].", - sibling]; - } - - auto layers = self.rawStyle->getLayers(); - std::string siblingIdentifier = sibling.identifier.UTF8String; - NSUInteger index = 0; - for (auto siblingLayer : layers) { - if (siblingLayer->getID() == siblingIdentifier) { - break; - } - index++; - } - - [self willChangeValueForKey:@"layers"]; - if (index + 1 > layers.size()) { - [NSException raise:NSInvalidArgumentException - format: - @"A style layer cannot be placed above %@ in the style. " - @"Make sure sibling was obtained using -[MGLStyle layerWithIdentifier:].", - sibling]; - } else if (index + 1 == layers.size()) { - try { - [layer addToStyle:self belowLayer:nil]; - } catch (std::runtime_error & err) { - [NSException raise:MGLRedundantLayerIdentifierException format:@"%s", err.what()]; - } - } else { - MGLStyleLayer *nextSibling = [self layerFromMBGLLayer:layers.at(index + 1)]; - try { - [layer addToStyle:self belowLayer:nextSibling]; - } catch (std::runtime_error & err) { - [NSException raise:MGLRedundantLayerIdentifierException format:@"%s", err.what()]; - } - } - [self didChangeValueForKey:@"layers"]; -} - -#pragma mark Style images - -- (void)setImage:(MGLImage *)image forName:(NSString *)name -{ - MGLLogDebug(@"Setting image: %@ forName: %@", image, name); - if (!image) { - [NSException raise:NSInvalidArgumentException - format:@"Cannot assign nil image to “%@”.", name]; - } - if (!name) { - [NSException raise:NSInvalidArgumentException - format:@"Cannot assign image %@ to a nil name.", image]; - } - - self.rawStyle->addImage([image mgl_styleImageWithIdentifier:name]); -} - -- (void)removeImageForName:(NSString *)name -{ - MGLLogDebug(@"Removing imageForName: %@", name); - if (!name) { - [NSException raise:NSInvalidArgumentException - format:@"Cannot remove image with nil name."]; - } - - self.rawStyle->removeImage([name UTF8String]); -} - -- (MGLImage *)imageForName:(NSString *)name -{ - MGLLogDebug(@"Querying imageForName: %@", name); - if (!name) { - [NSException raise:NSInvalidArgumentException - format:@"Cannot get image with nil name."]; - } - - auto styleImage = self.rawStyle->getImage([name UTF8String]); - return styleImage ? [[MGLImage alloc] initWithMGLStyleImage:&(*styleImage)] : nil; -} - -#pragma mark Style transitions - -- (void)setTransition:(MGLTransition)transition -{ - self.rawStyle->setTransitionOptions(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)transition -{ - const mbgl::style::TransitionOptions transitionOptions = self.rawStyle->getTransitionOptions(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setPerformsPlacementTransitions:(BOOL)performsPlacementTransitions -{ - mbgl::style::TransitionOptions transitionOptions = self.rawStyle->getTransitionOptions(); - transitionOptions.enablePlacementTransitions = static_cast<bool>(performsPlacementTransitions); - self.rawStyle->setTransitionOptions(transitionOptions); -} - -- (BOOL)performsPlacementTransitions -{ - mbgl::style::TransitionOptions transitionOptions = self.rawStyle->getTransitionOptions(); - return transitionOptions.enablePlacementTransitions; -} - -#pragma mark Style light - -- (void)setLight:(MGLLight *)light -{ - std::unique_ptr<mbgl::style::Light> mbglLight = std::make_unique<mbgl::style::Light>([light mbglLight]); - self.rawStyle->setLight(std::move(mbglLight)); -} - -- (MGLLight *)light -{ - auto mbglLight = self.rawStyle->getLight(); - MGLLight *light = [[MGLLight alloc] initWithMBGLLight:mbglLight]; - return light; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"<%@: %p; name = %@, URL = %@>", - NSStringFromClass([self class]), (void *)self, - self.name ? [NSString stringWithFormat:@"\"%@\"", self.name] : self.name, - self.URL ? [NSString stringWithFormat:@"\"%@\"", self.URL] : self.URL]; -} - -#pragma mark Mapbox Streets source introspection - -- (void)localizeLabelsIntoLocale:(nullable NSLocale *)locale { - NSSet<MGLVectorTileSource *> *streetsSources = - [self.sources filteredSetUsingPredicate: - [NSPredicate predicateWithBlock:^BOOL(MGLVectorTileSource * _Nullable source, NSDictionary<NSString *, id> * _Nullable bindings) { - return [source isKindOfClass:[MGLVectorTileSource class]] && [source isMapboxStreets]; - }]]; - NSSet<NSString *> *streetsSourceIdentifiers = [streetsSources valueForKey:@"identifier"]; - - for (MGLSymbolStyleLayer *layer in self.layers) { - if (![layer isKindOfClass:[MGLSymbolStyleLayer class]]) { - continue; - } - if (![streetsSourceIdentifiers containsObject:layer.sourceIdentifier]) { - continue; - } - - NSExpression *text = layer.text; - NSExpression *localizedText = [text mgl_expressionLocalizedIntoLocale:locale]; - if (![localizedText isEqual:text]) { - layer.text = localizedText; - } - } -} - -- (NSSet<MGLVectorTileSource *> *)mapboxStreetsSources { - return [self.sources objectsPassingTest:^BOOL (__kindof MGLVectorTileSource * _Nonnull source, BOOL * _Nonnull stop) { - return [source isKindOfClass:[MGLVectorTileSource class]] && source.mapboxStreets; - }]; -} - -- (NSArray<MGLStyleLayer *> *)placeStyleLayers { - NSSet *streetsSourceIdentifiers = [self.mapboxStreetsSources valueForKey:@"identifier"]; - - NSSet *placeSourceLayerIdentifiers = [NSSet setWithObjects:@"marine_label", @"country_label", @"state_label", @"place_label", @"water_label", @"poi_label", @"rail_station_label", @"mountain_peak_label", @"natural_label", @"transit_stop_label", nil]; - NSPredicate *isPlacePredicate = [NSPredicate predicateWithBlock:^BOOL (MGLVectorStyleLayer * _Nullable layer, NSDictionary<NSString *, id> * _Nullable bindings) { - return [layer isKindOfClass:[MGLVectorStyleLayer class]] && [streetsSourceIdentifiers containsObject:layer.sourceIdentifier] && [placeSourceLayerIdentifiers containsObject:layer.sourceLayerIdentifier]; - }]; - return [self.layers filteredArrayUsingPredicate:isPlacePredicate]; -} - -- (NSArray<MGLStyleLayer *> *)roadStyleLayers { - NSSet *streetsSourceIdentifiers = [self.mapboxStreetsSources valueForKey:@"identifier"]; - - NSSet *roadStyleLayerIdentifiers = [NSSet setWithObjects:@"road_label", @"road", nil]; - NSPredicate *isPlacePredicate = [NSPredicate predicateWithBlock:^BOOL (MGLVectorStyleLayer * _Nullable layer, NSDictionary<NSString *, id> * _Nullable bindings) { - return [layer isKindOfClass:[MGLVectorStyleLayer class]] && [streetsSourceIdentifiers containsObject:layer.sourceIdentifier] && [roadStyleLayerIdentifiers containsObject:layer.sourceLayerIdentifier]; - }]; - return [self.layers filteredArrayUsingPredicate:isPlacePredicate]; -} - -@end diff --git a/platform/darwin/src/MGLStyleLayer.h b/platform/darwin/src/MGLStyleLayer.h deleted file mode 100644 index 785a8db7b3..0000000000 --- a/platform/darwin/src/MGLStyleLayer.h +++ /dev/null @@ -1,66 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLInvalidStyleLayerException; - -/** - `MGLStyleLayer` is an abstract base class for style layers. A style layer - manages the layout and appearance of content at a specific z-index in a style. - An `MGLStyle` object consists of one or more `MGLStyleLayer` objects. - - Each style layer defined by the style JSON file is represented at runtime by an - `MGLStyleLayer` object, which you can use to refine the map’s appearance. You - can also add and remove style layers dynamically. - - Create instances of `MGLBackgroundStyleLayer` and the concrete subclasses of - `MGLForegroundStyleLayer` in order to use `MGLStyleLayer`'s properties and methods. - You do not create instances of `MGLStyleLayer` directly, and do not - create your own subclasses of this class. - - Do not add `MGLStyleLayer` objects to the `style` property of a `MGLMapView` before - `-mapView:didFinishLoadingStyle:` is called. - */ -MGL_EXPORT -@interface MGLStyleLayer : NSObject - -#pragma mark Initializing a Style Layer - -- (instancetype)init __attribute__((unavailable("Use -init methods of concrete subclasses instead."))); - -#pragma mark Identifying a Style Layer - -/** - A string that uniquely identifies the style layer in the style to which it is - added. - */ -@property (nonatomic, copy, readonly) NSString *identifier; - -#pragma mark Configuring a Style Layer’s Visibility - -/** - Whether this layer is displayed. A value of `NO` hides the layer. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/runtime-toggle-layer/"> - Show and hide a layer</a> example to learn how to toggle an `MGLStyleLayer` - object's visibility. - */ -@property (nonatomic, assign, getter=isVisible) BOOL visible; - -/** - The maximum zoom level at which the layer gets parsed and appears. This value is a floating-point number. - */ -@property (nonatomic, assign) float maximumZoomLevel; - -/** - The minimum zoom level at which the layer gets parsed and appears. This value is a floating-point number. - */ -@property (nonatomic, assign) float minimumZoomLevel; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyleLayer.h.ejs b/platform/darwin/src/MGLStyleLayer.h.ejs deleted file mode 100644 index 91ba813b17..0000000000 --- a/platform/darwin/src/MGLStyleLayer.h.ejs +++ /dev/null @@ -1,199 +0,0 @@ -<% - const doc = locals.doc; - const type = locals.type; - const examples = locals.examples; - const layoutProperties = locals.layoutProperties; - const paintProperties = locals.paintProperties; - const enumProperties = locals.enumProperties; --%> -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGL<%- -(type === 'background' ? '' : - (type === 'raster' || type === 'hillshade' ? 'Foreground' : - 'Vector')) -%>StyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -<% for (const property of layoutProperties) { -%> -<% if (definesEnum(property, layoutProperties)) { -%> -/** -<%- propertyDoc(enumName(property), property, type, 'enum').wrap(80, 1) %> - - Values of this type are used in the `MGL<%- camelize(type) %>StyleLayer.<%- camelizeWithLeadingLowercase(property.name) %>` - property. - */ -typedef NS_ENUM(NSUInteger, MGL<%- camelize(enumName(property)) %>) { -<% for (const value in property.values) { -%> - /** -<%- propertyDoc(enumName(property), property.values[value], type, 'enum').wrap(80, 4+1) %> - */ - MGL<%- camelize(enumName(property)) %><%- camelize(value) %>, -<% } -%> -}; - -<% } -%> -<% } -%> -<% for (const property of paintProperties) { -%> -<% if (definesEnum(property, paintProperties)) { -%> -/** -<%- propertyDoc(enumName(property), property, type, 'enum').wrap(80, 1) %> - - Values of this type are used in the `MGL<%- camelize(type) %>StyleLayer.<%- camelizeWithLeadingLowercase(enumName(property)) %>` - property. - */ -typedef NS_ENUM(NSUInteger, MGL<%- camelize(enumName(property)) %>) { -<% for (const value in property.values) { -%> - /** -<%- propertyDoc(enumName(property), property.values[value], type, 'enum').wrap(80, 4+1) %> - */ - MGL<%- camelize(enumName(property)) %><%- camelize(value) %>, -<% } -%> -}; - -<% } -%> -<% } -%> -<% if (type == 'background') { -%> -/** -<%- doc.wrap(80, 1) %> - */ -<% } else { -%> -/** -<%- doc.wrap(80, 1) %> - - You can access an existing <%- type %> style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new <%- type %> style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. -<% if (examples) { -%> - - #### Related examples -<%- examples.wrap(80, 1) %> -<% } -%> - - ### Example - - ```swift - ``` - */ -<% } -%> -MGL_EXPORT -@interface MGL<%- camelize(type) %>StyleLayer : MGL<%- -(type === 'background' ? '' : - (type === 'raster' || type === 'hillshade' ? 'Foreground' : - 'Vector')) -%>StyleLayer -<% if (type === 'background') { -%> - -/** -Returns a <%- type %> style layer initialized with an identifier. - -After initializing and configuring the style layer, add it to a map view’s -style using the `-[MGLStyle addLayer:]` or -`-[MGLStyle insertLayer:belowLayer:]` method. - -@param identifier A string that uniquely identifies the source in the style to -which it is added. -*/ -- (instancetype)initWithIdentifier:(NSString *)identifier; -<% } else { -%> - -/** - Returns a <%- type %> style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; -<% } -%> - -<% if (layoutProperties.length) { -%> -#pragma mark - Accessing the Layout Attributes - -<% for (const property of layoutProperties) { -%> -/** -<%- propertyDoc(property.name, property, type, 'layout').wrap(80, 1) %> -<% if (property.examples) { -%> - - #### Related examples -<%- propertyExample(property).wrap(80, 1) %> -<% } -%> - */ -@property (nonatomic<% if (!property.required) { %>, null_resettable<% } if (property.getter) { %>, getter=<%- objCGetter(property) -%><% } %>) NSExpression *<%- camelizeWithLeadingLowercase(property.name) %>; - -<% if (property.original) { %> -@property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) NSExpression *<%- camelizeWithLeadingLowercase(originalPropertyName(property)) %> __attribute__((unavailable("Use <%- camelizeWithLeadingLowercase(property.name) %> instead."))); - -<% } -%> -<% } -%> -<% } -%> -<% if (paintProperties.length) { -%> -#pragma mark - Accessing the Paint Attributes - -<% for (const property of paintProperties) { -%> -/** -<%- propertyDoc(property.name, property, type, 'paint').wrap(80, 1) %> -<% if (property.examples) { -%> - - #### Related examples -<%- propertyExample(property).wrap(80, 1) %> -<% } -%> - */ -@property (nonatomic<% if (!property.required) { %>, null_resettable<% } if (property.getter) { %>, getter=<%- objCGetter(property) -%><% } %>) NSExpression *<%- camelizeWithLeadingLowercase(property.name) %>; - -<% if (property["transition"]) { -%> -/** - The transition affecting any changes to this layer’s `<%- camelizeWithLeadingLowercase(property.name) %>` property. - - This property corresponds to the `<%- originalPropertyName(property) %>-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition <%- camelizeWithLeadingLowercase(property.name) %>Transition; - -<% } -%> -<% if (property.original) { -%> -@property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) NSExpression *<%- camelizeWithLeadingLowercase(originalPropertyName(property)) %> __attribute__((unavailable("Use <%- camelizeWithLeadingLowercase(property.name) %> instead."))); - -<% } -%> -<% } -%> -<% } -%> -@end - -<% if (enumProperties) { -%> -/** - Methods for wrapping an enumeration value for a style layer attribute in an - `MGL<%- camelize(type) %>StyleLayer` object and unwrapping its raw value. - */ -@interface NSValue (MGL<%- camelize(type) %>StyleLayerAdditions) - -#pragma mark Working with <%- camelize(unhyphenate(type)) %> Style Layer Attribute Values - -<% for (let property of enumProperties) { -%> -/** - Creates a new value object containing the given `MGL<%- camelize(enumName(property)) %>` enumeration. - - @param <%- objCName(property) %> The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGL<%- camelize(enumName(property)) %>:(MGL<%- camelize(enumName(property)) %>)<%- objCName(property) %>; - -/** - The `MGL<%- camelize(enumName(property)) %>` enumeration representation of the value. - */ -@property (readonly) MGL<%- camelize(enumName(property)) %> MGL<%- camelize(enumName(property)) %>Value; - -<% } -%> -@end - -<% } -%> -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm deleted file mode 100644 index 7847cbb319..0000000000 --- a/platform/darwin/src/MGLStyleLayer.mm +++ /dev/null @@ -1,123 +0,0 @@ -#import "MGLStyleLayer_Private.h" -#import "MGLStyle_Private.h" - -#include <mbgl/style/style.hpp> -#include <mbgl/style/layer.hpp> - -const MGLExceptionName MGLInvalidStyleLayerException = @"MGLInvalidStyleLayerException"; - -@interface MGLStyleLayer () - -@property (nonatomic, readonly) mbgl::style::Layer *rawLayer; - -@end - -@implementation MGLStyleLayer { - std::unique_ptr<mbgl::style::Layer> _pendingLayer; - mapbox::base::WeakPtr<mbgl::style::Layer> _weakLayer; -} - -- (instancetype)initWithRawLayer:(mbgl::style::Layer *)rawLayer { - if (self = [super init]) { - _identifier = @(rawLayer->getID().c_str()); - _weakLayer = rawLayer->makeWeakPtr(); - rawLayer->peer = LayerWrapper { self }; - } - return self; -} - -- (instancetype)initWithPendingLayer:(std::unique_ptr<mbgl::style::Layer>)pendingLayer { - if (self = [self initWithRawLayer:pendingLayer.get()]) { - _pendingLayer = std::move(pendingLayer); - } - return self; -} - -- (mbgl::style::Layer *)rawLayer -{ - return _weakLayer.get(); -} - -- (void)addToStyle:(MGLStyle *)style belowLayer:(MGLStyleLayer *)otherLayer -{ - if (_pendingLayer == nullptr) { - [NSException raise:MGLRedundantLayerException - format:@"This instance %@ was already added to %@. Adding the same layer instance " \ - "to the style more than once is invalid.", self, style]; - } - - if (otherLayer) { - const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; - style.rawStyle->addLayer(std::move(_pendingLayer), belowLayerId); - } else { - style.rawStyle->addLayer(std::move(_pendingLayer)); - } -} - -- (void)removeFromStyle:(MGLStyle *)style -{ - if (self.rawLayer == style.rawStyle->getLayer(self.identifier.UTF8String)) { - _pendingLayer = style.rawStyle->removeLayer(self.identifier.UTF8String); - } -} - -- (void)setVisible:(BOOL)visible -{ - MGLAssertStyleLayerIsValid(); - - mbgl::style::VisibilityType v = visible - ? mbgl::style::VisibilityType::Visible - : mbgl::style::VisibilityType::None; - self.rawLayer->setVisibility(v); -} - -- (BOOL)isVisible -{ - MGLAssertStyleLayerIsValid(); - - mbgl::style::VisibilityType v = self.rawLayer->getVisibility(); - return (v == mbgl::style::VisibilityType::Visible); -} - -- (void)setMaximumZoomLevel:(float)maximumZoomLevel -{ - MGLAssertStyleLayerIsValid(); - - self.rawLayer->setMaxZoom(maximumZoomLevel); -} - -- (float)maximumZoomLevel -{ - MGLAssertStyleLayerIsValid(); - - return self.rawLayer->getMaxZoom(); -} - -- (void)setMinimumZoomLevel:(float)minimumZoomLevel -{ - MGLAssertStyleLayerIsValid(); - - self.rawLayer->setMinZoom(minimumZoomLevel); -} - -- (float)minimumZoomLevel -{ - MGLAssertStyleLayerIsValid(); - - return self.rawLayer->getMinZoom(); -} - -- (NSString *)description -{ - if (self.rawLayer) { - return [NSString stringWithFormat:@"<%@: %p; identifier = %@; visible = %@>", - NSStringFromClass([self class]), (void *)self, self.identifier, - self.visible ? @"YES" : @"NO"]; - } - else { - return [NSString stringWithFormat:@"<%@: %p; identifier = %@; visible = NO>", - NSStringFromClass([self class]), (void *)self, self.identifier]; - } -} - -@end diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs deleted file mode 100644 index 5664f7fd45..0000000000 --- a/platform/darwin/src/MGLStyleLayer.mm.ejs +++ /dev/null @@ -1,265 +0,0 @@ -<% - const type = locals.type; - const layoutProperties = locals.layoutProperties; - const paintProperties = locals.paintProperties; - const enumProperties = locals.enumProperties; --%> -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGL<%- camelize(type) %>StyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGL<%- camelize(type) %>StyleLayer_Private.h" - -#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp> -#include <mbgl/style/transition_options.hpp> - -<% if (enumProperties) { -%> - -namespace mbgl { - -<% if (layoutProperties.length) { -%> -<% for (const property of layoutProperties) { -%> -<% if (definesEnum(property, layoutProperties)) { -%> - MBGL_DEFINE_ENUM(MGL<%- camelize(enumName(property)) %>, { -<% for (const value in property.values) { -%> - { MGL<%- camelize(enumName(property)) %><%- camelize(value) %>, "<%-value%>" }, -<% } -%> - }); - -<% } -%> -<% } -%> -<% } -%> -<% if (paintProperties.length) { -%> -<% for (const property of paintProperties) { -%> -<% if (definesEnum(property, paintProperties)) { -%> - MBGL_DEFINE_ENUM(MGL<%- camelize(enumName(property)) %>, { -<% for (const value in property.values) { -%> - { MGL<%- camelize(enumName(property)) %><%- camelize(value) %>, "<%-value%>" }, -<% } -%> - }); - -<% } -%> -<% } -%> -<% } -%> -} -<% } -%> - -@interface MGL<%- camelize(type) %>StyleLayer () - -@property (nonatomic, readonly) mbgl::style::<%- camelize(type) %>Layer *rawLayer; - -@end - -@implementation MGL<%- camelize(type) %>StyleLayer - -<% if (type == 'background') { -%> -- (instancetype)initWithIdentifier:(NSString *)identifier -{ - MGLLogDebug(@"Initializing %@ with identifier: %@", NSStringFromClass([self class]), identifier); - auto layer = std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -<% } else { -%> -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::<%- camelize(type) %>Layer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -<% } -%> -- (mbgl::style::<%- camelize(type) %>Layer *)rawLayer -{ - return (mbgl::style::<%- camelize(type) %>Layer *)super.rawLayer; -} - -<% if (type !== 'background') { -%> -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -<% if (type !== 'raster' && type !== 'hillshade') { -%> -- (NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - - auto layerID = self.rawLayer->getSourceLayer(); - return layerID.empty() ? nil : @(layerID.c_str()); -} - -- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting sourceLayerIdentifier: %@", sourceLayerIdentifier); - - self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); -} - -- (void)setPredicate:(NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting predicate: %@", predicate); - - self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::Filter()); -} - -- (NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - - return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; -} - -<% }} -%> -<% if (layoutProperties.length) { -%> -#pragma mark - Accessing the Layout Attributes - -<% for (const property of layoutProperties) { -%> -- (void)set<%- camelize(property.name) %>:(NSExpression *)<%- objCName(property) %> { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting <%- objCName(property) %>: %@", <%- objCName(property) %>); - -<% if (property.tokens) { -%> - if (<%- objCName(property) %> && <%- objCName(property) %>.expressionType == NSConstantValueExpressionType) { - std::string string = ((NSString *)<%- objCName(property) %>.constantValue).UTF8String; - if (mbgl::style::conversion::hasTokens(string)) { -<% if (property.type === 'formatted') { -%> - self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbgl::style::PropertyValue<mbgl::style::expression::Formatted>( - mbgl::style::conversion::convertTokenStringToFormatExpression(string))); -<% } else if (property.type === 'resolvedImage') { -%> - self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbgl::style::PropertyValue<mbgl::style::expression::Image>( - mbgl::style::conversion::convertTokenStringToImageExpression(string))); -<% } else { -%> - self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbgl::style::PropertyValue<std::string>( - mbgl::style::conversion::convertTokenStringToExpression(string))); -<% } -%> - return; - } - } -<% } -%> -<% if (isDataDriven(property)) { -%> - auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue<mbgl::style::PropertyValue<<%- valueTransformerArguments(property)[0] %>>>(<%- objCName(property) %>, true); -<% } else { -%> - auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue<mbgl::style::PropertyValue<<%- valueTransformerArguments(property)[0] %>>>(<%- objCName(property) %>, false); -<% } -%> - self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbglValue); -} - -- (NSExpression *)<%- objCGetter(property) %> { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->get<%- camelize(originalPropertyName(property)) %>(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefault<%- camelize(originalPropertyName(property)) %>(); - } - return MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toExpression(propertyValue); -} - -<% if (property.original) { -%> -- (void)set<%- camelize(originalPropertyName(property)) %>:(NSExpression *)<%- camelizeWithLeadingLowercase(originalPropertyName(property)) %> { -} - -- (NSExpression *)<%- camelizeWithLeadingLowercase(originalPropertyName(property)) %> { - return self.<%- objCGetter(property) %>; -} - -<% } -%> -<% } -%> -<% } -%> -<% if (paintProperties.length) { -%> -#pragma mark - Accessing the Paint Attributes -<% for (const property of paintProperties) { -%> - -- (void)set<%- camelize(property.name) %>:(NSExpression *)<%- objCName(property) %> { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting <%- objCName(property) %>: %@", <%- objCName(property) %>); - -<% switch (property['property-type']) { - case 'color-ramp': -%> - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::ColorRampPropertyValue>(<%- objCName(property) %>); -<% break - case 'data-driven': - case 'cross-faded-data-driven': -%> - auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue<mbgl::style::PropertyValue<<%- valueTransformerArguments(property)[0] %>>>(<%- objCName(property) %>, true); -<% break - default: -%> - auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue<mbgl::style::PropertyValue<<%- valueTransformerArguments(property)[0] %>>>(<%- objCName(property) %>, false); -<% } -%> - self.rawLayer->set<%- camelize(originalPropertyName(property)) %>(mbglValue); -} - -- (NSExpression *)<%- objCGetter(property) %> { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->get<%- camelize(originalPropertyName(property)) %>(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefault<%- camelize(originalPropertyName(property)) %>(); - } - return MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toExpression(propertyValue); -} -<% if (property["transition"]) { -%> - -- (void)set<%- camelize(property.name) %>Transition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting <%- objCName(property) %>Transition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->set<%- camelize(originalPropertyName(property)) %>Transition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)<%- objCGetter(property) %>Transition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->get<%- camelize(originalPropertyName(property)) %>Transition(); - - return MGLTransitionFromOptions(transitionOptions); -} -<% } -%> -<% if (property.original) { -%> - -- (void)set<%- camelize(originalPropertyName(property)) %>:(NSExpression *)<%- camelizeWithLeadingLowercase(originalPropertyName(property)) %> { -} - -- (NSExpression *)<%- camelizeWithLeadingLowercase(originalPropertyName(property)) %> { - return self.<%- objCGetter(property) %>; -} -<% } -%> -<% } -%> -<% } -%> - -@end -<% if (enumProperties) { -%> - -@implementation NSValue (MGL<%- camelize(type) %>StyleLayerAdditions) - -<% for (let property of enumProperties) { -%> -+ (NSValue *)valueWithMGL<%- camelize(enumName(property)) %>:(MGL<%- camelize(enumName(property)) %>)<%- objCName(property) %> { - return [NSValue value:&<%- objCName(property) %> withObjCType:@encode(MGL<%- camelize(enumName(property)) %>)]; -} - -- (MGL<%- camelize(enumName(property)) %>)MGL<%- camelize(enumName(property)) %>Value { - MGL<%- camelize(enumName(property)) %> <%- objCName(property) %>; - [self getValue:&<%- objCName(property) %>]; - return <%- objCName(property) %>; -} - -<% } -%> -@end -<% } -%> - -namespace mbgl { - -MGLStyleLayer* <%- camelize(type) %>StyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGL<%- camelize(type) %>StyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLStyleLayerManager.h b/platform/darwin/src/MGLStyleLayerManager.h deleted file mode 100644 index 95fecd0252..0000000000 --- a/platform/darwin/src/MGLStyleLayerManager.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#import "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/layer_manager.hpp> -#include <mbgl/style/layer.hpp> - -#include <map> -#include <string> -#include <vector> - -namespace mbgl { - -class LayerManagerDarwin : public LayerManager { -public: - static LayerManagerDarwin* get() noexcept; - ~LayerManagerDarwin(); - - MGLStyleLayer* createPeer(style::Layer*); - -private: - LayerManagerDarwin(); - /** - * Enables a layer type for both JSON style and runtime API. - */ - void addLayerType(std::unique_ptr<LayerPeerFactory>); - /** - * Enables a layer type for JSON style only. - * - * We might not want to expose runtime API for some layer types - * in order to save binary size (the corresponding SDK layer wrappers - * should be excluded from the project build). - */ - void addLayerTypeCoreOnly(std::unique_ptr<mbgl::LayerFactory>); - - void registerCoreFactory(LayerFactory*); - LayerPeerFactory* getPeerFactory(const style::LayerTypeInfo* typeInfo); - // mbgl::LayerManager overrides. - LayerFactory* getFactory(const std::string& type) noexcept final; - LayerFactory* getFactory(const mbgl::style::LayerTypeInfo* info) noexcept final; - - std::vector<std::unique_ptr<LayerPeerFactory>> peerFactories; - std::vector<std::unique_ptr<LayerFactory>> coreFactories; - std::map<std::string, LayerFactory*> typeToFactory; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLStyleLayerManager.mm b/platform/darwin/src/MGLStyleLayerManager.mm deleted file mode 100644 index 72673d4c23..0000000000 --- a/platform/darwin/src/MGLStyleLayerManager.mm +++ /dev/null @@ -1,147 +0,0 @@ -#import "MGLStyleLayerManager.h" - -#import "MGLBackgroundStyleLayer_Private.h" -#import "MGLCircleStyleLayer_Private.h" -#import "MGLFillExtrusionStyleLayer_Private.h" -#import "MGLFillStyleLayer_Private.h" -#import "MGLHeatmapStyleLayer_Private.h" -#import "MGLHillshadeStyleLayer_Private.h" -#import "MGLLineStyleLayer_Private.h" -#import "MGLRasterStyleLayer_Private.h" -#import "MGLSymbolStyleLayer_Private.h" -#import "MGLOpenGLStyleLayer_Private.h" - -#include <vector> - -namespace mbgl { - -LayerManagerDarwin::LayerManagerDarwin() { -#if defined(MBGL_LAYER_FILL_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<FillLayerFactory>()); -#elif !defined(MBGL_LAYER_FILL_DISABLE_ALL) - addLayerType(std::make_unique<FillStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_LINE_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<LineLayerFactory>()); -#elif !defined(MBGL_LAYER_LINE_DISABLE_ALL) - addLayerType(std::make_unique<LineStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_CIRCLE_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<CircleLayerFactory>()); -#elif !defined(MBGL_LAYER_CIRCLE_DISABLE_ALL) - addLayerType(std::make_unique<CircleStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_SYMBOL_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<SymbolLayerFactory>()); -#elif !defined(MBGL_LAYER_SYMBOL_DISABLE_ALL) - addLayerType(std::make_unique<SymbolStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_RASTER_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<RasterLayerFactory>()); -#elif !defined(MBGL_LAYER_RASTER_DISABLE_ALL) - addLayerType(std::make_unique<RasterStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_BACKGROUND_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<BackgroundLayerFactory>()); -#elif !defined(MBGL_LAYER_BACKGROUND_DISABLE_ALL) - addLayerType(std::make_unique<BackgroundStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_HILLSHADE_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<HillshadeLayerFactory>()); -#elif !defined(MBGL_LAYER_HILLSHADE_DISABLE_ALL) - addLayerType(std::make_unique<HillshadeStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_FILL_EXTRUSION_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<FillExtrusionLayerFactory>()); -#elif !defined(MBGL_LAYER_FILL_EXTRUSION_DISABLE_ALL) - addLayerType(std::make_unique<FillExtrusionStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_HEATMAP_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<HeatmapLayerFactory>()); -#elif !defined(MBGL_LAYER_HEATMAP_DISABLE_ALL) - addLayerType(std::make_unique<HeatmapStyleLayerPeerFactory>()); -#endif -#if defined(MBGL_LAYER_CUSTOM_DISABLE_RUNTIME) - addLayerTypeCoreOnly(std::make_unique<CustomLayerFactory>()); -#elif !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL) - addLayerType(std::make_unique<OpenGLStyleLayerPeerFactory>()); -#endif -} - -LayerManagerDarwin::~LayerManagerDarwin() = default; - -MGLStyleLayer* LayerManagerDarwin::createPeer(style::Layer* layer) { - if (auto* factory = getPeerFactory(layer->getTypeInfo())) { - return factory->createPeer(layer); - } - return nullptr; -} - -void LayerManagerDarwin::addLayerType(std::unique_ptr<LayerPeerFactory> factory) { - NSCAssert(getFactory(factory->getCoreLayerFactory()->getTypeInfo()) == nullptr, - @"A layer factory with the given info is already added."); - registerCoreFactory(factory->getCoreLayerFactory()); - peerFactories.emplace_back(std::move(factory)); -} - -void LayerManagerDarwin::addLayerTypeCoreOnly(std::unique_ptr<LayerFactory> factory) { - NSCAssert(getFactory(factory->getTypeInfo()) == nullptr, - @"A layer factory with the given info is already added."); - registerCoreFactory(factory.get()); - coreFactories.emplace_back(std::move(factory)); -} - -void LayerManagerDarwin::registerCoreFactory(LayerFactory* factory) { - std::string type{factory->getTypeInfo()->type}; - if (!type.empty()) { - NSCAssert(typeToFactory.find(type) == typeToFactory.end(), @"A layer type can be registered only once."); - typeToFactory.emplace(std::make_pair(std::move(type), factory)); - } -} - -LayerPeerFactory* LayerManagerDarwin::getPeerFactory(const mbgl::style::LayerTypeInfo* typeInfo) { - for (const auto& factory: peerFactories) { - if (factory->getCoreLayerFactory()->getTypeInfo() == typeInfo) { - return factory.get(); - } - } - return nullptr; -} - -LayerFactory* LayerManagerDarwin::getFactory(const std::string& type) noexcept { - auto search = typeToFactory.find(type); - return (search != typeToFactory.end()) ? search->second : nullptr; -} - -LayerFactory* LayerManagerDarwin::getFactory(const mbgl::style::LayerTypeInfo* info) noexcept { - if (LayerPeerFactory* peerFactory = getPeerFactory(info)) { - return peerFactory->getCoreLayerFactory(); - } - - for (const auto& factory: coreFactories) { - if (factory->getTypeInfo() == info) { - return factory.get(); - } - } - - return nullptr; -} - -// static -LayerManagerDarwin* LayerManagerDarwin::get() noexcept { - static LayerManagerDarwin impl; - return &impl; -} - -// static -LayerManager* LayerManager::get() noexcept { - return LayerManagerDarwin::get(); -} - -#if defined(MBGL_LAYER_LINE_DISABLE_ALL) || defined(MBGL_LAYER_SYMBOL_DISABLE_ALL) || defined(MBGL_LAYER_FILL_DISABLE_ALL) -const bool LayerManager::annotationsEnabled = false; -#else -const bool LayerManager::annotationsEnabled = true; -#endif - -} // namespace mbgl diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h deleted file mode 100644 index 52254f78c6..0000000000 --- a/platform/darwin/src/MGLStyleLayer_Private.h +++ /dev/null @@ -1,104 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLStyleLayer.h" -#import "MGLStyleValue_Private.h" - -#include <mbgl/layermanager/layer_factory.hpp> -#include <mbgl/style/layer.hpp> - -NS_ASSUME_NONNULL_BEGIN - -// A struct to be stored in the `peer` member of mbgl::style::Layer, in order to implement -// object identity. We don't store a MGLStyleLayer pointer directly because that doesn't -// interoperate with ARC. The inner pointer is weak in order to avoid a reference cycle for -// "pending" MGLStyleLayers, which have a strong owning pointer to the mbgl::style::Layer. -struct LayerWrapper { - __weak MGLStyleLayer *layer; -}; - -/** - Assert that the style layer is valid. - - This macro should be used at the beginning of any public-facing instance method - of `MGLStyleLayer` and its subclasses. For private methods, an assertion is more appropriate. - */ -#define MGLAssertStyleLayerIsValid() \ - do { \ - if (!self.rawLayer) { \ - [NSException raise:MGLInvalidStyleLayerException \ - format: \ - @"Either this layer got invalidated after the style change or " \ - @"-[MGLStyle removeLayer:] has been called " \ - @"with this instance but another style layer instance was added with the same identifer. It is an " \ - @"error to send any message to this layer since it cannot be recovered after removal due to the " \ - @"identifier collision. Use unique identifiers for all layer instances including layers of " \ - @"different types."]; \ - } \ - } while (NO); - -@class MGLStyle; - -@interface MGLStyleLayer (Private) - -/** - Initializes and returns a layer with a raw pointer to the backing store, - associated with a style. - */ -- (instancetype)initWithRawLayer:(mbgl::style::Layer *)rawLayer; - -/** - Initializes and returns a layer with an owning pointer to the backing store, - unassociated from a style. - */ -- (instancetype)initWithPendingLayer:(std::unique_ptr<mbgl::style::Layer>)pendingLayer; - -@property (nonatomic, readwrite, copy) NSString *identifier; - -/** - A raw pointer to the mbgl object, which is always initialized, either to the - value returned by `mbgl::Map getLayer`, or for independently created objects, - to the pointer value held in `pendingLayer`. In the latter case, this raw - pointer value stays even after ownership of the object is transferred via - `mbgl::Map addLayer`. - */ -@property (nonatomic, readonly) mbgl::style::Layer *rawLayer; - -/** - Adds the mbgl style layer that this object represents to the mbgl map below the - specified `otherLayer`. - - Once a mbgl style layer is added, ownership of the object is transferred to the - `mbgl::Map` and this object no longer has an active unique_ptr reference to the - `mbgl::style::Layer`. - */ -- (void)addToStyle:(MGLStyle *)style belowLayer:(nullable MGLStyleLayer *)otherLayer; - -/** - Removes the mbgl style layer that this object represents from the mbgl map. - - When a mbgl style layer is removed, ownership of the object is transferred back - to the `MGLStyleLayer` instance and the unique_ptr reference is valid again. It - is safe to add the layer back to the style after it is removed. - */ -- (void)removeFromStyle:(MGLStyle *)style; - -@end - -namespace mbgl { - -class LayerPeerFactory { -public: - virtual ~LayerPeerFactory() = default; - /** - Get the corresponding core layer factory. - */ - virtual LayerFactory* getCoreLayerFactory() = 0; - /** - Creates an MGLStyleLayer instance with a raw pointer to the backing store. - */ - virtual MGLStyleLayer* createPeer(style::Layer*) = 0; -}; - -} // namespace mbgl - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyleLayer_Private.h.ejs b/platform/darwin/src/MGLStyleLayer_Private.h.ejs deleted file mode 100644 index a6e6b9cd87..0000000000 --- a/platform/darwin/src/MGLStyleLayer_Private.h.ejs +++ /dev/null @@ -1,24 +0,0 @@ -<% - const doc = locals.doc; - const type = locals.type; - const layoutProperties = locals.layoutProperties; - const paintProperties = locals.paintProperties; - const enumProperties = locals.enumProperties; --%> -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/<%- type.replace('-', '_') %>_layer_factory.hpp> - -namespace mbgl { - -class <%- camelize(type) %>StyleLayerPeerFactory : public LayerPeerFactory, public mbgl::<%- camelize(type) %>LayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLStyleValue.h b/platform/darwin/src/MGLStyleValue.h deleted file mode 100644 index 2a90472b02..0000000000 --- a/platform/darwin/src/MGLStyleValue.h +++ /dev/null @@ -1,48 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreGraphics/CoreGraphics.h> - -#import "MGLFoundation.h" -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -typedef NSString *MGLStyleFunctionOption NS_STRING_ENUM NS_UNAVAILABLE; - -FOUNDATION_EXTERN MGL_EXPORT const MGLStyleFunctionOption MGLStyleFunctionOptionInterpolationBase __attribute__((unavailable("Use NSExpression instead, applying the mgl_interpolate:withCurveType:parameters:stops: function with a curve type of “exponential” and a non-nil parameter."))); - -FOUNDATION_EXTERN MGL_EXPORT const MGLStyleFunctionOption MGLStyleFunctionOptionDefaultValue __attribute__((unavailable("Use +[NSExpression expressionForConditional:trueExpression:falseExpression:] instead."))); - -typedef NS_ENUM(NSUInteger, MGLInterpolationMode) { - MGLInterpolationModeExponential __attribute__((unavailable("Use NSExpression instead, applying the mgl_interpolate:withCurveType:parameters:stops: function with a curve type of “exponential”."))) = 0, - MGLInterpolationModeInterval __attribute__((unavailable("Use NSExpression instead, calling the mgl_step:from:stops: function."))), - MGLInterpolationModeCategorical __attribute__((unavailable("Use NSExpression instead."))), - MGLInterpolationModeIdentity __attribute__((unavailable("Use +[NSExpression expressionForKeyPath:] instead."))) -} __attribute__((unavailable("Use NSExpression instead."))); - -MGL_EXPORT __attribute__((unavailable("Use NSExpression instead."))) -@interface MGLStyleValue<T> : NSObject -@end - -MGL_EXPORT __attribute__((unavailable("Use +[NSExpression expressionForConstantValue:] instead."))) -@interface MGLConstantStyleValue<T> : MGLStyleValue<T> -@end - -@compatibility_alias MGLStyleConstantValue MGLConstantStyleValue; - -MGL_EXPORT __attribute__((unavailable("Use NSExpression instead, calling the mgl_step:from:stops: or mgl_interpolate:withCurveType:parameters:stops: function."))) -@interface MGLStyleFunction<T> : MGLStyleValue<T> -@end - -MGL_EXPORT __attribute__((unavailable("Use NSExpression instead, applying the mgl_step:from:stops: or mgl_interpolate:withCurveType:parameters:stops: function to the $zoomLevel variable."))) -@interface MGLCameraStyleFunction<T> : MGLStyleFunction<T> -@end - -MGL_EXPORT __attribute__((unavailable("Use NSExpression instead, applying the mgl_step:from:stops: or mgl_interpolate:withCurveType:parameters:stops: function to a key path expression."))) -@interface MGLSourceStyleFunction<T> : MGLStyleFunction<T> -@end - -MGL_EXPORT __attribute__((unavailable("Use a NSExpression instead with nested mgl_step:from:stops: or mgl_interpolate:withCurveType:parameters:stops: function calls."))) -@interface MGLCompositeStyleFunction<T> : MGLStyleFunction<T> -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLStyleValue.mm b/platform/darwin/src/MGLStyleValue.mm deleted file mode 100644 index 01ad108d7f..0000000000 --- a/platform/darwin/src/MGLStyleValue.mm +++ /dev/null @@ -1,59 +0,0 @@ -#import "MGLStyleValue_Private.h" - -#include <mbgl/style/expression/expression.hpp> - -const MGLStyleFunctionOption MGLStyleFunctionOptionInterpolationBase = @"MGLStyleFunctionOptionInterpolationBase"; -const MGLStyleFunctionOption MGLStyleFunctionOptionDefaultValue = @"MGLStyleFunctionOptionDefaultValue"; - -id MGLJSONObjectFromMBGLValue(const mbgl::Value &value) { - return value.match([](const mbgl::NullValue) -> id { - return [NSNull null]; - }, [](const bool value) { - return @(value); - }, [](const float value) { - return @(value); - }, [](const int64_t value) { - return @(value); - }, [](const double value) { - return @(value); - }, [](const std::string &value) { - return @(value.c_str()); - }, [](const mbgl::Color &value) { - return [MGLColor mgl_colorWithColor:value]; - }, [](const mbgl::style::Position &value) { - std::array<float, 3> spherical = value.getSpherical(); - MGLSphericalPosition position = MGLSphericalPositionMake(spherical[0], spherical[1], spherical[2]); - return [NSValue valueWithMGLSphericalPosition:position]; - }, [&](const std::vector<mbgl::Value> &vector) { - NSMutableArray *array = [NSMutableArray arrayWithCapacity:vector.size()]; - for (auto value : vector) { - [array addObject:MGLJSONObjectFromMBGLValue(value)]; - } - return array; - }, [&](const std::unordered_map<std::string, mbgl::Value> &map) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:map.size()]; - for (auto &item : map) { - dictionary[@(item.first.c_str())] = MGLJSONObjectFromMBGLValue(item.second); - } - return dictionary; - }, [](const auto &) -> id { - return nil; - }); -} - -id MGLJSONObjectFromMBGLExpression(const mbgl::style::expression::Expression &mbglExpression) { - return MGLJSONObjectFromMBGLValue(mbglExpression.serialize()); -} - - -std::unique_ptr<mbgl::style::expression::Expression> MGLClusterPropertyFromNSExpression(NSExpression *expression) { - if (!expression) { - return nullptr; - } - - NSArray *jsonExpression = expression.mgl_jsonExpressionObject; - - auto expr = mbgl::style::expression::dsl::createExpression(mbgl::style::conversion::makeConvertible(jsonExpression)); - - return expr; -} diff --git a/platform/darwin/src/MGLStyleValue_Private.h b/platform/darwin/src/MGLStyleValue_Private.h deleted file mode 100644 index 43f0b9d282..0000000000 --- a/platform/darwin/src/MGLStyleValue_Private.h +++ /dev/null @@ -1,348 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLStyleValue.h" - -#import "NSValue+MGLStyleAttributeAdditions.h" -#import "NSValue+MGLAdditions.h" -#import "NSExpression+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLTypes.h" - -#import "MGLConversion.h" -#include <mbgl/style/conversion/color_ramp_property_value.hpp> -#include <mbgl/style/conversion/property_value.hpp> -#include <mbgl/style/conversion/position.hpp> -#include <mbgl/style/expression/dsl.hpp> -#import <mbgl/style/transition_options.hpp> -#import <mbgl/style/types.hpp> - -#import <mbgl/util/enum.hpp> -#include <mbgl/util/interpolate.hpp> - -#include <memory> - -#if TARGET_OS_IPHONE - #import "UIColor+MGLAdditions.h" -#else - #import "NSColor+MGLAdditions.h" -#endif - -namespace mbgl { - namespace style { - namespace expression { - class Expression; - } - } -} - -NS_INLINE MGLTransition MGLTransitionFromOptions(const mbgl::style::TransitionOptions& options) { - MGLTransition transition; - transition.duration = MGLTimeIntervalFromDuration(options.duration.value_or(mbgl::Duration::zero())); - transition.delay = MGLTimeIntervalFromDuration(options.delay.value_or(mbgl::Duration::zero())); - - return transition; -} - -NS_INLINE mbgl::style::TransitionOptions MGLOptionsFromTransition(MGLTransition transition) { - mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; - return options; -} - -std::unique_ptr<mbgl::style::expression::Expression> MGLClusterPropertyFromNSExpression(NSExpression *expression); - -id MGLJSONObjectFromMBGLExpression(const mbgl::style::expression::Expression &mbglExpression); - -template <typename MBGLType, typename ObjCType, typename MBGLElement = MBGLType, typename ObjCEnum = ObjCType> -class MGLStyleValueTransformer { -public: - - /// Convert an mbgl property value into an mgl style value - NSExpression *toExpression(const mbgl::style::PropertyValue<MBGLType> &mbglValue) { - PropertyExpressionEvaluator evaluator; - return mbglValue.evaluate(evaluator); - } - - // Convert an mbgl heatmap color property value into an mgl style value - NSExpression *toExpression(const mbgl::style::ColorRampPropertyValue &mbglValue) { - if (mbglValue.isUndefined()) { - return nil; - } - return [NSExpression expressionWithMGLJSONObject:MGLJSONObjectFromMBGLExpression(mbglValue.getExpression())]; - } - - /** - Converts an NSExpression to an mbgl property value. - */ - template <typename MBGLValue> - typename std::enable_if_t<!std::is_same<MBGLValue, mbgl::style::ColorRampPropertyValue>::value, - MBGLValue> toPropertyValue(NSExpression *expression, bool allowDataExpressions) { - if (!expression) { - return {}; - } - - if (expression.expressionType == NSConstantValueExpressionType) { - MBGLType mbglValue; - getMBGLValue(expression.constantValue, mbglValue); - return mbglValue; - } - if (expression.expressionType == NSAggregateExpressionType) { - MBGLType mbglValue; - getMBGLValue(expression.collection, mbglValue); - return mbglValue; - } - - NSArray *jsonExpression = expression.mgl_jsonExpressionObject; - - mbgl::style::conversion::Error valueError; - auto value = mbgl::style::conversion::convert<MBGLValue>( - mbgl::style::conversion::makeConvertible(jsonExpression), valueError, allowDataExpressions, false); - if (!value) { - [NSException raise:NSInvalidArgumentException - format:@"Invalid property value: %@", @(valueError.message.c_str())]; - return {}; - } - - return *value; - } - - /** - Converts an NSExpression to an mbgl property value. - */ - template <typename MBGLValue> - typename std::enable_if_t<std::is_same<MBGLValue, mbgl::style::ColorRampPropertyValue>::value, - MBGLValue> toPropertyValue(NSExpression *expression) { - if (!expression) { - return {}; - } - - NSArray *jsonExpression = expression.mgl_jsonExpressionObject; - - mbgl::style::conversion::Error valueError; - auto value = mbgl::style::conversion::convert<mbgl::style::ColorRampPropertyValue>( - mbgl::style::conversion::makeConvertible(jsonExpression), valueError); - if (!value) { - [NSException raise:NSInvalidArgumentException - format:@"Invalid property value: %@", @(valueError.message.c_str())]; - return {}; - } - - return *value; - } - -private: // Private utilities for converting from mgl to mbgl values - - /** - As hack to allow converting enum => string values, we accept a second, dummy parameter in - the toRawStyleSpecValue() methods for converting 'atomic' (non-style-function) values. - This allows us to use `std::enable_if` to test (at compile time) whether or not MBGLType is an Enum. - */ - template <typename MBGLEnum = MBGLType, - class = typename std::enable_if<!std::is_enum<MBGLEnum>::value>::type, - typename MGLEnum = ObjCEnum, - class = typename std::enable_if<!std::is_enum<MGLEnum>::value>::type> - NSObject* toRawStyleSpecValue(NSObject *rawMGLValue, MBGLEnum &) { - if ([rawMGLValue isKindOfClass:[NSValue class]]) { - const auto rawNSValue = (NSValue *)rawMGLValue; - if (strcmp([rawNSValue objCType], @encode(CGVector)) == 0) { - // offset [x, y] - std::array<float, 2> mglValue = rawNSValue.mgl_offsetArrayValue; - return [NSArray arrayWithObjects:@(mglValue[0]), @(mglValue[1]), nil]; - } - } - // noop pass-through plain NSObject-based items - return rawMGLValue; - } - - template <typename MBGLEnum = MBGLType, - class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type, - typename MGLEnum = ObjCEnum, - class = typename std::enable_if<std::is_enum<MGLEnum>::value>::type> - NSString* toRawStyleSpecValue(ObjCType rawValue, MBGLEnum &) { - MGLEnum mglEnum; - [rawValue getValue:&mglEnum]; - return @(mbgl::Enum<MGLEnum>::toString(mglEnum)); - } - - NSObject* toRawStyleSpecValue(MGLColor *color, MBGLType &) { - return @(color.mgl_color.stringify().c_str()); - } - - // Bool - void getMBGLValue(NSNumber *rawValue, bool &mbglValue) { - mbglValue = !!rawValue.boolValue; - } - - // Float - void getMBGLValue(NSNumber *rawValue, float &mbglValue) { - mbglValue = rawValue.floatValue; - } - - // String - void getMBGLValue(NSString *rawValue, std::string &mbglValue) { - mbglValue = rawValue.UTF8String; - } - - // Formatted - void getMBGLValue(NSString *rawValue, mbgl::style::expression::Formatted &mbglValue) { - mbglValue = mbgl::style::expression::Formatted(rawValue.UTF8String); - } - - // Offsets - void getMBGLValue(id rawValue, std::array<float, 2> &mbglValue) { - if ([rawValue isKindOfClass:[NSValue class]]) { - mbglValue = [rawValue mgl_offsetArrayValue]; - } else if ([rawValue isKindOfClass:[NSArray class]]) { - NSArray *array = (NSArray *)rawValue; - getMBGLValue(array[0], mbglValue[0]); - getMBGLValue(array[1], mbglValue[1]); - } - } - - // Padding - void getMBGLValue(id rawValue, std::array<float, 4> &mbglValue) { - if ([rawValue isKindOfClass:[NSValue class]]) { - mbglValue = [rawValue mgl_paddingArrayValue]; - } else if ([rawValue isKindOfClass:[NSArray class]]) { - NSArray *array = (NSArray *)rawValue; - getMBGLValue(array[0], mbglValue[0]); - getMBGLValue(array[1], mbglValue[1]); - getMBGLValue(array[2], mbglValue[2]); - getMBGLValue(array[3], mbglValue[3]); - getMBGLValue(array[4], mbglValue[4]); - } - } - - // Color - void getMBGLValue(MGLColor *rawValue, mbgl::Color &mbglValue) { - mbglValue = rawValue.mgl_color; - } - - // Image - void getMBGLValue(NSString *rawValue, mbgl::style::expression::Image &mbglValue) { - mbglValue = mbgl::style::expression::Image(rawValue.UTF8String); - } - - // Array - void getMBGLValue(ObjCType rawValue, std::vector<MBGLElement> &mbglValue) { - mbglValue.reserve(rawValue.count); - for (id obj in rawValue) { - id constantObject = obj; - if ([obj isKindOfClass:[NSExpression class]] && [obj expressionType] == NSConstantValueExpressionType) { - constantObject = [constantObject constantValue]; - } - MBGLElement mbglElement; - getMBGLValue(constantObject, mbglElement); - mbglValue.push_back(mbglElement); - } - } - - void getMBGLValue(NSValue *rawValue, mbgl::style::Position &mbglValue) { - auto spherical = rawValue.mgl_lightPositionArrayValue; - mbgl::style::Position position(spherical); - mbglValue = position; - } - - // Enumerations - template <typename MBGLEnum = MBGLType, - class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type, - typename MGLEnum = ObjCEnum, - class = typename std::enable_if<std::is_enum<MGLEnum>::value>::type> - void getMBGLValue(id rawValue, MBGLEnum &mbglValue) { - if ([rawValue isKindOfClass:[NSString class]]) { - mbglValue = *mbgl::Enum<MBGLEnum>::toEnum([(NSString *)rawValue UTF8String]); - } else { - MGLEnum mglEnum; - [(NSValue *)rawValue getValue:&mglEnum]; - auto str = mbgl::Enum<MGLEnum>::toString(mglEnum); - mbglValue = *mbgl::Enum<MBGLEnum>::toEnum(str); - } - } - -private: // Private utilities for converting from mbgl to mgl values - - // Bool - static NSNumber *toMGLRawStyleValue(const bool mbglStopValue) { - return @(mbglStopValue); - } - - // Float - static NSNumber *toMGLRawStyleValue(const float mbglStopValue) { - return @(mbglStopValue); - } - - // Integer - static NSNumber *toMGLRawStyleValue(const int64_t mbglStopValue) { - return @(mbglStopValue); - } - - // String - static NSString *toMGLRawStyleValue(const std::string &mbglStopValue) { - return @(mbglStopValue.c_str()); - } - - // Formatted - static NSString *toMGLRawStyleValue(const mbgl::style::expression::Formatted &mbglStopValue) { - return @(mbglStopValue.toString().c_str()); - } - - // Offsets - static NSValue *toMGLRawStyleValue(const std::array<float, 2> &mbglStopValue) { - return [NSValue mgl_valueWithOffsetArray:mbglStopValue]; - } - - // Padding - static NSValue *toMGLRawStyleValue(const std::array<float, 4> &mbglStopValue) { - return [NSValue mgl_valueWithPaddingArray:mbglStopValue]; - } - - // Color - static MGLColor *toMGLRawStyleValue(const mbgl::Color mbglStopValue) { - return [MGLColor mgl_colorWithColor:mbglStopValue]; - } - - // Image - static NSString *toMGLRawStyleValue(const mbgl::style::expression::Image &mbglImageValue) { - return @(mbglImageValue.id().c_str()); - } - - // Array - static NSArray<NSExpression*> *toMGLRawStyleValue(const std::vector<MBGLElement> &mbglStopValue) { - NSMutableArray *array = [NSMutableArray arrayWithCapacity:mbglStopValue.size()]; - for (const auto &mbglElement: mbglStopValue) { - [array addObject:[NSExpression expressionForConstantValue:toMGLRawStyleValue(mbglElement)]]; - } - return array; - } - - static NSValue *toMGLRawStyleValue(const mbgl::style::Position &mbglStopValue) { - std::array<float, 3> spherical = mbglStopValue.getSpherical(); - MGLSphericalPosition position = MGLSphericalPositionMake(spherical[0], spherical[1], spherical[2]); - return [NSValue valueWithMGLSphericalPosition:position]; - } - - // Enumerations - template <typename MBGLEnum = MBGLType, typename MGLEnum = ObjCEnum> - static NSString *toMGLRawStyleValue(const MBGLEnum &value) { - return @(mbgl::Enum<MBGLEnum>::toString(value)); - } - - /// Converts all types of mbgl property values into an equivalent NSExpression. - class PropertyExpressionEvaluator { - public: - NSExpression *operator()(const mbgl::style::Undefined) const { - return nil; - } - - NSExpression *operator()(const MBGLType &value) const { - id constantValue = toMGLRawStyleValue(value); - if ([constantValue isKindOfClass:[NSArray class]]) { - return [NSExpression expressionForAggregate:constantValue]; - } - return [NSExpression expressionForConstantValue:constantValue]; - } - - NSExpression *operator()(const mbgl::style::PropertyExpression<MBGLType> &mbglValue) const { - return [NSExpression expressionWithMGLJSONObject:MGLJSONObjectFromMBGLExpression(mbglValue.getExpression())]; - } - }; -}; diff --git a/platform/darwin/src/MGLStyle_Private.h b/platform/darwin/src/MGLStyle_Private.h deleted file mode 100644 index 1294b9ad1c..0000000000 --- a/platform/darwin/src/MGLStyle_Private.h +++ /dev/null @@ -1,40 +0,0 @@ -#import "MGLStyle.h" - -#import "MGLStyleLayer.h" -#import "MGLFillStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -namespace mbgl { - namespace style { - class Style; - } -} - -@class MGLAttributionInfo; -@class MGLMapView; -@class MGLOpenGLStyleLayer; -@class MGLVectorTileSource; -@class MGLVectorStyleLayer; - -@interface MGLStyle (Private) - -- (instancetype)initWithRawStyle:(mbgl::style::Style *)rawStyle mapView:(MGLMapView *)mapView; - -@property (nonatomic, readonly, weak) MGLMapView *mapView; -@property (nonatomic, readonly) mbgl::style::Style *rawStyle; - -- (nullable NSArray<MGLAttributionInfo *> *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; -@property (nonatomic, readonly, strong) NSMutableDictionary<NSString *, MGLOpenGLStyleLayer *> *openGLLayers; -- (void)setStyleClasses:(NSArray<NSString *> *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration; - -@end - -@interface MGLStyle (MGLStreetsAdditions) - -@property (nonatomic, readonly, copy) NSArray<MGLVectorStyleLayer *> *placeStyleLayers; -@property (nonatomic, readonly, copy) NSArray<MGLVectorStyleLayer *> *roadStyleLayers; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h deleted file mode 100644 index 8b6bef3c54..0000000000 --- a/platform/darwin/src/MGLSymbolStyleLayer.h +++ /dev/null @@ -1,2488 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLFoundation.h" -#import "MGLVectorStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Part of the icon placed closest to the anchor. - - Values of this type are used in the `MGLSymbolStyleLayer.iconAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLIconAnchor) { - /** - The center of the icon is placed closest to the anchor. - */ - MGLIconAnchorCenter, - /** - The left side of the icon is placed closest to the anchor. - */ - MGLIconAnchorLeft, - /** - The right side of the icon is placed closest to the anchor. - */ - MGLIconAnchorRight, - /** - The top of the icon is placed closest to the anchor. - */ - MGLIconAnchorTop, - /** - The bottom of the icon is placed closest to the anchor. - */ - MGLIconAnchorBottom, - /** - The top left corner of the icon is placed closest to the anchor. - */ - MGLIconAnchorTopLeft, - /** - The top right corner of the icon is placed closest to the anchor. - */ - MGLIconAnchorTopRight, - /** - The bottom left corner of the icon is placed closest to the anchor. - */ - MGLIconAnchorBottomLeft, - /** - The bottom right corner of the icon is placed closest to the anchor. - */ - MGLIconAnchorBottomRight, -}; - -/** - Orientation of icon when map is pitched. - - Values of this type are used in the `MGLSymbolStyleLayer.iconPitchAlignment` - property. - */ -typedef NS_ENUM(NSUInteger, MGLIconPitchAlignment) { - /** - The icon is aligned to the plane of the map. - */ - MGLIconPitchAlignmentMap, - /** - The icon is aligned to the plane of the viewport. - */ - MGLIconPitchAlignmentViewport, - /** - Automatically matches the value of - `MGLSymbolStyleLayer.iconRotationAlignment`. - */ - MGLIconPitchAlignmentAuto, -}; - -/** - In combination with `MGLSymbolStyleLayer.symbolPlacement`, determines the - rotation behavior of icons. - - Values of this type are used in the `MGLSymbolStyleLayer.iconRotationAlignment` - property. - */ -typedef NS_ENUM(NSUInteger, MGLIconRotationAlignment) { - /** - When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, aligns icons - east-west. When `symbolPlacement` is set to `MGLSymbolPlacementLine` or - `MGLSymbolPlacementLineCenter`, aligns icon x-axes with the line. - */ - MGLIconRotationAlignmentMap, - /** - Produces icons whose x-axes are aligned with the x-axis of the viewport, - regardless of the value of `MGLSymbolStyleLayer.symbolPlacement`. - */ - MGLIconRotationAlignmentViewport, - /** - When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, this is - equivalent to `MGLIconRotationAlignmentViewport`. When `symbolPlacement` is - set to `MGLSymbolPlacementLine` or `MGLSymbolPlacementLineCenter`, this is - equivalent to `MGLIconRotationAlignmentMap`. - */ - MGLIconRotationAlignmentAuto, -}; - -/** - Scales the icon to fit around the associated text. - - Values of this type are used in the `MGLSymbolStyleLayer.iconTextFit` - property. - */ -typedef NS_ENUM(NSUInteger, MGLIconTextFit) { - /** - The icon is displayed at its intrinsic aspect ratio. - */ - MGLIconTextFitNone, - /** - The icon is scaled in the x-dimension to fit the width of the text. - */ - MGLIconTextFitWidth, - /** - The icon is scaled in the y-dimension to fit the height of the text. - */ - MGLIconTextFitHeight, - /** - The icon is scaled in both x- and y-dimensions. - */ - MGLIconTextFitBoth, -}; - -/** - Label placement relative to its geometry. - - Values of this type are used in the `MGLSymbolStyleLayer.symbolPlacement` - property. - */ -typedef NS_ENUM(NSUInteger, MGLSymbolPlacement) { - /** - The label is placed at the point where the geometry is located. - */ - MGLSymbolPlacementPoint, - /** - The label is placed along the line of the geometry. Can only be used on - `LineString` and `Polygon` geometries. - */ - MGLSymbolPlacementLine, - /** - The label is placed at the center of the line of the geometry. Can only be - used on `LineString` and `Polygon` geometries. Note that a single feature - in a vector tile may contain multiple line geometries. - */ - MGLSymbolPlacementLineCenter, -}; - -/** - Controls the order in which overlapping symbols in the same layer are rendered - - Values of this type are used in the `MGLSymbolStyleLayer.symbolZOrder` - property. - */ -typedef NS_ENUM(NSUInteger, MGLSymbolZOrder) { - /** - If `MGLSymbolStyleLayer.symbolSortKey` is set, sort based on that. - Otherwise sort symbols by their y-position relative to the viewport. - */ - MGLSymbolZOrderAuto, - /** - Specify this z order if symbols’ appearance relies on lower features - overlapping higher features. For example, symbols with a pin-like - appearance would require this z order. - */ - MGLSymbolZOrderViewportY, - /** - Specify this z order if the order in which features appear in the source is - significant. - */ - MGLSymbolZOrderSource, -}; - -/** - Part of the text placed closest to the anchor. - - Values of this type are used in the `MGLSymbolStyleLayer.textAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLTextAnchor) { - /** - The center of the text is placed closest to the anchor. - */ - MGLTextAnchorCenter, - /** - The left side of the text is placed closest to the anchor. - */ - MGLTextAnchorLeft, - /** - The right side of the text is placed closest to the anchor. - */ - MGLTextAnchorRight, - /** - The top of the text is placed closest to the anchor. - */ - MGLTextAnchorTop, - /** - The bottom of the text is placed closest to the anchor. - */ - MGLTextAnchorBottom, - /** - The top left corner of the text is placed closest to the anchor. - */ - MGLTextAnchorTopLeft, - /** - The top right corner of the text is placed closest to the anchor. - */ - MGLTextAnchorTopRight, - /** - The bottom left corner of the text is placed closest to the anchor. - */ - MGLTextAnchorBottomLeft, - /** - The bottom right corner of the text is placed closest to the anchor. - */ - MGLTextAnchorBottomRight, -}; - -/** - Text justification options. - - Values of this type are used in the `MGLSymbolStyleLayer.textJustification` - property. - */ -typedef NS_ENUM(NSUInteger, MGLTextJustification) { - /** - The text is aligned towards the anchor position. - */ - MGLTextJustificationAuto, - /** - The text is aligned to the left. - */ - MGLTextJustificationLeft, - /** - The text is centered. - */ - MGLTextJustificationCenter, - /** - The text is aligned to the right. - */ - MGLTextJustificationRight, -}; - -/** - Orientation of text when map is pitched. - - Values of this type are used in the `MGLSymbolStyleLayer.textPitchAlignment` - property. - */ -typedef NS_ENUM(NSUInteger, MGLTextPitchAlignment) { - /** - The text is aligned to the plane of the map. - */ - MGLTextPitchAlignmentMap, - /** - The text is aligned to the plane of the viewport. - */ - MGLTextPitchAlignmentViewport, - /** - Automatically matches the value of - `MGLSymbolStyleLayer.textRotationAlignment`. - */ - MGLTextPitchAlignmentAuto, -}; - -/** - In combination with `MGLSymbolStyleLayer.symbolPlacement`, determines the - rotation behavior of the individual glyphs forming the text. - - Values of this type are used in the `MGLSymbolStyleLayer.textRotationAlignment` - property. - */ -typedef NS_ENUM(NSUInteger, MGLTextRotationAlignment) { - /** - When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, aligns text - east-west. When `symbolPlacement` is set to `MGLSymbolPlacementLine` or - `MGLSymbolPlacementLineCenter`, aligns text x-axes with the line. - */ - MGLTextRotationAlignmentMap, - /** - Produces glyphs whose x-axes are aligned with the x-axis of the viewport, - regardless of the value of `MGLSymbolStyleLayer.symbolPlacement`. - */ - MGLTextRotationAlignmentViewport, - /** - When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, this is - equivalent to `MGLTextRotationAlignmentViewport`. When `symbolPlacement` is - set to `MGLSymbolPlacementLine` or `MGLSymbolPlacementLineCenter`, this is - equivalent to `MGLTextRotationAlignmentMap`. - */ - MGLTextRotationAlignmentAuto, -}; - -/** - Specifies how to capitalize text. - - Values of this type are used in the `MGLSymbolStyleLayer.textTransform` - property. - */ -typedef NS_ENUM(NSUInteger, MGLTextTransform) { - /** - The text is not altered. - */ - MGLTextTransformNone, - /** - Forces all letters to be displayed in uppercase. - */ - MGLTextTransformUppercase, - /** - Forces all letters to be displayed in lowercase. - */ - MGLTextTransformLowercase, -}; - -/** - The property allows control over a symbol's orientation. Note that the property - values act as a hint, so that a symbol whose language doesn’t support the - provided orientation will be laid out in its natural orientation. Example: - English point symbol will be rendered horizontally even if array value contains - single 'vertical' enum value. The order of elements in an array define priority - order for the placement of an orientation variant. - - Values of this type are used in the `MGLSymbolStyleLayer.textWritingModes` - property. - */ -typedef NS_ENUM(NSUInteger, MGLTextWritingMode) { - /** - If a text's language supports horizontal writing mode, symbols with point - placement would be laid out horizontally. - */ - MGLTextWritingModeHorizontal, - /** - If a text's language supports vertical writing mode, symbols with point - placement would be laid out vertically. - */ - MGLTextWritingModeVertical, -}; - -/** - Controls the frame of reference for `MGLSymbolStyleLayer.iconTranslation`. - - Values of this type are used in the `MGLSymbolStyleLayer.iconTranslationAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLIconTranslationAnchor) { - /** - Icons are translated relative to the map. - */ - MGLIconTranslationAnchorMap, - /** - Icons are translated relative to the viewport. - */ - MGLIconTranslationAnchorViewport, -}; - -/** - Controls the frame of reference for `MGLSymbolStyleLayer.textTranslation`. - - Values of this type are used in the `MGLSymbolStyleLayer.textTranslationAnchor` - property. - */ -typedef NS_ENUM(NSUInteger, MGLTextTranslationAnchor) { - /** - The text is translated relative to the map. - */ - MGLTextTranslationAnchorMap, - /** - The text is translated relative to the viewport. - */ - MGLTextTranslationAnchorViewport, -}; - -/** - An `MGLSymbolStyleLayer` is a style layer that renders icon and text labels at - points or along lines on the map. - - Use a symbol style layer to configure the visual appearance of feature labels. - These features can come from vector tiles loaded by an `MGLVectorTileSource` - object, or they can be `MGLShape` or `MGLFeature` instances in an - `MGLShapeSource` or `MGLComputedShapeSource` object. - - You can access an existing symbol style layer using the - `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; - otherwise, find it using the `MGLStyle.layers` property. You can also create a - new symbol style layer and add it to the style using a method such as - `-[MGLStyle addLayer:]`. - - #### Related examples - See the <a - href="https://docs.mapbox.com/ios/maps/examples/runtime-multiple-annotations/">Dynamically - style interactive points</a> and <a - href="https://docs.mapbox.com/ios/maps/examples/clustering-with-images/">Use - images to cluster point data</a> examples learn how to style data on your map - using this layer. - - ### Example - - ```swift - let layer = MGLSymbolStyleLayer(identifier: "coffeeshops", source: pois) - layer.sourceLayerIdentifier = "pois" - layer.iconImageName = NSExpression(forConstantValue: "coffee") - layer.iconScale = NSExpression(forConstantValue: 0.5) - layer.text = NSExpression(forKeyPath: "name") - layer.textTranslation = NSExpression(forConstantValue: NSValue(cgVector: CGVector(dx: 10, dy: 0))) - layer.textJustification = NSExpression(forConstantValue: "left") - layer.textAnchor = NSExpression(forConstantValue: "left") - layer.predicate = NSPredicate(format: "%K == %@", "venue-type", "coffee") - mapView.style?.addLayer(layer) - ``` - */ -MGL_EXPORT -@interface MGLSymbolStyleLayer : MGLVectorStyleLayer - -/** - Returns a symbol style layer initialized with an identifier and source. - - After initializing and configuring the style layer, add it to a map view’s - style using the `-[MGLStyle addLayer:]` or - `-[MGLStyle insertLayer:belowLayer:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param source The source from which to obtain the data to style. If the source - has not yet been added to the current style, the behavior is undefined. - @return An initialized foreground style layer. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; - -#pragma mark - Accessing the Layout Attributes - -/** - If true, the icon will be visible even if it collides with other previously - drawn symbols. - - The default value of this property is an expression that evaluates to `NO`. Set - this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-icon-allow-overlap"><code>icon-allow-overlap</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconAllowsOverlap; - - -@property (nonatomic, null_resettable) NSExpression *iconAllowOverlap __attribute__((unavailable("Use iconAllowsOverlap instead."))); - -/** - Part of the icon placed closest to the anchor. - - The default value of this property is an expression that evaluates to `center`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLIconAnchor` values - * Any of the following constant string values: - * `center`: The center of the icon is placed closest to the anchor. - * `left`: The left side of the icon is placed closest to the anchor. - * `right`: The right side of the icon is placed closest to the anchor. - * `top`: The top of the icon is placed closest to the anchor. - * `bottom`: The bottom of the icon is placed closest to the anchor. - * `top-left`: The top left corner of the icon is placed closest to the - anchor. - * `top-right`: The top right corner of the icon is placed closest to the - anchor. - * `bottom-left`: The bottom left corner of the icon is placed closest to the - anchor. - * `bottom-right`: The bottom right corner of the icon is placed closest to - the anchor. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconAnchor; - -/** - If true, other symbols can be visible even if they collide with the icon. - - The default value of this property is an expression that evaluates to `NO`. Set - this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-icon-ignore-placement"><code>icon-ignore-placement</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconIgnoresPlacement; - - -@property (nonatomic, null_resettable) NSExpression *iconIgnorePlacement __attribute__((unavailable("Use iconIgnoresPlacement instead."))); - -/** - Name of a style image to use for drawing an image background. - - Use the `+[MGLStyle setImage:forName:]` method to associate an image with a - name that you can set this property to. - - Within a constant string value, a feature attribute name enclosed in curly - braces (e.g., `{token}`) is replaced with the value of the named attribute. - Tokens inside non-constant expressions are ignored; instead, use `mgl_join:` - and key path expressions. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-icon-image"><code>icon-image</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant string values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - - #### Related examples - See the <a - href="https://docs.mapbox.com/ios/maps/examples/clustering-with-images/">Use - images to cluster point data</a> example to learn how to dynamically set your - icons with an expression. - */ -@property (nonatomic, null_resettable) NSExpression *iconImageName; - - -@property (nonatomic, null_resettable) NSExpression *iconImage __attribute__((unavailable("Use iconImageName instead."))); - -#if TARGET_OS_IPHONE -/** - Offset distance of icon from its anchor. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 rightward and 0 - downward. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconOffset; -#else -/** - Offset distance of icon from its anchor. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 rightward and 0 - upward. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconOffset; -#endif - -/** - If true, text will display without their corresponding icons when the icon - collides with other symbols and the text does not. - - The default value of this property is an expression that evaluates to `NO`. Set - this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`, and - `text` is non-`nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable, getter=isIconOptional) NSExpression *iconOptional; - -/** - Size of the additional area around the icon bounding box used for detecting - symbol collisions. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `2`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconPadding; - -/** - Orientation of icon when map is pitched. - - The default value of this property is an expression that evaluates to `auto`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLIconPitchAlignment` values - * Any of the following constant string values: - * `map`: The icon is aligned to the plane of the map. - * `viewport`: The icon is aligned to the plane of the viewport. - * `auto`: Automatically matches the value of `icon-rotation-alignment`. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconPitchAlignment; - -/** - Rotates the icon clockwise. - - This property is measured in degrees. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-icon-rotate"><code>icon-rotate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconRotation; - - -@property (nonatomic, null_resettable) NSExpression *iconRotate __attribute__((unavailable("Use iconRotation instead."))); - -/** - In combination with `symbolPlacement`, determines the rotation behavior of - icons. - - The default value of this property is an expression that evaluates to `auto`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLIconRotationAlignment` values - * Any of the following constant string values: - * `map`: When `symbol-placement` is set to `point`, aligns icons east-west. - When `symbol-placement` is set to `line` or `line-center`, aligns icon x-axes - with the line. - * `viewport`: Produces icons whose x-axes are aligned with the x-axis of the - viewport, regardless of the value of `symbol-placement`. - * `auto`: When `symbol-placement` is set to `point`, this is equivalent to - `viewport`. When `symbol-placement` is set to `line` or `line-center`, this is - equivalent to `map`. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconRotationAlignment; - -/** - Scales the original size of the icon by the provided factor. The new point size - of the image will be the original point size multiplied by `iconScale`. 1 is - the original size; 3 triples the size of the image. - - This property is measured in factor of the original icon sizes. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-icon-size"><code>icon-size</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconScale; - - -@property (nonatomic, null_resettable) NSExpression *iconSize __attribute__((unavailable("Use iconScale instead."))); - -/** - Scales the icon to fit around the associated text. - - The default value of this property is an expression that evaluates to `none`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`, and - `text` is non-`nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLIconTextFit` values - * Any of the following constant string values: - * `none`: The icon is displayed at its intrinsic aspect ratio. - * `width`: The icon is scaled in the x-dimension to fit the width of the - text. - * `height`: The icon is scaled in the y-dimension to fit the height of the - text. - * `both`: The icon is scaled in both x- and y-dimensions. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconTextFit; - -#if TARGET_OS_IPHONE -/** - Size of the additional area added to dimensions determined by `iconTextFit`. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing `UIEdgeInsetsZero`. Set this property to `nil` to - reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`, and - `text` is non-`nil`, and `iconTextFit` is set to an expression that evaluates - to `MGLIconTextFitBoth`, `MGLIconTextFitWidth`, or `MGLIconTextFitHeight`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIEdgeInsets` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconTextFitPadding; -#else -/** - Size of the additional area added to dimensions determined by `iconTextFit`. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing `NSEdgeInsetsZero`. Set this property to `nil` to - reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`, and - `text` is non-`nil`, and `iconTextFit` is set to an expression that evaluates - to `MGLIconTextFitBoth`, `MGLIconTextFitWidth`, or `MGLIconTextFitHeight`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSEdgeInsets` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconTextFitPadding; -#endif - -/** - If true, the icon may be flipped to prevent it from being rendered upside-down. - - The default value of this property is an expression that evaluates to `NO`. Set - this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`, and - `iconRotationAlignment` is set to an expression that evaluates to `map`, and - `symbolPlacement` is set to an expression that evaluates to either - `MGLSymbolPlacementLine` or `MGLSymbolPlacementLineCenter`. Otherwise, it is - ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-icon-keep-upright"><code>icon-keep-upright</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *keepsIconUpright; - - -@property (nonatomic, null_resettable) NSExpression *iconKeepUpright __attribute__((unavailable("Use keepsIconUpright instead."))); - -/** - If true, the text may be flipped vertically to prevent it from being rendered - upside-down. - - The default value of this property is an expression that evaluates to `YES`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`, and - `textRotationAlignment` is set to an expression that evaluates to `map`, and - `symbolPlacement` is set to an expression that evaluates to either - `MGLSymbolPlacementLine` or `MGLSymbolPlacementLineCenter`. Otherwise, it is - ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-keep-upright"><code>text-keep-upright</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *keepsTextUpright; - - -@property (nonatomic, null_resettable) NSExpression *textKeepUpright __attribute__((unavailable("Use keepsTextUpright instead."))); - -/** - Maximum angle change between adjacent characters. - - This property is measured in degrees. - - The default value of this property is an expression that evaluates to the float - `45`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`, and - `symbolPlacement` is set to an expression that evaluates to either - `MGLSymbolPlacementLine` or `MGLSymbolPlacementLineCenter`. Otherwise, it is - ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-max-angle"><code>text-max-angle</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *maximumTextAngle; - - -@property (nonatomic, null_resettable) NSExpression *textMaxAngle __attribute__((unavailable("Use maximumTextAngle instead."))); - -/** - The maximum line width for text wrapping. - - This property is measured in ems. - - The default value of this property is an expression that evaluates to the float - `10`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-max-width"><code>text-max-width</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *maximumTextWidth; - - -@property (nonatomic, null_resettable) NSExpression *textMaxWidth __attribute__((unavailable("Use maximumTextWidth instead."))); - -/** - If true, the symbols will not cross tile edges to avoid mutual collisions. - Recommended in layers that don't have enough padding in the vector tile to - prevent collisions, or if it is a point symbol layer placed after a line symbol - layer. When using a client that supports global collision detection, like - Mapbox GL JS version 0.42.0 or greater, enabling this property is not needed to - prevent clipped labels at tile boundaries. - - The default value of this property is an expression that evaluates to `NO`. Set - this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-symbol-avoid-edges"><code>symbol-avoid-edges</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *symbolAvoidsEdges; - - -@property (nonatomic, null_resettable) NSExpression *symbolAvoidEdges __attribute__((unavailable("Use symbolAvoidsEdges instead."))); - -/** - Label placement relative to its geometry. - - The default value of this property is an expression that evaluates to `point`. - Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant `MGLSymbolPlacement` values - * Any of the following constant string values: - * `point`: The label is placed at the point where the geometry is located. - * `line`: The label is placed along the line of the geometry. Can only be - used on `LineString` and `Polygon` geometries. - * `line-center`: The label is placed at the center of the line of the - geometry. Can only be used on `LineString` and `Polygon` geometries. Note that - a single feature in a vector tile may contain multiple line geometries. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *symbolPlacement; - -/** - Sorts features in ascending order based on this value. Features with a higher - sort key will appear above features with a lower sort key when they overlap. - Features with a lower sort key will have priority over other features when - doing placement. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *symbolSortKey; - -/** - Distance between two symbol anchors. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `250`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `symbolPlacement` is set to an - expression that evaluates to `line`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 1 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *symbolSpacing; - -/** - Controls the order in which overlapping symbols in the same layer are rendered - - The default value of this property is an expression that evaluates to `auto`. - Set this property to `nil` to reset it to the default value. - - You can set this property to an expression containing any of the following: - - * Constant `MGLSymbolZOrder` values - * Any of the following constant string values: - * `auto`: If `symbol-sort-key` is set, sort based on that. Otherwise sort - symbols by their y-position relative to the viewport. - * `viewport-y`: Specify this z order if symbols’ appearance relies on lower - features overlapping higher features. For example, symbols with a pin-like - appearance would require this z order. - * `source`: Specify this z order if the order in which features appear in the - source is significant. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *symbolZOrder; - -/** - Value to use for a text label. - - Within a constant string value, a feature attribute name enclosed in curly - braces (e.g., `{token}`) is replaced with the value of the named attribute. - Tokens inside non-constant expressions are ignored; instead, use `mgl_join:` - and key path expressions. - - The default value of this property is an expression that evaluates to the empty - string. Set this property to `nil` to reset it to the default value. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-field"><code>text-field</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant string values - * Formatted expressions. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/clustering/">Cluster - point data</a> and <a - href="https://docs.mapbox.com/ios/maps/examples/clustering-with-images/">Use - images to cluster point data</a> to learn how to use an expression to set this - attribute to the number of markers within a cluster. - */ -@property (nonatomic, null_resettable) NSExpression *text; - - -@property (nonatomic, null_resettable) NSExpression *textField __attribute__((unavailable("Use text instead."))); - -/** - If true, the text will be visible even if it collides with other previously - drawn symbols. - - The default value of this property is an expression that evaluates to `NO`. Set - this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-allow-overlap"><code>text-allow-overlap</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textAllowsOverlap; - - -@property (nonatomic, null_resettable) NSExpression *textAllowOverlap __attribute__((unavailable("Use textAllowsOverlap instead."))); - -/** - Part of the text placed closest to the anchor. - - The default value of this property is an expression that evaluates to `center`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`, and - `textVariableAnchor` is set to `nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLTextAnchor` values - * Any of the following constant string values: - * `center`: The center of the text is placed closest to the anchor. - * `left`: The left side of the text is placed closest to the anchor. - * `right`: The right side of the text is placed closest to the anchor. - * `top`: The top of the text is placed closest to the anchor. - * `bottom`: The bottom of the text is placed closest to the anchor. - * `top-left`: The top left corner of the text is placed closest to the - anchor. - * `top-right`: The top right corner of the text is placed closest to the - anchor. - * `bottom-left`: The bottom left corner of the text is placed closest to the - anchor. - * `bottom-right`: The bottom right corner of the text is placed closest to - the anchor. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textAnchor; - -/** - An array of font face names used to display the text. - - Each font name must be included in the `{fontstack}` portion of the JSON - stylesheet’s <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#glyphs"><code>glyphs</code></a> - property. You can register a custom font when designing the style in Mapbox - Studio. Fonts installed on the system are not used. - - The first font named in the array is applied to the text. For each character in - the text, if the first font lacks a glyph for the character, the next font is - applied as a fallback, and so on. - - The default value of this property is an expression that evaluates to the array - `Open Sans Regular`, `Arial Unicode MS Regular`. Set this property to `nil` to - reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-font"><code>text-font</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant array values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textFontNames; - - -@property (nonatomic, null_resettable) NSExpression *textFont __attribute__((unavailable("Use textFontNames instead."))); - -/** - Font size. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `16`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-size"><code>text-size</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textFontSize; - - -@property (nonatomic, null_resettable) NSExpression *textSize __attribute__((unavailable("Use textFontSize instead."))); - -/** - If true, other symbols can be visible even if they collide with the text. - - The default value of this property is an expression that evaluates to `NO`. Set - this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-ignore-placement"><code>text-ignore-placement</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textIgnoresPlacement; - - -@property (nonatomic, null_resettable) NSExpression *textIgnorePlacement __attribute__((unavailable("Use textIgnoresPlacement instead."))); - -/** - Text justification options. - - The default value of this property is an expression that evaluates to `center`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-justify"><code>text-justify</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLTextJustification` values - * Any of the following constant string values: - * `auto`: The text is aligned towards the anchor position. - * `left`: The text is aligned to the left. - * `center`: The text is centered. - * `right`: The text is aligned to the right. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textJustification; - - -@property (nonatomic, null_resettable) NSExpression *textJustify __attribute__((unavailable("Use textJustification instead."))); - -/** - Text tracking amount. - - This property is measured in ems. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textLetterSpacing; - -/** - Text leading value for multi-line text. - - This property is measured in ems. - - The default value of this property is an expression that evaluates to the float - `1.2`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textLineHeight; - -#if TARGET_OS_IPHONE -/** - Offset distance of text from its anchor. - - This property is measured in ems. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 ems rightward and 0 - ems downward. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`, and - `textRadialOffset` is set to `nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textOffset; -#else -/** - Offset distance of text from its anchor. - - This property is measured in ems. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 ems rightward and 0 - ems upward. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`, and - `textRadialOffset` is set to `nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textOffset; -#endif - -/** - If true, icons will display without their corresponding text when the text - collides with other symbols and the icon does not. - - The default value of this property is an expression that evaluates to `NO`. Set - this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`, and - `iconImageName` is non-`nil`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant Boolean values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable, getter=isTextOptional) NSExpression *textOptional; - -/** - Size of the additional area around the text bounding box used for detecting - symbol collisions. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `2`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textPadding; - -/** - Orientation of text when map is pitched. - - The default value of this property is an expression that evaluates to `auto`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLTextPitchAlignment` values - * Any of the following constant string values: - * `map`: The text is aligned to the plane of the map. - * `viewport`: The text is aligned to the plane of the viewport. - * `auto`: Automatically matches the value of `text-rotation-alignment`. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textPitchAlignment; - -/** - Radial offset of text, in the direction of the symbol's anchor. Useful in - combination with `textVariableAnchor`, which defaults to using the - two-dimensional `textOffset` if present. - - This property is measured in ems. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textRadialOffset; - -/** - Rotates the text clockwise. - - This property is measured in degrees. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-rotate"><code>text-rotate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant numeric values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textRotation; - - -@property (nonatomic, null_resettable) NSExpression *textRotate __attribute__((unavailable("Use textRotation instead."))); - -/** - In combination with `symbolPlacement`, determines the rotation behavior of the - individual glyphs forming the text. - - The default value of this property is an expression that evaluates to `auto`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLTextRotationAlignment` values - * Any of the following constant string values: - * `map`: When `symbol-placement` is set to `point`, aligns text east-west. - When `symbol-placement` is set to `line` or `line-center`, aligns text x-axes - with the line. - * `viewport`: Produces glyphs whose x-axes are aligned with the x-axis of the - viewport, regardless of the value of `symbol-placement`. - * `auto`: When `symbol-placement` is set to `point`, this is equivalent to - `viewport`. When `symbol-placement` is set to `line` or `line-center`, this is - equivalent to `map`. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textRotationAlignment; - -/** - Specifies how to capitalize text. - - The default value of this property is an expression that evaluates to `none`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLTextTransform` values - * Any of the following constant string values: - * `none`: The text is not altered. - * `uppercase`: Forces all letters to be displayed in uppercase. - * `lowercase`: Forces all letters to be displayed in lowercase. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textTransform; - -/** - To increase the chance of placing high-priority labels on the map, you can - provide an array of `textAnchor` locations: the renderer will attempt to place - the label at each location, in order, before moving onto the next label. Use - `textJustify: auto` to choose justification based on anchor position. To apply - an offset, use the `textRadialOffset` or the two-dimensional `textOffset`. - - This property is only applied to the style if `text` is non-`nil`, and - `symbolPlacement` is set to an expression that evaluates to or - `MGLSymbolPlacementPoint`. Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `MGLTextAnchor` array values - * Constant array, in which each element is any of the following constant string - values: - * `center`: The center of the text is placed closest to the anchor. - * `left`: The left side of the text is placed closest to the anchor. - * `right`: The right side of the text is placed closest to the anchor. - * `top`: The top of the text is placed closest to the anchor. - * `bottom`: The bottom of the text is placed closest to the anchor. - * `top-left`: The top left corner of the text is placed closest to the - anchor. - * `top-right`: The top right corner of the text is placed closest to the - anchor. - * `bottom-left`: The bottom left corner of the text is placed closest to the - anchor. - * `bottom-right`: The bottom right corner of the text is placed closest to - the anchor. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textVariableAnchor; - -/** - The property allows control over a symbol's orientation. Note that the property - values act as a hint, so that a symbol whose language doesn’t support the - provided orientation will be laid out in its natural orientation. Example: - English point symbol will be rendered horizontally even if array value contains - single 'vertical' enum value. The order of elements in an array define priority - order for the placement of an orientation variant. - - This property is only applied to the style if `text` is non-`nil`, and - `symbolPlacement` is set to an expression that evaluates to or - `MGLSymbolPlacementPoint`. Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#layout-symbol-text-writing-mode"><code>text-writing-mode</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLTextWritingMode` array values - * Constant array, in which each element is any of the following constant string - values: - * `horizontal`: If a text's language supports horizontal writing mode, - symbols with point placement would be laid out horizontally. - * `vertical`: If a text's language supports vertical writing mode, symbols - with point placement would be laid out vertically. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textWritingModes; - - -@property (nonatomic, null_resettable) NSExpression *textWritingMode __attribute__((unavailable("Use textWritingModes instead."))); - -#pragma mark - Accessing the Paint Attributes - -#if TARGET_OS_IPHONE -/** - The tint color to apply to the icon. The `iconImageName` property must be set - to a template image. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconColor; -#else -/** - The tint color to apply to the icon. The `iconImageName` property must be set - to a template image. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconColor; -#endif - -/** - The transition affecting any changes to this layer’s `iconColor` property. - - This property corresponds to the `icon-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition iconColorTransition; - -/** - Fade out the halo towards the outside. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconHaloBlur; - -/** - The transition affecting any changes to this layer’s `iconHaloBlur` property. - - This property corresponds to the `icon-halo-blur-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition iconHaloBlurTransition; - -#if TARGET_OS_IPHONE -/** - The color of the icon’s halo. The `iconImageName` property must be set to a - template image. - - The default value of this property is an expression that evaluates to - `UIColor.clearColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconHaloColor; -#else -/** - The color of the icon’s halo. The `iconImageName` property must be set to a - template image. - - The default value of this property is an expression that evaluates to - `NSColor.clearColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconHaloColor; -#endif - -/** - The transition affecting any changes to this layer’s `iconHaloColor` property. - - This property corresponds to the `icon-halo-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition iconHaloColorTransition; - -/** - Distance of halo to the icon outline. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconHaloWidth; - -/** - The transition affecting any changes to this layer’s `iconHaloWidth` property. - - This property corresponds to the `icon-halo-width-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition iconHaloWidthTransition; - -/** - The opacity at which the icon will be drawn. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *iconOpacity; - -/** - The transition affecting any changes to this layer’s `iconOpacity` property. - - This property corresponds to the `icon-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition iconOpacityTransition; - -#if TARGET_OS_IPHONE -/** - Distance that the icon's anchor is moved from its original placement. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points downward. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-icon-translate"><code>icon-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconTranslation; -#else -/** - Distance that the icon's anchor is moved from its original placement. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points upward. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`. - Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-icon-translate"><code>icon-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconTranslation; -#endif - -/** - The transition affecting any changes to this layer’s `iconTranslation` property. - - This property corresponds to the `icon-translate-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition iconTranslationTransition; - -@property (nonatomic, null_resettable) NSExpression *iconTranslate __attribute__((unavailable("Use iconTranslation instead."))); - -/** - Controls the frame of reference for `iconTranslation`. - - The default value of this property is an expression that evaluates to `map`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `iconImageName` is non-`nil`, and - `iconTranslation` is non-`nil`. Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-icon-translate-anchor"><code>icon-translate-anchor</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLIconTranslationAnchor` values - * Any of the following constant string values: - * `map`: Icons are translated relative to the map. - * `viewport`: Icons are translated relative to the viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *iconTranslationAnchor; - -@property (nonatomic, null_resettable) NSExpression *iconTranslateAnchor __attribute__((unavailable("Use iconTranslationAnchor instead."))); - -#if TARGET_OS_IPHONE -/** - The color with which the text will be drawn. - - The default value of this property is an expression that evaluates to - `UIColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textColor; -#else -/** - The color with which the text will be drawn. - - The default value of this property is an expression that evaluates to - `NSColor.blackColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textColor; -#endif - -/** - The transition affecting any changes to this layer’s `textColor` property. - - This property corresponds to the `text-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition textColorTransition; - -/** - The halo's fadeout distance towards the outside. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textHaloBlur; - -/** - The transition affecting any changes to this layer’s `textHaloBlur` property. - - This property corresponds to the `text-halo-blur-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition textHaloBlurTransition; - -#if TARGET_OS_IPHONE -/** - The color of the text's halo, which helps it stand out from backgrounds. - - The default value of this property is an expression that evaluates to - `UIColor.clearColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `UIColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textHaloColor; -#else -/** - The color of the text's halo, which helps it stand out from backgrounds. - - The default value of this property is an expression that evaluates to - `NSColor.clearColor`. Set this property to `nil` to reset it to the default - value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant `NSColor` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textHaloColor; -#endif - -/** - The transition affecting any changes to this layer’s `textHaloColor` property. - - This property corresponds to the `text-halo-color-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition textHaloColorTransition; - -/** - Distance of halo to the font outline. Max text halo width is 1/4 of the - font-size. - - This property is measured in points. - - The default value of this property is an expression that evaluates to the float - `0`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values no less than 0 - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textHaloWidth; - -/** - The transition affecting any changes to this layer’s `textHaloWidth` property. - - This property corresponds to the `text-halo-width-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition textHaloWidthTransition; - -/** - The opacity at which the text will be drawn. - - The default value of this property is an expression that evaluates to the float - `1`. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - You can set this property to an expression containing any of the following: - - * Constant numeric values between 0 and 1 inclusive - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable and/or - feature attributes - */ -@property (nonatomic, null_resettable) NSExpression *textOpacity; - -/** - The transition affecting any changes to this layer’s `textOpacity` property. - - This property corresponds to the `text-opacity-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition textOpacityTransition; - -#if TARGET_OS_IPHONE -/** - Distance that the text's anchor is moved from its original placement. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points downward. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-text-translate"><code>text-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textTranslation; -#else -/** - Distance that the text's anchor is moved from its original placement. - - This property is measured in points. - - The default value of this property is an expression that evaluates to an - `NSValue` object containing a `CGVector` struct set to 0 points rightward and 0 - points upward. Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`. Otherwise, - it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-text-translate"><code>text-translate</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `CGVector` values - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Interpolation and step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation or step functions to - feature attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textTranslation; -#endif - -/** - The transition affecting any changes to this layer’s `textTranslation` property. - - This property corresponds to the `text-translate-transition` property in the style JSON file format. -*/ -@property (nonatomic) MGLTransition textTranslationTransition; - -@property (nonatomic, null_resettable) NSExpression *textTranslate __attribute__((unavailable("Use textTranslation instead."))); - -/** - Controls the frame of reference for `textTranslation`. - - The default value of this property is an expression that evaluates to `map`. - Set this property to `nil` to reset it to the default value. - - This property is only applied to the style if `text` is non-`nil`, and - `textTranslation` is non-`nil`. Otherwise, it is ignored. - - This attribute corresponds to the <a - href="https://www.mapbox.com/mapbox-gl-style-spec/#paint-text-translate-anchor"><code>text-translate-anchor</code></a> - layout property in the Mapbox Style Specification. - - You can set this property to an expression containing any of the following: - - * Constant `MGLTextTranslationAnchor` values - * Any of the following constant string values: - * `map`: The text is translated relative to the map. - * `viewport`: The text is translated relative to the viewport. - * Predefined functions, including mathematical and string operators - * Conditional expressions - * Variable assignments and references to assigned variables - * Step functions applied to the `$zoomLevel` variable - - This property does not support applying interpolation functions to the - `$zoomLevel` variable or applying interpolation or step functions to feature - attributes. - */ -@property (nonatomic, null_resettable) NSExpression *textTranslationAnchor; - -@property (nonatomic, null_resettable) NSExpression *textTranslateAnchor __attribute__((unavailable("Use textTranslationAnchor instead."))); - -@end - -/** - Methods for wrapping an enumeration value for a style layer attribute in an - `MGLSymbolStyleLayer` object and unwrapping its raw value. - */ -@interface NSValue (MGLSymbolStyleLayerAdditions) - -#pragma mark Working with Symbol Style Layer Attribute Values - -/** - Creates a new value object containing the given `MGLIconAnchor` enumeration. - - @param iconAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLIconAnchor:(MGLIconAnchor)iconAnchor; - -/** - The `MGLIconAnchor` enumeration representation of the value. - */ -@property (readonly) MGLIconAnchor MGLIconAnchorValue; - -/** - Creates a new value object containing the given `MGLIconPitchAlignment` enumeration. - - @param iconPitchAlignment The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLIconPitchAlignment:(MGLIconPitchAlignment)iconPitchAlignment; - -/** - The `MGLIconPitchAlignment` enumeration representation of the value. - */ -@property (readonly) MGLIconPitchAlignment MGLIconPitchAlignmentValue; - -/** - Creates a new value object containing the given `MGLIconRotationAlignment` enumeration. - - @param iconRotationAlignment The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLIconRotationAlignment:(MGLIconRotationAlignment)iconRotationAlignment; - -/** - The `MGLIconRotationAlignment` enumeration representation of the value. - */ -@property (readonly) MGLIconRotationAlignment MGLIconRotationAlignmentValue; - -/** - Creates a new value object containing the given `MGLIconTextFit` enumeration. - - @param iconTextFit The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLIconTextFit:(MGLIconTextFit)iconTextFit; - -/** - The `MGLIconTextFit` enumeration representation of the value. - */ -@property (readonly) MGLIconTextFit MGLIconTextFitValue; - -/** - Creates a new value object containing the given `MGLSymbolPlacement` enumeration. - - @param symbolPlacement The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLSymbolPlacement:(MGLSymbolPlacement)symbolPlacement; - -/** - The `MGLSymbolPlacement` enumeration representation of the value. - */ -@property (readonly) MGLSymbolPlacement MGLSymbolPlacementValue; - -/** - Creates a new value object containing the given `MGLSymbolZOrder` enumeration. - - @param symbolZOrder The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLSymbolZOrder:(MGLSymbolZOrder)symbolZOrder; - -/** - The `MGLSymbolZOrder` enumeration representation of the value. - */ -@property (readonly) MGLSymbolZOrder MGLSymbolZOrderValue; - -/** - Creates a new value object containing the given `MGLTextAnchor` enumeration. - - @param textAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLTextAnchor:(MGLTextAnchor)textAnchor; - -/** - The `MGLTextAnchor` enumeration representation of the value. - */ -@property (readonly) MGLTextAnchor MGLTextAnchorValue; - -/** - Creates a new value object containing the given `MGLTextJustification` enumeration. - - @param textJustification The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLTextJustification:(MGLTextJustification)textJustification; - -/** - The `MGLTextJustification` enumeration representation of the value. - */ -@property (readonly) MGLTextJustification MGLTextJustificationValue; - -/** - Creates a new value object containing the given `MGLTextPitchAlignment` enumeration. - - @param textPitchAlignment The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLTextPitchAlignment:(MGLTextPitchAlignment)textPitchAlignment; - -/** - The `MGLTextPitchAlignment` enumeration representation of the value. - */ -@property (readonly) MGLTextPitchAlignment MGLTextPitchAlignmentValue; - -/** - Creates a new value object containing the given `MGLTextRotationAlignment` enumeration. - - @param textRotationAlignment The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLTextRotationAlignment:(MGLTextRotationAlignment)textRotationAlignment; - -/** - The `MGLTextRotationAlignment` enumeration representation of the value. - */ -@property (readonly) MGLTextRotationAlignment MGLTextRotationAlignmentValue; - -/** - Creates a new value object containing the given `MGLTextTransform` enumeration. - - @param textTransform The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLTextTransform:(MGLTextTransform)textTransform; - -/** - The `MGLTextTransform` enumeration representation of the value. - */ -@property (readonly) MGLTextTransform MGLTextTransformValue; - -/** - Creates a new value object containing the given `MGLTextWritingMode` enumeration. - - @param textWritingModes The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLTextWritingMode:(MGLTextWritingMode)textWritingModes; - -/** - The `MGLTextWritingMode` enumeration representation of the value. - */ -@property (readonly) MGLTextWritingMode MGLTextWritingModeValue; - -/** - Creates a new value object containing the given `MGLIconTranslationAnchor` enumeration. - - @param iconTranslationAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLIconTranslationAnchor:(MGLIconTranslationAnchor)iconTranslationAnchor; - -/** - The `MGLIconTranslationAnchor` enumeration representation of the value. - */ -@property (readonly) MGLIconTranslationAnchor MGLIconTranslationAnchorValue; - -/** - Creates a new value object containing the given `MGLTextTranslationAnchor` enumeration. - - @param textTranslationAnchor The value for the new object. - @return A new value object that contains the enumeration value. - */ -+ (instancetype)valueWithMGLTextTranslationAnchor:(MGLTextTranslationAnchor)textTranslationAnchor; - -/** - The `MGLTextTranslationAnchor` enumeration representation of the value. - */ -@property (readonly) MGLTextTranslationAnchor MGLTextTranslationAnchorValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm deleted file mode 100644 index 966386e0f2..0000000000 --- a/platform/darwin/src/MGLSymbolStyleLayer.mm +++ /dev/null @@ -1,1670 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. - -#import "MGLSource.h" -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSDate+MGLAdditions.h" -#import "MGLStyleLayer_Private.h" -#import "MGLStyleValue_Private.h" -#import "MGLSymbolStyleLayer.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLSymbolStyleLayer_Private.h" - -#include <mbgl/style/layers/symbol_layer.hpp> -#include <mbgl/style/transition_options.hpp> - - -namespace mbgl { - - MBGL_DEFINE_ENUM(MGLIconAnchor, { - { MGLIconAnchorCenter, "center" }, - { MGLIconAnchorLeft, "left" }, - { MGLIconAnchorRight, "right" }, - { MGLIconAnchorTop, "top" }, - { MGLIconAnchorBottom, "bottom" }, - { MGLIconAnchorTopLeft, "top-left" }, - { MGLIconAnchorTopRight, "top-right" }, - { MGLIconAnchorBottomLeft, "bottom-left" }, - { MGLIconAnchorBottomRight, "bottom-right" }, - }); - - MBGL_DEFINE_ENUM(MGLIconPitchAlignment, { - { MGLIconPitchAlignmentMap, "map" }, - { MGLIconPitchAlignmentViewport, "viewport" }, - { MGLIconPitchAlignmentAuto, "auto" }, - }); - - MBGL_DEFINE_ENUM(MGLIconRotationAlignment, { - { MGLIconRotationAlignmentMap, "map" }, - { MGLIconRotationAlignmentViewport, "viewport" }, - { MGLIconRotationAlignmentAuto, "auto" }, - }); - - MBGL_DEFINE_ENUM(MGLIconTextFit, { - { MGLIconTextFitNone, "none" }, - { MGLIconTextFitWidth, "width" }, - { MGLIconTextFitHeight, "height" }, - { MGLIconTextFitBoth, "both" }, - }); - - MBGL_DEFINE_ENUM(MGLSymbolPlacement, { - { MGLSymbolPlacementPoint, "point" }, - { MGLSymbolPlacementLine, "line" }, - { MGLSymbolPlacementLineCenter, "line-center" }, - }); - - MBGL_DEFINE_ENUM(MGLSymbolZOrder, { - { MGLSymbolZOrderAuto, "auto" }, - { MGLSymbolZOrderViewportY, "viewport-y" }, - { MGLSymbolZOrderSource, "source" }, - }); - - MBGL_DEFINE_ENUM(MGLTextAnchor, { - { MGLTextAnchorCenter, "center" }, - { MGLTextAnchorLeft, "left" }, - { MGLTextAnchorRight, "right" }, - { MGLTextAnchorTop, "top" }, - { MGLTextAnchorBottom, "bottom" }, - { MGLTextAnchorTopLeft, "top-left" }, - { MGLTextAnchorTopRight, "top-right" }, - { MGLTextAnchorBottomLeft, "bottom-left" }, - { MGLTextAnchorBottomRight, "bottom-right" }, - }); - - MBGL_DEFINE_ENUM(MGLTextJustification, { - { MGLTextJustificationAuto, "auto" }, - { MGLTextJustificationLeft, "left" }, - { MGLTextJustificationCenter, "center" }, - { MGLTextJustificationRight, "right" }, - }); - - MBGL_DEFINE_ENUM(MGLTextPitchAlignment, { - { MGLTextPitchAlignmentMap, "map" }, - { MGLTextPitchAlignmentViewport, "viewport" }, - { MGLTextPitchAlignmentAuto, "auto" }, - }); - - MBGL_DEFINE_ENUM(MGLTextRotationAlignment, { - { MGLTextRotationAlignmentMap, "map" }, - { MGLTextRotationAlignmentViewport, "viewport" }, - { MGLTextRotationAlignmentAuto, "auto" }, - }); - - MBGL_DEFINE_ENUM(MGLTextTransform, { - { MGLTextTransformNone, "none" }, - { MGLTextTransformUppercase, "uppercase" }, - { MGLTextTransformLowercase, "lowercase" }, - }); - - MBGL_DEFINE_ENUM(MGLTextWritingMode, { - { MGLTextWritingModeHorizontal, "horizontal" }, - { MGLTextWritingModeVertical, "vertical" }, - }); - - MBGL_DEFINE_ENUM(MGLIconTranslationAnchor, { - { MGLIconTranslationAnchorMap, "map" }, - { MGLIconTranslationAnchorViewport, "viewport" }, - }); - - MBGL_DEFINE_ENUM(MGLTextTranslationAnchor, { - { MGLTextTranslationAnchorMap, "map" }, - { MGLTextTranslationAnchorViewport, "viewport" }, - }); - -} - -@interface MGLSymbolStyleLayer () - -@property (nonatomic, readonly) mbgl::style::SymbolLayer *rawLayer; - -@end - -@implementation MGLSymbolStyleLayer - -- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source -{ - MGLLogDebug(@"Initializing %@ with identifier: %@ source: %@", NSStringFromClass([self class]), identifier, source); - auto layer = std::make_unique<mbgl::style::SymbolLayer>(identifier.UTF8String, source.identifier.UTF8String); - return self = [super initWithPendingLayer:std::move(layer)]; -} - -- (mbgl::style::SymbolLayer *)rawLayer -{ - return (mbgl::style::SymbolLayer *)super.rawLayer; -} - -- (NSString *)sourceIdentifier -{ - MGLAssertStyleLayerIsValid(); - - return @(self.rawLayer->getSourceID().c_str()); -} - -- (NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - - auto layerID = self.rawLayer->getSourceLayer(); - return layerID.empty() ? nil : @(layerID.c_str()); -} - -- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting sourceLayerIdentifier: %@", sourceLayerIdentifier); - - self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); -} - -- (void)setPredicate:(NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting predicate: %@", predicate); - - self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::Filter()); -} - -- (NSPredicate *)predicate -{ - MGLAssertStyleLayerIsValid(); - - return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; -} - -#pragma mark - Accessing the Layout Attributes - -- (void)setIconAllowsOverlap:(NSExpression *)iconAllowsOverlap { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconAllowsOverlap: %@", iconAllowsOverlap); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(iconAllowsOverlap, false); - self.rawLayer->setIconAllowOverlap(mbglValue); -} - -- (NSExpression *)iconAllowsOverlap { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconAllowOverlap(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconAllowOverlap(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconAllowOverlap:(NSExpression *)iconAllowOverlap { -} - -- (NSExpression *)iconAllowOverlap { - return self.iconAllowsOverlap; -} - -- (void)setIconAnchor:(NSExpression *)iconAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconAnchor: %@", iconAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::SymbolAnchorType, NSValue *, mbgl::style::SymbolAnchorType, MGLIconAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::SymbolAnchorType>>(iconAnchor, true); - self.rawLayer->setIconAnchor(mbglValue); -} - -- (NSExpression *)iconAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::SymbolAnchorType, NSValue *, mbgl::style::SymbolAnchorType, MGLIconAnchor>().toExpression(propertyValue); -} - -- (void)setIconIgnoresPlacement:(NSExpression *)iconIgnoresPlacement { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconIgnoresPlacement: %@", iconIgnoresPlacement); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(iconIgnoresPlacement, false); - self.rawLayer->setIconIgnorePlacement(mbglValue); -} - -- (NSExpression *)iconIgnoresPlacement { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconIgnorePlacement(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconIgnorePlacement(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconIgnorePlacement:(NSExpression *)iconIgnorePlacement { -} - -- (NSExpression *)iconIgnorePlacement { - return self.iconIgnoresPlacement; -} - -- (void)setIconImageName:(NSExpression *)iconImageName { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconImageName: %@", iconImageName); - - if (iconImageName && iconImageName.expressionType == NSConstantValueExpressionType) { - std::string string = ((NSString *)iconImageName.constantValue).UTF8String; - if (mbgl::style::conversion::hasTokens(string)) { - self.rawLayer->setIconImage(mbgl::style::PropertyValue<mbgl::style::expression::Image>( - mbgl::style::conversion::convertTokenStringToImageExpression(string))); - return; - } - } - auto mbglValue = MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::expression::Image>>(iconImageName, true); - self.rawLayer->setIconImage(mbglValue); -} - -- (NSExpression *)iconImageName { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconImage(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconImage(); - } - return MGLStyleValueTransformer<mbgl::style::expression::Image, NSString *>().toExpression(propertyValue); -} - -- (void)setIconImage:(NSExpression *)iconImage { -} - -- (NSExpression *)iconImage { - return self.iconImageName; -} - -- (void)setIconOffset:(NSExpression *)iconOffset { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconOffset: %@", iconOffset); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 2>>>(iconOffset, true); - self.rawLayer->setIconOffset(mbglValue); -} - -- (NSExpression *)iconOffset { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconOffset(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconOffset(); - } - return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toExpression(propertyValue); -} - -- (void)setIconOptional:(NSExpression *)iconOptional { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconOptional: %@", iconOptional); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(iconOptional, false); - self.rawLayer->setIconOptional(mbglValue); -} - -- (NSExpression *)isIconOptional { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconOptional(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconOptional(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconPadding:(NSExpression *)iconPadding { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconPadding: %@", iconPadding); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(iconPadding, false); - self.rawLayer->setIconPadding(mbglValue); -} - -- (NSExpression *)iconPadding { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconPadding(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconPadding(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconPitchAlignment:(NSExpression *)iconPitchAlignment { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconPitchAlignment: %@", iconPitchAlignment); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLIconPitchAlignment>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::AlignmentType>>(iconPitchAlignment, false); - self.rawLayer->setIconPitchAlignment(mbglValue); -} - -- (NSExpression *)iconPitchAlignment { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconPitchAlignment(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconPitchAlignment(); - } - return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLIconPitchAlignment>().toExpression(propertyValue); -} - -- (void)setIconRotation:(NSExpression *)iconRotation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconRotation: %@", iconRotation); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(iconRotation, true); - self.rawLayer->setIconRotate(mbglValue); -} - -- (NSExpression *)iconRotation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconRotate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconRotate(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconRotate:(NSExpression *)iconRotate { -} - -- (NSExpression *)iconRotate { - return self.iconRotation; -} - -- (void)setIconRotationAlignment:(NSExpression *)iconRotationAlignment { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconRotationAlignment: %@", iconRotationAlignment); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLIconRotationAlignment>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::AlignmentType>>(iconRotationAlignment, false); - self.rawLayer->setIconRotationAlignment(mbglValue); -} - -- (NSExpression *)iconRotationAlignment { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconRotationAlignment(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconRotationAlignment(); - } - return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLIconRotationAlignment>().toExpression(propertyValue); -} - -- (void)setIconScale:(NSExpression *)iconScale { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconScale: %@", iconScale); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(iconScale, true); - self.rawLayer->setIconSize(mbglValue); -} - -- (NSExpression *)iconScale { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconSize(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconSize(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconSize:(NSExpression *)iconSize { -} - -- (NSExpression *)iconSize { - return self.iconScale; -} - -- (void)setIconTextFit:(NSExpression *)iconTextFit { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconTextFit: %@", iconTextFit); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::IconTextFitType, NSValue *, mbgl::style::IconTextFitType, MGLIconTextFit>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::IconTextFitType>>(iconTextFit, false); - self.rawLayer->setIconTextFit(mbglValue); -} - -- (NSExpression *)iconTextFit { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconTextFit(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconTextFit(); - } - return MGLStyleValueTransformer<mbgl::style::IconTextFitType, NSValue *, mbgl::style::IconTextFitType, MGLIconTextFit>().toExpression(propertyValue); -} - -- (void)setIconTextFitPadding:(NSExpression *)iconTextFitPadding { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconTextFitPadding: %@", iconTextFitPadding); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 4>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 4>>>(iconTextFitPadding, false); - self.rawLayer->setIconTextFitPadding(mbglValue); -} - -- (NSExpression *)iconTextFitPadding { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconTextFitPadding(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconTextFitPadding(); - } - return MGLStyleValueTransformer<std::array<float, 4>, NSValue *>().toExpression(propertyValue); -} - -- (void)setKeepsIconUpright:(NSExpression *)keepsIconUpright { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting keepsIconUpright: %@", keepsIconUpright); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(keepsIconUpright, false); - self.rawLayer->setIconKeepUpright(mbglValue); -} - -- (NSExpression *)keepsIconUpright { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconKeepUpright(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconKeepUpright(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconKeepUpright:(NSExpression *)iconKeepUpright { -} - -- (NSExpression *)iconKeepUpright { - return self.keepsIconUpright; -} - -- (void)setKeepsTextUpright:(NSExpression *)keepsTextUpright { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting keepsTextUpright: %@", keepsTextUpright); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(keepsTextUpright, false); - self.rawLayer->setTextKeepUpright(mbglValue); -} - -- (NSExpression *)keepsTextUpright { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextKeepUpright(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextKeepUpright(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextKeepUpright:(NSExpression *)textKeepUpright { -} - -- (NSExpression *)textKeepUpright { - return self.keepsTextUpright; -} - -- (void)setMaximumTextAngle:(NSExpression *)maximumTextAngle { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting maximumTextAngle: %@", maximumTextAngle); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(maximumTextAngle, false); - self.rawLayer->setTextMaxAngle(mbglValue); -} - -- (NSExpression *)maximumTextAngle { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextMaxAngle(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextMaxAngle(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextMaxAngle:(NSExpression *)textMaxAngle { -} - -- (NSExpression *)textMaxAngle { - return self.maximumTextAngle; -} - -- (void)setMaximumTextWidth:(NSExpression *)maximumTextWidth { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting maximumTextWidth: %@", maximumTextWidth); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(maximumTextWidth, true); - self.rawLayer->setTextMaxWidth(mbglValue); -} - -- (NSExpression *)maximumTextWidth { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextMaxWidth(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextMaxWidth(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextMaxWidth:(NSExpression *)textMaxWidth { -} - -- (NSExpression *)textMaxWidth { - return self.maximumTextWidth; -} - -- (void)setSymbolAvoidsEdges:(NSExpression *)symbolAvoidsEdges { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting symbolAvoidsEdges: %@", symbolAvoidsEdges); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(symbolAvoidsEdges, false); - self.rawLayer->setSymbolAvoidEdges(mbglValue); -} - -- (NSExpression *)symbolAvoidsEdges { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getSymbolAvoidEdges(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultSymbolAvoidEdges(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setSymbolAvoidEdges:(NSExpression *)symbolAvoidEdges { -} - -- (NSExpression *)symbolAvoidEdges { - return self.symbolAvoidsEdges; -} - -- (void)setSymbolPlacement:(NSExpression *)symbolPlacement { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting symbolPlacement: %@", symbolPlacement); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *, mbgl::style::SymbolPlacementType, MGLSymbolPlacement>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::SymbolPlacementType>>(symbolPlacement, false); - self.rawLayer->setSymbolPlacement(mbglValue); -} - -- (NSExpression *)symbolPlacement { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getSymbolPlacement(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultSymbolPlacement(); - } - return MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *, mbgl::style::SymbolPlacementType, MGLSymbolPlacement>().toExpression(propertyValue); -} - -- (void)setSymbolSortKey:(NSExpression *)symbolSortKey { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting symbolSortKey: %@", symbolSortKey); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(symbolSortKey, true); - self.rawLayer->setSymbolSortKey(mbglValue); -} - -- (NSExpression *)symbolSortKey { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getSymbolSortKey(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultSymbolSortKey(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setSymbolSpacing:(NSExpression *)symbolSpacing { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting symbolSpacing: %@", symbolSpacing); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(symbolSpacing, false); - self.rawLayer->setSymbolSpacing(mbglValue); -} - -- (NSExpression *)symbolSpacing { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getSymbolSpacing(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultSymbolSpacing(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setSymbolZOrder:(NSExpression *)symbolZOrder { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting symbolZOrder: %@", symbolZOrder); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::SymbolZOrderType, NSValue *, mbgl::style::SymbolZOrderType, MGLSymbolZOrder>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::SymbolZOrderType>>(symbolZOrder, false); - self.rawLayer->setSymbolZOrder(mbglValue); -} - -- (NSExpression *)symbolZOrder { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getSymbolZOrder(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultSymbolZOrder(); - } - return MGLStyleValueTransformer<mbgl::style::SymbolZOrderType, NSValue *, mbgl::style::SymbolZOrderType, MGLSymbolZOrder>().toExpression(propertyValue); -} - -- (void)setText:(NSExpression *)text { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting text: %@", text); - - if (text && text.expressionType == NSConstantValueExpressionType) { - std::string string = ((NSString *)text.constantValue).UTF8String; - if (mbgl::style::conversion::hasTokens(string)) { - self.rawLayer->setTextField(mbgl::style::PropertyValue<mbgl::style::expression::Formatted>( - mbgl::style::conversion::convertTokenStringToFormatExpression(string))); - return; - } - } - auto mbglValue = MGLStyleValueTransformer<mbgl::style::expression::Formatted, NSString *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::expression::Formatted>>(text, true); - self.rawLayer->setTextField(mbglValue); -} - -- (NSExpression *)text { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextField(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextField(); - } - return MGLStyleValueTransformer<mbgl::style::expression::Formatted, NSString *>().toExpression(propertyValue); -} - -- (void)setTextField:(NSExpression *)textField { -} - -- (NSExpression *)textField { - return self.text; -} - -- (void)setTextAllowsOverlap:(NSExpression *)textAllowsOverlap { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textAllowsOverlap: %@", textAllowsOverlap); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(textAllowsOverlap, false); - self.rawLayer->setTextAllowOverlap(mbglValue); -} - -- (NSExpression *)textAllowsOverlap { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextAllowOverlap(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextAllowOverlap(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextAllowOverlap:(NSExpression *)textAllowOverlap { -} - -- (NSExpression *)textAllowOverlap { - return self.textAllowsOverlap; -} - -- (void)setTextAnchor:(NSExpression *)textAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textAnchor: %@", textAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::SymbolAnchorType, NSValue *, mbgl::style::SymbolAnchorType, MGLTextAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::SymbolAnchorType>>(textAnchor, true); - self.rawLayer->setTextAnchor(mbglValue); -} - -- (NSExpression *)textAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::SymbolAnchorType, NSValue *, mbgl::style::SymbolAnchorType, MGLTextAnchor>().toExpression(propertyValue); -} - -- (void)setTextFontNames:(NSExpression *)textFontNames { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textFontNames: %@", textFontNames); - - auto mbglValue = MGLStyleValueTransformer<std::vector<std::string>, NSArray<NSString *> *, std::string>().toPropertyValue<mbgl::style::PropertyValue<std::vector<std::string>>>(textFontNames, true); - self.rawLayer->setTextFont(mbglValue); -} - -- (NSExpression *)textFontNames { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextFont(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextFont(); - } - return MGLStyleValueTransformer<std::vector<std::string>, NSArray<NSString *> *, std::string>().toExpression(propertyValue); -} - -- (void)setTextFont:(NSExpression *)textFont { -} - -- (NSExpression *)textFont { - return self.textFontNames; -} - -- (void)setTextFontSize:(NSExpression *)textFontSize { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textFontSize: %@", textFontSize); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textFontSize, true); - self.rawLayer->setTextSize(mbglValue); -} - -- (NSExpression *)textFontSize { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextSize(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextSize(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextSize:(NSExpression *)textSize { -} - -- (NSExpression *)textSize { - return self.textFontSize; -} - -- (void)setTextIgnoresPlacement:(NSExpression *)textIgnoresPlacement { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textIgnoresPlacement: %@", textIgnoresPlacement); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(textIgnoresPlacement, false); - self.rawLayer->setTextIgnorePlacement(mbglValue); -} - -- (NSExpression *)textIgnoresPlacement { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextIgnorePlacement(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextIgnorePlacement(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextIgnorePlacement:(NSExpression *)textIgnorePlacement { -} - -- (NSExpression *)textIgnorePlacement { - return self.textIgnoresPlacement; -} - -- (void)setTextJustification:(NSExpression *)textJustification { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textJustification: %@", textJustification); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextJustifyType, NSValue *, mbgl::style::TextJustifyType, MGLTextJustification>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::TextJustifyType>>(textJustification, true); - self.rawLayer->setTextJustify(mbglValue); -} - -- (NSExpression *)textJustification { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextJustify(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextJustify(); - } - return MGLStyleValueTransformer<mbgl::style::TextJustifyType, NSValue *, mbgl::style::TextJustifyType, MGLTextJustification>().toExpression(propertyValue); -} - -- (void)setTextJustify:(NSExpression *)textJustify { -} - -- (NSExpression *)textJustify { - return self.textJustification; -} - -- (void)setTextLetterSpacing:(NSExpression *)textLetterSpacing { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textLetterSpacing: %@", textLetterSpacing); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textLetterSpacing, true); - self.rawLayer->setTextLetterSpacing(mbglValue); -} - -- (NSExpression *)textLetterSpacing { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextLetterSpacing(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextLetterSpacing(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextLineHeight:(NSExpression *)textLineHeight { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textLineHeight: %@", textLineHeight); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textLineHeight, false); - self.rawLayer->setTextLineHeight(mbglValue); -} - -- (NSExpression *)textLineHeight { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextLineHeight(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextLineHeight(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextOffset:(NSExpression *)textOffset { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textOffset: %@", textOffset); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 2>>>(textOffset, true); - self.rawLayer->setTextOffset(mbglValue); -} - -- (NSExpression *)textOffset { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextOffset(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextOffset(); - } - return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toExpression(propertyValue); -} - -- (void)setTextOptional:(NSExpression *)textOptional { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textOptional: %@", textOptional); - - auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<bool>>(textOptional, false); - self.rawLayer->setTextOptional(mbglValue); -} - -- (NSExpression *)isTextOptional { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextOptional(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextOptional(); - } - return MGLStyleValueTransformer<bool, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextPadding:(NSExpression *)textPadding { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textPadding: %@", textPadding); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textPadding, false); - self.rawLayer->setTextPadding(mbglValue); -} - -- (NSExpression *)textPadding { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextPadding(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextPadding(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextPitchAlignment:(NSExpression *)textPitchAlignment { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textPitchAlignment: %@", textPitchAlignment); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextPitchAlignment>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::AlignmentType>>(textPitchAlignment, false); - self.rawLayer->setTextPitchAlignment(mbglValue); -} - -- (NSExpression *)textPitchAlignment { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextPitchAlignment(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextPitchAlignment(); - } - return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextPitchAlignment>().toExpression(propertyValue); -} - -- (void)setTextRadialOffset:(NSExpression *)textRadialOffset { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textRadialOffset: %@", textRadialOffset); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textRadialOffset, true); - self.rawLayer->setTextRadialOffset(mbglValue); -} - -- (NSExpression *)textRadialOffset { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextRadialOffset(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextRadialOffset(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextRotation:(NSExpression *)textRotation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textRotation: %@", textRotation); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textRotation, true); - self.rawLayer->setTextRotate(mbglValue); -} - -- (NSExpression *)textRotation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextRotate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextRotate(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextRotate:(NSExpression *)textRotate { -} - -- (NSExpression *)textRotate { - return self.textRotation; -} - -- (void)setTextRotationAlignment:(NSExpression *)textRotationAlignment { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textRotationAlignment: %@", textRotationAlignment); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextRotationAlignment>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::AlignmentType>>(textRotationAlignment, false); - self.rawLayer->setTextRotationAlignment(mbglValue); -} - -- (NSExpression *)textRotationAlignment { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextRotationAlignment(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextRotationAlignment(); - } - return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextRotationAlignment>().toExpression(propertyValue); -} - -- (void)setTextTransform:(NSExpression *)textTransform { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textTransform: %@", textTransform); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *, mbgl::style::TextTransformType, MGLTextTransform>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::TextTransformType>>(textTransform, true); - self.rawLayer->setTextTransform(mbglValue); -} - -- (NSExpression *)textTransform { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextTransform(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextTransform(); - } - return MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *, mbgl::style::TextTransformType, MGLTextTransform>().toExpression(propertyValue); -} - -- (void)setTextVariableAnchor:(NSExpression *)textVariableAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textVariableAnchor: %@", textVariableAnchor); - - auto mbglValue = MGLStyleValueTransformer<std::vector<mbgl::style::SymbolAnchorType>, NSArray<NSValue *> *, mbgl::style::SymbolAnchorType, MGLTextAnchor>().toPropertyValue<mbgl::style::PropertyValue<std::vector<mbgl::style::SymbolAnchorType>>>(textVariableAnchor, false); - self.rawLayer->setTextVariableAnchor(mbglValue); -} - -- (NSExpression *)textVariableAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextVariableAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextVariableAnchor(); - } - return MGLStyleValueTransformer<std::vector<mbgl::style::SymbolAnchorType>, NSArray<NSValue *> *, mbgl::style::SymbolAnchorType, MGLTextAnchor>().toExpression(propertyValue); -} - -- (void)setTextWritingModes:(NSExpression *)textWritingModes { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textWritingModes: %@", textWritingModes); - - auto mbglValue = MGLStyleValueTransformer<std::vector<mbgl::style::TextWritingModeType>, NSArray<NSValue *> *, mbgl::style::TextWritingModeType, MGLTextWritingMode>().toPropertyValue<mbgl::style::PropertyValue<std::vector<mbgl::style::TextWritingModeType>>>(textWritingModes, false); - self.rawLayer->setTextWritingMode(mbglValue); -} - -- (NSExpression *)textWritingModes { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextWritingMode(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextWritingMode(); - } - return MGLStyleValueTransformer<std::vector<mbgl::style::TextWritingModeType>, NSArray<NSValue *> *, mbgl::style::TextWritingModeType, MGLTextWritingMode>().toExpression(propertyValue); -} - -- (void)setTextWritingMode:(NSExpression *)textWritingMode { -} - -- (NSExpression *)textWritingMode { - return self.textWritingModes; -} - -#pragma mark - Accessing the Paint Attributes - -- (void)setIconColor:(NSExpression *)iconColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconColor: %@", iconColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(iconColor, true); - self.rawLayer->setIconColor(mbglValue); -} - -- (NSExpression *)iconColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setIconColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setIconColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)iconColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getIconColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setIconHaloBlur:(NSExpression *)iconHaloBlur { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconHaloBlur: %@", iconHaloBlur); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(iconHaloBlur, true); - self.rawLayer->setIconHaloBlur(mbglValue); -} - -- (NSExpression *)iconHaloBlur { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconHaloBlur(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconHaloBlur(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconHaloBlurTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconHaloBlurTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setIconHaloBlurTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)iconHaloBlurTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getIconHaloBlurTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setIconHaloColor:(NSExpression *)iconHaloColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconHaloColor: %@", iconHaloColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(iconHaloColor, true); - self.rawLayer->setIconHaloColor(mbglValue); -} - -- (NSExpression *)iconHaloColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconHaloColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconHaloColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setIconHaloColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconHaloColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setIconHaloColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)iconHaloColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getIconHaloColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setIconHaloWidth:(NSExpression *)iconHaloWidth { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconHaloWidth: %@", iconHaloWidth); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(iconHaloWidth, true); - self.rawLayer->setIconHaloWidth(mbglValue); -} - -- (NSExpression *)iconHaloWidth { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconHaloWidth(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconHaloWidth(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconHaloWidthTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconHaloWidthTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setIconHaloWidthTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)iconHaloWidthTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getIconHaloWidthTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setIconOpacity:(NSExpression *)iconOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconOpacity: %@", iconOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(iconOpacity, true); - self.rawLayer->setIconOpacity(mbglValue); -} - -- (NSExpression *)iconOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setIconOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setIconOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)iconOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getIconOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setIconTranslation:(NSExpression *)iconTranslation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconTranslation: %@", iconTranslation); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 2>>>(iconTranslation, false); - self.rawLayer->setIconTranslate(mbglValue); -} - -- (NSExpression *)iconTranslation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconTranslate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconTranslate(); - } - return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toExpression(propertyValue); -} - -- (void)setIconTranslationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconTranslationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setIconTranslateTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)iconTranslationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getIconTranslateTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setIconTranslate:(NSExpression *)iconTranslate { -} - -- (NSExpression *)iconTranslate { - return self.iconTranslation; -} - -- (void)setIconTranslationAnchor:(NSExpression *)iconTranslationAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting iconTranslationAnchor: %@", iconTranslationAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLIconTranslationAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::TranslateAnchorType>>(iconTranslationAnchor, false); - self.rawLayer->setIconTranslateAnchor(mbglValue); -} - -- (NSExpression *)iconTranslationAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getIconTranslateAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultIconTranslateAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLIconTranslationAnchor>().toExpression(propertyValue); -} - -- (void)setIconTranslateAnchor:(NSExpression *)iconTranslateAnchor { -} - -- (NSExpression *)iconTranslateAnchor { - return self.iconTranslationAnchor; -} - -- (void)setTextColor:(NSExpression *)textColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textColor: %@", textColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(textColor, true); - self.rawLayer->setTextColor(mbglValue); -} - -- (NSExpression *)textColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setTextColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setTextColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)textColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getTextColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setTextHaloBlur:(NSExpression *)textHaloBlur { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textHaloBlur: %@", textHaloBlur); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textHaloBlur, true); - self.rawLayer->setTextHaloBlur(mbglValue); -} - -- (NSExpression *)textHaloBlur { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextHaloBlur(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextHaloBlur(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextHaloBlurTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textHaloBlurTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setTextHaloBlurTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)textHaloBlurTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getTextHaloBlurTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setTextHaloColor:(NSExpression *)textHaloColor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textHaloColor: %@", textHaloColor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::PropertyValue<mbgl::Color>>(textHaloColor, true); - self.rawLayer->setTextHaloColor(mbglValue); -} - -- (NSExpression *)textHaloColor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextHaloColor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextHaloColor(); - } - return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); -} - -- (void)setTextHaloColorTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textHaloColorTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setTextHaloColorTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)textHaloColorTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getTextHaloColorTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setTextHaloWidth:(NSExpression *)textHaloWidth { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textHaloWidth: %@", textHaloWidth); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textHaloWidth, true); - self.rawLayer->setTextHaloWidth(mbglValue); -} - -- (NSExpression *)textHaloWidth { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextHaloWidth(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextHaloWidth(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextHaloWidthTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textHaloWidthTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setTextHaloWidthTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)textHaloWidthTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getTextHaloWidthTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setTextOpacity:(NSExpression *)textOpacity { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textOpacity: %@", textOpacity); - - auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textOpacity, true); - self.rawLayer->setTextOpacity(mbglValue); -} - -- (NSExpression *)textOpacity { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextOpacity(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextOpacity(); - } - return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue); -} - -- (void)setTextOpacityTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textOpacityTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setTextOpacityTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)textOpacityTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getTextOpacityTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setTextTranslation:(NSExpression *)textTranslation { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textTranslation: %@", textTranslation); - - auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue<mbgl::style::PropertyValue<std::array<float, 2>>>(textTranslation, false); - self.rawLayer->setTextTranslate(mbglValue); -} - -- (NSExpression *)textTranslation { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextTranslate(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextTranslate(); - } - return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toExpression(propertyValue); -} - -- (void)setTextTranslationTransition:(MGLTransition )transition { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textTranslationTransition: %@", MGLStringFromMGLTransition(transition)); - - self.rawLayer->setTextTranslateTransition(MGLOptionsFromTransition(transition)); -} - -- (MGLTransition)textTranslationTransition { - MGLAssertStyleLayerIsValid(); - - mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getTextTranslateTransition(); - - return MGLTransitionFromOptions(transitionOptions); -} - -- (void)setTextTranslate:(NSExpression *)textTranslate { -} - -- (NSExpression *)textTranslate { - return self.textTranslation; -} - -- (void)setTextTranslationAnchor:(NSExpression *)textTranslationAnchor { - MGLAssertStyleLayerIsValid(); - MGLLogDebug(@"Setting textTranslationAnchor: %@", textTranslationAnchor); - - auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLTextTranslationAnchor>().toPropertyValue<mbgl::style::PropertyValue<mbgl::style::TranslateAnchorType>>(textTranslationAnchor, false); - self.rawLayer->setTextTranslateAnchor(mbglValue); -} - -- (NSExpression *)textTranslationAnchor { - MGLAssertStyleLayerIsValid(); - - auto propertyValue = self.rawLayer->getTextTranslateAnchor(); - if (propertyValue.isUndefined()) { - propertyValue = self.rawLayer->getDefaultTextTranslateAnchor(); - } - return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *, mbgl::style::TranslateAnchorType, MGLTextTranslationAnchor>().toExpression(propertyValue); -} - -- (void)setTextTranslateAnchor:(NSExpression *)textTranslateAnchor { -} - -- (NSExpression *)textTranslateAnchor { - return self.textTranslationAnchor; -} - -@end - -@implementation NSValue (MGLSymbolStyleLayerAdditions) - -+ (NSValue *)valueWithMGLIconAnchor:(MGLIconAnchor)iconAnchor { - return [NSValue value:&iconAnchor withObjCType:@encode(MGLIconAnchor)]; -} - -- (MGLIconAnchor)MGLIconAnchorValue { - MGLIconAnchor iconAnchor; - [self getValue:&iconAnchor]; - return iconAnchor; -} - -+ (NSValue *)valueWithMGLIconPitchAlignment:(MGLIconPitchAlignment)iconPitchAlignment { - return [NSValue value:&iconPitchAlignment withObjCType:@encode(MGLIconPitchAlignment)]; -} - -- (MGLIconPitchAlignment)MGLIconPitchAlignmentValue { - MGLIconPitchAlignment iconPitchAlignment; - [self getValue:&iconPitchAlignment]; - return iconPitchAlignment; -} - -+ (NSValue *)valueWithMGLIconRotationAlignment:(MGLIconRotationAlignment)iconRotationAlignment { - return [NSValue value:&iconRotationAlignment withObjCType:@encode(MGLIconRotationAlignment)]; -} - -- (MGLIconRotationAlignment)MGLIconRotationAlignmentValue { - MGLIconRotationAlignment iconRotationAlignment; - [self getValue:&iconRotationAlignment]; - return iconRotationAlignment; -} - -+ (NSValue *)valueWithMGLIconTextFit:(MGLIconTextFit)iconTextFit { - return [NSValue value:&iconTextFit withObjCType:@encode(MGLIconTextFit)]; -} - -- (MGLIconTextFit)MGLIconTextFitValue { - MGLIconTextFit iconTextFit; - [self getValue:&iconTextFit]; - return iconTextFit; -} - -+ (NSValue *)valueWithMGLSymbolPlacement:(MGLSymbolPlacement)symbolPlacement { - return [NSValue value:&symbolPlacement withObjCType:@encode(MGLSymbolPlacement)]; -} - -- (MGLSymbolPlacement)MGLSymbolPlacementValue { - MGLSymbolPlacement symbolPlacement; - [self getValue:&symbolPlacement]; - return symbolPlacement; -} - -+ (NSValue *)valueWithMGLSymbolZOrder:(MGLSymbolZOrder)symbolZOrder { - return [NSValue value:&symbolZOrder withObjCType:@encode(MGLSymbolZOrder)]; -} - -- (MGLSymbolZOrder)MGLSymbolZOrderValue { - MGLSymbolZOrder symbolZOrder; - [self getValue:&symbolZOrder]; - return symbolZOrder; -} - -+ (NSValue *)valueWithMGLTextAnchor:(MGLTextAnchor)textAnchor { - return [NSValue value:&textAnchor withObjCType:@encode(MGLTextAnchor)]; -} - -- (MGLTextAnchor)MGLTextAnchorValue { - MGLTextAnchor textAnchor; - [self getValue:&textAnchor]; - return textAnchor; -} - -+ (NSValue *)valueWithMGLTextJustification:(MGLTextJustification)textJustification { - return [NSValue value:&textJustification withObjCType:@encode(MGLTextJustification)]; -} - -- (MGLTextJustification)MGLTextJustificationValue { - MGLTextJustification textJustification; - [self getValue:&textJustification]; - return textJustification; -} - -+ (NSValue *)valueWithMGLTextPitchAlignment:(MGLTextPitchAlignment)textPitchAlignment { - return [NSValue value:&textPitchAlignment withObjCType:@encode(MGLTextPitchAlignment)]; -} - -- (MGLTextPitchAlignment)MGLTextPitchAlignmentValue { - MGLTextPitchAlignment textPitchAlignment; - [self getValue:&textPitchAlignment]; - return textPitchAlignment; -} - -+ (NSValue *)valueWithMGLTextRotationAlignment:(MGLTextRotationAlignment)textRotationAlignment { - return [NSValue value:&textRotationAlignment withObjCType:@encode(MGLTextRotationAlignment)]; -} - -- (MGLTextRotationAlignment)MGLTextRotationAlignmentValue { - MGLTextRotationAlignment textRotationAlignment; - [self getValue:&textRotationAlignment]; - return textRotationAlignment; -} - -+ (NSValue *)valueWithMGLTextTransform:(MGLTextTransform)textTransform { - return [NSValue value:&textTransform withObjCType:@encode(MGLTextTransform)]; -} - -- (MGLTextTransform)MGLTextTransformValue { - MGLTextTransform textTransform; - [self getValue:&textTransform]; - return textTransform; -} - -+ (NSValue *)valueWithMGLTextWritingMode:(MGLTextWritingMode)textWritingModes { - return [NSValue value:&textWritingModes withObjCType:@encode(MGLTextWritingMode)]; -} - -- (MGLTextWritingMode)MGLTextWritingModeValue { - MGLTextWritingMode textWritingModes; - [self getValue:&textWritingModes]; - return textWritingModes; -} - -+ (NSValue *)valueWithMGLIconTranslationAnchor:(MGLIconTranslationAnchor)iconTranslationAnchor { - return [NSValue value:&iconTranslationAnchor withObjCType:@encode(MGLIconTranslationAnchor)]; -} - -- (MGLIconTranslationAnchor)MGLIconTranslationAnchorValue { - MGLIconTranslationAnchor iconTranslationAnchor; - [self getValue:&iconTranslationAnchor]; - return iconTranslationAnchor; -} - -+ (NSValue *)valueWithMGLTextTranslationAnchor:(MGLTextTranslationAnchor)textTranslationAnchor { - return [NSValue value:&textTranslationAnchor withObjCType:@encode(MGLTextTranslationAnchor)]; -} - -- (MGLTextTranslationAnchor)MGLTextTranslationAnchorValue { - MGLTextTranslationAnchor textTranslationAnchor; - [self getValue:&textTranslationAnchor]; - return textTranslationAnchor; -} - -@end - -namespace mbgl { - -MGLStyleLayer* SymbolStyleLayerPeerFactory::createPeer(style::Layer* rawLayer) { - return [[MGLSymbolStyleLayer alloc] initWithRawLayer:rawLayer]; -} - -} // namespace mbgl diff --git a/platform/darwin/src/MGLSymbolStyleLayer_Private.h b/platform/darwin/src/MGLSymbolStyleLayer_Private.h deleted file mode 100644 index 4c3505a9d4..0000000000 --- a/platform/darwin/src/MGLSymbolStyleLayer_Private.h +++ /dev/null @@ -1,17 +0,0 @@ -// This file is generated. -// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. -#pragma once - -#include "MGLStyleLayer_Private.h" - -#include <mbgl/layermanager/symbol_layer_factory.hpp> - -namespace mbgl { - -class SymbolStyleLayerPeerFactory : public LayerPeerFactory, public mbgl::SymbolLayerFactory { - // LayerPeerFactory overrides. - LayerFactory* getCoreLayerFactory() final { return this; } - virtual MGLStyleLayer* createPeer(style::Layer*) final; -}; - -} // namespace mbgl diff --git a/platform/darwin/src/MGLTilePyramidOfflineRegion.h b/platform/darwin/src/MGLTilePyramidOfflineRegion.h deleted file mode 100644 index 41fc200154..0000000000 --- a/platform/darwin/src/MGLTilePyramidOfflineRegion.h +++ /dev/null @@ -1,88 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLOfflineRegion.h" -#import "MGLGeometry.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - An offline region defined by a style URL, geographic coordinate bounds, and - range of zoom levels. - - To minimize the resources required by an irregularly shaped offline region, - use the MGLShapeOfflineRegion class instead. - - ### Example - ```swift - let northeast = CLLocationCoordinate2D(latitude: 40.989329, longitude: -102.062592) - let southwest = CLLocationCoordinate2D(latitude: 36.986207, longitude: -109.049896) - let bbox = MGLCoordinateBounds(sw: southwest, ne: northeast) - - let region = MGLTilePyramidOfflineRegion(styleURL: MGLStyle.lightStyleURL, bounds: bbox, fromZoomLevel: 11, toZoomLevel: 14) - let context = "Tile Pyramid Region".data(using: .utf8) - MGLOfflineStorage.shared.addPack(for: region, withContext: context!) - ``` - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/offline-pack/"> - Download an offline map</a> example to learn how to define an offline region - to be downloaded to a user's device. - */ -MGL_EXPORT -@interface MGLTilePyramidOfflineRegion : NSObject <MGLOfflineRegion, NSSecureCoding, NSCopying> - -/** - The coordinate bounds for the geographic region covered by the downloaded - tiles. - */ -@property (nonatomic, readonly) MGLCoordinateBounds bounds; - -/** - The minimum zoom level for which to download tiles and other resources. - - For more information about zoom levels, `-[MGLMapView zoomLevel]`. - */ -@property (nonatomic, readonly) double minimumZoomLevel; - -/** - The maximum zoom level for which to download tiles and other resources. - - For more information about zoom levels, `-[MGLMapView zoomLevel]`. - */ -@property (nonatomic, readonly) double maximumZoomLevel; - -- (instancetype)init NS_UNAVAILABLE; - -/** - Initializes a newly created offline region with the given style URL, geographic - coordinate bounds, and range of zoom levels. - - This is the designated initializer for `MGLTilePyramidOfflineRegion`. - - @param styleURL URL of the map style for which to download resources. The URL - may be a full HTTP or HTTPS URL or a Mapbox - style URL (`mapbox://styles/{user}/{style}`). Specify `nil` for the default style. - Relative file URLs cannot be used as offline style URLs. To download the - online resources required by a local style, specify a URL to an online copy - of the style. - @param bounds The coordinate bounds for the geographic region to be covered by - the downloaded tiles. - @param minimumZoomLevel The minimum zoom level to be covered by the downloaded - tiles. This parameter should be set to at least 0 but no greater than the - value of the `maximumZoomLevel` parameter. For each required tile source, if - this parameter is set to a value less than the tile source’s minimum zoom - level, the download covers zoom levels down to the tile source’s minimum - zoom level. - @param maximumZoomLevel The maximum zoom level to be covered by the downloaded - tiles. This parameter should be set to at least the value of the - `minimumZoomLevel` parameter. For each required tile source, if this - parameter is set to a value greater than the tile source’s minimum zoom - level, the download covers zoom levels up to the tile source’s maximum zoom - level. - */ -- (instancetype)initWithStyleURL:(nullable NSURL *)styleURL bounds:(MGLCoordinateBounds)bounds fromZoomLevel:(double)minimumZoomLevel toZoomLevel:(double)maximumZoomLevel NS_DESIGNATED_INITIALIZER; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLTilePyramidOfflineRegion.mm b/platform/darwin/src/MGLTilePyramidOfflineRegion.mm deleted file mode 100644 index 73fcaa91d8..0000000000 --- a/platform/darwin/src/MGLTilePyramidOfflineRegion.mm +++ /dev/null @@ -1,154 +0,0 @@ -#import "MGLTilePyramidOfflineRegion.h" - -#if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR - #import <Cocoa/Cocoa.h> -#endif - -#import "MGLOfflineRegion_Private.h" -#import "MGLTilePyramidOfflineRegion_Private.h" -#import "MGLGeometry_Private.h" -#import "MGLStyle.h" -#import "MGLLoggingConfiguration_Private.h" - -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR -#import "MMEConstants.h" -#endif - -@interface MGLTilePyramidOfflineRegion () <MGLOfflineRegion_Private, MGLTilePyramidOfflineRegion_Private> - -@end - -@implementation MGLTilePyramidOfflineRegion { - NSURL *_styleURL; -} - -@synthesize styleURL = _styleURL; -@synthesize includesIdeographicGlyphs = _includesIdeographicGlyphs; - --(NSDictionary *)offlineStartEventAttributes { - return @{ - #if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - MMEEventKeyShapeForOfflineRegion: @"tileregion", - MMEEventKeyMinZoomLevel: @(self.minimumZoomLevel), - MMEEventKeyMaxZoomLevel: @(self.maximumZoomLevel), - MMEEventKeyStyleURL: self.styleURL.absoluteString ?: [NSNull null] - #endif - }; -} - -+ (BOOL)supportsSecureCoding { - return YES; -} - -- (instancetype)init { - MGLLogInfo(@"Calling this initializer is not allowed."); - [NSException raise:NSGenericException format: - @"-[MGLTilePyramidOfflineRegion init] is unavailable. " - @"Use -initWithStyleURL:bounds:fromZoomLevel:toZoomLevel: instead."]; - return nil; -} - -- (instancetype)initWithStyleURL:(NSURL *)styleURL bounds:(MGLCoordinateBounds)bounds fromZoomLevel:(double)minimumZoomLevel toZoomLevel:(double)maximumZoomLevel { - MGLLogDebug(@"Initializing styleURL: %@ bounds: %@ fromZoomLevel: %f toZoomLevel: %f", styleURL, MGLStringFromCoordinateBounds(bounds), minimumZoomLevel, maximumZoomLevel); - if (self = [super init]) { - if (!styleURL) { - styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion]; - } - - if (!styleURL.scheme) { - [NSException raise:MGLInvalidStyleURLException format: - @"%@ does not support setting a relative file URL as the style URL. " - @"To download the online resources required by this style, " - @"specify a URL to an online copy of this style. " - @"For Mapbox-hosted styles, use the mapbox: scheme.", - NSStringFromClass([self class])]; - } - - _styleURL = styleURL; - _bounds = bounds; - _minimumZoomLevel = minimumZoomLevel; - _maximumZoomLevel = maximumZoomLevel; - _includesIdeographicGlyphs = NO; - } - return self; -} - -- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineTilePyramidRegionDefinition &)definition { - NSURL *styleURL = [NSURL URLWithString:@(definition.styleURL.c_str())]; - MGLCoordinateBounds bounds = MGLCoordinateBoundsFromLatLngBounds(definition.bounds); - MGLTilePyramidOfflineRegion* result = [self initWithStyleURL:styleURL bounds:bounds fromZoomLevel:definition.minZoom toZoomLevel:definition.maxZoom]; - result.includesIdeographicGlyphs = definition.includeIdeographs; - return result; -} - -- (const mbgl::OfflineRegionDefinition)offlineRegionDefinition { -#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR - const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale]; -#elif TARGET_OS_MAC - const float scaleFactor = [NSScreen mainScreen].backingScaleFactor; -#endif - return mbgl::OfflineTilePyramidRegionDefinition(_styleURL.absoluteString.UTF8String, - MGLLatLngBoundsFromCoordinateBounds(_bounds), - _minimumZoomLevel, _maximumZoomLevel, - scaleFactor, _includesIdeographicGlyphs); -} - -- (nullable instancetype)initWithCoder:(NSCoder *)coder { - MGLLogInfo(@"Initializing with coder."); - NSURL *styleURL = [coder decodeObjectForKey:@"styleURL"]; - CLLocationCoordinate2D sw = CLLocationCoordinate2DMake([coder decodeDoubleForKey:@"southWestLatitude"], - [coder decodeDoubleForKey:@"southWestLongitude"]); - CLLocationCoordinate2D ne = CLLocationCoordinate2DMake([coder decodeDoubleForKey:@"northEastLatitude"], - [coder decodeDoubleForKey:@"northEastLongitude"]); - MGLCoordinateBounds bounds = MGLCoordinateBoundsMake(sw, ne); - double minimumZoomLevel = [coder decodeDoubleForKey:@"minimumZoomLevel"]; - double maximumZoomLevel = [coder decodeDoubleForKey:@"maximumZoomLevel"]; - - MGLTilePyramidOfflineRegion* result = [self initWithStyleURL:styleURL bounds:bounds fromZoomLevel:minimumZoomLevel toZoomLevel:maximumZoomLevel]; - result.includesIdeographicGlyphs = [coder decodeBoolForKey:@"includesIdeographicGlyphs"]; - return result; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - [coder encodeObject:_styleURL forKey:@"styleURL"]; - [coder encodeDouble:_bounds.sw.latitude forKey:@"southWestLatitude"]; - [coder encodeDouble:_bounds.sw.longitude forKey:@"southWestLongitude"]; - [coder encodeDouble:_bounds.ne.latitude forKey:@"northEastLatitude"]; - [coder encodeDouble:_bounds.ne.longitude forKey:@"northEastLongitude"]; - [coder encodeDouble:_maximumZoomLevel forKey:@"maximumZoomLevel"]; - [coder encodeDouble:_minimumZoomLevel forKey:@"minimumZoomLevel"]; - [coder encodeBool:_includesIdeographicGlyphs forKey:@"includesIdeographicGlyphs"]; -} - -- (id)copyWithZone:(nullable NSZone *)zone { - MGLTilePyramidOfflineRegion* result = [[[self class] allocWithZone:zone] initWithStyleURL:_styleURL bounds:_bounds fromZoomLevel:_minimumZoomLevel toZoomLevel:_maximumZoomLevel]; - result.includesIdeographicGlyphs = _includesIdeographicGlyphs; - return result; -} - -- (BOOL)isEqual:(id)other { - if (other == self) { - return YES; - } - if (![other isKindOfClass:[self class]]) { - return NO; - } - - MGLTilePyramidOfflineRegion *otherRegion = other; - return (_minimumZoomLevel == otherRegion->_minimumZoomLevel - && _maximumZoomLevel == otherRegion->_maximumZoomLevel - && MGLCoordinateBoundsEqualToCoordinateBounds(_bounds, otherRegion->_bounds) - && [_styleURL isEqual:otherRegion->_styleURL] - && _includesIdeographicGlyphs == otherRegion->_includesIdeographicGlyphs); -} - -- (NSUInteger)hash { - return (_styleURL.hash - + @(_bounds.sw.latitude).hash + @(_bounds.sw.longitude).hash - + @(_bounds.ne.latitude).hash + @(_bounds.ne.longitude).hash - + @(_minimumZoomLevel).hash + @(_maximumZoomLevel).hash - + @(_includesIdeographicGlyphs).hash); -} - -@end diff --git a/platform/darwin/src/MGLTilePyramidOfflineRegion_Private.h b/platform/darwin/src/MGLTilePyramidOfflineRegion_Private.h deleted file mode 100644 index 90d8e05477..0000000000 --- a/platform/darwin/src/MGLTilePyramidOfflineRegion_Private.h +++ /dev/null @@ -1,22 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLOfflineRegion.h" - -#include <mbgl/storage/offline.hpp> - -NS_ASSUME_NONNULL_BEGIN - -@protocol MGLTilePyramidOfflineRegion_Private <MGLOfflineRegion> - -/** - Initializes and returns an offline region backed by the given C++ region - definition object. - - @param definition A reference to an offline region definition backing the - offline region. - */ -- (instancetype)initWithOfflineRegionDefinition:(const mbgl::OfflineTilePyramidRegionDefinition &)definition; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLTileSource.h b/platform/darwin/src/MGLTileSource.h deleted file mode 100644 index f22babc8ca..0000000000 --- a/platform/darwin/src/MGLTileSource.h +++ /dev/null @@ -1,206 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLSource.h" -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -@class MGLAttributionInfo; - -/** - Options for `MGLTileSource` objects. - */ -typedef NSString *MGLTileSourceOption NS_STRING_ENUM; - -/** - An `NSNumber` object containing an unsigned integer that specifies the minimum - zoom level at which to display tiles from the source. - - The value should be between 0 and 22, inclusive, and less than - `MGLTileSourceOptionMaximumZoomLevel`, if specified. The default value for this - option is 0. - - This option corresponds to the `minzoom` key in the - <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">TileJSON</a> - specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionMinimumZoomLevel; - -/** - An `NSNumber` object containing an unsigned integer that specifies the maximum - zoom level at which to display tiles from the source. - - The value should be between 0 and 22, inclusive, and less than - `MGLTileSourceOptionMinimumZoomLevel`, if specified. The default value for this - option is 22. - - This option corresponds to the `maxzoom` key in the - <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">TileJSON</a> - specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionMaximumZoomLevel; - -/** - An `NSValue` object containing an `MGLCoordinateBounds` struct that specifies - the geographic extent of the source. - - If this option is specified, the SDK avoids requesting any tile that falls - outside of the coordinate bounds. Otherwise, the SDK requests any tile needed - to cover the viewport, as it does by default. - - This option corresponds to the `bounds` key in the - <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">TileJSON</a> - specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionCoordinateBounds; - -#if TARGET_OS_IPHONE -/** - An HTML string defining the buttons to be displayed in an action sheet when the - source is part of a map view’s style and the map view’s attribution button is - pressed. - - By default, no attribution statements are displayed. If the - `MGLTileSourceOptionAttributionInfos` option is specified, this option is - ignored. - - This option corresponds to the `attribution` key in the - <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">TileJSON</a> - specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionAttributionHTMLString; - -/** - An array of `MGLAttributionInfo` objects defining the buttons to be displayed - in an action sheet when the source is part of a map view’s style and the map - view’s attribution button is pressed. - - By default, no attribution statements are displayed. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionAttributionInfos; -#else -/** - An HTML string defining the buttons to be displayed in the map view’s - attribution view when the source is part of the map view’s style. - - By default, no attribution statements are displayed. If the - `MGLTileSourceOptionAttributionInfos` option is specified, this option is - ignored. - - This option corresponds to the `attribution` key in the - <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">TileJSON</a> - specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionAttributionHTMLString; - -/** - An array of `MGLAttributionInfo` objects defining the buttons to be displayed - in the map view’s attribution view when the source is part of the map view’s - style. - - By default, no attribution statements are displayed. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionAttributionInfos; -#endif - -/** - An `NSNumber` object containing an unsigned integer that specifies the tile - coordinate system for the source’s tile URLs. The integer corresponds to one of - the constants described in `MGLTileCoordinateSystem`. - - The default value for this option is `MGLTileCoordinateSystemXYZ`. - - This option corresponds to the `scheme` key in the - <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">TileJSON</a> - specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLTileSourceOption MGLTileSourceOptionTileCoordinateSystem; - -/** - Tile coordinate systems that determine how tile coordinates in tile URLs are - interpreted. - */ -typedef NS_ENUM(NSUInteger, MGLTileCoordinateSystem) { - /** - The origin is at the top-left (northwest), and `y` values increase - southwards. - - This tile coordinate system is used by Mapbox and OpenStreetMap tile - servers. - */ - MGLTileCoordinateSystemXYZ = 0, - - /** - The origin is at the bottom-left (southwest), and `y` values increase - northwards. - - This tile coordinate system is used by tile servers that conform to the - <a href="http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification">Tile Map Service Specification</a>. - */ - MGLTileCoordinateSystemTMS -}; - -/** - The encoding formula used to generate the raster-dem tileset -*/ - -typedef NS_ENUM(NSUInteger, MGLDEMEncoding) { - - /** - Raster tiles generated with the [Mapbox encoding formula](https://docs.mapbox.com/help/troubleshooting/access-elevation-data/#mapbox-terrain-rgb). - */ - MGLDEMEncodingMapbox = 0, - - /** - Raster tiles generated with the [Mapzen Terrarium encoding formula](https://aws.amazon.com/public-datasets/terrain/). - */ - MGLDEMEncodingTerrarium -}; - -/** - `MGLTileSource` is a map content source that supplies map tiles to be shown on - the map. The location of and metadata about the tiles are defined either by an - option dictionary or by an external file that conforms to the - <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>. - A tile source is added to an `MGLStyle` object along with one or more - `MGLRasterStyleLayer` or `MGLVectorStyleLayer` objects. Use a style layer to - control the appearance of content supplied by the tile source. - - A tile source is also known as a tile set. To learn about the structure of a - Mapbox-hosted tile set, view it in - <a href="https://www.mapbox.com/studio/tilesets/">Mapbox Studio’s Tilesets editor</a>. - - Create instances of `MGLRasterTileSource` and `MGLVectorTileSource` in order - to use `MGLTileSource`'s properties and methods. Do not create instances of - `MGLTileSource` directly, and do not create your own subclasses of this class. - */ -MGL_EXPORT -@interface MGLTileSource : MGLSource - -#pragma mark Accessing a Source’s Content - -/** - The URL to the TileJSON configuration file that specifies the contents of the - source. - - If the receiver was initialized using - `-initWithIdentifier:tileURLTemplates:options`, this property is set to `nil`. - */ -@property (nonatomic, copy, nullable, readonly) NSURL *configurationURL; - -#pragma mark Accessing Attribution Strings - -/** - An array of `MGLAttributionInfo` objects that define the attribution - statements to be displayed when the map is shown to the user. - - By default, this array is empty. If the source is initialized with a - configuration URL, this array is also empty until the configuration JSON file - is loaded. - */ -@property (nonatomic, copy, readonly) NSArray<MGLAttributionInfo *> *attributionInfos; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLTileSource.mm b/platform/darwin/src/MGLTileSource.mm deleted file mode 100644 index eef3b33430..0000000000 --- a/platform/darwin/src/MGLTileSource.mm +++ /dev/null @@ -1,152 +0,0 @@ -#import "MGLTileSource_Private.h" - -#import "MGLAttributionInfo_Private.h" -#import "MGLGeometry_Private.h" -#import "MGLRasterDEMSource.h" -#import "NSString+MGLAdditions.h" -#import "NSValue+MGLAdditions.h" - -#if TARGET_OS_IPHONE - #import <UIKit/UIKit.h> -#else - #import <Cocoa/Cocoa.h> -#endif - -#include <mbgl/util/tileset.hpp> - -const MGLTileSourceOption MGLTileSourceOptionMinimumZoomLevel = @"MGLTileSourceOptionMinimumZoomLevel"; -const MGLTileSourceOption MGLTileSourceOptionMaximumZoomLevel = @"MGLTileSourceOptionMaximumZoomLevel"; -const MGLTileSourceOption MGLTileSourceOptionCoordinateBounds = @"MGLTileSourceOptionCoordinateBounds"; -const MGLTileSourceOption MGLTileSourceOptionAttributionHTMLString = @"MGLTileSourceOptionAttributionHTMLString"; -const MGLTileSourceOption MGLTileSourceOptionAttributionInfos = @"MGLTileSourceOptionAttributionInfos"; -const MGLTileSourceOption MGLTileSourceOptionTileCoordinateSystem = @"MGLTileSourceOptionTileCoordinateSystem"; -const MGLTileSourceOption MGLTileSourceOptionDEMEncoding = @"MGLTileSourceOptionDEMEncoding"; - -@implementation MGLTileSource - -- (NSURL *)configurationURL { - [NSException raise:MGLAbstractClassException - format:@"MGLTileSource is an abstract class"]; - return nil; -} - -- (NSArray<MGLAttributionInfo *> *)attributionInfos { - return [self attributionInfosWithFontSize:0 linkColor:nil]; -} - -- (NSArray<MGLAttributionInfo *> *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { - return [MGLAttributionInfo attributionInfosFromHTMLString:self.attributionHTMLString - fontSize:fontSize - linkColor:linkColor]; -} - -- (NSString *)attributionHTMLString { - [NSException raise:MGLAbstractClassException - format:@"MGLTileSource is an abstract class"]; - return nil; -} - -@end - -mbgl::Tileset MGLTileSetFromTileURLTemplates(NSArray<NSString *> *tileURLTemplates, NSDictionary<MGLTileSourceOption, id> * _Nullable options) { - mbgl::Tileset tileSet; - - for (NSString *tileURLTemplate in tileURLTemplates) { - tileSet.tiles.push_back(tileURLTemplate.UTF8String); - } - - // set the minimum / maximum zoom range to the values specified by this class if they - // were set. otherwise, use the core objects default values - if (NSNumber *minimumZoomLevel = options[MGLTileSourceOptionMinimumZoomLevel]) { - if (![minimumZoomLevel isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionMinimumZoomLevel must be set to an NSNumber."]; - } - tileSet.zoomRange.min = minimumZoomLevel.integerValue; - } - if (NSNumber *maximumZoomLevel = options[MGLTileSourceOptionMaximumZoomLevel]) { - if (![maximumZoomLevel isKindOfClass:[NSNumber class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionMinimumZoomLevel must be set to an NSNumber."]; - } - tileSet.zoomRange.max = maximumZoomLevel.integerValue; - } - if (tileSet.zoomRange.min > tileSet.zoomRange.max) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionMinimumZoomLevel must be less than MGLTileSourceOptionMaximumZoomLevel."]; - } - - if (NSValue *coordinateBounds = options[MGLTileSourceOptionCoordinateBounds]) { - if (![coordinateBounds isKindOfClass:[NSValue class]] - && strcmp(coordinateBounds.objCType, @encode(MGLCoordinateBounds)) == 0) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionCoordinateBounds must be set to an NSValue containing an MGLCoordinateBounds."]; - } - tileSet.bounds = MGLLatLngBoundsFromCoordinateBounds(coordinateBounds.MGLCoordinateBoundsValue); - } - - if (NSString *attribution = options[MGLTileSourceOptionAttributionHTMLString]) { - if (![attribution isKindOfClass:[NSString class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionAttributionHTMLString must be set to a string."]; - } - tileSet.attribution = attribution.UTF8String; - } - - if (NSArray *attributionInfos = options[MGLTileSourceOptionAttributionInfos]) { - if (![attributionInfos isKindOfClass:[NSArray class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionAttributionInfos must be set to a string."]; - } - - NSAttributedString *attributedString = [MGLAttributionInfo attributedStringForAttributionInfos:attributionInfos]; -#if TARGET_OS_IPHONE - static NSString * const NSExcludedElementsDocumentAttribute = @"ExcludedElements"; -#endif - NSDictionary *documentAttributes = @{ - NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, - NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding), - // The attribution string is meant to be a simple, inline fragment, not a full-fledged, validating document. - NSExcludedElementsDocumentAttribute: @[@"XML", @"DOCTYPE", @"html", @"head", @"meta", @"title", @"style", @"body", @"p"], - }; - NSData *data = [attributedString dataFromRange:attributedString.mgl_wholeRange documentAttributes:documentAttributes error:NULL]; - NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - tileSet.attribution = html.UTF8String; - } - - if (NSNumber *tileCoordinateSystemNumber = options[MGLTileSourceOptionTileCoordinateSystem]) { - if (![tileCoordinateSystemNumber isKindOfClass:[NSValue class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionTileCoordinateSystem must be set to an NSValue or NSNumber."]; - } - MGLTileCoordinateSystem tileCoordinateSystem; - [tileCoordinateSystemNumber getValue:&tileCoordinateSystem]; - switch (tileCoordinateSystem) { - case MGLTileCoordinateSystemXYZ: - tileSet.scheme = mbgl::Tileset::Scheme::XYZ; - break; - case MGLTileCoordinateSystemTMS: - tileSet.scheme = mbgl::Tileset::Scheme::TMS; - break; - } - } - - if (NSNumber *demEncodingNumber = options[MGLTileSourceOptionDEMEncoding]) { - if (![demEncodingNumber isKindOfClass:[NSValue class]]) { - [NSException raise:NSInvalidArgumentException - format:@"MGLTileSourceOptionDEMEncoding must be set to an NSValue or NSNumber."]; - } - MGLDEMEncoding demEncoding; - [demEncodingNumber getValue:&demEncoding]; - switch (demEncoding) { - case MGLDEMEncodingMapbox: - tileSet.encoding = mbgl::Tileset::DEMEncoding::Mapbox; - break; - case MGLDEMEncodingTerrarium: - tileSet.encoding = mbgl::Tileset::DEMEncoding::Terrarium; - break; - } - } - - return tileSet; -} diff --git a/platform/darwin/src/MGLTileSource_Private.h b/platform/darwin/src/MGLTileSource_Private.h deleted file mode 100644 index 1b260ca86a..0000000000 --- a/platform/darwin/src/MGLTileSource_Private.h +++ /dev/null @@ -1,38 +0,0 @@ -#import <CoreGraphics/CoreGraphics.h> - -#import "MGLFoundation.h" -#import "MGLTileSource.h" - -NS_ASSUME_NONNULL_BEGIN - -namespace mbgl { - class Tileset; -} - -@class MGLAttributionInfo; - -@interface MGLTileSource (Private) - -/** - An HTML string to be displayed as attribution when the map is shown to a user. - - The default value is `nil`. If the source is initialized with a configuration - URL, this property is also `nil` until the configuration JSON file is loaded. - */ -@property (nonatomic, copy, nullable, readonly) NSString *attributionHTMLString; - -/** - A structured representation of the `attribution` property. The default value is - `nil`. - - @param fontSize The default text size in points, or 0 to use the default. - @param linkColor The default link color, or `nil` to use the default. - */ -- (NSArray<MGLAttributionInfo *> *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; - -@end - -MGL_EXPORT -mbgl::Tileset MGLTileSetFromTileURLTemplates(NSArray<NSString *> *tileURLTemplates, NSDictionary<MGLTileSourceOption, id> * _Nullable options); - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h deleted file mode 100644 index 963eda384b..0000000000 --- a/platform/darwin/src/MGLTypes.h +++ /dev/null @@ -1,140 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreGraphics/CoreGraphics.h> - -#import "MGLFoundation.h" - -#pragma once - -#if TARGET_OS_IPHONE -@class UIImage; -#define MGLImage UIImage -#else -@class NSImage; -#define MGLImage NSImage -#endif - -#if TARGET_OS_IPHONE -@class UIColor; -#define MGLColor UIColor -#else -@class NSColor; -#define MGLColor NSColor -#endif - -NS_ASSUME_NONNULL_BEGIN - -typedef NSString *MGLExceptionName NS_TYPED_EXTENSIBLE_ENUM; - -/** - :nodoc: Generic exceptions used across multiple disparate classes. Exceptions - that are unique to a class or class-cluster should be defined in those headers. - */ -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLAbstractClassException; - -/** Indicates an error occurred in the Mapbox SDK. */ -FOUNDATION_EXTERN MGL_EXPORT NSErrorDomain const MGLErrorDomain; - -/** Error constants for the Mapbox SDK. */ -typedef NS_ENUM(NSInteger, MGLErrorCode) { - /** An unknown error occurred. */ - MGLErrorCodeUnknown = -1, - /** The resource could not be found. */ - MGLErrorCodeNotFound = 1, - /** The connection received an invalid server response. */ - MGLErrorCodeBadServerResponse = 2, - /** An attempt to establish a connection failed. */ - MGLErrorCodeConnectionFailed = 3, - /** A style parse error occurred while attempting to load the map. */ - MGLErrorCodeParseStyleFailed = 4, - /** An attempt to load the style failed. */ - MGLErrorCodeLoadStyleFailed = 5, - /** An error occurred while snapshotting the map. */ - MGLErrorCodeSnapshotFailed = 6, - /** Source is in use and cannot be removed */ - MGLErrorCodeSourceIsInUseCannotRemove = 7, - /** Source is in use and cannot be removed */ - MGLErrorCodeSourceIdentifierMismatch = 8, - /** An error occurred while modifying the offline storage database */ - MGLErrorCodeModifyingOfflineStorageFailed = 9, - /** Source is invalid and cannot be removed from the style (e.g. after a style change) */ - MGLErrorCodeSourceCannotBeRemovedFromStyle = 10, - /** An error occurred while rendering */ - MGLErrorCodeRenderingError = 11, -}; - -/** Options for enabling debugging features in an `MGLMapView` instance. */ -typedef NS_OPTIONS(NSUInteger, MGLMapDebugMaskOptions) { - /** Edges of tile boundaries are shown as thick, red lines to help diagnose - tile clipping issues. */ - MGLMapDebugTileBoundariesMask = 1 << 1, - /** Each tile shows its tile coordinate (x/y/z) in the upper-left corner. */ - MGLMapDebugTileInfoMask = 1 << 2, - /** Each tile shows a timestamp indicating when it was loaded. */ - MGLMapDebugTimestampsMask = 1 << 3, - /** Edges of glyphs and symbols are shown as faint, green lines to help - diagnose collision and label placement issues. */ - MGLMapDebugCollisionBoxesMask = 1 << 4, - /** Each drawing operation is replaced by a translucent fill. Overlapping - drawing operations appear more prominent to help diagnose overdrawing. - @note This option does nothing in Release builds of the SDK. */ - MGLMapDebugOverdrawVisualizationMask = 1 << 5, -#if !TARGET_OS_IPHONE - /** The stencil buffer is shown instead of the color buffer. - @note This option does nothing in Release builds of the SDK. */ - MGLMapDebugStencilBufferMask = 1 << 6, - /** The depth buffer is shown instead of the color buffer. - @note This option does nothing in Release builds of the SDK. */ - MGLMapDebugDepthBufferMask = 1 << 7, -#endif -}; - -/** - A structure containing information about a transition. - */ -typedef struct __attribute__((objc_boxable)) MGLTransition { - /** - The amount of time the animation should take, not including the delay. - */ - NSTimeInterval duration; - - /** - The amount of time in seconds to wait before beginning the animation. - */ - NSTimeInterval delay; -} MGLTransition; - -NS_INLINE NSString *MGLStringFromMGLTransition(MGLTransition transition) { - return [NSString stringWithFormat:@"transition { duration: %f, delay: %f }", transition.duration, transition.delay]; -} - -/** - Creates a new `MGLTransition` from the given duration and delay. - - @param duration The amount of time the animation should take, not including - the delay. - @param delay The amount of time in seconds to wait before beginning the - animation. - - @return Returns a `MGLTransition` struct containing the transition attributes. - */ -NS_INLINE MGLTransition MGLTransitionMake(NSTimeInterval duration, NSTimeInterval delay) { - MGLTransition transition; - transition.duration = duration; - transition.delay = delay; - - return transition; -} - -/** - Constants indicating the visibility of different map ornaments. - */ -typedef NS_ENUM(NSInteger, MGLOrnamentVisibility) { - /** A constant indicating that the ornament adapts to the current map state. */ - MGLOrnamentVisibilityAdaptive, - /** A constant indicating that the ornament is always hidden. */ - MGLOrnamentVisibilityHidden, - /** A constant indicating that the ornament is always visible. */ - MGLOrnamentVisibilityVisible -}; - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLTypes.m b/platform/darwin/src/MGLTypes.m deleted file mode 100644 index 89f88a9c1d..0000000000 --- a/platform/darwin/src/MGLTypes.m +++ /dev/null @@ -1,5 +0,0 @@ -#import "MGLTypes.h" - -const MGLExceptionName MGLAbstractClassException = @"MGLAbstractClassException"; - -NSString * const MGLErrorDomain = @"MGLErrorDomain"; diff --git a/platform/darwin/src/MGLValueEvaluator.h b/platform/darwin/src/MGLValueEvaluator.h deleted file mode 100644 index 2779deba90..0000000000 --- a/platform/darwin/src/MGLValueEvaluator.h +++ /dev/null @@ -1,49 +0,0 @@ -#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/MGLVectorStyleLayer.h b/platform/darwin/src/MGLVectorStyleLayer.h deleted file mode 100644 index d9431215a1..0000000000 --- a/platform/darwin/src/MGLVectorStyleLayer.h +++ /dev/null @@ -1,58 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#import "MGLForegroundStyleLayer.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - `MGLVectorStyleLayer` is an abstract superclass for style layers whose content - is defined by an `MGLShapeSource` or `MGLVectorTileSource` object. - - Create instances of `MGLCircleStyleLayer`, `MGLFillStyleLayer`, - `MGLFillExtrusionStyleLayer`, `MGLHeatmapStyleLayer`, `MGLLineStyleLayer`, and - `MGLSymbolStyleLayer` in order to use `MGLVectorStyleLayer`'s properties and - methods. Do not create instances of `MGLVectorStyleLayer` directly, and do not - create your own subclasses of this class. - */ -MGL_EXPORT -@interface MGLVectorStyleLayer : MGLForegroundStyleLayer - -#pragma mark Refining a Style Layer’s Content - -/** - Identifier of the layer within the source identified by the `sourceIdentifier` - property from which the receiver obtains the data to style. - */ -@property (nonatomic, nullable) NSString *sourceLayerIdentifier; - -/** - The style layer’s predicate. - - Use the style layer’s predicate to include only the features in the source - layer that satisfy a condition that you define. If the style layer initially - comes from the style, its predicate corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layer-filter">`filter`</a> - property in the style JSON. - - See the “<a href="../predicates-and-expressions.html">Predicates and Expressions</a>” - guide for details about the predicate syntax supported by this class. - - ### Example - - To filter the layer to include only the features whose `index` attribute is 5 - or 10 and whose `ele` attribute is at least 1,500, you could create an - `NSCompoundPredicate` along these lines: - - ```swift - let layer = MGLLineStyleLayer(identifier: "contour", source: terrain) - layer.sourceLayerIdentifier = "contours" - layer.predicate = NSPredicate(format: "(index == 5 || index == 10) && CAST(ele, 'NSNumber') >= 1500.0") - mapView.style?.addLayer(layer) - ``` - */ -@property (nonatomic, nullable) NSPredicate *predicate; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLVectorStyleLayer.mm b/platform/darwin/src/MGLVectorStyleLayer.mm deleted file mode 100644 index 691668629a..0000000000 --- a/platform/darwin/src/MGLVectorStyleLayer.mm +++ /dev/null @@ -1,34 +0,0 @@ -#import "MGLVectorStyleLayer.h" -#import "MGLStyleLayer_Private.h" - -@implementation MGLVectorStyleLayer - -- (void)setPredicate:(NSPredicate *)predicate { - [NSException raise:MGLAbstractClassException - format:@"MGLVectorStyleLayer is an abstract class"]; -} - -- (NSPredicate *)predicate { - [NSException raise:MGLAbstractClassException - format:@"MGLVectorStyleLayer is an abstract class"]; - return nil; -} - -- (NSString *)description { - if (self.rawLayer) { - return [NSString stringWithFormat: - @"<%@: %p; identifier = %@; sourceIdentifier = %@; " - @"sourceLayerIdentifier = %@; predicate = %@; visible = %@>", - NSStringFromClass([self class]), (void *)self, self.identifier, - self.sourceIdentifier, self.sourceLayerIdentifier, self.predicate, - self.visible ? @"YES" : @"NO"]; - } - else { - return [NSString stringWithFormat: - @"<%@: %p; identifier = %@; sourceIdentifier = <unknown>; " - @"sourceLayerIdentifier = <unknown>; predicate = <unknown>; visible = <unknown>>", - NSStringFromClass([self class]), (void *)self, self.identifier]; - } -} - -@end diff --git a/platform/darwin/src/MGLVectorTileSource.h b/platform/darwin/src/MGLVectorTileSource.h deleted file mode 100644 index f198d7ad2c..0000000000 --- a/platform/darwin/src/MGLVectorTileSource.h +++ /dev/null @@ -1,150 +0,0 @@ -#import "MGLFeature.h" -#import "MGLFoundation.h" -#import "MGLTileSource.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - `MGLVectorTileSource` is a map content source that supplies tiled vector data - in <a href="https://www.mapbox.com/vector-tiles/">Mapbox Vector Tile</a> format - to be shown on the map. The location of and metadata about the tiles are - defined either by an option dictionary or by an external file that conforms to - the - <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>. - A vector tile source is added to an `MGLStyle` object along with one or more - `MGLVectorStyleLayer` objects. A vector style layer defines the appearance of - any content supplied by the vector tile source. - - `MGLVectorTileSource` is optimized for data sets that are too large to fit - completely in memory, such as vector tile sets or data sets managed in - <a href="https://www.mapbox.com/studio/">Mapbox Studio</a>. For - <a href="http://geojson.org/">GeoJSON</a> data, use the `MGLShapeSource` - class. For tiled data that changes dynamically, the `MGLComputedShapeSource` - class may be a suitable alternative. - - Each - <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-vector"><code>vector</code></a> - source defined by the style JSON file is represented at runtime by an - `MGLVectorTileSource` object that you can use to initialize new style layers. - You can also add and remove sources dynamically using methods such as - `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`. - - Within each vector tile, each geometric coordinate must lie between - −1 × <var>extent</var> and - (<var>extent</var> × 2) − 1, inclusive. Any vector style - layer initialized with a vector tile source must have a non-`nil` value in its - `sourceLayerIdentifier` property. - - Commonly used vector tile sources include - <a href="https://www.mapbox.com/vector-tiles/mapbox-streets/">Mapbox Streets</a>, - <a href="https://www.mapbox.com/vector-tiles/mapbox-terrain/">Mapbox Terrain</a>, - and - <a href="https://www.mapbox.com/vector-tiles/mapbox-traffic-v1/">Mapbox Traffic</a>. - - ### Example - - ```swift - let source = MGLVectorTileSource(identifier: "pois", tileURLTemplates: ["https://example.com/vector-tiles/{z}/{x}/{y}.mvt"], options: [ - .minimumZoomLevel: 9, - .maximumZoomLevel: 16, - .attributionInfos: [ - MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "https://mapbox.com")) - ] - ]) - mapView.style?.addSource(source) - ``` - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/dds-circle-layer/"> - Data-driven circles</a> example to learn how to add data to your map using - an `MGLVectorTileSource` object. - */ -MGL_EXPORT -@interface MGLVectorTileSource : MGLTileSource - -#pragma mark Initializing a Source - -/** - Returns a vector tile source initialized with an identifier and configuration - URL. - - After initializing and configuring the source, add it to a map view’s style - using the `-[MGLStyle addSource:]` method. - - The URL may be a full HTTP or HTTPS URL or, for tilesets hosted by Mapbox, a - Mapbox URL indicating a tileset ID (`mapbox://<tilesetid>`). The URL should - point to a JSON file that conforms to the - <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param configurationURL A URL to a TileJSON configuration file describing the - source’s contents and other metadata. - @return An initialized vector tile source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL NS_DESIGNATED_INITIALIZER; - -/** - Returns a vector tile source initialized an identifier, tile URL templates, and - options. - - Tile URL templates are strings that specify the URLs of the vector tiles to - load. See the “<a href="../tile-url-templates.html">Tile URL Templates</a>” - guide for information about the format of a tile URL template. - - After initializing and configuring the source, add it to a map view’s style - using the `-[MGLStyle addSource:]` method. - - @param identifier A string that uniquely identifies the source in the style to - which it is added. - @param tileURLTemplates An array of tile URL template strings. Only the first - string is used; any additional strings are ignored. - @param options A dictionary containing configuration options. See - `MGLTileSourceOption` for available keys and values. Pass in `nil` to use - the default values. - @return An initialized tile source. - */ -- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray<NSString *> *)tileURLTemplates options:(nullable NSDictionary<MGLTileSourceOption, id> *)options NS_DESIGNATED_INITIALIZER; - -#pragma mark Accessing a Source’s Content - -/** - Returns an array of map features loaded by this source, restricted to the given - source layers and filtered by the given predicate. - - Each object in the returned array represents a feature loaded by the source and - provides access to attributes specified as part of the loaded feature. The - source loads a feature if the source is added to an `MGLMapView`’s style; that - style has a layer that uses the source; and the map view has recently scrolled - to the region containing the feature. - - Features come from tiled vector data that is converted to tiles internally, so - feature geometries are clipped at tile boundaries and features may appear - duplicated across tiles. For example, suppose part of a lengthy polyline - representing a road has recently scrolled into view. The resulting array - includes those parts of the road that lie within the map tiles that the source - has loaded, even if the road extends into other tiles. The portion of the road - within each map tile is included individually. - - Returned features may not necessarily be visible to the user at the time they - are loaded: the style may contain a layer that forces the source’s tiles to - load but filters out the features in question, preventing them from being - drawn. To obtain only _visible_ features, use the - `-[MGLMapView visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:predicate:]` - or - `-[MGLMapView visibleFeaturesInRect:inStyleLayersWithIdentifiers:predicate:]` - method. - - @param sourceLayerIdentifiers The source layers to include in the query. Only - the features contained in these source layers are included in the returned - array. This array may not be empty. - @param predicate A predicate to filter the returned features. Use `nil` to - include all loaded features. - @return An array of objects conforming to the `MGLFeature` protocol that - represent features loaded by the source that match the predicate. - */ -- (NSArray<id <MGLFeature>> *)featuresInSourceLayersWithIdentifiers:(NSSet<NSString *> *)sourceLayerIdentifiers predicate:(nullable NSPredicate *)predicate NS_SWIFT_NAME(features(sourceLayerIdentifiers:predicate:)); - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLVectorTileSource.mm b/platform/darwin/src/MGLVectorTileSource.mm deleted file mode 100644 index 9ab11e2e56..0000000000 --- a/platform/darwin/src/MGLVectorTileSource.mm +++ /dev/null @@ -1,154 +0,0 @@ -#import "MGLVectorTileSource_Private.h" - -#import "MGLFeature_Private.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLSource_Private.h" -#import "MGLTileSource_Private.h" -#import "MGLStyle_Private.h" -#import "MGLMapView_Private.h" - -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSURL+MGLAdditions.h" - -#include <mbgl/map/map.hpp> -#include <mbgl/style/sources/vector_source.hpp> -#include <mbgl/renderer/renderer.hpp> - -@interface MGLVectorTileSource () - -@property (nonatomic, readonly) mbgl::style::VectorSource *rawSource; - -@end - -@implementation MGLVectorTileSource - -- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL { - auto source = std::make_unique<mbgl::style::VectorSource>(identifier.UTF8String, - configurationURL.mgl_URLByStandardizingScheme.absoluteString.UTF8String); - return self = [super initWithPendingSource:std::move(source)]; -} - -- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NSArray<NSString *> *)tileURLTemplates options:(nullable NSDictionary<MGLTileSourceOption, id> *)options { - mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options); - auto source = std::make_unique<mbgl::style::VectorSource>(identifier.UTF8String, tileSet); - return self = [super initWithPendingSource:std::move(source)]; -} - -- (mbgl::style::VectorSource *)rawSource { - return (mbgl::style::VectorSource *)super.rawSource; -} - -- (NSURL *)configurationURL { - MGLAssertStyleSourceIsValid(); - auto url = self.rawSource->getURL(); - return url ? [NSURL URLWithString:@(url->c_str())] : nil; -} - -- (NSString *)attributionHTMLString { - if (!self.rawSource) { - MGLAssert(0, @"Source with identifier `%@` was invalidated after a style change", self.identifier); - return nil; - } - - auto attribution = self.rawSource->getAttribution(); - return attribution ? @(attribution->c_str()) : nil; -} - -- (NSArray<id <MGLFeature>> *)featuresInSourceLayersWithIdentifiers:(NSSet<NSString *> *)sourceLayerIdentifiers predicate:(nullable NSPredicate *)predicate { - MGLAssertStyleSourceIsValid(); - mbgl::optional<std::vector<std::string>> optionalSourceLayerIDs; - if (sourceLayerIdentifiers) { - __block std::vector<std::string> layerIDs; - layerIDs.reserve(sourceLayerIdentifiers.count); - [sourceLayerIdentifiers enumerateObjectsUsingBlock:^(NSString * _Nonnull identifier, BOOL * _Nonnull stop) { - layerIDs.push_back(identifier.UTF8String); - }]; - optionalSourceLayerIDs = layerIDs; - } - - mbgl::optional<mbgl::style::Filter> optionalFilter; - if (predicate) { - optionalFilter = predicate.mgl_filter; - } - - std::vector<mbgl::Feature> features; - if (self.mapView) { - features = self.mapView.renderer->querySourceFeatures(self.rawSource->getID(), { optionalSourceLayerIDs, optionalFilter }); - } - return MGLFeaturesFromMBGLFeatures(features); -} - -@end - -@implementation MGLVectorTileSource (Private) - -/** - An array of locale codes with dedicated name fields in the Mapbox Streets - source. - - https://www.mapbox.com/vector-tiles/mapbox-streets-v8/ - */ -static NSArray * const MGLMapboxStreetsLanguages = @[ - @"ar", @"de", @"en", @"es", @"fr", @"ja", @"ko", @"pt", @"ru", @"zh", - @"zh-Hans", -]; - -/** - Like `MGLMapboxStreetsLanguages`, but deanglicized for use with - `+[NSBundle preferredLocalizationsFromArray:forPreferences:]`. - */ -static NSArray * const MGLMapboxStreetsAlternativeLanguages = @[ - @"mul", @"ar", @"de", @"es", @"fr", @"ja", @"ko", @"pt", @"ru", @"zh", - @"zh-Hans", -]; - -+ (NSSet<NSString *> *)mapboxStreetsLanguages { - static dispatch_once_t onceToken; - static NSSet<NSString *> *mapboxStreetsLanguages; - dispatch_once(&onceToken, ^{ - mapboxStreetsLanguages = [NSSet setWithArray:MGLMapboxStreetsLanguages]; - }); - return mapboxStreetsLanguages; -} - -+ (NSString *)preferredMapboxStreetsLanguage { - return [self preferredMapboxStreetsLanguageForPreferences:[NSLocale preferredLanguages]]; -} - -+ (NSString *)preferredMapboxStreetsLanguageForPreferences:(NSArray<NSString *> *)preferencesArray { - BOOL acceptsEnglish = [preferencesArray filteredArrayUsingPredicate: - [NSPredicate predicateWithBlock:^BOOL(NSString * _Nullable language, NSDictionary<NSString *,id> * _Nullable bindings) { - NSString *languageCode; - - if (@available(iOS 10.0, macOS 10.12.0, *)) { - languageCode = [NSLocale localeWithLocaleIdentifier:language].languageCode; - } - else { - languageCode = [[NSLocale localeWithLocaleIdentifier:language] objectForKey:NSLocaleLanguageCode]; - } - - return [languageCode isEqualToString:@"en"]; - }]].count; - - NSArray<NSString *> *availableLanguages = acceptsEnglish ? MGLMapboxStreetsLanguages : MGLMapboxStreetsAlternativeLanguages; - NSArray<NSString *> *preferredLanguages = [NSBundle preferredLocalizationsFromArray:availableLanguages - forPreferences:preferencesArray]; - NSString *mostSpecificLanguage; - for (NSString *language in preferredLanguages) { - if (language.length > mostSpecificLanguage.length) { - mostSpecificLanguage = language; - } - } - return [mostSpecificLanguage isEqualToString:@"mul"] ? nil : mostSpecificLanguage; -} - -- (BOOL)isMapboxStreets { - NSURL *url = self.configurationURL; - if (![url.scheme isEqualToString:@"mapbox"]) { - return NO; - } - NSArray *identifiers = [url.host componentsSeparatedByString:@","]; - return [identifiers containsObject:@"mapbox.mapbox-streets-v8"] || [identifiers containsObject:@"mapbox.mapbox-streets-v7"]; -} - -@end diff --git a/platform/darwin/src/MGLVectorTileSource_Private.h b/platform/darwin/src/MGLVectorTileSource_Private.h deleted file mode 100644 index 8d287ae4c4..0000000000 --- a/platform/darwin/src/MGLVectorTileSource_Private.h +++ /dev/null @@ -1,16 +0,0 @@ -#import "MGLVectorTileSource.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLVectorTileSource (Private) - -@property (nonatomic, readonly, getter=isMapboxStreets) BOOL mapboxStreets; - -+ (NSSet<NSString *> *)mapboxStreetsLanguages; - -+ (nullable NSString *)preferredMapboxStreetsLanguage; -+ (nullable NSString *)preferredMapboxStreetsLanguageForPreferences:(NSArray<NSString *> *)preferencesArray; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSArray+MGLAdditions.h b/platform/darwin/src/NSArray+MGLAdditions.h deleted file mode 100644 index c4dfd8207b..0000000000 --- a/platform/darwin/src/NSArray+MGLAdditions.h +++ /dev/null @@ -1,27 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import <mbgl/util/feature.hpp> - -@interface NSArray (MGLAdditions) - -- (std::vector<mbgl::Value>)mgl_vector; - -/** Returns a string resulting from inserting a separator between each attributed string in the array */ -- (NSAttributedString *)mgl_attributedComponentsJoinedByString:(NSString *)separator; - -/** - Converts std::vector<CLLocationCoordinate> into an NSArray containing dictionary - representations of coordinates with the following structure: - [{"latitude": lat, "longitude": lng}] - */ -+ (NSArray *)mgl_coordinatesFromCoordinates:(std::vector<CLLocationCoordinate2D>)coords; - -/** - Converts the receiver into a std::vector<CLLocationCoordinate>. - Receiver must conform to the following structure: - [{"latitude": lat, "longitude": lng}] - */ -- (std::vector<CLLocationCoordinate2D>)mgl_coordinates; - -@end diff --git a/platform/darwin/src/NSArray+MGLAdditions.mm b/platform/darwin/src/NSArray+MGLAdditions.mm deleted file mode 100644 index c5f25c83b6..0000000000 --- a/platform/darwin/src/NSArray+MGLAdditions.mm +++ /dev/null @@ -1,66 +0,0 @@ -#import "NSArray+MGLAdditions.h" - -#import "NSDictionary+MGLAdditions.h" -#import "NSExpression+MGLPrivateAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -@implementation NSArray (MGLAdditions) - -- (std::vector<mbgl::Value>)mgl_vector { - std::vector<mbgl::Value> vector; - vector.reserve(self.count); - for (id value in self) { - if ([value isKindOfClass:[NSArray class]]) { - std::vector<mbgl::Value> innerVector = [value mgl_vector]; - vector.push_back(innerVector); - } else if ([value isKindOfClass:[NSDictionary class]]) { - mbgl::PropertyMap propertyMap = [value mgl_propertyMap]; - vector.push_back(propertyMap); - } else { - NSExpression *expression = [NSExpression expressionForConstantValue:value]; - vector.push_back(expression.mgl_constantMBGLValue); - } - } - return vector; -} - -- (NSAttributedString *)mgl_attributedComponentsJoinedByString:(NSString *)separator { - NSAttributedString *attributedSeparator = [[NSAttributedString alloc] initWithString:separator]; - NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init]; - BOOL isSubsequentItem = NO; - for (NSAttributedString *component in self) { - MGLAssert([component isKindOfClass:[NSAttributedString class]], @"Items in array must be attributed strings."); - if (isSubsequentItem) { - [attributedString appendAttributedString:attributedSeparator]; - } - isSubsequentItem = YES; - [attributedString appendAttributedString:component]; - } - return attributedString; -} - -+ (NSArray *)mgl_coordinatesFromCoordinates:(std::vector<CLLocationCoordinate2D>)coords { - NSMutableArray *coordinates = [NSMutableArray array]; - for (auto coord : coords) { - [coordinates addObject:@{@"latitude": @(coord.latitude), - @"longitude": @(coord.longitude)}]; - } - return coordinates; -} - -- (std::vector<CLLocationCoordinate2D>)mgl_coordinates { - NSUInteger numberOfCoordinates = [self count]; - CLLocationCoordinate2D *coords = (CLLocationCoordinate2D *)malloc(numberOfCoordinates * sizeof(CLLocationCoordinate2D)); - - for (NSUInteger i = 0; i < numberOfCoordinates; i++) { - coords[i] = CLLocationCoordinate2DMake([self[i][@"latitude"] doubleValue], - [self[i][@"longitude"] doubleValue]); - } - - std::vector<CLLocationCoordinate2D> coordinates = { coords, coords + numberOfCoordinates }; - free(coords); - - return coordinates; -} - -@end diff --git a/platform/darwin/src/NSBundle+MGLAdditions.h b/platform/darwin/src/NSBundle+MGLAdditions.h deleted file mode 100644 index dcafefedec..0000000000 --- a/platform/darwin/src/NSBundle+MGLAdditions.h +++ /dev/null @@ -1,45 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -// Strings in the SDK targets must be retrieved from the framework bundle rather -// than the main bundle, which is usually the application bundle. Redefining -// these macros ensures that the framework bundle’s string tables are used at -// runtime yet tools like genstrings and Xcode can still find the localizable -// string identifiers. (genstrings has an -s option that would allow us to -// define our own macros, but Xcode’s Export Localization feature lacks support -// for it.) -// -// As a consequence of this approach, this header must be included in all SDK -// files that include localizable strings. - -#undef NSLocalizedString -#define NSLocalizedString(key, comment) \ - [[NSBundle mgl_frameworkBundle] localizedStringForKey:(key) value:@"" table:nil] - -#undef NSLocalizedStringFromTable -#define NSLocalizedStringFromTable(key, tbl, comment) \ - [[NSBundle mgl_frameworkBundle] localizedStringForKey:(key) value:@"" table:(tbl)] - -#undef NSLocalizedStringWithDefaultValue -#define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment) \ - [[NSBundle mgl_frameworkBundle] localizedStringForKey:(key) value:(val) table:(tbl)] - -FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLBundleNotFoundException; - -@interface NSBundle (MGLAdditions) - -/// Returns the bundle containing the SDK’s classes and Info.plist file. -+ (instancetype)mgl_frameworkBundle; - -+ (nullable NSString *)mgl_frameworkBundleIdentifier; - -+ (nullable NSDictionary<NSString *, id> *)mgl_frameworkInfoDictionary; - -+ (nullable NSString *)mgl_applicationBundleIdentifier; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSBundle+MGLAdditions.m b/platform/darwin/src/NSBundle+MGLAdditions.m deleted file mode 100644 index da70a95373..0000000000 --- a/platform/darwin/src/NSBundle+MGLAdditions.m +++ /dev/null @@ -1,50 +0,0 @@ -#import "NSBundle+MGLAdditions.h" - -#import "MGLAccountManager.h" - -const MGLExceptionName MGLBundleNotFoundException = @"MGLBundleNotFoundException"; - -@implementation NSBundle (MGLAdditions) - -+ (instancetype)mgl_frameworkBundle { - NSBundle *bundle = [self bundleForClass:[MGLAccountManager class]]; - - if (![bundle.infoDictionary[@"CFBundlePackageType"] isEqualToString:@"FMWK"]) { - // For static frameworks, the bundle is the containing application - // bundle but the resources are in Mapbox.bundle. - NSString *bundlePath = [bundle pathForResource:@"Mapbox" ofType:@"bundle"]; - if (bundlePath) { - bundle = [self bundleWithPath:bundlePath]; - } else { - [NSException raise:MGLBundleNotFoundException - format:@"The Mapbox framework bundle could not be found. If using the Mapbox Maps SDK for iOS as a static framework, make sure that Mapbox.bundle is copied into the root of the app bundle."]; - } - } - - return bundle; -} - -+ (nullable NSString *)mgl_frameworkBundleIdentifier { - return self.mgl_frameworkInfoDictionary[@"CFBundleIdentifier"]; -} - -+ (nullable NSDictionary<NSString *, id> *)mgl_frameworkInfoDictionary { - NSBundle *bundle = self.mgl_frameworkBundle; - return bundle.infoDictionary; -} - -+ (nullable NSString *)mgl_applicationBundleIdentifier { - NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier; - -#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && (__IPHONE_OS_VERSION_MAX_ALLOWED < 120200)) || \ - (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && (__MAC_OS_X_VERSION_MAX_ALLOWED < 101404)) - // Before SDK 12.2 (bundled with Xcode 10.2): There’s no main bundle identifier when running in a unit test bundle. - // 12.2 and after: the above bundle identifier is: com.apple.dt.xctest.tool - if (!bundleIdentifier) { - bundleIdentifier = [NSBundle bundleForClass:[MGLAccountManager class]].bundleIdentifier; - } -#endif - return bundleIdentifier; -} - -@end diff --git a/platform/darwin/src/NSCoder+MGLAdditions.h b/platform/darwin/src/NSCoder+MGLAdditions.h deleted file mode 100644 index 036a99c5af..0000000000 --- a/platform/darwin/src/NSCoder+MGLAdditions.h +++ /dev/null @@ -1,16 +0,0 @@ -#import <Foundation/Foundation.h> -#import <CoreLocation/CoreLocation.h> - -#import <mbgl/util/feature.hpp> - -@interface NSCoder (MGLAdditions) - -- (void)encodeMGLCoordinate:(CLLocationCoordinate2D)coordinate forKey:(NSString *)key; - -- (CLLocationCoordinate2D)decodeMGLCoordinateForKey:(NSString *)key; - -- (void)mgl_encodeLocationCoordinates2D:(std::vector<CLLocationCoordinate2D>)coordinates forKey:(NSString *)key; - -- (std::vector<CLLocationCoordinate2D>)mgl_decodeLocationCoordinates2DForKey:(NSString *)key; - -@end diff --git a/platform/darwin/src/NSCoder+MGLAdditions.mm b/platform/darwin/src/NSCoder+MGLAdditions.mm deleted file mode 100644 index 4af6c7588b..0000000000 --- a/platform/darwin/src/NSCoder+MGLAdditions.mm +++ /dev/null @@ -1,26 +0,0 @@ -#import "NSCoder+MGLAdditions.h" - -#import "NSArray+MGLAdditions.h" -#import "NSValue+MGLAdditions.h" - -@implementation NSCoder (MGLAdditions) - -- (void)mgl_encodeLocationCoordinates2D:(std::vector<CLLocationCoordinate2D>)coordinates forKey:(NSString *)key { - [self encodeObject:[NSArray mgl_coordinatesFromCoordinates:coordinates] forKey:key]; -} - -- (std::vector<CLLocationCoordinate2D>)mgl_decodeLocationCoordinates2DForKey:(NSString *)key { - NSArray *coordinates = [self decodeObjectOfClass:[NSArray class] forKey:key]; - return [coordinates mgl_coordinates]; -} - -- (void)encodeMGLCoordinate:(CLLocationCoordinate2D)coordinate forKey:(NSString *)key { - [self encodeObject:@{@"latitude": @(coordinate.latitude), @"longitude": @(coordinate.longitude)} forKey:key]; -} - -- (CLLocationCoordinate2D)decodeMGLCoordinateForKey:(NSString *)key { - NSDictionary *coordinate = [self decodeObjectForKey:key]; - return CLLocationCoordinate2DMake([coordinate[@"latitude"] doubleValue], [coordinate[@"longitude"] doubleValue]); -} - -@end diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.h b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.h deleted file mode 100644 index 2cd4dd1577..0000000000 --- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.h +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100644 index af9216f9ce..0000000000 --- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm +++ /dev/null @@ -1,157 +0,0 @@ -#import "NSComparisonPredicate+MGLAdditions.h" - -#import "MGLStyleValue_Private.h" - -#import "NSPredicate+MGLAdditions.h" -#import "NSExpression+MGLPrivateAdditions.h" - -@implementation NSComparisonPredicate (MGLAdditions) - -- (NSString *)mgl_keyPath { - NSExpression *leftExpression = self.leftExpression; - NSExpression *rightExpression = self.rightExpression; - NSExpressionType leftType = leftExpression.expressionType; - NSExpressionType rightType = rightExpression.expressionType; - if (leftType == NSKeyPathExpressionType && rightType == NSConstantValueExpressionType) { - return leftExpression.keyPath; - } else if (leftType == NSConstantValueExpressionType && rightType == NSKeyPathExpressionType) { - return rightExpression.keyPath; - } - - [NSException raise:NSInvalidArgumentException - format:@"Comparison predicate must compare an attribute (as a key path) to a constant or vice versa."]; - return nil; -} - -- (mbgl::Value)mgl_constantValue { - NSExpression *leftExpression = self.leftExpression; - NSExpression *rightExpression = self.rightExpression; - NSExpressionType leftType = leftExpression.expressionType; - NSExpressionType rightType = rightExpression.expressionType; - mbgl::Value value; - if (leftType == NSKeyPathExpressionType && rightType == NSConstantValueExpressionType) { - value = rightExpression.mgl_constantMBGLValue; - } else if (leftType == NSConstantValueExpressionType && rightType == NSKeyPathExpressionType) { - value = leftExpression.mgl_constantMBGLValue; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Comparison predicate must compare an attribute (as a key path) to a constant or vice versa."]; - } - return value; -} - -- (mbgl::FeatureType)mgl_featureType { - NSExpression *leftExpression = self.leftExpression; - NSExpression *rightExpression = self.rightExpression; - NSExpressionType leftType = leftExpression.expressionType; - NSExpressionType rightType = rightExpression.expressionType; - mbgl::FeatureType type; - if (leftType == NSKeyPathExpressionType && rightType == NSConstantValueExpressionType) { - type = rightExpression.mgl_featureType; - } else if (leftType == NSConstantValueExpressionType && rightType == NSKeyPathExpressionType) { - type = leftExpression.mgl_featureType; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Comparison predicate must compare an attribute (as a key path) to a constant or vice versa."]; - } - return type; -} - -- (mbgl::FeatureIdentifier)mgl_featureIdentifier { - NSExpression *leftExpression = self.leftExpression; - NSExpression *rightExpression = self.rightExpression; - NSExpressionType leftType = leftExpression.expressionType; - NSExpressionType rightType = rightExpression.expressionType; - mbgl::FeatureIdentifier identifier; - if (leftType == NSKeyPathExpressionType && rightType == NSConstantValueExpressionType) { - identifier = rightExpression.mgl_featureIdentifier; - } else if (leftType == NSConstantValueExpressionType && rightType == NSKeyPathExpressionType) { - identifier = leftExpression.mgl_featureIdentifier; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Comparison predicate must compare an attribute (as a key path) to a constant or vice versa."]; - } - return identifier; -} - -@end - -@implementation NSComparisonPredicate (MGLExpressionAdditions) - -- (id)mgl_jsonExpressionObject { - NSString *op; - switch (self.predicateOperatorType) { - case NSLessThanPredicateOperatorType: - op = @"<"; - break; - case NSLessThanOrEqualToPredicateOperatorType: - op = @"<="; - break; - case NSGreaterThanPredicateOperatorType: - op = @">"; - break; - case NSGreaterThanOrEqualToPredicateOperatorType: - op = @">="; - break; - case NSEqualToPredicateOperatorType: - op = @"=="; - break; - case NSNotEqualToPredicateOperatorType: - op = @"!="; - break; - case NSBetweenPredicateOperatorType: { - op = @"all"; - NSArray *limits = self.rightExpression.constantValue; - NSPredicate *leftHandPredicate = [NSComparisonPredicate predicateWithLeftExpression:limits[0] - rightExpression:self.leftExpression - modifier:NSDirectPredicateModifier - type:NSLessThanOrEqualToPredicateOperatorType - options:0]; - NSPredicate *rightHandPredicate = [NSComparisonPredicate predicateWithLeftExpression:self.leftExpression - rightExpression:limits[1] - modifier:NSDirectPredicateModifier - type:NSLessThanOrEqualToPredicateOperatorType - options:0]; - return @[op, leftHandPredicate.mgl_jsonExpressionObject, rightHandPredicate.mgl_jsonExpressionObject]; - } - case NSInPredicateOperatorType: { - - NSExpression *matchExpression = [NSExpression expressionForFunction:@"MGL_MATCH" - arguments:@[self.leftExpression, - self.rightExpression, - [NSExpression expressionForConstantValue:@YES], - [NSExpression expressionForConstantValue:@NO]]]; - - return matchExpression.mgl_jsonExpressionObject; - } - case NSContainsPredicateOperatorType: { - NSPredicate *inPredicate = [NSComparisonPredicate predicateWithLeftExpression:self.rightExpression - rightExpression:self.leftExpression - modifier:self.comparisonPredicateModifier - type:NSInPredicateOperatorType - options:self.options]; - return inPredicate.mgl_jsonExpressionObject; - } - case NSMatchesPredicateOperatorType: - case NSLikePredicateOperatorType: - case NSBeginsWithPredicateOperatorType: - case NSEndsWithPredicateOperatorType: - case NSCustomSelectorPredicateOperatorType: - [NSException raise:NSInvalidArgumentException - format:@"NSPredicateOperatorType:%lu is not supported.", (unsigned long)self.predicateOperatorType]; - } - if (!op) { - return nil; - } - NSArray *comparisonArray = @[op, self.leftExpression.mgl_jsonExpressionObject, self.rightExpression.mgl_jsonExpressionObject]; - if (self.options) { - NSDictionary *collatorObject = @{ - @"case-sensitive": @(!(self.options & NSCaseInsensitivePredicateOption)), - @"diacritic-sensitive": @(!(self.options & NSDiacriticInsensitivePredicateOption)), - }; - return [comparisonArray arrayByAddingObject:@[@"collator", collatorObject]]; - } - return comparisonArray; -} - -@end diff --git a/platform/darwin/src/NSCompoundPredicate+MGLAdditions.h b/platform/darwin/src/NSCompoundPredicate+MGLAdditions.h deleted file mode 100644 index 0f9909255d..0000000000 --- a/platform/darwin/src/NSCompoundPredicate+MGLAdditions.h +++ /dev/null @@ -1,7 +0,0 @@ -#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 deleted file mode 100644 index 5eb20da846..0000000000 --- a/platform/darwin/src/NSCompoundPredicate+MGLAdditions.mm +++ /dev/null @@ -1,50 +0,0 @@ -#import "NSCompoundPredicate+MGLAdditions.h" - -#import "MGLStyleValue_Private.h" - -#import "NSPredicate+MGLPrivateAdditions.h" -#import "NSExpression+MGLPrivateAdditions.h" -#import "MGLLoggingConfiguration_Private.h" - -#include <mbgl/style/conversion/property_value.hpp> - -@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; -} - -@end - -@implementation NSCompoundPredicate (MGLExpressionAdditions) - -- (id)mgl_jsonExpressionObject { - switch (self.compoundPredicateType) { - case NSNotPredicateType: { - MGLAssert(self.subpredicates.count <= 1, @"NOT predicate cannot have multiple subpredicates."); - NSPredicate *subpredicate = self.subpredicates.firstObject; - return @[@"!", subpredicate.mgl_jsonExpressionObject]; - } - - case NSAndPredicateType: { - NSArray *subarrays = [self.subpredicates valueForKeyPath:@"mgl_jsonExpressionObject"]; - return [@[@"all"] arrayByAddingObjectsFromArray:subarrays]; - } - - case NSOrPredicateType: { - NSArray *subarrays = [self.subpredicates valueForKeyPath:@"mgl_jsonExpressionObject"]; - return [@[@"any"] arrayByAddingObjectsFromArray:subarrays]; - } - } - - [NSException raise:@"Compound predicate type not handled" - format:@""]; - return nil; -} - -@end diff --git a/platform/darwin/src/NSDate+MGLAdditions.h b/platform/darwin/src/NSDate+MGLAdditions.h deleted file mode 100644 index 1da03fda62..0000000000 --- a/platform/darwin/src/NSDate+MGLAdditions.h +++ /dev/null @@ -1,17 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLFoundation.h" -#include <mbgl/util/chrono.hpp> - -NS_ASSUME_NONNULL_BEGIN - - -/// Converts from a duration in seconds to a duration object usable in mbgl. -MGL_EXPORT -mbgl::Duration MGLDurationFromTimeInterval(NSTimeInterval duration); - -/// Converts from an mbgl duration object to a duration in seconds. -MGL_EXPORT -NSTimeInterval MGLTimeIntervalFromDuration(mbgl::Duration duration); - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSDate+MGLAdditions.mm b/platform/darwin/src/NSDate+MGLAdditions.mm deleted file mode 100644 index b45b41f836..0000000000 --- a/platform/darwin/src/NSDate+MGLAdditions.mm +++ /dev/null @@ -1,11 +0,0 @@ -#import "NSDate+MGLAdditions.h" - -mbgl::Duration MGLDurationFromTimeInterval(NSTimeInterval duration) -{ - return std::chrono::duration_cast<mbgl::Duration>(std::chrono::duration<NSTimeInterval>(duration)); -} - -NSTimeInterval MGLTimeIntervalFromDuration(mbgl::Duration duration) -{ - return std::chrono::duration<NSTimeInterval, std::ratio<1>>(duration).count(); -} diff --git a/platform/darwin/src/NSDictionary+MGLAdditions.h b/platform/darwin/src/NSDictionary+MGLAdditions.h deleted file mode 100644 index 556f21992b..0000000000 --- a/platform/darwin/src/NSDictionary+MGLAdditions.h +++ /dev/null @@ -1,13 +0,0 @@ -#import <Foundation/Foundation.h> - -#import <mbgl/util/feature.hpp> - -NS_ASSUME_NONNULL_BEGIN - -@interface NSDictionary (MGLAdditions) - -- (mbgl::PropertyMap)mgl_propertyMap; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSDictionary+MGLAdditions.mm b/platform/darwin/src/NSDictionary+MGLAdditions.mm deleted file mode 100644 index 4bc7ddb3cf..0000000000 --- a/platform/darwin/src/NSDictionary+MGLAdditions.mm +++ /dev/null @@ -1,24 +0,0 @@ -#import "NSDictionary+MGLAdditions.h" - -#import "NSExpression+MGLPrivateAdditions.h" -#import "NSArray+MGLAdditions.h" - -@implementation NSDictionary (MGLAdditions) - -- (mbgl::PropertyMap)mgl_propertyMap { - mbgl::PropertyMap propertyMap; - for (NSString *key in self.allKeys) { - if ([self[key] isKindOfClass:[NSDictionary class]]) { - propertyMap[[key UTF8String]] = [self[key] mgl_propertyMap]; - } else if ([self[key] isKindOfClass:[NSArray class]]) { - NSArray *array = self[key]; - propertyMap[[key UTF8String]] = [array mgl_vector]; - } else { - NSExpression *expression = [NSExpression expressionForConstantValue:self[key]]; - propertyMap[[key UTF8String]] = expression.mgl_constantMBGLValue; - } - } - return propertyMap; -} - -@end diff --git a/platform/darwin/src/NSException+MGLAdditions.h b/platform/darwin/src/NSException+MGLAdditions.h deleted file mode 100644 index 274ca50a89..0000000000 --- a/platform/darwin/src/NSException+MGLAdditions.h +++ /dev/null @@ -1,4 +0,0 @@ -#import <Foundation/Foundation.h> -#import "MGLLoggingConfiguration_Private.h" - -#define MGLAssertIsMainThread() MGLAssert([[NSThread currentThread] isMainThread], @"%s must be accessed on the main thread, not %@", __PRETTY_FUNCTION__, [NSThread currentThread]) diff --git a/platform/darwin/src/NSExpression+MGLAdditions.h b/platform/darwin/src/NSExpression+MGLAdditions.h deleted file mode 100644 index 2109310e69..0000000000 --- a/platform/darwin/src/NSExpression+MGLAdditions.h +++ /dev/null @@ -1,237 +0,0 @@ -#import <Foundation/Foundation.h> -#if TARGET_OS_IPHONE - #import <UIKit/UIKit.h> -#else - #import <Cocoa/Cocoa.h> -#endif - -#import "MGLTypes.h" - -@class MGLAttributedExpression; - -NS_ASSUME_NONNULL_BEGIN - -typedef NSString *MGLExpressionInterpolationMode NS_TYPED_ENUM; - -/** - An `NSString` identifying the `linear` interpolation type in an `NSExpression`. - - This attribute corresponds to the `linear` value in the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-interpolate"><code>interpolate</code></a> - expression operator in the Mapbox Style Specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolationModeLinear; - -/** - An `NSString` identifying the `expotential` interpolation type in an `NSExpression`. - - This attribute corresponds to the `exponential` value in the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-interpolate"><code>interpolate</code></a> - expression operator in the Mapbox Style Specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolationModeExponential; - -/** - An `NSString` identifying the `cubic-bezier` interpolation type in an `NSExpression`. - - This attribute corresponds to the `cubic-bezier` value in the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-interpolate"><code>interpolate</code></a> - expression operator in the Mapbox Style Specification. - */ -FOUNDATION_EXTERN MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier; - -/** - Methods for creating expressions that use Mapbox-specific functionality and for - converting to and from the JSON format defined in the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions">Mapbox Style Specification</a>. - */ -@interface NSExpression (MGLAdditions) - -#pragma mark Creating Variable Expressions - -/** - `NSExpression` variable that corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-zoom"><code>zoom</code></a> - expression operator in the Mapbox Style Specification. - */ -@property (class, nonatomic, readonly) NSExpression *zoomLevelVariableExpression; - -/** - `NSExpression` variable that corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-heatmap-density"><code>heatmap-density</code></a> - expression operator in the Mapbox Style Specification. - */ -@property (class, nonatomic, readonly) NSExpression *heatmapDensityVariableExpression; - -/** - `NSExpression` variable that corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-line-progress"><code>line-progress</code></a> - expression operator in the Mapbox Style Specification. - */ -@property (class, nonatomic, readonly) NSExpression *lineProgressVariableExpression; - -/** - `NSExpression` variable that corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#eexpressions-geometry-type"><code>geometry-type</code></a> - expression operator in the Mapbox Style Specification. - */ -@property (class, nonatomic, readonly) NSExpression *geometryTypeVariableExpression; - -/** - `NSExpression` variable that corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-id"><code>id</code></a> - expression operator in the Mapbox Style Specification. - */ -@property (class, nonatomic, readonly) NSExpression *featureIdentifierVariableExpression; - -/** - `NSExpression` variable that corresponds to the - <a href="https://docs.mapbox.com/mapbox-gl-js/style-spec/#accumulated"><code>id</code></a> - expression operator in the Mapbox Style Specification. - */ -@property (class, nonatomic, readonly) NSExpression *featureAccumulatedVariableExpression; - -/** - `NSExpression` variable that corresponds to the - <a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-properties"><code>properties</code></a> - expression operator in the Mapbox Style Specification. - */ -@property (class, nonatomic, readonly) NSExpression *featureAttributesVariableExpression; - -@property (class, nonatomic, readonly) NSExpression *featurePropertiesVariableExpression __attribute__((deprecated("", "featureAttributesVariableExpression"))); - -#pragma mark Creating Conditional Expressions - -/** - Returns a conditional function expression specifying the string predicate, and - expressions for each condition. - - @param conditionPredicate The predicate to get evaluated. - @param trueExpression The expression for conditions equal to true. - @param falseExpression The expression for conditions equal to false. - */ -+ (instancetype)mgl_expressionForConditional:(nonnull NSPredicate *)conditionPredicate trueExpression:(nonnull NSExpression *)trueExpression falseExpresssion:(nonnull NSExpression *)falseExpression NS_SWIFT_NAME(init(forMGLConditional:trueExpression:falseExpression:)); - -#pragma mark Creating Ramp, Scale, and Curve Expressions - -/** - Returns a step function expression specifying the stepping, from expression - and stops. - - @param steppingExpression The stepping expression. - @param minimumExpression The expression which could be a constant or function expression. - @param stops The stops must be an `NSDictionary` constant `NSExpression`. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/dds-circle-layer/"> - Data-driven circles</a>, <a href="https://docs.mapbox.com/ios/maps/examples/clustering/"> - Cluster point data</a>, and <a href="https://docs.mapbox.com/ios/maps/examples/clustering-with-images/"> - Use images to cluster point data</a> examples to learn how to use this - expression to style a map layer based on an attribute value. - */ -+ (instancetype)mgl_expressionForSteppingExpression:(nonnull NSExpression*)steppingExpression fromExpression:(nonnull NSExpression *)minimumExpression stops:(nonnull NSExpression*)stops NS_SWIFT_NAME(init(forMGLStepping:from:stops:)); - -/** - Returns an interpolated function expression specifying the function operator, curve type, - parameters and steps. - - @param inputExpression The interpolating expression input. - @param curveType The curve type could be `MGLExpressionInterpolationModeLinear`, - `MGLExpressionInterpolationModeExponential` and - `MGLExpressionInterpolationModeCubicBezier`. - @param parameters The parameters expression. - @param stops The stops expression. - - #### Related examples - See the <a href="https://docs.mapbox.com/ios/maps/examples/heatmap-example/"> - Create a heatmap layer</a> example to learn how to style an `MGLHeatmapStyleLayer` - based on zoom level and point density with this expression. - */ -+ (instancetype)mgl_expressionForInterpolatingExpression:(nonnull NSExpression*)inputExpression withCurveType:(nonnull MGLExpressionInterpolationMode)curveType parameters:(nullable NSExpression *)parameters stops:(nonnull NSExpression*)stops NS_SWIFT_NAME(init(forMGLInterpolating:curveType:parameters:stops:)); - -/** - Returns a match function expression specifying the input, matching values, - and default value. - - @param inputExpression The matching expression. - @param matchedExpressions The matched values expression dictionary must be condition : value. - @param defaultExpression The defaultValue expression to be used in case there is no match. - */ -+ (instancetype)mgl_expressionForMatchingExpression:(nonnull NSExpression *)inputExpression inDictionary:(nonnull NSDictionary<NSExpression *, NSExpression *> *)matchedExpressions defaultExpression:(nonnull NSExpression *)defaultExpression NS_SWIFT_NAME(init(forMGLMatchingKey:in:default:)); - -/** - Returns an attributed function expression specifying an `MGLAttributedExpression` constant - expression array. - - @param attributedExpressions The `MGLAttributedExpression` constant expression array. - */ -+ (instancetype)mgl_expressionForAttributedExpressions:(nonnull NSArray<NSExpression *> *)attributedExpressions NS_SWIFT_NAME(init(forAttributedExpressions:)); - -#pragma mark Concatenating String Expressions - -/** - Returns a constant expression appending the passed expression. - - @note Both the receiver and the given expression must be an `NSString` constant - expression type; otherwise, an exception is rised. - - @param expression The expression to append to the receiver. - */ -- (instancetype)mgl_expressionByAppendingExpression:(nonnull NSExpression *)expression NS_SWIFT_NAME(mgl_appending(_:)); - -#pragma mark Converting JSON Expressions - -/** - Returns an expression equivalent to the given Foundation object deserialized - from JSON data. - - The Foundation object is interpreted according to the - [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions). - See the - “[Information for Style Authors](../for-style-authors.html#setting-attribute-values)” - guide for a correspondence of operators and types between the style - specification and the `NSExpression` representation used by this SDK. - - @param object A Foundation object deserialized from JSON data, for example - using `NSJSONSerialization`. - @return An initialized expression equivalent to `object`, suitable for use as - the value of a style layer attribute. - */ -+ (instancetype)expressionWithMGLJSONObject:(id)object NS_SWIFT_NAME(init(mglJSONObject:)); - -/** - An equivalent Foundation object that can be serialized as JSON. - - The Foundation object conforms to the - [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions). - See the - “[Information for Style Authors](../for-style-authors.html#setting-attribute-values)” - guide for a correspondence of operators and types between the style - specification and the `NSExpression` representation used by this SDK. - - You can use `NSJSONSerialization` to serialize the Foundation object as data to - write to a file. - */ -@property (nonatomic, readonly) id mgl_jsonExpressionObject; - -#pragma mark Localizing the Expression - -/** - Returns a copy of the receiver localized into the given locale. - - This method assumes the receiver refers to the feature attributes that are - available in vector tiles supplied by the - <a href="https://www.mapbox.com/vector-tiles/mapbox-streets-v8/#overview">Mapbox Streets source</a>. - On iOS, the user can set the system’s preferred language in Settings, General - Settings, Language & Region. On macOS, the user can set the system’s preferred - language in the Language & Region pane of System Preferences. - - @param locale The locale into which labels should be localized. To use the - system’s preferred language, if supported, specify `nil`. To use the local - language, specify a locale with the identifier `mul`. - */ -- (NSExpression *)mgl_expressionLocalizedIntoLocale:(nullable NSLocale *)locale; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm deleted file mode 100644 index 80008aa69b..0000000000 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ /dev/null @@ -1,1605 +0,0 @@ -#import "MGLFoundation_Private.h" -#import "MGLGeometry_Private.h" -#import "NSExpression+MGLPrivateAdditions.h" - -#import "MGLTypes.h" -#if TARGET_OS_IPHONE - #import "UIColor+MGLAdditions.h" -#else - #import "NSColor+MGLAdditions.h" -#endif -#import "NSPredicate+MGLAdditions.h" -#import "NSValue+MGLStyleAttributeAdditions.h" -#import "MGLVectorTileSource_Private.h" -#import "MGLAttributedExpression.h" - -#import <objc/runtime.h> - -#import <mbgl/style/expression/expression.hpp> - -const MGLExpressionInterpolationMode MGLExpressionInterpolationModeLinear = @"linear"; -const MGLExpressionInterpolationMode MGLExpressionInterpolationModeExponential = @"exponential"; -const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier = @"cubic-bezier"; - -@interface MGLAftermarketExpressionInstaller: NSObject -@end - -@implementation MGLAftermarketExpressionInstaller - -+ (void)load { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - [self installFunctions]; - }); -} - -/** - Adds to NSExpression’s built-in repertoire of functions. - */ -+ (void)installFunctions { - Class MGLAftermarketExpressionInstaller = [self class]; - - // NSExpression’s built-in functions are backed by class methods on a - // private class, so use a function expression to get at the class. - // http://funwithobjc.tumblr.com/post/2922267976/using-custom-functions-with-nsexpression - NSExpression *functionExpression = [NSExpression expressionWithFormat:@"sum({})"]; - NSString *className = NSStringFromClass([functionExpression.operand.constantValue class]); - - // Effectively categorize the class with some extra class methods. - Class NSPredicateUtilities = objc_getMetaClass(className.UTF8String); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wundeclared-selector" - #define INSTALL_METHOD(sel) \ - { \ - Method method = class_getInstanceMethod(MGLAftermarketExpressionInstaller, @selector(sel)); \ - class_addMethod(NSPredicateUtilities, @selector(sel), method_getImplementation(method), method_getTypeEncoding(method)); \ - } - #define INSTALL_CONTROL_STRUCTURE(sel) \ - { \ - Method method = class_getInstanceMethod(MGLAftermarketExpressionInstaller, @selector(sel:)); \ - class_addMethod(NSPredicateUtilities, @selector(sel), method_getImplementation(method), method_getTypeEncoding(method)); \ - class_addMethod(NSPredicateUtilities, @selector(sel:), method_getImplementation(method), method_getTypeEncoding(method)); \ - } - - // Install method-like functions, taking the number of arguments implied by - // the selector name. - INSTALL_METHOD(mgl_join:); - INSTALL_METHOD(mgl_round:); - INSTALL_METHOD(mgl_interpolate:withCurveType:parameters:stops:); - INSTALL_METHOD(mgl_step:from:stops:); - INSTALL_METHOD(mgl_coalesce:); - INSTALL_METHOD(mgl_does:have:); - INSTALL_METHOD(mgl_acos:); - INSTALL_METHOD(mgl_cos:); - INSTALL_METHOD(mgl_asin:); - INSTALL_METHOD(mgl_sin:); - INSTALL_METHOD(mgl_atan:); - INSTALL_METHOD(mgl_tan:); - INSTALL_METHOD(mgl_log2:); - INSTALL_METHOD(mgl_attributed:); - - // Install functions that resemble control structures, taking arbitrary - // numbers of arguments. Vararg aftermarket functions need to be declared - // with an explicit and implicit first argument. - INSTALL_CONTROL_STRUCTURE(MGL_LET); - INSTALL_CONTROL_STRUCTURE(MGL_MATCH); - INSTALL_CONTROL_STRUCTURE(MGL_IF); - INSTALL_CONTROL_STRUCTURE(MGL_FUNCTION); - - #undef INSTALL_AFTERMARKET_FN -#pragma clang diagnostic pop -} - -/** - Joins the given components into a single string by concatenating each component - in order. - */ -- (NSString *)mgl_join:(NSArray<NSString *> *)components { - return [components componentsJoinedByString:@""]; -} - -- (NSString *)mgl_attributed:(NSArray<MGLAttributedExpression *> *)attributedExpressions { - [NSException raise:NSInvalidArgumentException - format:@"Text format expressions lack underlying Objective-C implementations."]; - return nil; -} - -/** - Rounds the given number to the nearest integer. If the number is halfway - between two integers, this method rounds it away from zero. - */ -- (NSNumber *)mgl_round:(NSNumber *)number { - return @(round(number.doubleValue)); -} - -/** - Computes the principal value of the inverse cosine. - */ -- (NSNumber *)mgl_acos:(NSNumber *)number { - return @(acos(number.doubleValue)); -} - -/** - Computes the principal value of the cosine. - */ -- (NSNumber *)mgl_cos:(NSNumber *)number { - return @(cos(number.doubleValue)); -} - -/** - Computes the principal value of the inverse sine. - */ -- (NSNumber *)mgl_asin:(NSNumber *)number { - return @(asin(number.doubleValue)); -} - -/** - Computes the principal value of the sine. - */ -- (NSNumber *)mgl_sin:(NSNumber *)number { - return @(sin(number.doubleValue)); -} - -/** - Computes the principal value of the inverse tangent. - */ -- (NSNumber *)mgl_atan:(NSNumber *)number { - return @(atan(number.doubleValue)); -} - -/** - Computes the principal value of the tangent. - */ -- (NSNumber *)mgl_tan:(NSNumber *)number { - return @(tan(number.doubleValue)); -} - -/** - Computes the logarithm base two of the value. - */ -- (NSNumber *)mgl_log2:(NSNumber *)number { - return @(log2(number.doubleValue)); -} - -/** - A placeholder for a method that evaluates an interpolation expression. - */ -- (id)mgl_interpolate:(id)inputExpression withCurveType:(NSString *)curveType parameters:(NSDictionary *)params stops:(NSDictionary *)stops { - [NSException raise:NSInvalidArgumentException - format:@"Interpolation expressions lack underlying Objective-C implementations."]; - return nil; -} - -/** - A placeholder for a method that evaluates a step expression. - */ -- (id)mgl_step:(id)inputExpression from:(id)minimumExpression stops:(NSDictionary *)stops { - [NSException raise:NSInvalidArgumentException - format:@"Step expressions lack underlying Objective-C implementations."]; - return nil; -} - -/** - A placeholder for a method that evaluates a coalesce expression. - */ -- (id)mgl_coalesce:(NSArray<NSExpression *> *)elements { - [NSException raise:NSInvalidArgumentException - format:@"Coalesce expressions lack underlying Objective-C implementations."]; - return nil; -} - -/** - Returns a Boolean value indicating whether the object has a value for the given - key. - */ -- (BOOL)mgl_does:(id)object have:(NSString *)key { - return [object valueForKey:key] != nil; -} - -/** - A placeholder for a method that evaluates an expression based on an arbitrary - number of variable names and assigned expressions. - */ -- (id)MGL_LET:(NSString *)firstVariableName, ... { - [NSException raise:NSInvalidArgumentException - format:@"Assignment expressions lack underlying Objective-C implementations."]; - return nil; -} - -/** - A placeholder for a method that evaluates an expression and returns the matching element. - */ -- (id)MGL_MATCH:(id)firstCondition, ... { - [NSException raise:NSInvalidArgumentException - format:@"Assignment expressions lack underlying Objective-C implementations."]; - return nil; -} - -/** - A placeholder for a method that evaluates an expression and returns the matching element. - */ -- (id)MGL_IF:(id)firstCondition, ... { - va_list argumentList; - va_start(argumentList, firstCondition); - - for (id eachExpression = firstCondition; eachExpression; eachExpression = va_arg(argumentList, id)) { - if ([eachExpression isKindOfClass:[NSComparisonPredicate class]]) { - id valueExpression = va_arg(argumentList, id); - if ([eachExpression evaluateWithObject:nil]) { - return valueExpression; - } - } else { - return eachExpression; - } - } - va_end(argumentList); - - return nil; -} - -/** - A placeholder for a catch-all method that evaluates an arbitrary number of - arguments as an expression according to the Mapbox Style Specification’s - expression language. - */ -- (id)MGL_FUNCTION:(id)firstArgument, ... { - [NSException raise:NSInvalidArgumentException - format:@"Mapbox GL function expressions lack underlying Objective-C implementations."]; - return nil; -} - -@end - -@implementation NSExpression (MGLPrivateAdditions) - -- (std::vector<mbgl::Value>)mgl_aggregateMBGLValue { - if ([self.constantValue isKindOfClass:[NSArray class]] || [self.constantValue isKindOfClass:[NSSet class]]) { - std::vector<mbgl::Value> convertedValues; - for (id value in self.constantValue) { - NSExpression *expression = value; - if (![expression isKindOfClass:[NSExpression class]]) { - expression = [NSExpression expressionForConstantValue:expression]; - } - convertedValues.push_back(expression.mgl_constantMBGLValue); - } - return convertedValues; - } - [NSException raise:NSInvalidArgumentException - format:@"Constant value expression must contain an array or set."]; - return {}; -} - -- (mbgl::Value)mgl_constantMBGLValue { - id value = self.constantValue; - 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(char)) == 0) || - (strcmp([number objCType], @encode(BOOL)) == 0)) { - // char: 32-bit boolean - // BOOL: 64-bit boolean - return { (bool)number.boolValue }; - } else if (strcmp([number objCType], @encode(double)) == 0) { - // Double values on all platforms are interpreted precisely. - return { (double)number.doubleValue }; - } else if (strcmp([number objCType], @encode(float)) == 0) { - // Float values when taken as double introduce precision problems, - // so warn the user to avoid them. This would require them to - // explicitly use -[NSNumber numberWithFloat:] arguments anyway. - // We still do this conversion in order to provide a valid value. - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSLog(@"Float value in expression will be converted to a double; some imprecision may result. " - @"Use double values explicitly when specifying constant expression values and " - @"when specifying arguments to predicate and expression format strings. " - @"This will be logged only once."); - }); - return { (double)number.doubleValue }; - } else if ([number compare:@(0)] == NSOrderedDescending || - [number compare:@(0)] == NSOrderedSame) { - // Positive integer or zero; use uint64_t per mbgl::Value definition. - // We use unsigned long long here to avoid any truncation. - return { (uint64_t)number.unsignedLongLongValue }; - } else if ([number compare:@(0)] == NSOrderedAscending) { - // Negative integer; use int64_t per mbgl::Value definition. - // We use long long here to avoid any truncation. - return { (int64_t)number.longLongValue }; - } - } else if ([value isKindOfClass:[MGLColor class]]) { - auto hexString = [(MGLColor *)value mgl_color].stringify(); - return { hexString }; - } else if (value && value != [NSNull null]) { - [NSException raise:NSInvalidArgumentException - format:@"Can’t convert %s:%@ to mbgl::Value", [value objCType], value]; - } - return {}; -} - -- (std::vector<mbgl::FeatureType>)mgl_aggregateFeatureType { - if ([self.constantValue isKindOfClass:[NSArray class]] || [self.constantValue isKindOfClass:[NSSet class]]) { - std::vector<mbgl::FeatureType> convertedValues; - for (id value in self.constantValue) { - NSExpression *expression = value; - if (![expression isKindOfClass:[NSExpression class]]) { - expression = [NSExpression expressionForConstantValue:expression]; - } - convertedValues.push_back(expression.mgl_featureType); - } - return convertedValues; - } - [NSException raise:NSInvalidArgumentException - format:@"Constant value expression must contain an array or set."]; - return {}; -} - -- (mbgl::FeatureType)mgl_featureType { - id value = self.constantValue; - if ([value isKindOfClass:NSString.class]) { - if ([value isEqualToString:@"Point"]) { - return mbgl::FeatureType::Point; - } - if ([value isEqualToString:@"LineString"]) { - return mbgl::FeatureType::LineString; - } - if ([value isEqualToString:@"Polygon"]) { - return mbgl::FeatureType::Polygon; - } - } else if ([value isKindOfClass:NSNumber.class]) { - switch ([value integerValue]) { - case 1: - return mbgl::FeatureType::Point; - case 2: - return mbgl::FeatureType::LineString; - case 3: - return mbgl::FeatureType::Polygon; - default: - break; - } - } - return mbgl::FeatureType::Unknown; -} - -- (std::vector<mbgl::FeatureIdentifier>)mgl_aggregateFeatureIdentifier { - if ([self.constantValue isKindOfClass:[NSArray class]] || [self.constantValue isKindOfClass:[NSSet class]]) { - std::vector<mbgl::FeatureIdentifier> convertedValues; - for (id value in self.constantValue) { - NSExpression *expression = value; - if (![expression isKindOfClass:[NSExpression class]]) { - expression = [NSExpression expressionForConstantValue:expression]; - } - convertedValues.push_back(expression.mgl_featureIdentifier); - } - return convertedValues; - } - [NSException raise:NSInvalidArgumentException - format:@"Constant value expression must contain an array or set."]; - return {}; -} - -- (mbgl::FeatureIdentifier)mgl_featureIdentifier { - mbgl::Value mbglValue = self.mgl_constantMBGLValue; - - if (mbglValue.is<std::string>()) { - return mbglValue.get<std::string>(); - } - if (mbglValue.is<double>()) { - return mbglValue.get<double>(); - } - if (mbglValue.is<uint64_t>()) { - return mbglValue.get<uint64_t>(); - } - if (mbglValue.is<int64_t>()) { - return mbglValue.get<int64_t>(); - } - - return {}; -} - -@end - -@implementation NSObject (MGLExpressionAdditions) - -- (NSNumber *)mgl_number { - return nil; -} - -- (NSNumber *)mgl_numberWithFallbackValues:(id)fallbackValue, ... { - if (self.mgl_number) { - return self.mgl_number; - } - - va_list fallbackValues; - va_start(fallbackValues, fallbackValue); - for (id value = fallbackValue; value; value = va_arg(fallbackValues, id)) { - if ([value mgl_number]) { - return [value mgl_number]; - } - } - - return nil; -} - -@end - -@implementation NSNull (MGLExpressionAdditions) - -- (id)mgl_jsonExpressionObject { - return self; -} - -@end - -@implementation NSString (MGLExpressionAdditions) - -- (id)mgl_jsonExpressionObject { - return self; -} - -- (NSNumber *)mgl_number { - if (self.doubleValue || ![[NSDecimalNumber decimalNumberWithString:self] isEqual:[NSDecimalNumber notANumber]]) { - return @(self.doubleValue); - } - - return nil; -} - -@end - -@implementation NSNumber (MGLExpressionAdditions) - -- (id)mgl_interpolateWithCurveType:(NSString *)curveType - parameters:(NSArray *)parameters - stops:(NSDictionary<NSNumber *, id> *)stops { - [NSException raise:NSInvalidArgumentException - format:@"Interpolation expressions lack underlying Objective-C implementations."]; - return nil; -} - -- (id)mgl_stepWithMinimum:(id)minimum stops:(NSDictionary<NSNumber *, id> *)stops { - [NSException raise:NSInvalidArgumentException - format:@"Interpolation expressions lack underlying Objective-C implementations."]; - return nil; -} - -- (NSNumber *)mgl_number { - return self; -} - -- (id)mgl_jsonExpressionObject { - if ([self isEqualToNumber:@(M_E)]) { - return @[@"e"]; - } else if ([self isEqualToNumber:@(M_PI)]) { - return @[@"pi"]; - } - return self; -} - -@end - -@implementation MGLColor (MGLExpressionAdditions) - -- (id)mgl_jsonExpressionObject { - auto color = [self mgl_color]; - if (color.a == 1) { - return @[@"rgb", @(color.r * 255), @(color.g * 255), @(color.b * 255)]; - } - return @[@"rgba", @(color.r * 255), @(color.g * 255), @(color.b * 255), @(color.a)]; -} - -@end - -@implementation NSArray (MGLExpressionAdditions) - -- (id)mgl_jsonExpressionObject { - return [self valueForKeyPath:@"mgl_jsonExpressionObject"]; -} - -- (id)mgl_coalesce { - [NSException raise:NSInvalidArgumentException - format:@"Coalesce expressions lack underlying Objective-C implementations."]; - return nil; -} - -@end - -@implementation NSDictionary (MGLExpressionAdditions) - -- (id)mgl_jsonExpressionObject { - NSMutableDictionary *expressionObject = [NSMutableDictionary dictionaryWithCapacity:self.count]; - [self enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - expressionObject[[key mgl_jsonExpressionObject]] = [obj mgl_jsonExpressionObject]; - }]; - - return expressionObject; -} - -- (id)mgl_has:(id)element { - [NSException raise:NSInvalidArgumentException - format:@"Has expressions lack underlying Objective-C implementations."]; - return nil; - -} - -@end - -@implementation NSExpression (MGLExpressionAdditions) - -- (NSExpression *)mgl_expressionWithContext:(NSDictionary<NSString *, NSExpression *> *)context { - [NSException raise:NSInternalInconsistencyException - format:@"Assignment expressions lack underlying Objective-C implementations."]; - return self; -} - -- (id)mgl_has:(id)element { - [NSException raise:NSInvalidArgumentException - format:@"Has expressions lack underlying Objective-C implementations."]; - return nil; -} - -@end - -@implementation NSExpression (MGLAdditions) - -+ (NSExpression *)zoomLevelVariableExpression { - return [NSExpression expressionForVariable:@"zoomLevel"]; -} - -+ (NSExpression *)heatmapDensityVariableExpression { - return [NSExpression expressionForVariable:@"heatmapDensity"]; -} - -+ (NSExpression *)lineProgressVariableExpression { - return [NSExpression expressionForVariable:@"lineProgress"]; -} - -+ (NSExpression *)featureAccumulatedVariableExpression { - return [NSExpression expressionForVariable:@"featureAccumulated"]; -} - -+ (NSExpression *)geometryTypeVariableExpression { - return [NSExpression expressionForVariable:@"geometryType"]; -} - -+ (NSExpression *)featureIdentifierVariableExpression { - return [NSExpression expressionForVariable:@"featureIdentifier"]; -} - -+ (NSExpression *)featureAttributesVariableExpression { - return [NSExpression expressionForVariable:@"featureAttributes"]; -} - -+ (NSExpression *)featurePropertiesVariableExpression { - return [self featureAttributesVariableExpression]; -} - -+ (instancetype)mgl_expressionForConditional:(nonnull NSPredicate *)conditionPredicate trueExpression:(nonnull NSExpression *)trueExpression falseExpresssion:(nonnull NSExpression *)falseExpression { - return [NSExpression expressionForConditional:conditionPredicate trueExpression:trueExpression falseExpression:falseExpression]; -} - -+ (instancetype)mgl_expressionForSteppingExpression:(nonnull NSExpression *)steppingExpression fromExpression:(nonnull NSExpression *)minimumExpression stops:(nonnull NSExpression *)stops { - return [NSExpression expressionForFunction:@"mgl_step:from:stops:" - arguments:@[steppingExpression, minimumExpression, stops]]; -} - -+ (instancetype)mgl_expressionForInterpolatingExpression:(nonnull NSExpression *)inputExpression withCurveType:(nonnull MGLExpressionInterpolationMode)curveType parameters:(nullable NSExpression *)parameters stops:(nonnull NSExpression *)stops { - NSExpression *sanitizeParams = parameters ? parameters : [NSExpression expressionForConstantValue:nil]; - return [NSExpression expressionForFunction:@"mgl_interpolate:withCurveType:parameters:stops:" - arguments:@[inputExpression, [NSExpression expressionForConstantValue:curveType], sanitizeParams, stops]]; -} - -+ (instancetype)mgl_expressionForMatchingExpression:(nonnull NSExpression *)inputExpression inDictionary:(nonnull NSDictionary<NSExpression *, NSExpression *> *)matchedExpressions defaultExpression:(nonnull NSExpression *)defaultExpression { - NSMutableArray *optionsArray = [NSMutableArray arrayWithObjects:inputExpression, nil]; - - NSEnumerator *matchEnumerator = matchedExpressions.keyEnumerator; - while (NSExpression *key = matchEnumerator.nextObject) { - [optionsArray addObject:key]; - [optionsArray addObject:[matchedExpressions objectForKey:key]]; - } - - [optionsArray addObject:defaultExpression]; - return [NSExpression expressionForFunction:@"MGL_MATCH" - arguments:optionsArray]; -} - -+ (instancetype)mgl_expressionForAttributedExpressions:(nonnull NSArray<NSExpression *> *)attributedExpressions { - return [NSExpression expressionForFunction:@"mgl_attributed:" arguments:attributedExpressions]; -} - -- (instancetype)mgl_expressionByAppendingExpression:(nonnull NSExpression *)expression { - NSExpression *subexpression = [NSExpression expressionForAggregate:@[self, expression]]; - return [NSExpression expressionForFunction:@"mgl_join:" arguments:@[subexpression]]; -} - -static NSDictionary<NSString *, NSString *> *MGLFunctionNamesByExpressionOperator; -static NSDictionary<NSString *, NSString *> *MGLExpressionOperatorsByFunctionNames; - -NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { - NSMutableArray *subexpressions = [NSMutableArray arrayWithCapacity:objects.count]; - for (id object in objects) { - NSExpression *expression = [NSExpression expressionWithMGLJSONObject:object]; - [subexpressions addObject:expression]; - } - return subexpressions; -} - -+ (instancetype)expressionWithMGLJSONObject:(id)object { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - MGLFunctionNamesByExpressionOperator = @{ - @"+": @"add:to:", - @"-": @"from:subtract:", - @"*": @"multiply:by:", - @"/": @"divide:by:", - @"%": @"modulus:by:", - @"sqrt": @"sqrt:", - @"log10": @"log:", - @"ln": @"ln:", - @"abs": @"abs:", - @"round": @"mgl_round:", - @"acos" : @"mgl_acos:", - @"cos" : @"mgl_cos:", - @"asin" : @"mgl_asin:", - @"sin" : @"mgl_sin:", - @"atan" : @"mgl_atan:", - @"tan" : @"mgl_tan:", - @"log2" : @"mgl_log2:", - @"floor": @"floor:", - @"ceil": @"ceiling:", - @"^": @"raise:toPower:", - @"upcase": @"uppercase:", - @"downcase": @"lowercase:", - @"let": @"MGL_LET", - }; - }); - if (!object || object == [NSNull null]) { - return [NSExpression expressionForConstantValue:nil]; - } - - if ([object isKindOfClass:[NSString class]] || - [object isKindOfClass:[NSNumber class]] || - [object isKindOfClass:[NSValue class]] || - [object isKindOfClass:[MGLColor class]]) { - return [NSExpression expressionForConstantValue:object]; - } - - if ([object isKindOfClass:[NSDictionary class]]) { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:[object count]]; - [object enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - dictionary[key] = [NSExpression expressionWithMGLJSONObject:obj]; - }]; - return [NSExpression expressionForConstantValue:dictionary]; - } - if ([object isKindOfClass:[NSArray class]]) { - NSArray *array = (NSArray *)object; - NSString *op = array.firstObject; - - if (![op isKindOfClass:[NSString class]]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(array); - return [NSExpression expressionForFunction:@"MGL_FUNCTION" arguments:subexpressions]; - } - - NSArray *argumentObjects = [array subarrayWithRange:NSMakeRange(1, array.count - 1)]; - - NSString *functionName = MGLFunctionNamesByExpressionOperator[op]; - if (functionName) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - if ([op isEqualToString:@"+"] && argumentObjects.count > 2) { - NSExpression *subexpression = [NSExpression expressionForAggregate:subexpressions]; - return [NSExpression expressionForFunction:@"sum:" - arguments:@[subexpression]]; - } else if ([op isEqualToString:@"^"] && [argumentObjects.firstObject isEqual:@[@"e"]]) { - functionName = @"exp:"; - subexpressions = [subexpressions subarrayWithRange:NSMakeRange(1, subexpressions.count - 1)]; - } - - return [NSExpression expressionForFunction:functionName - arguments:subexpressions]; - } else if ([op isEqualToString:@"collator"]) { - // Avoid wrapping collator options object in literal expression. - return [NSExpression expressionForFunction:@"MGL_FUNCTION" arguments:array]; - } else if ([op isEqualToString:@"literal"]) { - if ([argumentObjects.firstObject isKindOfClass:[NSArray class]]) { - return [NSExpression expressionForAggregate:MGLSubexpressionsWithJSONObjects(argumentObjects.firstObject)]; - } - return [NSExpression expressionWithMGLJSONObject:argumentObjects.firstObject]; - } else if ([op isEqualToString:@"to-boolean"]) { - NSExpression *operand = [NSExpression expressionWithMGLJSONObject:argumentObjects.firstObject]; - return [NSExpression expressionForFunction:operand selectorName:@"boolValue" arguments:@[]]; - } else if ([op isEqualToString:@"to-number"] || [op isEqualToString:@"number"]) { - NSExpression *operand = [NSExpression expressionWithMGLJSONObject:argumentObjects.firstObject]; - if (argumentObjects.count == 1) { - return [NSExpression expressionWithFormat:@"CAST(%@, 'NSNumber')", operand]; - } - argumentObjects = [argumentObjects subarrayWithRange:NSMakeRange(1, argumentObjects.count - 1)]; - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - return [NSExpression expressionForFunction:operand selectorName:@"mgl_numberWithFallbackValues:" arguments:subexpressions]; - } else if ([op isEqualToString:@"to-string"] || [op isEqualToString:@"string"]) { - NSExpression *operand = [NSExpression expressionWithMGLJSONObject:argumentObjects.firstObject]; - return [NSExpression expressionWithFormat:@"CAST(%@, 'NSString')", operand]; - } else if ([op isEqualToString:@"to-color"]) { - NSExpression *operand = [NSExpression expressionWithMGLJSONObject:argumentObjects.firstObject]; - - if (argumentObjects.count == 1) { -#if TARGET_OS_IPHONE - return [NSExpression expressionWithFormat:@"CAST(%@, 'UIColor')", operand]; -#else - return [NSExpression expressionWithFormat:@"CAST(%@, 'NSColor')", operand]; -#endif - } - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(array); - return [NSExpression expressionForFunction:@"MGL_FUNCTION" arguments:subexpressions]; - - } else if ([op isEqualToString:@"to-rgba"]) { - NSExpression *operand = [NSExpression expressionWithMGLJSONObject:argumentObjects.firstObject]; - return [NSExpression expressionWithFormat:@"CAST(noindex(%@), 'NSArray')", operand]; - } else if ([op isEqualToString:@"get"]) { - if (argumentObjects.count == 2) { - NSExpression *operand = [NSExpression expressionWithMGLJSONObject:argumentObjects.lastObject]; - if ([argumentObjects.firstObject isKindOfClass:[NSString class]]) { - return [NSExpression expressionWithFormat:@"%@.%K", operand, argumentObjects.firstObject]; - } - NSExpression *key = [NSExpression expressionWithMGLJSONObject:argumentObjects.firstObject]; - return [NSExpression expressionWithFormat:@"%@.%@", operand, key]; - } - return [NSExpression expressionForKeyPath:argumentObjects.firstObject]; - } else if ([op isEqualToString:@"length"]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - NSString *function = @"count:"; - if ([subexpressions.firstObject expressionType] == NSConstantValueExpressionType - && [[subexpressions.firstObject constantValue] isKindOfClass:[NSString class]]) { - function = @"length:"; - } - return [NSExpression expressionForFunction:function arguments:@[subexpressions.firstObject]]; - } else if ([op isEqualToString:@"rgb"]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - return [NSExpression mgl_expressionForRGBComponents:subexpressions]; - } else if ([op isEqualToString:@"rgba"]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - return [NSExpression mgl_expressionForRGBAComponents:subexpressions]; - } else if ([op isEqualToString:@"min"]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - NSExpression *subexpression = [NSExpression expressionForAggregate:subexpressions]; - return [NSExpression expressionForFunction:@"min:" arguments:@[subexpression]]; - } else if ([op isEqualToString:@"max"]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - NSExpression *subexpression = [NSExpression expressionForAggregate:subexpressions]; - return [NSExpression expressionForFunction:@"max:" arguments:@[subexpression]]; - } else if ([op isEqualToString:@"e"]) { - return [NSExpression expressionForConstantValue:@(M_E)]; - } else if ([op isEqualToString:@"pi"]) { - return [NSExpression expressionForConstantValue:@(M_PI)]; - } else if ([op isEqualToString:@"concat"]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - NSExpression *subexpression = [NSExpression expressionForAggregate:subexpressions]; - return [NSExpression expressionForFunction:@"mgl_join:" arguments:@[subexpression]]; - } else if ([op isEqualToString:@"at"]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - NSExpression *index = subexpressions.firstObject; - NSExpression *operand = subexpressions[1]; - return [NSExpression expressionForFunction:@"objectFrom:withIndex:" arguments:@[operand, index]]; - } else if ([op isEqualToString:@"has"]) { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(argumentObjects); - NSExpression *operand = argumentObjects.count > 1 ? subexpressions[1] : [NSExpression expressionForEvaluatedObject]; - NSExpression *key = subexpressions.firstObject; - return [NSExpression expressionForFunction:@"mgl_does:have:" arguments:@[operand, key]]; - } else if ([op isEqualToString:@"interpolate"]) { - NSArray *interpolationOptions = argumentObjects.firstObject; - NSString *curveType = interpolationOptions.firstObject; - NSExpression *curveTypeExpression = [NSExpression expressionWithMGLJSONObject:curveType]; - id curveParameters; - if ([curveType isEqual:@"exponential"]) { - curveParameters = interpolationOptions[1]; - } else if ([curveType isEqualToString:@"cubic-bezier"]) { - curveParameters = @[@"literal", [interpolationOptions subarrayWithRange:NSMakeRange(1, 4)]]; - } - else { - curveParameters = [NSNull null]; - } - NSExpression *curveParameterExpression = [NSExpression expressionWithMGLJSONObject:curveParameters]; - argumentObjects = [argumentObjects subarrayWithRange:NSMakeRange(1, argumentObjects.count - 1)]; - NSExpression *inputExpression = [NSExpression expressionWithMGLJSONObject:argumentObjects.firstObject]; - NSArray *stopExpressions = [argumentObjects subarrayWithRange:NSMakeRange(1, argumentObjects.count - 1)]; - NSMutableDictionary *stops = [NSMutableDictionary dictionaryWithCapacity:stopExpressions.count / 2]; - NSEnumerator *stopEnumerator = stopExpressions.objectEnumerator; - while (NSNumber *key = stopEnumerator.nextObject) { - NSExpression *valueExpression = stopEnumerator.nextObject; - stops[key] = [NSExpression expressionWithMGLJSONObject:valueExpression]; - } - NSExpression *stopExpression = [NSExpression expressionForConstantValue:stops]; - return [NSExpression expressionForFunction:@"mgl_interpolate:withCurveType:parameters:stops:" - arguments:@[inputExpression, curveTypeExpression, curveParameterExpression, stopExpression]]; - } else if ([op isEqualToString:@"step"]) { - NSExpression *inputExpression = [NSExpression expressionWithMGLJSONObject:argumentObjects[0]]; - NSArray *stopExpressions = [argumentObjects subarrayWithRange:NSMakeRange(1, argumentObjects.count - 1)]; - NSExpression *minimum; - if (stopExpressions.count % 2) { - minimum = [NSExpression expressionWithMGLJSONObject:stopExpressions.firstObject]; - stopExpressions = [stopExpressions subarrayWithRange:NSMakeRange(1, stopExpressions.count - 1)]; - } - NSMutableDictionary *stops = [NSMutableDictionary dictionaryWithCapacity:stopExpressions.count / 2]; - NSEnumerator *stopEnumerator = stopExpressions.objectEnumerator; - while (NSNumber *key = stopEnumerator.nextObject) { - NSExpression *valueExpression = stopEnumerator.nextObject; - if (minimum) { - stops[key] = [NSExpression expressionWithMGLJSONObject:valueExpression]; - } else { - minimum = [NSExpression expressionWithMGLJSONObject:valueExpression]; - } - } - - NSAssert(minimum, @"minimum should be non-nil"); - if (minimum) { - NSExpression *stopExpression = [NSExpression expressionForConstantValue:stops]; - return [NSExpression expressionForFunction:@"mgl_step:from:stops:" - arguments:@[inputExpression, minimum, stopExpression]]; - } - - } else if ([op isEqualToString:@"zoom"]) { - return NSExpression.zoomLevelVariableExpression; - } else if ([op isEqualToString:@"heatmap-density"]) { - return NSExpression.heatmapDensityVariableExpression; - } else if ([op isEqualToString:@"line-progress"]) { - return NSExpression.lineProgressVariableExpression; - } else if ([op isEqualToString:@"accumulated"]) { - return NSExpression.featureAccumulatedVariableExpression; - } else if ([op isEqualToString:@"geometry-type"]) { - return NSExpression.geometryTypeVariableExpression; - } else if ([op isEqualToString:@"id"]) { - return NSExpression.featureIdentifierVariableExpression; - } else if ([op isEqualToString:@"properties"]) { - return NSExpression.featureAttributesVariableExpression; - } else if ([op isEqualToString:@"var"]) { - return [NSExpression expressionForVariable:argumentObjects.firstObject]; - } else if ([op isEqualToString:@"case"]) { - NSMutableArray *arguments = [NSMutableArray array]; - - for (NSUInteger index = 0; index < argumentObjects.count; index++) { - if (index % 2 == 0 && index != argumentObjects.count - 1) { - NSPredicate *predicate = [NSPredicate predicateWithMGLJSONObject:argumentObjects[index]]; - NSExpression *argument = [NSExpression expressionForConstantValue:predicate]; - [arguments addObject:argument]; - } else { - [arguments addObject:[NSExpression expressionWithMGLJSONObject:argumentObjects[index]]]; - } - } - - if (arguments.count == 3) { - NSPredicate *conditional = [arguments.firstObject constantValue]; - return [NSExpression expressionForConditional:conditional trueExpression:arguments[1] falseExpression:arguments[2]]; - } - return [NSExpression expressionForFunction:@"MGL_IF" arguments:arguments]; - } else if ([op isEqualToString:@"match"]) { - NSMutableArray *optionsArray = [NSMutableArray array]; - - for (NSUInteger index = 0; index < argumentObjects.count; index++) { - NSExpression *option = [NSExpression expressionWithMGLJSONObject:argumentObjects[index]]; - // match operators with arrays as matching values should not parse arrays as generic functions. - if (index > 0 && index < argumentObjects.count - 1 && !(index % 2 == 0) && [argumentObjects[index] isKindOfClass:[NSArray class]]) { - option = [NSExpression expressionForAggregate:MGLSubexpressionsWithJSONObjects(argumentObjects[index])]; - } - [optionsArray addObject:option]; - } - - return [NSExpression expressionForFunction:@"MGL_MATCH" - arguments:optionsArray]; - } else if ([op isEqualToString:@"format"]) { - NSMutableArray *attributedExpressions = [NSMutableArray array]; - - for (NSUInteger index = 0; index < argumentObjects.count; index+=2) { - NSExpression *expression = [NSExpression expressionWithMGLJSONObject:argumentObjects[index]]; - NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; - if ((index + 1) < argumentObjects.count) { - attrs = [NSMutableDictionary dictionaryWithDictionary:argumentObjects[index + 1]]; - } - - for (NSString *key in attrs.allKeys) { - attrs[key] = [NSExpression expressionWithMGLJSONObject:attrs[key]]; - } - MGLAttributedExpression *attributedExpression = [[MGLAttributedExpression alloc] initWithExpression:expression attributes:attrs]; - - [attributedExpressions addObject:[NSExpression expressionForConstantValue:attributedExpression]]; - } - return [NSExpression expressionForFunction:@"mgl_attributed:" arguments:attributedExpressions]; - - } else if ([op isEqualToString:@"coalesce"]) { - NSMutableArray *expressions = [NSMutableArray array]; - for (id operand in argumentObjects) { - [expressions addObject:[NSExpression expressionWithMGLJSONObject:operand]]; - } - - return [NSExpression expressionWithFormat:@"mgl_coalesce(%@)", expressions]; - } else { - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(array); - return [NSExpression expressionForFunction:@"MGL_FUNCTION" arguments:subexpressions]; - } - } - - [NSException raise:NSInvalidArgumentException - format:@"Unable to convert JSON object %@ to an NSExpression.", object]; - - return nil; -} - -- (id)mgl_jsonExpressionObject { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - MGLExpressionOperatorsByFunctionNames = @{ - @"add:to:": @"+", - @"from:subtract:": @"-", - @"multiply:by:": @"*", - @"divide:by:": @"/", - @"modulus:by:": @"%", - @"sqrt:": @"sqrt", - @"log:": @"log10", - @"ln:": @"ln", - @"raise:toPower:": @"^", - @"ceiling:": @"ceil", - @"abs:": @"abs", - @"floor:": @"floor", - @"uppercase:": @"upcase", - @"lowercase:": @"downcase", - @"length:": @"length", - @"mgl_round:": @"round", - @"mgl_acos:" : @"acos", - @"mgl_cos:" : @"cos", - @"mgl_asin:" : @"asin", - @"mgl_sin:" : @"sin", - @"mgl_atan:" : @"atan", - @"mgl_tan:" : @"tan", - @"mgl_log2:" : @"log2", - // Vararg aftermarket expressions need to be declared with an explicit and implicit first argument. - @"MGL_LET": @"let", - @"MGL_LET:": @"let", - }; - }); - - switch (self.expressionType) { - case NSVariableExpressionType: { - if ([self.variable isEqualToString:@"heatmapDensity"]) { - return @[@"heatmap-density"]; - } - if ([self.variable isEqualToString:@"lineProgress"]) { - return @[@"line-progress"]; - } - if ([self.variable isEqualToString:@"zoomLevel"]) { - return @[@"zoom"]; - } - if ([self.variable isEqualToString:@"featureAccumulated"]) { - return @[@"accumulated"]; - } - if ([self.variable isEqualToString:@"geometryType"]) { - return @[@"geometry-type"]; - } - if ([self.variable isEqualToString:@"featureIdentifier"]) { - return @[@"id"]; - } - if ([self.variable isEqualToString:@"featureAttributes"]) { - return @[@"properties"]; - } - return @[@"var", self.variable]; - } - - case NSConstantValueExpressionType: { - id constantValue = self.constantValue; - if (!constantValue || constantValue == [NSNull null]) { - return [NSNull null]; - } - if ([constantValue isEqual:@(M_E)]) { - return @[@"e"]; - } - if ([constantValue isEqual:@(M_PI)]) { - return @[@"pi"]; - } - if ([constantValue isKindOfClass:[NSArray class]] || - [constantValue isKindOfClass:[NSDictionary class]]) { - NSArray *collection = [constantValue mgl_jsonExpressionObject]; - return @[@"literal", collection]; - } - if ([constantValue isKindOfClass:[MGLColor class]]) { - auto color = [constantValue mgl_color]; - if (color.a == 1) { - return @[@"rgb", @(color.r * 255), @(color.g * 255), @(color.b * 255)]; - } - return @[@"rgba", @(color.r * 255), @(color.g * 255), @(color.b * 255), @(color.a)]; - } - if ([constantValue isKindOfClass:[NSValue class]]) { - const auto boxedValue = (NSValue *)constantValue; - if (strcmp([boxedValue objCType], @encode(CGVector)) == 0) { - // offset [x, y] - std::array<float, 2> mglValue = boxedValue.mgl_offsetArrayValue; - return @[@"literal", @[@(mglValue[0]), @(mglValue[1])]]; - } - if (strcmp([boxedValue objCType], @encode(MGLEdgeInsets)) == 0) { - // padding [x, y] - std::array<float, 4> mglValue = boxedValue.mgl_paddingArrayValue; - return @[@"literal", @[@(mglValue[0]), @(mglValue[1]), @(mglValue[2]), @(mglValue[3])]]; - } - } - if ([constantValue isKindOfClass:[MGLAttributedExpression class]]) { - MGLAttributedExpression *attributedExpression = (MGLAttributedExpression *)constantValue; - id jsonObject = attributedExpression.expression.mgl_jsonExpressionObject; - NSMutableDictionary<MGLAttributedExpressionKey, NSExpression *> *attributedDictionary = [NSMutableDictionary dictionary]; - - if (attributedExpression.attributes) { - attributedDictionary = [NSMutableDictionary dictionaryWithDictionary:attributedExpression.attributes]; - - for (NSString *key in attributedExpression.attributes.allKeys) { - attributedDictionary[key] = attributedExpression.attributes[key].mgl_jsonExpressionObject; - } - - } - return @[jsonObject, attributedDictionary]; - } - return self.constantValue; - } - - case NSKeyPathExpressionType: { - NSArray *expressionObject; - NSArray *keyPath = [self.keyPath componentsSeparatedByString:@"."]; - for (NSString *pathComponent in keyPath) { - if (expressionObject) { - expressionObject = @[@"get", pathComponent, expressionObject]; - } else { - expressionObject = @[@"get", pathComponent]; - } - } - - NSAssert(expressionObject.count > 0, @"expressionObject should be non-empty"); - - // Return a non-null value to quieten static analysis - return expressionObject ?: @[]; - } - - case NSFunctionExpressionType: { - NSString *function = self.function; - - BOOL hasCollectionProperty = !( ! [self.arguments.firstObject isKindOfClass: [NSExpression class]] || self.arguments.firstObject.expressionType != NSAggregateExpressionType || self.arguments.firstObject.expressionType == NSSubqueryExpressionType); - NSString *op = MGLExpressionOperatorsByFunctionNames[function]; - if (op) { - NSArray *arguments = self.arguments.mgl_jsonExpressionObject; - return [@[op] arrayByAddingObjectsFromArray:arguments]; - } else if ([function isEqualToString:@"valueForKey:"] || [function isEqualToString:@"valueForKeyPath:"]) { - return @[@"get", self.arguments.firstObject.mgl_jsonExpressionObject, self.operand.mgl_jsonExpressionObject]; - } else if ([function isEqualToString:@"average:"]) { - NSExpression *sum = [NSExpression expressionForFunction:@"sum:" arguments:self.arguments]; - NSExpression *count = [NSExpression expressionForFunction:@"count:" arguments:self.arguments]; - return [NSExpression expressionForFunction:@"divide:by:" arguments:@[sum, count]].mgl_jsonExpressionObject; - } else if ([function isEqualToString:@"sum:"]) { - NSArray *arguments; - if (hasCollectionProperty) { - arguments = [self.arguments.firstObject.collection valueForKeyPath:@"mgl_jsonExpressionObject"]; - } else { - arguments = [self.arguments valueForKeyPath:@"mgl_jsonExpressionObject"]; - } - return [@[@"+"] arrayByAddingObjectsFromArray:arguments]; - } else if ([function isEqualToString:@"count:"]) { - NSArray *arguments = self.arguments.firstObject.mgl_jsonExpressionObject; - return @[@"length", arguments]; - } else if ([function isEqualToString:@"min:"]) { - NSArray *arguments; - if (!hasCollectionProperty) { - arguments = [self.arguments valueForKeyPath:@"mgl_jsonExpressionObject"]; - } else { - arguments = [self.arguments.firstObject.collection valueForKeyPath:@"mgl_jsonExpressionObject"]; - } - return [@[@"min"] arrayByAddingObjectsFromArray:arguments]; - } else if ([function isEqualToString:@"max:"]) { - NSArray *arguments; - if (!hasCollectionProperty) { - arguments = [self.arguments valueForKeyPath:@"mgl_jsonExpressionObject"]; - } else { - arguments = [self.arguments.firstObject.collection valueForKeyPath:@"mgl_jsonExpressionObject"]; - } - return [@[@"max"] arrayByAddingObjectsFromArray:arguments]; - } else if ([function isEqualToString:@"exp:"]) { - return [NSExpression expressionForFunction:@"raise:toPower:" arguments:@[@(M_E), self.arguments.firstObject]].mgl_jsonExpressionObject; - } else if ([function isEqualToString:@"trunc:"]) { - return [NSExpression expressionWithFormat:@"%@ - modulus:by:(%@, 1)", - self.arguments.firstObject, self.arguments.firstObject].mgl_jsonExpressionObject; - } else if ([function isEqualToString:@"mgl_join:"]) { - NSArray *arguments; - if (!hasCollectionProperty) { - arguments = [self.arguments valueForKeyPath:@"mgl_jsonExpressionObject"]; - } else { - arguments = [self.arguments.firstObject.collection valueForKeyPath:@"mgl_jsonExpressionObject"]; - } - return [@[@"concat"] arrayByAddingObjectsFromArray:arguments]; - } else if ([function isEqualToString:@"stringByAppendingString:"]) { - NSArray *arguments = self.arguments.mgl_jsonExpressionObject; - return [@[@"concat", self.operand.mgl_jsonExpressionObject] arrayByAddingObjectsFromArray:arguments]; - } else if ([function isEqualToString:@"objectFrom:withIndex:"]) { - id index = self.arguments[1].mgl_jsonExpressionObject; - - if ([self.arguments[1] expressionType] == NSConstantValueExpressionType - && [[self.arguments[1] constantValue] isKindOfClass:[NSString class]]) { - id value = self.arguments[1].constantValue; - - if ([value isEqualToString:@"FIRST"]) { - index = [NSExpression expressionForConstantValue:@0].mgl_jsonExpressionObject; - } else if ([value isEqualToString:@"LAST"]) { - index = [NSExpression expressionWithFormat:@"count(%@) - 1", self.arguments[0]].mgl_jsonExpressionObject; - } else if ([value isEqualToString:@"SIZE"]) { - return [NSExpression expressionWithFormat:@"count(%@)", self.arguments[0]].mgl_jsonExpressionObject; - } - } - - return @[@"at", index, self.arguments[0].mgl_jsonExpressionObject]; - } else if ([function isEqualToString:@"boolValue"]) { - return @[@"to-boolean", self.operand.mgl_jsonExpressionObject]; - } else if ([function isEqualToString:@"mgl_number"] || - [function isEqualToString:@"mgl_numberWithFallbackValues:"] || - [function isEqualToString:@"decimalValue"] || - [function isEqualToString:@"floatValue"] || - [function isEqualToString:@"doubleValue"]) { - NSArray *arguments = self.arguments.mgl_jsonExpressionObject; - return [@[@"to-number", self.operand.mgl_jsonExpressionObject] arrayByAddingObjectsFromArray:arguments]; - } else if ([function isEqualToString:@"stringValue"]) { - return @[@"to-string", self.operand.mgl_jsonExpressionObject]; - } else if ([function isEqualToString:@"noindex:"]) { - return self.arguments.firstObject.mgl_jsonExpressionObject; - } else if ([function isEqualToString:@"mgl_does:have:"] || - [function isEqualToString:@"mgl_has:"]) { - return self.mgl_jsonHasExpressionObject; - } else if ([function isEqualToString:@"mgl_interpolate:withCurveType:parameters:stops:"] - || [function isEqualToString:@"mgl_interpolateWithCurveType:parameters:stops:"]) { - return self.mgl_jsonInterpolationExpressionObject; - } else if ([function isEqualToString:@"mgl_step:from:stops:"] - || [function isEqualToString:@"mgl_stepWithMinimum:stops:"]) { - return self.mgl_jsonStepExpressionObject; - } else if ([function isEqualToString:@"mgl_expressionWithContext:"]) { - id context = self.arguments.firstObject; - if ([context isKindOfClass:[NSExpression class]]) { - context = [context constantValue]; - } - NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"let", nil]; - [context enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, NSExpression * _Nonnull obj, BOOL * _Nonnull stop) { - [expressionObject addObject:key]; - [expressionObject addObject:obj.mgl_jsonExpressionObject]; - }]; - [expressionObject addObject:self.operand.mgl_jsonExpressionObject]; - return expressionObject; - } else if ([function isEqualToString:@"MGL_IF"] || - [function isEqualToString:@"MGL_IF:"] || - [function isEqualToString:@"mgl_if:"]) { - return self.mgl_jsonIfExpressionObject; - } else if ([function isEqualToString:@"MGL_MATCH"] || - [function isEqualToString:@"MGL_MATCH:"] || - [function isEqualToString:@"mgl_match:"]) { - return self.mgl_jsonMatchExpressionObject; - } else if ([function isEqualToString:@"mgl_coalesce:"] || - [function isEqualToString:@"mgl_coalesce"]) { - - return self.mgl_jsonCoalesceExpressionObject; - } else if ([function isEqualToString:@"castObject:toType:"]) { - id object = self.arguments.firstObject.mgl_jsonExpressionObject; - NSString *type = self.arguments[1].mgl_jsonExpressionObject; - if ([type isEqualToString:@"NSString"]) { - return @[@"to-string", object]; - } else if ([type isEqualToString:@"NSNumber"]) { - return @[@"to-number", object]; - } -#if TARGET_OS_IPHONE - else if ([type isEqualToString:@"UIColor"] || [type isEqualToString:@"MGLColor"]) { - return @[@"to-color", object]; - } -#else - else if ([type isEqualToString:@"NSColor"] || [type isEqualToString:@"MGLColor"]) { - return @[@"to-color", object]; - } -#endif - else if ([type isEqualToString:@"NSArray"]) { - NSExpression *operand = self.arguments.firstObject; - if ([operand expressionType] == NSFunctionExpressionType ) { - operand = self.arguments.firstObject.arguments.firstObject; - } - if (([operand expressionType] != NSConstantValueExpressionType) || - ([operand expressionType] == NSConstantValueExpressionType && - [[operand constantValue] isKindOfClass:[MGLColor class]])) { - return @[@"to-rgba", object]; - } - } - [NSException raise:NSInvalidArgumentException - format:@"Casting expression to %@ not yet implemented.", type]; - } else if ([function isEqualToString:@"mgl_attributed:"]) { - return [self mgl_jsonFormatExpressionObject]; - - } else if ([function isEqualToString:@"MGL_FUNCTION"] || - [function isEqualToString:@"MGL_FUNCTION:"]) { - NSExpression *firstOp = self.arguments.firstObject; - if (firstOp.expressionType == NSConstantValueExpressionType - && [firstOp.constantValue isEqualToString:@"collator"]) { - // Avoid wrapping collator options object in literal expression. - return @[@"collator", self.arguments[1].constantValue]; - } - if (firstOp.expressionType == NSConstantValueExpressionType - && [firstOp.constantValue isEqualToString:@"format"]) { - // Avoid wrapping format options object in literal expression. - NSMutableArray *expressionObject = [NSMutableArray array]; - [expressionObject addObject:@"format"]; - - for (NSUInteger index = 1; index < self.arguments.count; index++) { - if (index % 2 == 1) { - [expressionObject addObject:self.arguments[index].mgl_jsonExpressionObject]; - } else { - [expressionObject addObject:self.arguments[index].constantValue]; - } - - } - - return expressionObject; - } - - return self.arguments.mgl_jsonExpressionObject; - } else if (op == [MGLColor class] && [function isEqualToString:@"colorWithRed:green:blue:alpha:"]) { - NSArray *arguments = self.arguments.mgl_jsonExpressionObject; - return [@[@"rgba"] arrayByAddingObjectsFromArray:arguments]; - } else if ([function isEqualToString:@"median:"] || - [function isEqualToString:@"mode:"] || - [function isEqualToString:@"stddev:"] || - [function isEqualToString:@"random"] || - [function isEqualToString:@"randomn:"] || - [function isEqualToString:@"now"] || - [function isEqualToString:@"bitwiseAnd:with:"] || - [function isEqualToString:@"bitwiseOr:with:"] || - [function isEqualToString:@"bitwiseXor:with:"] || - [function isEqualToString:@"leftshift:by:"] || - [function isEqualToString:@"rightshift:by:"] || - [function isEqualToString:@"onesComplement:"] || - [function isEqualToString:@"distanceToLocation:fromLocation:"]) { - [NSException raise:NSInvalidArgumentException - format:@"Expression function %@ not yet implemented.", function]; - return nil; - } else { - [NSException raise:NSInvalidArgumentException - format:@"Unrecognized expression function %@.", function]; - return nil; - } - } - - case NSConditionalExpressionType: { - NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"case", self.predicate.mgl_jsonExpressionObject, nil]; - [arguments addObject:self.trueExpression.mgl_jsonExpressionObject]; - [arguments addObject:self.falseExpression.mgl_jsonExpressionObject]; - - return arguments; - } - - case NSAggregateExpressionType: { - NSArray *collection = [self.collection valueForKeyPath:@"mgl_jsonExpressionObject"]; - return @[@"literal", collection]; - } - - case NSEvaluatedObjectExpressionType: - case NSUnionSetExpressionType: - case NSIntersectSetExpressionType: - case NSMinusSetExpressionType: - case NSSubqueryExpressionType: - case NSAnyKeyExpressionType: - case NSBlockExpressionType: - [NSException raise:NSInvalidArgumentException - format:@"Expression type %lu not yet implemented.", (unsigned long)self.expressionType]; - } - - // NSKeyPathSpecifierExpression - if (self.expressionType == 10) { - return self.description; - } - // An assignment expression type is present in the BNF grammar, but the - // corresponding NSExpressionType value and property getters are missing. - if (self.expressionType == 12) { - [NSException raise:NSInvalidArgumentException - format:@"Assignment expressions not yet implemented."]; - } - - return nil; -} - -- (id)mgl_jsonInterpolationExpressionObject { - NSUInteger expectedArgumentCount = [self.function componentsSeparatedByString:@":"].count - 1; - if (self.arguments.count < expectedArgumentCount) { - [NSException raise:NSInvalidArgumentException format: - @"Too few arguments to ‘%@’ function; expected %lu arguments.", - self.function, (unsigned long)expectedArgumentCount]; - } else if (self.arguments.count > expectedArgumentCount) { - [NSException raise:NSInvalidArgumentException format: - @"%lu unexpected arguments to ‘%@’ function; expected %lu arguments.", - self.arguments.count - (unsigned long)expectedArgumentCount, self.function, (unsigned long)expectedArgumentCount]; - } - - BOOL isAftermarketFunction = [self.function isEqualToString:@"mgl_interpolate:withCurveType:parameters:stops:"]; - NSUInteger curveTypeIndex = isAftermarketFunction ? 1 : 0; - NSString *curveType = self.arguments[curveTypeIndex].constantValue; - NSMutableArray *interpolationArray = [NSMutableArray arrayWithObject:curveType]; - if ([curveType isEqualToString:@"exponential"]) { - id base = [self.arguments[curveTypeIndex + 1] mgl_jsonExpressionObject]; - [interpolationArray addObject:base]; - } else if ([curveType isEqualToString:@"cubic-bezier"]) { - NSArray *controlPoints = [self.arguments[curveTypeIndex + 1].collection mgl_jsonExpressionObject]; - [interpolationArray addObjectsFromArray:controlPoints]; - } - - NSDictionary<NSNumber *, NSExpression *> *stops = self.arguments[curveTypeIndex + 2].constantValue; - - if (stops.count == 0) { - [NSException raise:NSInvalidArgumentException format:@"‘stops’ dictionary argument to ‘%@’ function must not be empty.", self.function]; - } - - NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"interpolate", interpolationArray, nil]; - [expressionObject addObject:(isAftermarketFunction ? self.arguments.firstObject : self.operand).mgl_jsonExpressionObject]; - for (NSNumber *key in [stops.allKeys sortedArrayUsingSelector:@selector(compare:)]) { - [expressionObject addObject:key]; - [expressionObject addObject:[stops[key] mgl_jsonExpressionObject]]; - } - return expressionObject; -} - -- (id)mgl_jsonStepExpressionObject { - BOOL isAftermarketFunction = [self.function isEqualToString:@"mgl_step:from:stops:"]; - NSUInteger minimumIndex = isAftermarketFunction ? 1 : 0; - id minimum = self.arguments[minimumIndex].mgl_jsonExpressionObject; - NSDictionary<NSNumber *, NSExpression *> *stops = self.arguments[minimumIndex + 1].constantValue; - - if (stops.count == 0) { - [NSException raise:NSInvalidArgumentException format:@"‘stops’ dictionary argument to ‘%@’ function must not be empty.", self.function]; - } - - NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"step", (isAftermarketFunction ? self.arguments.firstObject : self.operand).mgl_jsonExpressionObject, minimum, nil]; - - for (NSNumber *key in [stops.allKeys sortedArrayUsingSelector:@selector(compare:)]) { - [expressionObject addObject:key]; - [expressionObject addObject:[stops[key] mgl_jsonExpressionObject]]; - } - return expressionObject; -} - -- (id)mgl_jsonMatchExpressionObject { - BOOL isAftermarketFunction = [self.function hasPrefix:@"MGL_MATCH"]; - NSUInteger minimumIndex = isAftermarketFunction ? 1 : 0; - - NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"match", (isAftermarketFunction ? self.arguments.firstObject : self.operand).mgl_jsonExpressionObject, nil]; - NSArray<NSExpression *> *arguments = isAftermarketFunction ? self.arguments : self.arguments[minimumIndex].constantValue; - - for (NSUInteger index = minimumIndex; index < arguments.count; index++) { - NSArray *argumentObject = arguments[index].mgl_jsonExpressionObject; - // match operators with arrays as matching values should not parse arrays using the literal operator. - if (index > 0 && index < arguments.count - 1 && !(index % 2 == 0)) { - NSExpression *expression = arguments[index]; - if (![expression isKindOfClass:[NSExpression class]]) { - expression = [NSExpression expressionForConstantValue:expression]; - } - if (expression.expressionType == NSAggregateExpressionType || - (expression.expressionType == NSConstantValueExpressionType && [expression.constantValue isKindOfClass:[NSArray class]])) { - argumentObject = argumentObject.count == 2 ? argumentObject[1] : argumentObject; - } - } - [expressionObject addObject:argumentObject]; - } - - return expressionObject; -} - -- (id)mgl_jsonIfExpressionObject { - BOOL isAftermarketFunction = [self.function hasPrefix:@"MGL_IF"]; - NSUInteger minimumIndex = isAftermarketFunction ? 1 : 0; - NSExpression *firstCondition; - id condition; - - if (isAftermarketFunction) { - firstCondition = self.arguments.firstObject; - } else { - firstCondition = self.operand; - } - - if ([firstCondition respondsToSelector:@selector(constantValue)] && [firstCondition.constantValue isKindOfClass:[NSComparisonPredicate class]]) { - NSPredicate *predicate = (NSPredicate *)firstCondition.constantValue; - condition = predicate.mgl_jsonExpressionObject; - } else { - condition = firstCondition.mgl_jsonExpressionObject; - } - - NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"case", condition, nil]; - NSArray<NSExpression *> *arguments = isAftermarketFunction ? self.arguments : self.arguments[minimumIndex].constantValue; - - for (NSUInteger index = minimumIndex; index < arguments.count; index++) { - if ([arguments[index] respondsToSelector:@selector(constantValue)] && [arguments[index].constantValue isKindOfClass:[NSComparisonPredicate class]]) { - NSPredicate *predicate = (NSPredicate *)arguments[index].constantValue; - [expressionObject addObject:predicate.mgl_jsonExpressionObject]; - } else { - [expressionObject addObject:arguments[index].mgl_jsonExpressionObject]; - } - } - - return expressionObject; -} - -- (id)mgl_jsonCoalesceExpressionObject { - BOOL isAftermarketFunction = [self.function isEqualToString:@"mgl_coalesce:"]; - NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"coalesce", nil]; - - for (NSExpression *expression in (isAftermarketFunction ? self.arguments.firstObject : self.operand).constantValue) { - [expressionObject addObject:[expression mgl_jsonExpressionObject]]; - } - - return expressionObject; -} - -- (id)mgl_jsonHasExpressionObject { - BOOL isAftermarketFunction = [self.function isEqualToString:@"mgl_does:have:"]; - NSExpression *operand = isAftermarketFunction ? self.arguments[0] : self.operand; - NSExpression *key = self.arguments[isAftermarketFunction ? 1 : 0]; - - NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"has", key.mgl_jsonExpressionObject, nil]; - if (operand.expressionType != NSEvaluatedObjectExpressionType) { - [expressionObject addObject:operand.mgl_jsonExpressionObject]; - } - return expressionObject; -} - -- (id)mgl_jsonFormatExpressionObject { - NSArray<NSExpression *> *attributedExpressions; - NSExpression *formatArray = self.arguments.firstObject; - - if ([formatArray respondsToSelector:@selector(constantValue)] && [formatArray.constantValue isKindOfClass:[NSArray class]]) { - attributedExpressions = (NSArray *)formatArray.constantValue; - } else { - attributedExpressions = self.arguments; - } - - NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"format", nil]; - - for (NSUInteger index = 0; index < attributedExpressions.count; index++) { - [expressionObject addObjectsFromArray:attributedExpressions[index].mgl_jsonExpressionObject]; - } - - return expressionObject; -} - -#pragma mark Localization - -/** - Returns a localized copy of the given collection. - - If no localization takes place, this method returns the original collection. - */ -NSArray<NSExpression *> *MGLLocalizedCollection(NSArray<NSExpression *> *collection, NSLocale * _Nullable locale) { - __block NSMutableArray *localizedCollection; - [collection enumerateObjectsUsingBlock:^(NSExpression * _Nonnull item, NSUInteger idx, BOOL * _Nonnull stop) { - NSExpression *localizedItem = [item mgl_expressionLocalizedIntoLocale:locale]; - if (localizedItem != item) { - if (!localizedCollection) { - localizedCollection = [collection mutableCopy]; - } - localizedCollection[idx] = localizedItem; - } - }]; - return localizedCollection ?: collection; -}; - -/** - Returns a localized copy of the given stop dictionary. - - If no localization takes place, this method returns the original stop - dictionary. - */ -NSDictionary<NSNumber *, NSExpression *> *MGLLocalizedStopDictionary(NSDictionary<NSNumber *, NSExpression *> *stops, NSLocale * _Nullable locale) { - __block NSMutableDictionary *localizedStops; - [stops enumerateKeysAndObjectsUsingBlock:^(id _Nonnull zoomLevel, NSExpression * _Nonnull value, BOOL * _Nonnull stop) { - if (![value isKindOfClass:[NSExpression class]]) { - value = [NSExpression expressionForConstantValue:value]; - } - NSExpression *localizedValue = [value mgl_expressionLocalizedIntoLocale:locale]; - if (localizedValue != value) { - if (!localizedStops) { - localizedStops = [stops mutableCopy]; - } - localizedStops[zoomLevel] = localizedValue; - } - }]; - return localizedStops ?: stops; -}; - -- (NSExpression *)mgl_expressionLocalizedIntoLocale:(nullable NSLocale *)locale { - switch (self.expressionType) { - case NSConstantValueExpressionType: { - if ([self.constantValue isKindOfClass:[NSDictionary class]]) { - NSDictionary *localizedStops = MGLLocalizedStopDictionary(self.constantValue, locale); - if (localizedStops != self.constantValue) { - return [NSExpression expressionForConstantValue:localizedStops]; - } - } else if ([self.constantValue isKindOfClass:[NSArray class]]) { - NSArray *localizedValues = MGLLocalizedCollection(self.constantValue, locale); - if (localizedValues != self.constantValue) { - return [NSExpression expressionForConstantValue:localizedValues]; - } - } else if ([self.constantValue isKindOfClass:[MGLAttributedExpression class]]) { - MGLAttributedExpression *attributedExpression = (MGLAttributedExpression *)self.constantValue; - NSExpression *localizedExpression = [attributedExpression.expression mgl_expressionLocalizedIntoLocale:locale]; - MGLAttributedExpression *localizedAttributedExpression = [MGLAttributedExpression attributedExpression:localizedExpression attributes:attributedExpression.attributes]; - - return [NSExpression expressionForConstantValue:localizedAttributedExpression]; - } - return self; - } - - case NSKeyPathExpressionType: { - if ([self.keyPath isEqualToString:@"name"] || [self.keyPath hasPrefix:@"name_"]) { - NSString *localizedKeyPath = @"name"; - if (![locale.localeIdentifier isEqualToString:@"mul"]) { - NSArray *preferences = locale ? @[locale.localeIdentifier] : [NSLocale preferredLanguages]; - NSString *preferredLanguage = [MGLVectorTileSource preferredMapboxStreetsLanguageForPreferences:preferences]; - if (preferredLanguage) { - localizedKeyPath = [NSString stringWithFormat:@"name_%@", preferredLanguage]; - } - } - // If the keypath is `name`, no need to fallback - if ([localizedKeyPath isEqualToString:@"name"]) { - return [NSExpression expressionForKeyPath:localizedKeyPath]; - } - // If the keypath is `name_zh-Hans`, fallback to `name_zh` to `name`. - // CN tiles might using `name_zh-CN` for Simplified Chinese. - if ([localizedKeyPath isEqualToString:@"name_zh-Hans"]) { - return [NSExpression expressionWithFormat:@"mgl_coalesce({%K, %K, %K, %K})", - localizedKeyPath, @"name_zh-CN", @"name_zh", @"name"]; - } - // Mapbox Streets v8 has `name_zh-Hant`, we should fallback to Simplified Chinese if the field has no value. - if ([localizedKeyPath isEqualToString:@"name_zh-Hant"]) { - return [NSExpression expressionWithFormat:@"mgl_coalesce({%K, %K, %K, %K, %K})", - localizedKeyPath, @"name_zh-Hans", @"name_zh-CN", @"name_zh", @"name"]; - } - - // Other keypath fallback to `name` - return [NSExpression expressionWithFormat:@"mgl_coalesce({%K, %K})", localizedKeyPath, @"name"]; - } - return self; - } - - case NSFunctionExpressionType: { - NSExpression *operand = self.operand; - NSExpression *localizedOperand = [operand mgl_expressionLocalizedIntoLocale:locale]; - - NSArray *arguments = self.arguments; - NSArray *localizedArguments = MGLLocalizedCollection(arguments, locale); - if (localizedArguments != arguments) { - return [NSExpression expressionForFunction:localizedOperand - selectorName:self.function - arguments:localizedArguments]; - } - if (localizedOperand != operand) { - return [NSExpression expressionForFunction:localizedOperand - selectorName:self.function - arguments:self.arguments]; - } - return self; - } - - case NSConditionalExpressionType: { - NSExpression *trueExpression = self.trueExpression; - NSExpression *localizedTrueExpression = [trueExpression mgl_expressionLocalizedIntoLocale:locale]; - NSExpression *falseExpression = self.falseExpression; - NSExpression *localizedFalseExpression = [falseExpression mgl_expressionLocalizedIntoLocale:locale]; - if (localizedTrueExpression != trueExpression || localizedFalseExpression != falseExpression) { - return [NSExpression expressionForConditional:self.predicate - trueExpression:localizedTrueExpression - falseExpression:localizedFalseExpression]; - } - return self; - } - - case NSAggregateExpressionType: { - NSArray *collection = self.collection; - if ([collection isKindOfClass:[NSArray class]]) { - NSArray *localizedCollection = MGLLocalizedCollection(collection, locale); - if (localizedCollection != collection) { - return [NSExpression expressionForAggregate:localizedCollection]; - } - } - return self; - } - - default: - return self; - } -} - -@end diff --git a/platform/darwin/src/NSExpression+MGLPrivateAdditions.h b/platform/darwin/src/NSExpression+MGLPrivateAdditions.h deleted file mode 100644 index 54bc9068f4..0000000000 --- a/platform/darwin/src/NSExpression+MGLPrivateAdditions.h +++ /dev/null @@ -1,84 +0,0 @@ -#import <Foundation/Foundation.h> -#if TARGET_OS_IPHONE - #import <UIKit/UIKit.h> -#else - #import <Cocoa/Cocoa.h> -#endif - -#import "NSExpression+MGLAdditions.h" - -#include <mbgl/style/filter.hpp> - -NS_ASSUME_NONNULL_BEGIN - -@interface NSObject (MGLExpressionAdditions) - -- (nullable NSNumber *)mgl_number; -- (nullable NSNumber *)mgl_numberWithFallbackValues:(id)fallbackValue, ... NS_REQUIRES_NIL_TERMINATION; - -@end - -@interface NSExpression (MGLPrivateAdditions) - -@property (nonatomic, readonly) mbgl::Value mgl_constantMBGLValue; -@property (nonatomic, readonly) std::vector<mbgl::Value> mgl_aggregateMBGLValue; -@property (nonatomic, readonly) mbgl::FeatureType mgl_featureType; -@property (nonatomic, readonly) std::vector<mbgl::FeatureType> mgl_aggregateFeatureType; -@property (nonatomic, readonly) mbgl::FeatureIdentifier mgl_featureIdentifier; -@property (nonatomic, readonly) std::vector<mbgl::FeatureIdentifier> mgl_aggregateFeatureIdentifier; - -@end - -@interface NSNull (MGLExpressionAdditions) - -@property (nonatomic, readonly) id mgl_jsonExpressionObject; - -@end - -@interface NSString (MGLExpressionAdditions) - -@property (nonatomic, readonly) id mgl_jsonExpressionObject; - -@end - -@interface NSNumber (MGLExpressionAdditions) - -- (id)mgl_interpolateWithCurveType:(NSString *)curveType parameters:(NSArray *)parameters stops:(NSDictionary<NSNumber *, id> *)stops; -- (id)mgl_stepWithMinimum:(id)minimum stops:(NSDictionary<NSNumber *, id> *)stops; - -@property (nonatomic, readonly) id mgl_jsonExpressionObject; - -@end - -@interface NSArray (MGLExpressionAdditions) - -@property (nonatomic, readonly) id mgl_jsonExpressionObject; - -@end - -@interface NSDictionary (MGLExpressionAdditions) - -@property (nonatomic, readonly) id mgl_jsonExpressionObject; - -- (id)mgl_has:(id)element; - -@end - -@interface MGLColor (MGLExpressionAdditions) - -@property (nonatomic, readonly) id mgl_jsonExpressionObject; - -@end - -@interface NSExpression (MGLExpressionAdditions) - -- (NSExpression *)mgl_expressionWithContext:(NSDictionary<NSString *, NSExpression *> *)context; - - -- (id)mgl_has:(id)element; - -@end - -FOUNDATION_EXTERN NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects); - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.h b/platform/darwin/src/NSPredicate+MGLAdditions.h deleted file mode 100644 index 6c4b878d37..0000000000 --- a/platform/darwin/src/NSPredicate+MGLAdditions.h +++ /dev/null @@ -1,44 +0,0 @@ -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -@interface NSPredicate (MGLAdditions) - -#pragma mark Converting JSON Expressions - -/** - Returns a predicate equivalent to the given Foundation object deserialized - from JSON data. - - The Foundation object is interpreted according to the - [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions). - See the - “[Predicates and Expressions](../predicates-and-expressions.html)” - guide for a correspondence of operators and types between the style - specification and the `NSPredicate` representation used by this SDK. - - @param object A Foundation object deserialized from JSON data, for example - using `NSJSONSerialization`. - @return An initialized predicate equivalent to `object`, suitable for use - with the `MGLVectorStyleLayer.predicate` property. - */ -+ (instancetype)predicateWithMGLJSONObject:(id)object NS_SWIFT_NAME(init(mglJSONObject:)); - -/** - An equivalent Foundation object that can be serialized as JSON. - - The Foundation object conforms to the - [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions). - See the - “[Predicates and Expressions](../predicates-and-expressions.html)” - guide for a correspondence of operators and types between the style - specification and the `NSPredicate` representation used by this SDK. - - You can use `NSJSONSerialization` to serialize the Foundation object as data to - write to a file. - */ -@property (nonatomic, readonly) id mgl_jsonExpressionObject; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.mm b/platform/darwin/src/NSPredicate+MGLAdditions.mm deleted file mode 100644 index 436402c9e0..0000000000 --- a/platform/darwin/src/NSPredicate+MGLAdditions.mm +++ /dev/null @@ -1,220 +0,0 @@ -#import "NSPredicate+MGLPrivateAdditions.h" - -#import "MGLValueEvaluator.h" -#import "MGLStyleValue_Private.h" -#import "MGLLoggingConfiguration_Private.h" - -#include <mbgl/style/conversion/filter.hpp> - -@implementation NSPredicate (MGLPrivateAdditions) - -- (mbgl::style::Filter)mgl_filter -{ - mbgl::style::conversion::Error valueError; - NSArray *jsonObject = self.mgl_jsonExpressionObject; - auto value = mbgl::style::conversion::convert<mbgl::style::Filter>(mbgl::style::conversion::makeConvertible(jsonObject), valueError); - - if (!value) { - [NSException raise:NSInvalidArgumentException - format:@"Invalid filter value: %@", @(valueError.message.c_str())]; - return {}; - } - mbgl::style::Filter filter = std::move(*value); - - return filter; -} - -+ (instancetype)mgl_predicateWithFilter:(mbgl::style::Filter)filter -{ - if (filter.expression) { - id jsonObject = MGLJSONObjectFromMBGLExpression(**filter.expression); - return [NSPredicate predicateWithMGLJSONObject:jsonObject]; - } else { - return nil; - } -} - -@end - -@implementation NSPredicate (MGLAdditions) - -NSArray *MGLSubpredicatesWithJSONObjects(NSArray *objects) { - NSMutableArray *subpredicates = [NSMutableArray arrayWithCapacity:objects.count]; - for (id object in objects) { - NSPredicate *predicate = [NSPredicate predicateWithMGLJSONObject:object]; - [subpredicates addObject:predicate]; - } - return subpredicates; -} - -static NSDictionary * const MGLPredicateOperatorTypesByJSONOperator = @{ - @"==": @(NSEqualToPredicateOperatorType), - @"!=": @(NSNotEqualToPredicateOperatorType), - @"<": @(NSLessThanPredicateOperatorType), - @"<=": @(NSLessThanOrEqualToPredicateOperatorType), - @">": @(NSGreaterThanPredicateOperatorType), - @">=": @(NSGreaterThanOrEqualToPredicateOperatorType), -}; - -+ (instancetype)predicateWithMGLJSONObject:(id)object { - if ([object isEqual:@YES]) { - return [NSPredicate predicateWithValue:YES]; - } - if ([object isEqual:@NO]) { - return [NSPredicate predicateWithValue:NO]; - } - - MGLAssert([object isKindOfClass:[NSArray class]], @"Condition for case expression should be an expression."); - NSArray *objects = (NSArray *)object; - NSString *op = objects.firstObject; - - NSNumber *operatorTypeNumber = MGLPredicateOperatorTypesByJSONOperator[op]; - if (operatorTypeNumber) { - NSPredicateOperatorType operatorType = (NSPredicateOperatorType)[operatorTypeNumber unsignedIntegerValue]; - - NSComparisonPredicateOptions options = 0; - if (objects.count > 3) { - NSArray *collatorExpression = objects[3]; - MGLCAssert([collatorExpression isKindOfClass:[NSArray class]], @"Collators must be dictionaries."); - MGLCAssert(collatorExpression.count == 2, @"Malformed collator expression"); - NSDictionary *collator = collatorExpression[1]; - MGLCAssert([collator isKindOfClass:[NSDictionary class]], @"Malformed collator in collator expression"); - - // Predicate options can’t express specific locales as collators can. - if (!collator[@"locale"]) { - if ([(collator[@"case-sensitive"] ?: @YES) isEqual:@NO]) { - options |= NSCaseInsensitivePredicateOption; - } - if ([(collator[@"diacritic-sensitive"] ?: @YES) isEqual:@NO]) { - options |= NSDiacriticInsensitivePredicateOption; - } - } - } - - NSArray *subexpressions = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]); - return [NSComparisonPredicate predicateWithLeftExpression:subexpressions[0] - rightExpression:subexpressions[1] - modifier:NSDirectPredicateModifier - type:operatorType - options:options]; - } - - if ([op isEqualToString:@"!"]) { - NSArray *subpredicates = MGLSubpredicatesWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]); - if (subpredicates.count > 1) { - NSCompoundPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subpredicates]; - return [NSCompoundPredicate notPredicateWithSubpredicate:predicate]; - } - if (subpredicates.count) { - return [NSCompoundPredicate notPredicateWithSubpredicate:subpredicates.firstObject]; - } - return [NSPredicate predicateWithValue:YES]; - } - if ([op isEqualToString:@"all"]) { - NSArray<NSPredicate *> *subpredicates = MGLSubpredicatesWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]); - if (subpredicates.count == 2) { - // Determine if the expression is of BETWEEN type - if ([subpredicates[0] isKindOfClass:[NSComparisonPredicate class]] && - [subpredicates[1] isKindOfClass:[NSComparisonPredicate class]]) { - NSComparisonPredicate *leftCondition = (NSComparisonPredicate *)subpredicates[0]; - NSComparisonPredicate *rightCondition = (NSComparisonPredicate *)subpredicates[1]; - - NSArray *limits; - NSExpression *leftConditionExpression; - - if(leftCondition.predicateOperatorType == NSGreaterThanOrEqualToPredicateOperatorType && - rightCondition.predicateOperatorType == NSLessThanOrEqualToPredicateOperatorType) { - limits = @[leftCondition.rightExpression, rightCondition.rightExpression]; - leftConditionExpression = leftCondition.leftExpression; - - } else if (leftCondition.predicateOperatorType == NSLessThanOrEqualToPredicateOperatorType && - rightCondition.predicateOperatorType == NSLessThanOrEqualToPredicateOperatorType) { - limits = @[leftCondition.leftExpression, rightCondition.rightExpression]; - leftConditionExpression = leftCondition.rightExpression; - - } else if(leftCondition.predicateOperatorType == NSLessThanOrEqualToPredicateOperatorType && - rightCondition.predicateOperatorType == NSGreaterThanOrEqualToPredicateOperatorType) { - limits = @[leftCondition.leftExpression, rightCondition.leftExpression]; - leftConditionExpression = leftCondition.rightExpression; - - } else if(leftCondition.predicateOperatorType == NSGreaterThanOrEqualToPredicateOperatorType && - rightCondition.predicateOperatorType == NSGreaterThanOrEqualToPredicateOperatorType) { - limits = @[leftCondition.rightExpression, rightCondition.leftExpression]; - leftConditionExpression = leftCondition.leftExpression; - } - - if (limits && leftConditionExpression) { - return [NSPredicate predicateWithFormat:@"%@ BETWEEN %@", leftConditionExpression, [NSExpression expressionForAggregate:limits]]; - } - } - } - return [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]; - } - if ([op isEqualToString:@"any"]) { - NSArray *subpredicates = MGLSubpredicatesWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]); - return [NSCompoundPredicate orPredicateWithSubpredicates:subpredicates]; - } - - NSExpression *expression = [NSExpression expressionWithMGLJSONObject:object]; - return [NSComparisonPredicate predicateWithLeftExpression:expression - rightExpression:[NSExpression expressionForConstantValue:@YES] - modifier:NSDirectPredicateModifier - type:NSEqualToPredicateOperatorType - options:0]; - -} - -- (id)mgl_jsonExpressionObject { - if ([self isEqual:[NSPredicate predicateWithValue:YES]]) { - return @YES; - } - if ([self isEqual:[NSPredicate predicateWithValue:NO]]) { - return @NO; - } - - if ([self.predicateFormat hasPrefix:@"BLOCKPREDICATE("]) { - [NSException raise:NSInvalidArgumentException - format:@"Block-based predicates are not supported."]; - } - - [NSException raise:NSInvalidArgumentException - format:@"Unrecognized predicate type."]; - return nil; -} - -@end - -@implementation NSPredicate (MGLExpressionAdditions) - -- (id)mgl_if:(id)firstValue, ... { - - if ([self evaluateWithObject:nil]) { - return firstValue; - } - - id eachExpression; - va_list argumentList; - va_start(argumentList, firstValue); - - while ((eachExpression = va_arg(argumentList, id))) { - if ([eachExpression isKindOfClass:[NSComparisonPredicate class]]) { - id valueExpression = va_arg(argumentList, id); - if ([eachExpression evaluateWithObject:nil]) { - return valueExpression; - } - } else { - return eachExpression; - } - } - va_end(argumentList); - - return nil; -} - -- (id)mgl_match:(NSExpression *)firstCase, ... { - [NSException raise:NSInvalidArgumentException - format:@"Match expressions lack underlying Objective-C implementations."]; - return nil; -} - -@end diff --git a/platform/darwin/src/NSPredicate+MGLPrivateAdditions.h b/platform/darwin/src/NSPredicate+MGLPrivateAdditions.h deleted file mode 100644 index 051a2775a1..0000000000 --- a/platform/darwin/src/NSPredicate+MGLPrivateAdditions.h +++ /dev/null @@ -1,25 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "NSPredicate+MGLAdditions.h" - -#include <mbgl/style/filter.hpp> - -NS_ASSUME_NONNULL_BEGIN - -@interface NSPredicate (MGLPrivateAdditions) - -- (mbgl::style::Filter)mgl_filter; - -+ (nullable instancetype)mgl_predicateWithFilter:(mbgl::style::Filter)filter; - -@end - -@interface NSPredicate (MGLExpressionAdditions) - -- (nullable id)mgl_if:(id)firstValue, ...; - -- (nullable id)mgl_match:(NSExpression *)firstCase, ...; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSString+MGLAdditions.h b/platform/darwin/src/NSString+MGLAdditions.h deleted file mode 100644 index 4888c7a00f..0000000000 --- a/platform/darwin/src/NSString+MGLAdditions.h +++ /dev/null @@ -1,46 +0,0 @@ -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -@interface NSString (MGLAdditions) - -/** Returns the range spanning the entire receiver. */ -- (NSRange)mgl_wholeRange; - -/** Returns the receiver if non-empty or nil if empty. */ -- (nullable NSString *)mgl_stringOrNilIfEmpty; - -/** - Returns a title-cased representation of the receiver using the specified - locale. - - @param locale The locale. For strings presented to users, pass in the current - locale (`+[NSLocale currentLocale]`). To use the system locale, pass in - `nil`. - */ -- (NSString *)mgl_titleCasedStringWithLocale:(NSLocale *)locale; - -/** - Returns a transliterated representation of the receiver using the specified - script. If transliteration fails, the receiver will be returned. - - Only supports scripts for languages used by Mapbox Streets. - - @param script The four-letter code representing the name of the script, as - specified by ISO 15924. - */ -- (NSString *)mgl_stringByTransliteratingIntoScript:(NSString *)script; - -@end - -@interface NSAttributedString (MGLAdditions) - -/** Returns the range spanning the entire receiver. */ -- (NSRange)mgl_wholeRange; - -/** Returns a copy of the receiver with leading and trailing members of the given set removed. */ -- (NSAttributedString *)mgl_attributedStringByTrimmingCharactersInSet:(NSCharacterSet *)set; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSString+MGLAdditions.m b/platform/darwin/src/NSString+MGLAdditions.m deleted file mode 100644 index d452d56678..0000000000 --- a/platform/darwin/src/NSString+MGLAdditions.m +++ /dev/null @@ -1,82 +0,0 @@ -#import "NSString+MGLAdditions.h" - -#if TARGET_OS_OSX - #import <Availability.h> -#endif - -@implementation NSString (MGLAdditions) - -- (NSRange)mgl_wholeRange { - return NSMakeRange(0, self.length); -} - -- (nullable NSString *)mgl_stringOrNilIfEmpty { - return self.length ? self : nil; -} - -- (NSString *)mgl_titleCasedStringWithLocale:(NSLocale *)locale { - NSMutableString *string = self.mutableCopy; - NSOrthography *orthography; - if (@available(iOS 11.0, macOS 10.13.0, *)) { - orthography = [NSOrthography defaultOrthographyForLanguage:locale.localeIdentifier]; - } - [string enumerateLinguisticTagsInRange:string.mgl_wholeRange scheme:NSLinguisticTagSchemeLexicalClass options:0 orthography:orthography usingBlock:^(NSString * _Nonnull tag, NSRange tokenRange, NSRange sentenceRange, BOOL * _Nonnull stop) { - NSString *word = [string substringWithRange:tokenRange]; - if (word.length > 3 - || !([tag isEqualToString:NSLinguisticTagConjunction] - || [tag isEqualToString:NSLinguisticTagPreposition] - || [tag isEqualToString:NSLinguisticTagDeterminer] - || [tag isEqualToString:NSLinguisticTagParticle] - || [tag isEqualToString:NSLinguisticTagClassifier])) { - unichar firstLetter = [[word capitalizedStringWithLocale:locale] characterAtIndex:0]; - NSString *suffix = [word substringFromIndex:1]; - if (!([word hasPrefix:@"i"] && suffix.length - && [[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:[suffix characterAtIndex:0]])) { - word = [NSString stringWithFormat:@"%C%@", firstLetter, suffix]; - } - } - [string replaceCharactersInRange:tokenRange withString:word]; - }]; - return string; -} - -- (NSString *)mgl_stringByTransliteratingIntoScript:(NSString *)script { - NSMutableString *string = self.mutableCopy; - NSStringTransform transform; - if ([script isEqualToString:@"Latn"]) { - transform = NSStringTransformToLatin; - } else if ([script isEqualToString:@"Hans"]) { - transform = @"Hant-Hans"; - } else if ([script isEqualToString:@"Hant"]) { - transform = @"Hans-Hant"; - } else if ([script isEqualToString:@"Cyrl"]) { - transform = @"Any-Latin; Latin-Cyrillic"; - } else if ([script isEqualToString:@"Arab"]) { - transform = @"Any-Latin; Latin-Arabic"; - } else if ([script isEqualToString:@"Jpan"]) { - transform = @"Any-Latin; Latin-Katakana"; - } else if ([script isEqualToString:@"Kore"]) { - transform = @"Any-Latin; Latin-Hangul"; - } - return transform ? [string stringByApplyingTransform:transform reverse:NO] : string; -} - -@end - -@implementation NSAttributedString (MGLAdditions) - -- (NSRange)mgl_wholeRange { - return NSMakeRange(0, self.length); -} - -- (NSAttributedString *)mgl_attributedStringByTrimmingCharactersInSet:(NSCharacterSet *)set { - NSScanner *scanner = [NSScanner scannerWithString:self.string]; - scanner.charactersToBeSkipped = nil; - NSString *prefix; - [scanner scanCharactersFromSet:set intoString:&prefix]; - - NSString *trimmedString = [self.string stringByTrimmingCharactersInSet:set]; - return [self attributedSubstringFromRange:NSMakeRange(prefix.length, trimmedString.length)]; -} - -@end diff --git a/platform/darwin/src/NSURL+MGLAdditions.h b/platform/darwin/src/NSURL+MGLAdditions.h deleted file mode 100644 index 9845a180db..0000000000 --- a/platform/darwin/src/NSURL+MGLAdditions.h +++ /dev/null @@ -1,15 +0,0 @@ -#import <Foundation/Foundation.h> - -NS_ASSUME_NONNULL_BEGIN - -@interface NSURL (MGLAdditions) - -/** - Returns the given URL, modified if necessary to use the asset: URL scheme - expected by mbgl for local requests. - */ -- (nullable NSURL *)mgl_URLByStandardizingScheme; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSURL+MGLAdditions.m b/platform/darwin/src/NSURL+MGLAdditions.m deleted file mode 100644 index 09fdd5c880..0000000000 --- a/platform/darwin/src/NSURL+MGLAdditions.m +++ /dev/null @@ -1,14 +0,0 @@ -#import "NSURL+MGLAdditions.h" - -@implementation NSURL (MGLAdditions) - -- (nullable NSURL *)mgl_URLByStandardizingScheme { - if (!self.scheme) { - // Relative file URL, already escaped (in order to create the NSURL). - // Assume a relative path into the application’s resource folder. - return [NSURL URLWithString:[@"asset://" stringByAppendingString:self.absoluteString]]; - } - return self; -} - -@end diff --git a/platform/darwin/src/NSValue+MGLAdditions.h b/platform/darwin/src/NSValue+MGLAdditions.h deleted file mode 100644 index 9222f04620..0000000000 --- a/platform/darwin/src/NSValue+MGLAdditions.h +++ /dev/null @@ -1,148 +0,0 @@ -#import <Foundation/Foundation.h> - -#import "MGLGeometry.h" -#import "MGLLight.h" -#import "MGLOfflinePack.h" -#import "MGLTypes.h" - -NS_ASSUME_NONNULL_BEGIN - -/** - Methods for round-tripping values for Mapbox-defined types. - */ -@interface NSValue (MGLAdditions) - -#pragma mark Working with Geographic Coordinate Values - -/** - Creates a new value object containing the specified Core Location geographic - coordinate structure. - - @param coordinate The value for the new object. - @return A new value object that contains the geographic coordinate information. - */ -+ (instancetype)valueWithMGLCoordinate:(CLLocationCoordinate2D)coordinate; - -/** - The Core Location geographic coordinate structure representation of the value. - */ -@property (readonly) CLLocationCoordinate2D MGLCoordinateValue; - -/** - Creates a new value object containing the specified Mapbox map point structure. - - @param point The value for the new object. - @return A new value object that contains the coordinate and zoom level information. - */ -+ (instancetype)valueWithMGLMapPoint:(MGLMapPoint)point; - -/** - The Mapbox map point structure representation of the value. - */ -@property (readonly) MGLMapPoint MGLMapPointValue; - -/** - Creates a new value object containing the specified Mapbox coordinate span - structure. - - @param span The value for the new object. - @return A new value object that contains the coordinate span information. - */ -+ (instancetype)valueWithMGLCoordinateSpan:(MGLCoordinateSpan)span; - -/** - The Mapbox coordinate span structure representation of the value. - */ -@property (readonly) MGLCoordinateSpan MGLCoordinateSpanValue; - -/** - Creates a new value object containing the specified Mapbox coordinate bounds - structure. - - @param bounds The value for the new object. - @return A new value object that contains the coordinate bounds information. - */ -+ (instancetype)valueWithMGLCoordinateBounds:(MGLCoordinateBounds)bounds; - -/** - The Mapbox coordinate bounds structure representation of the value. - */ -@property (readonly) MGLCoordinateBounds MGLCoordinateBoundsValue; - -/** - Creates a new value object containing the specified Mapbox coordinate - quad structure. - - @param quad The value for the new object. - @return A new value object that contains the coordinate quad information. - */ -+ (instancetype)valueWithMGLCoordinateQuad:(MGLCoordinateQuad)quad; - -/** - The Mapbox coordinate quad structure representation of the value. - */ -- (MGLCoordinateQuad)MGLCoordinateQuadValue; - -#pragma mark Working with Offline Map Values - -/** - Creates a new value object containing the given `MGLOfflinePackProgress` - structure. - - @param progress The value for the new object. - @return A new value object that contains the offline pack progress information. - */ -+ (NSValue *)valueWithMGLOfflinePackProgress:(MGLOfflinePackProgress)progress; - -/** - The `MGLOfflinePackProgress` structure representation of the value. - */ -@property (readonly) MGLOfflinePackProgress MGLOfflinePackProgressValue; - -#pragma mark Working with Transition Values - -/** - Creates a new value object containing the given `MGLTransition` - structure. - - @param transition The value for the new object. - @return A new value object that contains the transition information. - */ -+ (NSValue *)valueWithMGLTransition:(MGLTransition)transition; - -/** - The `MGLTransition` structure representation of the value. - */ -@property (readonly) MGLTransition MGLTransitionValue; - -/** - Creates a new value object containing the given `MGLSphericalPosition` - structure. - - @param lightPosition The value for the new object. - @return A new value object that contains the light position information. - */ -+ (instancetype)valueWithMGLSphericalPosition:(MGLSphericalPosition)lightPosition; - -/** - The `MGLSphericalPosition` structure representation of the value. - */ -@property (readonly) MGLSphericalPosition MGLSphericalPositionValue; - -/** - Creates a new value object containing the given `MGLLightAnchor` - enum. - - @param lightAnchor The value for the new object. - @return A new value object that contains the light anchor information. - */ -+ (NSValue *)valueWithMGLLightAnchor:(MGLLightAnchor)lightAnchor; - -/** - The `MGLLightAnchor` enum representation of the value. - */ -@property (readonly) MGLLightAnchor MGLLightAnchorValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSValue+MGLAdditions.m b/platform/darwin/src/NSValue+MGLAdditions.m deleted file mode 100644 index 8f12066cc3..0000000000 --- a/platform/darwin/src/NSValue+MGLAdditions.m +++ /dev/null @@ -1,104 +0,0 @@ -#import "NSValue+MGLAdditions.h" - -@implementation NSValue (MGLAdditions) - -#pragma mark Geometry - -+ (instancetype)valueWithMGLCoordinate:(CLLocationCoordinate2D)coordinate { - return [self valueWithBytes:&coordinate objCType:@encode(CLLocationCoordinate2D)]; -} - -- (CLLocationCoordinate2D)MGLCoordinateValue { - CLLocationCoordinate2D coordinate; - [self getValue:&coordinate]; - return coordinate; -} - -+ (instancetype)valueWithMGLMapPoint:(MGLMapPoint)point { - return [self valueWithBytes:&point objCType:@encode(MGLMapPoint)]; -} - --(MGLMapPoint) MGLMapPointValue { - MGLMapPoint point; - [self getValue:&point]; - return point; -} - -+ (instancetype)valueWithMGLCoordinateSpan:(MGLCoordinateSpan)span { - return [self valueWithBytes:&span objCType:@encode(MGLCoordinateSpan)]; -} - -- (MGLCoordinateSpan)MGLCoordinateSpanValue { - MGLCoordinateSpan span; - [self getValue:&span]; - return span; -} - -+ (instancetype)valueWithMGLCoordinateBounds:(MGLCoordinateBounds)bounds { - return [self valueWithBytes:&bounds objCType:@encode(MGLCoordinateBounds)]; -} - -- (MGLCoordinateBounds)MGLCoordinateBoundsValue { - MGLCoordinateBounds bounds; - [self getValue:&bounds]; - return bounds; -} - -+ (instancetype)valueWithMGLCoordinateQuad:(MGLCoordinateQuad)quad { - return [self valueWithBytes:&quad objCType:@encode(MGLCoordinateQuad)]; -} - -- (MGLCoordinateQuad)MGLCoordinateQuadValue { - MGLCoordinateQuad quad; - [self getValue:&quad]; - return quad; -} - -#pragma mark Offline maps - -+ (NSValue *)valueWithMGLOfflinePackProgress:(MGLOfflinePackProgress)progress { - return [NSValue value:&progress withObjCType:@encode(MGLOfflinePackProgress)]; -} - -- (MGLOfflinePackProgress)MGLOfflinePackProgressValue { - MGLOfflinePackProgress progress; - [self getValue:&progress]; - return progress; -} - -#pragma mark Working with Transition Values - -+ (NSValue *)valueWithMGLTransition:(MGLTransition)transition { - return [NSValue value:&transition withObjCType:@encode(MGLTransition)]; -} - -- (MGLTransition)MGLTransitionValue { - MGLTransition transition; - [self getValue:&transition]; - return transition; -} - -+ (NSValue *)valueWithMGLSphericalPosition:(MGLSphericalPosition)lightPosition -{ - return [NSValue value:&lightPosition withObjCType:@encode(MGLSphericalPosition)]; -} - -- (MGLSphericalPosition)MGLSphericalPositionValue -{ - MGLSphericalPosition lightPosition; - [self getValue:&lightPosition]; - return lightPosition; -} - -+ (NSValue *)valueWithMGLLightAnchor:(MGLLightAnchor)lightAnchor { - return [NSValue value:&lightAnchor withObjCType:@encode(MGLLightAnchor)]; -} - -- (MGLLightAnchor)MGLLightAnchorValue -{ - MGLLightAnchor achorType; - [self getValue:&achorType]; - return achorType; -} - -@end diff --git a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h deleted file mode 100644 index 0f1e511694..0000000000 --- a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h +++ /dev/null @@ -1,14 +0,0 @@ -#import <Foundation/Foundation.h> - -#include <array> - -@interface NSValue (MGLStyleAttributeAdditions) - -+ (instancetype)mgl_valueWithOffsetArray:(std::array<float, 2>)offsetArray; -+ (instancetype)mgl_valueWithPaddingArray:(std::array<float, 4>)paddingArray; - -- (std::array<float, 2>)mgl_offsetArrayValue; -- (std::array<float, 4>)mgl_paddingArrayValue; -- (std::array<float, 3>)mgl_lightPositionArrayValue; - -@end diff --git a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm deleted file mode 100644 index aa3e003d04..0000000000 --- a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm +++ /dev/null @@ -1,76 +0,0 @@ -#import "NSValue+MGLStyleAttributeAdditions.h" -#import "MGLLight.h" -#import "MGLLoggingConfiguration_Private.h" -#import "MGLGeometry_Private.h" -#if TARGET_OS_IPHONE - #import <UIKit/UIKit.h> -#endif - -@implementation NSValue (MGLStyleAttributeAdditions) - -+ (instancetype)mgl_valueWithOffsetArray:(std::array<float, 2>)offsetArray -{ - CGVector vector = CGVectorMake(offsetArray[0], offsetArray[1]); -#if !TARGET_OS_IPHONE - // Style specification assumes an origin at the upper-left corner. - // macOS defines an origin at the lower-left corner. - vector.dy *= -1; -#endif - return [NSValue value:&vector withObjCType:@encode(CGVector)]; -} - -+ (instancetype)mgl_valueWithPaddingArray:(std::array<float, 4>)paddingArray -{ - // Style specification defines padding in clockwise order: top, right, bottom, left. - // Foundation defines padding in counterclockwise order: top, left, bottom, right. - MGLEdgeInsets insets = { - .top = paddingArray[0], - .right = paddingArray[1], - .bottom = paddingArray[2], - .left = paddingArray[3], - }; - return [NSValue value:&insets withObjCType:@encode(MGLEdgeInsets)]; -} - -- (std::array<float, 2>)mgl_offsetArrayValue -{ - MGLAssert(strcmp(self.objCType, @encode(CGVector)) == 0, @"Value does not represent a CGVector"); - CGVector vector; - [self getValue:&vector]; -#if !TARGET_OS_IPHONE - vector.dy *= -1; -#endif - return { - static_cast<float>(vector.dx), - static_cast<float>(vector.dy), - }; -} - -- (std::array<float, 4>)mgl_paddingArrayValue -{ - MGLAssert(strcmp(self.objCType, @encode(MGLEdgeInsets)) == 0, @"Value does not represent an NSEdgeInsets/UIEdgeInsets"); - MGLEdgeInsets insets; - [self getValue:&insets]; - // Style specification defines padding in clockwise order: top, right, bottom, left. - return { - static_cast<float>(insets.top), - static_cast<float>(insets.right), - static_cast<float>(insets.bottom), - static_cast<float>(insets.left), - }; -} - -- (std::array<float, 3>)mgl_lightPositionArrayValue -{ - MGLAssert(strcmp(self.objCType, @encode(MGLSphericalPosition)) == 0, @"Value does not represent an MGLSphericalPosition"); - MGLSphericalPosition lightPosition; - [self getValue:&lightPosition]; - // Style specification defines padding in clockwise order: top, right, bottom, left. - return { - static_cast<float>(lightPosition.radial), - static_cast<float>(lightPosition.azimuthal), - static_cast<float>(lightPosition.polar), - }; -} - -@end |