Add animated weather data
Load a raster image to a style using ImageSource and display it on a map as animated weather data using RasterLayer.
This example uses an image source. See the data format on GitHub.
ViewController.swift
import MapboxMaps class ViewController: UIViewController {var mapView: MapView!var sourceId = "radar-source"var timer: Timer?var imageNumber = 0 override func viewDidLoad() {super.viewDidLoad() let center = CLLocationCoordinate2D(latitude: 41.874, longitude: -75.789)let cameraOptions = CameraOptions(center: center, zoom: 5)let mapInitOptions = MapInitOptions(cameraOptions: cameraOptions, styleURI: .dark)mapView = MapView(frame: view.bounds, mapInitOptions: mapInitOptions)mapView.autoresizingMask = [.flexibleHeight, .flexibleWidth] // Hide the `scaleBar` at all zoom levels.mapView.ornaments.options.scaleBar.visibility = .hidden // This also updates the color of the info button to match the map's style.mapView.tintColor = .lightGray // Set the map's `CameraBoundsOptions` to limit the map's zoom level.try? mapView.mapboxMap.setCameraBounds(with: CameraBoundsOptions(maxZoom: 5.99, minZoom: 4)) view.addSubview(mapView) mapView.mapboxMap.onNext(.mapLoaded) { _ inself.addImageLayer() // The following line is just for testing purposes.self.finish()}} func addImageLayer() {let style = mapView.mapboxMap.style // Create an `ImageSource`. This will manage the image displayed in the `RasterLayer` as well// as the location of that image on the map.var imageSource = ImageSource() // Set the `coordinates` property to an array of longitude, latitude pairs.imageSource.coordinates = [[-80.425, 46.437],[-71.516, 46.437],[-71.516, 37.936],[-80.425, 37.936]] // Get the file path for the first radar image, then set the `url` for the `ImageSource` to that path.let path = Bundle.main.path(forResource: "radar0", ofType: "gif")!imageSource.url = path // Create a `RasterLayer` that will display the images from the `ImageSource`var imageLayer = RasterLayer(id: "radar-layer")imageLayer.source = sourceId // Set `rasterFadeDuration` to `0`. This prevents visible transitions when the image is updated.imageLayer.rasterFadeDuration = .constant(0) do {try style.addSource(imageSource, id: sourceId)try style.addLayer(imageLayer) // Add a tap gesture recognizer that will allow the animation to be stopped and started.let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(manageTimer))mapView.addGestureRecognizer(tapGestureRecognizer)} catch {print("Failed to add the source or layer to style. Error: \(error)")}manageTimer()} @objc func manageTimer() {if timer == nil {timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ inguard let self = self else { return } // There are five radar images, number 0-4. Increment the count. When that would// result in an `imageNumber` value greater than 4, reset `imageNumber` to `0`.if self.imageNumber < 4 {self.imageNumber += 1} else {self.imageNumber = 0}// Create a `UIImage` from the file at the specified path.let path = Bundle.main.path(forResource: "radar\(self.imageNumber)", ofType: "gif")let image = UIImage(contentsOfFile: path!) do {// Update the image used by the `ImageSource`.try self.mapView.mapboxMap.style.updateImageSource(withId: self.sourceId, image: image!)} catch {print("Failed to update style image. Error: \(error)")}}} else {timer?.invalidate()timer = nil}} deinit {timer?.invalidate()}}