-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Conversation
625715b
to
3a9c31b
Compare
4cfb29f
to
28a84a7
Compare
@param mapCamera the camera settings | ||
@param size the image size | ||
*/ | ||
- (instancetype )initWithStyleURL:(NSURL* )styleURL mapCamera:(MGLMapCamera*) mapCamera size:(CGSize) size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Inconsistent formatting. (only spaces before *
)
Drop map
from mapCamera
. (×3)
@property (nonatomic) MGLMapCamera* mapCamera; | ||
|
||
/** | ||
(Optionally) a region to capture. Overrides the center coordinate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's drop optional since region is invalid empty by default and Obj-C doesn't support optional structs.
/** | ||
A block to processes the result or error of a snapshot request. | ||
|
||
The result will be either an `MGLImage*` or a `NSError*` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: s/MGLImage*/MGLImage/NSError*/NSError (I don't think jazzy will link otherwise)
- (void)cancel; | ||
|
||
/** | ||
Indicates wether as snapshot is currently being generated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: s/wether/whether
[self startWithQueue:dispatch_get_main_queue() completionHandler:completion]; | ||
} | ||
|
||
- (void)startWithQueue:(dispatch_queue_t)queue completionHandler: (MGLMapSnapshotCompletionHandler)completion; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is slightly confusing. startWithQueue
implies that we generate the snapshot on the given queue but here we're calling the completion on the given queue. This is usually called handlerQueue
or delegateQueue
.
I think we should dispatch to the given queue before handing off to core so we can decide if we want to snapshot in parallel or serial.
std::unique_ptr<mbgl::MapSnapshotter> mbglMapSnapshotter; | ||
std::unique_ptr<mbgl::Actor<mbgl::MapSnapshotter::Callback>> snapshotCallback; | ||
|
||
BOOL loading; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: loading is already synthesized. This can be dropped. Use _loading
to bypass readonly when you set the variable.
mbglMapSnapshotter.reset(); | ||
} | ||
|
||
-(BOOL)isLoading; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: already synthesized. Drop this method.
6a6957e
to
f4ee3fb
Compare
@frederoni Thanks for the review! I've fixed up the comments and made sure the work is now all done on the provided queue (or the main queue). I also added some code to add the logo on the image in a work queue (https://github.com/mapbox/mapbox-gl-native/pull/9891/files#diff-56bc5c1e41273957efd873aa83e6c522R116). Could you check if that is the right queue to do this on? |
61159dd
to
4ad3a56
Compare
b6a46f4
to
3337f0c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for implementing this feature so swiftly! It’s certainly going to be well received. I left some comments below that the team will need to address as tail work, ideally before the first v3.7.0 beta.
In addition to the comments below, we’ll probably want to add MGLMapSnapshotter and MGLMapSnapshotOptions to the jazzy table of contents in jazzy.yml and update the changelog to mention the new feature, both for iOS and macOS.
*/ | ||
- (instancetype)initWithStyleURL:(NSURL*)styleURL camera:(MGLMapCamera*)camera size:(CGSize)size; | ||
|
||
#pragma mark - Configuring the map |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For our public headers, we use Title Case in marks, since jazzy uses the marks to produce section headings in the generated documentation. We could move to sentence case for that, but it would be nice to do it consistently across all the headers when we make that decision.
/** | ||
The style URL for these options. | ||
*/ | ||
@property (nonatomic, readonly) NSURL* styleURL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, the predominant style in our Objective-C code is to place the space before the asterisk. I realize this is different than the predominant style for our C++ code.
/** | ||
The zoom. Default is 0. | ||
*/ | ||
@property (nonatomic) double zoom; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The iOS/macOS APIs consistently use the term “zoom level” rather than “zoom” for this concept. The main reason is that “zoom” is also a verb; in Objective-C, [mapView zoom]
looks like a call to an action method rather than a reference to a property getter.
A region to capture. Overrides the center coordinate | ||
in the mapCamera options if set | ||
*/ | ||
@property (nonatomic) MGLCoordinateBounds region; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the API uses the term “coordinate bounds” instead of “region”, although there is some holdover from MapKit in the delegate methods. It’s a confusing situation overall, but I think it would be slightly less confusing to use coordinateBounds
here, to align with MGLMapView.visibleCoordinateBounds
.
#pragma mark - Configuring the image | ||
|
||
/** | ||
The size of the output image. Minimum is 64x64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this size measured in points or pixels?
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)]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MGLStyle has factory methods for style URLs. We use them whenever possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case the traffic style is deprecated, even tho it has not yet merged into master. Our recommendation is create an URL with this string mapbox://styles/mapbox/traffic-day-v2
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, the demo doesn’t depend on the traffic congestion information displayed by the Traffic Day style, so I’d recommend choosing a non-deprecated method like +[MGLStyle satelliteStreets]
.
|
||
} | ||
|
||
NSString *extension = [[fileURL pathExtension] lowercaseString]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File name extensions aren’t especially reliable on Apple platforms, since a file’s canonical type is represented by a UTI. The save panel even lets you save without an extension unless you restrict the allowed file types to those that can be represented as images:
panel.allowedFileTypes = [NSImage imageTypes];
Here’s a more robust way to go from a file extension to a UTI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An alternative to looking at file extensions:
- The save panel tells us the file path. use NSFileManager to determine the UTI at that path. (Not sure if this only works for existing files or if it would work for unsaved files as well.)
- Use
UTTypeConformsTo()
to determine whether the UTI at that path conforms topublic.jpeg
etc. - Avoid hard-coding UTIs like
public.jpeg
by iterating over+[NSImage imageTypes]
.
@param camera the camera settings | ||
@param size the image size | ||
*/ | ||
- (instancetype)initWithStyleURL:(NSURL*)styleURL camera:(MGLMapCamera*)camera size:(CGSize)size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to allow the style URL to be nil
and default to Mapbox Streets, as MGLMapView and MGLOfflineStorage do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@1ec5 could you please help me understand why defaulting to Mapbox streets is a good option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you create an MGLMapView or MGLOfflineRegion with a nil
style URL, we default to the current version of Mapbox Streets:
styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion]; |
styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion]; |
For consistency with these APIs, I think we should treat a nil
style URL here the same way.
|
||
/** | ||
Creates a set of options with the minimum required information | ||
@param styleURL the style url to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Start with a capital letter and end with a period. This makes things more consistent in the event that we have to cram more than one sentence in a parameter description, which isn’t uncommon.
- (void)startWithQueue:(dispatch_queue_t)queue completionHandler:(MGLMapSnapshotCompletionHandler)completion; | ||
{ | ||
if ([self isLoading]) { | ||
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"Already started this snapshotter"}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This string should be localizable, since it can be presented to the user.
For iOS: #9919 |
Filed #9920 so we can better track the fit-and-finish detailed in #9891 (review). |
@@ -128,6 +128,12 @@ | |||
<action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/> | |||
</connections> | |||
</menuItem> | |||
<menuItem title="Save snapshot" id="vjX-0E-kLO"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use title case on menu items.
iOS/macOS companion for #9748
TODO: