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:
- Click outside of polygons: 0 intersection features (click doesn't intersect with any layer).
- Click inside the polygon: 1 intersection feature (user's click intersects with 1 layer), so intersectingFeatures array has 1 object.
- 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]);
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;}}
L.circleMarker
? If so, it has no dimension regarding vector layer, it's only a point.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?L.circle
, this would make it a vector layer with dimensions, but then it's size on screen would change with zoom change.L.circle
vector layer also behaves as a point, not as a circular area. Simplest solution would then be to useturf.circle
to create GeoJSON polygonal approximation of the circle.