All docsMaps SDK for iOSExamplesAdd a line with a color gradient

Add a line with a color gradient

Load a polyline to a style using GeoJsonSource, display it on a map using LineLayer, and style it with a rainbow color gradient.

This example uses a GeoJSON data source. See the data format on GitHub.

ViewController.swift
import Foundation
import MapboxMaps
public class ViewController: UIViewController {
internal var mapView: MapView!
override public func viewDidLoad() {
super.viewDidLoad()
let options = MapInitOptions(styleURI: .light)
mapView = MapView(frame: view.bounds, mapInitOptions: options)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(mapView)
mapView.mapboxMap.onNext(.mapLoaded) { _ in
self.setupExample()
// Set the center coordinate and zoom level.
let centerCoordinate = CLLocationCoordinate2D(latitude: 38.875, longitude: -77.035)
let camera = CameraOptions(center: centerCoordinate, zoom: 12.0)
self.mapView.mapboxMap.setCamera(to: camera)
}
}
// Load GeoJSON file from local bundle and decode into a `FeatureCollection`.
internal func decodeGeoJSON(from fileName: String) throws -> FeatureCollection? {
guard let path = Bundle.main.path(forResource: fileName, ofType: "geojson") else {
preconditionFailure("File '\(fileName)' not found.")
}
let filePath = URL(fileURLWithPath: path)
var featureCollection: FeatureCollection?
do {
let data = try Data(contentsOf: filePath)
featureCollection = try JSONDecoder().decode(FeatureCollection.self, from: data)
} catch {
print("Error parsing data: \(error)")
}
return featureCollection
}
internal func setupExample() {
// Attempt to decode GeoJSON from file bundled with application.
guard let featureCollection = try? decodeGeoJSON(from: "GradientLine") else { return }
let geoJSONDataSourceIdentifier = "geoJSON-data-source"
// Create a GeoJSON data source.
var geoJSONSource = GeoJSONSource()
geoJSONSource.data = .featureCollection(featureCollection)
geoJSONSource.lineMetrics = true // MUST be `true` in order to use `lineGradient` expression
// Create a line layer
var lineLayer = LineLayer(id: "line-layer")
lineLayer.filter = Exp(.eq) {
"$type"
"LineString"
}
// Setting the source
lineLayer.source = geoJSONDataSourceIdentifier
// Styling the line
lineLayer.lineColor = .constant(StyleColor(.red))
lineLayer.lineGradient = .expression(
Exp(.interpolate) {
Exp(.linear)
Exp(.lineProgress)
0
UIColor.blue
0.1
UIColor.purple
0.3
UIColor.cyan
0.5
UIColor.green
0.7
UIColor.yellow
1
UIColor.red
}
)
let lowZoomWidth = 10
let highZoomWidth = 20
lineLayer.lineWidth = .expression(
Exp(.interpolate) {
Exp(.linear)
Exp(.zoom)
14
lowZoomWidth
18
highZoomWidth
}
)
lineLayer.lineCap = .constant(.round)
lineLayer.lineJoin = .constant(.round)
// Add the source and style layer to the map style.
try! mapView.mapboxMap.style.addSource(geoJSONSource, id: geoJSONDataSourceIdentifier)
try! mapView.mapboxMap.style.addLayer(lineLayer, layerPosition: nil)
}
}