summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjmkiley <jordan.kiley@mapbox.com>2018-04-18 00:12:37 -0700
committerjmkiley <jordan.kiley@mapbox.com>2018-04-18 00:12:37 -0700
commit9e8f511967dcaf51239693de8f96d28b58ec7d68 (patch)
treea59e266f7ff1522e4eb86b4de4144011c5c259d1
parent4c1ed22efaa6cf6db9fe8a1e98e173ef99f601a5 (diff)
downloadqtlocation-mapboxgl-9e8f511967dcaf51239693de8f96d28b58ec7d68.tar.gz
[ios, macos] Initial commit
-rw-r--r--platform/darwin/docs/guides/Style Layers Using Expressions.md.ejs138
-rw-r--r--platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs99
-rwxr-xr-xplatform/darwin/scripts/generate-style-code.js6
-rw-r--r--platform/darwin/test/MGLDocumentationGuideTests.swift55
-rw-r--r--platform/ios/docs/guides/Style Layers Using Expressions.md191
-rw-r--r--platform/ios/docs/guides/Using Style Functions at Runtime.md154
-rw-r--r--platform/ios/jazzy.yml2
-rw-r--r--platform/macos/docs/guides/Style Layers Using Expressions.md157
-rw-r--r--platform/macos/docs/guides/Using Style Functions at Runtime.md154
-rw-r--r--platform/macos/jazzy.yml2
10 files changed, 524 insertions, 434 deletions
diff --git a/platform/darwin/docs/guides/Style Layers Using Expressions.md.ejs b/platform/darwin/docs/guides/Style Layers Using Expressions.md.ejs
new file mode 100644
index 0000000000..af931982c8
--- /dev/null
+++ b/platform/darwin/docs/guides/Style Layers Using Expressions.md.ejs
@@ -0,0 +1,138 @@
+<%
+ const os = locals.os;
+ const iOS = os === 'iOS';
+ const macOS = os === 'macOS';
+ const cocoaPrefix = iOS ? 'UI' : 'NS';
+ const guide = 'StyleLayersUsingExpressions';
+-%>
+<!--
+ This file is generated.
+ Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
+-->
+
+# Styling Layers Using Expressions
+
+[Runtime Styling](runtime-styling.html) enables you to modify every aspect of the map’s appearance dynamically as a user interacts with your application. Much of the runtime styling API allows you to specify *non-constant expressions*. A style expression allows users to 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.
+
+Runtime styling removes the inconvenience of manually calculating intermediate values between different zoom levels or creating a multitude of style layers to handle homogeneous features in the map content. For example, if your content source indicates the prices of hotels in an area, you can color-code the hotels by price, relying on a data expression to smoothly interpolate among desired colors without having to specify the color for each exact price.
+*Data-driven styling* specifically refers to the use of non-constant expressions to vary the map’s appearance based on data in a content source.
+You can also specify expressions in a style JSON file, to be applied automatically when the map loads. See the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#types-function) for details.
+![available bikes](img/data-driven-styling/citibikes.png) ![subway lines](img/data-driven-styling/polylineExample.png)
+
+This guide uses earthquake data from the [U.S. Geological Survey](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php) and data-driven styling to style a map based on attributes. For more information about how to work with GeoJSON data in our iOS SDK, please see our [working with GeoJSON data](working-with-geojson-data.html) guide. To learn more about supported expressions functions, 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.
+
+An expression is represented at runtime by the `NSExpression` class. There are several types of expressions that can be used to determined paint and layout values.
+
+- A *constant expression* assigns a set value for that style property. For example, the opacity of a fill style layer can be set to a constant value between 0 and 1.
+- A *camera expression* changes a style property with zoom level. For example, you can make the radius of a circle increase according to zoom level. These changes occur either through interpolation or step functions applied to the `$zoom` value.
+- A *data expression* changes a style property with the attributes of a feature. For example, you can adjust the radius of a circle based on the magnitude of an earthquake.
+- A *composite expression* changes a style property with both zoom level and attribute values. For example, you can add a circle layer where each circle has a radius based on both zoom level and the magnitude of an earthquake.
+
+The documentation for each individual style layer property notes which non-constant expressions are enabled for that property.
+
+## Stops
+
+tops are dictionary keys that are associated with layer attribute values. You can use feature attribute values, zoom levels, and heatmap point density as keys, with an constant value or expression for the value. For example, you can use a stop dictionary with the zoom levels 0, 10, and 20 as keys and the colors yellow, orange, and red as the values.
+<%- guideExample(guide, 'Stops', os) %>
+
+Matched values can be used in the place of stops dictionaries with categorical interpolation. The `MGL_MATCH()` custom function creates feature and layer attribute value pairs.
+## Interpolation mode
+
+The effect a key has on the layer style value is determined by the interpolation mode. There are four interpolation modes that can be used with a style expression: exponential/linear, interval, categorical, and identity. You can also use exponential/linear and categorical interpolation modes with a camera expression.
+### Linear
+
+`MGLExpressionInterpolationModeLinear` interpolates linearly between stop values.
+The stops dictionary below, for example, shows colors that continuously shift from yellow to orange to red to blue to white based on the attribute value.
+<%- guideExample(guide, 'Linear', os) %>
+
+![exponential mode](img/data-driven-styling/exponential.png)
+
+### Exponential
+
+By combining `MGLExpressionInterpolationModeExponential` with an interpolation base greater than `0` (other than `1`), you can interpolate between values exponentially, create an accelerated ramp effect.
+Here’s a visualization from Mapbox Studio (see [Working with Mapbox Studio](working-with-mapbox-studio.html)) comparing interpolation base values of `1.5` and `0.5` based on zoom.
+
+<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`.
+<%- 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.
+
+When we use the stops dictionary given above with an interval interpolation mode, 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.
+<%- guideExample(guide, 'Interval', os) %>
+
+![interval mode](img/data-driven-styling/interval.png)
+
+### Categorical
+
+At each stop, a categorical, or match expression, produces an output value equal to the function input. We’re going to match different feature attribute and style layer property values than we did for the previous two modes.
+
+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.
+
+<%- guideExample(guide, 'Categorical', os) %>
+
+`MGL_MATCH` takes the attribute key, followed by possible attribute and style value pairs. The final argument is a default style value.
+
+![categorical mode](img/data-driven-styling/categorical1.png) ![categorical mode](img/data-driven-styling/categorical2.png)
+
+### Identity
+
+Identity interpolation mode uses the attribute’s value as the style layer property value. For example, you can set the `circleRadius` to the earthquake’s magnitude. Since the attribute value itself will be used as the style value, `sourceStops` should be set to `nil`.
+
+<%- guideExample(guide, 'Identity', os) %>
+
+![identity mode](img/data-driven-styling/identity.png)
+
+Some built-in expressions functions can be applied to attribute values to style layer property values. To set the circle radius to 3 times the earthquake’s magnitude, create a `multiply:by` function that takes the attribute value and the multiplier as arguments.
+
+<%- guideExample(guide, 'Multiply', os) %>
+
+Through expressions, 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) %>
+
+<% if (iOS) { -%>
+ ## Migrating from Style Functions to Expressions
+
+ For constant values that do not necessarily change based on camera or attribute values, use `[NSExpression expressionForConstantValue:]` (previously `[MGLStyleValue valueWithRawValue:]`. Expressions support format string syntax, as shown above, as well as convenience methods that include those listed below.
+
+ | | Syntax pre-v4.0.0 | v4.0.0 syntax |
+ | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+ | Linear | MGLStyleValue(interpolationMode: .exponential,
+ sourceStops: stops,
+ attributeName: "mag",
+ options: nil) | NSExpression(forMGLInterpolating: NSExpression(forKeyPath: "mag"),
+ curveType: MGLExpressionInterpolationMode.linear,
+ parameters: nil,
+ stops: NSExpression(forConstantValue: stops)) |
+ | Exponential | MGLStyleValue(interpolationMode: .exponential,
+ sourceStops: stops,
+ attributeName: “mag”,
+ options: [.interpolationBase: 1.5]) | |
+ | Interval | MGLStyleValue(interpolationMode: .interval,
+ sourceStops: [0: UIColor.yellow, 2.5: UIColor.orange],
+ attributeName: "mag",
+ options: [.defaultValue: MGLStyleValue<UIColor>(rawValue: .green)]) | NSExpression(forMGLStepping: NSExpression(forKeyPath: "mag"),
+ from: NSExpression(forConstantValue: UIColor.green),
+ stops: [0: UIColor.yellow, 2.5: UIColor.orange]) |
+ | Categorical | MGLStyleValue(interpolationMode: *.*categorical,
+ sourceStops: [featureValue : UIColor.green],
+ attributeName: "type",
+ options: [*.*defaultValue: MGLStyleValue*<*UIColor*>*(rawValue: *.*blue)]) | NSExpression(format: “MGL_MATCH(type, ‘earthquake’, %@, %@)”, UIColor.green, UIColor.blue) |
+ | Identity | MGLStyleValue(interpolationMode: .identity,
+ sourceStops: nil,
+ attributeName: "mag",
+ options: nil) | NSExpression(forConstantValue: “mag”) |
+
+ In order to convert camera style functions, use `$zoomLevel` or `MGL_FUNCTION('zoom')` as the attribute key.
+
+ <% } -%>
+##Resources
+
+* [USGS](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php)
+* [For Style Authors](for-style-authors.html)
+* [Predicates and Expressions](predicates-and-expressions.html)
diff --git a/platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs b/platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs
deleted file mode 100644
index 61034a674f..0000000000
--- a/platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs
+++ /dev/null
@@ -1,99 +0,0 @@
-<%
- const os = locals.os;
- const iOS = os === 'iOS';
- const macOS = os === 'macOS';
- const cocoaPrefix = iOS ? 'UI' : 'NS';
- const guide = 'UsingStyleFunctionsAtRuntime';
--%>
-<!--
- This file is generated.
- Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
--->
-
-# Using Style Functions at Runtime
-
-[Runtime Styling](runtime-styling.html) enables you to modify every aspect of the map’s appearance dynamically as a user interacts with your application. Much of the runtime styling API allows you to specify _style functions_ instead of constant values. A style function allows you to 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.
-
-Style functions spare you the inconvenience of manually calculating intermediate values between different zoom levels or creating a multitude of style layers to handle homogeneous features in the map content. For example, if your content source indicates the prices of hotels in an area, you can color-code the hotels by price, relying on a style function to smoothly interpolate among desired colors without having to specify the color for each exact price.
-
-_Data-driven styling_ specifically refers to the use of style functions to vary the map’s appearance based on data in a content source.
-
-You can also specify style functions in a style JSON file, to be applied automatically when the map loads. See the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#types-function) for details.
-
-![available bikes](img/data-driven-styling/citibikes.png) ![subway lines](img/data-driven-styling/polylineExample.png)
-
-This guide uses earthquake data from the [U.S. Geological Survey](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php) and data-driven styling to style a map based on attributes. For more information about how to work with GeoJSON data in our iOS SDK, please see our [working with GeoJSON data](working-with-geojson-data.html) guide.
-
-A style function is represented at runtime by the `MGLStyleFunction` class. There are three subclasses of `MGLStyleFunction`:
-
-* `MGLCameraStyleFunction` is a style value that changes with zoom level. For example, you can make the radius of a circle increase according to zoom level.
-* `MGLSourceStyleFunction` is a style value that changes with the attributes of a feature. For example, you can adjust the radius of a circle based on the magnitude of an earthquake.
-* `MGLCompositeStyleFunction` is a style value that changes with both zoom level and attribute values. For example, you can add a circle layer where each circle has a radius based on both zoom level and the magnitude of an earthquake.
-
-The documentation for each individual style layer property notes which style functions are enabled for that property.
-
-## Stops
-
-Stops are dictionary keys that are associated with layer attribute values. With feature attribute values as stops, you can use a dictionary with a zoom level for a key and an expression or constant value for the value. For example, you can use a stop dictionary with the zoom levels 0, 10, and 20 as keys and the colors yellow, orange, and red as the values. Alternatively, attribute values can be the keys.
-
-<%- guideExample(guide, 'Stops', os) %>
-
-## Interpolation mode
-
-The effect a key has on the style value is determined by the interpolation mode. There are four interpolation modes that can be used with a source style function: exponential, interval, categorical, and identity. You can also use exponential and interval interpolation modes with a camera style function.
-
-### Linear
-
-`MGLInterpolationModeExponential` interpolates linearly or exponentially between style function stop values. By default, the `MGLStyleFunction` options parameter `MGLStyleFunctionOptionInterpolationBase` equals `1`, which represents linear interpolation and doesn’t need to be included in the options dictionary.
-
-The stops dictionary below, for example, shows colors that continuously shift from yellow to orange to red to blue to white based on the attribute value.
-
-<%- guideExample(guide, 'Linear', os) %>
-
-![exponential mode](img/data-driven-styling/exponential.png)
-
-### Exponential
-
-By combining `MGLInterpolationModeExponential` with an `MGLStyleFunctionOptionInterpolationBase` greater than `0` (other than `1`), you can interpolate between values exponentially, create an accelerated ramp effect.
-
-Here’s a visualization from Mapbox Studio (see [Working with Mapbox Studio](working-with-mapbox-studio.html)) comparing interpolation base values of `1.5` and `0.5` based on zoom.
-
-<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 `MGLStyleFunctionOptionInterpolationBase` is `1.5`.
-
-<%- guideExample(guide, 'Exponential', os) %>
-
-### Interval
-
-`MGLInterpolationModeInterval` creates 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 style value assigned to that key.
-
-When we use the stops dictionary given above with an interval interpolation mode, 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.
-
-<%- guideExample(guide, 'Interval', os) %>
-
-![interval mode](img/data-driven-styling/interval.png)
-
-### Categorical
-
-At each stop, `MGLInterpolationModeCategorical` produces an output value equal to the function input. We’re going to use a different stops dictionary than we did for the previous two modes.
-
-There are three main types of events in the 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.
-
-<%- guideExample(guide, 'Categorical', os) %>
-
-![categorical mode](img/data-driven-styling/categorical1.png) ![categorical mode](img/data-driven-styling/categorical2.png)
-
-### Identity
-
-`MGLInterpolationModeIdentity` uses the attribute’s value as the style value. For example, you can set the `circleRadius` to the earthquake’s magnitude. Since the attribute value itself will be used as the style value, `sourceStops` should be set to `nil`.
-
-<%- guideExample(guide, 'Identity', os) %>
-
-![identity mode](img/data-driven-styling/identity.png)
-
-##Resources
-
-* [USGS](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php)
-* [For Style Authors](for-style-authors.html)
diff --git a/platform/darwin/scripts/generate-style-code.js b/platform/darwin/scripts/generate-style-code.js
index 9ea5dd3e80..384ee0012c 100755
--- a/platform/darwin/scripts/generate-style-code.js
+++ b/platform/darwin/scripts/generate-style-code.js
@@ -626,7 +626,7 @@ const layerH = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.h.
const layerM = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.mm.ejs', 'utf8'), { strict: true});
const testLayers = ejs.compile(fs.readFileSync('platform/darwin/test/MGLStyleLayerTests.mm.ejs', 'utf8'), { strict: true});
const forStyleAuthorsMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/For Style Authors.md.ejs', 'utf8'), { strict: true });
-const ddsGuideMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs', 'utf8'), { strict: true });
+const ddsGuideMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/Style Layers Using Expressions.md.ejs', 'utf8'), { strict: true });
const templatesMD = ejs.compile(fs.readFileSync('platform/darwin/docs/guides/Tile URL Templates.md.ejs', 'utf8'), { strict: true });
const lightH = ejs.compile(fs.readFileSync('platform/darwin/src/MGLLight.h.ejs', 'utf8'), {strict: true});
@@ -757,10 +757,10 @@ writeIfModified(`platform/macos/docs/guides/For Style Authors.md`, forStyleAutho
renamedProperties: renamedPropertiesByLayerType,
layers: layers,
}));
-writeIfModified(`platform/ios/docs/guides/Using Style Functions at Runtime.md`, ddsGuideMD({
+writeIfModified(`platform/ios/docs/guides/Style Layers Using Expressions.md`, ddsGuideMD({
os: 'iOS',
}));
-writeIfModified(`platform/macos/docs/guides/Using Style Functions at Runtime.md`, ddsGuideMD({
+writeIfModified(`platform/macos/docs/guides/Style Layers Using Expressions.md`, ddsGuideMD({
os: 'macOS',
}));
writeIfModified(`platform/ios/docs/guides/Tile URL Templates.md`, templatesMD({
diff --git a/platform/darwin/test/MGLDocumentationGuideTests.swift b/platform/darwin/test/MGLDocumentationGuideTests.swift
index 8769bc4428..9c260a88c1 100644
--- a/platform/darwin/test/MGLDocumentationGuideTests.swift
+++ b/platform/darwin/test/MGLDocumentationGuideTests.swift
@@ -50,10 +50,10 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate {
styleLoadingExpectation.fulfill()
}
- func testUsingStyleFunctionsAtRuntime$Stops() {
+ func testStyleLayersUsingExpressions$Stops() {
//#-example-code
#if os(macOS)
- let stops: [Float: NSColor] = [
+ let stops: [NSNumber: NSColor] = [
0: .yellow,
2.5: .orange,
5: .red,
@@ -61,7 +61,7 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate {
10: .white,
]
#else
- let stops: [Float: UIColor] = [
+ let stops: [NSNumber: UIColor] = [
0: .yellow,
2.5: .orange,
5: .red,
@@ -75,7 +75,7 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate {
stops[0]!, stops)
}
- func testUsingStyleFunctionsAtRuntime$Linear() {
+ func testStyleLayersUsingExpressions$Linear() {
//#-example-code
let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")!
let symbolSource = MGLSource(identifier: "source")
@@ -115,7 +115,7 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate {
//#-end-example-code
}
- func testUsingStyleFunctionsAtRuntime$Exponential() {
+ func testStyleLayersUsingExpressions$Exponential() {
let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil)
let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
@@ -131,7 +131,7 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate {
//#-end-example-code
}
- func testUsingStyleFunctionsAtRuntime$Interval() {
+ func testStyleLayersUsingExpressions$Interval() {
let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil)
let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
@@ -162,34 +162,26 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate {
//#-end-example-code
}
- func testUsingStyleFunctionsAtRuntime$Categorical() {
+ func testStyleLayersUsingExpressions$Categorical() {
let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil)
let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
//#-example-code
#if os(macOS)
- let colors: [String: NSColor] = [
- "earthquake": .orange,
- "explosion": .red,
- "quarry blast": .yellow,
- ]
let defaultColor = NSColor.blue
+ layer.circleColor = NSExpression(
+ format: "MGL_MATCH(type, 'earthquake', %@, 'explosion', %@, 'quarry blast', %@, %@)",
+ NSColor.orange, NSColor.red, NSColor.yellow, defaultColor)
#else
- let colors: [String: UIColor] = [
- "earthquake": .orange,
- "explosion": .red,
- "quarry blast": .yellow,
- ]
let defaultColor = UIColor.blue
+ layer.circleColor = NSExpression(
+ format: "MGL_MATCH(type, 'earthquake', %@, 'explosion', %@, 'quarry blast', %@, %@)",
+ UIColor.orange, UIColor.red, UIColor.yellow, defaultColor)
#endif
-
- layer.circleColor = NSExpression(
- format: "TERNARY(FUNCTION(%@, 'valueForKeyPath:', type) != nil, FUNCTION(%@, 'valueForKeyPath:', type), %@)",
- colors, colors, defaultColor)
//#-end-example-code
}
- func testUsingStyleFunctionsAtRuntime$Identity() {
+ func testStyleLayersUsingExpressions$Identity() {
let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil)
let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
@@ -197,4 +189,23 @@ class MGLDocumentationGuideTests: XCTestCase, MGLMapViewDelegate {
layer.circleRadius = NSExpression(forKeyPath: "mag")
//#-end-example-code
}
+
+ func testStyleLayersUsingExpressions$Multiply() {
+ let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil)
+ let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
+
+ //#-example-code
+ layer.circleRadius = NSExpression(forFunction: "multiply:by:", arguments: [NSExpression(forKeyPath: "mag"), 3])
+ //#-end-example-code
+ }
+
+ func testStyleLayersUsingExpressions$Cast() {
+ let source = MGLShapeSource(identifier: "circles", shape: nil, options: nil)
+
+ //#-example-code
+ let magnitudeLayer = MGLSymbolStyleLayer(identifier: "mag-layer", source: source)
+ magnitudeLayer.text = NSExpression(format: "CAST(mag, 'NSString')")
+ mapView.style?.addLayer(magnitudeLayer)
+ //#-end-example-code
+ }
}
diff --git a/platform/ios/docs/guides/Style Layers Using Expressions.md b/platform/ios/docs/guides/Style Layers Using Expressions.md
new file mode 100644
index 0000000000..d9e2c29d41
--- /dev/null
+++ b/platform/ios/docs/guides/Style Layers Using Expressions.md
@@ -0,0 +1,191 @@
+<!--
+ This file is generated.
+ Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
+-->
+
+# Styling Layers Using Expressions
+
+[Runtime Styling](runtime-styling.html) enables you to modify every aspect of the map’s appearance dynamically as a user interacts with your application. Much of the runtime styling API allows you to specify *non-constant expressions*. A style expression allows users to 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.
+
+Runtime styling removes the inconvenience of manually calculating intermediate values between different zoom levels or creating a multitude of style layers to handle homogeneous features in the map content. For example, if your content source indicates the prices of hotels in an area, you can color-code the hotels by price, relying on a data expression to smoothly interpolate among desired colors without having to specify the color for each exact price.
+*Data-driven styling* specifically refers to the use of non-constant expressions to vary the map’s appearance based on data in a content source.
+You can also specify expressions in a style JSON file, to be applied automatically when the map loads. See the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#types-function) for details.
+![available bikes](img/data-driven-styling/citibikes.png) ![subway lines](img/data-driven-styling/polylineExample.png)
+
+This guide uses earthquake data from the [U.S. Geological Survey](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php) and data-driven styling to style a map based on attributes. For more information about how to work with GeoJSON data in our iOS SDK, please see our [working with GeoJSON data](working-with-geojson-data.html) guide. To learn more about supported expressions functions, 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.
+
+An expression is represented at runtime by the `NSExpression` class. There are several types of expressions that can be used to determined paint and layout values.
+
+- A *constant expression* assigns a set value for that style property. For example, the opacity of a fill style layer can be set to a constant value between 0 and 1.
+- A *camera expression* changes a style property with zoom level. For example, you can make the radius of a circle increase according to zoom level. These changes occur either through interpolation or step functions applied to the `$zoom` value.
+- A *data expression* changes a style property with the attributes of a feature. For example, you can adjust the radius of a circle based on the magnitude of an earthquake.
+- A *composite expression* changes a style property with both zoom level and attribute values. For example, you can add a circle layer where each circle has a radius based on both zoom level and the magnitude of an earthquake.
+
+The documentation for each individual style layer property notes which non-constant expressions are enabled for that property.
+
+## Stops
+
+tops are dictionary keys that are associated with layer attribute values. You can use feature attribute values, zoom levels, and heatmap point density as keys, with an constant value or expression for the value. For example, you can use a stop dictionary with the zoom levels 0, 10, and 20 as keys and the colors yellow, orange, and red as the values.
+```swift
+let stops: [NSNumber: UIColor] = [
+ 0: .yellow,
+ 2.5: .orange,
+ 5: .red,
+ 7.5: .blue,
+ 10: .white,
+]
+```
+
+Matched values can be used in the place of stops dictionaries with categorical interpolation. The `MGL_MATCH()` custom function creates feature and layer attribute value pairs.
+## Interpolation mode
+
+The effect a key has on the layer style value is determined by the interpolation mode. There are four interpolation modes that can be used with a style expression: exponential/linear, interval, categorical, and identity. You can also use exponential/linear and categorical interpolation modes with a camera expression.
+### Linear
+
+`MGLExpressionInterpolationModeLinear` interpolates linearly between stop values.
+The stops dictionary below, for example, shows colors that continuously shift from yellow to orange to red to blue to white based on the attribute value.
+```swift
+let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")!
+let symbolSource = MGLSource(identifier: "source")
+let symbolLayer = MGLSymbolStyleLayer(identifier: "place-city-sm", source: symbolSource)
+
+let source = MGLShapeSource(identifier: "earthquakes", url: url, options: nil)
+mapView.style?.addSource(source)
+
+let stops: [Float: UIColor] = [
+ 0: .yellow,
+ 2.5: .orange,
+ 5: .red,
+ 7.5: .blue,
+ 10: .white,
+]
+
+let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
+layer.circleColor = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:(mag, 'linear', nil, %@)",
+ stops)
+layer.circleRadius = NSExpression(forConstantValue: 10)
+mapView.style?.insertLayer(layer, below: symbolLayer)
+```
+
+![exponential mode](img/data-driven-styling/exponential.png)
+
+### Exponential
+
+By combining `MGLExpressionInterpolationModeExponential` with an interpolation base greater than `0` (other than `1`), you can interpolate between values exponentially, create an accelerated ramp effect.
+Here’s a visualization from Mapbox Studio (see [Working with Mapbox Studio](working-with-mapbox-studio.html)) comparing interpolation base values of `1.5` and `0.5` based on zoom.
+
+<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`.
+```swift
+let stops = [
+ 12: 0.5,
+ 14: 2,
+ 18: 18,
+]
+
+layer.circleRadius = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.5, %@)",
+ stops)
+```
+
+### 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.
+
+When we use the stops dictionary given above with an interval interpolation mode, 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.
+```swift
+let stops: [Float: UIColor] = [
+ 0: .yellow,
+ 2.5: .orange,
+ 5: .red,
+ 7.5: .blue,
+ 10: .white,
+]
+
+layer.circleColor = NSExpression(format: "mgl_step:from:stops:(mag, %@, %@)",
+ UIColor.green, stops)
+```
+
+![interval mode](img/data-driven-styling/interval.png)
+
+### Categorical
+
+At each stop, a categorical, or match expression, produces an output value equal to the function input. We’re going to match different feature attribute and style layer property values than we did for the previous two modes.
+
+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.
+
+```swift
+let defaultColor = UIColor.blue
+layer.circleColor = NSExpression(
+format: "MGL_MATCH(type, 'earthquake', %@, 'explosion', %@, 'quarry blast', %@, %@)",
+ UIColor.orange, UIColor.red, UIColor.yellow, defaultColor)
+```
+
+`MGL_MATCH` takes the attribute key, followed by possible attribute and style value pairs. The final argument is a default style value.
+
+![categorical mode](img/data-driven-styling/categorical1.png) ![categorical mode](img/data-driven-styling/categorical2.png)
+
+### Identity
+
+Identity interpolation mode uses the attribute’s value as the style layer property value. For example, you can set the `circleRadius` to the earthquake’s magnitude. Since the attribute value itself will be used as the style value, `sourceStops` should be set to `nil`.
+
+```swift
+layer.circleRadius = NSExpression(forKeyPath: "mag")
+```
+
+![identity mode](img/data-driven-styling/identity.png)
+
+Some built-in expressions functions can be applied to attribute values to style layer property values. To set the circle radius to 3 times the earthquake’s magnitude, create a `multiply:by` function that takes the attribute value and the multiplier as arguments.
+
+```swift
+layer.circleRadius = NSExpression(forFunction: "multiply:by:", arguments: [NSExpression(forKeyPath: "mag"), 3])
+```
+
+Through expressions, 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.
+
+```swift
+let magnitudeLayer = MGLSymbolStyleLayer(identifier: "mag-layer", source: source)
+magnitudeLayer.text = NSExpression(format: "CAST(mag, 'NSString')")
+mapView.style?.addLayer(magnitudeLayer)
+```
+
+ ## Migrating from Style Functions to Expressions
+
+ For constant values that do not necessarily change based on camera or attribute values, use `[NSExpression expressionForConstantValue:]` (previously `[MGLStyleValue valueWithRawValue:]`. Expressions support format string syntax, as shown above, as well as convenience methods that include those listed below.
+
+ | | Syntax pre-v4.0.0 | v4.0.0 syntax |
+ | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+ | Linear | MGLStyleValue(interpolationMode: .exponential,
+ sourceStops: stops,
+ attributeName: "mag",
+ options: nil) | NSExpression(forMGLInterpolating: NSExpression(forKeyPath: "mag"),
+ curveType: MGLExpressionInterpolationMode.linear,
+ parameters: nil,
+ stops: NSExpression(forConstantValue: stops)) |
+ | Exponential | MGLStyleValue(interpolationMode: .exponential,
+ sourceStops: stops,
+ attributeName: “mag”,
+ options: [.interpolationBase: 1.5]) | |
+ | Interval | MGLStyleValue(interpolationMode: .interval,
+ sourceStops: [0: UIColor.yellow, 2.5: UIColor.orange],
+ attributeName: "mag",
+ options: [.defaultValue: MGLStyleValue<UIColor>(rawValue: .green)]) | NSExpression(forMGLStepping: NSExpression(forKeyPath: "mag"),
+ from: NSExpression(forConstantValue: UIColor.green),
+ stops: [0: UIColor.yellow, 2.5: UIColor.orange]) |
+ | Categorical | MGLStyleValue(interpolationMode: *.*categorical,
+ sourceStops: [featureValue : UIColor.green],
+ attributeName: "type",
+ options: [*.*defaultValue: MGLStyleValue*<*UIColor*>*(rawValue: *.*blue)]) | NSExpression(format: “MGL_MATCH(type, ‘earthquake’, %@, %@)”, UIColor.green, UIColor.blue) |
+ | Identity | MGLStyleValue(interpolationMode: .identity,
+ sourceStops: nil,
+ attributeName: "mag",
+ options: nil) | NSExpression(forConstantValue: “mag”) |
+
+ In order to convert camera style functions, use `$zoomLevel` or `MGL_FUNCTION('zoom')` as the attribute key.
+
+ ##Resources
+
+* [USGS](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php)
+* [For Style Authors](for-style-authors.html)
+* [Predicates and Expressions](predicates-and-expressions.html)
diff --git a/platform/ios/docs/guides/Using Style Functions at Runtime.md b/platform/ios/docs/guides/Using Style Functions at Runtime.md
deleted file mode 100644
index 7ac8a6aea5..0000000000
--- a/platform/ios/docs/guides/Using Style Functions at Runtime.md
+++ /dev/null
@@ -1,154 +0,0 @@
-<!--
- This file is generated.
- Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
--->
-
-# Using Style Functions at Runtime
-
-[Runtime Styling](runtime-styling.html) enables you to modify every aspect of the map’s appearance dynamically as a user interacts with your application. Much of the runtime styling API allows you to specify _style functions_ instead of constant values. A style function allows you to 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.
-
-Style functions spare you the inconvenience of manually calculating intermediate values between different zoom levels or creating a multitude of style layers to handle homogeneous features in the map content. For example, if your content source indicates the prices of hotels in an area, you can color-code the hotels by price, relying on a style function to smoothly interpolate among desired colors without having to specify the color for each exact price.
-
-_Data-driven styling_ specifically refers to the use of style functions to vary the map’s appearance based on data in a content source.
-
-You can also specify style functions in a style JSON file, to be applied automatically when the map loads. See the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#types-function) for details.
-
-![available bikes](img/data-driven-styling/citibikes.png) ![subway lines](img/data-driven-styling/polylineExample.png)
-
-This guide uses earthquake data from the [U.S. Geological Survey](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php) and data-driven styling to style a map based on attributes. For more information about how to work with GeoJSON data in our iOS SDK, please see our [working with GeoJSON data](working-with-geojson-data.html) guide.
-
-A style function is represented at runtime by the `MGLStyleFunction` class. There are three subclasses of `MGLStyleFunction`:
-
-* `MGLCameraStyleFunction` is a style value that changes with zoom level. For example, you can make the radius of a circle increase according to zoom level.
-* `MGLSourceStyleFunction` is a style value that changes with the attributes of a feature. For example, you can adjust the radius of a circle based on the magnitude of an earthquake.
-* `MGLCompositeStyleFunction` is a style value that changes with both zoom level and attribute values. For example, you can add a circle layer where each circle has a radius based on both zoom level and the magnitude of an earthquake.
-
-The documentation for each individual style layer property notes which style functions are enabled for that property.
-
-## Stops
-
-Stops are dictionary keys that are associated with layer attribute values. With feature attribute values as stops, you can use a dictionary with a zoom level for a key and an expression or constant value for the value. For example, you can use a stop dictionary with the zoom levels 0, 10, and 20 as keys and the colors yellow, orange, and red as the values. Alternatively, attribute values can be the keys.
-
-```swift
-let stops: [Float: UIColor] = [
- 0: .yellow,
- 2.5: .orange,
- 5: .red,
- 7.5: .blue,
- 10: .white,
-]
-```
-
-## Interpolation mode
-
-The effect a key has on the style value is determined by the interpolation mode. There are four interpolation modes that can be used with a source style function: exponential, interval, categorical, and identity. You can also use exponential and interval interpolation modes with a camera style function.
-
-### Linear
-
-`MGLInterpolationModeExponential` interpolates linearly or exponentially between style function stop values. By default, the `MGLStyleFunction` options parameter `MGLStyleFunctionOptionInterpolationBase` equals `1`, which represents linear interpolation and doesn’t need to be included in the options dictionary.
-
-The stops dictionary below, for example, shows colors that continuously shift from yellow to orange to red to blue to white based on the attribute value.
-
-```swift
-let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")!
-let symbolSource = MGLSource(identifier: "source")
-let symbolLayer = MGLSymbolStyleLayer(identifier: "place-city-sm", source: symbolSource)
-
-let source = MGLShapeSource(identifier: "earthquakes", url: url, options: nil)
-mapView.style?.addSource(source)
-
-let stops: [Float: UIColor] = [
- 0: .yellow,
- 2.5: .orange,
- 5: .red,
- 7.5: .blue,
- 10: .white,
-]
-
-let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
-layer.circleColor = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:(mag, 'linear', nil, %@)",
- stops)
-layer.circleRadius = NSExpression(forConstantValue: 10)
-mapView.style?.insertLayer(layer, below: symbolLayer)
-```
-
-![exponential mode](img/data-driven-styling/exponential.png)
-
-### Exponential
-
-By combining `MGLInterpolationModeExponential` with an `MGLStyleFunctionOptionInterpolationBase` greater than `0` (other than `1`), you can interpolate between values exponentially, create an accelerated ramp effect.
-
-Here’s a visualization from Mapbox Studio (see [Working with Mapbox Studio](working-with-mapbox-studio.html)) comparing interpolation base values of `1.5` and `0.5` based on zoom.
-
-<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 `MGLStyleFunctionOptionInterpolationBase` is `1.5`.
-
-```swift
-let stops = [
- 12: 0.5,
- 14: 2,
- 18: 18,
-]
-
-layer.circleRadius = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.5, %@)",
- stops)
-```
-
-### Interval
-
-`MGLInterpolationModeInterval` creates 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 style value assigned to that key.
-
-When we use the stops dictionary given above with an interval interpolation mode, 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.
-
-```swift
-let stops: [Float: UIColor] = [
- 0: .yellow,
- 2.5: .orange,
- 5: .red,
- 7.5: .blue,
- 10: .white,
-]
-
-layer.circleColor = NSExpression(format: "mgl_step:from:stops:(mag, %@, %@)",
- UIColor.green, stops)
-```
-
-![interval mode](img/data-driven-styling/interval.png)
-
-### Categorical
-
-At each stop, `MGLInterpolationModeCategorical` produces an output value equal to the function input. We’re going to use a different stops dictionary than we did for the previous two modes.
-
-There are three main types of events in the 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.
-
-```swift
-let colors: [String: UIColor] = [
- "earthquake": .orange,
- "explosion": .red,
- "quarry blast": .yellow,
-]
-let defaultColor = UIColor.blue
-
-layer.circleColor = NSExpression(
- format: "TERNARY(FUNCTION(%@, 'valueForKeyPath:', type) != nil, FUNCTION(%@, 'valueForKeyPath:', type), %@)",
- colors, colors, defaultColor)
-```
-
-![categorical mode](img/data-driven-styling/categorical1.png) ![categorical mode](img/data-driven-styling/categorical2.png)
-
-### Identity
-
-`MGLInterpolationModeIdentity` uses the attribute’s value as the style value. For example, you can set the `circleRadius` to the earthquake’s magnitude. Since the attribute value itself will be used as the style value, `sourceStops` should be set to `nil`.
-
-```swift
-layer.circleRadius = NSExpression(forKeyPath: "mag")
-```
-
-![identity mode](img/data-driven-styling/identity.png)
-
-##Resources
-
-* [USGS](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php)
-* [For Style Authors](for-style-authors.html)
diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml
index b9731d49ce..fb3ea4be34 100644
--- a/platform/ios/jazzy.yml
+++ b/platform/ios/jazzy.yml
@@ -19,7 +19,7 @@ custom_categories:
children:
- Adding Markers to a Map
- Runtime Styling
- - Using Style Functions at Runtime
+ - Style Layers Using Expressions
- Working with Mapbox Studio
- Working with GeoJSON Data
- Predicates and Expressions
diff --git a/platform/macos/docs/guides/Style Layers Using Expressions.md b/platform/macos/docs/guides/Style Layers Using Expressions.md
new file mode 100644
index 0000000000..478b31dc95
--- /dev/null
+++ b/platform/macos/docs/guides/Style Layers Using Expressions.md
@@ -0,0 +1,157 @@
+<!--
+ This file is generated.
+ Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
+-->
+
+# Styling Layers Using Expressions
+
+[Runtime Styling](runtime-styling.html) enables you to modify every aspect of the map’s appearance dynamically as a user interacts with your application. Much of the runtime styling API allows you to specify *non-constant expressions*. A style expression allows users to 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.
+
+Runtime styling removes the inconvenience of manually calculating intermediate values between different zoom levels or creating a multitude of style layers to handle homogeneous features in the map content. For example, if your content source indicates the prices of hotels in an area, you can color-code the hotels by price, relying on a data expression to smoothly interpolate among desired colors without having to specify the color for each exact price.
+*Data-driven styling* specifically refers to the use of non-constant expressions to vary the map’s appearance based on data in a content source.
+You can also specify expressions in a style JSON file, to be applied automatically when the map loads. See the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#types-function) for details.
+![available bikes](img/data-driven-styling/citibikes.png) ![subway lines](img/data-driven-styling/polylineExample.png)
+
+This guide uses earthquake data from the [U.S. Geological Survey](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php) and data-driven styling to style a map based on attributes. For more information about how to work with GeoJSON data in our iOS SDK, please see our [working with GeoJSON data](working-with-geojson-data.html) guide. To learn more about supported expressions functions, 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.
+
+An expression is represented at runtime by the `NSExpression` class. There are several types of expressions that can be used to determined paint and layout values.
+
+- A *constant expression* assigns a set value for that style property. For example, the opacity of a fill style layer can be set to a constant value between 0 and 1.
+- A *camera expression* changes a style property with zoom level. For example, you can make the radius of a circle increase according to zoom level. These changes occur either through interpolation or step functions applied to the `$zoom` value.
+- A *data expression* changes a style property with the attributes of a feature. For example, you can adjust the radius of a circle based on the magnitude of an earthquake.
+- A *composite expression* changes a style property with both zoom level and attribute values. For example, you can add a circle layer where each circle has a radius based on both zoom level and the magnitude of an earthquake.
+
+The documentation for each individual style layer property notes which non-constant expressions are enabled for that property.
+
+## Stops
+
+tops are dictionary keys that are associated with layer attribute values. You can use feature attribute values, zoom levels, and heatmap point density as keys, with an constant value or expression for the value. For example, you can use a stop dictionary with the zoom levels 0, 10, and 20 as keys and the colors yellow, orange, and red as the values.
+```swift
+let stops: [NSNumber: NSColor] = [
+ 0: .yellow,
+ 2.5: .orange,
+ 5: .red,
+ 7.5: .blue,
+ 10: .white,
+]
+```
+
+Matched values can be used in the place of stops dictionaries with categorical interpolation. The `MGL_MATCH()` custom function creates feature and layer attribute value pairs.
+## Interpolation mode
+
+The effect a key has on the layer style value is determined by the interpolation mode. There are four interpolation modes that can be used with a style expression: exponential/linear, interval, categorical, and identity. You can also use exponential/linear and categorical interpolation modes with a camera expression.
+### Linear
+
+`MGLExpressionInterpolationModeLinear` interpolates linearly between stop values.
+The stops dictionary below, for example, shows colors that continuously shift from yellow to orange to red to blue to white based on the attribute value.
+```swift
+let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")!
+let symbolSource = MGLSource(identifier: "source")
+let symbolLayer = MGLSymbolStyleLayer(identifier: "place-city-sm", source: symbolSource)
+
+let source = MGLShapeSource(identifier: "earthquakes", url: url, options: nil)
+mapView.style?.addSource(source)
+
+let stops: [Float: NSColor] = [
+ 0: .yellow,
+ 2.5: .orange,
+ 5: .red,
+ 7.5: .blue,
+ 10: .white,
+]
+
+let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
+layer.circleColor = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:(mag, 'linear', nil, %@)",
+ stops)
+layer.circleRadius = NSExpression(forConstantValue: 10)
+mapView.style?.insertLayer(layer, below: symbolLayer)
+```
+
+![exponential mode](img/data-driven-styling/exponential.png)
+
+### Exponential
+
+By combining `MGLExpressionInterpolationModeExponential` with an interpolation base greater than `0` (other than `1`), you can interpolate between values exponentially, create an accelerated ramp effect.
+Here’s a visualization from Mapbox Studio (see [Working with Mapbox Studio](working-with-mapbox-studio.html)) comparing interpolation base values of `1.5` and `0.5` based on zoom.
+
+<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`.
+```swift
+let stops = [
+ 12: 0.5,
+ 14: 2,
+ 18: 18,
+]
+
+layer.circleRadius = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.5, %@)",
+ stops)
+```
+
+### 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.
+
+When we use the stops dictionary given above with an interval interpolation mode, 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.
+```swift
+let stops: [Float: NSColor] = [
+ 0: .yellow,
+ 2.5: .orange,
+ 5: .red,
+ 7.5: .blue,
+ 10: .white,
+]
+
+layer.circleColor = NSExpression(format: "mgl_step:from:stops:(mag, %@, %@)",
+ NSColor.green, stops)
+```
+
+![interval mode](img/data-driven-styling/interval.png)
+
+### Categorical
+
+At each stop, a categorical, or match expression, produces an output value equal to the function input. We’re going to match different feature attribute and style layer property values than we did for the previous two modes.
+
+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.
+
+```swift
+let defaultColor = NSColor.blue
+layer.circleColor = NSExpression(
+format: "MGL_MATCH(type, 'earthquake', %@, 'explosion', %@, 'quarry blast', %@, %@)",
+ NSColor.orange, NSColor.red, NSColor.yellow, defaultColor)
+```
+
+`MGL_MATCH` takes the attribute key, followed by possible attribute and style value pairs. The final argument is a default style value.
+
+![categorical mode](img/data-driven-styling/categorical1.png) ![categorical mode](img/data-driven-styling/categorical2.png)
+
+### Identity
+
+Identity interpolation mode uses the attribute’s value as the style layer property value. For example, you can set the `circleRadius` to the earthquake’s magnitude. Since the attribute value itself will be used as the style value, `sourceStops` should be set to `nil`.
+
+```swift
+layer.circleRadius = NSExpression(forKeyPath: "mag")
+```
+
+![identity mode](img/data-driven-styling/identity.png)
+
+Some built-in expressions functions can be applied to attribute values to style layer property values. To set the circle radius to 3 times the earthquake’s magnitude, create a `multiply:by` function that takes the attribute value and the multiplier as arguments.
+
+```swift
+layer.circleRadius = NSExpression(forFunction: "multiply:by:", arguments: [NSExpression(forKeyPath: "mag"), 3])
+```
+
+Through expressions, 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.
+
+```swift
+let magnitudeLayer = MGLSymbolStyleLayer(identifier: "mag-layer", source: source)
+magnitudeLayer.text = NSExpression(format: "CAST(mag, 'NSString')")
+mapView.style?.addLayer(magnitudeLayer)
+```
+
+##Resources
+
+* [USGS](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php)
+* [For Style Authors](for-style-authors.html)
+* [Predicates and Expressions](predicates-and-expressions.html)
diff --git a/platform/macos/docs/guides/Using Style Functions at Runtime.md b/platform/macos/docs/guides/Using Style Functions at Runtime.md
deleted file mode 100644
index e87cd00185..0000000000
--- a/platform/macos/docs/guides/Using Style Functions at Runtime.md
+++ /dev/null
@@ -1,154 +0,0 @@
-<!--
- This file is generated.
- Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
--->
-
-# Using Style Functions at Runtime
-
-[Runtime Styling](runtime-styling.html) enables you to modify every aspect of the map’s appearance dynamically as a user interacts with your application. Much of the runtime styling API allows you to specify _style functions_ instead of constant values. A style function allows you to 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.
-
-Style functions spare you the inconvenience of manually calculating intermediate values between different zoom levels or creating a multitude of style layers to handle homogeneous features in the map content. For example, if your content source indicates the prices of hotels in an area, you can color-code the hotels by price, relying on a style function to smoothly interpolate among desired colors without having to specify the color for each exact price.
-
-_Data-driven styling_ specifically refers to the use of style functions to vary the map’s appearance based on data in a content source.
-
-You can also specify style functions in a style JSON file, to be applied automatically when the map loads. See the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec/#types-function) for details.
-
-![available bikes](img/data-driven-styling/citibikes.png) ![subway lines](img/data-driven-styling/polylineExample.png)
-
-This guide uses earthquake data from the [U.S. Geological Survey](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php) and data-driven styling to style a map based on attributes. For more information about how to work with GeoJSON data in our iOS SDK, please see our [working with GeoJSON data](working-with-geojson-data.html) guide.
-
-A style function is represented at runtime by the `MGLStyleFunction` class. There are three subclasses of `MGLStyleFunction`:
-
-* `MGLCameraStyleFunction` is a style value that changes with zoom level. For example, you can make the radius of a circle increase according to zoom level.
-* `MGLSourceStyleFunction` is a style value that changes with the attributes of a feature. For example, you can adjust the radius of a circle based on the magnitude of an earthquake.
-* `MGLCompositeStyleFunction` is a style value that changes with both zoom level and attribute values. For example, you can add a circle layer where each circle has a radius based on both zoom level and the magnitude of an earthquake.
-
-The documentation for each individual style layer property notes which style functions are enabled for that property.
-
-## Stops
-
-Stops are dictionary keys that are associated with layer attribute values. With feature attribute values as stops, you can use a dictionary with a zoom level for a key and an expression or constant value for the value. For example, you can use a stop dictionary with the zoom levels 0, 10, and 20 as keys and the colors yellow, orange, and red as the values. Alternatively, attribute values can be the keys.
-
-```swift
-let stops: [Float: NSColor] = [
- 0: .yellow,
- 2.5: .orange,
- 5: .red,
- 7.5: .blue,
- 10: .white,
-]
-```
-
-## Interpolation mode
-
-The effect a key has on the style value is determined by the interpolation mode. There are four interpolation modes that can be used with a source style function: exponential, interval, categorical, and identity. You can also use exponential and interval interpolation modes with a camera style function.
-
-### Linear
-
-`MGLInterpolationModeExponential` interpolates linearly or exponentially between style function stop values. By default, the `MGLStyleFunction` options parameter `MGLStyleFunctionOptionInterpolationBase` equals `1`, which represents linear interpolation and doesn’t need to be included in the options dictionary.
-
-The stops dictionary below, for example, shows colors that continuously shift from yellow to orange to red to blue to white based on the attribute value.
-
-```swift
-let url = URL(string: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson")!
-let symbolSource = MGLSource(identifier: "source")
-let symbolLayer = MGLSymbolStyleLayer(identifier: "place-city-sm", source: symbolSource)
-
-let source = MGLShapeSource(identifier: "earthquakes", url: url, options: nil)
-mapView.style?.addSource(source)
-
-let stops: [Float: NSColor] = [
- 0: .yellow,
- 2.5: .orange,
- 5: .red,
- 7.5: .blue,
- 10: .white,
-]
-
-let layer = MGLCircleStyleLayer(identifier: "circles", source: source)
-layer.circleColor = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:(mag, 'linear', nil, %@)",
- stops)
-layer.circleRadius = NSExpression(forConstantValue: 10)
-mapView.style?.insertLayer(layer, below: symbolLayer)
-```
-
-![exponential mode](img/data-driven-styling/exponential.png)
-
-### Exponential
-
-By combining `MGLInterpolationModeExponential` with an `MGLStyleFunctionOptionInterpolationBase` greater than `0` (other than `1`), you can interpolate between values exponentially, create an accelerated ramp effect.
-
-Here’s a visualization from Mapbox Studio (see [Working with Mapbox Studio](working-with-mapbox-studio.html)) comparing interpolation base values of `1.5` and `0.5` based on zoom.
-
-<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 `MGLStyleFunctionOptionInterpolationBase` is `1.5`.
-
-```swift
-let stops = [
- 12: 0.5,
- 14: 2,
- 18: 18,
-]
-
-layer.circleRadius = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'exponential', 1.5, %@)",
- stops)
-```
-
-### Interval
-
-`MGLInterpolationModeInterval` creates 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 style value assigned to that key.
-
-When we use the stops dictionary given above with an interval interpolation mode, 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.
-
-```swift
-let stops: [Float: NSColor] = [
- 0: .yellow,
- 2.5: .orange,
- 5: .red,
- 7.5: .blue,
- 10: .white,
-]
-
-layer.circleColor = NSExpression(format: "mgl_step:from:stops:(mag, %@, %@)",
- NSColor.green, stops)
-```
-
-![interval mode](img/data-driven-styling/interval.png)
-
-### Categorical
-
-At each stop, `MGLInterpolationModeCategorical` produces an output value equal to the function input. We’re going to use a different stops dictionary than we did for the previous two modes.
-
-There are three main types of events in the 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.
-
-```swift
-let colors: [String: NSColor] = [
- "earthquake": .orange,
- "explosion": .red,
- "quarry blast": .yellow,
-]
-let defaultColor = NSColor.blue
-
-layer.circleColor = NSExpression(
- format: "TERNARY(FUNCTION(%@, 'valueForKeyPath:', type) != nil, FUNCTION(%@, 'valueForKeyPath:', type), %@)",
- colors, colors, defaultColor)
-```
-
-![categorical mode](img/data-driven-styling/categorical1.png) ![categorical mode](img/data-driven-styling/categorical2.png)
-
-### Identity
-
-`MGLInterpolationModeIdentity` uses the attribute’s value as the style value. For example, you can set the `circleRadius` to the earthquake’s magnitude. Since the attribute value itself will be used as the style value, `sourceStops` should be set to `nil`.
-
-```swift
-layer.circleRadius = NSExpression(forKeyPath: "mag")
-```
-
-![identity mode](img/data-driven-styling/identity.png)
-
-##Resources
-
-* [USGS](https://earthquake.usgs.gov/earthquakes/feed/v1.0/geojson.php)
-* [For Style Authors](for-style-authors.html)
diff --git a/platform/macos/jazzy.yml b/platform/macos/jazzy.yml
index 9e9447a4f5..e1053324fb 100644
--- a/platform/macos/jazzy.yml
+++ b/platform/macos/jazzy.yml
@@ -20,7 +20,7 @@ custom_categories:
- Working with GeoJSON Data
- Predicates and Expressions
- For Style Authors
- - Using Style Functions at Runtime
+ - Style Layers Using Expressions
- Tile URL Templates
- Info.plist Keys
- name: Maps