Maplibre : Access 'way' and 'relation' ID from the mbtiles on the map - queryRenderedFeatures - openstreetmap

I'm using the queryRenderedFeatures function from https://maplibre.org/maplibre-gl-js-docs/example/queryrenderedfeatures/ to query all features over the mouse on a MapLibre map.
I have access to all Node, and the id identified in the windows looks similar to the OSM ID (where the mbtiles seems to add a '0' at the end of the OSM ID :
mbtiles ID : 1230 corresponds to OSM ID N123)
(A) When I'm trying to access Way, the ID doesn't show up in the queryRenderedFeatures function
A console.log of the queried feature shows the ID as undefined
When I compare to the query on OpenStreetMap website, I can confirm that both return similar results by re-building the LineString output from MapLibre.
In other words, the query looks good and accurate, but I'm curious on how to fetch the OSM_ID from a way with this function ?
The source ID is road_path_pedestrian, with its source layer being Transportation for which I've added the osm_id (in case this could have been the root cause)
(B) as for the relation, is there any way to fetch those from the mbtiles (rendered or not) directly on the map ?
In the example above, the summit track has a relation on OSM that gathers all portions of the summit track ways. Is there a way to access as well the ID of this relation from the mbtiles, on the go ?
The objective is to have the user clicking on a path/track on a maplibre map, and the function to return the full OSM relation ID and LineString.
Exactly the same way it's currently done on OpenStreetMap website. For the same example, it would be the yellow track with its 7 members.
Thanks in advance for your support!

Related

Import GeoJSON data into MongoDB

I have two geojson files
GeoJSON file for Provinces (here)
GeoJSON file for Municipalities (here)
Municipalities resides inside Provinces
My goal is to import these files into MongoDB. In MongoDB I have a collection called "Grocery", a collection with a geolocation field (long/lat)
Part of the goal is for each Grocery row to get the associated Province and Municipality by using the data from the two GeoJSON available. So say a Grocery row have a (X,Y) geolocation field stored, using these coordinates we will query the Provinces and Municipalities from the GeoJSON data to return the Province name and Municipality name, e.g. it will return "Mountain Province" plus "Lake City" (Municipality)
What is the general approach to achieving this?
Best approach in my opinion would (trivially) be to perform this transformation with the programming language you prefer, interfacing your MongoDB.
You will find many libraries allowing you to perform operations with GeoJSON objects, including testing a GeoJSON point inclusion within any GeoJSON shape. You may want to take a look to d3-geo (w/ Node.JS) or Python GeoJSON as well as Shapely.

Getting Streets of a specific postcode using Open Street Maps

I want to write a code that has the Countrycode and Postcode as an input and the ouput are the streets that are in the given postcode using some apis that use GSM.
My tactic is as follows:
I need to get the relation Id of the district. For Example 1991416 is the relation id for the third district in Vienna - Austria. It's provided by the nominatim api: http://nominatim.openstreetmap.org/details.php?place_id=158947085
Put the id in this api url: http://polygons.openstreetmap.fr/get_wkt.py?id=1991416&params=0
After downloading the polygon I can put the gathered polygon in this query on the overpass api
(
way
(poly: "polygone data")
["highway"~"^(primary|secondary|tertiary|residential)$"]
["name"];
);
out geom;
And this gives me the streets of the searched district. My two problems with this solution are
1. that it takes quite a time, because asking three different APIs per request isn't that easy on ressources and
2. I don't know how to gather the relation Id from step one automatically. When I enter a Nominatim query like http:// nominatim.openstreetmap.org/search?format=json&country=austria&postalcode=1030 I just get various point in the district, but not the relation id of the searched district in order to get the desired polygone.
So my questions are if someone can tell my how I can get the relation_Id in order to do the mentioned workflow or if there is another, maybe better way to work this issue out.
Thank you for your help!
Best Regards
Daniel
You can simplify your approach quite a bit, down to a single Overpass API call, assuming you define some relevant tags to match the relation in question. In particular, you don't have to resort to using poly at all, i.e. there's no need to convert a relation to a list of lat/lon pairs. Nowadays the concept of an area can be used instead to query for certain objects in a polygon defined by a way or relation. Please check out the documentation for more details on areas.
To get the matching area for relation 1991416, I have used postal_code=1030 and boundary=administrative as filter criteria. Using that area you can then search for ways in this specific polygon:
//uncomment the following line, if you need csv output
//[out:csv(::id, ::type, name)];
//adjust area to your needs, filter critera are the same as for relations
area[postal_code=1030][boundary=administrative]->.a;
// Alternative: {{geocodeArea:name}} -> see
// http://wiki.openstreetmap.org/wiki/Overpass_turbo/Extended_Overpass_Queries
way(area.a)["highway"~"^(primary|secondary|tertiary|residential)$"]["name"];
(._;>;);out meta;
// just for checking if we're looking at the right area
rel(pivot.a);out geom;
Try it on overpass turbo link: http://overpass-turbo.eu/s/6uN
Note: not all ways/relations have a corresponding area, i.e. some area generation rules apply (see wiki page above). For your particular use case you should be ok, however.

Openstreetmap: from "address" to "shapefile"

