メインコンテンツまでスキップ

Animate a line layer

This example demonstrates how to animate a GeoJSON line on a map using the Mapbox Maps SDK for iOS. The application creates a map with a LineLayer displaying a GeoJSON line feature and then animates the line by adding new coordinates to it over time. The line width is dynamically adjusted based on the zoom level using expressions. The animation is achieved by updating the GeoJSON data source with the new coordinates at regular intervals, redrawing the line on the map each time. The process is controlled by a timer that progressively extends the line segment by adding more coordinates until the animation completes.

iOS Examples App Available

This example code is part of the Maps SDK for iOS Examples App, a working iOS project available on Github. iOS developers are encouraged to run the examples app locally to interact with this example in an emulator and explore other features of the Maps SDK.

See our Run the Maps SDK for iOS Examples App tutorial for step-by-step instructions.

AnimateGeoJSONLineExample.swift
import UIKit
import MapboxMaps

final class ViewController: UIViewController {
private let sourceIdentifier = "route-source-identifier"
private var mapView: MapView!
private var routeLineSource: GeoJSONSource!
private var currentIndex = 0
private var cancelables = Set<AnyCancelable>()

override func viewDidLoad() {
super.viewDidLoad()

let centerCoordinate = CLLocationCoordinate2D(latitude: 45.5076, longitude: -122.6736)
let options = MapInitOptions(cameraOptions: CameraOptions(center: centerCoordinate,
zoom: 11.0))

mapView = MapView(frame: view.bounds, mapInitOptions: options)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(mapView)

// Wait for the map to load its style before adding data.
mapView.mapboxMap.onMapLoaded.observeNext { _ in

self.addLine()
self.animatePolyline()



}.store(in: &cancelables)
}

func addLine() {

// Create a GeoJSON data source.
routeLineSource = GeoJSONSource(id: sourceIdentifier)
routeLineSource.data = .feature(Feature(geometry: LineString([allCoordinates[currentIndex]])))

// Create a line layer
var lineLayer = LineLayer(id: "line-layer", source: sourceIdentifier)
lineLayer.lineColor = .constant(StyleColor(.red))

let lowZoomWidth = 5
let highZoomWidth = 20

// Use an expression to define the line width at different zoom extents
lineLayer.lineWidth = .expression(
Exp(.interpolate) {
Exp(.linear)
Exp(.zoom)
14
lowZoomWidth
18
highZoomWidth
}
)
lineLayer.lineCap = .constant(.round)
lineLayer.lineJoin = .constant(.round)

// Add the lineLayer to the map.
try! mapView.mapboxMap.addSource(routeLineSource)
try! mapView.mapboxMap.addLayer(lineLayer)
}

func animatePolyline() {
var currentCoordinates = [CLLocationCoordinate2D]()

// Start a timer that will add a new coordinate to the line and redraw it every time it repeats.
Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true) { [weak self] timer in
guard let self = self else {
timer.invalidate()
return
}

if self.currentIndex > self.allCoordinates.count {
timer.invalidate()
return
}

self.currentIndex += 1

// Create a subarray of locations up to the current index.
currentCoordinates = Array(self.allCoordinates[0..<self.currentIndex - 1])

let updatedLine = Feature(geometry: LineString(currentCoordinates))
self.routeLineSource.data = .feature(updatedLine)
self.mapView.mapboxMap.updateGeoJSONSource(withId: self.sourceIdentifier,
geoJSON: .feature(updatedLine))
}
}

