I have a gray layer to display multiple polygons on the Mapbox map. I'm attempting to change the color of only one of them when the user clicks on it to display the "selected" the polygon. I don't want interaction, that's why I'm not using the Draw library, just to show the selected polygon.
Is there any way to do it in just one layer?? I tried adding a boolean
property called "selected" to each polygon property, but I didn't achieve to update the layer.
// Define polygons with properties
var features = [];
areas.forEach(area => features.push(turf.polygon(area.polygon, { id_area: area.id_area, name: area.name, selected: 'false' })));
features = turf.featureCollection(features);
map.on('load', function () {
// Add polygons to map
map.addSource('areas', {
'type': 'geojson',
'data': features
});
// Layer settings
map.addLayer({
'id': 'polygons',
'type': 'fill',
'source': 'areas',
'paint': {
'fill-color': [
'match',
['get', 'selected'],
'true', '#64bdbb', // if selected true, paint in blue
'#888888' // else paint in gray
],
'fill-opacity': 0.4
},
'filter': ['==', '$type', 'Polygon']]
});
});
// Click on polygon
map.on('click', 'polygons', function (e) {
if(e.features.length) {
var feature = e.features[0];
if (feature.properties.id_area == id) {
feature.properties.selected = 'true';
} else {
feature.properties.selected = 'false';
}
// How can I update the layer here to repaint polygons????
}
});
Thank you in advance!
I have a gray layer to display multiple polygons on the Mapbox map. I'm attempting to change the color of only one of them when the user clicks on it to display the "selected" the polygon. I don't want interaction, that's why I'm not using the Draw library, just to show the selected polygon.
Is there any way to do it in just one layer?? I tried adding a boolean
property called "selected" to each polygon property, but I didn't achieve to update the layer.
// Define polygons with properties
var features = [];
areas.forEach(area => features.push(turf.polygon(area.polygon, { id_area: area.id_area, name: area.name, selected: 'false' })));
features = turf.featureCollection(features);
map.on('load', function () {
// Add polygons to map
map.addSource('areas', {
'type': 'geojson',
'data': features
});
// Layer settings
map.addLayer({
'id': 'polygons',
'type': 'fill',
'source': 'areas',
'paint': {
'fill-color': [
'match',
['get', 'selected'],
'true', '#64bdbb', // if selected true, paint in blue
'#888888' // else paint in gray
],
'fill-opacity': 0.4
},
'filter': ['==', '$type', 'Polygon']]
});
});
// Click on polygon
map.on('click', 'polygons', function (e) {
if(e.features.length) {
var feature = e.features[0];
if (feature.properties.id_area == id) {
feature.properties.selected = 'true';
} else {
feature.properties.selected = 'false';
}
// How can I update the layer here to repaint polygons????
}
});
Thank you in advance!
Share Improve this question asked Feb 6, 2020 at 13:28 nashnash 5331 gold badge5 silver badges21 bronze badges1 Answer
Reset to default 7You can use a click event and feature states to change a polygon's color when selected. I put together an example of this in a CodePen here, which is based on this example from Mapbox. Code:
mapboxgl.accessToken = 'pk.eyJ1IjoicGxtYXBib3giLCJhIjoiY2s3MHkzZ3VnMDFlbDNmbzNiajN5dm9lOCJ9.nbbtDF54HIXo0mCiekVxng';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-100.486052, 37.830348],
zoom: 2
});
var clickedStateId = null;
map.on('load', function() {
map.addSource('states', {
'type': 'geojson',
'data':
'https://docs.mapbox./mapbox-gl-js/assets/us_states.geojson'
});
// The feature-state dependent fill-color expression will render the click effect
// when a feature's click state is set to true.
map.addLayer({
'id': 'state-fills',
'type': 'fill',
'source': 'states',
'layout': {},
'paint': {
'fill-color': [
'case',
['boolean', ['feature-state', 'click'], false],
'#64bdbb',
'#888888'
]
}
});
map.addLayer({
'id': 'state-borders',
'type': 'line',
'source': 'states',
'layout': {},
'paint': {
'line-color': '#627BC1',
'line-width': 1
}
});
// When the user clicks we'll update the
// feature state for the feature under the mouse.
map.on('click', 'state-fills', function(e) {
if (e.features.length > 0) {
if (clickedStateId) {
map.setFeatureState(
{ source: 'states', id: clickedStateId },
{ click: false }
);
}
clickedStateId = e.features[0].id;
map.setFeatureState(
{ source: 'states', id: clickedStateId },
{ click: true }
);
}
});
});
Disclaimer: I work at Mapbox