summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLMapSnapshotter.mm
diff options
context:
space:
mode:
authorFabian Guerra Soto <fabian.guerra@mapbox.com>2017-10-04 10:03:03 -0400
committerGitHub <noreply@github.com>2017-10-04 10:03:03 -0400
commitf01588cac78b5e5411385faa451080a74320500b (patch)
tree1f0540cf5c71475f0ae6714d70b909338fed9b5f /platform/darwin/src/MGLMapSnapshotter.mm
parent6a846ce5a8ff1d62f4eafa3ef5bd0427096ca9e6 (diff)
downloadqtlocation-mapboxgl-f01588cac78b5e5411385faa451080a74320500b.tar.gz
[ios, macos] Improve snap shotter documentation. (#10020)
* [ios, macos] Improve snap shotter documentation. * [macos] Save snapshots in correct format * [macos] Renamed snapshot item to Export Image * [ios, macos] Clarify Snapshotter documentation. * [ios] Fix snapshot scale * [macOS] Fix snapshotter 4x scaling. * [ios] Fix snapshotter final image scale. * [ios, macos] Update snapshotter size documentation. * [ios, macos] Throw an exception when the snapshotter has already started. * [ios, macos] Add snapshotter header example. * [ios, macos] Use one of the predefined Foundation's exception names.
Diffstat (limited to 'platform/darwin/src/MGLMapSnapshotter.mm')
-rw-r--r--platform/darwin/src/MGLMapSnapshotter.mm78
1 files changed, 51 insertions, 27 deletions
diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm
index c81fd39c4a..12b932daa3 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,19 @@
#import "NSImage+MGLAdditions.h"
#endif
+const CGPoint MGLLogoImagePosition = CGPointMake(8, 8);
+const CGFloat MGLSnapshotterMinimumPixelSize = 64;
+
@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;
@@ -41,28 +49,34 @@
@end
+@interface MGLMapSnapshotter()
+@property (nonatomic) MGLMapSnapshotOptions *options;
+@end
+
@implementation MGLMapSnapshotter {
- std::shared_ptr<mbgl::ThreadPool> mbglThreadPool;
- std::unique_ptr<mbgl::MapSnapshotter> mbglMapSnapshotter;
- std::unique_ptr<mbgl::Actor<mbgl::MapSnapshotter::Callback>> snapshotCallback;
+ std::shared_ptr<mbgl::ThreadPool> _mbglThreadPool;
+ std::unique_ptr<mbgl::MapSnapshotter> _mbglMapSnapshotter;
+ std::unique_ptr<mbgl::Actor<mbgl::MapSnapshotter::Callback>> _snapshotCallback;
}
- (instancetype)initWithOptions:(MGLMapSnapshotOptions*)options;
{
self = [super init];
if (self) {
+ _options = options;
_loading = false;
mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource;
- mbglThreadPool = mbgl::sharedThreadPool();
+ _mbglThreadPool = mbgl::sharedThreadPool();
std::string styleURL = std::string([options.styleURL.absoluteString UTF8String]);
// Size; taking into account the minimum texture size for OpenGL ES
+ // For non retina screens the ratio is 1:1 MGLSnapshotterMinimumPixelSize
mbgl::Size size = {
- static_cast<uint32_t>(MAX(options.size.width, 64)),
- static_cast<uint32_t>(MAX(options.size.height, 64))
+ static_cast<uint32_t>(MAX(options.size.width, MGLSnapshotterMinimumPixelSize)),
+ static_cast<uint32_t>(MAX(options.size.height, MGLSnapshotterMinimumPixelSize))
};
float pixelRatio = MAX(options.scale, 1);
@@ -73,17 +87,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,30 +110,30 @@
- (void)startWithQueue:(dispatch_queue_t)queue completionHandler:(MGLMapSnapshotCompletionHandler)completion;
{
if ([self isLoading]) {
- NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Already started this snapshotter"};
- NSError *error = [NSError errorWithDomain:MGLErrorDomain code:1 userInfo:userInfo];
- dispatch_async(queue, ^{
- completion(nil, error);
- });
- return;
+ [NSException raise:NSInternalInconsistencyException
+ format:@"Already started this snapshotter."];
}
_loading = true;
dispatch_async(queue, ^{
- snapshotCallback = std::make_unique<mbgl::Actor<mbgl::MapSnapshotter::Callback>>(*mbgl::Scheduler::GetCurrent(), [=](std::exception_ptr mbglError, mbgl::PremultipliedImage image) {
+ _snapshotCallback = std::make_unique<mbgl::Actor<mbgl::MapSnapshotter::Callback>>(*mbgl::Scheduler::GetCurrent(), [=](std::exception_ptr mbglError, mbgl::PremultipliedImage image) {
_loading = false;
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, ^{
completion(nil, error);
});
} else {
+#if TARGET_OS_IPHONE
+ MGLImage *mglImage = [[MGLImage alloc] initWithMGLPremultipliedImage:std::move(image) scale:self.options.scale];
+#else
MGLImage *mglImage = [[MGLImage alloc] initWithMGLPremultipliedImage:std::move(image)];
+#endif
// Process image watermark in a work queue
dispatch_queue_t workQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
@@ -127,20 +141,30 @@
#if TARGET_OS_IPHONE
UIImage *logoImage = [UIImage imageNamed:@"mapbox" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil];
- UIGraphicsBeginImageContext(mglImage.size);
+ UIGraphicsBeginImageContextWithOptions(mglImage.size, NO, self.options.scale);
[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();
#else
NSImage *logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox" ofType:@"pdf"]];
- NSImage *compositedImage = mglImage;
+ NSImage *sourceImage = mglImage;
+
+ NSSize targetSize = NSMakeSize(self.options.size.width, self.options.size.height);
+ NSRect targetFrame = NSMakeRect(0, 0, targetSize.width, targetSize.height);
+ NSImage *compositedImage = nil;
+ NSImageRep *sourceImageRep = [sourceImage bestRepresentationForRect:targetFrame
+ context:nil
+ hints:nil];
+ compositedImage = [[NSImage alloc] initWithSize:targetSize];
[compositedImage lockFocus];
- [logoImage drawInRect:CGRectMake(8, 8, logoImage.size.width,logoImage.size.height)];
+ [sourceImageRep drawInRect: targetFrame];
+ [logoImage drawInRect:CGRectMake(MGLLogoImagePosition.x, MGLLogoImagePosition.y, logoImage.size.width,logoImage.size.height)];
[compositedImage unlockFocus];
+
#endif
// Dispatch result to origin queue
@@ -150,14 +174,14 @@
});
}
});
- mbglMapSnapshotter->snapshot(snapshotCallback->self());
+ _mbglMapSnapshotter->snapshot(_snapshotCallback->self());
});
}
- (void)cancel;
{
- snapshotCallback.reset();
- mbglMapSnapshotter.reset();
+ _snapshotCallback.reset();
+ _mbglMapSnapshotter.reset();
}
@end