Filtering intersections to (4-way intersections, T-junctions, and other ) using Overpass API in a given bounding box - openstreetmap

There is a script Here that can process the data from OSM to detect intersections in a given bounding box. It works by getting all the ways in a given bounding box and then finding other ways that share common nodes with these roads. Here is the query that does that,
way
["highway"]
["highway"!~"footway|cycleway|path|service|track|proposed"]
(, , , )
->.relevant_ways;
foreach.relevant_ways->.this_way{
node(w.this_way)->.this_ways_nodes;
way(bn.this_ways_nodes)->.linked_ways;
way.linked_ways
["highway"]
["highway"!~"footway|cycleway|path|service|track|proposed"]
->.linked_ways;
(
.linked_ways->.linked_ways;
-
.this_way->.this_way;
)->.linked_ways_only;
node(w.linked_ways_only)->.linked_ways_only_nodes;
node.linked_ways_only_nodes.this_ways_nodes;
out;
}
This query returns all kinds of intersections (4-way intersections, T-junctions, ... ).
Question:
Is there a way to further filter out the intersection to 4-way intersections and T-junctions?
One idea I have is to check if the common node is an endpoint of one the ways, which makes the intersection and if the common node is in the middle of the road it will be a 4-way intersection. But I am not sure how to write a query that does this.
Any help will be appreciated, Thanks.

Related

How to compute bounding boxes of specific roads from Overpass api

I have a high volume dataset with keys like this:
lat:6.897585,
long:52.785805,
speed:12,
bearing:144
Basically it is a dataset of records of various trips on cars. The data was stored every few seconds during each trip. The main goal of this project is to be able to visualize only u-turns (turn arounds) on a map. But for now, I am trying to at least show the data on specifc roads. For that, I am using Overpass API
With the help of Overpass Turbo, I can get a dataset with all the roads I need.
However, in the dataset, the road's geometry is represented with LineString type.
My question is, How can I get a bounding box(es) of the roads from Overpass API, so later on, I can display events that happened only on the given roads? Or maybe you have a better solution on how to achieve this?
A bounding box wouldn't be very helpful here, as using it to filter your points would show everything that falls within the box (which could include other nearby roads)
It sounds like getting a buffer around a linestring might get you closer, but could still include points that are within the buffer but not on the road you are inspecting.
The smarter way to do this would be to assign each event to a road segment using some logic based on their attributes/properties, so you don't have to depend on a spatial filter.

Geopoints: From Single Coordinate to Bounds on map

I try to figure out how to come from a single given coordinate (lat/lon) to the nearest bounds which enclose this coordinate on a map e.g. streets or sea.
Here two examples to give you a better understanding of what I mean:
What i tried already or thought about:
Setting up a Nominatim server and search for the given coordinate via the reverse-function to get the bbox and/or the geojson polygon of this coordinate. -> this only works when the given coordinate is within a POI or for example directly on a street.
Writing an algorithm to walk in all 4 or 8 directions (n/e/s/w) and 'stop' when the map layer/surface changes (change = stop for this direction and mark a bounding-point)
Building up an image-recognition system using TensorFlow to detect the different colors and 'draw' the polygon. Worked with TensorFlow a couple of times but this seems to be the most tricky solution to implement (but at my current understanding the most precise one)
Does someone of you have any other ideas to get a solution for this problem? Would appreciate any kind of approaches
Cheers!
If I got your question right, you might wanna first select all polygons in which the given point is inside of using ST_Contains, and then compute the distance to this point using ST_Distance. If you ORDER BY distance and LIMIT to 1 result you'll get the nearest polygon, e.g.
Data Sample
CREATE TABLE t (gid int, geom geometry);
INSERT INTO t VALUES
(1,'POLYGON((-4.47 54.26,-4.44 54.28,-4.41 54.24,-4.46 54.23,-4.47 54.26))'),
(2,'POLYGON((-4.48 54.25,-4.40 54.25,-4.41 54.23,-4.48 54.23,-4.48 54.25))'),
(3,'POLYGON((-4.53 54.23,-4.44 54.29,-4.38 54.22,-4.53 54.23))');
Query
SELECT gid,ST_AsText(geom) FROM t
WHERE ST_Contains(geom,ST_MakePoint(-4.45, 54.25))
ORDER BY ST_Distance(geom,ST_MakePoint(-4.45, 54.25))
LIMIT 1;
gid | st_astext
-----+------------------------------------------------------------------------
1 | POLYGON((-4.47 54.26,-4.44 54.28,-4.41 54.24,-4.46 54.23,-4.47 54.26))
(1 Zeile)

