Back

Technologies:

javascriptjavascript
avatar
Tolerim
an hour ago

How can a dropdown menu filter be set up for Leaflet with ease?

As a beginner in JavaScript, I am developing an interactive map to display information on NGOs in Spain. I have successfully added markers and implemented clustering. When a marker is clicked, a pop-up appears. Now, I want to filter markers based on their properties, such as "tematica". I followed an example (https://mappinggis.com/2019/11/filtrando-datos-geograficos-en-formato-geojson-con-leaflet/) but struggled to adapt it to my project. The example's geojson.js file was not organized, which made it difficult to understand. Here is an example of my Geojson file: {"type": "FeatureCollection","features": [{"type": "Feature","properties": {"coder_ID": "CHB","name": "Entorno Escorial","tematica": "Medio Ambiente","bio": "Organización medioambiental de El Escorial y de San Lorenzo de El Escorial","redes": "","website": "","CCAA": "Madrid","MAmbiente": true,"Educacion": false,"JSocial": false,"CClima": false,"TransEnerg": false,"AgroEco": false,"SobAlim": false,"EcoFem": false,"Invest": "false"},"geometry": {"coordinates": [-4.147899127581563,40.59572974584587],"type": "Point"}} Here's my JavaScript code so far:
const map = L.map('map').setView([40.382439468640214, -3.745878127504685], 6);

const tileLayer = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);

const geojsonMarkerOptions = {
    radius: 8,
    fillColor: "#37b18c",
    color: "#000",
    weight: 1,
    opacity: 1,
    fillOpacity: 0.8
};

const markers = L.markerClusterGroup();

var layer = L.geoJson (data, {
    onEachFeature: function (feature, layer) {
        layer.bindPopup('<h1>'+feature.properties.name+'</h1><p>Tematica: '+feature.properties.tematica+'</p><p>'+feature.properties.bio+'</p>');
        },
        pointToLayer: function (feature, latlng){
            return L.circleMarker(latlng, geojsonMarkerOptions);
        }
        });
        markers.addLayer(layer);
        map.addLayer(markers);

function tematicaSelect() {
    var miSelect = document.getElementById("ambito").value;
        
    var ambitos = L.geoJSON(data, {
        pointToLayer: function (feature, latlng) {
        return L.circleMarker(latlng, geojsonMarkerOptions);
    },
        filter: function(feature, layer) {                              
                if(miSelect != "TODOS")     
            return (feature.properties.tematica == miSelect );
                else
            return true;
        },  
        style:geojsonMarkerOptions,
        onEachFeature: layer    
                });     

    markers.clearLayers();
    markers.addLayer(ambitos);
}
Although my code seems correct, I am unable to filter the markers based on their properties. I would appreciate any help. Thank you!
Answers(1)
avatar
Tolerim
an hour ago
Verified Answer
It looks like you're trying to filter markers on your map based on a specific property, "tematica," using Leaflet. Your geojson data contains this property, but you're having trouble adapting the code from the example provided to your specific project. One potential issue is that you're not passing your data variable to the L.geoJSON function correctly. You could try changing this line:
to:
This should pass only the "features" array of your geojson data to the function, which is what L.geoJSON expects. To filter your markers based on the "tematica" property, you can modify the tematicaSelect() function. This function currently creates a new L.geoJSON object with a pointToLayer function that sets up the markers, but it's missing the filter function that would actually filter the markers based on the property. You can add the filter function like this:
return feature.properties.tematica === miSelect;
}
This will only include features where the "tematica" property matches the value of the "miSelect" variable (which you're getting from a dropdown with id "ambito"). Here's the modified code for the tematicaSelect() function:
var miSelect = document.getElementById("ambito").value;
            
    var filterLayer = L.geoJSON(data.features, {
        pointToLayer: function (feature, latlng) {
            return L.circleMarker(latlng, geojsonMarkerOptions);
        },
        filter: function(feature, layer) {                              
            return feature.properties.tematica === miSelect;
        },
        onEachFeature: function (feature, layer) {
            layer.bindPopup('<h1>'+feature.properties.name+'</h1><p>Tematica: '+feature.properties.tematica+'</p><p>'+feature.properties.bio+'</p>');
        }
    });     

    markers.clearLayers();
    markers.addLayer(filterLayer);
}
Try making these changes and see if they help you filter your markers as desired!
;