Skip to main content

Buildings on terrain

Common fill-extrusion layers can be combined with setTerrain. GeoJSON and MVT share the building mesh. Each Polygon is rigidly elevated to the displayed terrain triangle height at its footprint bounding-box center; MultiPolygon parts are handled independently. Roofs, exterior/courtyard walls and colors stay intact. Missing terrain withholds the corresponding building part rather than inventing zero ground.

// Supply your own raster-dem terrain source and polygon buildings source.
map.setTerrain({ source: 'terrain', exaggeration: 2 });
map.addLayer({ id: 'buildings', type: 'fill-extrusion', source: 'buildings',
  paint: { 'fill-extrusion-height': ['get', 'height'],
    'fill-extrusion-base': 0, 'fill-extrusion-color': '#22c55e' }
});
map.setPitch(45);
await map.sqs.flush({ render: true });
console.log(await map.queryRenderedFeatures({ layers: ['buildings'] }));

Height and base are real metres above ground. Terrain exaggeration affects ground only. Rendering and queries use the same ground surface and elevated roof/wall mesh. Property/state/visibility updates and terrain disable/restore retain the common interfaces. Raw browser SDK callers use view.flush(); native libraries send the same arguments through common source/layer/terrain JSON entry points. ABI is unchanged.

Buildings are rigid, using one foundation elevation; sloped-ground conformity and avoiding higher terrain are not guaranteed. Foundation clipping, globe and complete depth-occlusion filtering across all layers remain pending. Existing budgets remain500K vertices/1.5M indices per geometry and500K query triangles. Physical phones and Windows/macOS are verified separately.