文章:链接: python geopandas读取gis路网,最找最短路径
该文给出了基本的思路,但是给出的代码只是图片;细节也没有讲清楚。这里进一步补充。
计算路网的起点和终点坐标
结点数据带有id编号
路网数据带有id编号和长度
对路网数据进行两次迭代的空间连接(一对多)即可,下面介绍具体思路:
假设道路L,其两端为A、B两点;对L和结点空间连接(一对多),得到两条结果:L(A)、L(B)
对得到的结果再次进行空间连接(一对多),得到四条结果:L(A-A)、L(A-B)、L(B-B)、L(B-A)
再删除掉冗余的L(A-A)、L(B-B)、L(B-A)得到了想要的L(A-B)
空间连接参数设置如下,进行两次连接,第二次连接的目标要素为第一次空间连接的输出要素
选择起点终点坐标一样的元素,即删除L(A-A)、L(B-B)
余下L(A-B)、L(B-A)
由于L(A-B)、L(B-A)都是代表同一条路,根据道路的ID,删除相同项,余下L(A-B)、L(B-A)中的任一个,可构建无向图
绘制地图
读取shp,绘制地图
# -*- coding: utf-8 -*-
"""
Created on Thu Jul 28 17:22:05 2022
@author: xza
"""
import matplotlib.pyplot as plt
import geopandas as gp
import contextily as ctx
import networkx as nx
import pandas as pd
#读取shp文件
roadfile="Road.shp"
pointfile="point.shp"
road_shp = gp.read_file(roadfile).to_crs('EPSG:3857')#变换投影为web墨卡托即EPSG:3857
point_shp = gp.read_file(pointfile).to_crs('EPSG:3857')#变换投影为web墨卡托即EPSG:3857
#显示地图
fig, ax = plt.subplots(figsize=(10,10))
ax = road_shp.plot(ax=ax, alpha=0.1, edgecolor='k')
ax.axis('off')
road_shp.plot(ax=ax,linewidth=1.5,color='black')#alpha设置透明度
point_shp.plot(ax=ax,markersize=8)
ctx.add_basemap(ax,
source='https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
zoom=12)
计算最短路径
#计算最短路径
#nx.Graph() 无向图
#nx.DiGraph() 有向图
G=nx.from_pandas_edgelist(road_shp,'Point_x','Point_y',edge_attr=['RoadID','Length'],create_using=nx.Graph())
#起点和终点的结点id
start_node=1342
end_node=2792
path=nx.shortest_path(G,start_node,end_node,weight='Length')
#获取路径(DataFrame格式)
def GetPath(path,road):
pathroad=pd.DataFrame()
for i in range(len(path)-1):
node1=path[i]
node2=path[i+1]
r1=road[(road['Point_x']==node1)&(road['Point_y']==node2)]
r2=road[(road['Point_x']==node2)&(road['Point_y']==node1)]
pathroad=pathroad.append(r1)
pathroad=pathroad.append(r2)
return pathroad
path_road=GetPath(path,road_shp)
#DataFrame格式转为GeoDataFrame
path_road_shp = gp.GeoDataFrame(path_road, geometry=path_road.geometry)
networkx计算的路径,为每个结点的id
根据结点id找出对应的道路,即已知结点ID:A、B;道路L(A-B)由A-B唯一确定。
绘制结果图
#绘制结果图
fig, ax = plt.subplots(figsize=(10,10))
ax = road_shp.plot(ax=ax, alpha=0.1, edgecolor='k')
ax.axis('off')
road_shp.plot(ax=ax,linewidth=1.5,color='black')#alpha设置透明度
path_road_shp.plot(ax=ax,linewidth=3,color='r')#alpha设置透明度
ctx.add_basemap(ax,
source='https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
zoom=12)
新开通了本人的公众号,欢迎关注:燕南路GISer ,专注GIS干货分享,不定期更新。
主要兴趣:GIS、时空数据挖掘、python、机器学习深度学习
CSDN的部分内容会重写再搬迁到公众号,欢迎关注!