Hi!
How can I cluster custom markers ? I did not find anywhere how to cluster marker like Google Maps for example
https://developers.google.com/maps/documentation/javascript/marker-clustering
That is, clustering markers and when we zoom the cluster circle transforms to markers
Thanks in advance for your help
You're either looking for https://docs.mapbox.com/mapbox-gl-js/example/cluster/, or a more advanced https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/
@mighty-nyaina and anyone else in need of help please see my answer here.
Custom HTML clusters and markers with clean-up code
https://github.com/mapbox/mapbox-gl-js/issues/4491#issuecomment-501442036
You're either looking for https://docs.mapbox.com/mapbox-gl-js/example/cluster/, or a more advanced https://docs.mapbox.com/mapbox-gl-js/example/cluster-html/
@mourner I don麓t think thats the case TBH. You are referring the cases where custom html Clusters are rendered, or clusters with layered points for markers.
but the person, and many of us, are looking into clustering custom markers. The problem with this approach is that we need to remove custom markers from the map when they are inside the layered generated cluster, and vice-versa.
@mighty-nyaina / @luchux Did (any of) you ever find a solution to this ? I'm having the same issue. I'm adding markers not based from a json, but from user entered values, which works, but I have 4 locations within 1 square kilometer, which I want to cluster, but can't seem to get it done with the provided examples.
@Beee4life I have applied this solution:
Note this code will not work as it is, is just parts to explain you the solution.
I add a Source spaces, and a cluster layer for it. I don麓t create markers as layer, but instead I traverse the map feature list and from those that are not cluster I create a Map.marker instance with custom html. I update those markers based on each zoom-end event.
map.addSource('spaces', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: parseGeoData(theSpacesData),
},
cluster: true,
clusterMaxZoom: theme.clusters.maxZoom,
clusterRadius: theme.clusters.radius,
});
map.addLayer({
id: 'clusters',
type: 'circle',
source: 'spaces',
filter: ['has', 'point_count'],
paint: {
'circle-color': theme.clusters.backgroundColor,
'circle-radius': theme.clusters.circleRadius,
},
In this way you get the "spaces" data, and the clusters calculated when you zoom in-out by the native Mapbox APIs.
Then on each map zoom in-out, recalculate custom markers. What you can do is:
export const getUniqueFeatures = (array, comparatorProperty) => {
var existingFeatureKeys = {};
var uniqueFeatures = array.filter(function(el) {
if (existingFeatureKeys[el.properties[comparatorProperty]]) {
return false;
} else {
existingFeatureKeys[el.properties[comparatorProperty]] = true;
return true;
}
});
return uniqueFeatures;
};
const features = this.map.querySourceFeatures('spaces');
let spaces = features.filter(elem => !elem.properties.cluster);
spaces = getUniqueFeatures(spaces, 'title');
Above, you get the spaces features from the map and you can filter those that are not clusters, (those inside clusters will not appear as features in the map).
From here on you can traverse the list of your unique features, and check if you need to add or remove those markers to your custom markers list (if they are already rendered, don麓t render them, if they are not render them, and those that shouldn麓t be rendered and are rendered remove from markers). Keep a list of them in a state, and you will be able to re render and remove on zooming behaviour.
space=getUniqueFeatures(). Thank, appreciate the feedback... I will try to look into it asap...
@luchux I have looked but can't wrap my head around it....
I have uploaded my code here to give you a better look at it (if you would like to)...
The map is built here and the (added) settings are set here.
Lines 51 - 103 of the js file are new/added and aren't needed for the map which is shown here.
Is there a good solution for this, I also add markers manually to the map and can't find a way to cluster them.
I think you will need to do this manually, there is no implented way of doing this inside mapbox. Atleast that's my experience with mapbox.
My solution to this was to check all the markers inside the camera and check if any of those collided with each other. Those who did was added into different "cluster"-arrays, and when all the collision has been checked, I looped through the array and added new markers between the ones that collided. At the same time i hid the markers that was now inside the cluster group. I hope this can help someone into the right direction.
Most helpful comment
Is there a good solution for this, I also add markers manually to the map and can't find a way to cluster them.