← Files MapboxARCHIVED FILE

skills/mapbox-data-visualization-patterns/references/3d-extrusions.md

2.9 KB · Sep 30, 2026 · 23:11 UTC

↓ Download file

# 3D Extrusions

**Best for:** Building heights, elevation data, volumetric representation

**Pattern:** Extrude polygons based on data

> **Note:** The example below works with **classic styles only** (`streets-v12`, `dark-v11`, `light-v11`, etc.). The **Mapbox Standard style** includes 3D buildings with much greater detail by default.

```javascript
map.on('load', () => {
  // Insert the layer beneath any symbol layer for proper ordering
  const layers = map.getStyle().layers;
  const labelLayerId = layers.find((layer) => layer.type === 'symbol' && layer.layout['text-field']).id;

  // Add 3D buildings from basemap
  map.addLayer(
    {
      id: 'add-3d-buildings',
      source: 'composite',
      'source-layer': 'building',
      filter: ['==', 'extrude', 'true'],
      type: 'fill-extrusion',
      minzoom: 15,
      paint: {
        'fill-extrusion-color': '#aaa',
        // Smoothly transition height on zoom
        'fill-extrusion-height': ['interpolate', ['linear'], ['zoom'], 15, 0, 15.05, ['get', 'height']],
        'fill-extrusion-base': ['interpolate', ['linear'], ['zoom'], 15, 0, 15.05, ['get', 'min_height']],
        'fill-extrusion-opacity': 0.6
      }
    },
    labelLayerId
  );

  // Enable pitch and bearing for 3D view
  map.setPitch(45);
  map.setBearing(-17.6);
});
```

**Using Custom Data Source:**

```javascript
map.on('load', () => {
  // Add your own buildings data
  map.addSource('custom-buildings', {
    type: 'geojson',
    data: 'https://example.com/buildings.geojson'
  });

  // Add 3D buildings layer
  map.addLayer({
    id: '3d-custom-buildings',
    type: 'fill-extrusion',
    source: 'custom-buildings',
    paint: {
      // Height in meters
      'fill-extrusion-height': ['get', 'height'],
      // Base height if building on terrain
      'fill-extrusion-base': ['get', 'base_height'],
      // Color by building type or height
      'fill-extrusion-color': [
        'interpolate',
        ['linear'],
        ['get', 'height'],
        0,
        '#fafa6e',
        50,
        '#eca25b',
        100,
        '#e64a45',
        200,
        '#a63e3e'
      ],
      'fill-extrusion-opacity': 0.9
    }
  });
});
```

**Data-Driven 3D Heights:**

```javascript
// Population density visualization
'fill-extrusion-height': [
  'interpolate',
  ['linear'],
  ['get', 'density'],
  0, 0,
  1000, 500,    // 1000 people/sq mi = 500m height
  10000, 5000
]

// Revenue visualization (scale for visibility)
'fill-extrusion-height': [
  '*',
  ['get', 'revenue'],
  0.001  // Scale factor
]
```

## Anti-pattern: constant extrusion height

```javascript
// BAD — flat slabs are not data-driven 3D buildings
'fill-extrusion-height': 40

// GOOD — expression from feature properties
'fill-extrusion-height': ['get', 'height']
```

Agents often paste a constant height to “make 3D appear.” Prefer `['get', 'height']` (or an interpolate expression) whenever the challenge asks for data-driven extrusions.

SHA-256: 7e36a3d3e736df12f75081f7bd12cbbb69381e46ecb0b91d5a317e6d9e08998e