diff options
author | Fabian Guerra <fabian.guerra@mapbox.com> | 2017-09-18 17:04:03 -0400 |
---|---|---|
committer | Fabian Guerra <fabian.guerra@mapbox.com> | 2017-09-28 15:39:57 -0400 |
commit | 5213133dc74267bc04d312e5127336b24459b346 (patch) | |
tree | a0bb554c257fd5504854e73276d6bacd84a5a2b7 | |
parent | 64c75b442c4d387e4867757abf49462c561e5955 (diff) | |
download | qtlocation-mapboxgl-5213133dc74267bc04d312e5127336b24459b346.tar.gz |
[ios, macos] Improve snap shotter documentation.
-rw-r--r-- | platform/darwin/src/MGLMapSnapshotter.h | 59 | ||||
-rw-r--r-- | platform/darwin/src/MGLMapSnapshotter.mm | 28 | ||||
-rw-r--r-- | platform/darwin/src/MGLTypes.h | 2 | ||||
-rw-r--r-- | platform/ios/app/MBXSnapshotsViewController.m | 28 | ||||
-rw-r--r-- | platform/macos/app/MapDocument.m | 29 |
5 files changed, 91 insertions, 55 deletions
diff --git a/platform/darwin/src/MGLMapSnapshotter.h b/platform/darwin/src/MGLMapSnapshotter.h index a2a4f1b331..d39b252b51 100644 --- a/platform/darwin/src/MGLMapSnapshotter.h +++ b/platform/darwin/src/MGLMapSnapshotter.h @@ -12,40 +12,46 @@ MGL_EXPORT @interface MGLMapSnapshotOptions : NSObject /** - Creates a set of options with the minimum required information - @param styleURL the style url to use - @param camera the camera settings - @param size the image size + Creates a set of options with the minimum required information. + + @param styleURL URL of the map style to snapshot. The URL may be a full HTTP or HTTPS URL, + a Mapbox URL indicating the style’s map ID (mapbox://styles/{user}/{style}), or a path + to a local file relative to the application’s resource path. Specify nil for the default style. + @param size The image size. */ -- (instancetype)initWithStyleURL:(NSURL*)styleURL camera:(MGLMapCamera*)camera size:(CGSize)size; +- (instancetype)initWithStyleURL:(nullable NSURL*)styleURL camera:(MGLMapCamera*)camera size:(CGSize)size; -#pragma mark - Configuring the map +#pragma mark - Configuring the Map /** - The style URL for these options. + URL of the map style to snapshot. The URL may be a full HTTP or HTTPS URL, + a Mapbox URL indicating the style’s map ID (mapbox://styles/{user}/{style}), or a path + to a local file relative to the application’s resource path. Specify nil for the default style. */ -@property (nonatomic, readonly) NSURL* styleURL; +@property (nonatomic, readonly) NSURL *styleURL; /** - The zoom. Default is 0. + The default zoom level is 0. Overrides the altitude in the mapCamera options if set. */ -@property (nonatomic) double zoom; +@property (nonatomic) double zoomLevel; /** - The `MGLMapcamera` options to use. + A camera representing the viewport visible in the snapshot. */ -@property (nonatomic) MGLMapCamera* camera; +@property (nonatomic) MGLMapCamera *camera; /** - A region to capture. Overrides the center coordinate - in the mapCamera options if set + The cooordinate rectangle that encompasses the bounds to capture. Overrides the center coordinate + in the mapCamera options if set. */ -@property (nonatomic) MGLCoordinateBounds region; +@property (nonatomic) MGLCoordinateBounds coordinateBounds; -#pragma mark - Configuring the image +#pragma mark - Configuring the Image /** - The size of the output image. Minimum is 64x64 + The size of the output image. + + The image may be no less than 64 pixels wide and no less than 64 pixels tall. */ @property (nonatomic, readonly) CGSize size; @@ -57,18 +63,26 @@ MGL_EXPORT @end +#if TARGET_OS_IPHONE /** A block to processes the result or error of a snapshot request. - The result will be either an `MGLImage` or a `NSError` + @param snapshot The `UIImage` that was generated or `nil` if an error occurred. + @param error The error that occured or `nil` when succesful. + */ +typedef void (^MGLMapSnapshotCompletionHandler)(UIImage* _Nullable snapshot, NSError* _Nullable error); +#else +/** + A block to processes the result or error of a snapshot request. - @param snapshot The image that was generated or `nil` if an error occurred. + @param snapshot The `NSImage` that was generated or `nil` if an error occurred. @param error The eror that occured or `nil` when succesful. */ -typedef void (^MGLMapSnapshotCompletionHandler)(MGLImage* _Nullable snapshot, NSError* _Nullable error); +typedef void (^MGLMapSnapshotCompletionHandler)(NSImage* _Nullable snapshot, NSError* _Nullable error); +#endif /** - A utility object for capturing map-based images. + An immutable utility object for capturing map-based images. */ MGL_EXPORT @interface MGLMapSnapshotter : NSObject @@ -92,6 +106,9 @@ MGL_EXPORT /** Cancels the snapshot creation request, if any. + + Once you call this method, you cannot resume the snapshot. In order to obtain the + snapshot, create a new `MGLMapSnapshotter` object. */ - (void)cancel; diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm index c81fd39c4a..b1254b5d3b 100644 --- a/platform/darwin/src/MGLMapSnapshotter.mm +++ b/platform/darwin/src/MGLMapSnapshotter.mm @@ -13,6 +13,7 @@ #import "MGLOfflineStorage_Private.h" #import "MGLGeometry_Private.h" #import "NSBundle+MGLAdditions.h" +#import "MGLStyle.h" #if TARGET_OS_IPHONE #import "UIImage+MGLAdditions.h" @@ -20,12 +21,18 @@ #import "NSImage+MGLAdditions.h" #endif +const CGPoint MGLLogoImagePosition = CGPointMake(8, 8); + @implementation MGLMapSnapshotOptions -- (instancetype _Nonnull)initWithStyleURL:(NSURL* _Nonnull)styleURL camera:(MGLMapCamera*)camera size:(CGSize) size; +- (instancetype _Nonnull)initWithStyleURL:(nullable NSURL*)styleURL camera:(MGLMapCamera*)camera size:(CGSize) size; { self = [super init]; if (self) { + if ( !styleURL) + { + styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion]; + } _styleURL = styleURL; _size = size; _camera = camera; @@ -73,17 +80,17 @@ cameraOptions.center = MGLLatLngFromLocationCoordinate2D(options.camera.centerCoordinate); } cameraOptions.angle = MAX(0, options.camera.heading) * mbgl::util::DEG2RAD; - cameraOptions.zoom = MAX(0, options.zoom); + cameraOptions.zoom = MAX(0, options.zoomLevel); cameraOptions.pitch = MAX(0, options.camera.pitch); // Region - mbgl::optional<mbgl::LatLngBounds> region; - if (!MGLCoordinateBoundsIsEmpty(options.region)) { - region = MGLLatLngBoundsFromCoordinateBounds(options.region); + mbgl::optional<mbgl::LatLngBounds> coordinateBounds; + if (!MGLCoordinateBoundsIsEmpty(options.coordinateBounds)) { + coordinateBounds = MGLLatLngBoundsFromCoordinateBounds(options.coordinateBounds); } // Create the snapshotter - mbglMapSnapshotter = std::make_unique<mbgl::MapSnapshotter>(*mbglFileSource, *mbglThreadPool, styleURL, size, pixelRatio, cameraOptions, region); + mbglMapSnapshotter = std::make_unique<mbgl::MapSnapshotter>(*mbglFileSource, *mbglThreadPool, styleURL, size, pixelRatio, cameraOptions, coordinateBounds); } return self; } @@ -96,7 +103,8 @@ - (void)startWithQueue:(dispatch_queue_t)queue completionHandler:(MGLMapSnapshotCompletionHandler)completion; { if ([self isLoading]) { - NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Already started this snapshotter"}; + NSString *errorMessage = NSLocalizedStringWithDefaultValue(@"ALREADY_STARTED_SNAPSHOTTER", nil, nil, @"Already started this snapshotter", "User-friendly error description"); + NSDictionary *userInfo = @{NSLocalizedDescriptionKey: errorMessage}; NSError *error = [NSError errorWithDomain:MGLErrorDomain code:1 userInfo:userInfo]; dispatch_async(queue, ^{ completion(nil, error); @@ -112,7 +120,7 @@ if (mbglError) { NSString *description = @(mbgl::util::toString(mbglError).c_str()); NSDictionary *userInfo = @{NSLocalizedDescriptionKey: description}; - NSError *error = [NSError errorWithDomain:MGLErrorDomain code:1 userInfo:userInfo]; + NSError *error = [NSError errorWithDomain:MGLErrorDomain code:MGLErrorCodeSnapshotFailed userInfo:userInfo]; // Dispatch result to origin queue dispatch_async(queue, ^{ @@ -130,7 +138,7 @@ UIGraphicsBeginImageContext(mglImage.size); [mglImage drawInRect:CGRectMake(0, 0, mglImage.size.width, mglImage.size.height)]; - [logoImage drawInRect:CGRectMake(8, mglImage.size.height - (8 + logoImage.size.height), logoImage.size.width,logoImage.size.height)]; + [logoImage drawInRect:CGRectMake(MGLLogoImagePosition.x, mglImage.size.height - (MGLLogoImagePosition.y + logoImage.size.height), logoImage.size.width,logoImage.size.height)]; UIImage *compositedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); @@ -139,7 +147,7 @@ NSImage *compositedImage = mglImage; [compositedImage lockFocus]; - [logoImage drawInRect:CGRectMake(8, 8, logoImage.size.width,logoImage.size.height)]; + [logoImage drawInRect:CGRectMake(MGLLogoImagePosition.x, MGLLogoImagePosition.y, logoImage.size.width,logoImage.size.height)]; [compositedImage unlockFocus]; #endif diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h index b3227e1cdf..5c32791c2f 100644 --- a/platform/darwin/src/MGLTypes.h +++ b/platform/darwin/src/MGLTypes.h @@ -47,6 +47,8 @@ typedef NS_ENUM(NSInteger, MGLErrorCode) { MGLErrorCodeParseStyleFailed = 4, /** An attempt to load the style failed. */ MGLErrorCodeLoadStyleFailed = 5, + /** An error occurred while snapshotting the map. */ + MGLErrorCodeSnapshotFailed = 6, }; /** Options for enabling debugging features in an `MGLMapView` instance. */ diff --git a/platform/ios/app/MBXSnapshotsViewController.m b/platform/ios/app/MBXSnapshotsViewController.m index d26479f085..ab5ad97c90 100644 --- a/platform/ios/app/MBXSnapshotsViewController.m +++ b/platform/ios/app/MBXSnapshotsViewController.m @@ -18,27 +18,27 @@ @implementation MBXSnapshotsViewController { // Top row - MGLMapSnapshotter* snapshotterTL; - MGLMapSnapshotter* snapshotterTM; - MGLMapSnapshotter* snapshotterTR; + MGLMapSnapshotter* topLeftSnapshotter; + MGLMapSnapshotter* topCenterSnapshotter; + MGLMapSnapshotter* topRightSnapshotter; // Bottom row - MGLMapSnapshotter* snapshotterBL; - MGLMapSnapshotter* snapshotterBM; - MGLMapSnapshotter* snapshotterBR; + MGLMapSnapshotter* bottomLeftSnapshotter; + MGLMapSnapshotter* bottomCenterSnapshotter; + MGLMapSnapshotter* bottomRightSnapshotter; } - (void)viewDidLoad { [super viewDidLoad]; // Start snapshotters - snapshotterTL = [self startSnapshotterForImageView:_snapshotImageViewTL coordinates:CLLocationCoordinate2DMake(37.7184, -122.4365)]; - snapshotterTM = [self startSnapshotterForImageView:_snapshotImageViewTM coordinates:CLLocationCoordinate2DMake(38.8936, -77.0146)]; - snapshotterTR = [self startSnapshotterForImageView:_snapshotImageViewTR coordinates:CLLocationCoordinate2DMake(-13.1356, -74.2442)]; + topLeftSnapshotter = [self startSnapshotterForImageView:_snapshotImageViewTL coordinates:CLLocationCoordinate2DMake(37.7184, -122.4365)]; + topCenterSnapshotter = [self startSnapshotterForImageView:_snapshotImageViewTM coordinates:CLLocationCoordinate2DMake(38.8936, -77.0146)]; + topRightSnapshotter = [self startSnapshotterForImageView:_snapshotImageViewTR coordinates:CLLocationCoordinate2DMake(-13.1356, -74.2442)]; - snapshotterBL = [self startSnapshotterForImageView:_snapshotImageViewBL coordinates:CLLocationCoordinate2DMake(52.5072, 13.4247)]; - snapshotterBM = [self startSnapshotterForImageView:_snapshotImageViewBM coordinates:CLLocationCoordinate2DMake(60.2118, 24.6754)]; - snapshotterBR = [self startSnapshotterForImageView:_snapshotImageViewBR coordinates:CLLocationCoordinate2DMake(31.2780, 121.4286)]; + bottomLeftSnapshotter = [self startSnapshotterForImageView:_snapshotImageViewBL coordinates:CLLocationCoordinate2DMake(52.5072, 13.4247)]; + bottomCenterSnapshotter = [self startSnapshotterForImageView:_snapshotImageViewBM coordinates:CLLocationCoordinate2DMake(60.2118, 24.6754)]; + bottomRightSnapshotter = [self startSnapshotterForImageView:_snapshotImageViewBR coordinates:CLLocationCoordinate2DMake(31.2780, 121.4286)]; } - (MGLMapSnapshotter*) startSnapshotterForImageView:(UIImageView*) imageView coordinates:(CLLocationCoordinate2D) coordinates { @@ -46,8 +46,8 @@ MGLMapCamera* mapCamera = [[MGLMapCamera alloc] init]; mapCamera.pitch = 20; mapCamera.centerCoordinate = coordinates; - MGLMapSnapshotOptions* options = [[MGLMapSnapshotOptions alloc] initWithStyleURL:[NSURL URLWithString:@"mapbox://styles/mapbox/traffic-day-v2"] camera:mapCamera size:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)]; - options.zoom = 10; + MGLMapSnapshotOptions* options = [[MGLMapSnapshotOptions alloc] initWithStyleURL:[MGLStyle satelliteStreetsStyleURL] camera:mapCamera size:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)]; + options.zoomLevel = 10; // Create and start the snapshotter MGLMapSnapshotter* snapshotter = [[MGLMapSnapshotter alloc] initWithOptions:options]; diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 36ca4ad228..d466d2ef4b 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -163,7 +163,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio MGLMapCamera *camera = self.mapView.camera; MGLMapSnapshotOptions* options = [[MGLMapSnapshotOptions alloc] initWithStyleURL:self.mapView.styleURL camera:camera size:self.mapView.bounds.size]; - options.zoom = self.mapView.zoomLevel; + options.zoomLevel = self.mapView.zoomLevel; // Create and start the snapshotter snapshotter = [[MGLMapSnapshotter alloc] initWithOptions:options]; @@ -177,6 +177,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio // Set the default name for the file and show the panel. NSSavePanel* panel = [NSSavePanel savePanel]; + [panel setNameFieldStringValue:newName]; [panel beginSheetModalForWindow:window completionHandler:^(NSInteger result){ if (result == NSFileHandlingPanelOKButton) { @@ -196,16 +197,24 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio } - NSString *extension = [[fileURL pathExtension] lowercaseString]; - NSBitmapImageFileType fileType; - if ([extension isEqualToString:@"png"]) { + NSString *uti; + [fileURL getResourceValue:&uti forKey:NSURLTypeIdentifierKey error:nil]; + NSBitmapImageFileType fileType = NSTIFFFileType; + + if (UTTypeConformsTo((__bridge CFStringRef)uti, kUTTypePNG)) { fileType = NSPNGFileType; - } else if ([extension isEqualToString:@"gif"]) { - fileType = NSGIFFileType; - } else if ([extension isEqualToString:@"jpg"] || [extension isEqualToString:@"jpeg"]) { - fileType = NSJPEGFileType; - } else { - fileType = NSTIFFFileType; + } + if (UTTypeConformsTo((__bridge CFStringRef)uti, kUTTypeGIF)) { + fileType = NSGIFFileType; + } + if (UTTypeConformsTo((__bridge CFStringRef)uti, kUTTypeJPEG)) { + fileType = NSJPEGFileType; + } + if (UTTypeConformsTo((__bridge CFStringRef)uti, kUTTypeJPEG2000)) { + fileType = NSJPEGFileType; + } + if (UTTypeConformsTo((__bridge CFStringRef)uti, kUTTypeBMP)) { + fileType = NSBitmapImageFileTypeBMP; } NSData *imageData = [bitmapRep representationUsingType:fileType properties:@{}]; |