bmwcarit / barefoot

Java map matching library for integrating the map into software and services with state-of-the-art online and offline map matching that can be used stand-alone and in the cloud.
Apache License 2.0
666 stars 186 forks source link

Road ID #13

Closed jangottweiss closed 8 years ago

jangottweiss commented 8 years ago

Hello,

the installation and usage of Barefoot just worked fine. The matching already works and I got some good results.

Now I would like to get additional information about the matched roads. Barefoot returns data like this (slimjson mode) :

... { "route": "LINESTRING (106.89085170694243 -6.142643394836986, 106.89085170694243 -6.142643394836986)", "road": 1199220, "frac": 0.7514822019311651 } ... I would like to request information like speed level or road type. How can I retrieve this kind of information. Is there a way to query for example Nominatim?

What kind of Road ID is the returned one?

Thank you!

BR, Jan

smattheis commented 8 years ago

Hi Jan, ids are generated during import which is necessary because OSM roads must be split to get a routable road network. Hence, each road has a unique identifier but also knows the id of the corresponding OSM road with a 1-to-n relationship.

EDIT: The result format of the map matching library returns internal identifier that encodes the heading of the matched object. Hence, divide a road id (e.g. in SlimJSON format) by 2 where the remainder specifies the heading of your object, which is 0 for forward and 1 for backward relative to the road's direction (source node and target node of the road specify the road's direction). Example: A road id of 2001 refers to road gid 1000 where the object was heading backwards from the roads target node to the source node. In contrast, a road id of 2000 refers to road gid 1000 where the object was heading from the road's source node to the target node. This coding is library versions up to 0.0.2 and will be patched in later versions to have a more intuitive result format.

To get information about the road, you can query the DB (PostgreSQL/PostGIS) as follows (example):

sudo docker exec -it barefoot-oberbayern psql -h localhost -d oberbayern -U osmuser
oberbayern=> select gid,osm_id from bfmap_ways where gid=1;
 gid | osm_id 
-----+--------
   1 |     99
(1 row)
oberbayern=> select tags from ways where id=99;
                                             tags                                             
----------------------------------------------------------------------------------------------
 "ref"=>"FFB 11", "highway"=>"tertiary", "junction"=>"roundabout", "zone:traffic"=>"DE:urban"
(1 row)
oberbayern=> \q

Alternatively, you can also get road information in software with the provided API, see http://bmwcarit.github.io/barefoot/doc/index.html

I hope this helps. Please do not hesitate to ask more questions! Cheers, Sebastian

jangottweiss commented 8 years ago

Hello Sebastian,

thank you for your fast answer.

I got the chance to play a little bit around with barefoot and ran into an other issue related to the road ids.

I use data from Jakarta which I downloaded here: http://download.geofabrik.de/asia/indonesia.html.

I matched a route and the result looks great.

Not I have the following entry in my output (slimjson): { "route": "LINESTRING (106.878099830573 -6.240377845767836, 106.87808430000001 -6.2404653, 106.87808430000001 -6.2408972, 106.87806660000001 -6.2411253, 106.8780517 -6.2413164, 106.8780002 -6.2416577, 106.87781140000001 -6.2421099, 106.8776569 -6.2424426, 106.8774595 -6.2427498, 106.8768806 -6.2434584, 106.8766345 -6.2437872, 106.8764034 -6.244096, 106.8763411 -6.2441793, 106.87597740000001 -6.2450948, 106.8759303 -6.2452186, 106.87579310000001 -6.2456384, 106.8753865 -6.2466794, 106.87520850000001 -6.2470655, 106.8755095 -6.247391, 106.8757132 -6.2476112, 106.8760029 -6.2479418, 106.8762765 -6.2481871, 106.87638200487478 -6.24824783587129)", "road": 243210, "frac": 0.5456628631492966 }

So in this case the internal road id is 243210.

I followed your steps to get the osm id: image image

The OSM ID is valid and also in Indonesia http://www.openstreetmap.org/way/154218842 image

The Problem is that the osm road does not match the coordinates from the result in any way. So in this case the linestring is in Jakarta and the matched road in Bandung.

I also made this map on geojson.io for visualization purpose: http://bl.ocks.org/d/c3df07d7deab7e48ded46eeea21b20d7

Do you have a rough idea what is going wrong here and / or what I am doing wrong!

Thank you and Best Regards, Jan

smattheis commented 8 years ago

I'm glad it worked out. Just as a fast guess: Have you imported the Jakarta map multiple times? Please note that Barefoot stores a *.bfmap file as temporary buffer of map data. So it may be the case that you downloaded and imported OSM data, executed the map matching (*.bfmap is created), discarded the map container and imported some slightly different data again (with tiny changes due to e.g. OSM download of another day). Just to exclude that problem delete the *.bfmap file either manually or with mvn clean and run the matcher again, which REALLY pulls data from the container and creates a new *.bfmap, and check your ids again afterwards. It's not necessary to import the data again, we can just work with your latest import.

