Leaflet – Turf Intersect Point with Leaflet GeoJSON Error

javascriptleafletturfweb-mapping

Leaflet and Turf. I am trying find all the layers on a Leaflet map that intersect a point when the user clicks on the map. I am using the turf library to test for this. In the console when I click on the map it returns this error:

turf.min.js:1 Uncaught Error: geojson must be a valid Feature or Geometry Object
    at J (turf.min.js:1)
    at Object.Lo [as intersect] (turf.min.js:1)
    at js2.js:22
    at eachLayer (leaflet.js:5)
    at e.<anonymous> (js2.js:20)
    at e.fire (leaflet.js:5)
    at e._fireDOMEvent (leaflet.js:5)
    at e._handleDOMEvent (leaflet.js:5)
    at HTMLDivElement.r (leaflet.js:5)

Here is the code

map.on('click', function(e) {
        var str = "Latitude: " + e.latlng.lat.toFixed(5) + " Longitude: " + e.latlng.lng.toFixed(5) + " Zoom Level: " + map.getZoom();
        var lat = e.latlng.lat;
        var lng = e.latlng.lng;
        var pt = turf.point([lng, lat]);

        map.eachLayer(function(layer) {
            if (layer instanceof L.GeoJSON) {
                var click_intersection = turf.intersect(pt, layer.toGeoJSON());
                if (click_intersection) {
                    console.log(layer.feature.properties)
                }
            }
        });

Reference questions turf.js intersect problem?

Get popup info in multiple layers from one click

update

    var c = new L.GeoJSON.AJAX("http://127.0.0.1:8000/childcare_buff_data/",{
        style: color(c, "orange", 0.8)})
        ;
    c.addTo(map);

    map.on('click',function(e){
        lat = e.latlng.lat;
        lon = e.latlng.lng;
        ProcessClick(lat,lon)
    });

    var theMarker;
    var a;

    function ProcessClick(lat,lon){
        theMarker = L.marker([lat,lon]).addTo(map);
        c.eachLayer(function(layer) {
            intersects=turf.intersect(theMarker.toGeoJSON(),layer.toGeoJSON());
            if (intersects){
                a=layer.feature.properties.buff
                console.log(a);
                }
            })};

I get this error

turf.min.js:1 Uncaught TypeError: Cannot read property 'length' of null
    at turf.min.js:1
    at turf.min.js:1
    at S (turf.min.js:1)
    at Pn (turf.min.js:1)
    at Object.Lo [as intersect] (turf.min.js:1)
    at js2.js:31
    at eachLayer (leaflet.js:5)
    at ProcessClick (js2.js:30)
    at e.<anonymous> (js2.js:22)
    at e.fire (leaflet.js:5)

enter image description here

here is the geojson http://www.mediafire.com/file/9fnbz32ib9n1aaj/childcare.geojson/file

Best Answer

Okay, here is a possible solution, I used, 3 layers, muni, county, state, variables, a,b,c, when I would click on the map and it would grab the polygons feature Name from each layer, Then I posted the three feature Names to a dialog. Here is the process to get the values.I also create a marker to see where I clicked.

  map.on('click',function(e){  
        lat = e.latlng.lat;
        lon = e.latlng.lng;
        ProcessClick(lat,lon)   
  });

var theMarker;
var a;
var b;
var c;

function ProcessClick(lat,lon){

    if (theMarker != undefined) {
              map.removeLayer(theMarker);
        };
        if (newgeojsonLayer != undefined) {
              map.removeLayer(newgeojsonLayer);
        };  


    theMarker = L.marker([lat,lon]).addTo(map);  //added to show where you clicked.

        muniLayer.eachLayer(function (layer) {

        //isInside =turf.inside(theMarker.toGeoJSON(), layer.toGeoJSON());

       // Newer method in Turf
       isInside =turf.booleanPointInPolygon((theMarker.toGeoJSON(), layer.toGeoJSON());

        if (isInside){
                a = "City/Town: " + layer.feature.properties.NAME;
                console.log("City/Town: " + layer.feature.properties.NAME);
        }
    });

    countyLayer.eachLayer(function (layer) {

        isInside =turf.inside(theMarker.toGeoJSON(), layer.toGeoJSON());

        if (isInside){
                b = "County: " + layer.feature.properties.NAME;
                console.log("County: " + layer.feature.properties.NAME);
        }
    });

    stateLayer.eachLayer(function (layer) {

        isInside =turf.inside(theMarker.toGeoJSON(), layer.toGeoJSON());

        if (isInside){
            console.log("State: " + layer.feature.properties.STATE_NAME);
            c = "State: " + layer.feature.properties.STATE_NAME;
        }
    })

}

Basically I used it as a popup for all three layers, I just put the values for a,b,c in the popup dialog.

http://www.gistechsolutions.com/leaflet/DEMO/pointsinpoly/index.html http://www.gistechsolutions.com/leaflet/DEMO/pointsinpoly/indextab.html