Add a new clip layer to remove 3D content from the map.
This feature is available in Mapbox GL JS v3. Learn how to migrate in our migrate to v3 guide
Note that this is an experimental feature which is under development and is prone to change.
This example uses clip
layer to remove the 3D buildings from the Mapbox Standard style and replaces them with a new custom building model.
It uses addSource
to add a GeoJSON
source which is used to determine which regions of the map need to be removed by the clip
layer.
{
"id": "eraser",
"type": "geojson",
"data": {
// source data
}
}
Next the clip
layer is added using addLayer
. Note that clip-layer-types
layout property is used to specify that symbols and models (for example trees and wind turbines) also need to be removed.
{
"id": "eraser",
"type": "clip",
"source": "eraser",
"layout": {
"clip-layer-types": ["symbol", "model"]
}
}
Finally a custom building model is added in the same place by specifying an appropriate GeoJSON source using addSource
and a model
layer.
- It requires a source and can be also used with a vector source.
- The
clip-layer-types
property can be used to configure it such that it also removes trees, wind turbines and symbols from the map. - It only removes content from layers that are located below it in the style layer stack.
- It can be activated at a certain zoom range using layer
minzoom
andmaxzoom
.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add a new clip layer to remove 3D content from the map.</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v3.6.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.6.0/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
const map = (window.map = new mapboxgl.Map({
container: 'map',
center: [-0.126326, 51.533582],
zoom: 15.27,
pitch: 42,
bearing: -50,
style: 'mapbox://styles/mapbox/standard',
minZoom: 15,
maxZoom: 16
}));
map.on('style.load', () => {
// set the light preset to be in dusk mode.
map.setConfigProperty('basemap', 'lightPreset', 'dusk');
map.addSource('eraser', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'properties': {},
'geometry': {
'coordinates': [
[
[-0.12573446384880071, 51.53222253720682],
[-0.12458889852425159, 51.53219470021111],
[-0.12358091771250201, 51.53492205161518],
[-0.12701761368793996, 51.53391996847543],
[-0.12573446384880071, 51.53222253720682]
]
],
'type': 'Polygon'
}
}
]
}
});
map.addSource('model', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {
'model-uri':
'https://docs.mapbox.com/mapbox-gl-js/assets/tower.glb'
},
'geometry': {
'coordinates': [-0.12501974, 51.5332374],
'type': 'Point'
}
}
});
map.addLayer({
'id': 'eraser',
'type': 'clip',
'source': 'eraser',
'layout': {
'clip-layer-types': ['symbol', 'model']
}
});
map.addLayer({
'id': 'tower',
'type': 'model',
'source': 'model',
'minzoom': 15,
'layout': {
'model-id': ['get', 'model-uri']
},
'paint': {
'model-opacity': 1,
'model-rotation': [0.0, 0.0, 35.0],
'model-scale': [0.8, 0.8, 1.2],
'model-color-mix-intensity': 0,
'model-cast-shadows': true,
'model-emissive-strength': 0.8
}
});
});
</script>
</body>
</html>
import React, { useEffect, useRef } from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
const MapboxExample = () => {
const mapContainerRef = useRef();
const mapRef = useRef();
useEffect(() => {
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
mapRef.current = new mapboxgl.Map({
container: mapContainerRef.current,
center: [-0.126326, 51.533582],
zoom: 15.27,
pitch: 42,
bearing: -50,
style: 'mapbox://styles/mapbox/standard',
minZoom: 15,
maxZoom: 16
});
mapRef.current.on('style.load', () => {
mapRef.current.setConfigProperty('basemap', 'lightPreset', 'dusk');
mapRef.current.addSource('eraser', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
coordinates: [
[
[-0.12573446384880071, 51.53222253720682],
[-0.12458889852425159, 51.53219470021111],
[-0.12358091771250201, 51.53492205161518],
[-0.12701761368793996, 51.53391996847543],
[-0.12573446384880071, 51.53222253720682]
]
],
type: 'Polygon'
}
}
]
}
});
mapRef.current.addSource('model', {
type: 'geojson',
data: {
type: 'Feature',
properties: {
'model-uri': 'https://docs.mapbox.com/mapbox-gl-js/assets/tower.glb'
},
geometry: {
coordinates: [-0.12501974, 51.5332374],
type: 'Point'
}
}
});
mapRef.current.addLayer({
id: 'eraser',
type: 'clip',
source: 'eraser',
layout: {
'clip-layer-types': ['symbol', 'model']
}
});
mapRef.current.addLayer({
id: 'tower',
type: 'model',
source: 'model',
minzoom: 15,
layout: {
'model-id': ['get', 'model-uri']
},
paint: {
'model-opacity': 1,
'model-rotation': [0.0, 0.0, 35.0],
'model-scale': [0.8, 0.8, 1.2],
'model-color-mix-intensity': 0,
'model-cast-shadows': true,
'model-emissive-strength': 0.8
}
});
});
}, []);
return <div id="map" style={{ height: '100%' }} ref={mapContainerRef} />;
};
export default MapboxExample;