多个源节点和目标节点上的 Networkx 最短路径分析
Networkx Shortest Path Analysis on multiple source and target nodes
我有:
- 学校点的地理数据框(来源 - 共 18 个)
- 医院 pts 的地理数据框(目标 - 总共 27 个)
- 投影的 Osmnx 图(节点 + 边)
我想要的:
- 包含从每所学校到每家医院的最短路线几何图形的地理数据框(table 中共有 486 [18*27] 个要素,每个要素都有一条路线)
即
school id
hospital id
route
xxxxxxxxx
xxxxxxxxxxx
LineString(x,x,x)
阅读schools/hospitals后,拉动并投影osmnx街道图
我能够定义一个函数来获取源点和目标点的 neareset osm 节点
# import neceessary modules
import pandas as pd
import geopandas as gpd
import osmnx as ox
import networkx as nx
import matplotlib.pyplot as plt
from pyproj import CRS
from shapely.geometry import Polygon, Point, LineString
)
# read in file
hosp_fp = r'vtData/hospitals.shp'
school_fp = r'vtData/schools.shp'
# read files
hospitals = gpd.read_file(hosp_fp)
schools = gpd.read_file(school_fp)
#### skip the reading osmnx part (the error isn't here and, yes,everything in same crs) ######
# Create function to find nearest node
def get_nearest_node(points, graph):
# a function that finds the nearest node
# params: points (a gdf of points with an x and y column); graph (an osm network graph)
points['nearest_osm'] = None
for i in tqdm(points.index, desc='find nearest osm node from input points', position=0):
points.loc[i, 'nearest_osm'] = ox.get_nearest_node(graph, [points.loc[i, 'y'], points.loc[i, 'x']], method='euclidean') # find the nearest node from hospital location
return(points)
# use the function to find each destination point nearest node
## returns the original gdfs with corresponding osmid column
source = get_nearest_node(schools, graph)
target = get_nearest_node(hospitals, graph)
# extract osmid's from list
src_list = list(source['nearest_osm'])
trg_list = list(target['nearest_osm'])
### WHERE I AM STUCK ####
# a function meant to construct shortest path routes to each target from each source
def get_routes(graph, src_list, trg_list):
# a function that constructs a shortest routes to each target from the source
# params: graph_proj (a projected osmnx graph); src (source pts); trg (target pts)
# an empty list to append route linestring geometries to
routes = []
# a loop to construct all shortest path geometries
for src, trg in zip(src_list, trg_list):
sp = nx.shortest_path(graph, source=src, target=trg,
weight='length')
routes.append(sp)
print(len(routes))
我没有返回 486 条路由(每个源和目标一个),而是只得到一个列表
18个点(基本上只是根据对应的指标计算路线
源点和目标点,而不是为每所学校计算 27 条最短路线(医院总数)
从这里开始,我会将列表附加到一个名为路线的新地理数据框中,但我的 486 条路线中只有 18 条
您正在寻找出发地和目的地的笛卡尔积,而不是将它们压缩在一起。示例:
import numpy as np
import osmnx as ox
from itertools import product
ox.config(log_console=True)
# get a graph and add edge travel times
G = ox.graph_from_place('Piedmont, CA, USA', network_type='drive')
G = ox.add_edge_travel_times(ox.add_edge_speeds(G))
# randomly choose 10 origins and 10 destinations
n = 10
origs = np.random.choice(G.nodes, size=n)
dests = np.random.choice(G.nodes, size=n)
# calculate 100 (10 origins x 10 destinations) shortest paths
paths = []
for o, d in product(origs, dests):
path = ox.shortest_path(G, o, d, weight='travel_time')
paths.append(path)
len(paths) #100
我有:
- 学校点的地理数据框(来源 - 共 18 个)
- 医院 pts 的地理数据框(目标 - 总共 27 个)
- 投影的 Osmnx 图(节点 + 边)
我想要的:
- 包含从每所学校到每家医院的最短路线几何图形的地理数据框(table 中共有 486 [18*27] 个要素,每个要素都有一条路线) 即
school id | hospital id | route |
---|---|---|
xxxxxxxxx | xxxxxxxxxxx | LineString(x,x,x) |
阅读schools/hospitals后,拉动并投影osmnx街道图
我能够定义一个函数来获取源点和目标点的 neareset osm 节点
# import neceessary modules
import pandas as pd
import geopandas as gpd
import osmnx as ox
import networkx as nx
import matplotlib.pyplot as plt
from pyproj import CRS
from shapely.geometry import Polygon, Point, LineString
)
# read in file
hosp_fp = r'vtData/hospitals.shp'
school_fp = r'vtData/schools.shp'
# read files
hospitals = gpd.read_file(hosp_fp)
schools = gpd.read_file(school_fp)
#### skip the reading osmnx part (the error isn't here and, yes,everything in same crs) ######
# Create function to find nearest node
def get_nearest_node(points, graph):
# a function that finds the nearest node
# params: points (a gdf of points with an x and y column); graph (an osm network graph)
points['nearest_osm'] = None
for i in tqdm(points.index, desc='find nearest osm node from input points', position=0):
points.loc[i, 'nearest_osm'] = ox.get_nearest_node(graph, [points.loc[i, 'y'], points.loc[i, 'x']], method='euclidean') # find the nearest node from hospital location
return(points)
# use the function to find each destination point nearest node
## returns the original gdfs with corresponding osmid column
source = get_nearest_node(schools, graph)
target = get_nearest_node(hospitals, graph)
# extract osmid's from list
src_list = list(source['nearest_osm'])
trg_list = list(target['nearest_osm'])
### WHERE I AM STUCK ####
# a function meant to construct shortest path routes to each target from each source
def get_routes(graph, src_list, trg_list):
# a function that constructs a shortest routes to each target from the source
# params: graph_proj (a projected osmnx graph); src (source pts); trg (target pts)
# an empty list to append route linestring geometries to
routes = []
# a loop to construct all shortest path geometries
for src, trg in zip(src_list, trg_list):
sp = nx.shortest_path(graph, source=src, target=trg,
weight='length')
routes.append(sp)
print(len(routes))
我没有返回 486 条路由(每个源和目标一个),而是只得到一个列表 18个点(基本上只是根据对应的指标计算路线 源点和目标点,而不是为每所学校计算 27 条最短路线(医院总数)
从这里开始,我会将列表附加到一个名为路线的新地理数据框中,但我的 486 条路线中只有 18 条
您正在寻找出发地和目的地的笛卡尔积,而不是将它们压缩在一起。示例:
import numpy as np
import osmnx as ox
from itertools import product
ox.config(log_console=True)
# get a graph and add edge travel times
G = ox.graph_from_place('Piedmont, CA, USA', network_type='drive')
G = ox.add_edge_travel_times(ox.add_edge_speeds(G))
# randomly choose 10 origins and 10 destinations
n = 10
origs = np.random.choice(G.nodes, size=n)
dests = np.random.choice(G.nodes, size=n)
# calculate 100 (10 origins x 10 destinations) shortest paths
paths = []
for o, d in product(origs, dests):
path = ox.shortest_path(G, o, d, weight='travel_time')
paths.append(path)
len(paths) #100