summaryrefslogtreecommitdiff
path: root/platform/darwin/src
diff options
context:
space:
mode:
authorm-stephen <truestyle2005@163.com>2019-09-17 10:46:33 +0800
committerGitHub <noreply@github.com>2019-09-17 10:46:33 +0800
commiteb1f8eb32286dd7b89ae76b839b774b0071ca5a5 (patch)
tree0db6df1811ffb8c9a5139687817386dee23cfef1 /platform/darwin/src
parentb0018568b84f9bb1c185f0441a41741e9fde5a84 (diff)
parenta99240a54ffd5eb77568d41e10186411b1b759eb (diff)
downloadqtlocation-mapboxgl-eb1f8eb32286dd7b89ae76b839b774b0071ca5a5.tar.gz
Merge branch 'master' into stephen-ios-error-report
Diffstat (limited to 'platform/darwin/src')
-rw-r--r--platform/darwin/src/MGLAccountManager.m2
-rw-r--r--platform/darwin/src/MGLAccountManager_Private.h3
-rw-r--r--platform/darwin/src/MGLComputedShapeSource.mm3
-rw-r--r--platform/darwin/src/MGLForegroundStyleLayer.mm16
-rw-r--r--platform/darwin/src/MGLImageSource.mm19
-rw-r--r--platform/darwin/src/MGLMapSnapshotter.h34
-rw-r--r--platform/darwin/src/MGLMapSnapshotter.mm107
-rw-r--r--platform/darwin/src/MGLOfflineStorage.h10
-rw-r--r--platform/darwin/src/MGLRasterTileSource.mm2
-rw-r--r--platform/darwin/src/MGLRasterTileSource_Private.h2
-rw-r--r--platform/darwin/src/MGLRendererConfiguration.h3
-rw-r--r--platform/darwin/src/MGLRendererConfiguration.mm4
-rw-r--r--platform/darwin/src/MGLShapeSource.mm16
-rw-r--r--platform/darwin/src/MGLSource.h3
-rw-r--r--platform/darwin/src/MGLSource.mm15
-rw-r--r--platform/darwin/src/MGLSource_Private.h15
-rw-r--r--platform/darwin/src/MGLStyle.mm21
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm22
-rw-r--r--platform/darwin/src/MGLStyleLayer_Private.h1
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.h13
-rw-r--r--platform/darwin/src/MGLTypes.h4
-rw-r--r--platform/darwin/src/MGLVectorStyleLayer.m25
-rw-r--r--platform/darwin/src/MGLVectorStyleLayer.mm34
-rw-r--r--platform/darwin/src/MGLVectorTileSource.mm4
-rw-r--r--platform/darwin/src/http_file_source.mm19
-rw-r--r--platform/darwin/src/string_nsstring.mm4
26 files changed, 305 insertions, 96 deletions
diff --git a/platform/darwin/src/MGLAccountManager.m b/platform/darwin/src/MGLAccountManager.m
index 69170459bc..c37195967a 100644
--- a/platform/darwin/src/MGLAccountManager.m
+++ b/platform/darwin/src/MGLAccountManager.m
@@ -13,6 +13,8 @@ static NSString * const MGLAccountManagerExternalClassName = @"MBXAccounts";
static NSString * const MGLAccountManagerExternalMethodName = @"skuToken";
#endif
+NSString * const MGLMapboxAccountTypeKey = @"MGLMapboxAccountType";
+
@interface MGLAccountManager ()
@property (atomic) NSString *accessToken;
diff --git a/platform/darwin/src/MGLAccountManager_Private.h b/platform/darwin/src/MGLAccountManager_Private.h
index 3fd45f1ae8..4bf7963182 100644
--- a/platform/darwin/src/MGLAccountManager_Private.h
+++ b/platform/darwin/src/MGLAccountManager_Private.h
@@ -2,6 +2,9 @@
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.
diff --git a/platform/darwin/src/MGLComputedShapeSource.mm b/platform/darwin/src/MGLComputedShapeSource.mm
index 5110435b03..a04181af2f 100644
--- a/platform/darwin/src/MGLComputedShapeSource.mm
+++ b/platform/darwin/src/MGLComputedShapeSource.mm
@@ -199,6 +199,7 @@ mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDi
}
- (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);
@@ -236,10 +237,12 @@ mbgl::style::CustomGeometrySource::Options MBGLCustomGeometrySourceOptionsFromDi
}
- (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));
}
diff --git a/platform/darwin/src/MGLForegroundStyleLayer.mm b/platform/darwin/src/MGLForegroundStyleLayer.mm
index 76700d6f77..eaa5e83e59 100644
--- a/platform/darwin/src/MGLForegroundStyleLayer.mm
+++ b/platform/darwin/src/MGLForegroundStyleLayer.mm
@@ -1,4 +1,5 @@
#import "MGLForegroundStyleLayer.h"
+#import "MGLStyleLayer_Private.h"
@implementation MGLForegroundStyleLayer
@@ -9,10 +10,17 @@
}
- (NSString *)description {
- return [NSString stringWithFormat:
- @"<%@: %p; identifier = %@; sourceIdentifier = %@; visible = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier,
- self.sourceIdentifier, self.visible ? @"YES" : @"NO"];
+ 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/MGLImageSource.mm b/platform/darwin/src/MGLImageSource.mm
index 351247e901..421cc7a155 100644
--- a/platform/darwin/src/MGLImageSource.mm
+++ b/platform/darwin/src/MGLImageSource.mm
@@ -45,11 +45,13 @@
}
- (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;
@@ -59,6 +61,7 @@
}
- (void)setImage:(MGLImage *)image {
+ MGLAssertStyleSourceIsValid();
if (image != nullptr) {
self.rawSource->setImage(image.mgl_premultipliedImage);
} else {
@@ -68,16 +71,27 @@
}
- (MGLCoordinateQuad)coordinates {
+ MGLAssertStyleSourceIsValid();
return MGLCoordinateQuadFromLatLngArray(self.rawSource->getCoordinates());
}
- (void)setCoordinates: (MGLCoordinateQuad)coordinateQuad {
+ MGLAssertStyleSourceIsValid();
self.rawSource->setCoordinates(MGLLatLngArrayFromCoordinateQuad(coordinateQuad));
}
- (NSString *)description {
- return [NSString stringWithFormat:@"<%@: %p; identifier = %@; coordinates = %@; URL = %@; image = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier, MGLStringFromCoordinateQuad(self.coordinates), self.URL, self.image];
+ 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 {
@@ -85,6 +99,7 @@
}
- (NSString *)attributionHTMLString {
+ MGLAssertStyleSourceIsValid();
auto attribution = self.rawSource->getAttribution();
return attribution ? @(attribution->c_str()) : nil;
}
diff --git a/platform/darwin/src/MGLMapSnapshotter.h b/platform/darwin/src/MGLMapSnapshotter.h
index 1ee9bd99bb..0f20cf1bb2 100644
--- a/platform/darwin/src/MGLMapSnapshotter.h
+++ b/platform/darwin/src/MGLMapSnapshotter.h
@@ -6,6 +6,30 @@
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;
+
+@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
@@ -201,6 +225,16 @@ MGL_EXPORT
- (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 queue The queue to handle the result on.
+ @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
diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm
index 9ba0cbebfe..85619a780b 100644
--- a/platform/darwin/src/MGLMapSnapshotter.mm
+++ b/platform/darwin/src/MGLMapSnapshotter.mm
@@ -32,6 +32,26 @@
const CGPoint MGLLogoImagePosition = CGPointMake(8, 8);
const CGFloat MGLSnapshotterMinimumPixelSize = 64;
+
+@interface MGLMapSnapshotOverlay()
+
+- (instancetype)initWithContext:(CGContextRef)context;
+
+@end
+
+@implementation MGLMapSnapshotOverlay
+
+- (instancetype) initWithContext:(CGContextRef)context {
+ self = [super init];
+ if (self) {
+ _context = context;
+ }
+
+ return self;
+}
+
+@end
+
@implementation MGLMapSnapshotOptions
- (instancetype _Nonnull)initWithStyleURL:(nullable NSURL *)styleURL camera:(MGLMapCamera *)camera size:(CGSize)size
@@ -183,7 +203,15 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[self startWithQueue:dispatch_get_main_queue() completionHandler:completion];
}
-- (void)startWithQueue:(dispatch_queue_t)queue completionHandler:(MGLMapSnapshotCompletionHandler)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
@@ -210,8 +238,8 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
// 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) {
+ *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
@@ -227,12 +255,12 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
#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];
@@ -241,11 +269,12 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
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];
+
+ [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
@@ -253,7 +282,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
_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 {
++ (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];
@@ -295,7 +324,23 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
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];
+ 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();
@@ -362,6 +407,21 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[sourceImageRep drawInRect: targetFrame];
+ NSGraphicsContext *currentContext = [NSGraphicsContext currentContext];
+ if (currentContext && overlayHandler) {
+ MGLMapSnapshotOverlay *snapshotOverlay = [[MGLMapSnapshotOverlay alloc] initWithContext:currentContext.CGContext];
+ [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];
}
@@ -382,8 +442,8 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
#endif
}
-- (void)drawAttributedSnapshot:(mbgl::MapSnapshotter::Attributions)attributions snapshotImage:(MGLImage *)mglImage pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn latLngForFn:(mbgl::MapSnapshotter::LatLngForFn)latLngForFn {
-
+- (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;
@@ -397,19 +457,30 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
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];
+ 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) {
- MGLMapSnapshot* snapshot = [[MGLMapSnapshot alloc] initWithImage:compositedImage
- scale:scale
- pointForFn:pointForFn
- latLngForFn:latLngForFn];
- strongself.completion(snapshot, nil);
- strongself.completion = nil;
+
+ 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;
+ }
}
});
});
@@ -630,7 +701,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
// Create the snapshotter
_mbglMapSnapshotter = std::make_unique<mbgl::MapSnapshotter>(
- style, size, pixelRatio, cameraOptions, coordinateBounds, config.cacheDir, config.localFontFamilyName, resourceOptions);
+ style, size, pixelRatio, cameraOptions, coordinateBounds, config.localFontFamilyName, resourceOptions);
}
@end
diff --git a/platform/darwin/src/MGLOfflineStorage.h b/platform/darwin/src/MGLOfflineStorage.h
index 1ed364ddf3..d093bb938a 100644
--- a/platform/darwin/src/MGLOfflineStorage.h
+++ b/platform/darwin/src/MGLOfflineStorage.h
@@ -173,6 +173,11 @@ typedef NS_ENUM(NSUInteger, MGLResourceKind) {
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/">
@@ -341,8 +346,7 @@ MGL_EXPORT
attempt to download additional tiles until already downloaded tiles are removed
by calling the `-removePack:withCompletionHandler:` method.
- @note The <a href="https://www.mapbox.com/tos/">Mapbox Terms of Service</a>
- prohibits changing or bypassing this limit without permission from Mapbox.
+ @param maximumCount The maximum number of tiles allowed to be downloaded.
*/
- (void)setMaximumAllowedMapboxTiles:(uint64_t)maximumCount;
@@ -420,7 +424,7 @@ MGL_EXPORT
- (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
diff --git a/platform/darwin/src/MGLRasterTileSource.mm b/platform/darwin/src/MGLRasterTileSource.mm
index 61e9ef97fd..e89367711e 100644
--- a/platform/darwin/src/MGLRasterTileSource.mm
+++ b/platform/darwin/src/MGLRasterTileSource.mm
@@ -65,11 +65,13 @@ static const CGFloat MGLRasterTileSourceRetinaTileSize = 512;
}
- (NSURL *)configurationURL {
+ MGLAssertStyleSourceIsValid();
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
}
- (NSString *)attributionHTMLString {
+ MGLAssertStyleSourceIsValid();
auto attribution = self.rawSource->getAttribution();
return attribution ? @(attribution->c_str()) : nil;
}
diff --git a/platform/darwin/src/MGLRasterTileSource_Private.h b/platform/darwin/src/MGLRasterTileSource_Private.h
index 128dcb447d..8502b811e2 100644
--- a/platform/darwin/src/MGLRasterTileSource_Private.h
+++ b/platform/darwin/src/MGLRasterTileSource_Private.h
@@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface MGLRasterTileSource (Private)
-@property (nonatomic, readonly) mbgl::style::RasterSource *rawSource;
+@property (nonatomic, readonly, nullable) mbgl::style::RasterSource *rawSource;
- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize;
diff --git a/platform/darwin/src/MGLRendererConfiguration.h b/platform/darwin/src/MGLRendererConfiguration.h
index bfe88b7209..0c539f86f1 100644
--- a/platform/darwin/src/MGLRendererConfiguration.h
+++ b/platform/darwin/src/MGLRendererConfiguration.h
@@ -20,9 +20,6 @@ MGL_EXPORT
Based on the native scale where available, otherwise the standard screen scale. */
@property (nonatomic, readonly) const float scaleFactor;
-/** The cache dir to use. */
-@property (nonatomic, readonly) mbgl::optional<std::string> cacheDir;
-
/** 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
diff --git a/platform/darwin/src/MGLRendererConfiguration.mm b/platform/darwin/src/MGLRendererConfiguration.mm
index 54bdcaa691..136dc929a6 100644
--- a/platform/darwin/src/MGLRendererConfiguration.mm
+++ b/platform/darwin/src/MGLRendererConfiguration.mm
@@ -66,10 +66,6 @@ static NSString * const MGLIdeographicFontFamilyNameKey = @"MGLIdeographicFontFa
#endif
}
-- (mbgl::optional<std::string>)cacheDir {
- return mbgl::optional<std::string>();
-}
-
- (mbgl::optional<std::string>)localFontFamilyName {
return [self _localFontFamilyNameWithPropertyDictionary:[[NSBundle mainBundle] infoDictionary]];
}
diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm
index fc526f9850..3628a0eb74 100644
--- a/platform/darwin/src/MGLShapeSource.mm
+++ b/platform/darwin/src/MGLShapeSource.mm
@@ -150,11 +150,13 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
}
- (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;
@@ -164,17 +166,24 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
}
- (void)setShape:(MGLShape *)shape {
+ MGLAssertStyleSourceIsValid();
self.rawSource->setGeoJSON({ shape.geoJSONObject });
_shape = shape;
}
- (NSString *)description {
- return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; shape = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.shape];
+ 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;
@@ -190,6 +199,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
#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
diff --git a/platform/darwin/src/MGLSource.h b/platform/darwin/src/MGLSource.h
index 7bbf02fa7c..dc92e652e8 100644
--- a/platform/darwin/src/MGLSource.h
+++ b/platform/darwin/src/MGLSource.h
@@ -1,9 +1,12 @@
#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
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index 62308ce5e1..1d7b46e1cc 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -11,6 +11,8 @@
#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
@@ -23,13 +25,14 @@
@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;
+ _identifier = [identifier copy];
}
return self;
}
@@ -37,13 +40,18 @@
- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource mapView:(MGLMapView *)mapView {
NSString *identifier = @(rawSource->getID().c_str());
if (self = [self initWithIdentifier:identifier]) {
- _rawSource = rawSource;
- _rawSource->peer = SourceWrapper { self };
+ _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);
@@ -63,6 +71,7 @@
}
- (BOOL)removeFromMapView:(MGLMapView *)mapView error:(NSError * __nullable * __nullable)outError {
+ MGLAssertStyleSourceIsValid();
BOOL removed = NO;
if (self.rawSource == mapView.style.rawStyle->getSource(self.identifier.UTF8String)) {
diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h
index af14c11b90..4a7c31694d 100644
--- a/platform/darwin/src/MGLSource_Private.h
+++ b/platform/darwin/src/MGLSource_Private.h
@@ -2,6 +2,7 @@
#include <memory>
+
NS_ASSUME_NONNULL_BEGIN
namespace mbgl {
@@ -18,6 +19,20 @@ 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)
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 5768a7aaa7..cab0eaae28 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -226,12 +226,23 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles,
MGLLogDebug(@"Removing source: %@", source);
if (!source.rawSource) {
- [NSException raise:NSInvalidArgumentException format:
- @"The source %@ cannot be removed from the style. "
- @"Make sure the source was created as a member of a concrete subclass of MGLSource.",
- source];
+ 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];
}
diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm
index 05885bc63e..7847cbb319 100644
--- a/platform/darwin/src/MGLStyleLayer.mm
+++ b/platform/darwin/src/MGLStyleLayer.mm
@@ -14,13 +14,14 @@ const MGLExceptionName MGLInvalidStyleLayerException = @"MGLInvalidStyleLayerExc
@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());
- _rawLayer = rawLayer;
- _rawLayer->peer = LayerWrapper { self };
+ _weakLayer = rawLayer->makeWeakPtr();
+ rawLayer->peer = LayerWrapper { self };
}
return self;
}
@@ -32,6 +33,11 @@ const MGLExceptionName MGLInvalidStyleLayerException = @"MGLInvalidStyleLayerExc
return self;
}
+- (mbgl::style::Layer *)rawLayer
+{
+ return _weakLayer.get();
+}
+
- (void)addToStyle:(MGLStyle *)style belowLayer:(MGLStyleLayer *)otherLayer
{
if (_pendingLayer == nullptr) {
@@ -103,9 +109,15 @@ const MGLExceptionName MGLInvalidStyleLayerException = @"MGLInvalidStyleLayerExc
- (NSString *)description
{
- return [NSString stringWithFormat:@"<%@: %p; identifier = %@; visible = %@>",
- NSStringFromClass([self class]), (void *)self, self.identifier,
- self.visible ? @"YES" : @"NO"];
+ 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_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h
index 314f61f680..52254f78c6 100644
--- a/platform/darwin/src/MGLStyleLayer_Private.h
+++ b/platform/darwin/src/MGLStyleLayer_Private.h
@@ -27,6 +27,7 @@ struct LayerWrapper {
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 " \
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h
index fb00b0d165..53bc488a41 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.h
+++ b/platform/darwin/src/MGLSymbolStyleLayer.h
@@ -1404,8 +1404,7 @@ MGL_EXPORT
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`, and `textVariableAnchor` is set to `nil`.
- Otherwise, it is ignored.
+ `textRadialOffset` is set to `nil`. Otherwise, it is ignored.
You can set this property to an expression containing any of the following:
@@ -1428,8 +1427,7 @@ MGL_EXPORT
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`, and `textVariableAnchor` is set to `nil`.
- Otherwise, it is ignored.
+ `textRadialOffset` is set to `nil`. Otherwise, it is ignored.
You can set this property to an expression containing any of the following:
@@ -1521,8 +1519,8 @@ MGL_EXPORT
/**
Radial offset of text, in the direction of the symbol's anchor. Useful in
- combination with `textVariableAnchor`, which doesn't support the
- two-dimensional `textOffset`.
+ combination with `textVariableAnchor`, which defaults to using the
+ two-dimensional `textOffset` if present.
This property is measured in ems.
@@ -1634,8 +1632,7 @@ MGL_EXPORT
provide an array of `textAnchor` locations: the render 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` instead of the two-dimensional
- `textOffset`.
+ 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
diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h
index df3c61a61c..963eda384b 100644
--- a/platform/darwin/src/MGLTypes.h
+++ b/platform/darwin/src/MGLTypes.h
@@ -56,8 +56,10 @@ typedef NS_ENUM(NSInteger, MGLErrorCode) {
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 = 10,
+ MGLErrorCodeRenderingError = 11,
};
/** Options for enabling debugging features in an `MGLMapView` instance. */
diff --git a/platform/darwin/src/MGLVectorStyleLayer.m b/platform/darwin/src/MGLVectorStyleLayer.m
deleted file mode 100644
index 23f3556e0b..0000000000
--- a/platform/darwin/src/MGLVectorStyleLayer.m
+++ /dev/null
@@ -1,25 +0,0 @@
-#import "MGLVectorStyleLayer.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 {
- 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"];
-}
-
-@end
diff --git a/platform/darwin/src/MGLVectorStyleLayer.mm b/platform/darwin/src/MGLVectorStyleLayer.mm
new file mode 100644
index 0000000000..691668629a
--- /dev/null
+++ b/platform/darwin/src/MGLVectorStyleLayer.mm
@@ -0,0 +1,34 @@
+#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.mm b/platform/darwin/src/MGLVectorTileSource.mm
index f7a6869ade..85270c4a49 100644
--- a/platform/darwin/src/MGLVectorTileSource.mm
+++ b/platform/darwin/src/MGLVectorTileSource.mm
@@ -38,17 +38,19 @@
}
- (NSURL *)configurationURL {
+ MGLAssertStyleSourceIsValid();
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
}
- (NSString *)attributionHTMLString {
+ MGLAssertStyleSourceIsValid();
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;
diff --git a/platform/darwin/src/http_file_source.mm b/platform/darwin/src/http_file_source.mm
index 5737d8b999..b0f69f4a7f 100644
--- a/platform/darwin/src/http_file_source.mm
+++ b/platform/darwin/src/http_file_source.mm
@@ -88,15 +88,14 @@ class HTTPFileSource::Impl {
public:
Impl() {
@autoreleasepool {
-
- NSURLSessionConfiguration *sessionConfig =
- [MGLNetworkConfiguration sharedManager].sessionConfiguration;
-
+ NSURLSessionConfiguration *sessionConfig = [MGLNetworkConfiguration sharedManager].sessionConfiguration;
session = [NSURLSession sessionWithConfiguration:sessionConfig];
userAgent = getUserAgent();
- accountType = [[NSUserDefaults standardUserDefaults] integerForKey:@"MGLMapboxAccountType"];
+#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+ accountType = [[NSUserDefaults standardUserDefaults] integerForKey:MGLMapboxAccountTypeKey];
+#endif
}
}
@@ -205,13 +204,13 @@ NSURL *resourceURLWithAccountType(const Resource& resource, NSInteger accountTyp
if (accountType == 0 &&
([url.host isEqualToString:@"mapbox.com"] || [url.host hasSuffix:@".mapbox.com"])) {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
- NSURLQueryItem *accountsQueryItem = [NSURLQueryItem queryItemWithName:@"sku" value:MGLAccountManager.skuToken];
-
- NSMutableArray *queryItems = [NSMutableArray arrayWithObject:accountsQueryItem];
-
- // offline here
+ NSMutableArray *queryItems = [NSMutableArray array];
+
if (resource.usage == Resource::Usage::Offline) {
[queryItems addObject:[NSURLQueryItem queryItemWithName:@"offline" value:@"true"]];
+ } else {
+ // Only add SKU token to requests not tagged as "offline" usage.
+ [queryItems addObject:[NSURLQueryItem queryItemWithName:@"sku" value:MGLAccountManager.skuToken]];
}
if (components.queryItems) {
diff --git a/platform/darwin/src/string_nsstring.mm b/platform/darwin/src/string_nsstring.mm
index 096ed2b212..382a2acf33 100644
--- a/platform/darwin/src/string_nsstring.mm
+++ b/platform/darwin/src/string_nsstring.mm
@@ -43,6 +43,10 @@ std::string formatNumber(double number, const std::string& localeId, const std::
numberFormatter.maximumFractionDigits = maxFractionDigits;
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
} else {
+ // Reset fraction digits to NSNumberFormatter's default values, so that the
+ // system will choose formatting based on number formatter locale.
+ numberFormatter.minimumFractionDigits = 0;
+ numberFormatter.maximumFractionDigits = 0;
numberFormatter.numberStyle = NSNumberFormatterCurrencyStyle;
}
NSString *formatted = [numberFormatter stringFromNumber:@(number)];