Port remaining articles from Jazzy docs to DocC (#2778)

This commit is contained in:
Bart Louwers
2024-08-28 18:55:15 +02:00
committed by GitHub
parent ff2c1e8e73
commit 290bf927f5
40 changed files with 502 additions and 4106 deletions

View File

@@ -88,16 +88,6 @@ filegroup(
visibility = ["//visibility:public"],
)
filegroup(
name = "docs_ejs_templates",
srcs = [
"docs/guides/For_Style_Authors.md.ejs",
"docs/guides/Migrating_to_Expressions.md.ejs",
"docs/guides/Tile_URL_Templates.md.ejs",
],
visibility = ["//visibility:public"],
)
filegroup(
name = "generator_data",
srcs = [
@@ -112,7 +102,6 @@ filegroup(
js_run_binary(
name = "generated_code",
srcs = [
":docs_ejs_templates",
":generator_data",
":test_ejs_templates",
],

View File

@@ -1,212 +0,0 @@
<%
const os = locals.os;
const iOS = os === 'iOS';
const macOS = os === 'macOS';
const cocoaPrefix = iOS ? 'UI' : 'NS';
const guide = 'MigratingToExpressions';
-%>
<!--
This file is generated.
Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
-->
# Migrating from Style Functions to Expressions
[Runtime Styling](https://www.mapbox.com/ios-sdk/maps/overview/runtime-styling/) enables you to modify every aspect of the map’s appearance dynamically as a user interacts with your application. Developers can specify in advance how a layout or paint attribute will vary as the zoom level changes or how the appearance of individual features vary based on metadata provided by a content source.
With Mapbox Maps SDK for <%- iOS ? 'iOS v4.0.0' : 'macOS v0.7.0' %>, style functions have been replaced with expressions. These provide even more tools for developers who want to style their maps dynamically. This guide outlines some tips for migrating from style functions to expressions, and offers an overview of some things that developers can do with expressions.
An expression is represented at runtime by the `NSExpression` class. Expressions can be used to style paint and layout properties based on zoom level, data attributes, or a combination of the two.
A constant expression can also be assigned to a style property. For example, the opacity of a fill style layer can be set to a constant value between 0 and 1.
The documentation for each individual style layer property notes which non-constant expressions are enabled for that property. Style functions supported four interpolation modes: exponential, interval, categorical, and identity.
This guide uses earthquake data from the [U.S. Geological Survey](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php). Under each interpolation mode, the style function implementation will be shown, followed by the current syntax.
For more information about how to work with GeoJSON data in our <%- os %> SDK, please see our [working with GeoJSON data](working-with-geojson-data.html) guide. To learn more about supported expressions, see our ["Predicates and Expressions"](predicates-and-expressions.html) guide. The "Predicates and Expressions" guide also outlines Mapbox custom functions that can be used to dynamically style a map.
## Stops
Stops are dictionary keys that are associated with layer attribute values. Constant values no longer need to be wrapped as style values when they are values in a stops dictionary.
Style function syntax:
```swift
let stops = [
0: MLNStyleValue<UIColor>(rawValue: .yellow),
2.5: MLNStyleValue(rawValue: .orange),
5: MLNStyleValue(rawValue: .red),
7.5: MLNStyleValue(rawValue: .blue),
10: MLNStyleValue(rawValue: .white),
]
```
Current syntax:
<%- guideExample(guide, 'Stops', os) %>
## Interpolation mode
Style functions supported four interpolation modes: exponential/linear, interval, categorical, and identity. For more information about supported custom expressions, please see the "Predicates and Expressions" guide.
### Linear
`+[NSExpression(MLNAdditions) mgl_expressionForInterpolatingExpression:withCurveType:parameters:stops:]` takes the interpolation type as a parameter. If you previously used the default interpolation base, use the curve type `MLNExpressionInterpolationMode.linear`. See the [`mgl_interpolate:withCurveType:parameters:stops:`](predicates-and-expressions.html#code-mgl_interpolate-withcurvetype-parameters-stops-code) documentation for more details.
The stops dictionary below, shows colors that continuously shift from yellow to orange to red to blue to white based on the attribute value.
Style function syntax:
```swift
let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")!
let symbolSource = MLNSource(identifier: "source")
let symbolLayer = MLNSymbolStyleLayer(identifier: "place-city-sm", source: symbolSource)
let source = MLNShapeSource(identifier: "earthquakes", url: url, options: nil)
mapView.style?.addSource(source)
let stops = [
0: MLNStyleValue<UIColor>(rawValue: .yellow),
2.5: MLNStyleValue(rawValue: .orange),
5: MLNStyleValue(rawValue: .red),
7.5: MLNStyleValue(rawValue: .blue),
10: MLNStyleValue(rawValue: .white),
]
let layer = MLNCircleStyleLayer(identifier: "circles", source: source)
layer.circleColor = MLNStyleValue(interpolationMode: .exponential,
sourceStops: stops,
attributeName: "mag",
options: [.defaultValue: MLNStyleValue<UIColor>(rawValue: .green)])
layer.circleRadius = MLNStyleValue(rawValue: 10)
mapView.style?.insertLayer(layer, below: symbolLayer)
```
Current syntax:
<%- guideExample(guide, 'Linear', os) %>
### Exponential
If you previously used an interpolation base greater than `0` (other than `1`), you can use `MLNExpressionInterpolationMode.exponential` as the curve type for `+[NSExpression(MLNAdditions) mgl_expressionForInterpolatingExpression:withCurveType:parameters:stops:]` or `'exponential'` as the curve type for [`mgl_interpolate:withCurveType:parameters:stops:`](predicates-and-expressions.html#code-mgl_interpolate-withcurvetype-parameters-stops-code). The `parameters` argument takes that interpolation base. This interpolates between values exponentially, creating an accelerated ramp effect.
Here’s a visualization from Mapbox Studio (see [Mapbox Studio and iOS](https://www.mapbox.com/ios-sdk/maps/overview/mapbox-studio/)) comparing interpolation base values of `1.5` and `0.5` based on zoom. In order to convert camera style functions, use `$zoomLevel` or `MLN_FUNCTION('zoomLevel')` as the attribute key.
<img src="img/data-driven-styling/exponential-function.png" height=344/>
<img src="img/data-driven-styling/exponential-function-1.png" height=344/>
The example below increases a layer’s `circleRadius` exponentially based on a map’s zoom level. The interpolation base is `1.5`.
Style function syntax:
```swift
let stops = [
12: MLNStyleValue<NSNumber>(rawValue: 0.5),
14: MLNStyleValue(rawValue: 2),
18: MLNStyleValue(rawValue: 18),
]
layer.circleRadius = MLNStyleValue(interpolationMode: .exponential,
cameraStops: stops,
options: [.interpolationBase: 1.5])
```
Current syntax:
<%- guideExample(guide, 'Exponential', os) %>
### Interval
Steps, or intervals, create a range using the keys from the stops dictionary. The range is from the given key to just less than the next key. The attribute values that fall into that range are then styled using the layout or paint value assigned to that key. You can use the `+[NSExpression(MLNAdditions) mgl_expressionForSteppingExpression:fromExpression:stops:]` method or the custom function [`mgl_step:from:stops:`](predicates-and-expressions.html#code-mgl_step-from-stops-code) for cases where you previously used interval interpolation mode. The first parameter takes the feature attribute name and the second parameter (`from:`) optionally takes the default or fallback value for that function. The final parameter takes a stops dictionary as an argument.
When we use the stops dictionary given above with an `'mgl_step:from:stops:'`, we create ranges where earthquakes with a magnitude of 0 to just less than 2.5 would be yellow, 2.5 to just less than 5 would be orange, and so on.
Style function syntax:
```swift
let stops = [
0: MLNStyleValue<UIColor>(rawValue: .yellow),
2.5: MLNStyleValue(rawValue: .orange),
5: MLNStyleValue(rawValue: .red),
7.5: MLNStyleValue(rawValue: .blue),
10: MLNStyleValue(rawValue: .white),
]
layer.circleColor = MLNStyleValue(interpolationMode: .interval,
sourceStops: stops,
attributeName: "mag",
options: [.defaultValue: MLNStyleValue<UIColor>(rawValue: .green)])
````
Current syntax:
<%- guideExample(guide, 'Interval', os) %>
### Categorical
Categorical interpolation mode took a stops dictionary. If the value for a specified feature attribute name matched one in that stops dictionary, the style value for that attribute value would be used. Categorical style functions can now be replaced with `MLN_MATCH`.
`MLN_MATCH` takes an initial condition, which in this case is an attribute key. This is followed by possible matches for that key and the value to assign to the layer property if there is a match. The final argument can be a default style value that is to be used if none of the specified values match.
There are three main types of events in the USGS dataset: earthquakes, explosions, and quarry blasts. In this case, the color of the circle layer will be determined by the type of event, with a default value of blue to catch any events that do not fall into any of those categories.
Style function syntax:
```swift
let categoricalStops = [
"earthquake": MLNStyleValue<UIColor>(rawValue: .orange),
"explosion": MLNStyleValue(rawValue: .red),
"quarry blast": MLNStyleValue(rawValue: .yellow),
]
layer.circleColor = MLNStyleValue(interpolationMode: .categorical,
sourceStops: categoricalStops,
attributeName: "type",
options: [.defaultValue: MLNStyleValue<UIColor>(rawValue: .blue)])
```
Current syntax:
<%- guideExample(guide, 'Categorical', os) %>
If your use case does not require a default value, you can either apply a predicate to your layer prior to styling it, or use the format string `"valueForKeyPath:"`.
### Identity
Identity interpolation mode used the attribute’s value as the style layer property value. In this example, you might set the `circleRadius` to the earthquake’s magnitude. In order to use a feature attribute value to style a layer property, set the property value to `[NSExpression expressionForKeyPath:]`, which take the feature attribute name as an argument.
Style function syntax:
```swift
layer.circleRadius = MLNStyleValue(interpolationMode: .identity,
sourceStops: nil,
attributeName: "mag",
options: [.defaultValue: MLNStyleValue<NSNumber>(rawValue: 0)])
```
Current syntax:
<%- guideExample(guide, 'Identity', os) %>
![identity mode](img/data-driven-styling/identity.png)
Some built-in functions can be applied to attribute values to style layer property values. To set the circle radius to three times the earthquake’s magnitude, create a `multiply:by:` function that takes the attribute value and the multiplier as arguments, or use a format string.
<%- guideExample(guide, 'Multiply', os) %>
![multiply magnitude](img/data-driven-styling/multiply.png)
You can also cast attribute values in order to use them. One example is to cast an integer as an `NSString` and use it as a text value.
<%- guideExample(guide, 'Cast', os) %>
![cast a value](img/data-driven-styling/cast.png)
### Constant Values
For constant values that do not necessarily change based on camera or attribute values, use `[NSExpression expressionForConstantValue:]` (previously `[MLNStyleValue valueWithRawValue:]`).
## Resources
* [USGS Earthquake Feed](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php)
* [For Style Authors](for-style-authors.html)
* [Predicates and Expressions](predicates-and-expressions.html)

View File

@@ -1,109 +0,0 @@
<%
const os = locals.os;
const iOS = os === 'iOS';
//const macOS = os === 'macOS';
//const cocoaPrefix = iOS ? 'UI' : 'NS';
-%>
<!--
This file is generated.
Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
-->
# Tile URL Templates
`MLNTileSource` objects, specifically `MLNRasterTileSource` and
`MLNVectorTileSource` objects, can be created using an initializer that accepts
an array of tile URL templates. Tile URL templates are strings that specify the
URLs of the vector tiles or raster tile images to load. A template resembles an
absolute URL, but with any number of placeholder strings that the source
evaluates based on the tile it needs to load. For example:
* `http://www.example.com/tiles/{z}/{x}/{y}.pbf` could be
evaluated as `http://www.example.com/tiles/14/6/9.pbf`.
* `http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png` could be
evaluated as `http://www.example.com/tiles/14/6/9@2x.png`.
Tile URL templates are also used to define tilesets in TileJSON manifests or
[`raster`](https://maplibre.org/maplibre-style-spec/sources/#raster-tiles)
and
[`vector`](https://maplibre.org/maplibre-style-spec/sources/#vector-tiles)
sources in style JSON files. See the
[TileJSON specification](https://github.com/mapbox/tilejson-spec/tree/master/2.2.0)
for information about tile URL templates in the context of a TileJSON or style
JSON file.
Tile sources support the following placeholder strings in tile URL templates,
all of which are optional:
<table>
<thead>
<tr><th>Placeholder string</th><th>Description</th></tr>
</thead>
<tbody>
<tr>
<td><code>{x}</code></td>
<td>The index of the tile along the map’s x axis according to Spherical
Mercator projection. If the value is 0, the tile’s left edge corresponds
to the 180th meridian west. If the value is 2<sup><var>z</var></sup>−1,
the tile’s right edge corresponds to the 180th meridian east.</td>
</tr>
<tr>
<td><code>{y}</code></td>
<td>The index of the tile along the map’s y axis according to Spherical
Mercator projection. If the value is 0, the tile’s tile edge corresponds
to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value
is 2<sup><var>z</var></sup>−1, the tile’s bottom edge corresponds to
−arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is
inverted if the <code>options</code> parameter contains
<code>MLNTileSourceOptionTileCoordinateSystem</code> with a value of
<code>MLNTileCoordinateSystemTMS</code>.</td>
</tr>
<tr>
<td><code>{z}</code></td>
<td>The tile’s zoom level. At zoom level 0, each tile covers the entire
world map; at zoom level 1, it covers ¼ of the world; at zoom level 2,
<sup>1</sup>⁄<sub>16</sub> of the world, and so on. For tiles loaded by
a <code>MLNRasterTileSource</code> object, whether the tile zoom level
matches the map’s current zoom level depends on the value of the
source’s tile size as specified in the
<code>MLNTileSourceOptionTileSize</code> key of the <code>options</code>
parameter.</td>
</tr>
<tr>
<td><code>{bbox-epsg-3857}</code></td>
<td>The tile’s bounding box, expressed as a comma-separated list of the
tile’s western, southern, eastern, and northern extents according to
Spherical Mercator (EPSG:3857) projection. The bounding box is typically
used with map services conforming to the
<a href="http://www.opengeospatial.org/standards/wms">Web Map Service</a>
protocol.</td>
</tr>
<tr>
<td><code>{quadkey}</code></td>
<td>A quadkey indicating both the tile’s location and its zoom level. The
quadkey is typically used with
<a href="https://msdn.microsoft.com/en-us/library/bb259689.aspx">Bing Maps</a>.
</td>
</tr>
<tr>
<td><code>{ratio}</code></td>
<td>A suffix indicating the resolution of the tile image. The suffix is the
empty string for standard resolution displays and <code>@2x</code> for
<% if (iOS) { -%>
Retina displays, including displays for which <code>UIScreen.scale</code>
is 3.
<% } else { -%>
Retina displays.
<% } -%>
</td>
</tr>
<tr>
<td><code>{prefix}</code></td>
<td>Two hexadecimal digits chosen such that each visible tile has a
different prefix. The prefix is typically used for domain sharding.</td>
</tr>
</tbody>
</table>
For more information about the `{x}`, `{y}`, and `{z}` placeholder strings,
consult the
[OpenStreetMap Wiki](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames).

View File

@@ -1,101 +0,0 @@
# 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 `MLNShapeSource`
object. Pass the file’s URL into the
`-[MLNShapeSource initWithIdentifier:URL:options:]` initializer and add the
shape source to the map using the `-[MLNStyle 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 `MLNShapeSource` object,
you can configure the appearance of its data and control what data is visible
using `MLNStyleLayer` objects. You can also
[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 `MLNShape`, `MLNFeature`, or
`MLNShapeCollectionFeature` object that the `MLNShapeSource` class understands
natively. First, create an `NSData` object out of the source code string or file
contents, then pass that data object into the
`+[MLNShape shapeWithData:encoding:error:]` method. Finally, you can pass the
resulting shape or feature object into the
`-[MLNShapeSource 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.
To include multiple shapes in the source, create and pass an `MLNShapeCollection` or
`MLNShapeCollectionFeature` object to
`-[MLNShapeSource initWithIdentifier:shape:options:]`. Alternatively, use the
`-[MLNShapeSource initWithIdentifier:features:options:]` or
`-[MLNShapeSource initWithIdentifier:shapes:options:]` method to create a shape source
with an array. `-[MLNShapeSource initWithIdentifier:features:options:]` accepts only `MLNFeature`
instances, such as `MLNPointFeature` objects, whose attributes you can use when
applying a predicate to `MLNVectorStyleLayer` or configuring a style layer’s
appearance.
## Extracting GeoJSON data from the map
Any `MLNShape`, `MLNFeature`, or `MLNShapeCollectionFeature` object has an
`-[MLNShape 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
`-[MLNMapView visibleFeaturesAtPoint:]`.
## About GeoJSON deserialization
The process of converting GeoJSON text into `MLNShape`, `MLNFeature`, or
`MLNShapeCollectionFeature` 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` | `MLNPointAnnotation`
`MultiPoint` | `MLNPointCollection`
`LineString` | `MLNPolyline`
`MultiLineString` | `MLNMultiPolyline`
`Polygon` | `MLNPolygon`
Linear ring | `MLNPolygon.coordinates`, `MLNPolygon.interiorPolygons`
`MultiPolygon` | `MLNMultiPolygon`
`GeometryCollection` | `MLNShapeCollection`
`Feature` | `MLNFeature`
`FeatureCollection` | `MLNShapeCollectionFeature`
A `Feature` object in GeoJSON corresponds to an instance of an `MLNShape`
subclass conforming to the `MLNFeature` protocol. There is a distinct
`MLNFeature`-conforming class for each type of geometry that a GeoJSON feature
can contain. This allows features to be used as raw shapes where convenient. For
example, some features can be added to a map view as annotations. Note that
identifiers and attributes will not be available for feature querying when a
feature is used as an annotation.
In contrast to the GeoJSON standard, it is possible for `MLNShape` subclasses
other than `MLNPointAnnotation` 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` | `Bool`
Integer | `NSNumber.unsignedLongLongValue`, `NSNumber.longLongValue` | `UInt64`, `Int64`
Floating-point number | `NSNumber.doubleValue` | `Double`
String | `NSString` | `String`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -1,88 +0,0 @@
/* Rouge Syntax Highlighting, Mapbox Base style
------------------------------------------------------- */
.highlight .hll { background-color:#ffffcc }
/* No Styling, Just Default:
.highlight .nx, Normal Text
.highlight .ni Name.Entity
.highlight .nf Name.Entity
.highlight .no Name.Constant
*/
/* Comments */
.highlight .o, /* Operator */
.highlight .c,
.highlight .c1,
.highlight .cp,
.highlight .cm { color:#999; font-style:italic; }
.highlight .err { color:#F00000; background-color:#F0A0A0 } /* Error */
.highlight .k { color:#404040; font-weight:bold; } /* Keyword */
.highlight .css .k { font-weight:normal; }
.highlight .cs { color:#404040; font-style:italic; } /* Comment.Special */
.highlight .gd { color:#A00000; } /* Generic.Deleted */
.highlight .ge { font-style:italic } /* Generic.Emph */
.highlight .gs { font-weight:bold; } /* Generic.Strong */
.highlight .gr { color:#FF0000; } /* Generic.Error */
.highlight .gh { color:#000080; } /* Generic.Heading */
.highlight .gi { color:#00A000; } /* Generic.Inserted */
.highlight .go { color:#808080; } /* Generic.Output */
.highlight .gp { color:#c65d09; } /* Generic.Prompt */
.highlight .gu { color:#800080; } /* Generic.Subheading */
.highlight .gt { color:#0040D0; } /* Generic.Traceback */
.highlight .kc { color:#D24400; } /* Keyword.Constant */
/* Keyword.Declaration
* Keyword.Namespace
* Keyword.Reserved */
.highlight .kd,
.highlight .kn,
.highlight .kr,
.highlight .nt { color:#0B5A91; } /* Name.Tag */
/* Literal.Number */
.highlight .mh,
.highlight .mo,
.highlight .il,
.highlight .mi,
.highlight .kt,
.highlight .mf,
.highlight .nl, /* Name.Label */
.highlight .na, /* Name.Attribute */
.highlight .m { color:#0C9DC2; } /* Keyword.Type */
.highlight .kp { color:#0080f0; } /* Keyword.Pseudo */
.highlight .nc { color:#DF6637; } /* Name.Class */
.highlight .css .nc { color:#75A21C; }
.highlight .nd { color:#505050; } /* Name.Decorator */
.highlight .ne { color:#F00000; } /* Name.Exception */
.highlight .nn { color:#0e84b5; } /* Name.Namespace */
.highlight .nf, /* Name.Function */
.highlight .nv { color:#003060; } /* Name.Variable */
.highlight .ow { color:#404040; } /* Operator.Word */
.highlight .w { color:#bbbbbb; } /* Text.Whitespace */
.highlight .sc { color:#8080F0; } /* Literal.String.Char */
.highlight .sd { color:#D04020; } /* Literal.String.Doc */
/* Name.Builtin / Name.Builtin.Pseudo */
.highlight .bp,
.highlight .nb { color:#007020; }
/* Literal.String */
.highlight .s,
.highlight .sh,
.highlight .sb,
.highlight .s1,
.highlight .sr,
.highlight .se { color:#75A21C; }
.highlight .si { background-color:#eee; } /* Literal.String.Interpol */
.highlight .p { color:#444444; } /* Normal Text */
.highlight .ss { color:#f0c080; } /* Literal.String.Symbol */
.highlight .vc { color:#c0c0f0; } /* Name.Variable.Class */
.highlight .vg { color:#f08040; } /* Name.Variable.Global */
.highlight .vi { color:#a0a0f0; } /* Name.Variable.Instance */

View File

@@ -1,804 +0,0 @@
// ===========================================================================
//
// Variables
//
// ===========================================================================
$body_background: #fff;
$body_font: 14px/25px 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
$text_color: #333;
$gray_border: 1px solid #ddd;
$quote_color: #858585;
$quote_border: 4px solid #e5e5e5;
$link_color: #3887BE;
$link_hover_color: #63b6e5;
$table_alt_row_color: #fbfbfb;
$table_border_color: #ddd;
$color_light: #F5F8FC;
$color_darkblue: #0B293A;
$color_brightblue: #3A68D8;
$color_darkblue_lighten: rgba(11, 41, 58, 0.75);
$keyline_color: rgba(12, 40, 73, 0.08);
$code_font: Menlo, Bitstream Vera Sans Mono, Monaco, Consolas, monospace;
$purple: #9595D1;
$blue: #4092C5;
// ----- Layout
$gutter: 16px;
$navigation_min_width: 175px;
$navigation_max_width: 300px;
// ----- Header
$header_weight: normal;
$header_color: #555;
$header_font: 'Open Sans Bold', 'Helvetica Neue', Helvetica, Arial, sans-serif;
$header_link_color: #fff;
$doc_coverage_color: #999;
// ----- Navigation
$navigation_max_width: 300px;
$navigation_bg_color: #fbfbfb;
$navigation_task_color: $link_color;
$section_name_color: $color_darkblue;
$navigation_gloss_color: #999;
// ----- Content
$declaration_title_language_color: #4183c4;
$declaration_language_border: 4px solid $color_brightblue;
$declaration_bg_color: #fdfeff;
$declaration_border_color: #ddd;
$aside_color: #aaa;
$aside_border: 4px solid lighten($aside_color, 20%);
$aside_warning_color: #ff0000;
$aside_warning_border: 4px solid lighten($aside_warning_color, 20%);
// ----- Footer
$footer_text_color: #888;
$footer_link_color: #555;
// ===========================================================================
//
// Base
//
// ===========================================================================
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
background: $body_background;
color: $color_darkblue;
font: $body_font;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
// ----- Block elements
@mixin heading($font-size: 1rem, $margin: 1.275em 0 0.85em) {
font-family: $header_font;
font-size: $font-size;
font-weight: $header_weight;
color: $color_darkblue;
margin: $margin;
}
h1 {
@include heading(1.7rem, 0.5em 0 0.6em);
}
h1 a {
color: $color_darkblue;
}
h2 {
@include heading(1.5rem, 1em 0 0.6em);
}
h3 {
@include heading(1.2rem, 1em 0 0.3em);
}
h3 > code {
font-weight: bold;
font-size: 1.2rem;
}
h4 {
@include heading(1rem);
}
h5, h6 {
@include heading;
}
p {
margin: 0 0 1em;
}
ul, ol {
padding: 0 0 0 1.5em;
margin: 0 0 0.85em;
}
ul.item-container {
padding: 0px;
}
ul:first-of-type,
ol:first-of-type {
margin: 0px;
}
blockquote {
margin: 0 0 0.85em;
padding: 0 15px;
color: $quote_color;
border-left: $quote_border;
}
// ----- Inline elements
img {
max-width: 100%;
}
a {
color: $link_color;
text-decoration: none;
> *:hover, &:hover, &:focus {
opacity: 0.7;
}
&:focus {
box-shadow:inset 0 0 0 1px rgba(0,0,0,0.05);
}
}
// ----- Tables
table {
background: $body_background;
width: 100%;
font-size: 13px;
line-height: 23px;
border-collapse: collapse;
border-spacing: 0;
overflow: auto;
margin: 0 0 0.85em;
}
th, td {
padding: 6px 13px;
border: 1px solid $keyline_color;
}
// ----- Code
pre {
margin: 0 0 1.275em;
padding: .85em 1em;
overflow: auto;
background: $color_light;
font-family: $code_font;
border-radius: 4px;
}
code {
font-family: $code_font;
font-size: 13px;
line-height: .85em;
}
p, li {
> code {
background: $color_light;
padding: 0.1em 0.2em;
font-weight: bold;
border: 1px solid #D5D5D5;
border-radius: 4px;
}
}
td > code,
.graybox code {
font-weight: bold;
font-size: 12px;
}
pre code {
padding: 0;
white-space: pre;
}
// ===========================================================================
//
// Layout
//
// ===========================================================================
.content-wrapper {
display: flex;
flex-direction: column;
@media (min-width: 768px) {
flex-direction: row;
}
}
.limiter {
max-width: 1360px;
margin: auto;
padding: 0px 30px;
}
.space-right2 {
margin-right: 20px;
}
// ===========================================================================
//
// Header
//
// ===========================================================================
.header-container {
background: $color_brightblue;
}
.header {
display: flex;
padding: 12px 0px;
font-size: 12px;
color: $doc_coverage_color;
@media (max-width: 768px) {
display: block;
}
}
.header-tag {
vertical-align: text-top;
line-height: 10px;
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
padding: 2px 5px;
margin-left: 5px;
opacity: 0.9;
}
.header-col {
margin: 5px 0 0 0;
padding: 0
}
.header-col--primary {
flex: 1;
}
.header-link {
font-family: $header_font;
color: $header_link_color;
}
.header-image, .header-icon {
padding-right: 2px;
vertical-align: -4px;
height: 16px;
}
// ===========================================================================
//
// Breadcrumbs
//
// ===========================================================================
.breadcrumbs {
font-size: 13px;
padding: $gutter / 2 0px;
margin: 0;
background: $color_light;
border-bottom: 1px solid $keyline_color;
}
.carat {
height: 10px;
margin: 0 5px;
}
// ===========================================================================
//
// Navigation
//
// ===========================================================================
.navigation {
order: 2;
font-size: 13px;
padding-top: 20px;
@media (min-width: 768px) {
order: 1;
width: 25%;
min-width: $navigation_min_width;
max-width: $navigation_max_width;
padding-bottom: $gutter*4;
line-height: 20px;
overflow: hidden;
border-right: 1px solid $keyline_color;
}
}
.nav-groups {
list-style-type: none;
padding-left: 0;
}
.nav-group-name {
padding: $gutter/2 0 $gutter/2 0px;
}
.small-heading, h4 {
font-size: 13px;
font-family: $header_font;
text-transform: uppercase;
color: $color_darkblue;
letter-spacing: 1px;
}
.nav-group-tasks {
margin: $gutter/2 0;
padding: 0 0 0 0;
}
.nav-group-task {
font-size: 1em;
list-style-type: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: $navigation_task_color;
}
%nav-group-task-gloss {
color: $navigation_gloss_color;
font-size: 90%;
margin-left: 0.5em;
}
.nav-group-task[data-url^="Protocols/"] > .nav-group-task-link::after {
@extend %nav-group-task-gloss;
content: "(Protocol)";
}
.nav-group-task[data-name="MLNForegroundStyleLayer"],
.nav-group-task[data-name="MLNMultiPoint"],
.nav-group-task[data-name="MLNShape"],
.nav-group-task[data-name="MLNSource"],
.nav-group-task[data-name="MLNStyleFunction"],
.nav-group-task[data-name="MLNStyleLayer"],
.nav-group-task[data-name="MLNTileSource"],
.nav-group-task[data-name="MLNVectorStyleLayer"] {
.nav-group-task-link::after {
@extend %nav-group-task-gloss;
content: "(Abstract Class)";
}
}
.nav-group-name > .small-heading,
.nav-group-task-link {
display: block;
}
.nav-group-task-link {
color: $color_darkblue_lighten;
}
// ===========================================================================
//
// Content
//
// ===========================================================================
.main-content {
order: 1;
@media (min-width: 768px) {
order: 2;
flex: 1;
padding-bottom: 60px;
max-width: 80%;
}
}
.section {
padding: 0px 20px;
@media (max-width: 768px) {
padding: inherit;
}
}
.section-content {
margin: 0 auto;
padding: $gutter 0;
border-bottom: 1px solid $keyline_color;
}
.section-content img {
margin: 0 auto;
}
.section-name {
color: $section_name_color;
display: block;
}
.anchor-icon {
margin-left: 4px;
opacity: 0.7;
display: inline-block;
background: url("../img/link.svg");
background-repeat: no-repeat;
width: 10px;
height: 10px;
}
h1 > .anchor-icon { margin-bottom: 2px; }
.declaration .highlight {
font-size: 15px;
overflow-x: initial; // This allows the scrollbar to show up inside declarations
padding: $gutter/2 0;
line-height: 20px;
margin: 0;
background-color: transparent;
border: none;
}
.highlight a { text-decoration: underline; }
.task-group-section {
border-top: $gray_border;
}
.task-group {
padding-top: 0px;
}
.task-name-container {
a[name] {
&:before {
content: "";
display: block;
}
}
}
.item {
width: 100%;
list-style-type: none;
a[name] {
&:before {
content: "";
display: block;
}
}
.token {
margin-left: 0px;
font-size: 13px;
display: flex;
padding: 5px 0px;
line-height: 14px;
}
.token-name {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.token-icon {
background: url('../img/plus.svg');
width: 17px;
display: inline-block;
vertical-align: middle;
height: 13px;
opacity: 1;
margin-left: 5px;
background-repeat: no-repeat;
}
.token-icon-minus {
background: url('../img/minus.svg');
background-repeat: no-repeat;
}
.discouraged {
text-decoration: line-through;
}
.declaration-note {
font-size: 13px;
color: #808080;
font-style: italic;
}
}
.pointer-container {
border-bottom: $gray_border;
left: -23px;
padding-bottom: 13px;
position: relative;
width: 110%;
}
.pointer {
left: 21px;
top: 7px;
display: block;
position: absolute;
width: 12px;
height: 12px;
border-left: 1px solid $declaration_border_color;
border-top: 1px solid $declaration_border_color;
background: $declaration_bg_color;
transform: rotate(45deg);
}
.height-container {
display: none;
position: relative;
width: 100%;
overflow: hidden;
.section {
background: $declaration_bg_color;
border: 1px solid $keyline_color;
padding: 15px 20px;
border-radius: 4px;
margin: 10px 0px 30px;
}
}
.aside, .language {
padding: 6px 12px;
margin: 12px 0;
border-left: $aside_border;
border-radius: 4px;
overflow-y: hidden;
.aside-title {
font-size: 10px;
font-family: $header_font;
letter-spacing: 2px;
text-transform: uppercase;
padding: 2px 8px;
display: inline;
margin: 0;
-webkit-user-select: none;
}
p:last-child {
margin-bottom: 0;
}
}
.language {
background: $color_light;
border-left: $declaration_language_border;
}
.aside.aside-see, .aside.aside-note, {
background: $color_light;
.aside-title {
padding-left: 0px;
}
}
.aside-warning, .aside-deprecated, .aside-unavailable {
border-left: $aside_warning_border;
.aside-title {
color: $aside_warning_color;
}
}
.graybox {
width: 100%;
border-collapse:separate;
border:solid $keyline_color 1px;
border-radius:6px;
-moz-border-radius:6px;
p {
margin: 0;
word-break: break-word;
min-width: 50px;
}
td {
padding: 5px 25px 5px 10px;
vertical-align: middle;
}
tr td:first-of-type {
text-align: right;
padding: 7px;
vertical-align: top;
word-break: normal;
width: 40px;
border-left: none;
border-top: none;
}
th, td {
border-right:none;
border-top: none;
}
td:first-child, th:first-child {
border-left: none;
}
tr:last-of-type td {
border-bottom: none;
}
}
.show-on-github-icon {
width: 16px;
display: inline-block !important;
vertical-align: -3px;
padding-left: 2px;
}
.show-on-github a {
margin: 10px 0 10px;
display: inline-block;
font-size: 13px;
}
// ===========================================================================
//
// Search
//
// ===========================================================================
form[role=search] {
input {
font: $body_font;
font-size: 14px;
line-height: 24px;
padding: 0px 15px;
height: 36px;
margin: 0;
border: 1px solid $keyline_color;
background: $color_light;
outline: none;
margin-bottom: 10px;
border-radius: 18px;
.loading & {
background: white url(../img/spinner.gif) center right 4px no-repeat;
}
}
input:focus {
border: 1px solid $color_brightblue;
background: #fff;
}
// Typeahead elements
.twitter-typeahead {
width: 100%;
}
.tt-menu {
margin: 0;
background: $navigation_bg_color;
color: $text_color;
border: 1px solid $keyline_color;
}
.tt-highlight {
font-weight: bold;
}
.tt-suggestion {
font: $body_font;
padding: 0 $gutter/2;
span {
display: table-cell;
white-space: nowrap;
}
.doc-parent-name {
width: 100%;
text-align: right;
font-weight: normal;
font-size: 0.9em;
padding-left: $gutter;
}
}
.tt-suggestion:hover,
.tt-suggestion.tt-cursor {
cursor: pointer;
background-color: $link_color;
color: #fff;
}
.tt-suggestion:hover .doc-parent-name,
.tt-suggestion.tt-cursor .doc-parent-name {
color: #fff;
}
}
// ===========================================================================
//
// Footer
//
// ===========================================================================
.footer {
border-top: 1px $keyline_color solid;
padding: $gutter/2 $gutter;
color: $footer_text_color;
p {
display: inline;
}
a {
color: $footer_link_color;
}
}
// ===========================================================================
//
// Dash
//
// ===========================================================================
html.dash {
.header, .breadcrumbs, .navigation {
display: none;
}
.height-container {
display: block;
}
}
// ===========================================================================
//
// Fonts
//
// ===========================================================================
@font-face {
font-family:'Open Sans';
src:url('../fonts/opensans-regular.eot');
src:url('../fonts/opensans-regular.eot#iefix') format('embedded-opentype'),
url('../fonts/opensans-regular.woff') format('woff');
}
@font-face {
font-family:'Open Sans Bold';
src:url('../fonts/opensans-bold.eot');
src:url('../fonts/opensans-bold.eot#iefix') format('embedded-opentype'),
url('../fonts/opensans-bold.woff') format('woff');
}
.strong { font-family: $header_font;}
.text-purple { color: $purple; }
.text-blue { color: $blue; }
.keyline-purple { border-color: $purple; }
.keyline-blue { border-color: $blue; }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg viewBox="0 0 33 33" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path stroke="none" fill="#3887BE" fill-rule="evenodd" d="M16.6,0.4 C7.6,0.4 0.3,7.7 0.3,16.7 C0.3,23.9 5,30 11.4,32.2 C12.2,32.3 12.5,31.8 12.5,31.4 L12.5,28.6 C8,29.6 7,26.4 7,26.4 C6.3,24.5 5.2,24 5.2,24 C3.7,23 5.3,23 5.3,23 C6.9,23.1 7.8,24.7 7.8,24.7 C9.3,27.2 11.6,26.5 12.5,26.1 C12.6,25 13.1,24.3 13.5,23.9 C9.9,23.5 6.1,22.1 6.1,15.8 C6.1,14 6.7,12.6 7.8,11.4 C7.6,11 7.1,9.3 8,7.1 C8,7.1 9.4,6.7 12.5,8.8 C13.8,8.4 15.2,8.3 16.6,8.3 C18,8.3 19.4,8.5 20.7,8.8 C23.8,6.7 25.2,7.1 25.2,7.1 C26.1,9.3 25.5,11 25.4,11.4 C26.4,12.5 27.1,14 27.1,15.8 C27.1,22.1 23.3,23.4 19.7,23.8 C20.3,24.3 20.8,25.3 20.8,26.8 L20.8,31.3 C20.8,31.7 21.1,32.2 21.9,32.1 C28.4,29.9 33,23.8 33,16.6 C32.9,7.7 25.6,0.4 16.6,0.4 L16.6,0.4 Z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 919 B

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="10px" height="10px" viewBox="0 0 10 10" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41.2 (35397) - http://www.bohemiancoding.com/sketch -->
<title>Page 1 Copy</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.461229011">
<g id="Desktop-Copy" transform="translate(-251.000000, -309.000000)" fill="#071B32">
<path d="M255.260269,316.616571 L254.592518,317.284675 C254.075101,317.80176 253.233025,317.80176 252.715608,317.284675 C252.19819,316.766905 252.19819,315.925161 252.715608,315.407433 L254.592518,313.530854 C255.110267,313.013105 255.951679,313.013105 256.469097,313.530854 C256.630773,313.69253 256.736069,313.887591 256.796969,314.093309 C256.846216,314.064798 256.896791,314.04147 256.938262,313.999999 L257.810446,313.128146 C257.698992,312.93827 257.5707,312.755526 257.407407,312.592565 C256.371266,311.556133 254.69039,311.556133 253.653918,312.592565 L251.777339,314.469143 C250.740887,315.505927 250.740887,317.18618 251.777339,318.222964 C252.813791,319.259084 254.494355,319.259084 255.530828,318.222964 L256.953171,316.800601 C256.384848,316.884186 255.801346,316.827163 255.260269,316.616571 M260.222897,313.530854 L258.345675,315.407412 C257.309534,316.444196 255.628659,316.444196 254.592518,315.407412 C254.429225,315.244782 254.301576,315.061375 254.189458,314.872162 L255.061663,313.999978 C255.103134,313.958154 255.15433,313.934204 255.203246,313.906004 C255.263504,314.112096 255.3688,314.307115 255.530807,314.469123 C256.048225,314.986851 256.89028,314.986208 257.407386,314.469123 L259.283965,312.592544 C259.801714,312.074774 259.801714,311.233051 259.283965,310.715613 C258.766838,310.198195 257.925135,310.198195 257.407386,310.715613 L256.739925,311.383716 C256.198558,311.172772 255.615036,311.116081 255.047065,311.199355 L256.469076,309.777323 C257.50586,308.740892 259.186092,308.740892 260.222876,309.777323 C261.259038,310.813817 261.259038,312.494402 260.222897,313.530854" id="Page-1-Copy"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,42 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="new" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 800 180" style="enable-background:new 0 0 800 180;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>Mapbox_Logo_08</title>
<g>
<g>
<path class="st0" d="M594.6,49.8c-9.9,0-19.4,4.1-26.3,11.3V23c0-1.2-1-2.2-2.2-2.2l0,0h-13.4c-1.2,0-2.2,1-2.2,2.2v103
c0,1.2,1,2.2,2.2,2.2h13.4c1.2,0,2.2-1,2.2-2.2v0v-7.1c6.9,7.2,16.3,11.3,26.3,11.3c20.9,0,37.8-18,37.8-40.2
S615.5,49.8,594.6,49.8z M591.5,114.1c-12.7,0-23-10.6-23.1-23.8v-0.6c0.2-13.2,10.4-23.8,23.1-23.8c12.8,0,23.1,10.8,23.1,24.1
S604.2,114.1,591.5,114.1L591.5,114.1z"/>
<path class="st0" d="M681.7,49.8c-22.6,0-40.9,18-40.9,40.2s18.3,40.2,40.9,40.2c22.6,0,40.9-18,40.9-40.2S704.3,49.8,681.7,49.8z
M681.6,114.1c-12.8,0-23.1-10.8-23.1-24.1s10.4-24.1,23.1-24.1s23.1,10.8,23.1,24.1S694.3,114.1,681.6,114.1L681.6,114.1z"/>
<path class="st0" d="M431.6,51.8h-13.4c-1.2,0-2.2,1-2.2,2.2c0,0,0,0,0,0v7.1c-6.9-7.2-16.3-11.3-26.3-11.3
c-20.9,0-37.8,18-37.8,40.2s16.9,40.2,37.8,40.2c9.9,0,19.4-4.1,26.3-11.3v7.1c0,1.2,1,2.2,2.2,2.2l0,0h13.4c1.2,0,2.2-1,2.2-2.2
v0V54C433.8,52.8,432.8,51.8,431.6,51.8z M392.8,114.1c-12.8,0-23.1-10.8-23.1-24.1s10.4-24.1,23.1-24.1c12.7,0,23,10.6,23.1,23.8
v0.6C415.8,103.5,405.5,114.1,392.8,114.1L392.8,114.1z"/>
<path class="st0" d="M498.5,49.8c-9.9,0-19.4,4.1-26.3,11.3V54c0-1.2-1-2.2-2.2-2.2l0,0h-13.4c-1.2,0-2.2,1-2.2,2.2c0,0,0,0,0,0
v103c0,1.2,1,2.2,2.2,2.2l0,0h13.4c1.2,0,2.2-1,2.2-2.2v0v-38.1c6.9,7.2,16.3,11.3,26.3,11.3c20.9,0,37.8-18,37.8-40.2
S519.4,49.8,498.5,49.8z M495.4,114.1c-12.7,0-23-10.6-23.1-23.8v-0.6c0.2-13.2,10.4-23.8,23.1-23.8c12.8,0,23.1,10.8,23.1,24.1
S508.2,114.1,495.4,114.1L495.4,114.1z"/>
<path class="st0" d="M311.8,49.8c-10,0.1-19.1,5.9-23.4,15c-4.9-9.3-14.7-15.1-25.2-15c-8.2,0-15.9,4-20.7,10.6V54
c0-1.2-1-2.2-2.2-2.2l0,0h-13.4c-1.2,0-2.2,1-2.2,2.2c0,0,0,0,0,0v72c0,1.2,1,2.2,2.2,2.2h0h13.4c1.2,0,2.2-1,2.2-2.2v0V82.9
c0.5-9.6,7.2-17.3,15.4-17.3c8.5,0,15.6,7.1,15.6,16.4v44c0,1.2,1,2.2,2.2,2.2l13.5,0c1.2,0,2.2-1,2.2-2.2c0,0,0,0,0,0l-0.1-44.8
c1.2-8.8,7.5-15.6,15.2-15.6c8.5,0,15.6,7.1,15.6,16.4v44c0,1.2,1,2.2,2.2,2.2l13.5,0c1.2,0,2.2-1,2.2-2.2c0,0,0,0,0,0l-0.1-49.5
C339.9,61.7,327.3,49.8,311.8,49.8z"/>
<path class="st0" d="M794.7,125.1l-23.2-35.3l23-35c0.6-0.9,0.3-2.2-0.6-2.8c-0.3-0.2-0.7-0.3-1.1-0.3h-15.5
c-1.2,0-2.3,0.6-2.9,1.6L760.9,76l-13.5-22.6c-0.6-1-1.7-1.6-2.9-1.6h-15.5c-1.1,0-2,0.9-2,2c0,0.4,0.1,0.8,0.3,1.1l23,35
l-23.2,35.3c-0.6,0.9-0.3,2.2,0.6,2.8c0.3,0.2,0.7,0.3,1.1,0.3h15.5c1.2,0,2.3-0.6,2.9-1.6l13.8-23l13.8,23c0.6,1,1.7,1.6,2.9,1.6
H793c1.1,0,2-0.9,2-2C795,125.9,794.9,125.5,794.7,125.1z"/>
</g>
<g>
<path class="st0" d="M93.9,1.1C44.8,1.1,5,40.9,5,90s39.8,88.9,88.9,88.9s88.9-39.8,88.9-88.9C182.8,40.9,143,1.1,93.9,1.1z
M136.1,111.8c-30.4,30.4-84.7,20.7-84.7,20.7s-9.8-54.2,20.7-84.7C89,30.9,117,31.6,134.7,49.2S153,94.9,136.1,111.8L136.1,111.8
z"/>
<polygon class="st0" points="104.1,53.2 95.4,71.1 77.5,79.8 95.4,88.5 104.1,106.4 112.8,88.5 130.7,79.8 112.8,71.1 "/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.68516791">
<g id="Desktop-Copy" transform="translate(-633.000000, -419.000000)" fill="#3887BE">
<g id="Page-1" transform="translate(633.000000, 419.000000)">
<path d="M6.49003164,12.5026484 C9.77303945,12.5107734 12.477852,9.82012891 12.5025824,6.52148047 C12.5272621,3.23964063 9.80929727,0.507914063 6.50892227,0.497351563 C3.22951992,0.486890625 0.516836328,3.18535547 0.497336328,6.47735156 C0.477836328,9.76472656 3.19280508,12.4944727 6.49003164,12.5026484 M-1.5234375e-05,6.49233203 C8.6328125e-05,2.89442969 2.92752383,-0.00116796875 6.56371523,2.52575739e-14 C10.1085004,0.0011171875 13.0018637,2.95516406 12.9999848,6.57124609 C12.9981566,10.111918 10.0405551,13.0024883 6.42218789,13 C2.91340664,12.9976133 -0.000116796875,10.045293 -1.5234375e-05,6.49233203" id="Fill-1"></path>
<path d="M6.50034531,6.75380469 C5.4769,6.75380469 4.45345469,6.75385547 3.43000938,6.75370312 C3.37084922,6.75365234 3.2953375,6.77437109 3.25577891,6.74593359 C3.16254453,6.67885156 3.08637266,6.58795312 3.00329453,6.50665234 C3.09033359,6.42057812 3.17204063,6.32769922 3.26750938,6.2521875 C3.29904453,6.22720312 3.36592344,6.24624609 3.41665391,6.24624609 C5.47197422,6.24614453 7.52734531,6.24614453 9.58261484,6.24624609 C9.63334531,6.24624609 9.70017344,6.22720312 9.73186094,6.25213672 C9.82748203,6.32744531 9.90944297,6.42012109 9.99673594,6.50604297 C9.90543125,6.58810547 9.81905234,6.67697266 9.72013047,6.74852344 C9.68656406,6.77274609 9.62136094,6.75375391 9.57063047,6.75375391 C8.54723594,6.75380469 7.52373984,6.75380469 6.50034531,6.75380469" id="Fill-4"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Desktop-Copy" transform="translate(-664.000000, -384.000000)" fill="#3887BE">
<g id="Page-1-Copy-2" transform="translate(664.000000, 384.000000)">
<path d="M6.50560625,12.5026484 C9.79216875,12.4978242 12.4953055,9.79478906 12.502618,6.50583984 C12.5098797,3.21653516 9.78231719,0.489378906 6.49331719,0.497402344 C3.20421563,0.505425781 0.503719531,3.20576953 0.497321094,6.49294141 C0.490973438,9.78478516 3.21295,12.5074219 6.50560625,12.5026484 M2.03125001e-05,6.49563281 C7.10937501e-05,2.89549609 2.92552813,-0.00106640625 6.56045,2.10942375e-14 C10.1069109,0.001015625 13.0016961,2.95353906 13.0000203,6.56799609 C12.9982938,10.1104453 10.0425203,13.0021836 6.42547344,13 C2.91501641,12.9978672 -3.04687499e-05,10.0470195 2.03125001e-05,6.49563281" id="Fill-1"></path>
<path d="M6.75167695,6.75167187 L6.75167695,8.89296484 C6.75167695,9.13833984 6.74700508,9.38386719 6.75320039,9.62908984 C6.75797383,9.81850391 6.71440352,9.99253125 6.49934492,9.992125 C6.28459102,9.99161719 6.24574336,9.81753906 6.24655586,9.62817578 C6.25046602,8.68151172 6.2483332,7.73484766 6.2483332,6.75167187 L5.96527852,6.75167187 C5.14450117,6.75167187 4.32367305,6.75030078 3.5028957,6.75273828 C3.31896602,6.75329687 3.14113008,6.73039453 3.13772773,6.5040625 C3.13432539,6.27828906 3.30662617,6.2465 3.49405977,6.24700781 C4.39877852,6.24980078 5.30354805,6.24832812 6.2483332,6.24832812 L6.2483332,5.96999609 C6.2483332,5.19151953 6.25061836,4.41304297 6.24665742,3.63456641 C6.24569258,3.44982422 6.26976289,3.26711328 6.4872082,3.25975 C6.72288398,3.25172656 6.75416523,3.43834766 6.75320039,3.63456641 C6.74949336,4.4045625 6.75167695,5.17455859 6.75167695,5.94455469 L6.75167695,6.24832812 L7.06900898,6.24832812 C7.88130586,6.24832812 8.69365352,6.24980078 9.50595039,6.24716016 C9.69302852,6.24660156 9.86598945,6.27925391 9.86213008,6.50482422 C9.85821992,6.73080078 9.68002852,6.75339844 9.49609883,6.75278906 C8.68380195,6.75025 7.87150508,6.75167187 7.0592082,6.75167187 L6.75167695,6.75167187 Z" id="Fill-4"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,42 +0,0 @@
window.jazzy = {'docset': false}
if (typeof window.dash != 'undefined') {
document.documentElement.className += ' dash'
window.jazzy.docset = true
}
if (navigator.userAgent.match(/xcode/i)) {
document.documentElement.className += ' xcode'
window.jazzy.docset = true
}
// On doc load, toggle the URL hash discussion if present
$(document).ready(function() {
if (!window.jazzy.docset) {
var linkToHash = $('a[href="' + window.location.hash +'"]');
linkToHash.trigger("click");
}
});
// On token click, toggle its discussion and animate token.marginLeft
$(".token").click(function(event) {
if (window.jazzy.docset) {
return;
}
var link = $(this);
var linkIcon = link.find('.token-icon');
var animationDuration = 300;
var tokenOffset = "0px";
var original = link.css('marginLeft') == tokenOffset;
linkIcon.toggleClass('token-icon-minus');
link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration);
$content = link.parent().parent().next();
$content.slideToggle(animationDuration);
// Keeps the document from jumping to the hash.
var href = $(this).attr('href');
if (history.pushState) {
history.pushState({}, '', href);
} else {
location.hash = href;
}
event.preventDefault();
});

View File

@@ -1,70 +0,0 @@
$(function(){
var $typeahead = $('[data-typeahead]');
var $form = $typeahead.parents('form');
var searchURL = $form.attr('action');
function displayTemplate(result) {
return result.name;
}
function suggestionTemplate(result) {
var t = '<div class="list-group-item clearfix">';
t += '<span class="doc-name">' + result.name + '</span>';
if (result.parent_name) {
t += '<span class="doc-parent-name label">' + result.parent_name + '</span>';
}
t += '</div>';
return t;
}
$typeahead.one('focus', function() {
$form.addClass('loading');
$.getJSON(searchURL).then(function(searchData) {
const searchIndex = lunr(function() {
this.ref('url');
this.field('name');
this.field('abstract');
for (const [url, doc] of Object.entries(searchData)) {
this.add({url: url, name: doc.name, abstract: doc.abstract});
}
});
$typeahead.typeahead(
{
highlight: true,
minLength: 3,
autoselect: true
},
{
limit: 10,
display: displayTemplate,
templates: { suggestion: suggestionTemplate },
source: function(query, sync) {
const lcSearch = query.toLowerCase();
const results = searchIndex.query(function(q) {
q.term(lcSearch, { boost: 100 });
q.term(lcSearch, {
boost: 10,
wildcard: lunr.Query.wildcard.TRAILING
});
}).map(function(result) {
var doc = searchData[result.ref];
doc.url = result.ref;
return doc;
});
sync(results);
}
}
);
$form.removeClass('loading');
$typeahead.trigger('focus');
});
});
var baseURL = searchURL.slice(0, -"search.json".length);
$typeahead.on('typeahead:select', function(e, result) {
window.location = baseURL + result.url;
});
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +0,0 @@
{{#deprecation_message}}
<div class="aside aside-deprecated">
<p class="aside-title">Deprecated</p>
{{{deprecation_message}}}
</div>
{{/deprecation_message}}
{{#unavailable_message}}
<div class="aside aside-unavailable">
<p class="aside-title">Unavailable</p>
{{{unavailable_message}}}
</div>
{{/unavailable_message}}

View File

@@ -1,72 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{name}} {{kind}} Reference</title>
<link rel="stylesheet" type="text/css" href="{{path_to_root}}css/jazzy.css" />
<link rel="stylesheet" type="text/css" href="{{path_to_root}}css/highlight.css" />
<meta charset="utf-8">
<script src="{{path_to_root}}js/jquery.min.js" defer></script>
<script src="{{path_to_root}}js/jazzy.js" defer></script>
{{{custom_head}}}
{{^disable_search}}
<script src="{{path_to_root}}js/lunr.min.js" defer></script>
<script src="{{path_to_root}}js/typeahead.jquery.js" defer></script>
<script src="{{path_to_root}}js/jazzy.search.js" defer></script>
<meta class="swiftype" name="type" data-type="enum" content="{{module_name}} Reference" />
<meta class="swiftype" name="title" data-type="string" content="{{name}}" />
{{/disable_search}}
<style type="text/css">
.nav-group-name[data-name="{{name}}"] > .small-heading,
.nav-group-task[data-name="{{name}}"] {
background-color: #f5f8fc;
font-family: "Open Sans Bold";
border-left: 3px solid #3a68d8;
padding-left: 5px
}
</style>
</head>
<body>
{{#dash_type}}
<a name="//apple_ref/{{language_stub}}/{{dash_type}}/{{name}}" class="dashAnchor"></a>
{{/dash_type}}
<a title="{{name}} {{kind}} Reference"></a>
{{> header}}
<div class="breadcrumbs">
<div class="limiter">
<a class="breadcrumb" href="{{path_to_root}}index.html">{{module_name}} Reference</a>
<img class="carat" src="{{path_to_root}}img/carat.png" />
{{name}} {{kind}} Reference
</div>
</div>
<div class="content-wrapper limiter">
{{> nav}}
<article class="main-content">
<section class="section">
<div class="section-content">
{{^hide_name}}<a href="#/{{name}}"><h1 id="{{name}}">{{name}}<span class="anchor-icon" /></h1></a>{{/hide_name}}
{{> deprecation}}
{{#declaration}}
<div class="declaration">
<div class="language">
{{{declaration}}}
</div>
</div>
{{/declaration}}
{{{overview}}}
</div>
</section>
{{> tasks}}
</article>
</div>
{{> footer}}
</body>
</div>
</html>

View File

@@ -1,3 +0,0 @@
<section class="footer limiter">
{{{copyright}}} Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external">jazzy ♪♫ v{{jazzy_version}}</a>, a <a class="link" href="http://realm.io" target="_blank" rel="external">Realm</a> project.
</section>

View File

@@ -1,33 +0,0 @@
<header class="header-container">
<div class="limiter">
<div class="header">
<p class="header-col header-col--primary">
<a class="header-link" href="{{path_to_root}}index.html">
<img style="height: 25px;" class="header-icon" src="https://maplibre.org/img/maplibre-logo.svg" alt="{{module_name}} Docs"/>
<span class='header-tag'>{{docs_title}} Reference ({{module_version}})</span>
</a>
{{#doc_coverage}} ({{doc_coverage}}% documented){{/doc_coverage}}
</p>
{{#github_url}}
<p class="header-col header-col--secondary">
<a class="header-link space-right2" href="{{github_url}}">
<svg style="margin-bottom: 1px;" class="header-icon" viewBox="0 0 33 33" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path stroke="none" stroke-width="1" fill="white" fill-rule="evenodd" d="M16.6,0.4 C7.6,0.4 0.3,7.7 0.3,16.7 C0.3,23.9 5,30 11.4,32.2 C12.2,32.3 12.5,31.8 12.5,31.4 L12.5,28.6 C8,29.6 7,26.4 7,26.4 C6.3,24.5 5.2,24 5.2,24 C3.7,23 5.3,23 5.3,23 C6.9,23.1 7.8,24.7 7.8,24.7 C9.3,27.2 11.6,26.5 12.5,26.1 C12.6,25 13.1,24.3 13.5,23.9 C9.9,23.5 6.1,22.1 6.1,15.8 C6.1,14 6.7,12.6 7.8,11.4 C7.6,11 7.1,9.3 8,7.1 C8,7.1 9.4,6.7 12.5,8.8 C13.8,8.4 15.2,8.3 16.6,8.3 C18,8.3 19.4,8.5 20.7,8.8 C23.8,6.7 25.2,7.1 25.2,7.1 C26.1,9.3 25.5,11 25.4,11.4 C26.4,12.5 27.1,14 27.1,15.8 C27.1,22.1 23.3,23.4 19.7,23.8 C20.3,24.3 20.8,25.3 20.8,26.8 L20.8,31.3 C20.8,31.7 21.1,32.2 21.9,32.1 C28.4,29.9 33,23.8 33,16.6 C32.9,7.7 25.6,0.4 16.6,0.4 L16.6,0.4 Z"></path>
</svg>
View on GitHub
</a>
</p>
{{/github_url}}
{{#dash_url}}
<p class="header-col header-col--secondary">
<a class="header-link bold" href="{{dash_url}}">
<img style="margin-bottom: 1px;" class="header-icon" src="{{path_to_root}}img/dash.png"/>
Install in Dash
</a>
</p>
{{/dash_url}}
</div>
</div>
</header>

View File

@@ -1,23 +0,0 @@
<nav class="navigation">
{{^disable_search}}
<div class="header-col--secondary">
<form role="search" action="{{path_to_root}}search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
</form>
</div>
{{/disable_search}}
<ul class="nav-groups">
{{#structure}}
<li class="nav-group-name" data-name="{{section}}">
<a class="small-heading" href="{{path_to_root}}{{section}}.html">{{section}}<span class="anchor-icon" /></a>
<ul class="nav-group-tasks">
{{#children}}
<li class="nav-group-task" data-name="{{name}}" data-url="{{url}}">
<a title="{{name}}" class="nav-group-task-link" href="{{path_to_root}}{{url}}">{{name}}</a>
</li>
{{/children}}
</ul>
</li>
{{/structure}}
</ul>
</nav>

View File

@@ -1,12 +0,0 @@
<tr>
<td>
<code>
{{name}}
</code>
</td>
<td>
<div>
{{{discussion}}}
</div>
</td>
</tr>

View File

@@ -1,94 +0,0 @@
<div class="task-group">
{{#name}}
<div class="task-name-container">
<a name="/{{uid}}"></a>
<a name="//apple_ref/{{language_stub}}/Section/{{name}}" class="dashAnchor"></a>
<a href="#/{{uid}}">
<h3 id="{{uid}}" class="section-name">{{name}}<span class="anchor-icon" /></h3>
</a>
</div>
{{/name}}
<ul class="item-container">
{{#items}}
<li class="item">
<div>
<code>
<a name="/{{usr}}"></a>
<a name="//apple_ref/{{language_stub}}/{{dash_type}}/{{name}}" class="dashAnchor"></a>
<a class="token{{#usage_discouraged}} discouraged{{/usage_discouraged}}" href="#/{{usr}}"><span class="token-name">{{name}}</span><span class="token-icon" /></a>
</code>
{{#default_impl_abstract}}
<span class="declaration-note">
Default implementation
</span>
{{/default_impl_abstract}}
{{#from_protocol_extension}}
<span class="declaration-note">
Extension method
</span>
{{/from_protocol_extension}}
</div>
<div class="height-container">
<section class="section">
{{> deprecation}}
{{#abstract}}
<div class="abstract">
{{{abstract}}}
{{#url}}
<a href="{{{path_to_root}}}{{{url}}}" class="slightly-smaller">See more</a>
{{/url}}
</div>
{{/abstract}}
{{#default_impl_abstract}}
<h4>Default Implementation</h4>
<div class="default_impl abstract">
{{{default_impl_abstract}}}
</div>
{{/default_impl_abstract}}
{{#declaration}}
<div class="declaration">
<h4>Declaration</h4>
<div class="language keyline-blue">
<p style="background: rgba(65, 131, 196, 0.15);" class="aside-title text-blue">{{language}}</p>
{{{declaration}}}
</div>
{{#other_language_declaration}}
<div class="language keyline-purple">
<p style="background: rgba(149, 149, 209, 0.21);" class="aside-title text-purple">Swift</p>
{{{other_language_declaration}}}
</div>
{{/other_language_declaration}}
</div>
{{/declaration}}
{{#parameters.count}}
<div>
<h4>Parameters</h4>
<table class="graybox">
<tbody>
{{#parameters}}
{{> parameter}}
{{/parameters}}
</tbody>
</table>
</div>
{{/parameters.count}}
{{#return}}
<div>
<h4>Return Value</h4>
{{{return}}}
</div>
{{/return}}
{{#github_token_url}}
<div class="show-on-github">
<a href="{{{github_token_url}}}">
<img style="margin-bottom: 1px;" class="show-on-github-icon" src="{{{path_to_root}}}img/github.svg"/>
View Source on GitHub
</a>
</div>
{{/github_token_url}}
</section>
</div>
</li>
{{/items}}
</ul>
</div>

View File

@@ -1,9 +0,0 @@
{{#tasks.count}}
<section class="section">
<div class="section-content">
{{#tasks}}
{{> task}}
{{/tasks}}
</div>
</section>
{{/tasks.count}}

View File

@@ -1,33 +1,10 @@
<%
const os = locals.os;
const iOS = os === 'iOS';
const macOS = os === 'macOS';
const cocoaPrefix = iOS ? 'UI' : 'NS';
const layers = locals.layers;
const renamedProperties = locals.renamedProperties;
-%>
<!--
This file is generated.
Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
-->
# 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
the style. There are a number of considerations specific to iOS that may
not be obvious when designing your style with Maputnik. 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.
@@ -38,49 +15,33 @@ 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 contrasts 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
[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) { -%>
resolutions as 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 `MLNMapView.rotateEnabled` and
`MLNMapView.pitchEnabled` properties, respectively, or the corresponding
@@ -89,44 +50,23 @@ 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.,
`-[MLNMapView visibleFeaturesAtPoint:]`) to get details about the selected
``MLNMapView/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/).
To learn more about designing maps for mobile devices, see [Nathaniel Slaughter's blog post](https://www.mapbox.com/blog/designing-maps-for-mobile-devices/) on
To learn more about designing maps for mobile devices, see [Nathaniel Slaughter's blog post](https://blog.mapbox.com/designing-maps-for-mobile-devices-32d2e49d2096) on
the subject.
<% } 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
@@ -134,26 +74,15 @@ You set an `MLNMapView` object’s style either in code, by setting the
`MLNMapView.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
[MapLibre Style Spec](https://maplibre.org/maplibre-style-spec/). This
SDK supports the functionality defined by version 8 of the specification unless
otherwise noted in the
[style specification documentation](https://maplibre.org/maplibre-style-spec/).
[MapLibre Style Spec](https://maplibre.org/maplibre-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 `MLNStyle` object, which provides access to various
`MLNSource` and `MLNStyleLayer` objects that represent content sources and style
represented at runtime by an ``MLNStyle`` object, which provides access to various
``MLNSource`` and ``MLNStyleLayer`` 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](https://www.mapbox.com/ios-sdk/maps/overview/runtime-styling/)”.
<% } -%>
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:
@@ -174,15 +103,15 @@ source | content source
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 `MLNSource`:
source object is a member of one of the following subclasses of ``MLNSource``:
In style JSON | In the SDK
--------------|-----------
`vector` | `MLNVectorTileSource`
`raster` | `MLNRasterTileSource`
`raster-dem` | `MLNRasterDEMSource`
`geojson` | `MLNShapeSource`
`image` | `MLNImageSource`
`vector` | ``MLNVectorTileSource``
`raster` | ``MLNRasterTileSource``
`raster-dem` | ``MLNRasterDEMSource``
`geojson` | ``MLNShapeSource``
`image` | ``MLNImageSource``
`canvas` and `video` sources are not supported.
@@ -242,28 +171,90 @@ object is a member of one of the following subclasses of `MLNStyleLayer`:
In style JSON | In the SDK
--------------|-----------
<% for (const layer of layers) { -%>
`<%- layer.type %>` | `MLN<%- camelize(layer.type) %>StyleLayer`
<% } -%>
`background` | `MLNBackgroundStyleLayer`
`circle` | `MLNCircleStyleLayer`
`fill` | `MLNFillStyleLayer`
`fill-extrusion` | `MLNFillExtrusionStyleLayer`
`heatmap` | `MLNHeatmapStyleLayer`
`hillshade` | `MLNHillshadeStyleLayer`
`line` | `MLNLineStyleLayer`
`raster` | `MLNRasterStyleLayer`
`symbol` | `MLNSymbolStyleLayer`
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(unhyphenate(type)) %> style layers
### Circle 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]) %>` | `MLN<%- camelize(type) %>StyleLayer.<%- objCName(renamedProperties[type][name]) %>` | `MLN<%- camelize(type) %>StyleLayer.<%- objCGetter(renamedProperties[type][name]) %>`
<% } -%>
<% } -%>
<% } -%>
<% } -%>
`circle-pitch-scale` | `MLNCircleStyleLayer.circleScaleAlignment` | `MLNCircleStyleLayer.circleScaleAlignment`
`circle-translate` | `MLNCircleStyleLayer.circleTranslation` | `MLNCircleStyleLayer.circleTranslation`
`circle-translate-anchor` | `MLNCircleStyleLayer.circleTranslationAnchor` | `MLNCircleStyleLayer.circleTranslationAnchor`
### Fill style layers
In style JSON | In Objective-C | In Swift
--------------|----------------|---------
`fill-antialias` | `MLNFillStyleLayer.fillAntialiased` | `MLNFillStyleLayer.isFillAntialiased`
`fill-translate` | `MLNFillStyleLayer.fillTranslation` | `MLNFillStyleLayer.fillTranslation`
`fill-translate-anchor` | `MLNFillStyleLayer.fillTranslationAnchor` | `MLNFillStyleLayer.fillTranslationAnchor`
### Fill extrusion style layers
In style JSON | In Objective-C | In Swift
--------------|----------------|---------
`fill-extrusion-vertical-gradient` | `MLNFillExtrusionStyleLayer.fillExtrusionHasVerticalGradient` | `MLNFillExtrusionStyleLayer.fillExtrusionHasVerticalGradient`
`fill-extrusion-translate` | `MLNFillExtrusionStyleLayer.fillExtrusionTranslation` | `MLNFillExtrusionStyleLayer.fillExtrusionTranslation`
`fill-extrusion-translate-anchor` | `MLNFillExtrusionStyleLayer.fillExtrusionTranslationAnchor` | `MLNFillExtrusionStyleLayer.fillExtrusionTranslationAnchor`
### Line style layers
In style JSON | In Objective-C | In Swift
--------------|----------------|---------
`line-dasharray` | `MLNLineStyleLayer.lineDashPattern` | `MLNLineStyleLayer.lineDashPattern`
`line-translate` | `MLNLineStyleLayer.lineTranslation` | `MLNLineStyleLayer.lineTranslation`
`line-translate-anchor` | `MLNLineStyleLayer.lineTranslationAnchor` | `MLNLineStyleLayer.lineTranslationAnchor`
### Raster style layers
In style JSON | In Objective-C | In Swift
--------------|----------------|---------
`raster-brightness-max` | `MLNRasterStyleLayer.maximumRasterBrightness` | `MLNRasterStyleLayer.maximumRasterBrightness`
`raster-brightness-min` | `MLNRasterStyleLayer.minimumRasterBrightness` | `MLNRasterStyleLayer.minimumRasterBrightness`
`raster-hue-rotate` | `MLNRasterStyleLayer.rasterHueRotation` | `MLNRasterStyleLayer.rasterHueRotation`
`raster-resampling` | `MLNRasterStyleLayer.rasterResamplingMode` | `MLNRasterStyleLayer.rasterResamplingMode`
### Symbol style layers
In style JSON | In Objective-C | In Swift
--------------|----------------|---------
`icon-allow-overlap` | `MLNSymbolStyleLayer.iconAllowsOverlap` | `MLNSymbolStyleLayer.iconAllowsOverlap`
`icon-ignore-placement` | `MLNSymbolStyleLayer.iconIgnoresPlacement` | `MLNSymbolStyleLayer.iconIgnoresPlacement`
`icon-image` | `MLNSymbolStyleLayer.iconImageName` | `MLNSymbolStyleLayer.iconImageName`
`icon-optional` | `MLNSymbolStyleLayer.iconOptional` | `MLNSymbolStyleLayer.isIconOptional`
`icon-rotate` | `MLNSymbolStyleLayer.iconRotation` | `MLNSymbolStyleLayer.iconRotation`
`icon-size` | `MLNSymbolStyleLayer.iconScale` | `MLNSymbolStyleLayer.iconScale`
`icon-keep-upright` | `MLNSymbolStyleLayer.keepsIconUpright` | `MLNSymbolStyleLayer.keepsIconUpright`
`text-keep-upright` | `MLNSymbolStyleLayer.keepsTextUpright` | `MLNSymbolStyleLayer.keepsTextUpright`
`text-max-angle` | `MLNSymbolStyleLayer.maximumTextAngle` | `MLNSymbolStyleLayer.maximumTextAngle`
`text-max-width` | `MLNSymbolStyleLayer.maximumTextWidth` | `MLNSymbolStyleLayer.maximumTextWidth`
`symbol-avoid-edges` | `MLNSymbolStyleLayer.symbolAvoidsEdges` | `MLNSymbolStyleLayer.symbolAvoidsEdges`
`text-field` | `MLNSymbolStyleLayer.text` | `MLNSymbolStyleLayer.text`
`text-allow-overlap` | `MLNSymbolStyleLayer.textAllowsOverlap` | `MLNSymbolStyleLayer.textAllowsOverlap`
`text-font` | `MLNSymbolStyleLayer.textFontNames` | `MLNSymbolStyleLayer.textFontNames`
`text-size` | `MLNSymbolStyleLayer.textFontSize` | `MLNSymbolStyleLayer.textFontSize`
`text-ignore-placement` | `MLNSymbolStyleLayer.textIgnoresPlacement` | `MLNSymbolStyleLayer.textIgnoresPlacement`
`text-justify` | `MLNSymbolStyleLayer.textJustification` | `MLNSymbolStyleLayer.textJustification`
`text-optional` | `MLNSymbolStyleLayer.textOptional` | `MLNSymbolStyleLayer.isTextOptional`
`text-rotate` | `MLNSymbolStyleLayer.textRotation` | `MLNSymbolStyleLayer.textRotation`
`text-writing-mode` | `MLNSymbolStyleLayer.textWritingModes` | `MLNSymbolStyleLayer.textWritingModes`
`icon-translate` | `MLNSymbolStyleLayer.iconTranslation` | `MLNSymbolStyleLayer.iconTranslation`
`icon-translate-anchor` | `MLNSymbolStyleLayer.iconTranslationAnchor` | `MLNSymbolStyleLayer.iconTranslationAnchor`
`text-translate` | `MLNSymbolStyleLayer.textTranslation` | `MLNSymbolStyleLayer.textTranslation`
`text-translate-anchor` | `MLNSymbolStyleLayer.textTranslationAnchor` | `MLNSymbolStyleLayer.textTranslationAnchor`
## Setting attribute values
@@ -287,129 +278,21 @@ or set.
In style JSON | In Objective-C | In Swift
--------------|-----------------------|---------
Color | `<%- cocoaPrefix %>Color` | `<%- cocoaPrefix %>Color`
Color | `UIColor` | `UIColor`
Enum | `NSString` | `String`
String | `NSString` | `String`
Boolean | `NSNumber.boolValue` | `NSNumber.boolValue`
Number | `NSNumber.floatValue` | `NSNumber.floatValue`
Array (`-dasharray`) | `NSArray<NSNumber>` | `[Float]`
Array (`-font`) | `NSArray<NSString>` | `[String]`
<% if (iOS) { -%>
Array (`-offset`, `-translate`) | `NSValue.CGVectorValue` | `NSValue.cgVectorValue`
Array (`-padding`) | `NSValue.UIEdgeInsetsValue` | `NSValue.uiEdgeInsetsValue`
<% } else { -%>
Array (`-offset`, `-translate`) | `NSValue` containing `CGVector` | `NSValue` containing `CGVector`
Array (`-padding`) | `NSValue.edgeInsetsValue` | `NSValue.edgeInsetsValue`
<% } -%>
For padding attributes, note that the arguments to
<% if (iOS) { -%>
`UIEdgeInsetsMake()` in Objective-C and `UIEdgeInsets(top:left:bottom:right:)`
in Swift
<% } else { -%>
`NSEdgeInsetsMake()` in Objective-C and `EdgeInsets(top:left:bottom:right:)` in
Swift
<% } -%>
are specified in counterclockwise order, in contrast to the clockwise order
defined by the style specification.
<% if (macOS) { -%>
Additionally, on macOS, a screen coordinate of (0, 0) is located at the
lower-left corner of the screen. Therefore, a positive `CGVector.dy` means an
offset or translation upward, while a negative `CGVector.dy` means an offset or
translation downward. This is the reverse of how `CGVector` is interpreted on
iOS.
<% } -%>
### Expression operators
Many expression operators defined in the style specification have corresponding
symbols to be used with the `+[NSExpression expressionWithFormat:]`,
`+[NSExpression expressionForFunction:arguments:]`, or
`+[NSExpression expressionForFunction:selectorName:arguments:]` method:
In style specification | Method, function, or predicate type | Format string syntax
-----------------------|-------------------------------------|---------------------
`array` | |
`boolean` | |
`collator` | `NSComparisonPredicateOptions` | `'Québec' =[cd] 'QUEBEC'`
`literal` | `+[NSExpression expressionForConstantValue:]` | `%@` representing `NSArray` or `NSDictionary`
`number` | |
`string` | |
`to-boolean` | `boolValue` |
`to-color` | | `CAST(var, '<%- cocoaPrefix %>Color')`
`to-number` | `mgl_numberWithFallbackValues:` | `CAST(zipCode, 'NSNumber')`
`to-string` | `stringValue` | `CAST(ele, 'NSString')`
`typeof` | |
`geometry-type` | `NSExpression.geometryTypeVariableExpression` | `$geometryType`
`id` | `NSExpression.featureIdentifierVariableExpression` | `$featureIdentifier`
`properties` | `NSExpression.featureAttributesVariableExpression` | `$featureAttributes`
`at` | `objectFrom:withIndex:` | `array[n]`
`get` | `+[NSExpression expressionForKeyPath:]` | Key path
`has` | `mgl_does:have:` | `mgl_does:have:(self, 'key')`
`in` | `NSInPredicateOperatorType` | `needle IN haystack` or `haystack CONTAINS needle` or `ANY haystack = needle`
`length` | `count:` | `count({1, 2, 2, 3, 4, 7, 9})`
`!` | `NSNotPredicateType` | `NOT (p0 OR … OR pn)`
`!=` | `NSNotEqualToPredicateOperatorType` | `key != value`
`<` | `NSLessThanPredicateOperatorType` | `key < value`
`<=` | `NSLessThanOrEqualToPredicateOperatorType` | `key <= value`
`==` | `NSEqualToPredicateOperatorType` | `key == value`
`>` | `NSGreaterThanPredicateOperatorType` | `key > value`
`>=` | `NSGreaterThanOrEqualToPredicateOperatorType` | `key >= value`
`all` | `NSAndPredicateType` | `p0 AND … AND pn`
`any` | `NSOrPredicateType` | `p0 OR … OR pn`
`case` | `+[NSExpression expressionForConditional:trueExpression:falseExpression:]` or `MLN_IF` or `+[NSExpression mgl_expressionForConditional:trueExpression:falseExpresssion:]` | `TERNARY(1 = 2, YES, NO)` or `MLN_IF(1 = 2, YES, 2 = 2, YES, NO)`
`coalesce` | `mgl_coalesce:` | `mgl_coalesce({x, y, z})`
`match` | `MLN_MATCH` or `+[NSExpression mgl_expressionForMatchingExpression:inDictionary:defaultExpression:]` | `MLN_MATCH(x, 0, 'zero match', 1, 'one match', 'two match', 'default')`
`within` | `NSInPredicateOperatorType` | `SELF IN %@` or `%@ CONTAINS SELF` where `%@` is an `MLNShape`
`interpolate` | `mgl_interpolate:withCurveType:parameters:stops:` or `+[NSExpression mgl_expressionForInterpolatingExpression:withCurveType:parameters:stops:]` |
`step` | `mgl_step:from:stops:` or `+[NSExpression mgl_expressionForSteppingExpression:fromExpression:stops:]` |
`let` | `mgl_expressionWithContext:` | `MLN_LET('ios', 11, 'macos', 10.13, $ios + $macos)`
`var` | `+[NSExpression expressionForVariable:]` | `$variable`
`concat` | `mgl_join:` or `-[NSExpression mgl_expressionByAppendingExpression:]` | `mgl_join({'Old', ' ', 'MacDonald'})`
`downcase` | `lowercase:` | `lowercase('DOWNTOWN')`
`upcase` | `uppercase:` | `uppercase('Elysian Fields')`
<% if (macOS) { -%>
`rgb` | `+[NSColor colorWithCalibratedRed:green:blue:alpha:]` |
`rgba` | `+[NSColor colorWithCalibratedRed:green:blue:alpha:]` |
<% } else { -%>
`rgb` | `+[UIColor colorWithRed:green:blue:alpha:]` |
`rgba` | `+[UIColor colorWithRed:green:blue:alpha:]` |
<% } -%>
`to-rgba` | | `CAST(noindex(var), 'NSArray')`
`-` | `from:subtract:` | `2 - 1`
`*` | `multiply:by:` | `1 * 2`
`/` | `divide:by:` | `1 / 2`
`%` | `modulus:by:` |
`^` | `raise:toPower:` | `2 ** 2`
`+` | `add:to:` | `1 + 2`
`abs` | `abs:` | `abs(-1)`
`acos` | `mgl_acos:` | `mgl_acos(1)`
`asin` | `mgl_asin:` | `mgl_asin(0)`
`atan` | `mgl_atan:` | `mgl_atan(20)`
`ceil` | `ceiling:` | `ceiling(0.99999)`
`cos` | `mgl_cos:` | `mgl_cos(0)`
`distance` | | `mgl_distanceFrom(%@)` where `%@` is an `MLNShape`
`e` | | `%@` representing `NSNumber` containing `M_E`
`floor` | `floor:` | `floor(-0.99999)`
`ln` | `ln:` | `ln(2)`
`ln2` | | `%@` representing `NSNumber` containing `M_LN2`
`log10` | `log:` | `log(1)`
`log2` | `mgl_log2:` | `mgl_log2(1024)`
`max` | `max:` | `max({1, 2, 2, 3, 4, 7, 9})`
`min` | `min:` | `min({1, 2, 2, 3, 4, 7, 9})`
`pi` | | `%@` representing `NSNumber` containing `M_PI`
`round` | `mgl_round:` | `mgl_round(1.5)`
`sin` | `mgl_sin:` | `mgl_sin(0)`
`sqrt` | `sqrt:` | `sqrt(2)`
`tan` | `mgl_tan:` | `mgl_tan(0)`
`zoom` | `NSExpression.zoomLevelVariableExpression` | `$zoomLevel`
`heatmap-density` | `NSExpression.heatmapDensityVariableExpression` | `$heatmapDensity`
`line-progress` | `NSExpression.lineProgressVariableExpression` | `$lineProgress`
`format` | `+[NSExpression mgl_expressionForAttributedExpressions:]` or `mgl_attributed:` | `mgl_attributed({x, y, z})`
For operators that have no corresponding `NSExpression` symbol, use the
`MLN_FUNCTION()` format string syntax.
defined by the style specification
## Filtering sources
@@ -445,5 +328,5 @@ In style JSON | In Objective-C | In Swift
`font-scale` | `MLNFontScaleAttribute` | `.fontScaleAttribute`
`text-color` | `MLNFontColorAttribute` | `.fontColorAttribute`
See the “[Predicates and Expressions](predicates-and-expressions.html)” guide for
See <doc:Predicates_and_Expressions> for
a full description of the supported operators and operand types.

View File

@@ -0,0 +1,94 @@
# Working with GeoJSON Data
## Adding a GeoJSON file to the map
MapLibre iOS offers several ways to work with [GeoJSON](http://geojson.org/) files.
GeoJSON is a standard file format for representing geographic data.
You can host a GeoJSON file or bundle it with
your application, you can use a GeoJSON file as the basis of an ``MLNShapeSource``
object. Pass the file’s URL into the
``MLNShapeSource/initWithIdentifier:URL:options:`` initializer and add the
shape source to the map using the ``MLNStyle/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 ``MLNShapeSource`` object,
you can configure the appearance of its data and control what data is visible
using ``MLNStyleLayer`` objects. You can also
[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 ``MLNShape``, ``MLNFeature``, or
``MLNShapeCollectionFeature`` object that the ``MLNShapeSource`` class understands
natively. First, create an `NSData` object out of the source code string or file
contents, then pass that data object into the
``MLNShape/shapeWithData:encoding:error:`` method. Finally, you can pass the
resulting shape or feature object into the
``MLNShapeSource/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.
To include multiple shapes in the source, create and pass an ``MLNShapeCollection`` or
``MLNShapeCollectionFeature`` object to
``MLNShapeSource/initWithIdentifier:shape:options:``. Alternatively, use the
``MLNShapeSource/initWithIdentifier:features:options:`` or
``MLNShapeSource/initWithIdentifier:shapes:options:`` method to create a shape source
with an array. ``MLNShapeSource/initWithIdentifier:features:options:`` accepts only ``MLNFeature``
instances, such as ``MLNPointFeature`` objects, whose attributes you can use when
applying a predicate to ``MLNVectorStyleLayer`` or configuring a style layer’s
appearance.
## Extracting GeoJSON data from the map
Any ``MLNShape``, ``MLNFeature``, or ``MLNShapeCollectionFeature`` object has an
``MLNShape/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
``MLNMapView/visibleFeaturesAtPoint:``.
## About GeoJSON deserialization
The process of converting GeoJSON text into ``MLNShape``, ``MLNFeature``, or
``MLNShapeCollectionFeature`` 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` | ``MLNPointAnnotation``
`MultiPoint` | ``MLNPointCollection``
`LineString` | ``MLNPolyline``
`MultiLineString` | ``MLNMultiPolyline``
`Polygon` | ``MLNPolygon``
`MultiPolygon` | ``MLNMultiPolygon``
`GeometryCollection` | ``MLNShapeCollection``
`Feature` | ``MLNFeature``
`FeatureCollection` | ``MLNShapeCollectionFeature``
A `Feature` object in GeoJSON corresponds to an instance of an ``MLNShape``
subclass conforming to the ``MLNFeature`` protocol. There is a distinct
``MLNFeature``-conforming class for each type of geometry that a GeoJSON feature
can contain. This allows features to be used as raw shapes where convenient. For
example, some features can be added to a map view as annotations. Note that
identifiers and attributes will not be available for feature querying when a
feature is used as an annotation.
In contrast to the GeoJSON standard, it is possible for ``MLNShape`` subclasses
other than ``MLNPointAnnotation`` 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` | `Bool`
Integer | `NSNumber.unsignedLongLongValue`, `NSNumber.longLongValue` | `UInt64`, `Int64`
Floating-point number | `NSNumber.doubleValue` | `Double`
String | `NSString` | `String`

View File

@@ -29,6 +29,7 @@ Powerful, free and open-source mapping toolkit with full control over data sourc
- <doc:LineStyleLayerExample>
- <doc:DDSCircleLayerExample>
- <doc:POIAlongRouteExample>
- <doc:GeoJSON>
### Map Interaction
@@ -47,6 +48,17 @@ Powerful, free and open-source mapping toolkit with full control over data sourc
- <doc:OfflinePackExample>
- <doc:ManageOfflineRegionsExample>
### Other Articles
- <doc:Customizing_Fonts>
- <doc:Info.plist_Keys>
- <doc:GeoJSON>
- <doc:GestureRecognizers>
- <doc:MultipleImagesExample>
- <doc:Predicates_and_Expressions>
- <doc:Tile_URL_Templates>
- <doc:For_Style_Authors>
### Map
- ``MLNSettings``

View File

@@ -1,5 +1,7 @@
# Predicates and expressions
Using `NSPredicate` with MapLibre iOS
Style layers use predicates and expressions to determine what to display and how
to format it. _Predicates_ are represented by the same `NSPredicate` class that
filters results from Core Data or items in an `NSArray` in Objective-C.
@@ -11,8 +13,7 @@ syntax supported by this SDK. For a more general introduction to predicates and
expressions, consult the
_[Predicate Programming Guide](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html)_
in Apple developer documentation. For additional detail on how this SDK has
extended the `NSExpression` class, consult the [`NSExpression(MLNAdditions)`](./Categories/NSExpression(MLNAdditions).html)
section of this documentation.
extended the `NSExpression` class, see the [`NSExpression+MLNAdditions.h`](https://github.com/maplibre/maplibre-native/blob/main/platform/darwin/src/NSExpression%2BMLNAdditions.h) header.
## Using predicates to filter vector data
@@ -144,28 +145,11 @@ polygon.
The following special attributes are also available on features that are produced
as a result of clustering multiple point features together in a shape source:
<table>
<thead>
<tr><th>Attribute</th><th>Type</th><th>Meaning</th></tr>
</thead>
<tbody>
<tr>
<td><code>cluster</code></td>
<td>Bool</td>
<td>True if the feature is a point cluster. If the attribute is false (or not present) then the feature should not be considered a cluster.</td>
</tr>
<tr>
<td><code>cluster_id</code></td>
<td>Number</td>
<td>Identifier for the point cluster.</td>
</tr>
<tr>
<td><code>point_count</code></td>
<td>Number</td>
<td>The number of point features in a given cluster.</td>
</tr>
</tbody>
</table>
| Attribute | Type | Meaning |
|-------------|--------|------------------------------------------------------------------------------------------------------------------------------------------|
| cluster | Bool | True if the feature is a point cluster. If the attribute is false (or not present) then the feature should not be considered a cluster. |
| cluster_id | Number | Identifier for the point cluster. |
| point_count | Number | The number of point features in a given cluster. |
Some characters may not be used directly as part of a key path in a format
string. For example, if a feature’s attribute is named `ISO 3166-1:2006`, an
@@ -220,7 +204,7 @@ Initializer parameter | Format string syntax
`length:` | `length('Wapakoneta')`
`castObject:toType:` | `CAST(ele, 'NSString')`<br>`CAST(ele, 'NSNumber')`
A number of [Mapbox-specific functions](#mapbox-specific-functions) are also
A number of [MapLibre-specific functions](#MapLibre-specific-functions) are also
available.
The following predefined functions are **not** supported:
@@ -259,87 +243,17 @@ expression.
The following variables are defined by this SDK for use with style layers:
<table>
<thead>
<tr><th>Variable</th><th>Type</th><th>Meaning</th></tr>
</thead>
<tbody>
<tr>
<td><code>$featureIdentifier</code></td>
<td>
Any
<a href="working-with-geojson-data.html#about-geojson-deserialization">GeoJSON data type</a>
</td>
<td>
A value that uniquely identifies the feature in the containing source.
This variable corresponds to the
<code>NSExpression.featureIdentifierVariableExpression</code> property.
</td>
</tr>
<tr>
<td><code>$geometryType</code></td>
<td>String</td>
<td>
The type of geometry represented by the feature. A feature’s type is one
of the following strings:
<ul>
<li>
<code>Point</code> for point features, corresponding to the
<code>MLNPointAnnotation</code> class
</li>
<li>
<code>LineString</code> for polyline features, corresponding to
the <code>MLNPolyline</code> class
</li>
<li>
<code>Polygon</code> for polygon features, corresponding to the
<code>MLNPolygon</code> class
</li>
</ul>
This variable corresponds to the
<code>NSExpression.geometryTypeVariableExpression</code> property.
</td>
</tr>
<tr>
<td><code>$heatmapDensity</code></td>
<td>Number</td>
<td>
The
<a href="https://en.wikipedia.org/wiki/Kernel_density_estimation">kernel density estimation</a>
of a screen point in a heatmap layer; in other words, a relative measure
of how many data points are crowded around a particular pixel. This
variable can only be used with the <code>heatmapColor</code> property.
This variable corresponds to the
<code>NSExpression.heatmapDensityVariableExpression</code> property.
</td>
</tr>
<tr>
<td><code>$zoomLevel</code></td>
<td>Number</td>
<td>
The current zoom level. In style layout and paint properties, this
variable may only appear as the target of a top-level interpolation or
step expression. This variable corresponds to the
<code>NSExpression.zoomLevelVariableExpression</code> property.
</td>
</tr>
<tr>
<td><code>$lineProgress</code></td>
<td>Number</td>
<td>
A number that indicates the relative distance along a line at a given
point along the line. This variable evaluates to 0 at the beginning of the
line and 1 at the end of the line. It can only be used with the
`MLNLineStyleLayer.lineGradient` property. It corresponds to the
<code>NSExpression.lineProgressVariableExpression</code> property.
</td>
</tr>
</tbody>
</table>
| Variable | Type | Meaning |
| --- | --- | --- |
| `$featureIdentifier` | Any GeoJSON data type | A value that uniquely identifies the feature in the containing source. This variable corresponds to the `NSExpression.featureIdentifierVariableExpression` property. |
| `$geometryType` | String | The type of geometry represented by the feature. A feature’s type is one of the following strings:<br><br>* `Point` for point features, corresponding to the `MLNPointAnnotation` class<br>* `LineString` for polyline features, corresponding to the ``MLNPolyline`` class<br>* `Polygon` for polygon features, corresponding to the ``MLNPolygon`` class<br><br>This variable corresponds to the `NSExpression.geometryTypeVariableExpression` property. |
| `$heatmapDensity` | Number | The [kernel density estimation](https://en.wikipedia.org/wiki/Kernel_density_estimation) of a screen point in a heatmap layer; in other words, a relative measure of how many data points are crowded around a particular pixel. This variable can only be used with the `heatmapColor` property. This variable corresponds to the `NSExpression.heatmapDensityVariableExpression` property. |
| `$zoomLevel` | Number | The current zoom level. In style layout and paint properties, this variable may only appear as the target of a top-level interpolation or step expression. This variable corresponds to the `NSExpression.zoomLevelVariableExpression` property. |
| `$lineProgress` | Number | A number that indicates the relative distance along a line at a given point along the line. This variable evaluates to 0 at the beginning of the line and 1 at the end of the line. It can only be used with the ``MLNLineStyleLayer/lineGradient`` property. It corresponds to the `NSExpression.lineProgressVariableExpression` property. |
In addition to these variables, you can define your own variables and refer to
them elsewhere in the expression. The syntax for defining a variable makes use
of a [Mapbox-specific function](#mapbox-specific-functions) that takes an
of a [MapLibre-specific function](#MapLibre-specific-functions) that takes an
`NSDictionary` as an argument:
```objc
@@ -350,7 +264,9 @@ of a [Mapbox-specific function](#mapbox-specific-functions) that takes an
NSExpression(format: "MLN_LET(floorCount, 2, $floorCount + 1)")
```
## Mapbox-specific functions
## MapLibre-specific functions
> Warning: Due to a change in iOS 15.5, some of these stopped working. See [#331](https://github.com/maplibre/maplibre-native/issues/331) for more information and workarounds.
For compatibility with the MapLibre Style Spec, the following functions
are defined by this SDK. When setting a style layer property, you can call these
@@ -358,60 +274,50 @@ functions just like the predefined functions above, using either the
`+[NSExpression expressionForFunction:arguments:]` method or a convenient format
string syntax:
### `mgl_does:have:`
<dl>
<dt>Selector:</dt>
<dd><code>mgl_does:have:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_does:have:(SELF, '🧀🍔')</code> or <code>mgl_does:have:(%@, '🧀🍔')</code></dd>
</dl>
### mgl_does:have:
**Selector:** `mgl_does:have:`
**Format string syntax:** `mgl_does:have:(SELF, '🧀🍔')` or `mgl_does:have:(%@, '🧀🍔')`
Returns a Boolean value indicating whether the dictionary has a value for the
key or whether the evaluated object (`SELF`) has a value for the feature
attribute. Compared to the [`mgl_has:`](#code-mgl_has-code) custom function,
that function’s target is instead passed in as the first argument to this
that function's target is instead passed in as the first argument to this
function. Both functions are equivalent to the syntax `key != NIL` or
`%@[key] != NIL` but can be used outside of a predicate.
### `mgl_interpolate:withCurveType:parameters:stops:`
### mgl_interpolate:withCurveType:parameters:stops:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_interpolate:withCurveType:parameters:stops:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_interpolate:withCurveType:parameters:stops:(x, 'linear', nil, %@)</code></dd>
</dl>
**Selector:** `mgl_interpolate:withCurveType:parameters:stops:`
**Format string syntax:** `mgl_interpolate:withCurveType:parameters:stops:(x, 'linear', nil, %@)`
Produces continuous, smooth results by interpolating between pairs of input and
output values (“stops”). Compared to the
output values ("stops"). Compared to the
[`mgl_interpolateWithCurveType:parameters:stops:`](#code-mgl_interpolatewithcurvetype-parameters-stops-code)
custom function, the input expression (that function’s target) is instead passed
custom function, the input expression (that function's target) is instead passed
in as the first argument to this function.
### `mgl_step:from:stops:`
### mgl_step:from:stops:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_step:from:stops:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_step:from:stops:(x, 11, %@)</code></dd>
</dl>
**Selector:** `mgl_step:from:stops:`
**Format string syntax:** `mgl_step:from:stops:(x, 11, %@)`
Produces discrete, stepped results by evaluating a piecewise-constant function
defined by pairs of input and output values ("stops"). Compared to the
[`mgl_stepWithMinimum:stops:`](#code-mgl_stepwithminimum-stops-code) custom
function, the input expression (that function’s target) is instead passed in as
function, the input expression (that function's target) is instead passed in as
the first argument to this function.
### `mgl_join:`
### mgl_join:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_join:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_join({'Old', 'MacDonald'})</code></dd>
</dl>
**Selector:** `mgl_join:`
**Format string syntax:** `mgl_join({'Old', 'MacDonald'})`
Returns the result of concatenating together all the elements of an array in
order. Compared to the
@@ -419,14 +325,11 @@ order. Compared to the
function, this function takes only one argument, which is an aggregate
expression containing the strings to concatenate.
### `mgl_acos:`
### mgl_acos:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_acos:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_acos(1)</code></dd>
</dl>
**Selector:** `mgl_acos:`
**Format string syntax:** `mgl_acos(1)`
Returns the arccosine of the number.
@@ -434,14 +337,11 @@ This function corresponds to the
[`acos`](https://maplibre.org/maplibre-style-spec/expressions/#acos)
operator in the MapLibre Style Spec.
### `mgl_asin:`
### mgl_asin:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_asin:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_asin(0)</code></dd>
</dl>
**Selector:** `mgl_asin:`
**Format string syntax:** `mgl_asin(0)`
Returns the arcsine of the number.
@@ -449,14 +349,11 @@ This function corresponds to the
[`asin`](https://maplibre.org/maplibre-style-spec/expressions/#asin)
operator in the MapLibre Style Spec.
### `mgl_atan:`
### mgl_atan:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_atan:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_atan(20)</code></dd>
</dl>
**Selector:** `mgl_atan:`
**Format string syntax:** `mgl_atan(20)`
Returns the arctangent of the number.
@@ -464,14 +361,11 @@ This function corresponds to the
[`atan`](https://maplibre.org/maplibre-style-spec/expressions/#atan)
operator in the MapLibre Style Spec.
### `mgl_cos:`
### mgl_cos:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_cos:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_cos(0)</code></dd>
</dl>
**Selector:** `mgl_cos:`
**Format string syntax:** `mgl_cos(0)`
Returns the cosine of the number.
@@ -479,14 +373,11 @@ This function corresponds to the
[`cos`](https://maplibre.org/maplibre-style-spec/expressions/#cos)
operator in the MapLibre Style Spec.
### `mgl_log2:`
### mgl_log2:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_log2:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_log2(1024)</code></dd>
</dl>
**Selector:** `mgl_log2:`
**Format string syntax:** `mgl_log2(1024)`
Returns the base-2 logarithm of the number.
@@ -494,14 +385,11 @@ This function corresponds to the
[`log2`](https://maplibre.org/maplibre-style-spec/expressions/#log2)
operator in the MapLibre Style Spec.
### `mgl_round:`
### mgl_round:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_round:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_round(1.5)</code></dd>
</dl>
**Selector:** `mgl_round:`
**Format string syntax:** `mgl_round(1.5)`
Returns the number rounded to the nearest integer. If the number is halfway
between two integers, this function rounds it away from zero.
@@ -510,14 +398,11 @@ This function corresponds to the
[`round`](https://maplibre.org/maplibre-style-spec/expressions/#round)
operator in the MapLibre Style Spec.
### `mgl_sin:`
### mgl_sin:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_sin:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_sin(0)</code></dd>
</dl>
**Selector:** `mgl_sin:`
**Format string syntax:** `mgl_sin(0)`
Returns the sine of the number.
@@ -525,14 +410,11 @@ This function corresponds to the
[`sin`](https://maplibre.org/maplibre-style-spec/expressions/#sin)
operator in the MapLibre Style Spec.
### `mgl_tan:`
### mgl_tan:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_tan:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_tan(0)</code></dd>
</dl>
**Selector:** `mgl_tan:`
**Format string syntax:** `mgl_tan(0)`
Returns the tangent of the number.
@@ -540,29 +422,23 @@ This function corresponds to the
[`tan`](https://maplibre.org/maplibre-style-spec/expressions/#tan)
operator in the MapLibre Style Spec.
### `mgl_distanceFrom:`
### mgl_distanceFrom:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_distanceFrom:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_distanceFrom(%@)</code> with an <code>MLNShape</code></dd>
</dl>
**Selector:** `mgl_distanceFrom:`
**Format string syntax:** `mgl_distanceFrom(%@)` with an `MLNShape`
Returns the straight-line distance from the evaluated object to the given shape.
This function corresponds to the
[`distance`](https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/#distance)
[`distance`](https://maplibre.org/maplibre-style-spec/expressions/#distance)
operator in the MapLibre Style Spec.
### `mgl_coalesce:`
### mgl_coalesce:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_coalesce:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_coalesce({x, y, z})</code></dd>
</dl>
**Selector:** `mgl_coalesce:`
**Format string syntax:** `mgl_coalesce({x, y, z})`
Returns the first non-`nil` value from an array of expressions.
@@ -570,14 +446,11 @@ This function corresponds to the
[`coalesce`](https://maplibre.org/maplibre-style-spec/expressions/#coalesce)
operator in the MapLibre Style Spec.
### `mgl_attributed:`
### mgl_attributed:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_attributed:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_attributed({x, y, z})</code></dd>
</dl>
**Selector:** `mgl_attributed:`
**Format string syntax:** `mgl_attributed({x, y, z})`
Concatenates and returns the array of `MLNAttributedExpression` objects, for use
with the `MLNSymbolStyleLayer.text` property.
@@ -594,20 +467,15 @@ This function corresponds to the
[`format`](https://maplibre.org/maplibre-style-spec/expressions/#types-format)
operator in the MapLibre Style Spec.
### `MLN_LET`
### MLN_LET
<dl>
<dt>Selector:</dt>
<dd><code>MLN_LET:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>MLN_LET('age', uppercase('old'), 'name', uppercase('MacDonald'), mgl_join({$age, $name}))</code></dd>
<dt>Arguments:</dt>
<dd>
Any number of variable names interspersed with their assigned
<code>NSExpression</code> values, followed by an <code>NSExpression</code>
that may contain references to those variables.
</dd>
</dl>
**Selector:** `MLN_LET:`
**Format string syntax:** `MLN_LET('age', uppercase('old'), 'name', uppercase('MacDonald'), mgl_join({$age, $name}))`
**Arguments:** Any number of variable names interspersed with their assigned
`NSExpression` values, followed by an `NSExpression`
that may contain references to those variables.
Returns the result of evaluating an expression with the given variable values.
Compared to the
@@ -615,24 +483,19 @@ Compared to the
function, this function takes the variable names and values inline before the
expression that contains references to those variables.
### `MLN_MATCH`
### MLN_MATCH
<dl>
<dt>Selector:</dt>
<dd><code>MLN_MATCH:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>MLN_MATCH(x, 0, 'zero match', 1, 'one match', 2, 'two match', 'default')</code></dd>
<dt>Arguments:</dt>
<dd>
An input expression, then any number of argument pairs, followed by a default
expression. Each argument pair consists of a constant value followed by an
expression to produce as a result of matching that constant value.
If the input value is an aggregate expression, then any of the constant values within
that aggregate expression result in the following argument. This is shorthand for
specifying an argument pair for each of the constant values within that aggregate
expression. It is not possible to match the aggregate expression itself.
</dd>
</dl>
**Selector:** `MLN_MATCH:`
**Format string syntax:** `MLN_MATCH(x, 0, 'zero match', 1, 'one match', 2, 'two match', 'default')`
**Arguments:** An input expression, then any number of argument pairs, followed by a default
expression. Each argument pair consists of a constant value followed by an
expression to produce as a result of matching that constant value.
If the input value is an aggregate expression, then any of the constant values within
that aggregate expression result in the following argument. This is shorthand for
specifying an argument pair for each of the constant values within that aggregate
expression. It is not possible to match the aggregate expression itself.
Returns the result of matching the input expression against the given constant
values.
@@ -643,24 +506,19 @@ method and the
[`match`](https://maplibre.org/maplibre-style-spec/expressions/#match)
operator in the MapLibre Style Spec.
### `MLN_IF`
### MLN_IF
<dl>
<dt>Selector:</dt>
<dd><code>MLN_IF:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>MLN_IF(1 = 2, YES, 2 = 2, YES, NO)</code></dd>
<dt>Arguments:</dt>
<dd>
Alternating <code>NSPredicate</code> conditionals and resulting expressions,
followed by a default expression.
</dd>
</dl>
**Selector:** `MLN_IF:`
**Format string syntax:** `MLN_IF(1 = 2, YES, 2 = 2, YES, NO)`
**Arguments:** Alternating `NSPredicate` conditionals and resulting expressions,
followed by a default expression.
Returns the first expression that meets the condition; otherwise, the default
value. Unlike
`+[NSExpression expressionForConditional:trueExpression:falseExpression:]` or
the `TERNARY()` syntax, this function can accept multiple “if else” conditions
the `TERNARY()` syntax, this function can accept multiple "if else" conditions
and is supported on iOS 8._x_ and macOS 10.10._x_; however, each conditional
passed into this function must be wrapped in a constant expression.
@@ -670,18 +528,13 @@ method and the
[`case`](https://maplibre.org/maplibre-style-spec/expressions/#case)
operator in the MapLibre Style Spec.
### `MLN_FUNCTION`
### MLN_FUNCTION
<dl>
<dt>Selector:</dt>
<dd><code>MLN_FUNCTION:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>MLN_FUNCTION('typeof', mystery)</code></dd>
<dt>Arguments:</dt>
<dd>
Any arguments required by the expression operator.
</dd>
</dl>
**Selector:** `MLN_FUNCTION:`
**Format string syntax:** `MLN_FUNCTION('typeof', mystery)`
**Arguments:** Any arguments required by the expression operator.
An expression exactly as defined by the
[MapLibre Style Spec](https://maplibre.org/maplibre-style-spec/expressions/).
@@ -694,7 +547,7 @@ The following custom functions are also available with the
Some of these functions are defined as methods on their respective target
classes, but you should not call them directly outside the context of an
expression, because the result may differ from the evaluated expression’s result
expression, because the result may differ from the evaluated expression's result
or may result in undefined behavior.
The MapLibre Style Spec defines some operators for which no custom
@@ -702,46 +555,33 @@ function is available. To use these operators in an `NSExpression`, call the
[`MLN_FUNCTION()`](#code-mgl_function-code) function with the same arguments
that the operator expects.
### `boolValue`
### boolValue
<dl>
<dt>Selector:</dt>
<dd><code>boolValue</code></dd>
<dt>Format string syntax:</dt>
<dd><code>FUNCTION(1, 'boolValue')</code></dd>
<dt>Target:</dt>
<dd>
An <code>NSExpression</code> that evaluates to a number or string.
</dd>
<dt>Arguments:</dt>
<dd>None.</dd>
</dl>
**Selector:** `boolValue`
A Boolean representation of the target: <code>FALSE</code> when then input is an
empty string, 0, <code>FALSE</code>, <code>NIL</code>, or <code>NaN</code>,
otherwise <code>TRUE</code>.
**Format string syntax:** `FUNCTION(1, 'boolValue')`
### `mgl_has:`
**Target:** An `NSExpression` that evaluates to a number or string.
<dl>
<dt>Selector:</dt>
<dd><code>mgl_has:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>FUNCTION($featureAttributes, 'mgl_has:', '🧀🍔')</code></dd>
<dt>Target:</dt>
<dd>
An <code>NSExpression</code> that evaluates to an <code>NSDictionary</code>
or the evaluated object (<code>SELF</code>).
</dd>
<dt>Arguments:</dt>
<dd>
An <code>NSExpression</code> that evaluates to an <code>NSString</code>
representing the key to look up in the dictionary or the feature attribute to
look up in the evaluated object (see <code>MLNFeature.attributes</code>).
</dd>
</dl>
**Arguments:** None.
<code>true</code> if the dictionary has a value for the key or if the evaluated
A Boolean representation of the target: `FALSE` when then input is an
empty string, 0, `FALSE`, `NIL`, or `NaN`, otherwise `TRUE`.
### mgl_has:
**Selector:** `mgl_has:`
**Format string syntax:** `FUNCTION($featureAttributes, 'mgl_has:', '🧀🍔')`
**Target:** An `NSExpression` that evaluates to an `NSDictionary`
or the evaluated object (`SELF`).
**Arguments:** An `NSExpression` that evaluates to an `NSString`
representing the key to look up in the dictionary or the feature attribute to
look up in the evaluated object (see `MLNFeature.attributes`).
`true` if the dictionary has a value for the key or if the evaluated
object has a value for the feature attribute.
This function corresponds to the
@@ -752,28 +592,19 @@ without the `FUNCTION()` operator. You can also check whether an object has an
attribute by comparing the key path to `NIL`, for example `cheeseburger != NIL`
or `burger.cheese != NIL`
### `mgl_expressionWithContext:`
### mgl_expressionWithContext:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_expressionWithContext:</code></dd>
<dt>Format string syntax:</dt>
<dd>
<code>FUNCTION($ios + $macos, 'mgl_expressionWithContext:', %@)</code> with
a dictionary containing <code>ios</code> and <code>macos</code> keys
</dd>
<dt>Target:</dt>
<dd>
An <code>NSExpression</code> that may contain references to the variables
defined in the context dictionary.
</dd>
<dt>Arguments:</dt>
<dd>
An <code>NSDictionary</code> with <code>NSString</code>s as keys and
<code>NSExpression</code>s as values. Each key is a variable name and each
value is the variable’s value within the target expression.
</dd>
</dl>
**Selector:** `mgl_expressionWithContext:`
**Format string syntax:** `FUNCTION($ios + $macos, 'mgl_expressionWithContext:', %@)` with
a dictionary containing `ios` and `macos` keys
**Target:** An `NSExpression` that may contain references to the variables
defined in the context dictionary.
**Arguments:** An `NSDictionary` with `NSString`s as keys and
`NSExpression`s as values. Each key is a variable name and each
value is the variable's value within the target expression.
The target expression with variable subexpressions replaced with the values
defined in the context dictionary.
@@ -784,48 +615,33 @@ operator in the MapLibre Style Spec. See also the
[`MLN_LET`](#code-mgl_let-code) function, which is used on its own without the
`FUNCTION()` operator.
### `mgl_interpolateWithCurveType:parameters:stops:`
### mgl_interpolateWithCurveType:parameters:stops:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_interpolateWithCurveType:parameters:stops:</code></dd>
<dt>Format string syntax:</dt>
<dd>
<code>FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', NIL, %@)</code>
with a dictionary containing zoom levels or other constant values as keys
</dd>
<dt>Target:</dt>
<dd>
An <code>NSExpression</code> that evaluates to a number and contains a
variable or key path expression.
</dd>
<dt>Arguments:</dt>
<dd>
The first argument is one of the following strings denoting curve types:
<code>linear</code>, <code>exponential</code>, or <code>cubic-bezier</code>.
**Selector:** `mgl_interpolateWithCurveType:parameters:stops:`
The second argument is an expression providing parameters for the curve:
**Format string syntax:** `FUNCTION($zoomLevel, 'mgl_interpolateWithCurveType:parameters:stops:', 'linear', NIL, %@)`
with a dictionary containing zoom levels or other constant values as keys
<ul>
<li>If the curve type is <code>linear</code>, the argument is <code>NIL</code>.</li>
<li>
If the curve type is <code>exponential</code>, the argument is an
expression that evaluates to a number, specifying the base of the
exponential interpolation.
</li>
<li>
If the curve type is <code>cubic-bezier</code>, the argument is an
array or aggregate expression containing four expressions, each
evaluating to a number. The four numbers are control points for the
cubic Bézier curve.
</li>
</ul>
**Target:** An `NSExpression` that evaluates to a number and contains a
variable or key path expression.
The third argument is an <code>NSDictionary</code> object representing the
interpolation’s stops, with numeric zoom levels as keys and expressions as
values.
</dd>
</dl>
**Arguments:** The first argument is one of the following strings denoting curve types:
`linear`, `exponential`, or `cubic-bezier`.
The second argument is an expression providing parameters for the curve:
* If the curve type is `linear`, the argument is `NIL`.
* If the curve type is `exponential`, the argument is an
expression that evaluates to a number, specifying the base of the
exponential interpolation.
* If the curve type is `cubic-bezier`, the argument is an
array or aggregate expression containing four expressions, each
evaluating to a number. The four numbers are control points for the
cubic Bézier curve.
The third argument is an `NSDictionary` object representing the
interpolation's stops, with numeric zoom levels as keys and expressions as
values.
A value interpolated along the continuous mathematical function defined by the
arguments, with the target as the input to the function.
@@ -844,36 +660,50 @@ operator in the MapLibre Style Spec. See also the
[`mgl_interpolate:withCurveType:parameters:stops:`](#code-mgl_interpolate-withcurvetype-parameters-stops-code)
function, which is used on its own without the `FUNCTION()` operator.
### `mgl_numberWithFallbackValues:`
### mgl_numberWithFallbackValues:
<dl>
<dt>Selector:</dt>
<dd>
<code>mgl_numberWithFallbackValues:</code>,
<code>doubleValue</code>,
<code>floatValue</code>, or
<code>decimalValue</code>
</dd>
<dt>Format string syntax:</dt>
<dd><code>FUNCTION(ele, 'mgl_numberWithFallbackValues:', 0)</code></dd>
<dt>Target:</dt>
<dd>
An <code>NSExpression</code> that evaluates to a Boolean value, number, or
string.
</dd>
<dt>Arguments:</dt>
<dd>
Zero or more <code>NSExpression</code>s, each evaluating to a Boolean value
or string.
</dd>
</dl>
**Selector:** `mgl_numberWithFallbackValues:`,
`doubleValue`,
`floatValue`, or
`decimalValue`
**Format string syntax:** `FUNCTION(ele, 'mgl_numberWithFallbackValues:', 0)`
**Target:** An `NSExpression` that evaluates to a Boolean value, number, or
string.
**Arguments:** Zero or more `NSExpression`s, each evaluating to a Boolean value
or string.
A numeric representation of the target:
* If the target is <code>NIL</code> or <code>FALSE</code>, the result is 0.
* If the target is `NIL` or `FALSE`, the result is 0.
* If the target is true, the result is 1.
* If the target is a string, it is converted to a number as specified by the
**Selector:**
`mgl_numberWithFallbackValues:`,
`doubleValue`,
`floatValue`, or
`decimalValue`
**Format string syntax:**
`FUNCTION(ele, 'mgl_numberWithFallbackValues:', 0)`
**Target:**
An `NSExpression` that evaluates to a Boolean value, number, or
string.
**Arguments:**
Zero or more `NSExpression`s, each evaluating to a Boolean value
or string.
A numeric representation of the target:
* If the target is `NIL` or `FALSE`, the result is 0.
* If the target is true, the result is 1.
* If the target is a string, it is converted to a number as specified by the
“[ToNumber Applied to the String Type](https://tc39.github.io/ecma262/#sec-tonumber-applied-to-the-string-type)”
"[ToNumber Applied to the String Type](https://tc39.github.io/ecma262/#sec-tonumber-applied-to-the-string-type)"
algorithm of the ECMAScript Language Specification.
* If multiple values are provided, each one is evaluated in order until the
first successful conversion is obtained.
@@ -884,35 +714,30 @@ operator in the MapLibre Style Spec. You can also cast a value to a
number by passing the value and the string `NSNumber` into the `CAST()`
operator.
### `mgl_stepWithMinimum:stops:`
### mgl_stepWithMinimum:stops:
<dl>
<dt>Selector:</dt>
<dd><code>mgl_stepWithMinimum:stops:</code></dd>
<dt>Format string syntax:</dt>
<dd>
<code>FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', 0, %@)</code> with
a dictionary with zoom levels or other constant values as keys
</dd>
<dt>Target:</dt>
<dd>
An <code>NSExpression</code> that evaluates to a number and contains a
variable or key path expression.
</dd>
<dt>Arguments:</dt>
<dd>
The first argument is an expression that evaluates to a number, specifying
the minimum value in case the target is less than any of the stops in the
second argument.
**Selector:**
`mgl_stepWithMinimum:stops:`
The second argument is an <code>NSDictionary</code> object representing the
interpolation’s stops, with numeric zoom levels as keys and expressions as
values.
</dd>
</dl>
**Format string syntax:**
`FUNCTION($zoomLevel, 'mgl_stepWithMinimum:stops:', 0, %@)` with
a dictionary with zoom levels or other constant values as keys
**Target:**
An `NSExpression` that evaluates to a number and contains a
variable or key path expression.
**Arguments:**
The first argument is an expression that evaluates to a number, specifying
the minimum value in case the target is less than any of the stops in the
second argument.
The second argument is an `NSDictionary` object representing the
interpolation's stops, with numeric zoom levels as keys and expressions as
values.
The output value of the stop whose key is just less than the evaluated target,
or the minimum value if the target is less than the least of the stops’ keys.
or the minimum value if the target is less than the least of the stops' keys.
The input expression is matched against the keys in the stop dictionary. The
keys may be feature attribute values, zoom levels, or heatmap densities. The
@@ -926,18 +751,19 @@ method and the
[`step`](https://maplibre.org/maplibre-style-spec/expressions/#step)
operator in the MapLibre Style Spec.
### `stringByAppendingString:`
### stringByAppendingString:
<dl>
<dt>Selector:</dt>
<dd><code>stringByAppendingString:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>FUNCTION('Old', 'stringByAppendingString:', 'MacDonald')</code></dd>
<dt>Target:</dt>
<dd>An <code>NSExpression</code> that evaluates to a string.</dd>
<dt>Arguments:</dt>
<dd>One or more <code>NSExpression</code>s, each evaluating to a string.</dd>
</dl>
**Selector:**
`stringByAppendingString:`
**Format string syntax:**
`FUNCTION('Old', 'stringByAppendingString:', 'MacDonald')`
**Target:**
An `NSExpression` that evaluates to a string.
**Arguments:**
One or more `NSExpression`s, each evaluating to a string.
The target string with each of the argument strings appended in order.
@@ -949,21 +775,20 @@ operator in the MapLibre Style Spec. See also the
[`mgl_join:`](#code-mgl_join-code) function, which concatenates multiple
expressions and is used on its own without the `FUNCTION()` operator.
### `stringValue`
### stringValue
<dl>
<dt>Selector:</dt>
<dd><code>stringValue</code></dd>
<dt>Format string syntax:</dt>
<dd><code>FUNCTION(ele, 'stringValue')</code></dd>
<dt>Target:</dt>
<dd>
An <code>NSExpression</code> that evaluates to a Boolean value, number, or
string.
</dd>
<dt>Arguments:</dt>
<dd>None.</dd>
</dl>
**Selector:**
`stringValue`
**Format string syntax:**
`FUNCTION(ele, 'stringValue')`
**Target:**
An `NSExpression` that evaluates to a Boolean value, number, or
string.
**Arguments:**
None.
A string representation of the target:

View File

@@ -0,0 +1,41 @@
# Tile URL Templates
Using URL Templates when defining tile sources
``MLNTileSource`` objects, specifically ``MLNRasterTileSource`` and
``MLNVectorTileSource`` objects, can be created using an initializer that accepts
an array of tile URL templates. Tile URL templates are strings that specify the
URLs of the vector tiles or raster tile images to load. A template resembles an
absolute URL, but with any number of placeholder strings that the source
evaluates based on the tile it needs to load. For example:
* `http://www.example.com/tiles/{z}/{x}/{y}.pbf` could be
evaluated as `http://www.example.com/tiles/14/6/9.pbf`.
* `http://www.example.com/tiles/{z}/{x}/{y}{ratio}.png` could be
evaluated as `http://www.example.com/tiles/14/6/9@2x.png`.
Tile URL templates are also used to define tilesets in TileJSON manifests or
[`raster`](https://maplibre.org/maplibre-style-spec/sources/#raster)
and
[`vector`](https://maplibre.org/maplibre-style-spec/sources/#vector-tiles)
sources in style JSON files. See the
[TileJSON specification](https://github.com/mapbox/tilejson-spec/tree/master/2.2.0)
for information about tile URL templates in the context of a TileJSON or style
JSON file.
Tile sources support the following placeholder strings in tile URL templates,
all of which are optional:
| Placeholder string | Description |
| --- | --- |
| `{x}` | The index of the tile along the map’s x axis according to Spherical Mercator projection. If the value is 0, the tile’s left edge corresponds to the 180th meridian west. If the value is 2^z−1, the tile’s right edge corresponds to the 180th meridian east. |
| `{y}` | The index of the tile along the map’s y axis according to Spherical Mercator projection. If the value is 0, the tile’s tile edge corresponds to arctan(sinh(π)), or approximately 85.0511 degrees north. If the value is 2^z−1, the tile’s bottom edge corresponds to −arctan(sinh(π)), or approximately 85.0511 degrees south. The y axis is inverted if the options parameter contains ``MLNTileSourceOptionTileCoordinateSystem`` with a value of ``MLNTileCoordinateSystem/MLNTileCoordinateSystemTMS``. |
| `{z}` | The tile’s zoom level. At zoom level 0, each tile covers the entire world map; at zoom level 1, it covers ¼ of the world; at zoom level 2, 1⁄16 of the world, and so on. For tiles loaded by a ``MLNRasterTileSource`` object, whether the tile zoom level matches the map’s current zoom level depends on the value of the source’s tile size as specified in the ``MLNTileSourceOptionTileSize`` key of the options parameter. |
| `{bbox-epsg-3857}` | The tile’s bounding box, expressed as a comma-separated list of the tile’s western, southern, eastern, and northern extents according to Spherical Mercator (EPSG:3857) projection. The bounding box is typically used with map services conforming to the <a href="http://www.opengeospatial.org/standards/wms">Web Map Service</a> protocol. |
| `{quadkey}` | A quadkey indicating both the tile’s location and its zoom level. The quadkey is typically used with <a href="https://msdn.microsoft.com/en-us/library/bb259689.aspx">Bing Maps</a>. |
| `{ratio}` | A suffix indicating the resolution of the tile image. The suffix is the empty string for standard resolution displays and `@2x` for Retina displays, including displays for which `UIScreen.scale` is 3. |
| `{prefix}` | Two hexadecimal digits chosen such that each visible tile has a different prefix. The prefix is typically used for domain sharding. |
For more information about the `{x}`, `{y}`, and `{z}` placeholder strings,
consult the
[OpenStreetMap Wiki](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames).