Add geometry
Estimated reading time: 3 minutesCheck out this code sample that uses the Mapbox GL iOS library to add a geometry from GeoJSON onto your map.
import UIKit
import Mapbox
class AddGeometryViewController: UIViewController, MGLMapViewDelegate {
// Update the token here if you want to customize the token for this controller in your own project.
// Otherwise update the value at the top of the main controller: ViewController.swift.
// let accessToken = "YOUR_ACCESS_TOKEN"
var mapView = MGLMapView()
var timer: Timer?
var polylineSource: MGLShapeSource?
var currentIndex = 1
var allCoordinates: [CLLocationCoordinate2D]!
override func viewDidLoad() {
super.viewDidLoad()
// Initialize title
title = "Simple geometry"
let url = URL(string: "https://api.jawg.io/styles/jawg-dark.json?access-token="+accessToken)
mapView = MGLMapView(frame: view.bounds, styleURL: url)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.delegate = self
mapView.logoView.isHidden = true
// Set the map’s center coordinate and zoom level.
mapView.setCenter(
CLLocationCoordinate2D(latitude: 48.8534, longitude: 2.3488),
zoomLevel: 10,
animated: false)
view.addSubview(mapView)
allCoordinates = coordinates
}
// Paris boundaries
let coordinates = [(2.319887,48.90046),(2.329981,48.901163),(2.38515,48.902008),(2.394906,48.898444),(2.397627,48.894578),(2.398846,48.887109),(2.408308,48.880409),(2.41327,48.872892),(2.413838,48.864376),(2.416341,48.849234),(2.412246,48.834539),(2.422139,48.835798),(2.41939,48.842577),(2.42813,48.841528),(2.447699,48.844818),(2.463438,48.842089),(2.467426,48.838891),(2.467582,48.833133),(2.462696,48.81906),(2.458705,48.81714),(2.438448,48.818232),(2.421462,48.824054),(2.406032,48.827615),(2.390939,48.826079),(2.379296,48.821214),(2.363947,48.816314),(2.345958,48.816036),(2.331898,48.817011),(2.332461,48.818247),(2.292196,48.827142),(2.279052,48.83249),(2.272793,48.82792),(2.263174,48.83398),(2.255144,48.83481),(2.251709,48.838822),(2.250612,48.845555),(2.239978,48.849702),(2.224219,48.853517),(2.228225,48.865183),(2.231736,48.869069),(2.245678,48.876435),(2.25541,48.874264),(2.258467,48.880387),(2.277487,48.877968),(2.282327,48.883923),(2.291507,48.889472),(2.319887,48.90046)].map({CLLocationCoordinate2D(latitude: $0.1, longitude: $0.0)})
func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
addPolyline(to: mapView.style!)
// To get an animation, uncomment this line and remove the code at the end of addPolyline()
//animatePolyline()
}
func addPolyline(to style: MGLStyle) {
// Add an empty MGLShapeSource, we’ll keep a reference to this and add points to this later.
let source = MGLShapeSource(identifier: "polyline", shape: nil, options: nil)
style.addSource(source)
polylineSource = source
// Add a layer to style our polyline.
let layer = MGLLineStyleLayer(identifier: "polyline", source: source)
layer.lineJoin = NSExpression(forConstantValue: "round")
layer.lineCap = NSExpression(forConstantValue: "round")
layer.lineColor = NSExpression(forConstantValue: UIColor.systemBlue)
// The line width should gradually increase based on the zoom level.
layer.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",[14: 5, 18: 20])
style.addLayer(layer)
// Update polyline - remove if an animated polyline is desired
let polyline = MGLPolylineFeature(coordinates: allCoordinates, count: UInt(allCoordinates.count))
polylineSource?.shape = polyline
}
func animatePolyline() {
currentIndex = 1
// Start a timer that will simulate adding points to our polyline. This could also represent coordinates being added to our polyline from another source, such as a CLLocationManagerDelegate.
timer = Timer.scheduledTimer(timeInterval: 0.05, target: self, selector: #selector(tick), userInfo: nil, repeats: true)
}
@objc func tick() {
if currentIndex > allCoordinates.count {
timer?.invalidate()
timer = nil
return
}
// Create a subarray of locations up to the current index.
let coordinates = Array(allCoordinates[0..<currentIndex])
// Update our MGLShapeSource with the current locations.
updatePolylineWithCoordinates(coordinates: coordinates)
currentIndex += 1
}
func updatePolylineWithCoordinates(coordinates: [CLLocationCoordinate2D]) {
var mutableCoordinates = coordinates
let polyline = MGLPolylineFeature(coordinates: &mutableCoordinates, count: UInt(mutableCoordinates.count))
// Updating the MGLShapeSource’s shape will have the map redraw our polyline with the current coordinates.
polylineSource?.shape = polyline
}
}