Does using the Overpass polygon query have a computational advantage over a bounding box?

For a project on geospatial data analytics, we are currently extracting road type and speed limit data of certain roads along a track by using Overpass' polygon query (where we define the roads by a buffer zone around them). The problem is that in the case of separate tracks, we can end up with disconnected polygons which often lead to a significant increase in computation time. In this situation, we were wondering how Overpass' polygon query actually works. Does the algorithm actually query only the data inside this polygon/these polygons, or does it query inside a bounding box, after which it filters out the data inside the polygons?
The algorithm checks if nodes are inside the defined polygon, or if a way crosses the polygon. It's not based on bounding boxes as you mentioned.
From your description it's not quite clear why disconnected polygons pose an issue. You should get decent performance with a lz4-based backend and a reasonable number of lat/lon pairs in your (poly: ) filter (the more pairs you provide, the more expensive the computation gets).
BTW: The best approach to tackle this issue would be something I described in this blog post: https://www.openstreetmap.org/user/mmd/diary/42055 - unfortunately, this feature is not yet available in the official branch. If you see some use for it, please upvote here: https://github.com/drolbr/Overpass-API/issues/418

Check intersections between points and polygons in QGIS

I have two data layers, one with points and one with polygons. Both layers have ID's and I would like to check whether the points with ID x lay inside or outside the polygon with ID x.
Does someone know how to do this?
Thanks,
Marie
One potential solution which gives you a comma separated list in the python console is to run a small script from the python console:
mapcanvas = iface.mapCanvas()
layers = mapcanvas.layers()
for a in layers[0].getFeatures():
for b in layers[1].getFeatures():
if a.geometry().intersects(b.geometry()):
print a.id(),",",b.id()
This should produce a result of cases where one feature intersects the other. The order of the layers did not matter in my testing, however, both layers had to use the same coordinate reference system, so you might need to re-project your data if both layers have different reference systems. This worked for points in polygons and polygons intersecting polygons (I'm sure it would work with lines as well).
Answers such as this: https://gis.stackexchange.com/questions/168266/pyqgis-a-geometry-intersectsb-geometry-wouldnt-find-any-intersections may help with further refinement of such a script, and was a primary source on this answer.

How can I find all nodes around a point that are members of a way with a certain tag?

I would like to find all highway way member nodes in a certain radius. I cannot see how to do this without using intersection, however, that is not in the API. For example I have this:
[out:json];
way(around:25, 50.61193,-4.68711)["highway"];>->.a;
(node(around:25, 50.61193,-4.68711) - .a);
out;
Result set .a contains the nodes I want but also nodes outside the radius - potentially a large number if the ways are long. I can find all the nodes inside the radius I don't need, as returned by the complete query above. Now I can always perform a second around query and do the intersection of the two result sets outside of Overpass. Or I can do another difference:
[out:json];
way(around:25, 50.61193,-4.68711)["highway"];>->.a;
(node(around:25, 50.61193,-4.68711) - .a)->.b;
(node(around:25, 50.61193,-4.68711) - .b);
out;
This gives the result I want but can it be simplified? I'm certain I'm missing something here.
Indeed, your query can be simplified to an extent that we don't need any difference operator at all. I would recommend the following approach:
We first query for all nodes around a certain lat/lon position and a given radius.
Based on this set of nodes we determine all ways, which contain some of the previously found nodes (-> Hint: that's why we don't need any kind of intersection or difference!).
Using our set of highway ways we now look again for all nodes of those ways within a certain radius of our lat/lon position.
In Overpass QL this reads like:
[out:json];
node(around:25, 50.61193,-4.68711);
way(bn)[highway];
node(w)(around:25, 50.61193,-4.68711);
out;
Try it on Overpass Turbo