Universite-Gustave-Eiffel / Tempus

C++ framework to develop multimodal path planning requests
76 stars 13 forks source link

Shortest path, bad result (bad chosen start and end vertices) #14

Closed celiamercier closed 6 years ago

celiamercier commented 9 years ago

Hi guys, I noticed a probem using the sample_road_plugin. I used the following points on the ile_de_france osm database : A = (649852.2252142751, 6858778.845797726) B = (649750.725317172, 6858876.96575924)

Here is the result : problem1 problem2

We can notice two problems :

What do you think of that ?

mhugo commented 9 years ago

Are there one way streets ? Or streets forbidden to cars ? This simple plugin only considers you are using a car.

celiamercier commented 9 years ago

I didn't know that sample_road_plugin was only for cars ! That explains why it make a such long itinerary, because of the one way restriction. Here is a diagram of the spot :

problem4

But this does not explain why the start point is not binded on the closest street (that is not forbidden for cars). Also how can I modify the plugin to compute the path as a pedestrian ?

mhugo commented 9 years ago

Sorry, my bad, the plugin does the opposite, it is pedestrian only and forbids road sections where pedestrians are not allowed. For the closest point ... that's because the first allowed mode of your request is pedestrian. Then tempus looks for the closest node allowed for the selected mode. Then it should be the case for the "residential" way. Could you list the attributes of this road_section imported by tempus in the database ? If you want to modify what road sections are allowed / restricted by the plugin, have a look at the WeightCalculator around lin 41 in sample_road_plugin.cc

celiamercier commented 9 years ago

But it really seems that the algorithm avoid to take one way roads in the bad direction, why that ? As regards the road_section attributes, the only tags are highway: residential and a name: Villa Deshayes. Here is the Tempus attributes :

Thanks !

EDIT : I look at the code.

if (graph[e].traffic_rules() & TrafficRuleCar) == 0)
   return std::numeric_limits<double>::infinity();

You were right, according to those lines the sample_road_plugin is meant to be used for car itineraries. I changed to TrafficRulePedestrian and it solve the problem of shortest path, but not the problem of vertex choice : pedestrian_view

Here is another exemple of a bad vertex binding (there is a vertex just on the A point) : qgis_view This is weird because the chosen vertex belong to the same road than the vertex that should have been taken (its a footway road).

celiamercier commented 9 years ago

There a mistake in the tempus function tempus.road_node_id_from_coordinates, but i don't really understand why ... Anyway I replace it by :

create or replace function tempus.road_node_id_from_coordinates_prettystreets( float8, float8 ) returns bigint
as '
select id from tempus.road_node
order by geom <-> st_setsrid(st_point($1, $2), 2154) limit 1
'
language sql;

I directly look at nodes instead of roads, and it works. But it is not applicable for the tempus.road_node_id_from_coordinates_and_modes function.

celiamercier commented 9 years ago

Here is a view that explain the problem and may help to solve it : vertex_choice_problem

The green point is the point for which I want to find the closest vertex. The green street is the first street that should be selected when looking for the closest one from the vertex with this request :

select id, node_from, node_to l from tempus.road_section
order by geom <-> st_setsrid(st_point($1, $2), 2154) limit 1

But in reality it is considered by this request as the 6th closest road ! Black roads are considered closer than the green one, and the black node is the closest node return by the whole request. There clearly is a problem here, what that the '<->' do exactly ?

mhugo commented 9 years ago

Thanks for this. You're right it comes from the <->. It actually takes the centers of the bounding boxes to compute the distance, my mistake. The right query would be something like : limit to N (say 10) closest points (using <#>) and then order by st_distance (the real distance computation) and take the first.

celiamercier commented 9 years ago

I try this and it works :

with rs as (
select node_from, node_to from tempus.road_section
)
select id from rs, tempus.road_node as p
where rs.node_from = p.id or rs.node_to = p.id
order by p.geom <-> st_setsrid(st_point($1, $2), 2154) limit 1
mhugo commented 9 years ago

Indeed. Thanks !