Project-OSRM / osrm-backend

Open Source Routing Machine - C++ backend
http://map.project-osrm.org
BSD 2-Clause "Simplified" License
6.18k stars 3.29k forks source link

`Steps=true` option modifies the geometry response #3953

Open vinci1it2000 opened 7 years ago

vinci1it2000 commented 7 years ago

When running a API route service query using the steps option sometimes it returns two different geometries but same annotations.

Follows a python code to replicate the bug:

import requests
import polyline
import pandas as pd
urls = [
    'http://router.project-osrm.org/route/v1/driving/9.268558013555479,45.42256566115992%3B9.221927306655532,45.51650000195285?overview=false&overview=full&hints=%3B&annotations=nodes,distance',
    'http://router.project-osrm.org/route/v1/driving/9.150644636112535,45.416512787345255%3B9.12820434092079,45.467479188059706?overview=false&overview=full&hints=%3B&annotations=nodes,distance',
    'http://router.project-osrm.org/route/v1/driving/9.15,45.41%3B9.12,45.46?overview=false&overview=full&hints=%3B&annotations=nodes,distance'
]

for url in urls:
    res = []
    for step in ('false', 'true'):
        route = requests.get(url+ '&steps=' + step).json()['routes'][0]
        nodes = route['legs'][0]['annotation']['nodes']
        distance = route['legs'][0]['annotation']['distance']
        res.append(
            {
                'step': step,
                'geometry': route['geometry'],
                'len(geometry)': len(polyline.decode(route['geometry'], 5)),
                'len(node)': len(nodes),
                'nodes': str(nodes),
                'len(distance)': len(distance),
                'distance': str(distance)
            }
        )
    print(url)
    df = pd.DataFrame(res)
    df['geometry == geometry[0]'] = df.pop('geometry') == res[0]['geometry']
    df['nodes == nodes[0]'] = df.pop('nodes') == res[0]['nodes']
    df['distance == distance[0]'] = df.pop('distance') == res[0]['distance']
    print(df)

This is the response of the code:

http://router.project-osrm.org/route/v1/driving/9.268558013555479,45.42256566115992%3B9.221927306655532,45.51650000195285?overview=false&overview=full&hints=%3B&annotations=nodes,distance
   len(distance)  len(geometry)  len(node)   step geometry == geometry[0]  nodes == nodes[0] distance == distance[0]
0            503            504        504  false                    True       True                    True 
1            503            503        503   true                   False      False                    True   

http://router.project-osrm.org/route/v1/driving/9.150644636112535,45.416512787345255%3B9.12820434092079,45.467479188059706?overview=false&overview=full&hints=%3B&annotations=nodes,distance
   len(distance)  len(geometry)  len(node)   step geometry == geometry[0]  nodes == nodes[0] distance == distance[0]  
0            369            370        370  false                    True       True                    True 
1            369            369        369   true                   False      False                    True  

http://router.project-osrm.org/route/v1/driving/9.15,45.41%3B9.12,45.46?overview=false&overview=full&hints=%3B&annotations=nodes,distance
   len(distance)  len(geometry)  len(node)   step geometry == geometry[0]  nodes == nodes[0] distance == distance[0]
0            293            294        294  false                    True       True                    True   
1            293            294        294   true                    True       True                    True

First and second urls return different geometries (BUG), while the third (CORRECT) returns the same result with steps=true and steps=false.

Note: when steps=true the node length == the annotation length (according to #2511, this is a bug).

vinci1it2000 commented 7 years ago

I check that the last node is missing.

TheMarex commented 7 years ago

I think this might be related to post-processing on the turn instructions omitting the last coordinate which seems to be the same as the second last coordinate.

vinci1it2000 commented 7 years ago

what you said is valid for the first url but is not for the second one has the last distance ~= 0. Hence, the last and the second last coordinates are different.

oxidase commented 7 years ago

Steps to reproduce

curl -s 'http://router.project-osrm.org/route/v1/driving/9.2222883,45.5163789;9.221927306655532,45.51650000195285?overview=false&overview=full&hints=%3B&annotations=nodes,distance&steps=false' | jq '.routes[0].legs[0].annotation'
{
  "nodes": [
    1344438658,
    1344438579,
    269518197,
    1344438622
  ],
  "distance": [
    0,
    6.928318,
    0.111226
  ]
}
curl -s 'http://router.project-osrm.org/route/v1/driving/9.2222883,45.5163789;9.221927306655532,45.51650000195285?overview=false&overview=full&hints=%3B&annotations=nodes,distance&steps=true' | jq '.routes[0].legs[0].annotation'
{
  "nodes": [
    1344438579,
    269518197
  ],
  "distance": [
    6.928318,
    0.111226
  ]
}

The problem origin is in missing annotation for the source point. So geometry.annotations does not correspond to geometry.segment_offsets and the last annotation is not removed.

The corresponding FIXME is related to the issue.

EDIT: OSM https://www.openstreetmap.org/#map=19/45.51640/9.22223