diff --git a/platform/ios/platform/darwin/src/MGLLocationManager.h b/platform/ios/platform/darwin/src/MGLLocationManager.h index ecb919298..d9dfe3911 100644 --- a/platform/ios/platform/darwin/src/MGLLocationManager.h +++ b/platform/ios/platform/darwin/src/MGLLocationManager.h @@ -58,6 +58,18 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)setDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 +/** + Specifies the level of location accuracy the Maps SDK has permission to use. + + @note If the value of this property is `CLAccuracyAuthorizationFullAccuracy`, you can set the + `MGLLocationManager.desiredAccuracy` property to any value. If the value is `CLAccuracyAuthorizationReducedAccuracy`, + setting `MGLLocationManager.desiredAccuracy` to a value other than` kCLLocationAccuracyReduced` has no effect on + the location information. + */ +- (CLAccuracyAuthorization)accuracyAuthorization API_AVAILABLE(ios(14)); +#endif + /** Specifies the type of user activity associated with the location updates. @@ -78,6 +90,17 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)setActivityType:(CLActivityType)activityType; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 +/** + Requests the user's permission to temporarily use location update services + with full accuracy. + + @note If the user turned off location accuracy you may use this method to + request full accuracy for a session. + */ +- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey API_AVAILABLE(ios(14)); +#endif + @required /** @@ -195,6 +218,14 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)locationManager:(id)manager didFailWithError:(nonnull NSError *)error; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 +/** + Notifies the delegate that the location authorization status has changed. + + @param manager The location manager reporting the change. + */ +- (void)locationManagerDidChangeAuthorization:(id)manager; +#endif @optional diff --git a/platform/ios/platform/darwin/src/MGLLocationManager.m b/platform/ios/platform/darwin/src/MGLLocationManager.m index 29e3ccaa3..5729f26b3 100644 --- a/platform/ios/platform/darwin/src/MGLLocationManager.m +++ b/platform/ios/platform/darwin/src/MGLLocationManager.m @@ -38,7 +38,15 @@ } - (CLAuthorizationStatus)authorizationStatus { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 + if (@available(iOS 14.0, *)) { + return self.locationManager.authorizationStatus; + } else { + return kCLAuthorizationStatusNotDetermined; + } +#else return [CLLocationManager authorizationStatus]; +#endif } - (void)setActivityType:(CLActivityType)activityType { @@ -49,6 +57,23 @@ return self.locationManager.activityType; } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 +- (CLAccuracyAuthorization)accuracyAuthorization { + if (@available(iOS 14.0, *)) { + return self.locationManager.accuracyAuthorization; + } else { + return CLAccuracyAuthorizationFullAccuracy; + } +} + +- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey { + if (@available(iOS 14.0, *)) { + [self.locationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:purposeKey]; + } +} +#endif + + - (void)dismissHeadingCalibrationDisplay { [self.locationManager dismissHeadingCalibrationDisplay]; } @@ -113,4 +138,9 @@ } } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 +- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager { + [self.delegate locationManagerDidChangeAuthorization:self]; +} +#endif @end diff --git a/platform/ios/platform/darwin/src/MGLStyleValue.mm b/platform/ios/platform/darwin/src/MGLStyleValue.mm index 01ad108d7..f379e71b8 100644 --- a/platform/ios/platform/darwin/src/MGLStyleValue.mm +++ b/platform/ios/platform/darwin/src/MGLStyleValue.mm @@ -14,6 +14,8 @@ id MGLJSONObjectFromMBGLValue(const mbgl::Value &value) { return @(value); }, [](const int64_t value) { return @(value); + }, [](const uint64_t value) { + return @(value); }, [](const double value) { return @(value); }, [](const std::string &value) { diff --git a/platform/ios/platform/darwin/src/MGLStyleValue_Private.h b/platform/ios/platform/darwin/src/MGLStyleValue_Private.h index 43f0b9d28..cec6e1aae 100644 --- a/platform/ios/platform/darwin/src/MGLStyleValue_Private.h +++ b/platform/ios/platform/darwin/src/MGLStyleValue_Private.h @@ -35,6 +35,8 @@ namespace mbgl { } } +id MGLJSONObjectFromMBGLValue(const mbgl::Value &value); + NS_INLINE MGLTransition MGLTransitionFromOptions(const mbgl::style::TransitionOptions& options) { MGLTransition transition; transition.duration = MGLTimeIntervalFromDuration(options.duration.value_or(mbgl::Duration::zero())); diff --git a/platform/ios/platform/ios/CHANGELOG.md b/platform/ios/platform/ios/CHANGELOG.md index e0f535877..358ece1f6 100644 --- a/platform/ios/platform/ios/CHANGELOG.md +++ b/platform/ios/platform/ios/CHANGELOG.md @@ -6,6 +6,18 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Features +* Added `MGLLocationManager.accuracyAuthorization` and `[MGLLocationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKeyproperty:]` to support iOS 14 location accuracy privacy changes. (cherry pick from [#361](https://github.com/mapbox/mapbox-gl-native-ios/pull/361)) +* Added `[MGLLocationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKeyproperty:]` to allow developers request just-in-time full-accuracy permissions. (cherry pick from [#361](https://github.com/mapbox/mapbox-gl-native-ios/pull/361)) +* Added `[MGLLocationManagerDelegate locationManagerDidChangeAuthorization:]` to let `MGLMapView` know about privacy changes. (cherry pick from [#376](https://github.com/mapbox/mapbox-gl-native-ios/pull/376)) +* Added `[MGLMapViewDelegate mapView:didChangeLocationManagerAuthorization:]` to allow developers adjust their apps to privacy settings changes. (cherry pick from [#376](https://github.com/mapbox/mapbox-gl-native-ios/pull/376)) +* Added an approximate user location halo when `MGLLocationManager.accuracyAuthorization` is set to `CLAccuracyAuthorizationReducedAccuracy`. (cherry pick from [#381](https://github.com/mapbox/mapbox-gl-native-ios/pull/381)) +* The `MGLAccuracyAuthorizationDescription` as element of `NSLocationTemporaryUsageDescriptionDictionary` Info.plist key can now be set to describe why you request accuracy authorization. (cherry pick from [#392](https://github.com/mapbox/mapbox-gl-native-ios/pull/392)) +* Added `[MGLMapViewDelegate mapViewStyleForDefaultUserLocationAnnotationView:]` and `MGLUserLocationAnnotationViewStyle` class to allow developers customize the default user location annotation view UI style. (cherry pick from [#403](https://github.com/mapbox/mapbox-gl-native-ios/pull/403)) + +### Bug Fixes + +* Fixed an issue that caused a crash when custom location managers did not implement `MGLLocationManager.accuracyAuthorization`. (cherry pick from [#474](https://github.com/mapbox/mapbox-gl-native-ios/pull/474)) + ### Other * mapbox-gl-js submodule has been replaced with maplibre-gl-js diff --git a/platform/ios/platform/ios/app/Info.plist b/platform/ios/platform/ios/app/Info.plist index e7c23e481..5bcd3b34b 100644 --- a/platform/ios/platform/ios/app/Info.plist +++ b/platform/ios/platform/ios/app/Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.mapbox.MapboxGL + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -26,12 +26,28 @@ NSHumanReadableCopyright © 2014–2019 Mapbox + NSLocationAlwaysAndWhenInUseUsageDescription + The map will display your location. If you choose Always, the map may also use your location when it isn’t visible in order to improve OpenStreetMap. NSLocationAlwaysUsageDescription - The map will display your location. The map may also use your location when it isn’t visible in order to improve OpenStreetMap and Mapbox products. + The map will display your location. The map may also use your location when it isn’t visible in order to improve OpenStreetMap. + NSLocationTemporaryUsageDescriptionDictionary + + MGLAccuracyAuthorizationDescription + MapLibre requires your precise location to help you navigate the map. + NSLocationWhenInUseUsageDescription The map will display your location. - NSLocationAlwaysAndWhenInUseUsageDescription - The map will display your location. If you choose Always, the map may also use your location when it isn’t visible in order to improve OpenStreetMap and Mapbox products. + UIApplicationShortcutItems + + + UIApplicationShortcutItemIconFile + settings + UIApplicationShortcutItemTitle + Settings + UIApplicationShortcutItemType + $(PRODUCT_BUNDLE_IDENTIFIER).settings + + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -53,16 +69,5 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - UIApplicationShortcutItems - - - UIApplicationShortcutItemTitle - Settings - UIApplicationShortcutItemType - $(PRODUCT_BUNDLE_IDENTIFIER).settings - UIApplicationShortcutItemIconFile - settings - - diff --git a/platform/ios/platform/ios/app/MBXOrnamentsViewController.m b/platform/ios/platform/ios/app/MBXOrnamentsViewController.m index f451f647e..28dc79641 100644 --- a/platform/ios/platform/ios/app/MBXOrnamentsViewController.m +++ b/platform/ios/platform/ios/app/MBXOrnamentsViewController.m @@ -2,7 +2,7 @@ #import "MBXOrnamentsViewController.h" -@interface MBXOrnamentsViewController () +@interface MBXOrnamentsViewController () @property (nonatomic) MGLMapView *mapView; @property (nonatomic) NSTimer *timer; @@ -64,7 +64,6 @@ zoomLevel:16 direction:30 animated:NO]; - mapView.delegate = self; mapView.showsScale = YES; [self.view addSubview:mapView]; diff --git a/platform/ios/platform/ios/app/MBXViewController.m b/platform/ios/platform/ios/app/MBXViewController.m index af668317c..678736a4d 100644 --- a/platform/ios/platform/ios/app/MBXViewController.m +++ b/platform/ios/platform/ios/app/MBXViewController.m @@ -15,7 +15,6 @@ #import "MBXFrameTimeGraphView.h" #import "../src/MGLMapView_Experimental.h" - #import static const CLLocationCoordinate2D WorldTourDestinations[] = { @@ -213,7 +212,7 @@ CLLocationCoordinate2D randomWorldCoordinate() { @property (nonatomic) BOOL zoomLevelOrnamentEnabled; @property (nonatomic) NSMutableArray *helperWindows; @property (nonatomic) NSMutableArray *contentInsetsOverlays; - +@property (nonatomic, copy) void (^locationBlock)(void); @end @interface MGLMapView (MBXViewController) @@ -1952,6 +1951,12 @@ CLLocationCoordinate2D randomWorldCoordinate() { } - (IBAction)locateUser:(id)sender +{ + [self nextTrackingMode:sender]; +} + + +- (void)nextTrackingMode:(id)sender { MGLUserTrackingMode nextMode; NSString *nextAccessibilityValue; @@ -2333,6 +2338,33 @@ CLLocationCoordinate2D randomWorldCoordinate() { } } +- (void)mapView:(nonnull MGLMapView *)mapView didChangeLocationManagerAuthorization:(nonnull id)manager { + if (@available(iOS 14, *)) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 + if (manager.authorizationStatus == kCLAuthorizationStatusDenied || manager.accuracyAuthorization == CLAccuracyAuthorizationReducedAccuracy) { + [self alertAccuracyChanges]; + } +#endif + } +} + +- (void)alertAccuracyChanges { + UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"MapLibre works best with your precise location." + message:@"You'll get turn-by-turn directions." + preferredStyle:UIAlertControllerStyleAlert]; + + UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:@"Turn On in Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; + }]; + + UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"Keep Precise Location Off" style:UIAlertActionStyleDefault + handler:nil]; + + [alert addAction:settingsAction]; + [alert addAction:defaultAction]; + [self presentViewController:alert animated:YES completion:nil]; +} + - (void)saveCurrentMapState:(__unused NSNotification *)notification { // The following properties can change after the view loads so we need to save their diff --git a/platform/ios/platform/ios/benchmark/Info.plist b/platform/ios/platform/ios/benchmark/Info.plist index 1e8779904..0891d4a59 100644 --- a/platform/ios/platform/ios/benchmark/Info.plist +++ b/platform/ios/platform/ios/benchmark/Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - com.mapbox.GL.benchmark + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,6 +24,8 @@ 15256 LSRequiresIPhoneOS + MGLMapboxMetricsEnabledSettingShownInApp + NSHumanReadableCopyright © 2015–2019 Mapbox UIApplicationExitsOnSuspend @@ -47,7 +49,5 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - MGLMapboxMetricsEnabledSettingShownInApp - diff --git a/platform/ios/platform/ios/benchmark/MBXBenchViewController.h b/platform/ios/platform/ios/benchmark/MBXBenchViewController.h index c4439be5e..c93e28d6a 100644 --- a/platform/ios/platform/ios/benchmark/MBXBenchViewController.h +++ b/platform/ios/platform/ios/benchmark/MBXBenchViewController.h @@ -1,4 +1,5 @@ #import +#import @interface MBXBenchViewController : UIViewController diff --git a/platform/ios/platform/ios/benchmark/MBXBenchViewController.mm b/platform/ios/platform/ios/benchmark/MBXBenchViewController.mm index 901eb07cd..9bd47f7ba 100644 --- a/platform/ios/platform/ios/benchmark/MBXBenchViewController.mm +++ b/platform/ios/platform/ios/benchmark/MBXBenchViewController.mm @@ -1,6 +1,7 @@ #import "MBXBenchViewController.h" #import "MBXBenchAppDelegate.h" #import "MGLMapView_Private.h" +#import "MGLMapViewDelegate.h" #include "locations.hpp" diff --git a/platform/ios/platform/ios/docs/guides/Info.plist Keys.md b/platform/ios/platform/ios/docs/guides/Info.plist Keys.md index 446045764..39dfceb08 100644 --- a/platform/ios/platform/ios/docs/guides/Info.plist Keys.md +++ b/platform/ios/platform/ios/docs/guides/Info.plist Keys.md @@ -10,6 +10,22 @@ Mapbox-hosted vector tiles and styles require an API access token, which you can As an alternative, you can use `MGLAccountManager.accessToken` to set a token in code. See [our guide](https://www.mapbox.com/help/ios-private-access-token/) for some tips on keeping access tokens in open source code private. +## MGLAccuracyAuthorizationDescription + +Set the Mapbox accuracy authorization description string as an element of `NSLocationTemporaryUsageDescriptionDictionary` to be used by the map to request authorization when the `MGLLocationManager.accuracyAuthorization` is set to `CLAccuracyAuthorizationReducedAccuracy`. Requesting accuracy authorization is available for devices running iOS 14.0 and above. + +Example: + +```xml +NSLocationTemporaryUsageDescriptionDictionary + + MGLAccuracyAuthorizationDescription + Mapbox requires your precise location to help you navigate the map. + +``` + +Remove `MGLAccuracyAuthorizationDescription` if you want to control when to request for accuracy authorization. + ## MGLMapboxAPIBaseURL Use this key if you need to customize the API base URL used throughout the SDK. If unset, the default Mapbox API is used. @@ -47,4 +63,3 @@ At runtime, you can obtain the value of this key using the `MGLOfflineStorage.da Beginning in version 4.0, the SDK also performs collision detection between style layers based on different sources by default. For the default behavior, omit the `MGLCollisionBehaviorPre4_0` key or set it to NO (`false`). This property may also be set using `[[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"MGLCollisionBehaviorPre4_0"]`; it will override any value specified in the `Info.plist`. - diff --git a/platform/ios/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/platform/ios/ios.xcodeproj/project.pbxproj index 62d5c2dbd..5da4776e4 100644 --- a/platform/ios/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/platform/ios/ios.xcodeproj/project.pbxproj @@ -224,6 +224,12 @@ 40F887701D7A1E58008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; }; 40F887711D7A1E59008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; }; 40FDA76B1CCAAA6800442548 /* MBXAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */; }; + 4BC5769325E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC5769125E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BC5769425E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BC5769125E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h */; }; + 4BC5769525E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC5769225E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m */; }; + 4BC5769625E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BC5769225E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m */; }; + 4BC576C925E443CE006E06EB /* MGLFaux3DUserLocationAnnotationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC576C825E443CE006E06EB /* MGLFaux3DUserLocationAnnotationView.mm */; }; + 4BC576CA25E443CE006E06EB /* MGLFaux3DUserLocationAnnotationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC576C825E443CE006E06EB /* MGLFaux3DUserLocationAnnotationView.mm */; }; 550570C622958FB400228ECF /* MGLMapView+Impl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 550570C422958FB300228ECF /* MGLMapView+Impl.mm */; }; 550570C722958FB400228ECF /* MGLMapView+Impl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 550570C422958FB300228ECF /* MGLMapView+Impl.mm */; }; 550570C822958FB400228ECF /* MGLMapView+Impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 550570C522958FB400228ECF /* MGLMapView+Impl.h */; }; @@ -530,7 +536,6 @@ DA88485A1CBAFB9800AB86E3 /* MGLUserLocation_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88484B1CBAFB9800AB86E3 /* MGLUserLocation_Private.h */; }; DA88485B1CBAFB9800AB86E3 /* MGLUserLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88484C1CBAFB9800AB86E3 /* MGLUserLocation.m */; }; DA88485C1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88484D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h */; }; - DA88485D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88484E1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m */; }; DA8848601CBAFC2E00AB86E3 /* Mapbox.h in Headers */ = {isa = PBXBuildFile; fileRef = DA88485E1CBAFC2E00AB86E3 /* Mapbox.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA88488B1CBB037E00AB86E3 /* SMCalloutView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848891CBB037E00AB86E3 /* SMCalloutView.h */; }; DA88488C1CBB037E00AB86E3 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */; }; @@ -568,7 +573,6 @@ DAA4E42F1CBB730400178DFB /* MGLCompactCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8848451CBAFB9800AB86E3 /* MGLCompactCalloutView.m */; }; DAA4E4321CBB730400178DFB /* MGLMapView.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88484A1CBAFB9800AB86E3 /* MGLMapView.mm */; }; DAA4E4331CBB730400178DFB /* MGLUserLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88484C1CBAFB9800AB86E3 /* MGLUserLocation.m */; }; - DAA4E4341CBB730400178DFB /* MGLFaux3DUserLocationAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88484E1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m */; }; DAA4E4351CBB730400178DFB /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */; }; DAAF722B1DA903C700312FA4 /* MGLStyleValue.h in Headers */ = {isa = PBXBuildFile; fileRef = DAAF72291DA903C700312FA4 /* MGLStyleValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; DAAF722C1DA903C700312FA4 /* MGLStyleValue.h in Headers */ = {isa = PBXBuildFile; fileRef = DAAF72291DA903C700312FA4 /* MGLStyleValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -907,6 +911,9 @@ 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShapeSource_Private.h; sourceTree = ""; }; 40FDA7691CCAAA6800442548 /* MBXAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBXAnnotationView.h; sourceTree = ""; }; 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXAnnotationView.m; sourceTree = ""; }; + 4BC5769125E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLUserLocationAnnotationViewStyle.h; sourceTree = ""; }; + 4BC5769225E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLUserLocationAnnotationViewStyle.m; sourceTree = ""; }; + 4BC576C825E443CE006E06EB /* MGLFaux3DUserLocationAnnotationView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFaux3DUserLocationAnnotationView.mm; sourceTree = ""; }; 550570C422958FB300228ECF /* MGLMapView+Impl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "MGLMapView+Impl.mm"; sourceTree = ""; }; 550570C522958FB400228ECF /* MGLMapView+Impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLMapView+Impl.h"; sourceTree = ""; }; 554180411D2E97DE00012372 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; @@ -1038,7 +1045,7 @@ DA17BE2F1CC4BAC300402C41 /* MGLMapView_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLMapView_Private.h; sourceTree = ""; }; DA1AC01B1E5B8774006DF1D6 /* lt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Localizable.strings; sourceTree = ""; }; DA1AC0201E5B8917006DF1D6 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Foundation.stringsdict; sourceTree = ""; }; - DA1DC94A1CB6C1C2006E619F /* Mapbox GL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mapbox GL.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + DA1DC94A1CB6C1C2006E619F /* MapLibre GL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "MapLibre GL.app"; sourceTree = BUILT_PRODUCTS_DIR; }; DA1DC9501CB6C1C2006E619F /* MBXAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBXAppDelegate.h; sourceTree = ""; }; DA1DC9531CB6C1C2006E619F /* MBXViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBXViewController.h; sourceTree = ""; }; DA1DC95E1CB6C1C2006E619F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -1184,7 +1191,6 @@ DA88484B1CBAFB9800AB86E3 /* MGLUserLocation_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLUserLocation_Private.h; sourceTree = ""; }; DA88484C1CBAFB9800AB86E3 /* MGLUserLocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLUserLocation.m; sourceTree = ""; }; DA88484D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFaux3DUserLocationAnnotationView.h; sourceTree = ""; }; - DA88484E1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLFaux3DUserLocationAnnotationView.m; sourceTree = ""; }; DA88485E1CBAFC2E00AB86E3 /* Mapbox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Mapbox.h; path = src/Mapbox.h; sourceTree = SOURCE_ROOT; }; DA8848891CBB037E00AB86E3 /* SMCalloutView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMCalloutView.h; sourceTree = ""; }; DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SMCalloutView.m; sourceTree = ""; }; @@ -1698,7 +1704,7 @@ DA1DC94B1CB6C1C2006E619F /* Products */ = { isa = PBXGroup; children = ( - DA1DC94A1CB6C1C2006E619F /* Mapbox GL.app */, + DA1DC94A1CB6C1C2006E619F /* MapLibre GL.app */, DABCABA81CB80692000A7C39 /* Bench GL.app */, DA8847D21CBAF91600AB86E3 /* Mapbox.framework */, DAA4E4131CBB71D400178DFB /* libMapbox.a */, @@ -1919,6 +1925,8 @@ 5580B45A229570A10091291B /* MGLMapView+OpenGL.mm */, DA8848371CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h */, DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */, + 4BC5769125E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h */, + 4BC5769225E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m */, ); name = Kit; path = src; @@ -2124,6 +2132,7 @@ DAD165841CF4D06B001FF4B9 /* Annotations */ = { isa = PBXGroup; children = ( + 4BC576C825E443CE006E06EB /* MGLFaux3DUserLocationAnnotationView.mm */, 404326881D5B9B1A007111BD /* MGLAnnotationContainerView_Private.h */, 40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */, 40EDA1BE1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.m */, @@ -2137,7 +2146,6 @@ DA8848441CBAFB9800AB86E3 /* MGLCompactCalloutView.h */, DA8848451CBAFB9800AB86E3 /* MGLCompactCalloutView.m */, DA88484D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h */, - DA88484E1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m */, DA88484B1CBAFB9800AB86E3 /* MGLUserLocation_Private.h */, DA8848391CBAFB8500AB86E3 /* MGLUserLocation.h */, DA88484C1CBAFB9800AB86E3 /* MGLUserLocation.m */, @@ -2160,6 +2168,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 4BC5769325E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h in Headers */, 556660DB1E1D8E8D00E2C41B /* MGLFoundation.h in Headers */, 92FC0AEA207CEE16007B6B54 /* MGLShapeOfflineRegion.h in Headers */, 35D13AC31D3D19DD00AFB4E0 /* MGLFillStyleLayer.h in Headers */, @@ -2397,6 +2406,7 @@ 1F2B94C1221636D900210640 /* MGLNetworkConfiguration_Private.h in Headers */, 35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */, 96E516F32000597100A02306 /* NSDictionary+MGLAdditions.h in Headers */, + 4BC5769425E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h in Headers */, 1FCAE2A920B88B3800C577DD /* MGLLocationManager_Private.h in Headers */, 96E516F02000595800A02306 /* NSBundle+MGLAdditions.h in Headers */, 96E516F920005A3500A02306 /* MGLFaux3DUserLocationAnnotationView.h in Headers */, @@ -2529,7 +2539,7 @@ ); name = iosapp; productName = iosapp; - productReference = DA1DC94A1CB6C1C2006E619F /* Mapbox GL.app */; + productReference = DA1DC94A1CB6C1C2006E619F /* MapLibre GL.app */; productType = "com.apple.product-type.application"; }; DA2E88501CC036F400F24E7B /* test */ = { @@ -2645,11 +2655,13 @@ }; DA1DC9491CB6C1C2006E619F = { CreatedOnToolsVersion = 7.3; - DevelopmentTeam = GJZR2MEM28; + DevelopmentTeam = KBDAWM7T4E; LastSwiftMigration = 0820; + ProvisioningStyle = Manual; }; DA2E88501CC036F400F24E7B = { CreatedOnToolsVersion = 7.3; + DevelopmentTeam = V6F7X5J9Y7; LastSwiftMigration = 1010; }; DA8847D11CBAF91600AB86E3 = { @@ -2664,7 +2676,8 @@ }; DABCABA71CB80692000A7C39 = { CreatedOnToolsVersion = 7.3; - DevelopmentTeam = GJZR2MEM28; + DevelopmentTeam = KBDAWM7T4E; + ProvisioningStyle = Manual; }; }; }; @@ -2985,7 +2998,6 @@ 3510FFEC1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */, DAED38651D62D0FC00D7640F /* NSURL+MGLAdditions.m in Sources */, 354B83981D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */, - DA88485D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m in Sources */, DAD165701CF41981001FF4B9 /* MGLFeature.mm in Sources */, 30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */, 550570C622958FB400228ECF /* MGLMapView+Impl.mm in Sources */, @@ -3033,6 +3045,7 @@ 35D13AB91D3D15E300AFB4E0 /* MGLStyleLayer.mm in Sources */, 74CB5EB3219B252C00102936 /* MGLStyleLayerManager.mm in Sources */, DA35A2CB1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */, + 4BC576C925E443CE006E06EB /* MGLFaux3DUserLocationAnnotationView.mm in Sources */, 071BBB001EE7613F001FB02A /* MGLImageSource.mm in Sources */, DA8848321CBAFA6200AB86E3 /* NSString+MGLAdditions.m in Sources */, 408AA8581DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */, @@ -3062,6 +3075,7 @@ DA8848241CBAFA6200AB86E3 /* MGLOfflineStorage.mm in Sources */, DA88482A1CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm in Sources */, 4049C29F1DB6CD6C00B3F799 /* MGLPointCollection.mm in Sources */, + 4BC5769525E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m in Sources */, 35136D3F1D42273000C20EFD /* MGLLineStyleLayer.mm in Sources */, DA704CC41F65A475004B3F28 /* MGLMapAccessibilityElement.mm in Sources */, DA72620D1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm in Sources */, @@ -3128,6 +3142,7 @@ DA35A2CC1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */, 408AA8591DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */, 74CB5EB4219B252C00102936 /* MGLStyleLayerManager.mm in Sources */, + 4BC576CA25E443CE006E06EB /* MGLFaux3DUserLocationAnnotationView.mm in Sources */, DAA4E4281CBB730400178DFB /* MGLTypes.m in Sources */, DA35A2A21CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */, 357FE2E01E02D2B20068B753 /* NSCoder+MGLAdditions.mm in Sources */, @@ -3145,7 +3160,6 @@ 355AE0021E9281DA00F3939D /* MGLScaleBar.mm in Sources */, 4018B1C81CDC287F00F666AF /* MGLAnnotationView.mm in Sources */, 07D8C6FB1F67560100381808 /* MGLComputedShapeSource.mm in Sources */, - DAA4E4341CBB730400178DFB /* MGLFaux3DUserLocationAnnotationView.m in Sources */, DACA86292019218600E9693A /* MGLRasterDEMSource.mm in Sources */, 35B82BFB1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */, 966FCF4F1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m in Sources */, @@ -3158,6 +3172,7 @@ 4049C2A01DB6CD6C00B3F799 /* MGLPointCollection.mm in Sources */, 35136D401D42273000C20EFD /* MGLLineStyleLayer.mm in Sources */, DA704CC51F65A475004B3F28 /* MGLMapAccessibilityElement.mm in Sources */, + 4BC5769625E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m in Sources */, DA72620E1DEEE3480043BB89 /* MGLOpenGLStyleLayer.mm in Sources */, DAA4E42F1CBB730400178DFB /* MGLCompactCalloutView.m in Sources */, 3510FFFC1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm in Sources */, @@ -3490,6 +3505,8 @@ 96AF1AA321B615A3007CB696 /* RelWithDebInfo */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -3516,11 +3533,13 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO; - DEVELOPMENT_TEAM = GJZR2MEM28; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = KBDAWM7T4E; INFOPLIST_FILE = app/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL; - PRODUCT_NAME = "Mapbox GL"; + PRODUCT_BUNDLE_IDENTIFIER = org.maplibre.maplibregl; + PRODUCT_NAME = "MapLibre GL"; + PROVISIONING_PROFILE_SPECIFIER = "MapLibre GL TestApp Development"; }; name = RelWithDebInfo; }; @@ -3528,7 +3547,10 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = GJZR2MEM28; + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LIBRARY = "libc++"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = KBDAWM7T4E; HEADER_SEARCH_PATHS = ( "$(PROJECT_DIR)/../../../../include", "$(PROJECT_DIR)/../../../default/include", @@ -3545,9 +3567,11 @@ "$(PROJECT_DIR)/../../../darwin/include", ); INFOPLIST_FILE = benchmark/Info.plist; + LD_GENERATE_MAP_FILE = YES; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.bench; + PRODUCT_BUNDLE_IDENTIFIER = org.maplibre.bench; PRODUCT_NAME = "Bench GL"; + PROVISIONING_PROFILE_SPECIFIER = "MapLibre GL Bench Development"; }; name = RelWithDebInfo; }; @@ -3629,6 +3653,8 @@ baseConfigurationReference = CAE5AE2B2389FBF000E4A5A1 /* ios.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + DEVELOPMENT_TEAM = V6F7X5J9Y7; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; OTHER_CFLAGS = "-fvisibility=hidden"; @@ -3708,6 +3734,8 @@ DA1DC95F1CB6C1C2006E619F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -3732,6 +3760,8 @@ DA1DC9601CB6C1C2006E619F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -3758,11 +3788,13 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO; - DEVELOPMENT_TEAM = GJZR2MEM28; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = KBDAWM7T4E; INFOPLIST_FILE = app/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL; - PRODUCT_NAME = "Mapbox GL"; + PRODUCT_BUNDLE_IDENTIFIER = org.maplibre.maplibregl; + PRODUCT_NAME = "MapLibre GL"; + PROVISIONING_PROFILE_SPECIFIER = "MapLibre GL TestApp Development"; }; name = Debug; }; @@ -3773,11 +3805,13 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_LOCALIZABILITY_EMPTY_CONTEXT = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO; - DEVELOPMENT_TEAM = GJZR2MEM28; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = KBDAWM7T4E; INFOPLIST_FILE = app/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL; - PRODUCT_NAME = "Mapbox GL"; + PRODUCT_BUNDLE_IDENTIFIER = org.maplibre.maplibregl; + PRODUCT_NAME = "MapLibre GL"; + PROVISIONING_PROFILE_SPECIFIER = "MapLibre GL TestApp Development"; }; name = Release; }; @@ -3786,6 +3820,8 @@ baseConfigurationReference = CAE5AE2B2389FBF000E4A5A1 /* ios.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + DEVELOPMENT_TEAM = V6F7X5J9Y7; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; OTHER_CFLAGS = "-fvisibility=hidden"; @@ -3813,6 +3849,8 @@ baseConfigurationReference = CAE5AE2B2389FBF000E4A5A1 /* ios.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; + DEVELOPMENT_TEAM = V6F7X5J9Y7; INFOPLIST_FILE = test/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; OTHER_CFLAGS = "-fvisibility=hidden"; @@ -3985,7 +4023,10 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = GJZR2MEM28; + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LIBRARY = "libc++"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = KBDAWM7T4E; HEADER_SEARCH_PATHS = ( "$(PROJECT_DIR)/../../../../include", "$(PROJECT_DIR)/../../../default/include", @@ -4002,9 +4043,11 @@ "$(PROJECT_DIR)/../../../platform/darwin/include", ); INFOPLIST_FILE = benchmark/Info.plist; + LD_GENERATE_MAP_FILE = YES; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.bench; + PRODUCT_BUNDLE_IDENTIFIER = org.maplibre.bench; PRODUCT_NAME = "Bench GL"; + PROVISIONING_PROFILE_SPECIFIER = "MapLibre GL Bench Development"; }; name = Debug; }; @@ -4012,7 +4055,10 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = GJZR2MEM28; + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LIBRARY = "libc++"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = KBDAWM7T4E; HEADER_SEARCH_PATHS = ( "$(PROJECT_DIR)/../../../../include", "$(PROJECT_DIR)/../../../default/include", @@ -4029,9 +4075,11 @@ "$(PROJECT_DIR)/../../../platform/darwin/include", ); INFOPLIST_FILE = benchmark/Info.plist; + LD_GENERATE_MAP_FILE = YES; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.bench; + PRODUCT_BUNDLE_IDENTIFIER = org.maplibre.bench; PRODUCT_NAME = "Bench GL"; + PROVISIONING_PROFILE_SPECIFIER = "MapLibre GL Bench Development"; }; name = Release; }; diff --git a/platform/ios/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m b/platform/ios/platform/ios/src/MGLFaux3DUserLocationAnnotationView.mm similarity index 64% rename from platform/ios/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m rename to platform/ios/platform/ios/src/MGLFaux3DUserLocationAnnotationView.mm index 30ab7de26..8a68fb5bc 100644 --- a/platform/ios/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m +++ b/platform/ios/platform/ios/src/MGLFaux3DUserLocationAnnotationView.mm @@ -1,10 +1,13 @@ #import "MGLFaux3DUserLocationAnnotationView.h" -#import "MGLMapView.h" +#import "MGLMapView_Private.h" +#import "MGLMapViewDelegate.h" #import "MGLUserLocation.h" #import "MGLUserLocationHeadingIndicator.h" #import "MGLUserLocationHeadingArrowLayer.h" #import "MGLUserLocationHeadingBeamLayer.h" +#import "MGLLocationManager_Private.h" +#import "MGLUserLocationAnnotationViewStyle.h" const CGFloat MGLUserLocationAnnotationDotSize = 22.0; const CGFloat MGLUserLocationAnnotationHaloSize = 115.0; @@ -14,9 +17,12 @@ const CGFloat MGLUserLocationAnnotationArrowSize = MGLUserLocationAnnotationPuck const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; +const CGFloat MGLUserLocationApproximateZoomThreshold = 7.0; + @implementation MGLFaux3DUserLocationAnnotationView { BOOL _puckModeActivated; + BOOL _approximateModeActivated; CALayer *_puckDot; CAShapeLayer *_puckArrow; @@ -26,6 +32,8 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; CALayer *_dotBorderLayer; CALayer *_dotLayer; CALayer *_haloLayer; + + CALayer *_approximateLayer; CLLocationDirection _oldHeadingAccuracy; CLLocationAccuracy _oldHorizontalAccuracy; @@ -49,29 +57,80 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; if (CLLocationCoordinate2DIsValid(self.userLocation.coordinate)) { - (self.mapView.userTrackingMode == MGLUserTrackingModeFollowWithCourse) ? [self drawPuck] : [self drawDot]; - [self updatePitch]; + if (@available(iOS 14, *)) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 + if (![self.mapView.locationManager respondsToSelector:@selector(accuracyAuthorization)] || + self.mapView.locationManager.accuracyAuthorization == CLAccuracyAuthorizationFullAccuracy) { + [self drawPreciseLocationPuck]; + } else { + [self drawApproximate]; + [self updatePitch]; + } +#endif + } else { + [self drawPreciseLocationPuck]; + } + } + +} + +- (void)drawPreciseLocationPuck { + if (_approximateModeActivated) { + [_approximateLayer removeFromSuperlayer]; + _approximateLayer = nil; + + _approximateModeActivated = NO; + } + (self.mapView.userTrackingMode == MGLUserTrackingModeFollowWithCourse) ? [self drawPuck] : [self drawDot]; + [self updatePitch]; _haloLayer.hidden = ! CLLocationCoordinate2DIsValid(self.mapView.userLocation.coordinate) || self.mapView.userLocation.location.horizontalAccuracy > 10; } - (void)setTintColor:(UIColor *)tintColor { - CGColorRef newTintColor = [tintColor CGColor]; - + UIColor *puckArrowFillColor = tintColor; + UIColor *puckArrowStrokeColor = tintColor; + + UIColor *approximateFillColor = tintColor; + + UIColor *accuracyFillColor = tintColor; + UIColor *haloFillColor = tintColor; + UIColor *dotFillColor = tintColor; + UIColor *headingFillColor = tintColor; + + if ([self.mapView.delegate respondsToSelector:@selector(mapViewStyleForDefaultUserLocationAnnotationView:)]) { + MGLUserLocationAnnotationViewStyle *style = [self.mapView.delegate mapViewStyleForDefaultUserLocationAnnotationView:self.mapView]; + + puckArrowFillColor = style.puckArrowFillColor ? style.puckArrowFillColor : puckArrowFillColor; + + if (@available(iOS 14, *)) { + approximateFillColor = style.approximateHaloFillColor ? style.approximateHaloFillColor : approximateFillColor; + } + + haloFillColor = style.haloFillColor ? style.haloFillColor : haloFillColor; + dotFillColor = style.puckFillColor ? style.puckFillColor : dotFillColor; + headingFillColor = style.puckFillColor ? style.puckFillColor : headingFillColor; + } + if (_puckModeActivated) { - _puckArrow.fillColor = newTintColor; - _puckArrow.strokeColor = newTintColor; + _puckArrow.fillColor = [puckArrowFillColor CGColor]; + _puckArrow.strokeColor = [puckArrowStrokeColor CGColor]; + } + else if (_approximateModeActivated) + { + _approximateLayer.backgroundColor = [approximateFillColor CGColor]; } else { - _accuracyRingLayer.backgroundColor = newTintColor; - _haloLayer.backgroundColor = newTintColor; - _dotLayer.backgroundColor = newTintColor; - [_headingIndicatorLayer updateTintColor:newTintColor]; + _accuracyRingLayer.backgroundColor = [accuracyFillColor CGColor]; + _haloLayer.backgroundColor = [haloFillColor CGColor]; + _dotLayer.backgroundColor = [dotFillColor CGColor]; + [_headingIndicatorLayer updateTintColor:[headingFillColor CGColor]]; } + } - (void)updatePitch @@ -145,6 +204,18 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; [self updateFrameWithSize:MGLUserLocationAnnotationPuckSize]; } + + UIColor *arrowColor = self.mapView.tintColor; + UIColor *puckShadowColor = UIColor.blackColor; + CGFloat shadowOpacity = 0.25; + + + if ([self.mapView.delegate respondsToSelector:@selector(mapViewStyleForDefaultUserLocationAnnotationView:)]) { + MGLUserLocationAnnotationViewStyle *style = [self.mapView.delegate mapViewStyleForDefaultUserLocationAnnotationView:self.mapView]; + arrowColor = style.puckArrowFillColor ? style.puckArrowFillColor : arrowColor; + puckShadowColor = style.puckShadowColor ? style.puckShadowColor : puckShadowColor; + shadowOpacity = style.puckShadowOpacity; + } // background dot (white with black shadow) // @@ -152,8 +223,8 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; { _puckDot = [self circleLayerWithSize:MGLUserLocationAnnotationPuckSize]; _puckDot.backgroundColor = [[UIColor whiteColor] CGColor]; - _puckDot.shadowColor = [[UIColor blackColor] CGColor]; - _puckDot.shadowOpacity = 0.25; + _puckDot.shadowColor = [puckShadowColor CGColor]; + _puckDot.shadowOpacity = shadowOpacity; _puckDot.shadowPath = [[UIBezierPath bezierPathWithOvalInRect:_puckDot.bounds] CGPath]; if (self.mapView.camera.pitch) @@ -175,7 +246,7 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; { _puckArrow = [CAShapeLayer layer]; _puckArrow.path = [[self puckArrow] CGPath]; - _puckArrow.fillColor = [self.mapView.tintColor CGColor]; + _puckArrow.fillColor = [arrowColor CGColor]; _puckArrow.bounds = CGRectMake(0, 0, round(MGLUserLocationAnnotationArrowSize), round(MGLUserLocationAnnotationArrowSize)); _puckArrow.position = CGPointMake(CGRectGetMidX(super.bounds), CGRectGetMidY(super.bounds)); _puckArrow.shouldRasterize = YES; @@ -227,6 +298,20 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; [self updateFrameWithSize:MGLUserLocationAnnotationDotSize]; } + + UIColor *haloColor = self.mapView.tintColor; + UIColor *puckBackgroundColor = self.mapView.tintColor; + UIColor *puckShadowColor = UIColor.blackColor; + CGFloat shadowOpacity = 0.25; + + + if ([self.mapView.delegate respondsToSelector:@selector(mapViewStyleForDefaultUserLocationAnnotationView:)]) { + MGLUserLocationAnnotationViewStyle *style = [self.mapView.delegate mapViewStyleForDefaultUserLocationAnnotationView:self.mapView]; + haloColor = style.haloFillColor ? style.haloFillColor : haloColor; + puckBackgroundColor = style.puckFillColor ? style.puckFillColor : puckBackgroundColor; + puckShadowColor = style.puckShadowColor ? style.puckShadowColor : puckShadowColor; + shadowOpacity = style.puckShadowOpacity; + } // heading indicator (tinted, beam or arrow) // @@ -251,11 +336,13 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; if (headingTrackingModeEnabled) { _headingIndicatorLayer = [[MGLUserLocationHeadingBeamLayer alloc] initWithUserLocationAnnotationView:self]; + [_headingIndicatorLayer updateTintColor:[haloColor CGColor]]; [self.layer insertSublayer:_headingIndicatorLayer below:_dotBorderLayer]; } else { _headingIndicatorLayer = [[MGLUserLocationHeadingArrowLayer alloc] initWithUserLocationAnnotationView:self]; + [_headingIndicatorLayer updateTintColor:[puckBackgroundColor CGColor]]; [self.layer addSublayer:_headingIndicatorLayer]; _headingIndicatorLayer.zPosition = 1; } @@ -294,7 +381,7 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; // if (_accuracyRingLayer && (_oldZoom != self.mapView.zoomLevel || _oldHorizontalAccuracy != self.userLocation.location.horizontalAccuracy)) { - CGFloat accuracyRingSize = [self calculateAccuracyRingSize]; + CGFloat accuracyRingSize = [self calculateAccuracyRingSize: self.mapView.zoomLevel]; // only show the accuracy ring if it won't be obscured by the location dot if (accuracyRingSize > MGLUserLocationAnnotationDotSize + 15) @@ -336,7 +423,7 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; // if ( ! _accuracyRingLayer && self.userLocation.location.horizontalAccuracy) { - CGFloat accuracyRingSize = [self calculateAccuracyRingSize]; + CGFloat accuracyRingSize = [self calculateAccuracyRingSize: self.mapView.zoomLevel]; _accuracyRingLayer = [self circleLayerWithSize:accuracyRingSize]; _accuracyRingLayer.backgroundColor = [self.mapView.tintColor CGColor]; _accuracyRingLayer.opacity = 0.1; @@ -351,7 +438,7 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; if ( ! _haloLayer) { _haloLayer = [self circleLayerWithSize:MGLUserLocationAnnotationHaloSize]; - _haloLayer.backgroundColor = [self.mapView.tintColor CGColor]; + _haloLayer.backgroundColor = [haloColor CGColor]; _haloLayer.allowsGroupOpacity = NO; _haloLayer.zPosition = -0.1f; @@ -381,8 +468,8 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; { _dotBorderLayer = [self circleLayerWithSize:MGLUserLocationAnnotationDotSize]; _dotBorderLayer.backgroundColor = [[UIColor whiteColor] CGColor]; - _dotBorderLayer.shadowColor = [[UIColor blackColor] CGColor]; - _dotBorderLayer.shadowOpacity = 0.25; + _dotBorderLayer.shadowColor = [puckShadowColor CGColor]; + _dotBorderLayer.shadowOpacity = shadowOpacity; _dotBorderLayer.shadowPath = [[UIBezierPath bezierPathWithOvalInRect:_dotBorderLayer.bounds] CGPath]; if (self.mapView.camera.pitch) @@ -403,7 +490,7 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; if ( ! _dotLayer) { _dotLayer = [self circleLayerWithSize:MGLUserLocationAnnotationDotSize * 0.75]; - _dotLayer.backgroundColor = [self.mapView.tintColor CGColor]; + _dotLayer.backgroundColor = [puckBackgroundColor CGColor]; // set defaults for the animations CAAnimationGroup *animationGroup = [self loopingAnimationGroupWithDuration:1.5]; @@ -433,6 +520,86 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; [self updateFaux3DEffect]; } + +} + +- (void)drawApproximate +{ + + if ( ! _approximateModeActivated) + { + self.layer.sublayers = nil; + + _headingIndicatorLayer = nil; + _dotBorderLayer = nil; + _dotLayer = nil; + _accuracyRingLayer = nil; + _haloLayer = nil; + _puckDot = nil; + _puckArrow = nil; + + _approximateModeActivated = YES; + } + + UIColor *backgroundColor = self.mapView.tintColor; + UIColor *strokeColor = UIColor.blackColor; + CGFloat borderSize = 2.0; + CGFloat opacity = 0.25; + + if ([self.mapView.delegate respondsToSelector:@selector(mapViewStyleForDefaultUserLocationAnnotationView:)]) { + MGLUserLocationAnnotationViewStyle *style = [self.mapView.delegate mapViewStyleForDefaultUserLocationAnnotationView:self.mapView]; + if (@available(iOS 14, *)) { + backgroundColor = style.approximateHaloFillColor ? style.approximateHaloFillColor : backgroundColor; + strokeColor = style.approximateHaloBorderColor ? style.approximateHaloBorderColor : strokeColor; + opacity = style.approximateHaloOpacity; + borderSize = style.approximateHaloBorderWidth; + } + } + + // approximate ring + if ( ! _approximateLayer && self.userLocation.location.horizontalAccuracy) + { + CGFloat accuracyRingSize = [self calculateAccuracyRingSize: MAX(self.mapView.zoomLevel, MGLUserLocationApproximateZoomThreshold)]; + _approximateLayer = [self circleLayerWithSize:accuracyRingSize]; + _approximateLayer.backgroundColor = [backgroundColor CGColor]; + _approximateLayer.opacity = opacity; + _approximateLayer.shouldRasterize = NO; + _approximateLayer.allowsGroupOpacity = NO; + _approximateLayer.borderWidth = borderSize; + _approximateLayer.borderColor = [strokeColor CGColor]; + + [self.layer addSublayer:_approximateLayer]; + } + + // update approximate ring (if zoom or horizontal accuracy have changed) + if (_approximateLayer && (_oldZoom != self.mapView.zoomLevel || _oldHorizontalAccuracy != self.userLocation.location.horizontalAccuracy)) + { + if (self.mapView.zoomLevel < MGLUserLocationApproximateZoomThreshold) { + borderSize = 1.0; + } + _approximateLayer.borderWidth = borderSize; + + if (self.mapView.zoomLevel >= MGLUserLocationApproximateZoomThreshold) { + CGFloat accuracyRingSize = [self calculateAccuracyRingSize: self.mapView.zoomLevel]; + + _approximateLayer.hidden = NO; + + // disable implicit animation of the accuracy ring, unless triggered by a change in accuracy + BOOL shouldDisableActions = _oldHorizontalAccuracy == self.userLocation.location.horizontalAccuracy; + + [CATransaction begin]; + [CATransaction setDisableActions:shouldDisableActions]; + + _approximateLayer.bounds = CGRectMake(0, 0, accuracyRingSize, accuracyRingSize); + _approximateLayer.cornerRadius = accuracyRingSize / 2.0; + + [CATransaction commit]; + } + + // store accuracy and zoom so we're not redrawing unchanged location updates + _oldHorizontalAccuracy = self.userLocation.location.horizontalAccuracy; + _oldZoom = self.mapView.zoomLevel; + } } - (CALayer *)circleLayerWithSize:(CGFloat)layerSize @@ -461,10 +628,10 @@ const CGFloat MGLUserLocationHeadingUpdateThreshold = 0.01; return animationGroup; } -- (CGFloat)calculateAccuracyRingSize +- (CGFloat)calculateAccuracyRingSize:(double)zoomLevel { // diameter in screen points - return round(self.userLocation.location.horizontalAccuracy / [self.mapView metersPerPointAtLatitude:self.userLocation.coordinate.latitude] * 2.0); + return round(self.userLocation.location.horizontalAccuracy / [self.mapView metersPerPointAtLatitude:self.userLocation.coordinate.latitude zoomLevel:zoomLevel] * 2.0); } @end diff --git a/platform/ios/platform/ios/src/MGLMapView.mm b/platform/ios/platform/ios/src/MGLMapView.mm index f16883b22..c17ba1bec 100644 --- a/platform/ios/platform/ios/src/MGLMapView.mm +++ b/platform/ios/platform/ios/src/MGLMapView.mm @@ -517,7 +517,7 @@ public: _annotationViewReuseQueueByIdentifier = [NSMutableDictionary dictionary]; _selectedAnnotationTag = MGLAnnotationTagNotFound; _annotationsNearbyLastTap = {}; - + // TODO: This warning should be removed when automaticallyAdjustsScrollViewInsets is removed from // the UIViewController api. static dispatch_once_t onceToken; @@ -4056,6 +4056,11 @@ public: return mbgl::Projection::getMetersPerPixelAtLatitude(latitude, self.zoomLevel); } +- (CLLocationDistance)metersPerPointAtLatitude:(CLLocationDegrees)latitude zoomLevel:(double)zoomLevel +{ + return mbgl::Projection::getMetersPerPixelAtLatitude(latitude, zoomLevel); +} + #pragma mark - Camera Change Reason - - (void)resetCameraChangeReason @@ -5417,6 +5422,11 @@ public: } } +- (NSString *)accuracyDescriptionString { + NSDictionary *dictionary = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationTemporaryUsageDescriptionDictionary"]; + return dictionary[@"MGLAccuracyAuthorizationDescription"]; +} + - (void)setShowsUserLocation:(BOOL)showsUserLocation { MGLLogDebug(@"Setting showsUserLocation: %@", MGLStringFromBOOL(showsUserLocation)); @@ -5975,6 +5985,47 @@ public: } } +- (void)locationManagerDidChangeAuthorization:(id)manager +{ + if (![self shouldShowLocationDotBasedOnCurrentLocationPermissions]) + { + [self.userLocationAnnotationView removeFromSuperview]; + [self.locationManager stopUpdatingLocation]; + [self.locationManager stopUpdatingHeading]; + } else { + if (@available(iOS 14, *)) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000 + if (self.userTrackingMode != MGLUserTrackingModeNone && + [manager respondsToSelector:@selector(authorizationStatus)] && + (manager.authorizationStatus != kCLAuthorizationStatusRestricted || + manager.authorizationStatus != kCLAuthorizationStatusAuthorizedAlways || + manager.authorizationStatus != kCLAuthorizationStatusAuthorizedWhenInUse) && + [manager respondsToSelector:@selector(accuracyAuthorization)] && + manager.accuracyAuthorization == CLAccuracyAuthorizationReducedAccuracy && + [self accuracyDescriptionString] != nil ) { + [self.locationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:@"MGLAccuracyAuthorizationDescription"]; + } else { + [self validateLocationServices]; + } +#endif + } else { + [self validateLocationServices]; + } + } + + if (@available(iOS 14, *)) { + if ([self.delegate respondsToSelector:@selector(mapView:didChangeLocationManagerAuthorization:)]) { + [self.delegate mapView:self didChangeLocationManagerAuthorization:manager]; + } + } +} + +- (BOOL)shouldShowLocationDotBasedOnCurrentLocationPermissions +{ + return self.locationManager && (self.locationManager.authorizationStatus == kCLAuthorizationStatusAuthorizedAlways + || self.locationManager.authorizationStatus == kCLAuthorizationStatusAuthorizedWhenInUse); +} + - (void)updateHeadingForDeviceOrientation { if (self.locationManager) diff --git a/platform/ios/platform/ios/src/MGLMapViewDelegate.h b/platform/ios/platform/ios/src/MGLMapViewDelegate.h index 3ddb7b007..e3ba90e05 100644 --- a/platform/ios/platform/ios/src/MGLMapViewDelegate.h +++ b/platform/ios/platform/ios/src/MGLMapViewDelegate.h @@ -6,6 +6,7 @@ NS_ASSUME_NONNULL_BEGIN @class MGLMapView; +@class MGLUserLocationAnnotationViewStyle; /** The `MGLMapViewDelegate` protocol defines a set of optional methods that you @@ -313,6 +314,16 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)mapViewDidStopLocatingUser:(MGLMapView *)mapView; +/** + Asks the delegate styling options for each default user location annotation view. + + This method is called many times during gesturing, so you should avoid performing + complex or performance-intensive tasks in your implementation. + + @param mapView The map view that is tracking the user’s location. + */ +- (MGLUserLocationAnnotationViewStyle *)mapViewStyleForDefaultUserLocationAnnotationView:(MGLMapView *)mapView NS_SWIFT_NAME(mapView(styleForDefaultUserLocationAnnotationView:)); + /** Tells the delegate that the location of the user was updated. @@ -368,6 +379,18 @@ NS_ASSUME_NONNULL_BEGIN */ - (CGPoint)mapViewUserLocationAnchorPoint:(MGLMapView *)mapView; +/** + Tells the delegate that the map's location updates accuracy authorization has changed. + + This method is called after the user changes location accuracy authorization when + requesting location permissions or in privacy settings. + + @param mapView The map view that changed its location accuracy authorization. + @param manager The location manager reporting the update. + + */ +- (void)mapView:(MGLMapView *)mapView didChangeLocationManagerAuthorization:(id)manager API_AVAILABLE(ios(14)); + #pragma mark Managing the Appearance of Annotations /** diff --git a/platform/ios/platform/ios/src/MGLMapView_Private.h b/platform/ios/platform/ios/src/MGLMapView_Private.h index 155527000..bb34644f2 100644 --- a/platform/ios/platform/ios/src/MGLMapView_Private.h +++ b/platform/ios/platform/ios/src/MGLMapView_Private.h @@ -46,6 +46,8 @@ FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const _Nonnull MGLUnderlyingMapUna - (void)didFailToLoadImage:(nonnull NSString *)imageName; - (BOOL)shouldRemoveStyleImage:(nonnull NSString *)imageName; +- (CLLocationDistance)metersPerPointAtLatitude:(CLLocationDegrees)latitude zoomLevel:(double)zoomLevel; + /** Triggers another render pass even when it is not necessary. */ - (void)setNeedsRerender; diff --git a/platform/ios/platform/ios/src/MGLUserLocationAnnotationViewStyle.h b/platform/ios/platform/ios/src/MGLUserLocationAnnotationViewStyle.h new file mode 100644 index 000000000..26c580a4c --- /dev/null +++ b/platform/ios/platform/ios/src/MGLUserLocationAnnotationViewStyle.h @@ -0,0 +1,57 @@ +#import + +#import "MGLFoundation.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + A class containing information about the default User Location annotation view style. + */ +MGL_EXPORT +@interface MGLUserLocationAnnotationViewStyle : NSObject + +/** + The fill color for the puck view. + */ +@property (nonatomic) UIColor *puckFillColor; +/** + The shadow color for the puck view. + */ +@property (nonatomic) UIColor *puckShadowColor; +/** + The shadow opacity for the puck view. + Set any value between 0.0 and 1.0. + The default value of this property is equal to `0.25` + */ +@property (nonatomic, assign) CGFloat puckShadowOpacity; +/** + The fill color for the arrow puck. + */ +@property (nonatomic) UIColor *puckArrowFillColor; +/** + The fill color for the puck view. + */ +@property (nonatomic) UIColor *haloFillColor; +/** + The halo fill color for the approximate view. + */ +@property (nonatomic) UIColor *approximateHaloFillColor API_AVAILABLE(ios(14)); +/** + The halo border color for the approximate view. + */ +@property (nonatomic) UIColor *approximateHaloBorderColor API_AVAILABLE(ios(14)); +/** + The halo border width for the approximate view. + The default value of this property is equal to `2.0` + */ +@property (nonatomic, assign) CGFloat approximateHaloBorderWidth API_AVAILABLE(ios(14)); +/** + The halo opacity for the approximate view. + Set any value between 0.0 and 1.0 + The default value of this property is equal to `0.15` + */ +@property (nonatomic, assign) CGFloat approximateHaloOpacity API_AVAILABLE(ios(14)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/ios/platform/ios/src/MGLUserLocationAnnotationViewStyle.m b/platform/ios/platform/ios/src/MGLUserLocationAnnotationViewStyle.m new file mode 100644 index 000000000..3857a9c9e --- /dev/null +++ b/platform/ios/platform/ios/src/MGLUserLocationAnnotationViewStyle.m @@ -0,0 +1,62 @@ +#import "MGLUserLocationAnnotationViewStyle.h" +#import "MGLLoggingConfiguration_Private.h" + +@implementation MGLUserLocationAnnotationViewStyle + +- (instancetype)init { + if ((self = [super init])) { + self.puckShadowOpacity = 0.25; + if (@available(iOS 14, *)) { + self.approximateHaloBorderWidth = 2.0; + self.approximateHaloOpacity = 0.15; + } + } + return self; +} + +- (void)setPuckFillColor:(UIColor *)puckFillColor { + MGLLogDebug(@"Setting puckFillColor: %@", puckFillColor); + _puckFillColor = puckFillColor; +} + +- (void)setPuckShadowColor:(UIColor *)puckShadowColor { + MGLLogDebug(@"Setting puckShadowColor: %@", puckShadowColor); + _puckShadowColor = puckShadowColor; +} + +- (void)setPuckShadowOpacity:(CGFloat)puckShadowOpacity { + MGLLogDebug(@"Setting puckShadowOpacity: %.2f", puckShadowOpacity); + _puckShadowOpacity = puckShadowOpacity; +} + +- (void)setPuckArrowFillColor:(UIColor *)puckArrowFillColor { + MGLLogDebug(@"Setting puckArrowFillColor: %@", puckArrowFillColor); + _puckArrowFillColor = puckArrowFillColor; +} + +- (void)setHaloFillColor:(UIColor *)haloFillColor { + MGLLogDebug(@"Setting haloFillColor: %@", haloFillColor); + _haloFillColor = haloFillColor; +} + +- (void)setApproximateHaloFillColor:(UIColor *)approximateHaloFillColor { + MGLLogDebug(@"Setting approximateHaloFillColor: %@", approximateHaloFillColor); + _approximateHaloFillColor = approximateHaloFillColor; +} + +- (void)setApproximateHaloBorderColor:(UIColor *)approximateHaloBorderColor { + MGLLogDebug(@"Setting approximateHaloBorderColor: %@", approximateHaloBorderColor); + _approximateHaloBorderColor = approximateHaloBorderColor; +} + +- (void)setApproximateHaloBorderWidth:(CGFloat)approximateHaloBorderWidth { + MGLLogDebug(@"Setting approximateHaloBorderWidth: %.2f", approximateHaloBorderWidth); + _approximateHaloBorderWidth = approximateHaloBorderWidth; +} + +- (void)setApproximateHaloOpacity:(CGFloat)approximateHaloOpacity { + MGLLogDebug(@"Setting approximateHaloOpacity: %.2f", approximateHaloOpacity); + _approximateHaloOpacity = approximateHaloOpacity; +} + +@end \ No newline at end of file diff --git a/platform/ios/platform/ios/src/Mapbox.h b/platform/ios/platform/ios/src/Mapbox.h index b5fd86e85..c5d00ae2a 100644 --- a/platform/ios/platform/ios/src/Mapbox.h +++ b/platform/ios/platform/ios/src/Mapbox.h @@ -1,5 +1,4 @@ #import - #import "MGLFoundation.h" /// Project version number for Mapbox. @@ -8,69 +7,70 @@ FOUNDATION_EXPORT MGL_EXPORT double MapboxVersionNumber; /// Project version string for Mapbox. FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[]; -#import "MGLAnnotationView.h" #import "MGLAccountManager.h" #import "MGLAnnotation.h" #import "MGLAnnotationImage.h" +#import "MGLAnnotationView.h" +#import "MGLAttributedExpression.h" +#import "MGLAttributionInfo.h" +#import "MGLBackgroundStyleLayer.h" #import "MGLCalloutView.h" +#import "MGLCircleStyleLayer.h" #import "MGLClockDirectionFormatter.h" #import "MGLCluster.h" #import "MGLCompassButton.h" #import "MGLCompassDirectionFormatter.h" +#import "MGLComputedShapeSource.h" #import "MGLCoordinateFormatter.h" #import "MGLDistanceFormatter.h" #import "MGLFeature.h" +#import "MGLFillExtrusionStyleLayer.h" +#import "MGLFillStyleLayer.h" +#import "MGLForegroundStyleLayer.h" #import "MGLGeometry.h" +#import "MGLHeatmapStyleLayer.h" +#import "MGLHillshadeStyleLayer.h" +#import "MGLImageSource.h" #import "MGLLight.h" +#import "MGLLineStyleLayer.h" +#import "MGLLocationManager.h" +#import "MGLLoggingConfiguration.h" #import "MGLMapCamera.h" +#import "MGLMapSnapshotter.h" #import "MGLMapView.h" -#import "MGLMapView+IBAdditions.h" #import "MGLMapViewDelegate.h" +#import "MGLMapView+IBAdditions.h" #import "MGLMultiPoint.h" +#import "MGLNetworkConfiguration.h" #import "MGLOfflinePack.h" #import "MGLOfflineRegion.h" #import "MGLOfflineStorage.h" +#import "MGLOpenGLStyleLayer.h" #import "MGLOverlay.h" #import "MGLPointAnnotation.h" #import "MGLPointCollection.h" #import "MGLPolygon.h" #import "MGLPolyline.h" +#import "MGLRasterDEMSource.h" +#import "MGLRasterStyleLayer.h" +#import "MGLRasterTileSource.h" #import "MGLShape.h" #import "MGLShapeCollection.h" +#import "MGLShapeOfflineRegion.h" +#import "MGLShapeSource.h" +#import "MGLSource.h" #import "MGLStyle.h" #import "MGLStyleLayer.h" -#import "MGLForegroundStyleLayer.h" -#import "MGLVectorStyleLayer.h" -#import "MGLFillExtrusionStyleLayer.h" -#import "MGLFillStyleLayer.h" -#import "MGLLineStyleLayer.h" +#import "MGLStyleValue.h" #import "MGLSymbolStyleLayer.h" -#import "MGLRasterStyleLayer.h" -#import "MGLCircleStyleLayer.h" -#import "MGLHeatmapStyleLayer.h" -#import "MGLHillshadeStyleLayer.h" -#import "MGLBackgroundStyleLayer.h" -#import "MGLOpenGLStyleLayer.h" -#import "MGLSource.h" -#import "MGLTileSource.h" -#import "MGLVectorTileSource.h" -#import "MGLShapeSource.h" -#import "MGLComputedShapeSource.h" -#import "MGLRasterTileSource.h" -#import "MGLRasterDEMSource.h" -#import "MGLImageSource.h" -#import "MGLShapeOfflineRegion.h" #import "MGLTilePyramidOfflineRegion.h" +#import "MGLTileSource.h" #import "MGLTypes.h" #import "MGLUserLocation.h" #import "MGLUserLocationAnnotationView.h" -#import "NSValue+MGLAdditions.h" -#import "MGLStyleValue.h" -#import "MGLAttributionInfo.h" -#import "MGLMapSnapshotter.h" +#import "MGLVectorStyleLayer.h" +#import "MGLVectorTileSource.h" #import "NSExpression+MGLAdditions.h" #import "NSPredicate+MGLAdditions.h" -#import "MGLLocationManager.h" -#import "MGLLoggingConfiguration.h" -#import "MGLNetworkConfiguration.h" -#import "MGLAttributedExpression.h" +#import "NSValue+MGLAdditions.h" +#import "MGLUserLocationAnnotationViewStyle.h" \ No newline at end of file diff --git a/platform/ios/platform/ios/test/MGLMapViewDelegateIntegrationTests.swift b/platform/ios/platform/ios/test/MGLMapViewDelegateIntegrationTests.swift index 172538c65..d581183c7 100644 --- a/platform/ios/platform/ios/test/MGLMapViewDelegateIntegrationTests.swift +++ b/platform/ios/platform/ios/test/MGLMapViewDelegateIntegrationTests.swift @@ -100,4 +100,8 @@ extension MGLMapViewDelegateIntegrationTests: MGLMapViewDelegate { func mapView(_ mapView: MGLMapView, didFailToLoadImage imageName: String) -> UIImage? { return nil } func mapView(_ mapView: MGLMapView, shouldRemoveStyleImage imageName: String) -> Bool { return false } + + func mapView(_ mapView: MGLMapView, didChangeLocationManagerAuthorization manager: MGLLocationManager) {} + + func mapView(styleForDefaultUserLocationAnnotationView mapView: MGLMapView) -> MGLUserLocationAnnotationViewStyle { return MGLUserLocationAnnotationViewStyle() } }