Search code examples
leafletleaflet.markercluster

Removing items from leaflet markercluster


I have two functions that load markers into my map. (Both functions are called on success of an AJAX call)

First Function is like this:

function loadEpsMarkers(data) {
  for (var i = 0; i < data.length; i++) {
    var plateNo = data[i].PLATE_NUMBER;
    var permitNo = data[i].PERMITINFOID;
    var inventoryId = data[i].INVENTORY_ID;
    var icon = epsiconR;

    if (data[i].INVENTORY_STATUS === 'Complete') {
      icon = epsiconC;
    }

    var popup = '<h5>EPS</h5>' + 'Plate:' + plateNo + '<br/>' +
      ' Permit: <a class=\'link\' data-inventoryId="' + inventoryId + '" href=' + url + '>' + permitNo + '</a>' +
      '<p style=\"color:blue\">' + '' + '<a class=\'link\'  href=' + url + '>' + 
      'Import' + '</a>' + '<br/>' + '<a class=\'link\'  href=' + url + '>' + 
      'Duplicate' + '</a>' + '<br/>' + '<a class=\'link\'  href=' + url + '>' + 
      'Removed' + '</a>' + '<br/>' + '</p>';
            
    var m = L.marker([data[i].REF_LATITUDE, data[i].REF_LONGITUDE], { icon: icon, draggable: 'true' })
               .bindPopup(popup);
    markerClusters.addLayer(m);
  }

  map.addLayer(markerClusters);
  map.invalidateSize(false);
}

The second Function is same except the data is different. This works fine and I get the clustered markers as expected.

Now I have a button, when I click this button, it should hide the markers from the first call.

The easy way out is to remove layers and then redo just the second call. But that seems like an inefficient way of doing this.

This gets more complex if I have 4 such data calls and I want to toggle markers from each of those calls.

I have tried something like this as well:

$('#dvEpsOnlyMarkers').click(function () {
  markerClusters.removeLayer(m);
});

But that isn't working. How can I make this work ?


Solution

  • A very simple way of achieving what you describe is to store references to markers of each group in arrays, and manipulate those arrays to add / remove the layers into MCG:

    var markersCall1 = [],
        markersCall2 = [],
        markersCall3 = [],
        markersCall4 = [];
    
    function loadEpsMarkersX(data) { // Replace X by 1...4
        for (var i = 0; i < data.length; i++) {
            // Convert data...
    
            var m = L.marker(/* latLng, options, popup... */);
    
            markersCallX.push(m); // Replace X by 1...4
        }
    
        // Actually add to MarkerClusterGroup.
        // Replace X by 1...4
        markerClusters.addLayers(markersCallX); // note the addLayers with "s".
    }
    
    
    $('#dvEpsOnlyMarkersX').click(function (event) { // Replace X by 1...4
        // Assuming it is a checkbox, you can use it to toggle.
        if (this.checked) {
            // Replace X by 1...4
            markerClusters.addLayers(markersCallX); // note the "s".
        } else {
            // Replace X by 1...4
            markerClusters.removeLayers(markersCallX); // note the "s".
        }
    });
    

    When you have batches of markers to add / remove like in your case, you can conveniently use the MarkerClusterGroup methods addLayers and removeLayers (with a trailing s) with an array of the markers to process. These methods are much more efficient than adding / removing markers one by one.