I need to get the driving time and distance between two sets of coordinates using Python and an open source mapping service ( preferably OSM).
I found a lot of different python libraries that can calculate the distance between two given points (locations) but it is not the driving distance.
I also noticed that using the Google Distance Matrix API and a JSON interpreter I can pretty much do this but I don't want to use google for this project. Please advise on an appropriate library that uses Open Street Map network and calculates the travel time and distance and preferably allows for creating a map of the selected route.
p.s. I noticed that a similar task is done using OSM but not with python
The math. dist() method returns the Euclidean distance between two points (p and q), where p and q are the coordinates of that point. Note: The two points (p and q) must be of the same dimensions.
distance((lat1, lon1), (lat2, lon2)). km . There are different ellipsoid models available, the previous function uses the WGS-84 model and here's an alternative syntax: distance. geodesic((lat1, lon1), (lat2, lon2), ellipsoid='WGS-84').
For this divide the values of longitude and latitude of both the points by 180/pi. The value of pi is 22/7. The value of 180/pi is approximately 57.29577951. If we want to calculate the distance between two places in miles, use the value 3, 963, which is the radius of Earth.
You can now make use of the OSMnx package together with the NetworkX package to find the route between two points. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. The default method for finding the shortest path is ' dijkstra '.
You could use OSMnx.
Here is a sample code that do what you're asking for:
import osmnx as ox
import networkx as nx
from datetime import timedelta
# The place where your 2 points are located. It will be used to create a graph from the OSM data
# In this example, the 2 points are two addresses in Manhattan, so we choose "Manhattan"
# It could be a bounding box too, or an area around a point
graph_area = ("Manhattan, New York, USA")
# Create the graph of the area from OSM data. It will download the data and create the graph
G = ox.graph_from_place(graph_area, network_type='drive')
# OSM data are sometime incomplete so we use the speed module of osmnx to add missing edge speeds and travel times
G = ox.add_edge_speeds(G)
G = ox.add_edge_travel_times(G)
# Save graph to disk if you want to reuse it
ox.save_graphml(G, "Manhattan.graphml")
# Load the graph
#G = ox.load_graphml("Manhattan.graphml")
# Plot the graph
fig, ax = ox.plot_graph(G, figsize=(10, 10), node_size=0, edge_color='y', edge_linewidth=0.2)
# Two pairs of (lat,lng) coordinates
origin_coordinates = (40.70195053163349, -74.01123198479581)
destination_coordinates = (40.87148739347057, -73.91517498611597)
# If you want to take an address (osmx will use Nominatim service for this)
# origin_coordinates = ox.geocode("2 Broad St, New York, NY 10005")
# In the graph, get the nodes closest to the points
origin_node = ox.get_nearest_node(G, origin_coordinates)
destination_node = ox.get_nearest_node(G, destination_coordinates)
# Get the shortest route by distance
shortest_route_by_distance = ox.shortest_path(G, origin_node, destination_node, weight='length')
# Plot the shortest route by distance
fig, ax = ox.plot_graph_route(G, shortest_route_by_distance, route_color='y', route_linewidth=6, node_size=0)
# Get the shortest route by travel time
shortest_route_by_travel_time = ox.shortest_path(G, origin_node, destination_node, weight='length')
# Plot the shortest route by travel time
fig, ax = ox.plot_graph_route(G, shortest_route_by_travel_time, route_color='y', route_linewidth=6, node_size=0)
# Plot the 2 routes
fig, ax = ox.plot_graph_routes(G, routes=[shortest_route_by_distance, shortest_route_by_travel_time], route_colors=['r', 'y'], route_linewidth=6, node_size=0)
# Get the travel time, in seconds
# Note here that we use "nx" (networkx), not "ox" (osmnx)
travel_time_in_seconds = nx.shortest_path_length(G, origin_node, destination_node, weight='travel_time')
print(travel_time_in_seconds)
#The travel time in "HOURS:MINUTES:SECONDS" format
travel_time_in_hours_minutes_seconds = str(timedelta(seconds=travel_time_in_seconds))
print(travel_time_in_hours_minutes_seconds)
# Get the distance in meters
distance_in_meters = nx.shortest_path_length(G, origin_node, destination_node, weight='length')
print(distance_in_meters)
# Distance in kilometers
distance_in_kilometers = distance_in_meters / 1000
print(distance_in_kilometers)
And by the way thanks to Geoff Boeing for this great library!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With