2

i have to change the color or borders of buildings on click.

HTML & JS

Like the examples to hover countries, but with click and not countries -> buildings.

If it's easier with another plugin, please say so. 3D is not a 'must have'.

My Code:

<script>
mapboxgl.accessToken = 'hidden';
var map = new mapboxgl.Map({
    style: 'mapbox://styles/mapbox/light-v9',
    center: [7.3337859, 50.8403206],
    zoom: 19.8,
    pitch: 60,
    bearing: -70,
    hash: true,
    container: 'map'
});

// The 'building' layer in the mapbox-streets vector source contains building-height
// data from OpenStreetMap.
map.on('load', function() {
    // Insert the layer beneath any symbol layer.
    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': '3d-buildings',
        'source': 'composite',
        'source-layer': 'building',
        'filter': ['==', 'extrude', 'true'],
        'type': 'fill-extrusion',
        'minzoom': 15,
        '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': .6
        }
    }, labelLayerId);

    map.on('click', '3d-buildings', function(e) {
        console.log(e.features[0]);
        //map.setPaintProperty('3d-buildings', 'fill-extrude-color', '#FF0000');
        map.setPaintProperty('3d-buildings', 'fill-color', '#faafee');
    });
});

Thanks :)

2
  • Can you add a jsfiddle.net example? Commented Apr 20, 2018 at 7:26
  • Yes :) jsfiddle.net/dtttemyo Commented Apr 20, 2018 at 7:38

1 Answer 1

5

You need to add a layer on which to display the selected buildings. For example:

  map.addSource('currentBuildings', {
    type: 'geojson',
    data: {
      "type": "FeatureCollection",
      "features": []
    }
  });
  map.addLayer({
    "id": "highlight",
    "source": "currentBuildings",
    'type': 'line',
    'minzoom': 15,
    'paint': {
        'line-color': '#f00',
      'line-width': 3
    }
  }, labelLayerId);
  map.on('click', '3d-buildings', function(e) {
    map.getSource('currentBuildings').setData({
      "type": "FeatureCollection",
      "features": e.features[0]]
    });
  });

[ https://jsfiddle.net/o50vy8jc/ ]

Sign up to request clarification or add additional context in comments.

1 Comment

This answer pointed me in the right direction, thank you. However, when setting the data, the "features" value should read e.features without the index and additional square bracket, as in the jsfiddle example. Cheers.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.