I have an interactive map in which each marker is a location, and each radio button filters those locations by region. By default, the markers are grouped by clusters.
Tha map has :
- an interactive list. When an item in the list is clicked, the map zooms in on the corresponding marker and vice versa.
- A filter box where each radio button filters the map by region.
This is working great after help from @TomazicM.
What I'm trying to do now: I try to adapt the code of the tutorial Filter features within map view of Mapbox, which uses queryRenderedFeatures to restrict a list of features in a vector tile layer to only return those that are visible in the map view.
1- When targeting a region throught the filters (radio buttons), I want the list in the left sidebar to be updated by listing only the locations of the targeted region. So for example, if I click on radio button "region 1", only the locations of region 1 are listed on the left sidebar, and so on. When I click on "All", all locations are listed in the sidebar.
Here is my (broken) fiddle And here is the original code
What I tried
1 - I tried to adapt the Mapbox tutorial code on my small project, by simply replacing the names of the variables.
So I just added, outside the on(load) function :
function normalize(string) {
return string.trim().toLowerCase();
}
function getUniqueFeatures(features, comparatorProperty) {
const uniqueIds = new Set();
const uniqueFeatures = [];
for (const feature of features) {
const id = feature.properties[comparatorProperty];
if (!uniqueIds.has(id)) {
uniqueIds.add(id);
uniqueFeatures.push(feature);
}
}
return uniqueFeatures;
}
let airports = [];
Inside the on(load)function I added :
map.on('movestart', () => {
map.setFilter(clustersId, ['has', 'region']);
});
map.on('moveend', () => {
const features = map.queryRenderedFeatures({ layers: clustersId });
if (features) {
const uniqueFeatures = getUniqueFeatures(features, 'name');
buildLocationList(uniqueFeatures);
airports = uniqueFeatures;
}
});
map.on('mousemove', clustersId, (e) => {
map.getCanvas().style.cursor = 'pointer';
const feature = e.features[0];
popup
.setLngLat(feature.geometry.coordinates)
.setText(
`${feature.properties.name} (${feature.properties.region})`
)
.addTo(map);
});
map.on('mouseleave', clustersId, () => {
map.getCanvas().style.cursor = '';
popup.remove();
})