今天要來寫GIS與路網相關的(當然只要跟graph有關的都可以使用,例如管線)一些應用。
在GIS及LBS應用中少不了路徑規劃,這些路網資料的應用路主要基於graph,networkX
可以用來建立及操作graph的工具,它可以產生各種garph,也包含了很多graph演算法。
大綱:
路網系統有很多應用,今天將使用台中市數位地圖館的台中市路網資料來做測試。
networkX
有支援將shp格式的node與edge轉為garph,然而我們原始拿到的路網資料並無node,需要拆解,這邊我們簡單使用一套s2g(shape2graph)的工具(產生無向圖)
我們先切一小塊來看
import geopandas as gpd
road = gpd.read_file('data/Road/road.shp',encoding='utf-8')
road
這邊發現這份路網是linestring Z,我們先把它轉為linestring,並轉坐標系統
from shapely.geometry import shape,LineString,Point
geoms =road['geometry']
geoms = [LineString([xy[0:2] for xy in list(geom.coords)]) for geom in geoms]
road['geometry']=geoms
road.to_file('data/Road/road2.shp',encoding='utf-8')
road
確認為linestring後,
使用sg ShapeGraph 把shp丟進去
from s2g import ShapeGraph
import networkx as nx
sg = ShapeGraph(shapefile='data/Road/road2.shp', to_graph=True)
g_nw = sg.to_networkx()
s2g產生要計算一段時間,產生下列訊息
拿到的g_nw就是networkX的graph格式
graph可以算node間的最短路徑,使用`shortest_path'
nearest_path= nx.shortest_path(graph, source=start_id, target=end_id)
其中input的是node的id
這邊我們先用sg物件內存的節點來手動給
sg.node_xy
我們先手動給start_id=1, end_id=30
nearest_path= nx.shortest_path(g_nw, source=5, target=19)
nearest_path
回傳結果:[5, 11, 14, 3, 18, 19]
繪圖:
base=road.plot()
geoms=[]
for item in nearest_path:
geoms.append(sg.node_xy[item])
train_lines = gpd.GeoDataFrame(crs= {'init' :'epsg:3826'},geometry=[LineString(geoms)])
train_lines.plot(ax=base,color='red')