Skip to content

3D Buildings

Add an MLNFillExtrusionStyleLayer on the building source layer. The Street style ships this already; the other six styles draw buildings flat.

Filter on extrude. The layer carries a boolean marking the footprints meant to stand up, and the Street style filters on the same flag. Take the base from min_height, so parts that begin above ground level do not sink into the surface.

3D terrain is not available here: setTerrain() raises an UnsupportedError on MapLibre Native. See 3D Buildings and Terrain.

func mapView(_ mapView: MLNMapView, didFinishLoading style: MLNStyle) {
    guard let source = style.source(withIdentifier: "mtk") as? MLNVectorTileSource else { return }

    let buildings = MLNFillExtrusionStyleLayer(identifier: "buildings-3d", source: source)
    buildings.sourceLayerIdentifier = "building"
    buildings.minimumZoomLevel = 14
    buildings.predicate = NSPredicate(format: "extrude == YES")
    buildings.fillExtrusionColor = NSExpression(forConstantValue: UIColor(red: 0.81, green: 0.85, blue: 0.86, alpha: 1))
    buildings.fillExtrusionHeight = NSExpression(forKeyPath: "height")
    buildings.fillExtrusionBase = NSExpression(forKeyPath: "min_height")
    buildings.fillExtrusionOpacity = NSExpression(forConstantValue: 0.9)

    style.addLayer(buildings)
}

Tilt the camera, or the extrusions are only ever seen from directly above:

let camera = MLNMapCamera(
    lookingAtCenter: CLLocationCoordinate2D(latitude: 51.50222, longitude: -0.12025),
    altitude: 1200,
    pitch: 60,
    heading: 45
)
mapView.setCamera(camera, animated: false)