0

I am attempting to have a click event popup with some data pulled from Wikipedia and displayed on my Leaflet map for each point that displays GeoJSON data. My data is displayed on map as you can see here: enter image description here

Each GeoJSON point has a property:name associated with it that would be used for the Wikipedia search. My problem is that I can not get the layer.bindpopup function to properly display a popup when any feature is clicked. This may be an issue due to my use of the leaflet-ajax plugin, I am not sure.

After consulting multiple solutions found here:

Leaflet

Geeks With Attitude

Savas Labs

Github

And other threads on gis.stackexchange, I have not been able to make the popup work for me. My cursor changes during hover, but I can not select the highlighted shapes on my map.

What might I be doing wrong with the following code?

                <script>
                //Create initial map with predefined location.
                var map = L.map('mapid').setView([37.7688150141044, -122.44451522827147], 14);
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition((position) => {
                        map.panTo(L.latLng(position.coords.latitude, position.coords.longitude))
                    })
                }
                //Initial Map
                L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=vpKwi7e2rRjEWHBci22Y', {
                    attribution: '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',
                }).addTo(map);

                function onEachFeature(feature, layer) {
                // does this feature have a property named 'name'?
                    if (feature.properties && feature.properties.name) {
                        layer.bindPopup(feature.properties.name);
                    }
                }
                //Create layer containing GeoJSON data
                var geojson = new L.GeoJSON.AJAX("SFLandmarks.geojson")
                //Wait until data loaded
                geojson.on('data:loaded', function () {
                    geojson.addTo(map);
                });
                //Create onEachFeature popup?
                L.geoJSON(geojson, {
                    onEachFeature: onEachFeature
                }).addTo(map);
            </script>
1

L.GeoJSON.AJAX object is an extension of Leaflet L.GeoJSON object and so it inherits all it's options (this is not explicitly mentioned in leaflet-ajax plugin docs). This means it's possible to use onEachFeature option to specify function where popup is binded to layer.

In your case this would look something like:

function onEachFeature(feature, layer) {
  if (feature.properties && feature.properties.name) {
    layer.bindPopup(feature.properties.name);
  }
}

var geojson = new L.GeoJSON.AJAX("SFLandmarks.geojson", {
  onEachFeature: onEachFeature
});

geojson.on('data:loaded', function () {
  geojson.addTo(map);
});
  • This does work. The difference being the location of 'onEachFeature: onEachFeature' during the creation of my GeoJSON layer rather than after the fact? Is there an identifiable reason why the method shown on leafletjs.com is not working in this scenario? That is: L.geoJSON(geojsonFeature, { onEachFeature: onEachFeature }).addTo(map); – KullideDev Jan 16 at 8:26
1

Instead of using the L.GeoJSON.AJAX method of loading in my data, I have opted to use $.getJSON as shown here. I was able to then load the popup at a later line using L.geoJSON and add my 'onEachFeature' using .addTo(map). This can be seen in the following code:

                <script>
                //Create initial map with predefined location.
                var map = L.map('mapid').setView([37.7688150141044, -122.44451522827147], 14);
                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition((position) => {
                        map.panTo(L.latLng(position.coords.latitude, position.coords.longitude))
                    })
                }
                //Initial Map
                L.tileLayer('https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=vpKwi7e2rRjEWHBci22Y', {
                    attribution: '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',
                }).addTo(map);

                function onEachFeature(feature, layer) {
                    // does this feature have a property named 'name'?
                    if (feature.properties && feature.properties.name) {
                        layer.bindPopup(feature.properties.name);
                    }
                }
                //Create layer containing GeoJSON data using .getJSON as opposed to GeoJSON.AJAX
                $.getJSON("SFLandmarks.geojson", function (geojson) {
                    console.log(geojson);
                    //geoJSON loaded here instead of above on getJSON line
                    L.geoJSON(geojson, {
                        onEachFeature: onEachFeature
                    }).addTo(map);
                });
            </script>

The specific code in question is here:

                    $.getJSON("SFLandmarks.geojson", function (geojson) {
                    console.log(geojson);
                    //geoJSON loaded here instead of above on getJSON line
                    L.geoJSON(geojson, {
                        onEachFeature: onEachFeature
                    }).addTo(map);

As you can see on the first line I am using the $.getJSON method as mentioned above, this allowed me to not only load the data into the console log to see what the server was seeing, but also load in my EachFeature click event to the map.

There may be a better more easy way to do and explain this, but I am still working and would like to leave this available for anybody struggling in the future to see a possible solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.