Search code examples
javascriptmapsleafletmarkerclusterermarkers

Marker cluster leaflet : dynamically modify icon


I'm using Leaflet and the marker cluster plugin and I want to dynamically modify the icon of the cluster from which child is inside.

First I create my clusterGroups then I add some markers. I create two groups but I display only the first one "cluster" and I want to edit this icon if one of his children also belong to the group "ClusterBatterieFaible".

My code works but doesn't do want I want : in the function iconCreateFunction I want to count markers of "ClusterBatterieFaible", but I don't know how to send it as a parameter. Any suggestion ?

var ClusterBatterieFaible = L.markerClusterGroup({    });

var cluster = L.markerClusterGroup({
iconCreateFunction: function (cluster) {
    var childCount = cluster.getChildCount();
    if (childCount > 1){
        var c = ' marker-cluster-large';
    }
    else {
        var c = ' marker-cluster-small';
    }
    return new L.DivIcon({ html: '<div><span>' + childCount + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });
}

});

For loop
  if batteryOk :    
     L.marker(latlng, {icon: mainIconE}).bindPopup("blabla");}   }).addTo(cluster)

  if batteryNotOk : 
     L.marker(latlng, {icon: mainIconE}).bindPopup("blabla");}   }).addTo(ClusterBatterieFaible).addTo(cluster)

Solution

  • Bienvenue sur SO !

    Refrain from adding your markers to several MarkerClusterGroups (MCG). That would break their clusters as they will be "confused" about which cluster the markers belong to.

    Instead you could simply use an Array of markers, or an L.LayerGroup into which you add your markers (but DO NOT add it to the map!), for the group that you want to test ("batteryNotOk" if my understanding is correct). And add only the remaining MCG to the map.

    To test if a given marker is contained in an Array, simply use myArray.indexOf(marker) >= 0.

    To test if a given marker has been added in a Layer Group, simply use myLayerGroup.hasLayer(marker)

    So your iconCreateFunction would be something like:

    function (cluster) {
        var markers = clusters.getAllChildMarkers(),
            iconClass = "allBatteriesOk";
    
        for (var i = 0; i < markers.length; i += 1) {
            if (myArray.indexOf(markers[i]) >= 0) {
                iconClass = "atLeastOneBatteryNotOk";
                break;
            }
        }
    
        return L.divIcon({
            html: '<div><span>' + childCount + '</span></div>',
            className: iconClass,
            iconSize: new L.Point(40, 40)
        });
    }