1

I am using leaflet.markercluster plugin to show clusters on my map and getting information about each cluster on hover/click event.

What I'd like to do now is to write a method that if a user zooms or pans the map, it returns list of clusters within the current map bounds.

var option = {
    useCanvas: true,
    anchorWidth: 20,
    anchorHeight: 40,
    canvasPadding: 0.0,
    map: map
};
var clusterMarkers = L.markerClusterGroup(options, { chunkedLoading: true });

for(var i = 0;i<pakData.length;i++){
  option.lat = pakData[i][0];
  option.lng = pakData[i][1];    
var marker = TPLMaps.overlays.point(option);
clusterMarkers.addLayer(marker);

}
map.addLayer(clusterMarkers);
clusterMarkers.addEventListener('clusterclick', (e)=>{
    console.log(e); // I want list of these e.target within current bounds
})
2
  • You write "it returns list of clusters". Who/what is this "it"?
    – TomazicM
    Aug 11, 2020 at 10:16
  • Any method. I'd like to write a method which returns list of clusters within the current map bounds
    – SZ.
    Aug 11, 2020 at 12:42

2 Answers 2

4

It seems there is no exposed or internal method or array for enumerating current marker clusters. The only useful method seems to be .getVisibleParent, which returns visible parent cluster marker of given marker.

Method to obtain visible marker clusters is then simply brute force: iterate through all the markers, construct array of all visible marker clusters and check which one of those is really visible.

I this method is used within moveend event processing function, it has to be called with delay of about one second to let marker cluster processing be finished.

Code to log visible marker clusters on the console at each map move event could then look something like this (tested):

function logVisibleClusters() {
  var parent;
  var visibleClusterMarkers = [];
  var bounds = map.getBounds();
  clusterMarkers.eachLayer(function (marker) {
    parent = clusterMarkers.getVisibleParent(marker);
    if (parent && (typeof visibleClusterMarkers[parent._leaflet_id] == 'undefined')) {
      visibleClusterMarkers[parent._leaflet_id] = parent;
    }
  });
  visibleClusterMarkers.forEach(function(clusterMarker) {
    if (bounds.contains(clusterMarker._latlng)) {
      console.log('visible: ', clusterMarker);
    }
  });
}

map.on('moveend', function(e) {
  setTimeout(logVisibleClusters, 1000);
});
1
  • That's exactly what I needed. Thank you so much
    – SZ.
    Aug 12, 2020 at 12:29
2

I have just fixed this issue for myself with the following snippet. Note the use of 'zoomend' event.

map.on('zoomend', () => {
     let clusters = []
     map.eachLayer((l) => {
          if( l instanceof L.Marker && map.getBounds().contains(l.getLatLng()) )
               clusters.push(l)
     })
     // do something with clusters such as cluster[0].spiderfy() 
})

zoomend info can be found here.

2
  • zoomend instead of moveend seems like a good idea Dec 15, 2022 at 18:08
  • I feel like this should be the more accepted answer, it's not perfect because on zoom won't help here, but in terms of getting the markers currently visible and in bounds it seems more efficient than using the get Visible for all your on clustered markers.
    – Link19
    Apr 19, 2023 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.