How to associate nested polygons to their parent from different GeoJSON files? - leaflet

I have 3 separated GeoJSON files, each one contains a Feature Collection of Polygons.
First one for regions, the second for provinces and last for communes.
So the scenario is: for each region on click or zoom, show provinces in the clicked region then same thing with procinces.
I am using Leaflet for interactive map.
I am stuck on how to link every region with their provinces.
Is there any way to detect nested polygons?
Do I need a database or server side analysis?

Welcome to SO!
You would like to be able to tell the child ("nested") polygons of a given parent / container polygon, so that when a user clicks on the latter, you can show only the former.
The easiest would be to embed in your GeoJSON data properties some ID to each Feature, and for each child the ID of its container parent, and/or for each parent the array (list) of its children.
If your GeoJSON data does not already contain such association, then you could refactor it once to make it available. You have plenty ways of doing so, whether in GIS software, or directly using Client libraries. E.g. have a look at http://turfjs.org/ and its booleanContains method:
Boolean-contains returns True if the second geometry is completely contained by the first geometry. The interiors of both geometries must intersect and, the interior and boundary of the secondary (geometry b) must not intersect the exterior of the primary (geometry a).

Related

how to avoid polygon being clipped with tileset?

I am generating a layer UK scale, it is composed for several polygons, the idea for the layer is to display it fully and then the user can zoom to most specific area. The main problem is because the number of polygons when I create the .mbtile it split some of the polygon at determined zooms.
I have tried with different options of tippecanoe like --not duplication extend zooms if still dropping ... but I couldn't nail whit the correct commands to make it work.
tippecanoe -zg --read-parallel -l $LAYER -o "$OUT_MBTILES" "$OUT_JSON" --coalesce-densest-as-needed --extend-zooms-if-still-dropping --no-duplication
I suspect this is somehow related to --no-duplication. Per the documentation:
--no-duplication: As with --no-clipping, each feature is included intact instead of cut to tile boundaries. In addition, it is included only in a single tile per zoom level rather than potentially in multiple copies. Clients of the tileset must check adjacent tiles (possibly some distance away) to ensure they have all features.
I'm not sure why you're using that option, but disable it if possible.
It's hard to be more specific without seeing your data and having a lot more information about what you're trying to achieve, zoom levels, attributes, data size etc.

Hide polygons that are within a specific area

