-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrade to Mapbox GL–based Mapbox Static API #54
Conversation
Renamed SnapshotOptions to ClassicSnapshotOptions. Added a similar SnapshotOptions class tailored to the GL-based Static API. Split out ClassicSnapshotTests.
We previously made this initializer failable instead of throwable because of a compiler bug, but the bug appears to have been resolved in Swift 3.
Split out classic overlay tests into a separate test class. Replaced clever but untested URL parsing code in tests with much more straightforward string literals that can be verified easily. Added test fixture images. Verify that NSImage or UIImage can be created from each test fixture image. Switched to mapbox.streets in overlay tests to make fixtures easier to identify. Added configuration tests.
Upgraded example applications to use the new SnapshotOptions initializer. Refined MBSnapshotCamera initializer for Objective-C in the form of a factory method.
The server-side rendering issues have been fixed, so the remaining work is no longer blocked. |
Added altitude as an alternative to zoom level in SnapshotCamera, for consistency with MapKit and the Mapbox iOS SDK.
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.
Not entirely sold on the map camera approach, but that’s a matter of taste.
My first time using the playground here — it’s nice.
#endif | ||
|
||
/** | ||
A structure that determines what a snapshot depicts and how it is formatted. A classic snapshot is made by compositing one or more [tile sets](https://www.mapbox.com/help/define-tileset/) with optional overlays using the [classic Mapbox Static API](https://www.mapbox.com/api-documentation/?language=Swift#static-classic). |
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 it a historical oversight that these lines aren’t manually wrapped?
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.
Since Xcode automatically reformats the comment in the generated interface (whether you're coming from Swift or Objective-C code), I've been less concerned about documentation comment formatting here than in the gl-native codebase. But if you're concerned about readability for contributors to this codebase, we can address the line wrapping issue in a separate PR.
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.
We’d have to tread carefully, because the component that translates Swift into Objective-C headers (and thus reStructuredText into Doxygen) is a bit fragile. Objective-C bridging has broken in the past due to something as innocuous as a blank line between - parameter
and - note
.
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.
Mostly the line length just made it slightly more painful to review.
MapboxStatic/Snapshot.swift
Outdated
|
||
If you use `Snapshot` to display a [vector tile set](https://www.mapbox.com/help/define-tileset/#vector-tilesets), the snapshot image will depict a wireframe representation of the tile set. To generate a static, styled image of a vector tile set, use the [vector Mapbox Static API](https://www.mapbox.com/api-documentation/?language=Swift#static). | ||
The snapshot image can be used in an image view (`UIImage` on iOS and tvOS, `NSImage` on macOS, `WKImage` on watchOS). To add interactivity, use the `MGLMapView` class provided by the [Mapbox iOS SDK](https://www.mapbox.com/ios-sdk/) or [Mapbox macOS SDK](https://github.com/mapbox/mapbox-gl-native/tree/master/platform/macos/). (See the “[Custom raster style](https://www.mapbox.com/ios-sdk/examples/raster-styles/)” example to display a raster tile set in an `MGLMapView`.) |
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.
To add interactivity, use the
MGLMapView
...
This makes the two libraries sound as if one is necessary for the other or that they are somehow integrated. I think we should frame this more as, “For interactive maps, see our fully-featured SDKs...” and avoid mentioning classnames that impatient readers might expect to exist in this library.
I’m also unsure of the mention of the iOS SDK’s raster tiles example — it strikes me as a non-sequitor, given that that example deals in tilesets and not individual static images.
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.
Clarified in 5ccc930.
/** | ||
Size of a tile. | ||
*/ | ||
static let tileSize = CGSize(width: 512, height: 512) |
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.
Strictly reading this code, it could be made more clear that tileSize
represents an internal implementation detail and not size
.
Besides a little disambiguation, is there a source of truth for this that we can link to?
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 an private variable factored out for the purpose of keeping the altitude conversion code readable.
} | ||
|
||
func string(size: CGSize) -> String { | ||
assert(-90...90 ~= centerCoordinate.latitude, "Center latitude must be between −90° and 90°.") |
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.
Nice range comparison.
assert(0...20 ~= zoomLevel, "Zoom level must be between 0 and 20.") | ||
components.append(Double(zoomLevel)) | ||
|
||
if heading > 0 { |
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.
Does heading
need a range check, or will >360 just keep wrapping?
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 API wraps it automatically.
/** | ||
A Boolean determining whether the resulting image includes the Mapbox logo. | ||
|
||
When shown, the Mapbox logo is located in the lower-left corner of the image. By default, this property is set to `true`. |
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.
Chances are quite high that the developer is required to include the logo, so linking https://www.mapbox.com/help/attribution/ here also makes sense.
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.
Noted in 5ccc930.
README.md
Outdated
@@ -16,13 +16,13 @@ MapboxStatic.swift pairs well with [MapboxDirections.swift](https://github.com/m | |||
Specify the following dependency in your [Carthage](https://github.com/Carthage/Carthage/) Cartfile: | |||
|
|||
```sh | |||
github "Mapbox/MapboxStatic.swift" "~> 0.7" | |||
github "Mapbox/MapboxStatic.swift" "master" |
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.
Risky... is it necessary not to specify a version?
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 now. Whenever we rewrite the readme, we have to instruct the developer to get the master version so that the instructions are consistent. Otherwise we'd have to stage changes to the documentation, which would render them inconsistent with the rest of the repository in the meantime.
This shouldn't be a problem, because both CocoaPods and Carthage instruct developers to check in their lock files.
iOS.playground/Contents.swift
Outdated
*/ | ||
|
||
let mapIdentifiers = ["justin.tm2-basemap"] | ||
let styleURL = URL(string: "mapbox://styles/mapbox/streets-v9")! | ||
let mapIdentifiers = ["mapbox.satellite"] | ||
let accessToken = "pk.eyJ1IjoianVzdGluIiwiYSI6IlpDbUJLSUEifQ.4mG8vhelFMju6HpIY-Hi5A" |
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 token belongs to @incanus — it should be replaced with one belonging to the mapbox
account, if we’re going to include one at all.
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.
We do need to include the token if we want the playground to function as it does. We can replace it with a Mapbox corporate token, though.
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.
Replaced in 49ec1d0.
macOS.playground/Contents.swift
Outdated
*/ | ||
|
||
let mapIdentifiers = ["justin.tm2-basemap"] | ||
let styleURL = URL(string: "mapbox://styles/mapbox/streets-v9")! | ||
let mapIdentifiers = ["mapbox.satellite"] | ||
let accessToken = "pk.eyJ1IjoianVzdGluIiwiYSI6IlpDbUJLSUEifQ.4mG8vhelFMju6HpIY-Hi5A" |
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.
Ditto to this access token.
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.
Dittoed in 49ec1d0.
Clarified the relationship between Snapshot and the iOS and macOS SDKs. Added a notice about the general requirement to leave the logo enabled.
Huzzah! |
This PR adds support for the Mapbox GL–powered Mapbox Static API alongside the existing support for the classic Static API. In the process, the existing Swift files have been split up to be more manageable.
The
Snapshot
class andOverlay
subclasses are largely untouched, a consequence of the fact that the new API tries to mimic the classic API’s overlay options.SnapshotOptions
has been renamedClassicSnapshotOptions
. This PR takes advantage of theSnapshotOptionsProtocol
protocol – meant to provide a common interface forClassicSnapshotOptions
andMarkerOptions
– to add another conforming protocol, namedSnapshotOptions
, that exposes options for working with the new API.SnapshotOptions
is a bit more complex thanClassicSnapshotOptions
. Instead of accepting separatecenterCoordinate
andzoomLevel
options, it takes a singlecamera
option of typeSnapshotCamera
.SnapshotCamera
defines both a conventionalzoomLevel
property and analtitude
property (for compatibility with the Mapbox iOS and macOS SDKs’MGLMapCamera
class); the developer can use either.SnapshotCamera
closely parallels the Mapbox iOS and macOS SDKs’ MGLMapCamera class, in much the same way that MapKit’s MKMapSnapshotOptions and MKMapView classes both havecamera
properties of type MKMapCamera. This library can’t simply reuse MGLMapCamera because it lives in the Mapbox iOS and macOS SDKs, which are separate frameworks. (Perhaps we should move this entire library’s functionality into those SDKs to fix mapbox/mapbox-gl-native#1701?)GeoJSON(object:)
is once again throwable. #23 made it throwable, but #28 had to make it failable instead due to a type mismatch when bridging to Objective-C. As of Swift 3, SE-0112 resolved the type mismatch, so the initializer can once again be throwable without breaking Objective-C support.The classic snapshot tests have been rewritten to replace clever but untested URL parsing code in tests with much more straightforward string literals that can be verified easily. Now, if you want to know the URL that a particular
ClassicSnapshotOptions
produces, you can copy the stub’sisPath()
call’s argument into a browser instead of having to run the test code. Test fixture images have been added, and the tests verify that an NSImage or UIImage can be created from each test fixture image produced bySnapshot
.To recap:
SnapshotOptions
toClassicSnapshotOptions
SnapshotOptions
based on GL-based APIGeoJSON
initializer throwableFixes #9.
/cc @frederoni @bsudekum @incanus @friedbunny