I've been looking for an answer on the web since quite a long time, but I couldn't make it. So, I hope Stackoverflow users could help/advice me a bit.
I have 7 000 addresses (like "67, place Lobligeois 75017 Paris, France") and I would like to get a Shapefile that contains the 7 000 buildings corresponding to these 7 000 addresses.
My idea is to:
Use Mapquest API to get the "OSM node" for these 7 000 "addresses"
Use Overpass API to get, for all buildings in Paris, their "ways" and "nodes"
Match (1) et (3) to get the "ways" corresponding to my 7 000 "nodes/adresses"
Load in QGIS a shapefile (found at download.bbbike.org/osm/bbbike/Paris/) of all Paris buildings (shapefile where "OSM_ID" equals "way")
Find in my shapefile the "ways" obtained in (3) and delete all buildings that do not match.
Is it a good idea? Or is there a simpler way to do it (I hope)?
By the way, I am not able to download the data from my step 2, overpass-turbo.eu fails each time. Do you have any idea (is my Bbox too big)?
I would be delighted to get some advices/help.
Charles H.
Try to use this: https://github.com/kiselev-dv/gazetteer/tree/develop/Gazetteer
You can get csv with addresses, address components, osm id's and geometry as WKT string.
After that, you can compare points from step one by osm id or by address and filter csv rows you need.
Finally open csv in QGIS and save it as shape.
There are a couple of things I recommend.
Don't bother trying to extract the buildings. That will put a big hurting on your browser. Instead, grab one of the Geofabrik daily extracts for the Paris region. While those won't include the address nodes, they will have all the buildings.
Next do an overpass query for just addresses on nodes using the NominatimArea function. It looks like there are 30MB worth of them in Paris (!!), so you may have to break that area down into smaller districts, if Paris has any. Export that as GeoJSON and convert to shape.

How to set street obstructed in planet_osm_line/pg_route

I am working on a project where we are going to be looking at finding the shortest/fastest route from point A to point B. I've been looking at the tables generated by the osm2pgsql. And I'm wondering how would I represent a road obstructed after the osm has been loaded into our database. Our project will rely on osm to map out all of the roads we will also have an operator looking at live video footage of roads. At which point if the operator see's a road is obstructed we want to update the database to reflect this road obstructed say by a downed tree.
I've been looking at all of the columns and the only one that stands out in my head is barrier. I have been unable to find any documentation on what each column represents and how pg_route takes each into consideration when creating a route. What I'm looking for is a column that when pg_route looks in the database and sees a road it says oh that roads blocked skip it?
This is good question for gis.se...
First thing is pg_routing can't route via data generated by osm2pgsql - this data is not a network. You need data generated by osm2po or osm2pgrouting and this data is quite different.
Second thing is - there is no such column. In every pg_routing function you're passing sql which will select data for route search so you're deciding which edge will be in this dataset and which not - it's not a problem to add extra column to table with edges.
Here is link to pgrouting workshop it will guide you through all process from import of data to first generated route. It's using osm2pgroutin to import data, but I suggest you use osm2po instead.
So as Jendrusk mentioned, when you generate a route you will pass the function a SQL query to select the edges for the graph you want to solve, 'select * from edges where the_geom && <bbox>' You can model blockages using point and radius, lines, or polygons that you want the route to avoid by adding to the query above avoidance zones like:
'select * from edges where the_geom && <bbox> and not st_dwithin(the_geom, point, radius) and not stdwithin(the_geom, line_or_polygon, 0.0)'
If you have lots of these avoidances then put them in a table and do a join to eliminate the edges that are used to build the graph. If the edges are not there the route is forces to find a way around the avoidance.

How can I associate a leaflet marker with an object id in my database

On a webpage with leaflet maps - I want to be able to display my database objects, each of which have a lat,lng. using markers on the map.
So when I click the marker, I would like to fetch information from db and display this.
How can I store the object id or associate it with a marker so that when a marker is clicked I can load my object from database and display detailed information?
I know I could use lat/lng to find the object using radius search or something, but this won't work and is not accurate, as there could be more than one object with same lat/lng.
Ok based on the answer provided by #Ivar in another thread: Leaflet: Add a link to the markers
You can associate a dbObject Id to the marker directly, after the marker is added to the map. when a marker is added to the map it gets assigned an ID called "_leaflet_id". This can be fetched through the target object, and also set to a custom value after it has been added to the map.
Now in the marker OnClick event you can just get the clicked marker's id and use it to query the database.
marker._leaflet_id = dbObjectId;
Not sure how you are connecting to your db, but the flow would be something like this:
grab the clicked point's lat/lng, then send that info to some logic that employs a spatial geometry lib like S2 or something. Create an envelope around the clicked point, and get all the points whose lat/lngs are within that envelope, then whichever's lat/lng is the shortest spherical distance to your clicked point is your match.
I am sure there is an easier way to do this through CartoDB or something like PostGIS.
--
Assuming your database objects are set up in a table like this:
ID(guid) | Name | Latitude | Longitude
fe124etc.| Marker1| 43.123 | -117.123
y75W2etc.| Marker2| 44.123 | -116.123
you do the method above and then once you have the marker you want, you send the other db data (name, address, w/e) back to a popup that is bound to the marker.
Another avenue to explore is (depending on the data) you can make a geoJSON layer out of it. (leaflet geojson use). If you do that, you can create/store/read attributes for each point.
Hope this makes it a little more clear.