Search code examples
javascriptfilterleafletmarkers

Leaflet filter markers by name using checkbox


I want to filter my markers by name, using map.addLayer(nameOfTheMarker) and map.remvoeLayer(nameOfTheLayer) with a checkbox like this:

$('#markertoggle').change(function () {
    if (!this.checked) 
    //  ^
         map.addLayer(nameOfTheMarker);
    else 
        map.remvoeLayer(nameOfTheLayer;
});

I found a jsfiddle with an example of a filter, but I don't know how to apply it to my code:

var locations = [
['AB11 5HW','17','A',57.147701,-2.085442 ] ,
['AB11 8DG','3','B',57.129372,-2.090916 ]
];

var markersA = [];
var markersB = [];

//Loop through the initial array and add to two different arrays based on the specified variable
for(var i=0; i < locations.length; i++) {
    switch (locations[i][2]) {            
        case 'A' : 
            markersA.push(L.marker([locations[i][3], locations[i][4]]));
            break;        
        case 'B' :
            markersB.push(L.marker([locations[i][3], locations[i][4]]));
            break;
        default :
            break;
    }
}

//add the groups of markers to layerGroups
var groupA = L.layerGroup(markersA);
var groupB = L.layerGroup(markersB);

//background tile set
var tileLayer = {'Gray' : L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png')
};

var map = L.map('map', {
    center: new L.LatLng(57.0, -2),
    zoom: 9,
    layers: [tileLayer['Gray'], groupA, groupB] //change this to determine which ones start loaded on screen
});


//Control on the Top Left that handles the switching between A and B
var overlayMaps = {
    "A": groupA,
    "B": groupB
};
L.control.layers(tileLayer, overlayMaps, {position:'topleft'}).addTo(map);

http://jsfiddle.net/RogerHN/31v2afte/2/

The function that I use to pull the markers:

function showMarkersByName(name) {
for (var i = 0; i < markers.resources.length; i++) {
    var resName = markers.resources[i].name;

    if (resName == name) {
        var resIcon = icons.resources[i].icon;
        var resSize = icons.resources[i].size;
        var resPname = icons.resources[i].pname;

        var customIcon = L.icon({
            iconUrl: resIcon,
            iconSize: resSize, // size of the icon
            iconAnchor:   [resSize[0]/2, resSize[1]/2], // point of the icon which will correspond to marker's location
            popupAnchor:  [2, -resSize[1]/2] // point from which the popup should open relative to the iconAnchor
        });

        for (var j = 0; j < markers.resources[i].coords.length; j++) {
            var x = markers.resources[i].coords[j].x;
            var y = markers.resources[i].coords[j].y;

            marker = L.marker([y, x], {icon: customIcon});
            marker.addTo(map).bindPopup(resPname);
            $(marker._icon).addClass(name)

        }
    }
}

My markers structure its very similar with the one in the example, I just don't know where in my function I need to insert the filter to filter the markers by name, adding then to a layer to later toggle them use the checkbox above.

My full code here: http://plnkr.co/edit/UwAelIuUYz4OkoOG7zFn?p=preview


Solution

  • Using the example above and the code iH8 mentioned I was able to create a checkbox to toggle markers filtering them by its name:

    function initLayerGroups() {
      for (var i = 0; i < markers.resources.length; i++) {
        switch (markers.resources[i].name) {
          case 'GreenMarker':
            for (var j = 0; j < markers.resources[i].coords.length; j++) {
              var x = markers.resources[i].coords[j].x;
              var y = markers.resources[i].coords[j].y;
    
              marker = L.marker([y, x], {
                icon: getIcon(i)
              }).bindPopup(getPopupContent(i));
    
              markersGreen.push(marker);
            }
            break;
          case 'BlueMarker':
            for (var j = 0; j < markers.resources[i].coords.length; j++) {
              var x = markers.resources[i].coords[j].x;
              var y = markers.resources[i].coords[j].y;
    
              marker = L.marker([y, x], {
                icon: getIcon(i)
              }).bindPopup(getPopupContent(i));
    
              markersBlue.push(marker);
            }
            break;
          case 'RedMarker':
            for (var j = 0; j < markers.resources[i].coords.length; j++) {
              var x = markers.resources[i].coords[j].x;
              var y = markers.resources[i].coords[j].y;
    
              marker = L.marker([y, x], {
                icon: getIcon(i)
              }).bindPopup(getPopupContent(i));
    
              markersRed.push(marker);
            }
            break;
          default:
            break;
        }
      }
    
      groupGreen = L.layerGroup(markersGreen);
      groupBlue = L.layerGroup(markersBlue);
      groupRed = L.layerGroup(markersRed);
    }
    

    The checkbox:

    <input type="checkbox" id="greenmarkertoggle"/>
    <label for="greenmarkertoggle">Green Marker</label>
    

    And the javascript code to show or hide the layer:

    $('#greenmarkertoggle').change(function() {
        if (this.checked)
          map.addLayer(groupGreen);
        else
          map.removeLayer(groupGreen);
    });
    

    And here's the full working example using the code above:

    http://plnkr.co/edit/GuIVhtFdtMDbmZdME1bV?p=preview

    Thanks to iH8 and the example above I was able to create that function and filter the markers by its name.