路网自动构建路段拓扑
背景
在做道路匹配的時候,你發(fā)現(xiàn)很多論文都是基于路網(wǎng)的拓撲關(guān)系做的,但是問題就是:如何構(gòu)建路網(wǎng)的拓撲關(guān)系?一般的論文都已經(jīng)在構(gòu)建好拓撲關(guān)系的基礎上直接拿來用,有些論文說是使用MapInfo、MapX等等工具生成拓撲關(guān)系(我沒試過,但是好像也需要寫代碼)。
其實,在ArcGIS里面,稍稍研究一下,間接就能建立路段之間的拓撲關(guān)系了。
然而,在百度搜“ArcGIS建立拓撲”,多數(shù)都是拓撲關(guān)系的處理,比如批量消除偽節(jié)點、懸掛點等等(對路網(wǎng)數(shù)據(jù)的處理確實很好用),和本文主題說的路段拓撲關(guān)系構(gòu)建不是一個概念。
補充
正文
路段拓撲的定義:在路網(wǎng)數(shù)據(jù)中,使用"弧-結(jié)點"形式的數(shù)據(jù)結(jié)構(gòu)來表示,弧段由兩個端點定義:指示弧段起始位置的起始節(jié)點,指示弧段終止位置的終止節(jié)點。這被稱為弧-結(jié)點拓撲。正是由于有這樣的結(jié)構(gòu),只要路段收尾相連不斷開,就能保證路網(wǎng)的連通性。
在ArcGIS里面,有一種用于存儲矢量數(shù)據(jù)的地理相關(guān)數(shù)據(jù)模型,它叫:Coverage。當Coverage生成的時候,它就包括了節(jié)點(node)、弧段(arc)、tic文件。這就可以基于coverage的存儲結(jié)構(gòu)使用這些文件來進行路段拓撲的構(gòu)建。
那么,為什么coverage可以做到呢?因為Coverage具有連通性、區(qū)域定義、鄰接、生成拓撲的功能。我們看一張ArcGIS官方對Coverage的連通性描述:
從圖片中可以看出,在交叉路口(相鄰的邊),邊與邊共享同一個結(jié)點。例如:路段1的起點ID是10,終點ID是11。路段2的起始ID是11,終點ID是12。則路段1.endID=路段2.startID。具有這種連通性拓撲結(jié)構(gòu)的網(wǎng)絡,才是我們需要的路段拓撲。
構(gòu)建路段拓撲需要的準備: 首先,你得有一份路網(wǎng)數(shù)據(jù)。當然,一般的路網(wǎng)數(shù)據(jù)都是有各種問題的,這個需要我們處理,比如:路網(wǎng)的偽節(jié)點、懸掛點等等情況。
當你已經(jīng)處理好了這樣的數(shù)據(jù)了(即一條路以交叉路口為分界),如下圖所示,你就可以開始構(gòu)建路段拓撲了。
開始構(gòu)路段建拓撲:
一、新建一個個人地理數(shù)據(jù)庫,然后道路你的路網(wǎng)數(shù)據(jù),然后建立集合網(wǎng)絡。
其中,構(gòu)建出來的幾何網(wǎng)絡有一個叫:xxx_Junction的,這個是路段的起點和終點。(再次聲明:要按照上述準備階段處理完的路網(wǎng)結(jié)構(gòu)才行!)
二、路網(wǎng)數(shù)據(jù)導出Coverage格式
在你的個人地理數(shù)據(jù)庫里面,右鍵你的路網(wǎng)數(shù)據(jù)–>導出–>轉(zhuǎn)為Coverage。
到這一步,要把剛才的xxx_Junction一起選入。
三、簡單瀏覽導出的Coverage文件
這時候,就會生成節(jié)點文件、弧段文件、tic文件、原路網(wǎng)文件。其中,我們重點關(guān)注是arc弧段文件。
我們來分析一下arc弧段文件:FNODE是起點編號(下文"編號"統(tǒng)統(tǒng)用"ID"來稱呼),TNODE是終點ID。其余一些屬性是系統(tǒng)自動生成的,沒什么實際用處,我們重點來關(guān)注FNODE和TNODE即可。
我們來測試一下它生成路段的起始ID和終點ID是否正確:
通過多次隨機抽取路段進行對比,都是正確的。其中,路段顯示方向這個是根據(jù)direction字段進行可視化顯示的,與數(shù)字化道路方向相同或相反(有的使用oneway字段)。但是,無論是direction還是oneway字段,都是你路網(wǎng)數(shù)據(jù)有的,要么你自己抽取出來。
四、arc弧段文件導出shp格式:
右鍵arc弧段文件–>導出
五、把arc弧段文件和原路網(wǎng)文件進行合并處理(重要的一步)
ArcToolbox–>分析工具–>疊加分析–>相交
把兩個文件的相交部分合并在一起,這樣arc弧段文件的起點ID和終點ID的屬性列表也就合并在原文件里面了。
六、查看合并結(jié)果
經(jīng)過對比分析,每條路段的起點ID、終點ID是一致的。并且,上一路段的終點ID等于下一路段的起點ID。
補充
關(guān)于上面生成的道路節(jié)點,只需要記住:snode是數(shù)字化道路的起點,enode是數(shù)字化道路的終點,就可以了。
至于加入direction方向(可參考我另一篇博客:數(shù)字化方向)來判斷之后,會顯得很繞。但是大概的拓撲關(guān)系我都寫在下圖了。
結(jié)語
連續(xù)整了好幾天,終于整出來了。其實,我不是學地理信息專業(yè)的,但是有句話說得很好:念念不忘,必有回響。距離發(fā)表論文還是有段距離,寫下來記錄一下自己的成果吧。 現(xiàn)在論文被錄了,這篇博客就可以放出來了~
其實,在構(gòu)建路段拓撲的時候,也有過A、B、C等等一系列的解決方案,都失敗了,最后還是這個方案成功了。也說說其他方案的處理,或許能給其他人提供解決方案。
A方案:ArcGIS里面能提出每條路段的起始、終止節(jié)點。數(shù)據(jù)管理工具–>要素–>要素折點轉(zhuǎn)點。但是提取出來的端點編號全部不一致,無法做到上一路段的終點ID等于下一路段的起點ID。
B方案:PostGreSQL數(shù)據(jù)庫里面,有一個交Pgrouting的內(nèi)置處理命令可以對路網(wǎng)數(shù)據(jù)自動構(gòu)建拓撲,具體命令如下所示:
select pgr_createTopology('wgs84testsegments',0.001, 'geom', 'gid');但是,我嘗試過了用這個命令生成的拓撲結(jié)構(gòu),em…反正我單從表面邏輯上沒看出來有什么道路的連通性。
C方案:由于之前我不知道有“相交”這個功能,我得到arc弧段文件后,使用python對文件進行處理。因為arc弧段文件和原路網(wǎng)文件實際上是一樣的,只是記錄的屬性表不一樣(即使是一樣的,但是每個點的經(jīng)緯度還是不一樣,因為要具體到小數(shù)點后7位之后,只是肉眼看不出來,以為是一樣的)。我把arc弧段的起點和終點的經(jīng)緯度提取出來,和原路網(wǎng)文件的起點、終點的經(jīng)緯度進行比較,如果一樣,就把arc弧段文件的拓撲屬性丟給原文件。這時候我發(fā)現(xiàn),即使在ArcMap里面看起來一樣的點,實際上小數(shù)點后7位之后的數(shù)字還是不一樣。無果,放棄。
D方案:就是本文的方案,完美解決。
打完收工~
總結(jié)
以上是生活随笔為你收集整理的路网自动构建路段拓扑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 路在脚下,梦已启程
- 下一篇: 分布式事务Seata源码解析十:AT模式