How to match GPS points to a particular "way"?

Hello!

I have a problem like this: I have a list of latitude, longitude pairs and for each one of those, I would like to know which type of road was it generated on. All the points are from GPS units of cars driving on public roads.

I have downloaded OpenStreetMap .osm export, where the roads are stored in a format as follows:

Now my question is, is there any tool to find a match between GPS coordinates and this way ids? How is this done using OpenStreetMaps?

Thanks in advance!

This problem needs to be solved for routers and geo-coders, but is not something for which OSM, itself, provides APIs.

I imagine there are papers available on finding the closest polyline to a point.

The following is probably far from optimal, but would work.

Download all the ways within a reasonable area around the point.

For each pair of adjacent nodes on a way, compute the distance from the point to the line joining them.

Choose the way with the lowest minimum distance.

It might be possible to pre-screen by computing bounding boxes.

I’m probably missing something, but why not upload the GPS trace and eyeball it in the iD editor?

You have severalways of doing this:

  • Map Matching: the process of taking your GPS trace and snapping it to road features. Graphhopper provide tools for doing this as part of their routing engine.
  • A simple reverse geocode of the points using Nominatim which will return basic information about features around that point. (example query https://nominatim.openstreetmap.org/reverse.php?format=html&lat=51&lon=-1.2&zoom=16; always run multiple queries against Nominatim more than 1 s apart)
  • Using overpass-turbo to do a query for highways around n metres from your point. (example http://overpass-turbo.eu/s/y5J)).

In both of the latter cases if your point is near 2 or more roads you need some way to select the road you want, but both are rather simpler than the former.

Thanks all of you for your responses.

I think Overpass suits my needs the best. However, there is an issue with speed. The HTTP requests just take too long to synchronize a large dataset.

Is it possible to make Overpass query a local db (created from a local .osm export for example)? Does anyone know? Or is there other tool for this?

Okay, so in the end I figured it out as follows:

First, I have installed an Overpass API on my Ubuntu machine and loaded the downloaded .osm there. Then I could query the loaded .osm file like this:

/some_path/osm-3s_v0.7.54/bin/osm3s_query --db-dir=/some_path/osm-3s_v0.7.54/mydb <<< "way['highway'](around:10,'_GPSLAT_,_GPSLON_');out;"

This returned an XML string where I could parse for a way id.

The major issue with this approach is that when your GPS point is close to multiple roads, you get an XML response with multiple way ids. In my solution I have totally neglected this and I am fine with any error this might give. Since my dataset is very large and dense I assume the error made would not be significant and early experiments proved me right.

How would you find out the type of road by looking at the way id?

BTW: I would use larger batches instead of calling osm3s_query for each single lat/lon. “Zero” values separate way ids for each lat/lon pair. Also by using CSV there’s no need to parse any XML.


[out:csv(::id;false;"")];
way(around:50,51.946,-1.185)["highway"]; out; make sep ::id = 0; out;
way(around:50,51.946,-1.285)["highway"]; out; make sep ::id = 0; out;
way(around:50,51.946,-1.385)["highway"]; out; make sep ::id = 0; out;
way(around:50,51.946,-1.485)["highway"]; out; make sep ::id = 0; out;

If one is doing large batches, one should probably be considering the high level objective that you are trying to achieve, as it is possible there may be features about it that mean that the process can be done more efficiently, and, in extreme cases, it may be that it is inappropriate to use the public servers and you should be working with a local copy of the part of the world that you are interested in.

In particular, if you your set of points is very dense, the correct approach may be to look up the ways in the points, rather than the points in the ways. That would need to be done with a local copy.

Alright, thank you both for the hints I will definitely try those out!

I am a complete novice to the world of OSM, so I am very grateful for such corrections.

Oh. I might have not expressed myself very well. I am interested in the way id as a number + all the parameters the way id has such as “highway” (AKA the type of the rode), “surface”, “maxspeed”, etc.