如何解决如何沿最近的边找到最近的节点?
我从这里使用这个脚本:link
我想为其添加新功能。我希望它不仅通过找到最近的节点(因为这会产生奇怪的结果,例如在另一条道路上找到最近的节点)来定义图上的起始节点,而且还要找到沿该边的最近和最近的节点。 我的代码在下面可用。我创建了 findnearestnodeonnearestedge 函数,它应该可以完成工作,但它不起作用。 它为起点和终点找到相同的节点,即使它们相距很远...... 我正在使用所有软件包的最新版本,因此您可以轻松地尝试代码。
感谢您的帮助
import osmnx as ox
import networkx as nx
import plotly.graph_objects as go
import numpy as np
def findnearestnodeonnearestedge(Gr,pointin):
u,v,key = ox.distance.nearest_edges(G,pointin[0],pointin[1])
n1 = Gr.nodes[u]
n2 = Gr.nodes[v]
d1 = ox.distance.euclidean_dist_vec(pointin[0],pointin[1],n1['x'],n1['y'])
d2 = ox.distance.euclidean_dist_vec(pointin[0],n2['x'],n2['y'])
if d1 < d2:
nodeid = u
else:
nodeid = v
return nodeid
state = ox.geocode_to_gdf('Georgia,US')
ax = ox.project_gdf(state).plot(fc='gray',ec='none')
_ = ax.axis('off')
# Defining the map boundaries
north,east,south,west = 33.798,-84.378,33.763,-84.422
# Downloading the map as a graph object
G = ox.graph_from_bBox(north,west,network_type = 'drive')
# Plotting the map graph
ox.plot_graph(G)
# displaying the 3rd node
list(G.nodes(data=True))[2]
# displaying the 1st edge
list(G.edges(data=True))[1]
# displaying the shape of edge using the geometry
list(G.edges(data=True))[1][2]['geometry']
# define origin and desination locations
origin_point = (33.787201,-84.405076)
destination_point = (33.764135,-84.394980)
# get the nearest nodes to the locations
origin_node = findnearestnodeonnearestedge(G,origin_point)
destination_node = findnearestnodeonnearestedge(G,destination_point)
# printing the closest node id to origin and destination points
origin_node,destination_node
# Finding the optimal path
route = nx.shortest_path(G,origin_node,destination_node,weight = 'length')
route
# getting coordinates of the nodes
# we will store the longitudes and latitudes in following list
long = []
lat = []
for i in route:
point = G.nodes[i]
long.append(point['x'])
lat.append(point['y'])
def plot_path(lat,long,origin_point,destination_point):
"""
Given a list of latitudes and longitudes,origin
and destination point,plots a path on a map
Parameters
----------
lat,long: list of latitudes and longitudes
origin_point,destination_point: co-ordinates of origin
and destination
Returns
-------
nothing. Only shows the map.
"""
# adding the lines joining the nodes
fig = go.figure(go.ScattermapBox(
name="Path",mode="lines",lon=long,lat=lat,marker={'size': 10},line=dict(width=4.5,color='blue')))
# adding source marker
fig.add_trace(go.ScattermapBox(
name="Source",mode="markers",lon=[origin_point[1]],lat=[origin_point[0]],marker={'size': 12,'color': "red"}))
# adding destination marker
fig.add_trace(go.ScattermapBox(
name="Destination",lon=[destination_point[1]],lat=[destination_point[0]],'color': 'green'}))
# getting center for plots:
lat_center = np.mean(lat)
long_center = np.mean(long)
# defining the layout using mapBox_style
fig.update_layout(mapBox_style="stamen-terrain",mapBox_center_lat=30,mapBox_center_lon=-80)
fig.update_layout(margin={"r": 0,"t": 0,"l": 0,"b": 0},mapBox={
'center': {'lat': lat_center,'lon': long_center},'zoom': 13})
fig.show()
plot_path(lat,destination_point)
# Getting the start and end node of this part
start_node=route[-7]
end_node=route[-6]
# Getting the edge connecting these nodes and storing it as a list in z to maintain the data structure of G.edges
z = []
for i in list(G.edges(data=True)):
if (i[0]==start_node) & (i[1]==end_node):
z.append(i)
z[0][2]['geometry']
def node_list_to_path(G,node_list):
"""
Given a list of nodes,return a list of lines that together follow the path
defined by the list of nodes.
Parameters
----------
G : networkx multidigraph
route : list
the route as a list of nodes
Returns
-------
lines : list of lines given as pairs ( (x_start,y_start),(x_stop,y_stop) )
"""
edge_nodes = list(zip(node_list[:-1],node_list[1:]))
lines = []
for u,v in edge_nodes:
# if there are parallel edges,select the shortest in length
data = min(G.get_edge_data(u,v).values(),key=lambda x: x['length'])
# if it has a geometry attribute (ie,a list of line segments)
if 'geometry' in data:
# add them to the list of lines to plot
xs,ys = data['geometry'].xy
lines.append(list(zip(xs,ys)))
else:
# if it doesn't have a geometry attribute,the edge is a straight
# line from node to node
x1 = G.nodes[u]['x']
y1 = G.nodes[u]['y']
x2 = G.nodes[v]['x']
y2 = G.nodes[v]['y']
line = [(x1,y1),(x2,y2)]
lines.append(line)
return lines
# getting the list of coordinates from the path (which is a list of nodes)
lines = node_list_to_path(G,route)
long2 = []
lat2 = []
for i in range(len(lines)):
z = list(lines[i])
l1 = list(list(zip(*z))[0])
l2 = list(list(zip(*z))[1])
for j in range(len(l1)):
long2.append(l1[j])
lat2.append(l2[j])
print("Length of lat: ",len(lat))
print("Length of lat2: ",len(lat2))
plot_path(lat2,long2,destination_point)
解决方法
问题在于图中坐标以相反的顺序存储。所以函数中的所有pointin[0]和pointin[1]都应该颠倒,然后它就可以工作了
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。