Search code examples
javascriptleafletopenstreetmapleaflet.markercluster

Handling Average of a lot of Values


I'm inserting Markers with a specific Value onto an Openstreetmap via leaflet. Futhermore I want those Markers to get Clusterd while zooming out of the map. The Clustericon should show the average Value of the Cluster.

This far, there is no problem. I iterate over all markers in each cluster, add the values together and then divide by the amount of markers. Then I create a custom icon which is colored depending on the value and has a label with the average value. This works great for small amounts of Markers.

The problem is, that I have to insert a LOT of Markers in the northern area of Germany. I mean like at least 50000.

In this Case the Browser isn't able to load the page. But if I set the default zoom to 18 it does load the page. And there are no problems while zooming out of the page. I paste my code below:

var markers = L.markerClusterGroup({
        chunkedLoading: true, 
        chunkProgress: updateProgressBar,
        showCoverageOnHover: false,
        maxClusterRadius: 100,
        iconCreateFunction : function(cluster) {
            var val = 0;
            for (i = 0; i < cluster.getAllChildMarkers().length; i++) {
                val = val
                        + parseInt(cluster.getAllChildMarkers()[i].options.speed)
            } 
            var avg = val / cluster.getAllChildMarkers().length;
            avg = Math.round(avg * 10) / 10;
                    
            
            return new L.divIcon({
                html: "<div style='background-color: " + generateColor(avg) + "'><span>" + avg + "</span></div>",
                className: ' marker-cluster',
                iconSize: new L.point(40, 40)
            })
        }
    });  

Now I need a solution to make this map functional.


Solution

  • Hard to tell exactly what is your bottleneck without a proper case reproduction.

    You could at least start by caching your markers array:

    function iconCreateFunction(cluster) {
        var val = 0,
            childMarkers = cluster.getAllChildMarkers(), // Store in local variable to avoid having to execute it many times.
            total = childMarkers.length;
    
        for (i = 0; i < total; i++) {
            val = val + parseInt(childMarkers[i].options.speed)
        } 
        var avg = val / total;
        avg = Math.round(avg * 10) / 10;
    
    
        return new L.divIcon({
            html: "<div style='background-color: " + generateColor(avg) + "'><span>" + avg + "</span></div>",
            className: ' marker-cluster',
            iconSize: new L.point(40, 40)
        })
    }