From 18d2a948b8f0e643976c57998c14503f0b9c3404 Mon Sep 17 00:00:00 2001 From: Marius Merschformann Date: Thu, 24 Oct 2024 14:42:28 +0200 Subject: [PATCH 1/2] Use fallback when dealing with OSRM noroute errors --- nextplot/osrm.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/nextplot/osrm.py b/nextplot/osrm.py index 64ee1e7..4ea05d2 100644 --- a/nextplot/osrm.py +++ b/nextplot/osrm.py @@ -21,6 +21,7 @@ class OsrRouteResponse: distances: list[float] durations: list[float] zero_distance: bool = False + no_route: bool = False def query_route( @@ -40,9 +41,26 @@ def query_route( # Query OSRM try: response = requests.get(url) + # If no route was found, use as-the-crow-flies fallback + if response.status_code == 400 and response.json()["code"] == "NoRoute": + print( + f"Warning: OSRM was unable to find a route for {[(p.lat, p.lon) for p in route.positions]}" + + "(lat,lon ordering), using as-the-crow-flies fallback" + ) + paths, distances, durations = [], [], [] + for f, t in zip(route.positions, route.positions[1:], strict=False): + paths.append( + [types.Position(lon=f.lon, lat=f.lat, desc=None), types.Position(lon=t.lon, lat=t.lat, desc=None)] + ) + distances.append(common.haversine(f, t)) + durations.append(common.haversine(f, t) / TRAVEL_SPEED) + return OsrRouteResponse(paths=paths, distances=distances, durations=durations, no_route=True) + # Make sure we are not getting an error response.raise_for_status() except requests.exceptions.RequestException as e: print(f"Error querying OSRM at {url_base}:", e) + if response: + print(response.text) sys.exit(1) result = response.json() if result["code"] != "Ok": @@ -103,7 +121,7 @@ def query_routes( # Query all routes reqs = [OsrmRouteRequest(positions=route.points) for route in routes] - zero_distance_routes = 0 + zero_distance_routes, no_route_routes = 0, 0 for r, req in enumerate(reqs): result = query_route(endpoint, req) routes[r].legs = result.paths @@ -111,5 +129,9 @@ def query_routes( routes[r].leg_durations = result.durations if result.zero_distance: zero_distance_routes += 1 + if result.no_route: + no_route_routes += 1 if zero_distance_routes > 0: print(f"Warning: {zero_distance_routes} / {len(routes)} routes have zero distance according to OSRM") + if no_route_routes > 0: + print(f"Warning: {no_route_routes} / {len(routes)} routes could not be found by OSRM") From a9676feee673c4210102dbe62e518ebddb1baa62 Mon Sep 17 00:00:00 2001 From: Marius Merschformann Date: Thu, 24 Oct 2024 15:55:56 +0200 Subject: [PATCH 2/2] Fixing typo --- nextplot/osrm.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nextplot/osrm.py b/nextplot/osrm.py index 4ea05d2..c45b5b0 100644 --- a/nextplot/osrm.py +++ b/nextplot/osrm.py @@ -16,7 +16,7 @@ class OsrmRouteRequest: @dataclasses.dataclass -class OsrRouteResponse: +class OsrmRouteResponse: paths: list[list[types.Position]] distances: list[float] durations: list[float] @@ -27,7 +27,7 @@ class OsrRouteResponse: def query_route( endpoint: str, route: OsrmRouteRequest, -) -> OsrRouteResponse: +) -> OsrmRouteResponse: """ Queries a route from the OSRM server. """ @@ -54,7 +54,7 @@ def query_route( ) distances.append(common.haversine(f, t)) durations.append(common.haversine(f, t) / TRAVEL_SPEED) - return OsrRouteResponse(paths=paths, distances=distances, durations=durations, no_route=True) + return OsrmRouteResponse(paths=paths, distances=distances, durations=durations, no_route=True) # Make sure we are not getting an error response.raise_for_status() except requests.exceptions.RequestException as e: @@ -103,13 +103,13 @@ def query_route( print(f"Warning: number of legs ({len(legs)}) does not match number of positions ({len(route.positions)} - 1)") # Extract route - return OsrRouteResponse(paths=legs, distances=distances, durations=durations, zero_distance=all_zero_distances) + return OsrmRouteResponse(paths=legs, distances=distances, durations=durations, zero_distance=all_zero_distances) def query_routes( endpoint: str, routes: list[types.Route], -) -> list[OsrRouteResponse]: +) -> list[OsrmRouteResponse]: """ Queries multiple routes from the OSRM server.