PruneCluster icon indicating copy to clipboard operation
PruneCluster copied to clipboard

Force decluttering of markers at a certain zoom level

Open pmusaraj opened this issue 9 years ago • 15 comments

I'm coming to PruneCluster from Leaflet markerCluster, and the performance is much, much better. What I am building is a simple mobile app with about 1000 markers, and the difference in performance is very noticeable on phones/tablets.

But there is one feature of markerCluster that I can't yet find a solution to in PruneCluster: the disableClusteringAtZoom option. That is, I would like to be able to have the map disable clustering after a certain zoom level.

How would I go about doing this?

pmusaraj avatar Feb 17 '15 02:02 pmusaraj

Hello,

A disableClusteringAtZoom feature is not available. The easiest solution is removing the PruneCluster layer and adding the Leaflet markers directly.

It's also possible to do that in the ProcessView method, but this method is already huge so I think a separate component is better.

I will add this feature on the TODO list, I think it can be useful in some cases. But if you want something working before a long time, I suggest removing the PruneCluster layer and adding the leaflet markers directly when zoomed. It's not the fastest solution, but with 1000 markers it should be ok.

fungiboletus avatar Feb 17 '15 12:02 fungiboletus

:+1: I'd also need this feature already with two projects.

simison avatar Feb 17 '15 13:02 simison

You can also reduce the size of the grid when zoomed. I will try this approach first.

If you really want to display all the markers on the map, you might need something like this : https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet

fungiboletus avatar Feb 17 '15 15:02 fungiboletus

Thanks @yellowiscool for the quick feedback. Reducing the size of the grid can probably do this, that's what I was thinking at first.

My scenario is the following: I have a search tool on the map, once users click on a search result, I map.setView() to center the map to the selected marker and zoom to it. In most cases, this works fine, but in some, the selected marker is inside of a cluster with 2 or 3 markers.

Which makes me think of yet a different approach: maybe disable clusters if there are less than x markers in it (2 or 3 in my case)?

pmusaraj avatar Feb 17 '15 15:02 pmusaraj

Yes selecting a marker is not satisfactory in the current version. In my application when a marker is selected I remove (or filter) it from PruneCluster and add it again directly as a Leaflet object. But it's not perfect because it can hide the cluster just below.

I need to think about how to select a marker easily, even when it's inside a cluster. The selected marker should also be draggable, be able to open popups…

Disabling the cluster when it has 2 or 3 markers is a good idea, but it's not a perfect solution. If you still have a cluster with a small grid and a high zoom level, it's often because the markers are exactly at the same position or are very close. Also the current algorithm doesn't allow this without a big performance cost or a lot of changes (everything is a cluster in the current implementation).

fungiboletus avatar Feb 17 '15 15:02 fungiboletus

Quick update: for now, I have fixed this issue by changing the maxZoom on the map. It used be set at 19, which was a little too deep, and now it's at 17. PruneCluster respects it. Some markers that are too close, get the spiderfied treatment.

pmusaraj avatar Feb 25 '15 20:02 pmusaraj

+1. I'd really like to see this feature too.

turbobuilt avatar Mar 12 '15 21:03 turbobuilt

+1 ;)

valerio-bozzolan avatar Mar 12 '15 21:03 valerio-bozzolan

First of all, you may want to set zoomAnimation to false to avoid evil users clog your app. Then:

map.on('zoomend', function(){
 var oldsize = pruneCluster.Cluster.Size;
 pruneCluster.Cluster.Size = (map.getZoom()>= mymaxclusterzoom)? -1 : oldsize;
 pruneCluster.ProcessView(); // looks like it works OK without this line
})

AbelVM avatar May 14 '15 09:05 AbelVM

Does it work for you? You set -1 as grid size, which is a value I haven't think about when I wrote the algorithm. I quickly tried it and it doesn't work with 100 random elements.

fungiboletus avatar May 14 '15 17:05 fungiboletus

You are right, old value is overwritten this way. My project uses a hardcoded value of 120 (default one), and it works fine this way:

map.on('zoomend', function(){
 pruneCluster.Cluster.Size = (map.getZoom()>= mymaxclusterzoom)? -1 : 120;
 pruneCluster.ProcessView(); // looks like it works OK without this line
})

Tried to post a more generic version of it and messed the code :grimacing:

To use a user selected size, we should store the value outside the event function:

// somewhere else
 mysize = 120;

map.on('zoomend', function(){
 pruneCluster.Cluster.Size = (map.getZoom()>= mymaxclusterzoom)? -1 : mysize;
 pruneCluster.ProcessView(); // looks like it works OK without this line
})

AbelVM avatar May 14 '15 18:05 AbelVM

Here's a similar workaround that works as long as there are no clusters with exactly the same latlng.

var decluster = false;
function clusterMarkers() {
    if(pruneCluster){
        pruneCluster.Cluster.Size = .0000000000001;
        pruneCluster.Cluster.Margin = .000000000001;
        pruneCluster.ProcessView();
    }
}
function declusterMarkers() {
    if(pruneCluster){
        pruneCluster.Cluster.Size = 35;
        pruneCluster.Cluster.Margin = 10;
        pruneCluster.ProcessView();
    }
}

leafletMainMap.on('zoomend', function () {
    if (leafletMainMap.getZoom() > 9) {
        if (decluster === false) {
            clusterMarkers()
            decluster = true;
        }
    }else{
        if (decluster === true) {
            declusterMarkers()
            decluster = false;
        }
    }
});

turbobuilt avatar May 15 '15 18:05 turbobuilt

@AbelVM solution isnt suitable for large number of markers. When going from declustered to clustered views, there's a noticable lag since a lot of markers are being rendered while the switch hasnt been made yet.

kasparsklavins avatar Jun 09 '16 06:06 kasparsklavins

Looking forward for this nice feature.

TimoRuetten avatar Dec 02 '16 13:12 TimoRuetten

any news on this feature?

dtheb avatar May 27 '17 01:05 dtheb