let allCoordinates = [
CLLocationCoordinate2D(latitude: 45.52214, longitude: -122.63748),
CLLocationCoordinate2D(latitude: 45.52218, longitude: -122.64855),
CLLocationCoordinate2D(latitude: 45.52219, longitude: -122.6545),
CLLocationCoordinate2D(latitude: 45.52196, longitude: -122.65497),
CLLocationCoordinate2D(latitude: 45.52104, longitude: -122.65631),
CLLocationCoordinate2D(latitude: 45.51935, longitude: -122.6578),
CLLocationCoordinate2D(latitude: 45.51848, longitude: -122.65867),
CLLocationCoordinate2D(latitude: 45.51293, longitude: -122.65872),
CLLocationCoordinate2D(latitude: 45.51295, longitude: -122.66576),
CLLocationCoordinate2D(latitude: 45.51252, longitude: -122.66745),
CLLocationCoordinate2D(latitude: 45.51244, longitude: -122.66813),
CLLocationCoordinate2D(latitude: 45.51385, longitude: -122.67359),
CLLocationCoordinate2D(latitude: 45.51406, longitude: -122.67415),
CLLocationCoordinate2D(latitude: 45.51484, longitude: -122.67481),
CLLocationCoordinate2D(latitude: 45.51532, longitude: -122.676),
CLLocationCoordinate2D(latitude: 45.51668, longitude: -122.68106),
CLLocationCoordinate2D(latitude: 45.50934, longitude: -122.68503),
CLLocationCoordinate2D(latitude: 45.50858, longitude: -122.68546),
CLLocationCoordinate2D(latitude: 45.50783, longitude: -122.6852),
CLLocationCoordinate2D(latitude: 45.50714, longitude: -122.68424),
CLLocationCoordinate2D(latitude: 45.50585, longitude: -122.68433),
CLLocationCoordinate2D(latitude: 45.50521, longitude: -122.68429),
CLLocationCoordinate2D(latitude: 45.50445, longitude: -122.68456),
CLLocationCoordinate2D(latitude: 45.50371, longitude: -122.68538),
CLLocationCoordinate2D(latitude: 45.50311, longitude: -122.68653),
CLLocationCoordinate2D(latitude: 45.50292, longitude: -122.68731),
CLLocationCoordinate2D(latitude: 45.50253, longitude: -122.68742),
CLLocationCoordinate2D(latitude: 45.50239, longitude: -122.6867),
CLLocationCoordinate2D(latitude: 45.5026, longitude: -122.68545),
CLLocationCoordinate2D(latitude: 45.50294, longitude: -122.68407),
CLLocationCoordinate2D(latitude: 45.50271, longitude: -122.68357),
CLLocationCoordinate2D(latitude: 45.50055, longitude: -122.68236),
CLLocationCoordinate2D(latitude: 45.49994, longitude: -122.68233),
CLLocationCoordinate2D(latitude: 45.49955, longitude: -122.68267),
CLLocationCoordinate2D(latitude: 45.49919, longitude: -122.68257),
CLLocationCoordinate2D(latitude: 45.49842, longitude: -122.68376),
CLLocationCoordinate2D(latitude: 45.49821, longitude: -122.68428),
CLLocationCoordinate2D(latitude: 45.49798, longitude: -122.68573),
CLLocationCoordinate2D(latitude: 45.49805, longitude: -122.68923),
CLLocationCoordinate2D(latitude: 45.49857, longitude: -122.68926),
CLLocationCoordinate2D(latitude: 45.49911, longitude: -122.68814),
CLLocationCoordinate2D(latitude: 45.49921, longitude: -122.68865),
CLLocationCoordinate2D(latitude: 45.49905, longitude: -122.6897),
CLLocationCoordinate2D(latitude: 45.49917, longitude: -122.69346),
CLLocationCoordinate2D(latitude: 45.49902, longitude: -122.69404),
CLLocationCoordinate2D(latitude: 45.49796, longitude: -122.69438),
CLLocationCoordinate2D(latitude: 45.49697, longitude: -122.69504),
CLLocationCoordinate2D(latitude: 45.49661, longitude: -122.69624),
CLLocationCoordinate2D(latitude: 45.4955, longitude: -122.69781),
CLLocationCoordinate2D(latitude: 45.49517, longitude: -122.69803),
CLLocationCoordinate2D(latitude: 45.49508, longitude: -122.69711),
CLLocationCoordinate2D(latitude: 45.4948, longitude: -122.69688),
CLLocationCoordinate2D(latitude: 45.49368, longitude: -122.69744),
CLLocationCoordinate2D(latitude: 45.49311, longitude: -122.69702),
CLLocationCoordinate2D(latitude: 45.49294, longitude: -122.69665),
CLLocationCoordinate2D(latitude: 45.49212, longitude: -122.69788),
CLLocationCoordinate2D(latitude: 45.49264, longitude: -122.69771),
CLLocationCoordinate2D(latitude: 45.49332, longitude: -122.69835),
CLLocationCoordinate2D(latitude: 45.49334, longitude: -122.7007),
CLLocationCoordinate2D(latitude: 45.49358, longitude: -122.70167),
CLLocationCoordinate2D(latitude: 45.49401, longitude: -122.70215),
CLLocationCoordinate2D(latitude: 45.49439, longitude: -122.70229),
CLLocationCoordinate2D(latitude: 45.49566, longitude: -122.70185),
CLLocationCoordinate2D(latitude: 45.49635, longitude: -122.70215),
CLLocationCoordinate2D(latitude: 45.49674, longitude: -122.70346),
CLLocationCoordinate2D(latitude: 45.49758, longitude: -122.70517),
CLLocationCoordinate2D(latitude: 45.49736, longitude: -122.70614),
CLLocationCoordinate2D(latitude: 45.49736, longitude: -122.70663),
CLLocationCoordinate2D(latitude: 45.49767, longitude: -122.70807),
CLLocationCoordinate2D(latitude: 45.49798, longitude: -122.70807),
CLLocationCoordinate2D(latitude: 45.49798, longitude: -122.70717),
CLLocationCoordinate2D(latitude: 45.4984, longitude: -122.70713),
CLLocationCoordinate2D(latitude: 45.49893, longitude: -122.70774)
]
}
このexampleは役に立ちましたか?