Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapbox GL 3D building style dynamically change

I was wondering if the "fill-color" of the 3D building can be dynamically changed based on certain events, such as mouseMoveEvent when hover over a building, highlight the 3D building.

like image 798
ethan Avatar asked Dec 06 '25 08:12

ethan


1 Answers

Try this

map.on('load', function () {
        var layers = map.getStyle().layers;

        var labelLayerId;
        for (var i = 0; i < layers.length; i++) {
          if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
            labelLayerId = layers[i].id;
            break;
          }
        }
        map.addLayer(
          {
            'id': '3dbuildings',
            'source': 'composite',
            'source-layer': 'building',
            'filter': ['==', 'extrude', 'true'],
            'type': 'fill-extrusion',
            'minzoom': 15,
            pitch: 60,
            bearing: -60,
            'paint': {
              'fill-extrusion-color': '#aaa',

              // use an 'interpolate' expression to add a smooth transition effect to the
              // buildings as the user zooms in
              '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
        );

        map.addSource('currentBuildings', {
          type: 'geojson',
          data: {
            "type": "FeatureCollection",
            "features": []
          }
        });

        map.addLayer(
          {
            'id': 'highlight',
            'source': 'currentBuildings',
            'filter': ['==', 'extrude', 'true'],
            'type': 'fill-extrusion',
            'minzoom': 15,
            pitch: 60,
            bearing: -60,

            'paint': {
              'fill-extrusion-color': '#f00',
              // use an 'interpolate' expression to add a smooth transition effect to the
              // buildings as the user zooms in
              'fill-extrusion-height': [
                'interpolate',
                ['linear'],
                ['zoom'],
                4,
                0,
                15.05,
                ['get', 'height']
              ],
              'fill-extrusion-base': [
                'interpolate',
                ['linear'],
                ['zoom'],
                4,
                0,
                15.05,
                ['get', 'min_height']
              ],
              'fill-extrusion-opacity': 0.6
            }
          },
          labelLayerId
        );


        map.on('click', '3dbuildings', function (e) {
          map.getSource('currentBuildings').setData({
            "type": "FeatureCollection",
            "features": e.features
          });
        });
        map.on('mousemove', '3dbuildings', function (e) {
          map.getSource('currentBuildings').setData({
            "type": "FeatureCollection",
            "features": e.features
          });
        });
      });
like image 155
Iqbal Avatar answered Dec 10 '25 01:12

Iqbal