Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Map snapshotter additions #10163

Merged
merged 10 commits into from
Oct 31, 2017
Merged

Map snapshotter additions #10163

merged 10 commits into from
Oct 31, 2017

Conversation

ivovandongen
Copy link
Contributor

@ivovandongen ivovandongen commented Oct 9, 2017

Some additions to the map snapshotter api

@ivovandongen ivovandongen added Android Mapbox Maps SDK for Android Core The cross-platform C++ core, aka mbgl iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS labels Oct 9, 2017
@ivovandongen ivovandongen self-assigned this Oct 9, 2017
@ivovandongen ivovandongen force-pushed the ivd-mapsnapshotter-extensions branch 2 times, most recently from 23b471e to d93b9b5 Compare October 9, 2017 16:59
, fileSource(other.fileSource)
, spriteLoader(std::make_unique<SpriteLoader>(pixelRatio))
, light(std::make_unique<Light>(*other.light))
, observer(&nullObserver) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about all the other members? images, sources, layers, etc.?

Copying the collections is going to be tricky. The wrapper classes should be copied, because they have an observer reference, while the immutable instances (and the immutable vector) should be shared.

Ideally, Style::Impl is itself held in an Immutable, and we move the wrappers, observers, Scheduler, FileSource, AsyncRequest, and SpriteLoader to Style. Then MapSnapshotter can accept an Immutable<Style::Impl> and doesn't have to handle making copies of anything, while the dirty work of copying all the wrappers and setting new observers can be centralized in Style(const Style&).

