Leaflet.markercluster

repository·master·Indexed 26 days ago

https://github.com/leaflet/leaflet.markercluster

A plugin for the Leaflet maps library that provides animated marker clustering functionality to manage large numbers of markers by grouping them into clusters based on proximity. Version 1.5.4 includes features such as custom cluster icons via iconCreateFunction, spiderfy animations for overlapping markers, and chunked loading for high-performance bulk marker additions.

Tokens
3K
Snippets
11
Records
18
Agent score
38%

What's inside leaflet.markercluster

  1. Install Leaflet.markercluster

    master

    Include the plugin CSS and JS files on your page after Leaflet files. You can install via npm, use a CDN, or download the release manually.

    Files required from the dist folder:

    • MarkerCluster.css
    • MarkerCluster.Default.css (only if you are NOT using a custom iconCreateFunction)
    • leaflet.markercluster.js (or leaflet.markercluster-src.js for the non-minified version)

    Installation methods:

    • npm: npm install leaflet.markercluster
    • unpkg CDN: https://unpkg.com/leaflet.markercluster@1.4.1/dist/
    npm install leaflet.markercluster
  2. Configure MarkerClusterGroup Options

    master

    You can pass an options object to L.markerClusterGroup() to customize behavior.

    Commonly disabled defaults:

    • spiderfyOnMaxZoom: Whether to spiderfy clusters at the bottom zoom level.
    • showCoverageOnHover: Whether to show the bounds of markers when mousing over a cluster.
    • zoomToBoundsOnClick: Whether to zoom to cluster bounds on click.
    var markers = L.markerClusterGroup({
    	spiderfyOnMaxZoom: false,
    	showCoverageOnHover: false,
    	zoomToBoundsOnClick: false
    });
  3. Basic Usage of MarkerClusterGroup

    master

    To use the plugin, create a new L.markerClusterGroup, add your markers to it using addLayer(), and then add the group to your map.

    var markers = L.markerClusterGroup();
    markers.addLayer(L.marker(getRandomLatLng(map)));
    ... Add more layers ...
    map.addLayer(markers);
  4. Refresh cluster icons

    master

    If you have customized cluster icons based on marker data and that data changes, use refreshClusters() to force a re-draw. This method accepts several types of arguments:

    • No arguments: Forces all cluster icons in the group to re-draw.
    • Array or Mapping: refreshClusters([marker1, marker2]) or refreshClusters({id: marker}) forces only the parent clusters of the specified markers to re-draw.
    • L.LayerGroup: Forces re-draw for all markers within the provided group (ensure the group contains only markers already in the MarkerClusterGroup).
    • Single Marker: Refreshes the parent cluster of the specific marker.
    markers.refreshClusters();
    markers.refreshClusters([myMarker0, myMarker33]);
    markers.refreshClusters({id_0: myMarker0, id_any: myMarker33});
    markers.refreshClusters(myLayerGroup);
    markers.refreshClusters(myMarker);
  5. Zoom to a cluster's bounds

    master

    When handling cluster events, you can easily zoom the map to the area covered by the cluster using cluster.zoomToBounds(options). The options argument accepts any standard Leaflet fitBounds options (e.g., padding).

    markers.on('clusterclick', function (a) {
    	// a.layer is the cluster
    	a.layer.zoomToBounds({padding: [20, 20]});
    });
  6. Listen to cluster events

    master

    Standard Leaflet events like click or mouseover apply to individual markers. To listen for events on the clusters themselves, prefix the event name with cluster. For example, use clusterclick, clustermouseover, or clustermouseout.

    When a cluster event is triggered, a.layer refers to the cluster object.

    markers.on('click', function (a) {
    	console.log('marker ' + a.layer);
    });
    
    markers.on('clusterclick', function (a) {
    	// a.layer is actually a cluster
    	console.log('cluster ' + a.layer.getAllChildMarkers().length);
    });
  7. Customise Clustered Marker Icons

    master

    Provide an iconCreateFunction to define how cluster icons look. The function receives a cluster object (a MarkerCluster instance). You can use cluster.getChildCount() or cluster.getAllChildMarkers() to determine the icon content.

    Note: If you use a custom icon function, you do not need to include MarkerCluster.Default.css.

    var markers = L.markerClusterGroup({
    	iconCreateFunction: function(cluster) {
    		return L.divIcon({ html: '<b>' + cluster.getChildCount() + '</b>' });
    	}
    });
  8. Add and remove markers in bulk

    master

    While addLayer, removeLayer, and clearLayers are supported for single operations, use addLayers and removeLayers for bulk operations. These methods accept an array of markers and are more efficient.

    Note on Layer Groups: These methods extract non-group layer children from LayerGroup types, even if deeply nested. However, the LayerGroup itself is not added to the MarkerClusterGroup; only its non-group child layers are. Consequently, hasLayer will return true for child layers but false for the parent LayerGroup type.

  9. Update marker icon options and refresh clusters

    master

    The plugin extends L.Marker with refreshIconOptions(options, [triggerRefresh]).

    • options: The new icon options mapping.
    • triggerRefresh (optional): A boolean. If true, it immediately triggers a refreshCluster on the parent MarkerClusterGroup for that specific marker.

    For bulk updates, it is more efficient to loop through markers using refreshIconOptions and then call markerClusterGroup.refreshClusters(markersArray) once at the end.

    // Bulk update pattern
    for (i in markersSubArray) {
    	markersSubArray[i].refreshIconOptions(newOptionsMappingArray[i]);
    }
    markers.refreshClusters(markersSubArray);
    
    // Single marker update with immediate parent refresh
    myMarker.refreshIconOptions(optionsMap, true); 
  10. Get cluster bounds and convex hull

    master

    Clusters provide methods to query their spatial extent:

    • getBounds(): Returns the LatLngBounds of the cluster.
    • getConvexHull(): Returns the bounding convex polygon of the cluster.

    Example of drawing the convex hull as a Leaflet polygon:

    markers.on('clusterclick', function (a) {
    	map.addLayer(L.polygon(a.layer.getConvexHull()));
    });
  11. Get the visible parent of a marker

    master

    Use getVisibleParent(marker) to retrieve the marker itself or the cluster it is currently contained in that is visible on the map. If the marker and its parent clusters are not currently visible (e.g., they are outside the current map viewport), this method returns null.

    var visibleOne = markerClusterGroup.getVisibleParent(myMarker);
    console.log(visibleOne.getLatLng());
  12. Customise Spiderfy Shape Positions

    master

    Override the default circular spiderfy shape by providing a spiderfyShapePositions function. This function should return an array of points.

    var markers = L.markerClusterGroup({
    	spiderfyShapePositions: function(count, centerPt) {
                    var distanceFromCenter = 35,
                        markerDistance = 45,
                        lineLength = markerDistance * (count - 1),
                        lineStart = centerPt.y - lineLength / 2,
                        res = [],
                        i;
    
                    res.length = count;
    
                    for (i = count - 1; i >= 0; i--) {
                        res[i] = new Point(centerPt.x + distanceFromCenter, lineStart + markerDistance * i);
                    }
    
                    return res;
                }
    });