鐵人賽2019 Day18 networkX與GIS資料初探

  1. 1. 路網圖資
  2. 2. 建立garph
  3. 3. graph操作

今天要來寫GIS與路網相關的(當然只要跟graph有關的都可以使用,例如管線)一些應用。

在GIS及LBS應用中少不了路徑規劃,這些路網資料的應用路主要基於graph,networkX可以用來建立及操作graph的工具,它可以產生各種garph,也包含了很多graph演算法。

大綱:

  • 路網圖資
  • 建立garph
  • graph操作

路網圖資

路網系統有很多應用,今天將使用台中市數位地圖館的台中市路網資料來做測試。

建立garph

networkX有支援將shp格式的node與edge轉為garph,然而我們原始拿到的路網資料並無node,需要拆解,這邊我們簡單使用一套s2g(shape2graph)的工具(產生無向圖)

我們先切一小塊來看

1
2
3
import geopandas as gpd
road = gpd.read_file('data/Road/road.shp',encoding='utf-8')
road

https://ithelp.ithome.com.tw/upload/images/20181102/20107816FzJWNwNOSf.png
https://ithelp.ithome.com.tw/upload/images/20181102/20107816RbHZfdagR9.png

這邊發現這份路網是linestring Z,我們先把它轉為linestring,並轉坐標系統

1
2
3
4
5
6
7
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

https://ithelp.ithome.com.tw/upload/images/20181103/201078169rjwa8h5NI.png

確認為linestring後,
使用sg ShapeGraph 把shp丟進去

1
2
3
4
5
from s2g import ShapeGraph
import networkx as nx

sg = ShapeGraph(shapefile='data/Road/road2.shp', to_graph=True)
g_nw = sg.to_networkx()

s2g產生要計算一段時間,產生下列訊息
https://ithelp.ithome.com.tw/upload/images/20181102/20107816jNiCyeYKUa.png
拿到的g_nw就是networkX的graph格式

graph操作

graph可以算node間的最短路徑,使用`shortest_path’

1
nearest_path= nx.shortest_path(graph, source=start_id, target=end_id)

其中input的是node的id
這邊我們先用sg物件內存的節點來手動給

1
sg.node_xy

我們先手動給start_id=1, end_id=30

1
2
nearest_path= nx.shortest_path(g_nw, source=5, target=19)
nearest_path

回傳結果:[5, 11, 14, 3, 18, 19]

繪圖:

1
2
3
4
5
6
7
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')

https://ithelp.ithome.com.tw/upload/images/20181103/20107816SntOGemFm2.png