如何使用OSM和Python找到两个坐标之间的路径和距离?

cld4siwp  于 2023-04-10  发布在  Python
关注(0)|答案(2)|浏览(207)

我需要使用Python和开源Map服务(* 最好是OSM*)获取两组坐标之间的行驶时间和距离。
我发现了很多不同的Python库,可以计算两个给定点(位置)之间的距离,但它不是驾驶距离。
我还注意到,使用谷歌距离矩阵API和JSON解释器,我几乎可以做到这一点,但我不想使用谷歌为这个项目。请建议在一个适当的库,使用开放的街道Map网络,计算旅行时间和距离,最好允许创建一个Map的选择路线。

  • p.s.我注意到类似的任务是使用OSM完成的,而不是使用python*
6mzjoqzu

6mzjoqzu1#

你可以使用OSMnx
下面是一个示例代码,可以完成您所要求的操作:

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')
# (For a better accuracy, create a graph with lot more nodes:)
#G = ox.graph_from_place(graph_area, network_type='drive', simplify=False)

# 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.nearest_nodes(G, Y=origin_coordinates[0], X=origin_coordinates[1])
destination_node = ox.nearest_nodes(G, Y=destination_coordinates[0], X=destination_coordinates[1])

# 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='travel_time')

# 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", 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", 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_meters)
# Distance in kilometers
distance_in_kilometers = distance_in_meters / 1000
print("distance in kilometers", distance_in_kilometers)

顺便说一句,感谢杰夫波音为这个伟大的图书馆!

更新2023相对于@KBurchfiel评论:

事实上,它将取决于路径的形状。有时它会更准确,但有时它会更不准确。看看这些图像(它们来自https://github.com/nathanrooy/taxicab):

您可以做两件事来产生更准确的距离测量:
1.创建图表时添加simplify=FalseG = ox.graph_from_place(graph_area, network_type='drive', simplify=False)。你的图将有更多的节点。
1.使用nathanrooy的Taxicab
下面是一个使用Taxicab的例子:

import osmnx as ox
import networkx as nx
import taxicab as tc

# Load the graph
G = ox.load_graphml("Manhattan.graphml")
origin_coordinates = (40.70195053163349, -74.01123198479581)
destination_coordinates = (40.87148739347057, -73.91517498611597)
route = tc.distance.shortest_path(G, origin_coordinates, destination_coordinates)
tc.plot.plot_graph_route(G, route)

请注意,Taxicab只有距离的功能,而不是旅行时间。我现在没有时间编码它,但如果你或其他读者有它,请随时添加它在这里和/或贡献Taxicab/Osmnx ;- )

cigdeys3

cigdeys32#

刚刚搜索了你,我没有测试它,但这似乎是你正在寻找的:http://wiki.openstreetmap.org/wiki/PyrouteLib

相关问题