2

I spent a lot of time reading and testing the example notebooks of OSMnx but I couldn't figure out a way to simply calculate the travel time from a given point (GPS coordonates) to an other one. I would like to estimate, for each point from my list, how long it takes to go to a specific point (sometimes 100km away). I don't need to generate a graph/map/plot, as I only need the duration of each trip (and I think that OSMnx maps render better at a city-scale).

I am pretty desperate as I could not find a simple way to do this across different Python libraries... If doing this calculation for +-10k points within a country-scale map is asking too much from OSMnx, could a locally stored pbf file of the country be helpful for another solution?

Trag0
  • 25
  • 1
  • 6
  • Try this? https://www.movable-type.co.uk/scripts/latlong.html – James Oct 10 '21 at 00:09
  • Thank you, but I am looking for the travel time (by walking, cycling or driving) and this seems to only measure distance? – Trag0 Oct 10 '21 at 00:26
  • If you only have GPS points then you can't directly calculate these details. You need to know the allowed speeds. Walking can be estimated by using the average walk speed. It depends on what other information you can get about the location point. Is the information in JSON with other details or is it just a pure GPS location? – James Oct 10 '21 at 09:07
  • I know you don't want to hear it but have you considered using Google Maps API instead? Google have invested huge amounts of money in mapping all street details for most of the world. Your query against the data is simple in python using Google Maps API. These maps are kept up to date. https://medium.com/future-vision/google-maps-in-python-part-2-393f96196eaf – James Oct 10 '21 at 09:35
  • @James What I have is pure GPS location of my points. I looked at Google Maps API but there is a ratelimit, that is why I wanted to use OSRM or Graph Hopper (the APIs used by Opens Street Map), as they also seem pretty accurate (and open!) – Trag0 Oct 10 '21 at 12:49
  • In that case without additional information from the system, all you can do is estimate walking time. To estimate travel time using vehicles you will not be able to account for road speed limits. Hence, using google maps API might be better as that will use additional data like road speeds etc... – James Oct 10 '21 at 12:54
  • You can calculate travel times with OSMnx, accounting for speed limits, with no rate limiting. – gboeing Oct 10 '21 at 14:43
  • @gboeing thank you for your answer. Could you please provide an example snippet doing this job for two given GPS points (e.g. getting the travel time to go from London (51.5073509, -0.1277583) to Oxford (51.752022, -1.257677) by bike)? That would get me out of many troubles – Trag0 Oct 10 '21 at 18:13
  • @gboeing Your [example notebook](https://github.com/gboeing/osmnx-examples/blob/main/notebooks/02-routing-speed-time.ipynb) shows how to calculate the time of travel between two nodes of the graph (e.g. `dest = list(G)[120]`, i.e. the 121st node of the graph if I'm correct), but I did not find how to input GPS coordinates... PS: is it possible to load a graph for a whole region/country, not just _n_ km around a given city? – Trag0 Oct 14 '21 at 09:04
  • I'll provide you some example code today when time permits. – gboeing Oct 14 '21 at 18:16

1 Answers1

0

There are inherent trade-offs when you want to model a large study area such as an entire region or an entire country: 1) model precision vs 2) area size vs 3) memory/speed. You need to trade off one of these three.

For the first, you can model a coarser-grained network, such as only major roads in the region/country, rather than millions of fine-grained residential streets and paths. For the second, you can study a smaller area. For the third, you can provision a machine with lots of memory and then let the script run for a while to complete the process. What you trade off will be up to your own needs for this analysis.

In the example code below, I chose to trade off #1: I've modeled this region (West Midlands) by its motorways and trunk roads. Given a different analytical goal, you may trade off other things instead. After creating the model, I randomly sample 1000 origin and destination lat-long points, snap them to the nearest nodes in the graph, and solve the shortest paths by travel time (accounting for speed limits) with multiprocessing.

import osmnx as ox

# get boundaries of West Midlands region by its OSM ID
gdf = ox.geocode_to_gdf('R151283', by_osmid=True)
polygon = gdf.iloc[0]['geometry']

# get network of motorways and trunk roads, with speed and travel time
cf = '["highway"~"motorway|motorway_link|trunk|trunk_link"]'
G = ox.graph_from_polygon(polygon, network_type='drive', custom_filter=cf)
G = ox.add_edge_speeds(G)
G = ox.add_edge_travel_times(G)

# randomly sample lat-lng points across the graph
origin_points = ox.utils_geo.sample_points(ox.get_undirected(G), 1000)
origin_nodes = ox.nearest_nodes(G, origin_points.x, origin_points.y)
dest_points = ox.utils_geo.sample_points(ox.get_undirected(G), 1000)
dest_nodes = ox.nearest_nodes(G, dest_points.x, dest_points.y)

%%time
# solve 1000 shortest paths between origins and destinations
# minimizing travel time, using all available CPUs
paths = ox.shortest_path(G, origin_nodes, dest_nodes, weight='travel_time', cpus=None)
# elapsed time: 9.8 seconds

For faster modeling, you can load the network data from a .osm XML file instead of having to make numerous calls to the Overpass API. OSMnx by default divides your query area into 50km x 50km pieces, then queries Overpass for each piece one a time to not exceed the server's per-query memory limits. You can configure this max_query_area_size parameter, as well as the server memory allocation, if you prefer to use OSMnx's API querying functions rather than its from-file functionality.

gboeing
  • 5,691
  • 2
  • 15
  • 41
  • Thank you for your answer! Is there a way, within a region loaded as you did with West Midlands, to get the `shortest_path` between two precise latlon points (and not randomly sampled ones)? All the best – Trag0 Oct 20 '21 at 06:43
  • Yes. Just pass whatever coordinates you want into the `nearest_nodes` function. – gboeing Oct 20 '21 at 14:58