(數據科學學習手札80)用Python編寫小工具下載OSM路網數據

本文對應腳本已上傳至我的Github倉庫https://github.com/CNFeffery/DataScienceStudyNotes

1 簡介

  我們平時在數據可視化或空間數據分析的過程中經常會需要某個地區的道路網絡及節點數據,而OpenStreetMap就是一個很好的數據來源(譬如圖1柏林路網):

圖1

  通常我們可以在 https://www.openstreetmap.org/export 中選擇矩形區域內的路網矢量數據進行下載,但這種方式對選擇區域的大小有一定限制,想獲取較大範圍區域的路網數據並下載比較費事;而另一種方式是事先下載已經整合好的大區域的文件,譬如在 http://download.geofabrik.de/ 中提供了各大洲、國家等大範圍的數據整合包,可以花費一定時間將其下載下來,再在需要哪些小區域時在本地GIS軟件或編程工具中裁剪下所需的範圍路網,但這種方式一是對電腦資源要求較高,譬如中國範圍路網信息shapefile文件大小達到了800多兆,二是OSM的路網信息不定期更新之後,要想及時跟上最新數據,就需要人工持續下載數據。

  為了更加靈活自由,且即時地獲取最新版本的OSM路網,我們可以利用Python,來編寫腳本工具方便快捷地檢索或下載OSM可以識別出的各個級別行政區對應的矢量格式數據。

2 基於Python的OSM路網下載

2.1 工作流程

  編寫這個工具靈感來源於 https://anvaka.github.io/city-roads/?q= 這個網站:

圖2

  用戶通過輸入指定城市的名稱並檢索,等待數據資源加載完成之後就可以在網頁中看到渲染好的城市路網,以重慶為例:

圖3

  通過對該網站進行抓包和源碼分析,我弄明白了其工作流程大致如下:

  • Step1:

    根據用戶輸入的城市名稱,利用OSM官方的API進行模糊匹配,獲取可能的對象列表:

圖4

  • Step2:

    用戶點擊選擇正確的區域,後台js對其所對應的id信息進行變換,再通過網站自帶的API獲取對應的.pbf格式數據,或overpass的API獲取JSON格式的矢量數據。

圖5

  • Step3:

    渲染路網:

圖6

  了解了上述步驟之後,我們利用requestsgeopandas等庫僅用不到100行代碼就可以參考上述過程,提取所需的shapefileGeoJSON文件保存到本地,具體的代碼部分本文不做詳細說明,我將這部分功能封裝到文章開頭對應Github倉庫下的OsmDownloader.pyhttps://github.com/CNFeffery/DataScienceStudyNotes/blob/master/(數據科學學習手札80)用Python編寫小工具下載OSM路網數據/OsmDownloader.py )中,可以自行去下載並使用,下面我們來學習如何在Python中使用它。

2.2 使用方式

  按照上文所述的地址下載對應腳本之後(請提前安裝完成requestsgeopandaspandas以及tqdm這幾個三方庫),記住其所在路徑,接着在其他腳本開頭導入模塊部分添加:

import sys  sys.path.append(r'所在路徑')  from OsmDownloader import OsmDownloader  

  這樣才能成功導入沒有在Python中註冊過的獨立模塊,接下來我們來下載數據,只需要兩行代碼即可完成對單個行政區路網數據的下載,以成都市為例:

# 單個地區路網下載  downloader = OsmDownloader(area='成都市') # area參數控制檢索的行政區,請盡量準確填寫  downloader.download_shapefile(path='保存路徑') # path參數控制文件保存的路徑  

  程序運行後稍等片刻即可完成下載(具體的耗時取決於你的網絡狀況),譬如這裡我花了不到20秒就完成成都市路網數據的下載:

圖7

  保存下來的數據線圖層與點圖層分開保存:

圖8
圖9

  如果你想要下載保存JSON格式的數據,換成downloader.download_geojson(path)即可,而如果你想要批量下載多個地區的數據,結合for循環即可,如下例:

# 多個地區路網下載  area_list = ['北京市', '重慶市江北區', 'Tokyo', 'Boston', '台灣省']  for area in area_list:  	downloader = OsmDownloader(area=area)  	downloader.download_shapefile(path='保存路徑')  

  等待一段時間後,我們area_list里多個不同級別行政區的路網數據便下載完成:

圖10

  如果擔心中途網絡連接原因導致中斷,可以結合Python中的錯誤捕捉機制來進行相對應的處理,比較簡單這裡就不再贅述。

  
  以上就是本文全部內容,對腳本獲取或使用有疑問的可以留言告訴我。