From 334dde0d76ee7407c21ba25f0e1f0c899ef48c31 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Thu, 5 Oct 2017 14:19:07 +0300 Subject: [darwin] map snapshotter - snapshotter mutability --- platform/darwin/src/MGLMapSnapshotter.h | 40 ++++++++++++++- platform/darwin/src/MGLMapSnapshotter.mm | 87 ++++++++++++++++++++++++++++++-- 2 files changed, 121 insertions(+), 6 deletions(-) diff --git a/platform/darwin/src/MGLMapSnapshotter.h b/platform/darwin/src/MGLMapSnapshotter.h index 615d39bee4..8bc929e3a9 100644 --- a/platform/darwin/src/MGLMapSnapshotter.h +++ b/platform/darwin/src/MGLMapSnapshotter.h @@ -46,7 +46,7 @@ MGL_EXPORT @property (nonatomic) MGLMapCamera *camera; /** - The cooordinate rectangle that encompasses the bounds to capture. + The coordinate rectangle that encompasses the bounds to capture. If this property is non-empty and the camera property is non-nil, the camera’s center coordinate and altitude are ignored in favor of this property’s value. @@ -138,6 +138,44 @@ MGL_EXPORT */ - (void)cancel; +/** + The zoom level. + + The default zoom level is 0. This overwrites the camera zoom level if set. + */ +@property (nonatomic) double zoomLevel; + +/** + A camera representing the viewport visible in the snapshot. + + If this property is non-nil and the `coordinateBounds` property is set to a non-empty + coordinate bounds, the camera’s center coordinate and altitude are ignored in favor + of the `coordinateBounds` property. + */ +@property (nonatomic) MGLMapCamera *camera; + +/** + The coordinate rectangle that encompasses the bounds to capture. + + If this property is non-empty and the camera property is non-nil, the camera’s + center coordinate and altitude are ignored in favor of this property’s value. + */ +@property (nonatomic) MGLCoordinateBounds coordinateBounds; + +/** + 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) NSURL* styleURL; + +/** + The size of the output image, measured in points. + */ +@property (nonatomic) CGSize size; + /** Indicates whether as snapshot is currently being generated. */ diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm index 835e1995f3..9d32ecf72c 100644 --- a/platform/darwin/src/MGLMapSnapshotter.mm +++ b/platform/darwin/src/MGLMapSnapshotter.mm @@ -26,7 +26,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64; @implementation MGLMapSnapshotOptions -- (instancetype _Nonnull)initWithStyleURL:(nullable NSURL*)styleURL camera:(MGLMapCamera*)camera size:(CGSize) size; +- (instancetype _Nonnull)initWithStyleURL:(nullable NSURL *)styleURL camera:(MGLMapCamera *)camera size:(CGSize) size { self = [super init]; if (self) { @@ -60,7 +60,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64; std::unique_ptr> _snapshotCallback; } -- (instancetype)initWithOptions:(MGLMapSnapshotOptions*)options; +- (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options { self = [super init]; if (self) { @@ -102,12 +102,12 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64; return self; } -- (void)startWithCompletionHandler:(MGLMapSnapshotCompletionHandler)completion; +- (void)startWithCompletionHandler:(MGLMapSnapshotCompletionHandler)completion { [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)completion { if ([self isLoading]) { [NSException raise:NSInternalInconsistencyException @@ -180,10 +180,87 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64; }); } -- (void)cancel; +- (void)cancel { _snapshotCallback.reset(); _mbglMapSnapshotter.reset(); } +- (NSURL *)styleURL +{ + NSString *styleURLString = @(_mbglMapSnapshotter->getStyleURL().c_str()); + return styleURLString && styleURLString.length > 0 ? [NSURL URLWithString:styleURLString] : nil; +} + +- (void)setStyleURL:(NSURL *)url +{ + _mbglMapSnapshotter->setStyleURL(std::string([url.absoluteString UTF8String])); +} + +- (CGSize)size +{ + mbgl::Size size = _mbglMapSnapshotter->getSize(); + return CGSizeMake(size.width, size.height); +} + +- (void)setSize:(CGSize)size +{ + _mbglMapSnapshotter->setSize({ + static_cast(MAX(size.width, MGLSnapshotterMinimumPixelSize)), + static_cast(MAX(size.height, MGLSnapshotterMinimumPixelSize)) + }); +} + +- (MGLMapCamera *)camera +{ + mbgl::CameraOptions cameraOptions = _mbglMapSnapshotter->getCameraOptions(); + CGFloat pitch = *cameraOptions.pitch; + CLLocationDirection heading = mbgl::util::wrap(*cameraOptions.angle, 0., 360.); + CLLocationDistance distance = MGLAltitudeForZoomLevel(*cameraOptions.zoom, pitch, cameraOptions.center->latitude(), [self size]); + return [MGLMapCamera cameraLookingAtCenterCoordinate:MGLLocationCoordinate2DFromLatLng(*cameraOptions.center) + fromDistance:distance + pitch:pitch + heading:heading]; +} + +- (void)setCamera:(MGLMapCamera *)camera +{ + mbgl::CameraOptions cameraOptions; + CLLocationCoordinate2D center; + if (CLLocationCoordinate2DIsValid(camera.centerCoordinate)) { + cameraOptions.center = MGLLatLngFromLocationCoordinate2D(camera.centerCoordinate); + center = camera.centerCoordinate; + } else { + // Center is optional, but always set. + center = MGLLocationCoordinate2DFromLatLng(*_mbglMapSnapshotter->getCameraOptions().center); + } + + cameraOptions.angle = MAX(0, camera.heading) * mbgl::util::DEG2RAD; + cameraOptions.zoom = MAX(0, MGLZoomLevelForAltitude(camera.altitude, camera.pitch, center.latitude, [self size])); + cameraOptions.pitch = MAX(0, camera.pitch); +} + +- (double)zoomLevel +{ + mbgl::CameraOptions cameraOptions = _mbglMapSnapshotter->getCameraOptions(); + return MGLAltitudeForZoomLevel(*cameraOptions.zoom, *cameraOptions.pitch, cameraOptions.center->latitude(), [self size]); +} + +- (void)setZoomLevel:(double)zoomLevel +{ + mbgl::CameraOptions cameraOptions = _mbglMapSnapshotter->getCameraOptions(); + cameraOptions.zoom = zoomLevel; + _mbglMapSnapshotter->setCameraOptions(cameraOptions); +} + +- (MGLCoordinateBounds)coordinateBounds +{ + return MGLCoordinateBoundsFromLatLngBounds(_mbglMapSnapshotter->getRegion()); +} + +- (void)setCoordinateBounds:(MGLCoordinateBounds)coordinateBounds +{ + _mbglMapSnapshotter->setRegion(MGLLatLngBoundsFromCoordinateBounds(coordinateBounds)); +} + @end -- cgit v1.2.1