@@ -16,17 +16,18 @@ class OsrmRouteRequest:
1616
1717
1818@dataclasses .dataclass
19- class OsrRouteResponse :
19+ class OsrmRouteResponse :
2020 paths : list [list [types .Position ]]
2121 distances : list [float ]
2222 durations : list [float ]
2323 zero_distance : bool = False
24+ no_route : bool = False
2425
2526
2627def query_route (
2728 endpoint : str ,
2829 route : OsrmRouteRequest ,
29- ) -> OsrRouteResponse :
30+ ) -> OsrmRouteResponse :
3031 """
3132 Queries a route from the OSRM server.
3233 """
@@ -40,9 +41,26 @@ def query_route(
4041 # Query OSRM
4142 try :
4243 response = requests .get (url )
44+ # If no route was found, use as-the-crow-flies fallback
45+ if response .status_code == 400 and response .json ()["code" ] == "NoRoute" :
46+ print (
47+ f"Warning: OSRM was unable to find a route for { [(p .lat , p .lon ) for p in route .positions ]} "
48+ + "(lat,lon ordering), using as-the-crow-flies fallback"
49+ )
50+ paths , distances , durations = [], [], []
51+ for f , t in zip (route .positions , route .positions [1 :], strict = False ):
52+ paths .append (
53+ [types .Position (lon = f .lon , lat = f .lat , desc = None ), types .Position (lon = t .lon , lat = t .lat , desc = None )]
54+ )
55+ distances .append (common .haversine (f , t ))
56+ durations .append (common .haversine (f , t ) / TRAVEL_SPEED )
57+ return OsrmRouteResponse (paths = paths , distances = distances , durations = durations , no_route = True )
58+ # Make sure we are not getting an error
4359 response .raise_for_status ()
4460 except requests .exceptions .RequestException as e :
4561 print (f"Error querying OSRM at { url_base } :" , e )
62+ if response :
63+ print (response .text )
4664 sys .exit (1 )
4765 result = response .json ()
4866 if result ["code" ] != "Ok" :
@@ -85,13 +103,13 @@ def query_route(
85103 print (f"Warning: number of legs ({ len (legs )} ) does not match number of positions ({ len (route .positions )} - 1)" )
86104
87105 # Extract route
88- return OsrRouteResponse (paths = legs , distances = distances , durations = durations , zero_distance = all_zero_distances )
106+ return OsrmRouteResponse (paths = legs , distances = distances , durations = durations , zero_distance = all_zero_distances )
89107
90108
91109def query_routes (
92110 endpoint : str ,
93111 routes : list [types .Route ],
94- ) -> list [OsrRouteResponse ]:
112+ ) -> list [OsrmRouteResponse ]:
95113 """
96114 Queries multiple routes from the OSRM server.
97115
@@ -103,13 +121,17 @@ def query_routes(
103121
104122 # Query all routes
105123 reqs = [OsrmRouteRequest (positions = route .points ) for route in routes ]
106- zero_distance_routes = 0
124+ zero_distance_routes , no_route_routes = 0 , 0
107125 for r , req in enumerate (reqs ):
108126 result = query_route (endpoint , req )
109127 routes [r ].legs = result .paths
110128 routes [r ].leg_distances = result .distances
111129 routes [r ].leg_durations = result .durations
112130 if result .zero_distance :
113131 zero_distance_routes += 1
132+ if result .no_route :
133+ no_route_routes += 1
114134 if zero_distance_routes > 0 :
115135 print (f"Warning: { zero_distance_routes } / { len (routes )} routes have zero distance according to OSRM" )
136+ if no_route_routes > 0 :
137+ print (f"Warning: { no_route_routes } / { len (routes )} routes could not be found by OSRM" )
0 commit comments