jangottweiss commented 8 years ago

Hello Sebastian,

thank you again for your fast answer.

I tried out your proposal. Sadly it did not work quiet well. I even cleaned up the database and imported the data in a clean db. Sadly the result is the same.

For further investigation:

[ { "id": "test1", "time": 1462349317000, "point": "POINT ( 106.79691016674042 -6.137071904422551)" }, { "id": "test2", "time": 1462349417000, "point": "POINT ( 106.79719984531403 -6.140037419160422)" }, { "id": "test3", "time": 1462349517000, "point": "POINT ( 106.79690480232239 -6.140261432192995)" }, { "id": "test4", "time": 1462349617000, "point": "POINT ( 106.79538130760193 -6.140400106880215)" }, { "id": "test5", "time": 1462349717000, "point": "POINT ( 106.79549396038055 -6.141152149747436)" } ]

[ { "road": 75816, "frac": 0.03702688304634867 }, { "route": "LINESTRING (106.796906170721 -6.137072300134278, 106.79719927932089 -6.140037475208727)", "road": 75816, "frac": 0.9436418984080973 }, { "route": "LINESTRING (106.79719927932089 -6.140037475208727, 106.7972175 -6.1402218, 106.79690478172907 -6.140261268738254)", "road": 75885, "frac": 0.6314989587548852 }, { "route": "LINESTRING (106.79690478172907 -6.140261268738254, 106.79672230000001 -6.1402843, 106.7954076 -6.1404261)", "road": 75883, "frac": 1 }, { "route": "LINESTRING (106.7954076 -6.1404261, 106.7954076 -6.1404261, 106.795455 -6.1408417, 106.79549105373752 -6.141152487537958)", "road": 75823, "frac": 0.19908239435368935 } ]

image

http://www.openstreetmap.org/way/55896897#map=10/0.9712/104.4131

=> Trip was in Jakarta Matched Road is in Batam

I would like to know would do you think about this issue and if you maybe have an idea for a solution.

Thank you and best regards, Jan

smattheis commented 8 years ago

I think I found the problem. In the generation of map matching results, the library is using - currently - a different internal ID, which is slightly different than what's the GID: The library maps each road to two virtual (directed) roads and, hence, maps each road's gid to one virtual road with an id gid * 2 and another one with id gid * 2 + 1. To check that, can you just divide your gid of 75816 by 2 and look up gid 37908? The rationale of the current implementation is that it's coding the heading of your object in the result. I'm sorry for confusion. The use of the internal id was done by design, but I think this should be changed. I'm not sure what's the most appropriate format the library could return. I would be happy about your feedback and would patch it soon. Thanks for your detailed problem description!

jangottweiss commented 8 years ago

Thank you!

I checked the gid 37908: image

http://www.openstreetmap.org/way/31151383#map=17/-6.13932/106.79788

OSM Road 31151383 is now the right one in Jakarta. So this solved the issue. Great!

For the future maybe it would be helpful to directly return the gid and the osm_id. In my case the osm id is very important since it is needed to get further information and for later reference.

smattheis commented 8 years ago

I'm glad it finally worked out. I would leave this issue open as a reminder (for me) to implement this feature like, e.g., returning gid and with an additional heading flag. I will close the issue afterwards. Thanks for your feedback!

smattheis commented 8 years ago

I have included the feature in the current release.

hujilin1229 commented 4 years ago

Hi smattheis,

I need to open this question again since you may have done some updates. Here are some of the outputs from barefoot-0.1.5. `Dict{String,Any}("heading" => "backward","frac" => 0.13446057036560966,"route" => "LINESTRING (126.68184286716307 45.74102117694165, 126.6827154 45.7408905, 126.68499840000001 45.740608, 126.6866781 45.7403736, 126.68688944588732 45.74034219126958)","road" => 8218)

Dict{String,Any}("heading" => "backward","frac" => 0.05082859770087944,"route" => "LINESTRING (126.67102809937109 45.73470807933948, 126.6710781 45.7347204, 126.6706101 45.7357515, 126.67084260000001 45.7366047, 126.670992 45.7371533, 126.67105450000001 45.7373827, 126.67108658683402 45.737500475050645)","road" => 14518), ` Both "road" id have ZERO remainders, but it has heading backward. Moreover, when I do 8218 / 2 = 4109, and use this as gid in my "bfmap_ways" table, the geom is far away from the LINESTRING.

In this case, how should I interpret the road id here?