Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
302 changes: 302 additions & 0 deletions platform/darwin/docs/guides/For Style Authors.md.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
<%
const os = locals.os;
const iOS = os === 'iOS';
const macOS = os === 'macOS';
const cocoaPrefix = iOS ? 'UI' : 'NS';
const types = locals.types;
const renamedProperties = locals.renamedProperties;
-%>
<!--
This file is generated.
Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-->
# Information for Style Authors

A _style_ defines a map view’s content and appearance. If you’ve authored a
style using
[Mapbox Studio’s Styles editor](https://www.mapbox.com/studio/styles/) or as
JSON in a text editor, you can use that style in this SDK and manipulate it
afterwards in code. This document provides information you can use to ensure a
seamless transition from Mapbox Studio to your application.

<% if (iOS) { -%>
## Designing for iOS
<% } else { -%>
## Designing for macOS
<% } -%>

When designing your style, consider the context in which your application shows
the style. There are a number of considerations specific to <%- os %> that may
not be obvious when designing your style in Mapbox Studio on the Web. A map view
is essentially a graphical user interface element, so many of same issues in
user interface design also apply when designing a map style.

### Color

Ensure sufficient contrast in your application’s user interface when your map
style is present. Standard user interface elements such as toolbars, sidebars,
and sheets often overlap the map view with a translucent, blurred background, so
make sure the contents of these elements remain legible with the map view
underneath.
<% if (iOS) { -%>
The user location annotation view, the attribution button, any buttons in
callout views, and any items in the navigation bar are influenced by your
application’s tint color, so choose a tint color that constrasts well with your
map style. If you intend your style to be used in the dark, consider the impact
that Night Shift may have on your style’s colors.
<% } -%>

### Typography and graphics

<% if (iOS) { -%>
Choose font and icon sizes appropriate to iOS devices. iPhones and iPads have
smaller screens than the typical browser window in which you would use Mapbox
Studio, especially when multitasking is enabled. Your user’s viewing distance
may be shorter than on a desktop computer. Some of your users may use the Larger
Dynamic Type and Accessibility Text features to increase the size of all text on
the device. You can use the
[runtime styling API](#manipulating-the-style-at-runtime) to adjust your style’s
font and icon sizes accordingly.
<% } -%>

Design sprite images and choose font weights that look crisp on both
standard-resolution displays and Retina displays. This SDK supports the same
resolutions as <%- os %>.
<% if (iOS) { -%>
Standard-resolution displays are limited to older devices that your application
may or may not support, depending on its minimum deployment target.
<% } else { -%>
Standard-resolution displays are often found on external monitors. Even with
built-in screens, some of your users may use the Larger Text option in Display
Preferences, which is essentially standard resolution, to make text easier to
read.
<% } -%>

Icon and text labels should be legible regardless of the map’s orientation.
<% if (iOS) { -%>
By default, this SDK makes it easy for your users to rotate or tilt the map
using multitouch gestures.
<% } else { -%>
By default, this SDK makes it easy for your users to rotate or tilt the map
using multitouch trackpad gestures or keyboard shortcuts.
<% } -%>
If you do not intend your design to accommodate rotation and tilting, disable
these gestures using the `MGLMapView.rotateEnabled` and
`MGLMapView.pitchEnabled` properties, respectively, or the corresponding
inspectables in Interface Builder.

### Interactivity

Pay attention to whether elements of your style appear to be interactive.
<% if (iOS) { -%>
A text label may look like a tappable button merely due to matching your
application’s tint color or the default blue tint color.
<% } else { -%>
An icon with a shadow or shading effect may appear to be clickable.
<% } -%>
You can make an icon or text label interactive by installing a gesture
recognizer and performing feature querying (e.g.,
`-[MGLMapView visibleFeaturesAtPoint:]`) to get details about the selected
feature.
<% if (macOS) { -%>
You can install cursor or tooltip tracking rectangles to indicate interactive
features as an alternative to prominent hover effects.
<% } -%>

<% if (iOS) { -%>
Make sure your users can easily distinguish any interactive elements from the
surrounding map, such as pins, the user location annotation view, or a route
line. Avoid relying on hover effects to indicate interactive elements. Leave
enough room between interactive elements to accommodate imprecise tapping
gestures.
<% } else { -%>
Make sure your users can easily distinguish any interactive elements from the
surrounding map, such as pins or a route line. If your application supports
printing, consider using the
[runtime styling API](#manipulating-the-style-at-runtime) to optimize your style
for ink economy before printing the map view.
<% } -%>

<% if (iOS) { -%>
For more information about user interface design, consult Apple’s
[_iOS Human Interface Guidelines_](https://developer.apple.com/ios/human-interface-guidelines/).
<% } else { -%>
For more information about user interface design, consult Apple’s
[_macOS Human Interface Guidelines_](https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/OSXHIGuidelines/).
<% } -%>

## Applying your style

You set an `MGLMapView` object’s style either in code, by setting the
`MGLMapView.styleURL` property, or in Interface Builder, by setting the “Style
URL” inspectable. The URL must point to a local or remote style JSON file. The
style JSON file format is defined by the
[Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/). This
SDK supports the functionality defined by version 8 of the specification unless
otherwise noted in the
[style specification documentation](https://www.mapbox.com/mapbox-gl-style-spec/).

## Manipulating the style at runtime

The _runtime styling API_ enables you to modify every aspect of a style
dynamically as a user interacts with your application. The style itself is
represented at runtime by an `MGLStyle` object, which provides access to various
`MGLSource` and `MGLStyleLayer` objects that represent content sources and style
layers, respectively.
<% if (iOS) { -%>
For more information about the capabilities exposed by the runtime styling API,
see “[Runtime Styling](runtime-styling.html)”.
<% } -%>

The names of runtime styling classes and properties on <%- os %> are generally
consistent with the style specification and Mapbox Studio’s Styles editor. Any
exceptions are listed in this document.

To avoid conflicts with Objective-C keywords or Cocoa terminology, this SDK uses
the following terms for concepts defined in the style specification:

In the style specification | In the SDK
---------------------------|---------
class | style class
filter | predicate
id | identifier
image | style image
layer | style layer
property | attribute
SDF icon | template image
source | content source

## Specifying the map’s content

Each source defined by a style JSON file is represented at runtime by a content
source object that you can use to initialize new style layers. The content
source object is a member of one of the following subclasses of `MGLSource`:

In style JSON | In the SDK
--------------|-----------
`geojson` | `MGLShapeSource`
`raster` | `MGLRasterSource`
`vector` | `MGLVectorSource`

`image` and `video` sources are not supported.

### Tile sources

Raster and vector sources may be defined in TileJSON configuration files. This
SDK supports the properties defined in the style specification, which are a
subset of the keys defined in version 2.1.0 of the
[TileJSON](https://github.com/mapbox/tilejson-spec/tree/master/2.1.0)
specification. As an alternative to authoring a custom TileJSON file, you may
supply various tile source options when creating a raster or vector source.
These options are detailed in the `MGLTileSourceOption` documentation:

In style JSON | In TileJSON | In the SDK
--------------|---------------|-----------
`url` | — | `configurationURL` parameter in `-[MGLTileSource initWithIdentifier:configurationURL:]`
`tiles` | `tiles` | `tileURLTemplates` parameter in `-[MGLTileSource initWithIdentifier:tileURLTemplates:options:]`
`minzoom` | `minzoom` | `MGLTileSourceOptionMinimumZoomLevel`
`maxzoom` | `maxzoom` | `MGLTileSourceOptionMaximumZoomLevel`
`tileSize` | — | `MGLTileSourceOptionTileSize`
`attribution` | `attribution` | `MGLTileSourceOptionAttributionHTMLString` (but consider specifying `MGLTileSourceOptionAttributionInfos` instead for improved security)
`scheme` | `scheme` | `MGLTileSourceOptionTileCoordinateSystem`

### Shape sources

Shape sources also accept various options. These options are detailed in the
`MGLShapeSourceOption` documentation:

In style JSON | In the SDK
-----------------|-----------
`data` | `url` parameter in `-[MGLShapeSource initWithIdentifier:URL:options:]`
`maxzoom` | `MGLShapeSourceOptionMaximumZoomLevel`
`buffer` | `MGLShapeSourceOptionBuffer`
`tolerance` | `MGLShapeSourceOptionSimplificationTolerance`
`cluster` | `MGLShapeSourceOptionClustered`
`clusterRadius` | `MGLShapeSourceOptionClusterRadius`
`clusterMaxZoom` | `MGLShapeSourceOptionMaximumZoomLevelForClustering`

To create a shape source from local GeoJSON data, first
[convert the GeoJSON data into a shape](working-with-geojson-data.html#converting-geojson-data-into-shape-objects),
then use the `-[MGLShapeSource initWithIdentifier:shape:options:]` method.

## Configuring the map content’s appearance

Each layer defined by the style JSON file is represented at runtime by a style
layer object, which you can use to refine the map’s appearance. The style layer
object is a member of one of the following subclasses of `MGLStyleLayer`:

In style JSON | In the SDK
--------------|-----------
<% for (const type of types) { -%>
`<%- type %>` | `MGL<%- camelize(type) %>StyleLayer`
<% } -%>

You configure layout and paint attributes by setting properties on these style
layer objects. The property names generally correspond to the style JSON
properties, except for the use of camelCase instead of kebab-case. Properties
whose names differ from the style specification are listed below:
<% for (const type in renamedProperties) { -%>
<% if (renamedProperties.hasOwnProperty(type)) { -%>

### <%- camelize(type) %> style layers

In style JSON | In Objective-C | In Swift
--------------|----------------|---------
<% for (const name in renamedProperties[type]) { -%>
<% if (renamedProperties[type].hasOwnProperty(name)) { -%>
`<%- originalPropertyName(renamedProperties[type][name]) %>` | `MGL<%- camelize(type) %>StyleLayer.<%- objCName(renamedProperties[type][name]) %>` | `MGL<%- camelize(type) %>StyleLayer.<%- objCGetter(renamedProperties[type][name]) %>`
<% } -%>
<% } -%>
<% } -%>
<% } -%>

## Setting attribute values

Each property representing a layout or paint attribute is set to an
`MGLStyleValue` object, which is either an `MGLStyleConstantValue` object (for
constant values) or an `MGLStyleFunction` object (for zoom level functions). The
style value object is a container for the raw value or function parameters that
you want the attribute to be set to.

In contrast to the JSON type that the style specification defines for each
layout or paint property, the style value object often contains a more specific
Foundation or Cocoa type. General rules for attribute types are listed below.
Pay close attention to the SDK documentation for the attribute you want to set.

In style JSON | In Objective-C | In Swift
--------------|-----------------------|---------
Color | `<%- cocoaPrefix %>Color` | `<%- cocoaPrefix %>Color`
Enum | `NSValue` (see `NSValue(MGLAdditions)`) | `NSValue` (see `NSValue(MGLAdditions)`)
String | `NSString` | `String`
Boolean | `NSNumber.boolValue` | `NSNumber.boolValue`
Number | `NSNumber.floatValue` | `NSNumber.floatValue`
Array (`-dasharray`) | `NSArray<NSNumber>` | `[NSNumber]`
Array (`-font`) | `NSArray<NSString>` | `[String]`
Array (`-offset`, `-translate`) | `CGVector` | `CGVector`
Array (`-padding`) | `<%- cocoaPrefix %>EdgeInsets` | `<%- cocoaPrefix %>EdgeInsets`

## Filtering sources

You can filter a shape or vector source by setting the
`MGLVectorStyleLayer.predicate` property to an `NSPredicate` object. Below is a
table of style JSON operators and the corresponding operators used in the
predicate format string:

In style JSON | In the format string
--------------------------|---------------------
`["has", key]` | `key != nil`
`["!has", key]` | `key == nil`
`["==", key, value]` | `key == value`
`["!=", key, value]` | `key != value`
`[">", key, value]` | `key > value`
`[">=", key, value]` | `key >= value`
`["<", key, value]` | `key < value`
`["<=", key, value]` | `key <= value`
`["in", key, v0, …, vn]` | `key IN {v0, …, vn}`
`["!in", key, v0, …, vn]` | `NOT key IN {v0, …, vn}`
`["all", f0, …, fn]` | `p0 AND … AND pn`
`["any", f0, …, fn]` | `p0 OR … OR pn`
`["none", f0, …, fn]` | `NOT (p0 OR … OR pn)`

See the `MGLVectorStyleLayer.predicate` documentation for a full description of
the supported operators and operand types.
89 changes: 89 additions & 0 deletions platform/darwin/docs/guides/Working with GeoJSON Data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Working with GeoJSON Data

This SDK offers several ways to work with [GeoJSON](http://geojson.org/) files.
GeoJSON is a standard file format for representing geographic data.

## Adding a GeoJSON file to the map

You can use
[Mapbox Studio’s Datasets editor](https://www.mapbox.com/studio/datasets/) to
upload a GeoJSON file and include it in your custom map style. The GeoJSON data
will be hosted on Mapbox servers. When a user loads your style, the SDK
automatically loads the GeoJSON data for display.

Alternatively, if you need to host the GeoJSON file elsewhere or bundle it with
your application, you can use a GeoJSON file as the basis of an `MGLShapeSource`
object. Pass the file’s URL into the
`-[MGLShapeSource initWithIdentifier:URL:options:]` initializer and add the
shape source to the map using the `-[MGLStyle addSource:]` method. The URL may
be a local file URL, an HTTP URL, or an HTTPS URL.

Once you’ve added the GeoJSON file to the map via an `MGLShapeSource` object,
you can configure the appearance of its data and control what data is visible
using `MGLStyleLayer` objects, you can
[access the data programmatically](#Extracting GeoJSON data from the map).

## Converting GeoJSON data into shape objects

If you have GeoJSON data in the form of source code (also known as “GeoJSON
text”), you can convert it into an `MGLShape`, `MGLFeature`, or
`MGLShapeCollectionFeature` object that the `MGLShapeSource` class understands
natively. First, create an `NSData` object out of the source code string or file
contents, then pass that data object into the
`+[MGLShape shapeWithData:encoding:error:]` method. Finally, you can pass the
resulting shape or feature object into the
`-[MGLShapeSource initWithIdentifier:shape:options:]` initializer and add it to
the map, or you can use the object and its properties to power non-map-related
functionality in your application.

## Extracting GeoJSON data from the map

Any `MGLShape`, `MGLFeature`, or `MGLShapeCollectionFeature` object has an
`-[MGLShape geoJSONDataUsingEncoding:]` method that you can use to create a
GeoJSON source code representation of the object. You can extract a feature
object from the map using a method such as
`-[MGLMapView visibleFeaturesAtPoint:]`.

## About GeoJSON deserialization

The process of converting GeoJSON text into `MGLShape`, `MGLFeature`, or
`MGLShapeCollectionFeature` objects is known as “GeoJSON deserialization”.
GeoJSON geometries, features, and feature collections are known in this SDK as
shapes, features, and shape collection features, respectively.

Each GeoJSON object type corresponds to a type provided by either this SDK or
the Core Location framework:

GeoJSON object type | SDK type
--------------------|---------
`Position` (longitude, latitude) | `CLLocationCoordinate2D` (latitude, longitude)
`Point` | `MGLPointAnnotation`
`MultiPoint` | `MGLPointCollection`
`LineString` | `MGLPolyline`
`MultiLineString` | `MGLMultiPolyline`
`Polygon` | `MGLPolygon`
Linear ring | `MGLPolygon.coordinates`, `MGLPolygon.interiorPolygons`
`MultiPolygon` | `MGLMultiPolygon`
`GeometryCollection` | `MGLShapeCollection`
`Feature` | `MGLFeature`
`FeatureCollection` | `MGLShapeCollectionFeature`

A `Feature` object in GeoJSON corresponds to an instance of an `MGLShape`
subclass conforming to the `MGLFeature` protocol. There is a distinct
`MGLFeature`-conforming class for each type of geometry that a GeoJSON feature
can contain. This allows features to be used as shapes where convenient. For
example, some features can be added to a map view as annotations.

In contrast to the GeoJSON standard, it is possible for `MGLShape` subclasses
other than `MGLPointAnnotation` to straddle the antimeridian.

The following GeoJSON data types correspond straightforwardly to Foundation data
types when they occur as feature identifiers or property values:

GeoJSON data type | Objective-C representation | Swift representation
-------------------|----------------------------|---------------------
`null` | `NSNull` | `NSNull`
`true`, `false` | `NSNumber.boolValue` | `NSNumber.boolValue`
Integer | `NSNumber.unsignedLongLongValue`, `NSNumber.longLongValue` | `NSNumber.uint64Value`, `NSNumber.int64Value`
Floating-point number | `NSNumber.doubleValue` | `NSNumber.doubleValue`
String | `NSString` | `String`
Loading