From 5d4d5dcf1b2f56f1dff3ef9dbca57fd076932c50 Mon Sep 17 00:00:00 2001 From: Jesse Bounds Date: Wed, 5 Apr 2017 12:05:29 -0700 Subject: [ios, macos] Rename Data-driven styling guide (#8627) * [ios, macos] Rename Data-driven styling guide This turns the Data-driven styling guide into a guide for working with style functions. This helps clarify that not all style functions are DDS specific but keeps the discussion of this related functionality in the same guide. --- .../darwin/docs/guides/Data-Driven Styling.md.ejs | 159 -------------------- .../darwin/docs/guides/For Style Authors.md.ejs | 3 +- .../guides/Using Style Functions at Runtime.md.ejs | 161 +++++++++++++++++++++ platform/darwin/scripts/generate-style-code.js | 6 +- platform/ios/CHANGELOG.md | 1 + platform/ios/docs/guides/Data-Driven Styling.md | 153 -------------------- platform/ios/docs/guides/For Style Authors.md | 3 +- .../guides/Using Style Functions at Runtime.md | 155 ++++++++++++++++++++ platform/ios/jazzy.yml | 2 +- platform/macos/CHANGELOG.md | 1 + platform/macos/docs/guides/Data-Driven Styling.md | 153 -------------------- platform/macos/docs/guides/For Style Authors.md | 3 +- .../guides/Using Style Functions at Runtime.md | 155 ++++++++++++++++++++ platform/macos/jazzy.yml | 2 +- 14 files changed, 481 insertions(+), 476 deletions(-) delete mode 100644 platform/darwin/docs/guides/Data-Driven Styling.md.ejs create mode 100644 platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs delete mode 100644 platform/ios/docs/guides/Data-Driven Styling.md create mode 100644 platform/ios/docs/guides/Using Style Functions at Runtime.md delete mode 100644 platform/macos/docs/guides/Data-Driven Styling.md create mode 100644 platform/macos/docs/guides/Using Style Functions at Runtime.md diff --git a/platform/darwin/docs/guides/Data-Driven Styling.md.ejs b/platform/darwin/docs/guides/Data-Driven Styling.md.ejs deleted file mode 100644 index 7b597c6737..0000000000 --- a/platform/darwin/docs/guides/Data-Driven Styling.md.ejs +++ /dev/null @@ -1,159 +0,0 @@ - -<% - const os = locals.os; - const iOS = os === 'iOS'; - const macOS = os === 'macOS'; - const cocoaPrefix = iOS ? 'UI' : 'NS'; --%> - - -# Data-Driven Styling - -Mapbox’s data-driven styling features allow you to use attributes in the data to style your maps. You can style map features automatically based on their individual attributes. - -Vary POI icons, transit route line colors, city polygon opacity, and more based on any attribute in your data. Need to visualize hotel data by price? You can have your map’s point radii and colors change automatically with your data. - -![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) 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. - -## Style functions - -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 key-value pairs that that determine a style value. With a `MGLCameraSourceFunction` stop, you can use a dictionary with a zoom level for a key and a `MGLStyleValue` for the value. For example, you can use a stops dictionary with zoom levels 0, 10, and 20 as keys, and yellow, orange, and red as the values. A `MGLSourceStyleFunction` uses the relevant attribute value as the key. - -```swift -let stops = [0: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .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) -style.addSource(source) - -let stops = [0: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .white)] - -let layer = MGLCircleStyleLayer(identifier: "circles", source: source) -layer.circleColor = MGLStyleValue(interpolationMode: .exponential, - sourceStops: stops, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .green)]) -layer.circleRadius = MGLStyleValue(rawValue: 10) -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. - - - - -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: MGLStyleValue(rawValue: 0.5), - 14: MGLStyleValue(rawValue: 2), - 18: MGLStyleValue(rawValue: 18)] - -layer.circleRadius = MGLStyleValue(interpolationMode: .exponential, - cameraStops: stops, - options: [.interpolationBase: 1.5]) -``` - -### 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 = [0: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .white)] - -layer.circleColor = MGLStyleValue(interpolationMode: .interval, - sourceStops: stops, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .green)]) -``` - -![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 green to catch any events that do not fall into any of those categories. - -``` swift -let categoricalStops = ["earthquake": MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .orange), - "explosion": MGLStyleValue(rawValue: .red), - "quarry blast": MGLStyleValue(rawValue: .yellow)] - -layer.circleColor = MGLStyleValue(interpolationMode: .categorical, - sourceStops: categoricalStops, - attributeName: "type", - options: [.defaultValue: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .blue)]) - -``` - -![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 = MGLStyleValue(interpolationMode: .identity, - sourceStops: nil, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue(rawValue: 0)]) - -``` - -![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/docs/guides/For Style Authors.md.ejs b/platform/darwin/docs/guides/For Style Authors.md.ejs index 93ca7014a3..86f8c46f53 100644 --- a/platform/darwin/docs/guides/For Style Authors.md.ejs +++ b/platform/darwin/docs/guides/For Style Authors.md.ejs @@ -308,8 +308,7 @@ iOS. A _style function_ allows you to vary the value of a layout or paint attribute based on the zoom level, data provided by content sources, or both. For more -information about style functions that incorporate data from sources, see -“[Data-Driven Styling](data-driven-styling.html)”. +information about style functions, see “[Using Style Functions at Runtime](using-style-functions-at-runtime.html)”. Each kind of style function is represented by a distinct class, but you typically create style functions as you create any other style value, using 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 new file mode 100644 index 0000000000..bd477042c7 --- /dev/null +++ b/platform/darwin/docs/guides/Using Style Functions at Runtime.md.ejs @@ -0,0 +1,161 @@ + +<% + const os = locals.os; + const iOS = os === 'iOS'; + const macOS = os === 'macOS'; + const cocoaPrefix = iOS ? 'UI' : 'NS'; +-%> + + +# 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 key-value pairs that that determine a style value. With a `MGLCameraSourceFunction` stop, you can use a dictionary with a zoom level for a key and a `MGLStyleValue` for the value. For example, you can use a stops dictionary with zoom levels 0, 10, and 20 as keys, and yellow, orange, and red as the values. A `MGLSourceStyleFunction` uses the relevant attribute value as the key. + +```swift +let stops = [0: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .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) +style.addSource(source) + +let stops = [0: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white)] + +let layer = MGLCircleStyleLayer(identifier: "circles", source: source) +layer.circleColor = MGLStyleValue(interpolationMode: .exponential, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .green)]) +layer.circleRadius = MGLStyleValue(rawValue: 10) +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. + + + + +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: MGLStyleValue(rawValue: 0.5), + 14: MGLStyleValue(rawValue: 2), + 18: MGLStyleValue(rawValue: 18)] + +layer.circleRadius = MGLStyleValue(interpolationMode: .exponential, + cameraStops: stops, + options: [.interpolationBase: 1.5]) +``` + +### 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 = [0: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white)] + +layer.circleColor = MGLStyleValue(interpolationMode: .interval, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .green)]) +``` + +![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 categoricalStops = ["earthquake": MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .orange), + "explosion": MGLStyleValue(rawValue: .red), + "quarry blast": MGLStyleValue(rawValue: .yellow)] + +layer.circleColor = MGLStyleValue(interpolationMode: .categorical, + sourceStops: categoricalStops, + attributeName: "type", + options: [.defaultValue: MGLStyleValue<<%- cocoaPrefix %>Color>(rawValue: .blue)]) + +``` + +![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 = MGLStyleValue(interpolationMode: .identity, + sourceStops: nil, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue(rawValue: 0)]) + +``` + +![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 9c4569709d..7e798154e4 100644 --- a/platform/darwin/scripts/generate-style-code.js +++ b/platform/darwin/scripts/generate-style-code.js @@ -528,7 +528,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 guideMD = 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/Data-Driven Styling.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 layers = _(spec.layer.type.values).map((value, layerType) => { const layoutProperties = Object.keys(spec[`layout_${layerType}`]).reduce((memo, name) => { @@ -615,9 +615,9 @@ fs.writeFileSync(`platform/macos/docs/guides/For Style Authors.md`, guideMD({ renamedProperties: renamedPropertiesByLayerType, layers: layers, })); -fs.writeFileSync(`platform/ios/docs/guides/Data-Driven Styling.md`, ddsGuideMD({ +fs.writeFileSync(`platform/ios/docs/guides/Using Style Functions at Runtime.md`, ddsGuideMD({ os: 'iOS', })); -fs.writeFileSync(`platform/macos/docs/guides/Data-Driven Styling.md`, ddsGuideMD({ +fs.writeFileSync(`platform/macos/docs/guides/Using Style Functions at Runtime.md`, ddsGuideMD({ os: 'macOS', })); diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 8b1d6219a3..c79347e572 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -7,6 +7,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue that caused the return type of a map view delegate method to bridge incorrectly to applications written in Swift. ([#8541](https://github.com/mapbox/mapbox-gl-native/pull/8541)) * Fixed a crash that could occur when calling `-[MGLShapeSource featuresMatchingPredicate:]` or `-[MGLVectorSource featuresInSourceLayersWithIdentifiers:predicate:]`. ([#8553](https://github.com/mapbox/mapbox-gl-native/pull/8553)) * Fixed a crash that could occur after adding view-backed annotations to the map. ([#8513](https://github.com/mapbox/mapbox-gl-native/pull/8513)) +* Renamed the "Data-Driven Styling" guide to "Using Style Functions at Runtime" and clarified the meaning of data-driven styling in the guide's discussion of runtime style functions. ([#8627](https://github.com/mapbox/mapbox-gl-native/pull/8627)) ## 3.5.0 diff --git a/platform/ios/docs/guides/Data-Driven Styling.md b/platform/ios/docs/guides/Data-Driven Styling.md deleted file mode 100644 index a5ed874b5d..0000000000 --- a/platform/ios/docs/guides/Data-Driven Styling.md +++ /dev/null @@ -1,153 +0,0 @@ - - - -# Data-Driven Styling - -Mapbox’s data-driven styling features allow you to use attributes in the data to style your maps. You can style map features automatically based on their individual attributes. - -Vary POI icons, transit route line colors, city polygon opacity, and more based on any attribute in your data. Need to visualize hotel data by price? You can have your map’s point radii and colors change automatically with your data. - -![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) 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. - -## Style functions - -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 key-value pairs that that determine a style value. With a `MGLCameraSourceFunction` stop, you can use a dictionary with a zoom level for a key and a `MGLStyleValue` for the value. For example, you can use a stops dictionary with zoom levels 0, 10, and 20 as keys, and yellow, orange, and red as the values. A `MGLSourceStyleFunction` uses the relevant attribute value as the key. - -```swift -let stops = [0: MGLStyleValue(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .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) -style.addSource(source) - -let stops = [0: MGLStyleValue(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .white)] - -let layer = MGLCircleStyleLayer(identifier: "circles", source: source) -layer.circleColor = MGLStyleValue(interpolationMode: .exponential, - sourceStops: stops, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue(rawValue: .green)]) -layer.circleRadius = MGLStyleValue(rawValue: 10) -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. - - - - -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: MGLStyleValue(rawValue: 0.5), - 14: MGLStyleValue(rawValue: 2), - 18: MGLStyleValue(rawValue: 18)] - -layer.circleRadius = MGLStyleValue(interpolationMode: .exponential, - cameraStops: stops, - options: [.interpolationBase: 1.5]) -``` - -### 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 = [0: MGLStyleValue(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .white)] - -layer.circleColor = MGLStyleValue(interpolationMode: .interval, - sourceStops: stops, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue(rawValue: .green)]) -``` - -![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 green to catch any events that do not fall into any of those categories. - -``` swift -let categoricalStops = ["earthquake": MGLStyleValue(rawValue: .orange), - "explosion": MGLStyleValue(rawValue: .red), - "quarry blast": MGLStyleValue(rawValue: .yellow)] - -layer.circleColor = MGLStyleValue(interpolationMode: .categorical, - sourceStops: categoricalStops, - attributeName: "type", - options: [.defaultValue: MGLStyleValue(rawValue: .blue)]) - -``` - -![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 = MGLStyleValue(interpolationMode: .identity, - sourceStops: nil, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue(rawValue: 0)]) - -``` - -![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/docs/guides/For Style Authors.md b/platform/ios/docs/guides/For Style Authors.md index d3ba331e09..ed9018b121 100644 --- a/platform/ios/docs/guides/For Style Authors.md +++ b/platform/ios/docs/guides/For Style Authors.md @@ -288,8 +288,7 @@ defined by the style specification. A _style function_ allows you to vary the value of a layout or paint attribute based on the zoom level, data provided by content sources, or both. For more -information about style functions that incorporate data from sources, see -“[Data-Driven Styling](data-driven-styling.html)”. +information about style functions, see “[Using Style Functions at Runtime](using-style-functions-at-runtime.html)”. Each kind of style function is represented by a distinct class, but you typically create style functions as you create any other style value, using diff --git a/platform/ios/docs/guides/Using Style Functions at Runtime.md b/platform/ios/docs/guides/Using Style Functions at Runtime.md new file mode 100644 index 0000000000..13c4cc0bbc --- /dev/null +++ b/platform/ios/docs/guides/Using Style Functions at Runtime.md @@ -0,0 +1,155 @@ + + + +# 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 key-value pairs that that determine a style value. With a `MGLCameraSourceFunction` stop, you can use a dictionary with a zoom level for a key and a `MGLStyleValue` for the value. For example, you can use a stops dictionary with zoom levels 0, 10, and 20 as keys, and yellow, orange, and red as the values. A `MGLSourceStyleFunction` uses the relevant attribute value as the key. + +```swift +let stops = [0: MGLStyleValue(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .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) +style.addSource(source) + +let stops = [0: MGLStyleValue(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white)] + +let layer = MGLCircleStyleLayer(identifier: "circles", source: source) +layer.circleColor = MGLStyleValue(interpolationMode: .exponential, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue(rawValue: .green)]) +layer.circleRadius = MGLStyleValue(rawValue: 10) +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. + + + + +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: MGLStyleValue(rawValue: 0.5), + 14: MGLStyleValue(rawValue: 2), + 18: MGLStyleValue(rawValue: 18)] + +layer.circleRadius = MGLStyleValue(interpolationMode: .exponential, + cameraStops: stops, + options: [.interpolationBase: 1.5]) +``` + +### 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 = [0: MGLStyleValue(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white)] + +layer.circleColor = MGLStyleValue(interpolationMode: .interval, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue(rawValue: .green)]) +``` + +![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 categoricalStops = ["earthquake": MGLStyleValue(rawValue: .orange), + "explosion": MGLStyleValue(rawValue: .red), + "quarry blast": MGLStyleValue(rawValue: .yellow)] + +layer.circleColor = MGLStyleValue(interpolationMode: .categorical, + sourceStops: categoricalStops, + attributeName: "type", + options: [.defaultValue: MGLStyleValue(rawValue: .blue)]) + +``` + +![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 = MGLStyleValue(interpolationMode: .identity, + sourceStops: nil, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue(rawValue: 0)]) + +``` + +![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 5d39e276b6..87af09a9b9 100644 --- a/platform/ios/jazzy.yml +++ b/platform/ios/jazzy.yml @@ -19,7 +19,7 @@ custom_categories: children: - Adding Points to a Map - Runtime Styling - - Data-Driven Styling + - Using Style Functions at Runtime - Working with Mapbox Studio - Working with GeoJSON Data - For Style Authors diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index cf2c1d4884..326a70ebb2 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -3,6 +3,7 @@ ## 0.4.1 * Fixed an issue causing code signing failures and bloating the framework. ([#8640](https://github.com/mapbox/mapbox-gl-native/pull/8640)) +* Renamed the "Data-Driven Styling" guide to "Using Style Functions at Runtime" and clarified the meaning of data-driven styling in the guide's discussion of runtime style functions. ([#8627](https://github.com/mapbox/mapbox-gl-native/pull/8627)) ## 0.4.0 diff --git a/platform/macos/docs/guides/Data-Driven Styling.md b/platform/macos/docs/guides/Data-Driven Styling.md deleted file mode 100644 index 2adb0197d1..0000000000 --- a/platform/macos/docs/guides/Data-Driven Styling.md +++ /dev/null @@ -1,153 +0,0 @@ - - - -# Data-Driven Styling - -Mapbox’s data-driven styling features allow you to use attributes in the data to style your maps. You can style map features automatically based on their individual attributes. - -Vary POI icons, transit route line colors, city polygon opacity, and more based on any attribute in your data. Need to visualize hotel data by price? You can have your map’s point radii and colors change automatically with your data. - -![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) 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. - -## Style functions - -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 key-value pairs that that determine a style value. With a `MGLCameraSourceFunction` stop, you can use a dictionary with a zoom level for a key and a `MGLStyleValue` for the value. For example, you can use a stops dictionary with zoom levels 0, 10, and 20 as keys, and yellow, orange, and red as the values. A `MGLSourceStyleFunction` uses the relevant attribute value as the key. - -```swift -let stops = [0: MGLStyleValue(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .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) -style.addSource(source) - -let stops = [0: MGLStyleValue(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .white)] - -let layer = MGLCircleStyleLayer(identifier: "circles", source: source) -layer.circleColor = MGLStyleValue(interpolationMode: .exponential, - sourceStops: stops, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue(rawValue: .green)]) -layer.circleRadius = MGLStyleValue(rawValue: 10) -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. - - - - -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: MGLStyleValue(rawValue: 0.5), - 14: MGLStyleValue(rawValue: 2), - 18: MGLStyleValue(rawValue: 18)] - -layer.circleRadius = MGLStyleValue(interpolationMode: .exponential, - cameraStops: stops, - options: [.interpolationBase: 1.5]) -``` - -### 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 = [0: MGLStyleValue(rawValue: .yellow), - 2.5: MGLStyleValue(rawValue: .orange), - 5: MGLStyleValue(rawValue: .red), - 7.5: MGLStyleValue(rawValue: .blue), - 10: MGLStyleValue(rawValue: .white)] - -layer.circleColor = MGLStyleValue(interpolationMode: .interval, - sourceStops: stops, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue(rawValue: .green)]) -``` - -![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 green to catch any events that do not fall into any of those categories. - -``` swift -let categoricalStops = ["earthquake": MGLStyleValue(rawValue: .orange), - "explosion": MGLStyleValue(rawValue: .red), - "quarry blast": MGLStyleValue(rawValue: .yellow)] - -layer.circleColor = MGLStyleValue(interpolationMode: .categorical, - sourceStops: categoricalStops, - attributeName: "type", - options: [.defaultValue: MGLStyleValue(rawValue: .blue)]) - -``` - -![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 = MGLStyleValue(interpolationMode: .identity, - sourceStops: nil, - attributeName: "mag", - options: [.defaultValue: MGLStyleValue(rawValue: 0)]) - -``` - -![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/docs/guides/For Style Authors.md b/platform/macos/docs/guides/For Style Authors.md index f576921857..9ed69ac9ea 100644 --- a/platform/macos/docs/guides/For Style Authors.md +++ b/platform/macos/docs/guides/For Style Authors.md @@ -283,8 +283,7 @@ iOS. A _style function_ allows you to vary the value of a layout or paint attribute based on the zoom level, data provided by content sources, or both. For more -information about style functions that incorporate data from sources, see -“[Data-Driven Styling](data-driven-styling.html)”. +information about style functions, see “[Using Style Functions at Runtime](using-style-functions-at-runtime.html)”. Each kind of style function is represented by a distinct class, but you typically create style functions as you create any other style value, using diff --git a/platform/macos/docs/guides/Using Style Functions at Runtime.md b/platform/macos/docs/guides/Using Style Functions at Runtime.md new file mode 100644 index 0000000000..b3098dfe04 --- /dev/null +++ b/platform/macos/docs/guides/Using Style Functions at Runtime.md @@ -0,0 +1,155 @@ + + + +# 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 key-value pairs that that determine a style value. With a `MGLCameraSourceFunction` stop, you can use a dictionary with a zoom level for a key and a `MGLStyleValue` for the value. For example, you can use a stops dictionary with zoom levels 0, 10, and 20 as keys, and yellow, orange, and red as the values. A `MGLSourceStyleFunction` uses the relevant attribute value as the key. + +```swift +let stops = [0: MGLStyleValue(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .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) +style.addSource(source) + +let stops = [0: MGLStyleValue(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white)] + +let layer = MGLCircleStyleLayer(identifier: "circles", source: source) +layer.circleColor = MGLStyleValue(interpolationMode: .exponential, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue(rawValue: .green)]) +layer.circleRadius = MGLStyleValue(rawValue: 10) +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. + + + + +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: MGLStyleValue(rawValue: 0.5), + 14: MGLStyleValue(rawValue: 2), + 18: MGLStyleValue(rawValue: 18)] + +layer.circleRadius = MGLStyleValue(interpolationMode: .exponential, + cameraStops: stops, + options: [.interpolationBase: 1.5]) +``` + +### 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 = [0: MGLStyleValue(rawValue: .yellow), + 2.5: MGLStyleValue(rawValue: .orange), + 5: MGLStyleValue(rawValue: .red), + 7.5: MGLStyleValue(rawValue: .blue), + 10: MGLStyleValue(rawValue: .white)] + +layer.circleColor = MGLStyleValue(interpolationMode: .interval, + sourceStops: stops, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue(rawValue: .green)]) +``` + +![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 categoricalStops = ["earthquake": MGLStyleValue(rawValue: .orange), + "explosion": MGLStyleValue(rawValue: .red), + "quarry blast": MGLStyleValue(rawValue: .yellow)] + +layer.circleColor = MGLStyleValue(interpolationMode: .categorical, + sourceStops: categoricalStops, + attributeName: "type", + options: [.defaultValue: MGLStyleValue(rawValue: .blue)]) + +``` + +![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 = MGLStyleValue(interpolationMode: .identity, + sourceStops: nil, + attributeName: "mag", + options: [.defaultValue: MGLStyleValue(rawValue: 0)]) + +``` + +![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 fd6052c9f2..1f0e2fbc74 100644 --- a/platform/macos/jazzy.yml +++ b/platform/macos/jazzy.yml @@ -19,7 +19,7 @@ custom_categories: children: - Working with GeoJSON Data - For Style Authors - - Data-Driven Styling + - Using Style Functions at Runtime - Info.plist Keys - name: Maps children: -- cgit v1.2.1