Skip to content

Display buildings in 3D

Use extrusions to display buildings' height in 3D.

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <title>Display buildings in 3D</title>
    <meta property="og:description" content="Use extrusions to display buildings' height in 3D." />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/trackasia-gl.css" />
    <script src="https://unpkg.com/[email protected]/dist/trackasia-gl.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
      }

      html,
      body,
      #map {
        height: 100%;
      }
    </style>
  </head>

  <body>
    <div id="map"></div>
    <script>
      const map = new trackasiagl.Map({
        style: 'https://maps.track-asia.com/styles/v1/streets.json?key=public_key',
        center: {lng: 106.721196, lat:10.792019},
        zoom: 16.5,
        pitch: 45,
        bearing: -17.6,
        container: 'map',
        canvasContextAttributes: { antialias: true }
      });

      // The 'building' layer in the streets vector source contains building-height
      // data from OpenStreetMap.
      map.on('load', () => {
        // Insert the layer beneath any symbol layer.
        const layers = map.getStyle().layers;

        let labelLayerId;
        for (let i = 0; i < layers.length; i++) {
          if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
            labelLayerId = layers[i].id;
            break;
          }
        }

        map.addLayer(
          {
            'id': '3d-buildings-example',
            'source': 'base',
            'source-layer': 'building',
            'type': 'fill-extrusion',
            'minzoom': 15,
            'filter': ['!=', ['get', 'hide_3d'], true],
            'paint': {
              'fill-extrusion-color': [
                'interpolate',
                ['linear'],
                ['get', 'height'], 0, 'lightgray', 200, 'royalblue', 400, 'lightblue'
              ],
              'fill-extrusion-height': [
                'interpolate',
                ['linear'],
                ['zoom'],
                15,
                0,
                16,
                ['get', 'height']
              ],
              'fill-extrusion-base': ['case',
                ['>=', ['get', 'zoom'], 16],
                ['get', 'min_height'], 0
              ]
            }
          },
          labelLayerId
        );
      });
    </script>

  </body>

</html>