Instruction time and distance don't match to path details time and distance

I calculated random routes and found out that sometimes total time and distance from instruction list don’t equals to total time and distance from path details. I’d like to share my findings here.

Input data: GraphHopper 5.3
Andorra OSM 2022-07-07
Route: (42.50702432225021, 1.540252979300468) ---> (42.51053446153803, 1.5473162007930066)

config.yml:

graphhopper:
  datareader.file: "andorra-220707.osm.pbf"
  graph.location: ""
  graph.elevation.provider: "srtm"
  prepare.min_network_size: 700
  routing.non_ch.max_waypoint_distance: 1000000
  graph.dataaccess: "RAM_STORE"
  graph.encoded_values: "toll"
  graph.flag_encoders: car|turn_costs=true|speed_bits=7|speed_factor=2

  profiles_ch:
    - profile: my_car

  profiles:
    - name: my_car
      vehicle: car
      weighting: shortest
      turn_costs: true
      u_turn_costs: 20

I add "instructions" -> true hint to request and also expect to see Details.TIME and Details.DISTANCE in response.

What we have:

best.distance=1493.7759272543913
instructions.distance=1493.7759272543913
details.distance=1326.143927254391
difference between instructions and details=167.63199999999983

best.time=120864
instructions.time=100864 # turn cost is 20 seconds
details.time=89689
difference between instructions and details=11175 

Now let’s inspect what we have inside instructions and path details:

Instructions (name; time; distance):
1) CG-2;47062;836.753927254391
2) CG-2;24532;364.91
3) CG-2;13710;205.66500000000002
4) <no name>;15560;86.44699999999999
5) <no name>;0;0.0

distance details (first;last;value)
0;8;384.39992725439106
8;11;96.298
11;12;2.352
12;16;91.095
16;18;56.415
18;19;27.288
19;20;16.92
20;21;3.03
21;22;13.629
22;23;64.338
23;24;55.955
24;26;25.034
26;27;2.889
27;29;11.895
29;30;3.063
30;36;179.431
36;44;167.632
44;46;38.033
46;47;18.13
47;48;68.317

time details (first;last;value)
0;8;21622
8;11;5416
11;12;132
12;16;5124
16;18;3173
18;19;1534
19;20;951
20;21;170
21;22;766
22;23;3619
23;24;3147
24;26;1408
26;27;226
27;29;930
29;30;239
30;36;11962
36;44;11175
44;46;2535
46;47;3263
47;48;12297

if we try to align instructions and detail intervals, we will get:

(name;time;distance;interval first;interval last)
1) CG-2;47062;836.753927254391;0;26
2) CG-2;24532;364.91;26;44
3) CG-2;13710;205.66500000000002;36;46
4) <no name>;15560;86.44699999999999;46;48
5) <no name>;0;0.0

as we see, two instructions contain interval [36-44] with time=11175 and distance=167.632 that are exactly match the difference we saw in the beginning.

I observed such behaviour for shortest and custom weightings. Didn’t check it with fastest one.

Let me know if it’s a bug or I did a mistake in my experiments.

Thanks for the detailed description, this sounds like two bugs.

Regarding the bug with the distance&time mismatch - can you try?

--- a/core/src/main/java/com/graphhopper/util/details/DistanceDetails.java
+++ b/core/src/main/java/com/graphhopper/util/details/DistanceDetails.java
@@ -32,8 +32,8 @@ public class DistanceDetails extends AbstractPathDetailsBuilder {
 
     @Override
     public boolean isEdgeDifferentToLastEdge(EdgeIteratorState edge) {
-        if (edge.getEdge() != edgeId) {
-            edgeId = edge.getEdge();
+        if (edge.getEdgeKey() != edgeId) {
+            edgeId = edge.getEdgeKey();

similar for the TimeDetails.

best.time=120864
instructions.time=100864 # turn cost is 20 seconds

This might be a known (and different) bug, see the discussion here: ResponsePath time not equal sum instruction times? - #3 by Juan_Pablo_Lopez )

For this, if you like, you can try the following patch:

--- a/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java
+++ b/core/src/main/java/com/graphhopper/routing/InstructionsFromEdges.java
@@ -430,8 +430,10 @@ public class InstructionsFromEdges implements Path.EdgeVisitor {
         }
         double newDist = edge.getDistance();
         prevInstruction.setDistance(newDist + prevInstruction.getDistance());
-        // todo: why do we not account for turn times here ?
-        prevInstruction.setTime(weighting.calcEdgeMillis(edge, false) + prevInstruction.getTime());
+        if (prevEdge != null)
+            prevInstruction.setTime(GHUtility.calcMillisWithTurnMillis(weighting, edge, false, prevEdge.getEdge()) + prevInstruction.getTime());
+        else
+            prevInstruction.setTime(weighting.calcEdgeMillis(edge, false) + prevInstruction.getTime());

btw: I highly recommend against using the shortest weighting for car (use the custom weighting with a high distance influence instead). Maybe we should better remove the shortest.

Can you try the fix https://github.com/graphhopper/graphhopper/pull/2626 ?

yes, I’ll be back asap

with this fix every works for me - all distance and time values are the same. awesome :+1:

1 Like
Powered by Discourse