@@ -101,7 +120,7 @@ typedef void (^MGLMapSnapshotCompletionHandler)(NSImage* _Nullable snapshot, NSE
options.zoomLevel = 10

var snapshotter = MGLMapSnapshotter(options: options)
snapshotter.start { (image, error) in
snapshotter.start { (snapshot, error) in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add this example to MGLDocumentationExampleTests.swift, per these instructions for adding a code example. Otherwise, the next time someone generates runtime styling code, this block may get overwritten.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was missed when the sample was added apparently. Added it now and updated the code.

/**
URL of the map style to snapshot.
*/
@property (nonatomic) NSURL* styleURL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: space before asterisk. (Sorry. 😬)

@@ -139,6 +158,37 @@ MGL_EXPORT
- (void)cancel;

/**
The zoom level.

The default zoom level is 0. This overwrites the camera zoom level if set.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, let’s match the language used in MGLMapSnapshotOptions documentation:

The zoom level.
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.

mbgl::ScreenCoordinate sc = _pointForFn(MGLLatLngFromLocationCoordinate2D(coordinate));
return NSMakePoint(sc.x * self.scale, sc.y * self.scale);
}
#endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, on macOS, NSPoint is a typedef for CGPoint and NSMakePoint() calls CGPointMake(), so conditional compilation isn’t strictly necessary in the implementation.

- (NSURL*)styleURL;
{
NSString *styleURLString = @(_mbglMapSnapshotter->getStyleURL().c_str());
return styleURLString && styleURLString.length > 0 ? [NSURL URLWithString:styleURLString] : nil;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, styleURLString.length ? … : nil is acceptable shorthand.

- (NSURL*)styleURL;
{
NSString *styleURLString = @(_mbglMapSnapshotter->getStyleURL().c_str());
return styleURLString && styleURLString.length > 0 ? [NSURL URLWithString:styleURLString] : nil;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can styleURL be nil? If so, then the property should be declared nullable in the interface. Otherwise, we can assert here that the style is non-nil.

@ivovandongen
Copy link
Contributor Author

As discussed, Runtime Style support is going to need more effort to separate Style from Map on iOS (and Android in the next major release) #9914. Dropping from this PR.

@ivovandongen ivovandongen force-pushed the ivd-mapsnapshotter-extensions branch 4 times, most recently from 180c242 to 4a89384 Compare October 27, 2017 17:18
@ivovandongen
Copy link
Contributor Author

@fabian-guerra @tobrun I finished up the wrappers and added the attributions to the callback so they are ready to use in the SDKs. Should be good to go.

@tobrun
Copy link
Member

tobrun commented Oct 27, 2017

Played around with the Android code and is looking 👍

Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are good changes – thank you. On the iOS/macOS front, just one documentation request, a historical note, and a proposed improvement to the provided example code.

/**
A camera representing the viewport visible in the snapshot.

This overwrites the coordinate bounds if set.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly to #10163 (comment), we should try to be consistent with the corresponding properties of MGLMapSnapshotOptions:

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.

The cooordinate 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.

etc.

@@ -186,4 +214,81 @@ - (void)cancel;
_mbglMapSnapshotter.reset();
}

- (NSURL*)styleURL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The trailing semicolon here is technically incorrect, but GCC and Clang are lenient about it by default because it used to be very common a decade or so ago. (If I remember correctly, older versions of Interface Builder would generate boilerplate code for you that included the semicolon.) Just an FYI; I thought you might find it interesting. The most substantive issue is the space before the asterisk. 😛

//#-example-code
let camera = MGLMapCamera()
camera.centerCoordinate = CLLocationCoordinate2D(latitude: 37.7184, longitude: -122.4365)
camera.pitch = 20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The preferred way to create a camera is via one of the other initializers, either MGLMapCamera(lookingAtCenter:fromEyeCoordinate:eyeAltitude:) or MGLMapCamera(lookingAtCenter:fromDistance:pitch:heading:). Following MapKit’s lead, these initializers encourage developers to make it clear as to whether the camera is based on a focused point on the map or an actor somewhere in space.

(You can specify whatever distance you want, since zoomLevel will override it below. #5583 would allow us to eliminate this awkward situation.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just moved over the existing documentation, but I will adapt.

@tobrun
Copy link
Member

tobrun commented Oct 31, 2017

@ivovandongen noticing the following when implementing attribution on android:

I'm getting back the following String:

<a href="https://www.mapbox.com/about/maps/" target="_blank">&copy; Mapbox</a> <a href="http://www.openstreetmap.org/about/" target="_blank">&copy; OpenStreetMap</a> <a class="mapbox-improve-map" href="https://www.mapbox.com/map-feedback/" target="_blank">Improve this map</a>

Would it be possible to exclude the improve this map link?

Additionally the attribution was setup as String[], but these seem to be placed in a single string:
screen shot 2017-10-30 at 18 02 37

Also there is an empty string that shouldn't be there.

}};

// Collect all source attributions
std::vector<std::string> attributions;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, we decided in #6465, we decided that mbgl wouldn’t be responsible for collecting each source’s attribution strings. I take it this is merely a stopgap until we have full runtime styling support for snapshots?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The situation is slightly different here as the Map/Style/Sources live on another thread. This means we can't call them directly from the main thread and copying them over just to give access to the attribution strings seems like a waste. That's why I opted to pass them along with the snapshot result.

@1ec5
Copy link
Contributor

1ec5 commented Oct 31, 2017

Additionally the attribution was setup as String[], but these seem to be placed in a single string

Most likely, there are two sources, and one has multiple links in its attribution HTML, while another has an empty string as its attribution HTML. It should be the job of platform-specific code to parse links out of the HTML and detect map feedback links, as it does in the usual case for interactive map views.

@tobrun
Copy link
Member

tobrun commented Oct 31, 2017

Thank you for adding the context, will adapt the binding code accordingly

@ivovandongen ivovandongen merged commit e0a3052 into master Oct 31, 2017
@fabian-guerra fabian-guerra mentioned this pull request Nov 1, 2017
@tobrun tobrun mentioned this pull request Nov 3, 2017
21 tasks
This was referenced Nov 14, 2017
@jfirebaugh jfirebaugh deleted the ivd-mapsnapshotter-extensions branch July 27, 2018 22:47
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Android Mapbox Maps SDK for Android Core The cross-platform C++ core, aka mbgl iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS runtime styling
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants