Add multiple shapes from a single shape source

Download metro-line.geojson and add it to your project.

For more information on styling data at runtime, see our Information for style authors guide.

import Mapbox
class ViewController: UIViewController, MGLMapViewDelegate {
var mapView: MGLMapView!
override func viewDidLoad() {
mapView = MGLMapView(frame: view.bounds)
mapView.styleURL = MGLStyle.lightStyleURL
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.tintColor = .darkGray
mapView.setCenter(CLLocationCoordinate2D(latitude: 38.897435, longitude: -77.039679), zoomLevel: 12, animated: false)
mapView.delegate = self
func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) {
// Parse the GeoJSON data. {
guard let url = Bundle.main.url(forResource: "metro-line", withExtension: "geojson") else {
preconditionFailure("Failed to load local GeoJSON file")
guard let data = try? Data(contentsOf: url) else {
preconditionFailure("Failed to decode GeoJSON file")
DispatchQueue.main.async {
try? self.drawShapeCollection(data: data)
func drawShapeCollection(data: Data) throws {
guard let style = else { return }
// Use [MGLShape shapeWithData:encoding:error:] to create a MGLShapeCollectionFeature from GeoJSON data.
guard let feature = try? MGLShape(data: data, encoding: String.Encoding.utf8.rawValue) as? MGLShapeCollectionFeature else {
fatalError("Could not cast to specified MGLShapeCollectionFeature")
// Create source and add it to the map style.
let source = MGLShapeSource(identifier: "transit", shape: feature, options: nil)
// Create station style layer.
let circleLayer = MGLCircleStyleLayer(identifier: "stations", source: source)
// Use a predicate to filter out non-points.
circleLayer.predicate = NSPredicate(format: "TYPE = 'Station'")
circleLayer.circleColor = NSExpression(forConstantValue:
circleLayer.circleRadius = NSExpression(forConstantValue: 6)
circleLayer.circleStrokeWidth = NSExpression(forConstantValue: 2)
circleLayer.circleStrokeColor = NSExpression(forConstantValue:
// Create line style layer.
let lineLayer = MGLLineStyleLayer(identifier: "rail-line", source: source)
// Use a predicate to filter out the stations.
lineLayer.predicate = NSPredicate(format: "TYPE = 'Rail line'")
lineLayer.lineColor = NSExpression(forConstantValue:
lineLayer.lineWidth = NSExpression(forConstantValue: 2)
// Add style layers to the map view's style.
style.insertLayer(lineLayer, below: circleLayer)