[GIS] Leaflet: 4 overlay layers, 1 click, get properties of all intersecting polygons.

leaflet

I have a leaflet application where I have 4 layers that have many intersecting polygons such as, a counties layer, a school districts layer, a cities layer, and a layer of miscellaneous areas. All cities and miscellaneous areas physically intersect with counties and school districts. Some miscellaneous areas intersect with cities. I need "on" my click to get a popup that tells me the feature properties of each polygon at each layer – if that layer is indeed selected. I am having a terrible time working on a solution.

I love how I can loop over each layer in the leaflet L.featureGroup function. But I am stumped with querying each layer's features past that. I see the ._layer elements returned in the console. I suspect I need to detect intersections. Can someone point me in the right direction in terms of plugins and or leaflet methods.

Best Answer

This is not trivial, due to how web browsers handle DOM elements. If you have two (or more) overlapping (not nested) elements, pointer events will only apply to the top-most element. This is a limitation of the DOM model.

Two approaches to the problem spring to mind:

1 - Use GIS magic to calculate the intersection of all your different features. Create a feature layer with small polygons, each of which contains the properties of all your 4 feature layers.

i.e. each polygon should contain information about schools, counties, cities and misc; and each combination of schools, counties, cities and misc has its own polygon.

2 - Use something like Leaflet.CheapLayerAt to automate querying displayed vector data on the screen. When the user clicks on a feature on the map, remove that feature layer, run a Leaflet.CheapLayerAt query. That should return the feature from the underlying feature layer. Repeat this process until no more features are found, then re-add all the feature layers.

Yes, if you use this method you must remove and add layers. Or send them to the back of the stacking context so other layer is the top-most one when querying again.