1

I am trying to catch intersecting features. So when a user clicks on the map I would like to identify all layers that has been clicked on, and show the menu - from which parcel the user wants to get info. For example, in the picture below, there should be 3 options:

  1. Click outside of polygons: 0 intersection features (click doesn't intersect with any layer).
  2. Click inside the polygon: 1 intersection feature (user's click intersects with 1 layer), so intersectingFeatures array has 1 object.
  3. Click on the point: 2 intersecting features: Polygon and Point (user's click intersects with 2 layers), so intersectingFeatures array has 2 objects.

But somehow I can't catch intersection with Point. Function intersects() just doesn't recognize intersection with Point. Is there any other way to capture click intersection with Point geometry type? (catch intersection with Polygon works perfectly though).

   useMapEffect(({instance}) => { // instance is a Map object

    const onClick = (e: any) => {
        const clickBounds = L.latLngBounds(e.latlng, e.latlng);
        intersectingFeatures = [];

        for (const l in (instance as any)._layers) {
            const overlay = (instance as any)._layers[l];

            if (overlay.feature) {
                let bounds;
                
                if (overlay.getBounds) {
                    bounds = overlay.getBounds();
                } else if (overlay._latlng) { // for Point
                     bounds = L.latLngBounds(overlay._latlng, overlay._latlng);
                }
                
                 if (bounds && clickBounds.intersects(bounds)) {
                     intersectingFeatures.push(overlay);
                 }
            }
        }
        console.log(intersectingFeatures);
    }

    instance.on("click", onClick);

    return () => {
        instance.off("click", onClick);
    }    }, [intersectingFeatures]);

enter image description here

The same with leaflet-pip library. If I use it this way (instead of intersects() function), Point features also doesn't fall into results array, Polygons only.

const results = leafletPIP.pointInLayer(e.latlng, L.geoJSON(overlay.toGeoJSON()));

How I create Points:

const featureObj = rows.map((data:any) => {
                    if(featureProps.featureType === "point"){
                    const {_X_COORD:longitude,_Y_COORD:latitude}:
                        {_X_COORD:string,_Y_COORD:string} = data;
                    const wktPoint = `Point (${longitude} ${latitude})`;

                    const geometry = Leaflet.L.geoJSON(
                        {
                            ...wkt2geojson(wktPoint) as GeoJsonObject,
                            properties: {
                                data: (featureProps.featureLabel) ? (featureProps.featureLabel(data)) : "",
                                type: "Custom-Point"
                            },
                        } as any,
                        {
                            pointToLayer: function (feature, latlng){
                                return L.circle(latlng, {
                                    radius: 10,
                                    fillOpacity: 0.5
                                })
                            }
                        });

                    return geometry;}}
         
8
  • How is circle defined? As L.circleMarker? If so, it has no dimension regarding vector layer, it's only a point.
    – TomazicM
    May 14, 2022 at 18:31
  • @TomazicM, exactly, it is defined as L.circleMarker. I thought since circleMarker has radius, it is not a simple Point, and it can be used in this case. What would be the best approach then? May 15, 2022 at 19:43
  • Here it gets a bit complicated if you want to have marker size in pixels, since at each zoom level it covers different map area. In short, for each zoom level you would have to calculate marker radius in meters, create buffer with that radius around the point and check if click coordinate falls within it. turf.js library can help you with that.
    – TomazicM
    May 15, 2022 at 20:28
  • If you would define your circle as L.circle, this would make it a vector layer with dimensions, but then it's size on screen would change with zoom change.
    – TomazicM
    May 15, 2022 at 20:31
  • Sorry, my last comment is wrong. L.circle vector layer also behaves as a point, not as a circular area. Simplest solution would then be to use turf.circle to create GeoJSON polygonal approximation of the circle.
    – TomazicM
    May 17, 2022 at 21:31

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.