PruneCluster is a fast and realtime marker clustering library.
It's working with Leaflet as an alternative to Leaflet.markercluster.
The library is designed for large datasets or live situations. The memory consumption is keeped low and the library is fast on mobile devices, thanks to a new algorithm inspired by collision detection in physical engines.
The clusters can be updated in realtime. It's perfect for live situations.
Number of markers | First step | Update (low zoom level) | Update (high zoom level) |
---|---|---|---|
100 | instant | instant | instant |
1 000 | instant | instant | instant |
10 000 | 14ms | 3ms | 2ms |
60 000 | 70ms | 23ms | 9ms |
150 000 | 220ms | 60ms | 20ms |
1 000 000 | 1.9s | 400ms | 135ms |
This values are tested with random positions, on a recent laptop and Chrome 38. The half of markers is moving randomly and the other half is static. It is also fast enough for mobile devices.
If you prefer real world data, the 50k Leaflet.markercluster example is computed in 60ms (original).
You can specify the weight of each marker.
For example, you may want to add more importance to a marker representing an incident than a marker representing a tweet.
You can specify a category for the markers. Then a small object representing the number of markers for each category is attached to the clusters. This way, you can create cluster icons adapted to their content.
The size of cluster can be adjusted on the fly (Example)
The markers can be filtered easely with no performance cost.
var pruneCluster = new PruneClusterForLeaflet();
...
var marker = new PruneCluster.Marker(latitude, longitude);
pruneCluster.RegisterMarker(marker);
...
leafletMap.addLayer(pruneCluster);
marker.Move(lat, lng);
// Remove all the markers
pruneCluster.RemoveMarkers();
// Remove a list of markers
pruneCluster.RemoveMarkers([markerA,markerB,...]);
The category can be a number or a string, but in order to minimize the performance cost, it is recommanded to use numbers between 0 and 7.
marker.category = 5;
marker.weight = 4;
marker.filtered = true|false;
pruneCluster.Cluster.Size = 87;
pruneCluster.ProcessView();
Each marker has a data object where you can specify your data.
marker.data.name = 'Roger';
marker.data.ID = '76ez';
In order to improve the performances, the Leaflet marker is created only if needed and can be recycled. You can setup the marker by overriding the PreapareLeafletMarker method.
pruneCluster.PrepareLeafletMarker = function(leafletMarker, data) {
leafletMarker.setIcon(/*... */); // See http://leafletjs.com/reference.html#icon
// A popup can already be attached to the marker
// bindPopup can override it, but it's faster to update the content instead
if (leafletMarker.getPopup()) {
leafletMarker.setPopupContent(data.name);
} else {
leafletMarker.bindPopup(data.name);
}
};
pruneCluster.BuildLeafletClusterIcon = function(cluster) {
var population = cluster.population, // the number of markers inside the cluster
stats = cluster.stats; // if you have categories on your markers
// If you want list of markers inside the cluster
// (you must enable the option using PruneCluster.Cluster.ENABLE_MARKERS_LIST = true)
var markers = cluster.getClusterMarkers()
...
return icon; // L.Icon object (See http://leafletjs.com/reference.html#icon);
};
This library is developed in context of the BRIDGE project.
The source code of this library is licenced under the MIT License.