Kerblooy
Kerblooy

Reputation: 219

How to change cluster zoom level on click with Leaflet map?

I have a Leaflet map that has zoom levels 2-7 and uses the MarkerCluster plugin.

By default I have the L.MarkerClusterGroup disable clustering at zoom level 2 (which means no clustering) and I'm trying to allow the user to click a button that then changes the clustering zoom level to 5.

Is this possible?

I know I could do it by making two markercluster groups, one that has no clustering and one that has clustering and remove/add it based on click, but that just seems incredibly messy.

Really, there's several ways to do it but they are so incredibly clunky.

Code:

Default (2 is the lowest level of zoom):

var markers = new L.MarkerClusterGroup (
    {
        disableClusteringAtZoom: 2,
        maxClusterRadius: 100,
        animateAddingMarkers: true
    });

What I want to do be able to do:

 $('#mcluster').click(function() {
    //do some code that sets the disableClusterAtZoom to 5
});

Upvotes: 5

Views: 8068

Answers (2)

ghybs
ghybs

Reputation: 53185

I know you needed a solution a few months ago, but just to let you know that I released recently a sub-plugin for Leaflet.markercluster that can perform exactly what you are looking for (with a few extra code): Leaflet.MarkerCluster.Freezable (demo here).

var mcg = L.markerClusterGroup().addTo(map),
    disableClusteringAtZoom = 2;

function changeClustering() {
    if (map.getZoom() >= disableClusteringAtZoom) {
        mcg.disableClustering(); // New method from sub-plugin.
    } else {
        mcg.enableClustering(); // New method from sub-plugin.
    }
}

map.on("zoomend", changeClustering);

$('#mcluster').click(function () {
    disableClusteringAtZoom = (disableClusteringAtZoom === 2) ? 5 : 2;
    changeClustering();
});

mcg.addLayers(arrayOfMarkers);

// Initially disabled, as if disableClusteringAtZoom option were at 2.
changeClustering();

Demo: http://jsfiddle.net/fqnbwg3q/3/

Note: in the above demo I used a refinement to make sure the markers merge with animation when clustering is re-enabled. Simply use a timeout before using enableClustering():

// Use a timeout to trigger clustering after the zoom has ended,
// and make sure markers animate.
setTimeout(function () {
    mcg.enableClustering();
}, 0);

Upvotes: 4

Kerblooy
Kerblooy

Reputation: 219

I could not find a way to disable clustering or set a new value for disableClustering at zoom, but I found a less clunky way of achieving this.

var markers = new L.LayerGroup(); //non cluster layer is added to map
markers.addTo(map);
var clusters = new L.MarkerClusterGroup (
    {
        disableClusteringAtZoom: 5,
        maxClusterRadius: 100,
        animateAddingMarkers: true
    }); //cluster layer is set and waiting to be used

var clusterStatus = 'no'; //since non cluster group is on by default, the status for cluster is set to no
 $('#mcluster').click(function( event ) {
    if(clusterStatus === 'no'){
        clusterStatus = 'yes';
        var current1 = markers.getLayers(); //get current layers in markers
        map.removeLayer(markers); // remove markers from map
        clusters.clearLayers(); // clear any layers in clusters just in case
        current1.forEach(function(item) {  //loop through the current layers and add them to clusters
            clusters.addLayer(item);
        });
        map.addLayer(clusters);
    } else {
        clusterStatus = 'no';  //we're turning off clustering here
        var current2 = clusters.getLayers(); //same code as before just reversed
        map.removeLayer(clusters);
        markers.clearLayers();
        current2.forEach(function(item) {
            markers.addLayer(item);
        });
        map.addLayer(markers);
    }
});

I'm sure there is a more elegant solution but with my still growing knowledge this is what I came up with.

Upvotes: 2

Related Questions