I'm trying to create an experience where I have a couple of detailed 3D models of buildings on the map with extruded building footprints of neighboring buildings via a vector tile source. The 3D models would be the main focus point and the extruded footprints would be for reference. One challenge I'm running into is that I have a global building footprint layer and it has a footprint for the 3D buildings which doesn't match up perfectly. Additionally, when extruded, it ends up merging/overlapping the nice 3D models.
I'd like to be able to hide the individual footprints that overlap the 3D models. My original thought was to grab the bounding box of the 3D model and then use the new within style expression, but it looks like this will only filter points and lines, not polygons. The building footprint polygons have no unique information in them that I could use to filter on.
I know I could monitor map movements and query the rendered features and manually detect intersecting polygons, but since there is no unique property on the footprint, I can't filter or use feature state.
Any ideas of how to efficiently avoid rendering individual polygons in a specific area that come in from a vector tile source?
It is a common issue that the buildings layer in Mapbox Streets don't contain any unique attributes to allow filtering or rendering differently.
The best solution is usually to source a different buildings layer, and in this case, remove those redundant buildings in pre-processing.
I can think of one rather crazy workaround that might work here, although the performance may be poor.
Add the building layer with very low opacity, of type fill, essentially invisible. (Maybe invisible would work.) Call your main source buildings`.
Create a secondary building source of type geojson, and a secondary fill-extrusion layer. Call this source buildings-copy.
On map move or moveend, use querySourceFeatures to obtain a copy of all buildings.
Process this copy using Turf to remove the buildings you don't want, and call setData to set the copy as the data for buildings-copy.
You may need to do some clever caching to get reasonable performance.

Best Practice to display local markers and a wider area of points of interest markers?

I've created a base layer and 6 different overlay (Points of Interest) layers for a leaflet map.
The base layer of markers can appear on the map almost anywhere in the world, but I want the POI layers to appear only if they are in the same area (mapBounds) of the base layer. Probably the screen size.
All the data is pulled from a MySQL database and using Ajax I create the various sets of markers from two different tables, base and poi. This much is all done and working, you can see it at https://net-control.us/map2.php. The green and blue markers are from the base table, other markers are currently selected for view by clicking on the appropriate icon in the lower right. The only one active at the moment is 'Fire Station'. But if you zoom out far enough you will see additional fire stations in the Kansas City area, and in Florida. Those sets are not needed.
After the query runs I create a fitBounds variable of the base layer and another poiBounds for the poi layer. But I'm not sure I need the poiBounds. The number of base markers is generally less than 50 for the base query, but if all the poi markers are pulled world wide that number could be very large.
So I'm hoping someone can help me determine a best practice for this kind of scenario and maybe offer up an example of how it should be done. Should I...
1) Download all POIs and not worry about them appearing outside the base bounds layer? Should I inhibit them from showing in the javascript or in the SQL? How?
2) If I inhibit the unwanted points from SQL do I test one POI at a time to see if its included in the base bounds? How? Are there MySQL functions perhaps to work with this kind of data?
I'm fairly new at leaflet maps and would appreciate examples if appropriate.
2) If I inhibit the unwanted points from SQL do I test one POI at a time to see if its included in the base bounds? How? Are there MySQL functions perhaps to work with this kind of data?
You probably want a column of type POINT, a spatial index on such column (which internally is likely to be implemented as an R-Tree), and spatial relation functions on your SQL query to make use of that index.
Start by reading https://dev.mysql.com/doc/refman/8.0/en/spatial-types.html. Take your time, as spatial databases, spatial data types and spatial indices work a bit differently than their non-spatial equivalents.

Mongodb GeoSpatial querying within shapes in collection

I have a collection that has a 2d geospatial index on a field (center) which is an array of long/lat, the collection also has a radius field. So each item can represent a circle. I know that mongodb has a operator $within, and I want to get a list of all items that contain a specific point [long,lat], but it seems that I can only check which points are within a specific shape.
You are correct, right now, you can't do what you want. Please file a feature request at http://jira.mongodb.org as I can't find one already existing for this.
This is how I solved it (i.e. get a shape that covers a given point) in my situation, using a basic grid. It has a limited accuracy, depending on the grid resolution:
create a collection "grid" with points that covers the common bounding box of all your shapes (use a nested for loop in javascript)
create a 2d index on the grid
for each shape, search for all the grid points that lie within the shape; label each grid point with the id of the shape (use an array attribute on the grid point)
To see in what shape(s) a point lies, search for the closest grid point, and return its assigned shape(s) property. First check for the common bounding box, because points outside it should always return 'not in any shape', and not use the closest grid point.
Depending on the precision you need, this might or might not be a usable solution. The accuracy depends on how many points you put in your grid, and you may be able to do something smart with local densities of your grid.

OpenStreetMap Api call returns empty set

I am trying to call OpenStreetMap API:
http://api.openstreetmap.org/api/0.6/map?bbox=43.65,-79.38,43.66,-79.37
It returns no error, but map is empty:
Do you have any ideas why?
thanks
I think for the given request, the empty dataset delivered is actually the correct response.
The API documentation says api/0.6/map returns
All nodes that are inside a given bounding box and any relations that reference them.
All ways that reference at least one node that is inside a given bounding box, any relations that reference them [the ways], and any
nodes outside the bounding box that the ways may reference.
All relations that reference one of the nodes, ways or relations included due to the above rules. (Does not apply recursively, see
explanation below.)
As far as I can see, your bounding box selects a bit of Antarctica. What data did you expect?
I guess, in OSM, Antarctica is just a way, describing its outline (and maybe some research stations somewhere). If you now ask for an area in the middle of nowhere there, there are no data to get. This is because within your bbox there are no nodes. The way for the outline/area of Antarctica is only fetched if at least one of its nodes lies within your bounding box.
PS: If you want a piece of Toronto (with lots of data), swap longitude and latitude values :)
https://wiki.openstreetmap.org/wiki/Download#Construct_a_URL_for_the_HTTP_API
it says the bounding box can only be 0.5 by 0.5 degrees. it also says you might want to try XAPI for such a large area