Reputation: 11
Using my styled Mapbox GL JS map, with multistring lines from my geojson file, when a user clicks one of the lines I need it highlighted, this part I have working using:
map.on('click', 'route', function(e) {
var features = map.queryRenderedFeatures(e.point, { layers: ['route'] });
if (!features.length) {
return;
}
if (typeof map.getLayer('selectedRoad') !== "undefined" ){
map.removeLayer('selectedRoad')
map.removeSource('selectedRoad');
}
var feature = features[0];
console.log(feature.toJSON());
map.addSource('selectedRoad', {
"type":"geojson",
"data": feature.toJSON()
});
map.addLayer({
"id": "selectedRoad",
"type": "line",
"source": "selectedRoad",
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "yellow",
"line-width": 8
}
});
Example of my geojson entries:
{"type": "FeatureCollection", "features": [{"type":"Feature","geometry":
{"type":"MultiLineString","coordinates":[[[-117.252069,32.748772],[-117.25169,32.749212],
[-117.25135,32.749608]]]},"properties":{"displaylabel":"1950-1999 GRAND
ST","sidedaytime1":"West Side Fri 7 am-10 am","sidedaytime2":"7am"}},
{"type":"Feature","geometry":{"type":"MultiLineString","coordinates":
[[[-117.25135,32.749608],[-117.250981,32.750037],[-117.250621,32.750452]]]},"properties":
{"displaylabel":"2000-2049 GRAND ST","sidedaytime1":"West Side Fri 7 am-10
am","sidedaytime2":"East Side Wed 7 am-10 am"}}
I need the user to be able to click and highlight 1 to 4 lines, and all 1 to 4 stay highlighted. Additionally, when a user 2nd clicks a highlighted line, I need it "unhighlighted. I cannot find any examples anywhere. Help is much appreciated!
Upvotes: 0
Views: 998
Reputation: 37
The easiest way to accomplish this is to attach an event handler to the layer containing these lines, and then edit the feature state when a feature is clicked. When you load the layer to the map, you can use an expression to style each feature based on its feature state. Here's how I've handled this situation before:
/*loading the layer using an expression that defines a feature's color based on the
value located in the 'click' property*/
map.on('load', function() {
map.addLayer({
'id': 'route',
'type': 'line',
'source': {/*your source data*/},
'paint': {
'line-color': [
'case',
['boolean', ['feature-state', 'click'], false],
'#0f397d',
'#2e6fd9',
]}
});
});
/*this function would then be used to change the 'click' feature state
when the feature is clicked on*/
map.on('click', 'route', function (e) {
var features = map.queryRenderedFeatures(e.point, { layers: ['route'] });
for (var i = 0; i < features.length; i++) {
map.setFeatureState({source: 'route', id: features[i].id}, {click: true});
}
});
The above code will set any clicked feature to have a 'click' feature state of true, which will then style it using the second color listed in the expression. If you want to change it back on another click, you can set it back to false.
Upvotes: 3