Skip to content

GeoJSON Layer (iOS)

Load and display GeoJSON data on a SmartMaps styled map.

MapSession required

Remember to integrate the MapSession in your app. The MapSession must be called periodically every 10 minutes while the map is active.

Add a GeoJSON Line

import UIKit
import MapLibre

class GeoJSONViewController: UIViewController, MLNMapViewDelegate {
    private var mapView: MLNMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let styleURL = URL(string:
            "https://tiles.smartmaps.cloud/styles/v1/smartmaps/light/style.json?apiKey=[INSERT API-KEY]&channel=app"
        )!

        mapView = MLNMapView(frame: view.bounds, styleURL: styleURL)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.delegate = self
        view.addSubview(mapView)
    }

    func mapView(_ mapView: MLNMapView, didFinishLoading style: MLNStyle) {
        let coordinates = [
            CLLocationCoordinate2D(latitude: 49.0069, longitude: 8.4037),
            CLLocationCoordinate2D(latitude: 49.4875, longitude: 8.4660),
            CLLocationCoordinate2D(latitude: 48.7758, longitude: 9.1829)
        ]

        let polyline = MLNPolylineFeature(coordinates: coordinates, count: UInt(coordinates.count))
        let source = MLNShapeSource(identifier: "route-source", shape: polyline, options: nil)
        style.addSource(source)

        let lineLayer = MLNLineStyleLayer(identifier: "route-layer", source: source)
        lineLayer.lineColor = NSExpression(forConstantValue: UIColor(red: 0.09, green: 0.20, blue: 0.36, alpha: 1))
        lineLayer.lineWidth = NSExpression(forConstantValue: 4)
        style.addLayer(lineLayer)

        // Fit camera to the line
        let bounds = MLNCoordinateBounds(
            sw: CLLocationCoordinate2D(latitude: 48.7758, longitude: 8.4037),
            ne: CLLocationCoordinate2D(latitude: 49.4875, longitude: 9.1829)
        )
        mapView.setVisibleCoordinateBounds(bounds, edgePadding: UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50), animated: true)
    }
}

Add a GeoJSON Polygon

func mapView(_ mapView: MLNMapView, didFinishLoading style: MLNStyle) {
    let coordinates = [
        CLLocationCoordinate2D(latitude: 48.99, longitude: 8.38),
        CLLocationCoordinate2D(latitude: 48.99, longitude: 8.44),
        CLLocationCoordinate2D(latitude: 49.02, longitude: 8.44),
        CLLocationCoordinate2D(latitude: 49.02, longitude: 8.38),
        CLLocationCoordinate2D(latitude: 48.99, longitude: 8.38)
    ]

    let polygon = MLNPolygonFeature(coordinates: coordinates, count: UInt(coordinates.count))
    let source = MLNShapeSource(identifier: "area-source", shape: polygon, options: nil)
    style.addSource(source)

    // Fill layer
    let fillLayer = MLNFillStyleLayer(identifier: "area-fill", source: source)
    fillLayer.fillColor = NSExpression(forConstantValue: UIColor(red: 0.09, green: 0.20, blue: 0.36, alpha: 0.3))
    style.addLayer(fillLayer)

    // Outline layer
    let outlineLayer = MLNLineStyleLayer(identifier: "area-outline", source: source)
    outlineLayer.lineColor = NSExpression(forConstantValue: UIColor(red: 0.09, green: 0.20, blue: 0.36, alpha: 1))
    outlineLayer.lineWidth = NSExpression(forConstantValue: 2)
    style.addLayer(outlineLayer)
}

Load GeoJSON from URL

func mapView(_ mapView: MLNMapView, didFinishLoading style: MLNStyle) {
    let url = URL(string: "https://example.com/data.geojson")!
    let source = MLNShapeSource(identifier: "remote-source", url: url, options: nil)
    style.addSource(source)

    let circleLayer = MLNCircleStyleLayer(identifier: "points-layer", source: source)
    circleLayer.circleRadius = NSExpression(forConstantValue: 6)
    circleLayer.circleColor = NSExpression(forConstantValue: UIColor(red: 0.09, green: 0.20, blue: 0.36, alpha: 1))
    style.addLayer(circleLayer)
}