問題
做專案的時候發現osm自定義區域匯出后,還是會有延伸到區域外的資料,且會影響其他軟體匯入osm后的錨點,如下圖,黑色背景的區域全是多余的資料

推測官網匯出的規則為:只要某條道路的其中一部分存在于我們選擇的區域內,osm就會匯出該條道路包含的全部節點,
這個問題似乎沒辦法避免,于是想到了用python手動處理一下osm資料,將多余節點洗掉,
分析
首先進行分析,我們先觀察一下osm的資料格式

發現osm資料采用的也是xml格式,所以我們可以使用ElementTree API來處理
我們還能看到,其中第3行bounds正是我們所設定的匯出區域范圍,而其他node也有它們自己所在的經緯度資訊
所以方法很簡單:我們先獲取到bounds的經緯資訊,再用它來遍歷所有node做對比,洗掉經緯度不在范圍內的行即可,

注意在所有node列出后,還有一些way塊,經過對比可發現,其中子節點nd的ref屬性正對應前面node的id屬性,說明從這里開始的資料是在參考前面的節點來構成道路,所以我們刪了某個node后同樣需要到后面把它的參考也刪掉,否則后續匯入就會報錯!
分析完畢,下面直接上代碼,
代碼
#author:dizzyding
#date:2020/9/16
#verison:python3.8
import xml.etree.ElementTree as xee
def osmProcess():
# 讀取檔案
domTree = xee.parse("osm.osm")
# 獲得所有節點的內容
root = domTree.getroot()
# 獲得所選區域的經緯度范圍
bound = root.findall("bounds")
maxLat = float(bound[0].get("maxlat"))
maxLon = float(bound[0].get("maxlon"))
minLat = float(bound[0].get("minlat"))
minLon = float(bound[0].get("minlon"))
# 輸出所選區域的經緯度范圍
print('Bounds:' + '\n' + 'minLat: ' + str(minLat) + '\n' + 'maxLat: ' + str(maxLat) + '\n' +
'minLon: ' + str(minLon) + '\n' + 'maxLon: ' + str(maxLon) + '\n' +'Nodes: ')
# 存盤不在所選區域內的node ID
IDlist = []
# 逐個檢查node
nodes = root.findall("node")
for node in nodes:
# 當前節點的經緯度和ID
Lat = float(node.get("lat"))
Lon = float(node.get("lon"))
ID = node.get("id")
#輸出node資訊
print('nodeID:' + ID + ', Lat:' + str(Lat) + ', Lon:' + str(Lon) + ', Bound: ' , end='')
# 判斷
if Lat < minLat or Lat > maxLat or Lon < minLon or Lon > maxLon:
root.remove(node)
IDlist.append(ID)
#輸出bound比對情況,若Lat和Lon均不符合則只輸出Lat
if Lat < minLat:
print('Lat < min')
elif Lat > maxLat:
print('Lat > max')
elif Lon < minLon:
print('Lon < min')
elif Lon > maxLon:
print('Lon > max')
else:
print('Satisfied')
# 洗掉不在所選區域內的node在后續道路的參照行
ways = root.findall("way")
for ID in IDlist:
for way in ways:
refnodes = way.findall("nd")
for node in refnodes:
if node.get("ref") == ID:
way.remove(node)
# 輸出檔案
domTree.write("out.osm",encoding="utf8")
if __name__=="__main__":
osmProcess()
效果
運行完后效果是這樣的,超出的節點全被干掉了

丟進Houdini里也能直接居中對齊了,不用再手動調引數

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/67986.html
標籤:其他
下一篇:Pandas基本常用操作
