summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2017-10-09 19:50:21 +0300
committerIvo van Dongen <ivovandongen@users.noreply.github.com>2017-10-31 19:52:08 +0200
commit3cdb249c703b9e21a111afe060f78033f0933138 (patch)
tree67b3e0e7b7320340a53e8c491ee53ccd1d4e8539
parentdde1a922919770fa009c90ff0525b69488e30bb1 (diff)
downloadqtlocation-mapboxgl-3cdb249c703b9e21a111afe060f78033f0933138.tar.gz
[darwin][ios][macos] map snapshotter - add MGLMapSnapshot wrapper
-rw-r--r--platform/darwin/src/MGLMapSnapshotter.h62
-rw-r--r--platform/darwin/src/MGLMapSnapshotter.mm34
-rw-r--r--platform/darwin/test/MGLDocumentationExampleTests.swift18
-rw-r--r--platform/ios/app/MBXSnapshotsViewController.m4
-rw-r--r--platform/macos/app/MapDocument.m6
5 files changed, 94 insertions, 30 deletions
diff --git a/platform/darwin/src/MGLMapSnapshotter.h b/platform/darwin/src/MGLMapSnapshotter.h
index 8bc929e3a9..b6228269cf 100644
--- a/platform/darwin/src/MGLMapSnapshotter.h
+++ b/platform/darwin/src/MGLMapSnapshotter.h
@@ -69,23 +69,42 @@ MGL_EXPORT
@end
+/**
+ An image generated by a snapshotter object.
+ */
+@interface MGLMapSnapshot : NSObject
+
#if TARGET_OS_IPHONE
/**
- A block to processes the result or error of a snapshot request.
-
- @param snapshot The `UIImage` that was generated or `nil` if an error occurred.
- @param error The error that occured or `nil` when successful.
+ Converts the specified map coordinate to a point in the coordinate space of the image.
*/
-typedef void (^MGLMapSnapshotCompletionHandler)(UIImage* _Nullable snapshot, NSError* _Nullable error);
+- (CGPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate;
+
+/**
+ The image of the map’s content.
+ */
+@property(nonatomic, readonly) UIImage *image;
#else
/**
+ Converts the specified map coordinate to a point in the coordinate space of the image.
+ */
+- (NSPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate;
+
+/**
+ The image of the map’s content.
+ */
+@property(nonatomic, readonly) NSImage *image;
+#endif
+
+@end
+
+/**
A block to processes the result or error of a snapshot request.
- @param snapshot The `NSImage` that was generated or `nil` if an error occurred.
- @param error The eror that occured or `nil` when succesful.
+ @param snapshot The `MGLMapSnapshot` that was generated or `nil` if an error occurred.
+ @param error The error that occured or `nil` when successful.
*/
-typedef void (^MGLMapSnapshotCompletionHandler)(NSImage* _Nullable snapshot, NSError* _Nullable error);
-#endif
+typedef void (^MGLMapSnapshotCompletionHandler)(MGLMapSnapshot* _Nullable snapshot, NSError* _Nullable error);
/**
An immutable utility object for capturing map-based images.
@@ -93,20 +112,18 @@ typedef void (^MGLMapSnapshotCompletionHandler)(NSImage* _Nullable snapshot, NSE
### Example
```swift
- var camera = MGLMapCamera()
- camera.centerCoordinate = CLLocationCoordinate2D(latitude: 37.7184, longitude: -122.4365)
- camera.pitch = 20
+ let camera = MGLMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.7184, longitude: -122.4365), fromDistance: 100, pitch: 20, heading: 0)
- var options = MGLMapSnapshotOptions(styleURL: MGLStyle.satelliteStreetsStyleURL(), camera: camera, size: CGSize(width: 320, height: 480))
+ let options = MGLMapSnapshotOptions(styleURL: MGLStyle.satelliteStreetsStyleURL(), camera: camera, size: CGSize(width: 320, height: 480))
options.zoomLevel = 10
- var snapshotter = MGLMapSnapshotter(options: options)
- snapshotter.start { (image, error) in
- if error {
- // error handler
- } else {
- // image handler
- }
+ let snapshotter = MGLMapSnapshotter(options: options)
+ snapshotter.start { (snapshot, error) in
+ if error != nil {
+ // error handler
+ } else {
+ // image handler
+ }
}
```
*/
@@ -141,7 +158,8 @@ MGL_EXPORT
/**
The zoom level.
- The default zoom level is 0. This overwrites the camera zoom level if set.
+ The default zoom level is 0. If this property is non-zero and the camera property
+ is non-nil, the camera’s altitude is ignored in favor of this property’s value.
*/
@property (nonatomic) double zoomLevel;
@@ -169,7 +187,7 @@ MGL_EXPORT
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) NSURL* styleURL;
+@property (nonatomic, nullable) NSURL *styleURL;
/**
The size of the output image, measured in points.
diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm
index 9d32ecf72c..193548ac11 100644
--- a/platform/darwin/src/MGLMapSnapshotter.mm
+++ b/platform/darwin/src/MGLMapSnapshotter.mm
@@ -49,6 +49,33 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
@end
+@interface MGLMapSnapshot()
+- (instancetype)initWithImage:(nullable MGLImage *)image scale:(CGFloat)scale pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn;
+
+@property (nonatomic) CGFloat scale;
+@end
+
+@implementation MGLMapSnapshot {
+ mbgl::MapSnapshotter::PointForFn _pointForFn;
+}
+- (instancetype)initWithImage:(nullable MGLImage *)image scale:(CGFloat)scale pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn
+{
+ self = [super init];
+ if (self) {
+ _pointForFn = std::move(pointForFn);
+ _scale = scale;
+ _image = image;
+ }
+ return self;
+}
+
+- (CGPoint)pointForCoordinate:(CLLocationCoordinate2D)coordinate
+{
+ mbgl::ScreenCoordinate sc = _pointForFn(MGLLatLngFromLocationCoordinate2D(coordinate));
+ return CGPointMake(sc.x * self.scale, sc.y * self.scale);
+}
+@end
+
@interface MGLMapSnapshotter()
@property (nonatomic) MGLMapSnapshotOptions *options;
@end
@@ -117,7 +144,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
_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, mbgl::MapSnapshotter::PointForFn pointForFn) {
_loading = false;
if (mbglError) {
NSString *description = @(mbgl::util::toString(mbglError).c_str());
@@ -171,7 +198,8 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
// Dispatch result to origin queue
dispatch_async(queue, ^{
- completion(compositedImage, nil);
+ MGLMapSnapshot* snapshot = [[MGLMapSnapshot alloc] initWithImage:compositedImage scale:self.options.scale pointForFn:pointForFn];
+ completion(snapshot, nil);
});
});
}
@@ -189,7 +217,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
- (NSURL *)styleURL
{
NSString *styleURLString = @(_mbglMapSnapshotter->getStyleURL().c_str());
- return styleURLString && styleURLString.length > 0 ? [NSURL URLWithString:styleURLString] : nil;
+ return styleURLString.length ? [NSURL URLWithString:styleURLString] : nil;
}
- (void)setStyleURL:(NSURL *)url
diff --git a/platform/darwin/test/MGLDocumentationExampleTests.swift b/platform/darwin/test/MGLDocumentationExampleTests.swift
index 42c656f203..8762af9ba4 100644
--- a/platform/darwin/test/MGLDocumentationExampleTests.swift
+++ b/platform/darwin/test/MGLDocumentationExampleTests.swift
@@ -278,6 +278,24 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate {
//#-end-example-code
}
+ func testMGLMapSnapshotter() {
+ //#-example-code
+ let camera = MGLMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.7184, longitude: -122.4365), fromDistance: 100, pitch: 20, heading: 0)
+
+ let options = MGLMapSnapshotOptions(styleURL: MGLStyle.satelliteStreetsStyleURL(), camera: camera, size: CGSize(width: 320, height: 480))
+ options.zoomLevel = 10
+
+ let snapshotter = MGLMapSnapshotter(options: options)
+ snapshotter.start { (snapshot, error) in
+ if error != nil {
+ // error handler
+ } else {
+ // image handler
+ }
+ }
+ //#-end-example-code
+ }
+
// For testMGLMapView().
func myCustomFunction() {}
}
diff --git a/platform/ios/app/MBXSnapshotsViewController.m b/platform/ios/app/MBXSnapshotsViewController.m
index ab5ad97c90..3bf93d8721 100644
--- a/platform/ios/app/MBXSnapshotsViewController.m
+++ b/platform/ios/app/MBXSnapshotsViewController.m
@@ -51,11 +51,11 @@
// Create and start the snapshotter
MGLMapSnapshotter* snapshotter = [[MGLMapSnapshotter alloc] initWithOptions:options];
- [snapshotter startWithCompletionHandler: ^(UIImage *image, NSError *error) {
+ [snapshotter startWithCompletionHandler: ^(MGLMapSnapshot* snapshot, NSError *error) {
if (error) {
NSLog(@"Could not load snapshot: %@", [error localizedDescription]);
} else {
- imageView.image = image;
+ imageView.image = snapshot.image;
}
}];
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m
index feef53062b..0df6b10518 100644
--- a/platform/macos/app/MapDocument.m
+++ b/platform/macos/app/MapDocument.m
@@ -167,7 +167,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
// Create and start the snapshotter
snapshotter = [[MGLMapSnapshotter alloc] initWithOptions:options];
- [snapshotter startWithCompletionHandler:^(NSImage *image, NSError *error) {
+ [snapshotter startWithCompletionHandler:^(MGLMapSnapshot *snapshot, NSError *error) {
if (error) {
NSLog(@"Could not load snapshot: %@", error.localizedDescription);
} else {
@@ -182,7 +182,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
NSURL *fileURL = panel.URL;
NSBitmapImageRep *bitmapRep;
- for (NSImageRep *imageRep in image.representations) {
+ for (NSImageRep *imageRep in snapshot.image.representations) {
if ([imageRep isKindOfClass:[NSBitmapImageRep class]]) {
bitmapRep = (NSBitmapImageRep *)imageRep;
break; // stop on first bitmap rep we find
@@ -190,7 +190,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
}
if (!bitmapRep) {
- bitmapRep = [NSBitmapImageRep imageRepWithData:image.TIFFRepresentation];
+ bitmapRep = [NSBitmapImageRep imageRepWithData:snapshot.image.TIFFRepresentation];
}
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileURL.pathExtension, NULL /* inConformingToUTI */);