處理 OSM 資料
osm
格式為 openstreetmap.org API 較常使用的 XML 可讀格式,
基本上所有的後續加值資料都由此衍生而來。
例如,以下的 osm 物件包含 2 個 node 和 1 個 way:
<osm version="0.6">
<node id="2183019342" version="6" timestamp="2020-08-08T20:51:11Z" lat="23.9729809" lon="120.9261691">
<tag k="highway" v="traffic_signals"/>
</node>
<node id="7797369546" version="2" timestamp="2021-02-03T14:07:03Z" lat="23.972903" lon="120.9262552">
<tag k="highway" v="traffic_signals"/>
</node>
<way id="32811162" version="11" timestamp="2020-08-08T20:51:11Z">
<nd ref="7797369546"/>
<nd ref="369731714"/>
<tag k="highway" v="motorway_link"/>
<tag k="name" v="愛蘭交流道"/>
<tag k="name:zh" v="愛蘭交流道"/>
<tag k="oneway" v="yes"/>
</way>
</osm>
不過考慮到網路傳輸、儲存和地理空間的處理,通常會使用其它不同的格式。
可以在 OSM 的維基頁面中,找到更多相關資訊:
- 有關 OSM 格式: https://wiki.openstreetmap.org/wiki/OSM_XML
- 原始資料的取得: https://wiki.openstreetmap.org/wiki/Planet.osm
以下的範例可在 Linux 系統上使用,並以 osm.pbf
和 osmx
為主軸:
下載 OSM 台灣區切片
除了 OSM 基金會提供的主伺服器1之外,也有其它許多鏡像站可以下載全球或特定區域的原始資料:
https://wiki.openstreetmap.org/wiki/Planet.osm
這邊使用頁面中提到的 geofabrik 服務:
From Geofabrik
- Geofabrik 台灣切片頁面: http://download.geofabrik.de/asia/taiwan.html
- 可下載
osm.pbf
格式(無損),或shapfile
格式(有損) osm.pbf
格式較緊湊,容量較小,但搜尋上較慢。詳情可見 wiki 頁面2
建議下載後轉換為其它格式
- 可下載
# 使用 curl 指令下載
curl -O http://download.geofabrik.de/asia/taiwan-latest.osm.pbf
From KCWU
- 台灣山友
kcwu
提供的切片服務: http://osm.kcwu.csie.org/download/tw-extract/recent/- 可下載
o5m
格式(無損) o5m
雖然不可讀,但內部結構較接近osm
格式,因此查詢、處理速度較快。詳情可見 wiki 頁面3
- 可下載
# 使用 curl 指令下載
curl -O http://osm.kcwu.csie.org/download/tw-extract/recent/taiwan-latest.o5m
轉換資料格式
OSMExpress 格式在依 ID 或空間查詢時效率非常高,
雖然許多工具也可以直接查詢 osm.pbf
格式,但建議轉換為 OSMExpress
專屬的 .osmx
格式。
# 直接在 Github release 頁面下載 Linux 版本的 OSMExpress 命令行工具
curl -LO https://github.com/protomaps/OSMExpress/releases/download/0.2.0/osmexpress-0.2.0-Linux.tgz
# 用 tar 解壓縮
tar -zxvf osmexpress-0.2.0-Linux.tgz
# 使用命令行工具將 osm.pbf 格式轉換為 osmx 格式
./osmx expand taiwan-latest.osm.pbf taiwan.osmx
自行製作切片/查詢最近的路徑
osmx
指令可以取得較小範圍的區域切片
# 使用 bounding box 產生較小的 osm.pbf (南方緯度,西側經度,北方緯度,東側經度)
./osmx extract taiwan.osmx clip.osm.pbf --bbox 24.9752,121.6431,25.0067,121.68
# 或者,輸出人類可讀的 osm 格式
./osmx extract taiwan.osmx clip2.osm --bbox 24.9752,121.6431,25.0067,121.68
或者,直接找出與某點最相鄰的 osm 物件。
以下範例使用 osmx
格式,查找座標 E121.5° N24° 的點位,最近的路徑名稱。
在筆電上耗時約 0.2 秒。
# 使用 --disc 選項可以指定地點,用 <緯度,經度,半徑(經緯度)> 的格式來取得切片
# 經緯度在台灣大致換算:
# 0.005°: 450 公尺
# 0.0001°: 8~10 公尺
# 以下命令將取得 座標 E121.5° N24° 周圍 450 公尺的所有 osm 物件
./osmx extract taiwan.osmx clip3.osm --disc 24,121.5,0.005
# 使用管道命令和 gdal 來取得 GeoJSON 格式:
#
# gdal 在解析地理資料時預設會使用故定的 layer,
# 這邊我們只指定 lines 這個 layer,也就是只包含 way 物件
#
# 因為 osmx 命令行工具目前不提供 stdout 輸出的選項
# 故這邊使用 mkfifo 創造一個 named pipe 協作
mkfifo fifo.osm
osmx extract taiwan.osmx fifo.osm --disc 24,121.5,0.0005 | \
cat fifo.osm | \
ogr2ogr -f GEOJSON -nln foo /vsistdout/ /vsistdin/ lines
# 再加入 jq 的解析命令,即可取得道路名稱
# 輸出為:
# 白葉山路線
# 七腳川山路線
mkfifo fifo.osm
osmx extract taiwan.osmx fifo.osm --disc 24,121.5,0.0005 | \
cat fifo.osm | \
ogr2ogr -f GEOJSON -nln foo /vsistdout/ /vsistdin/ lines | \
jq '.features[]|.properties.name' -r
更新 OSM 圖資
geofabrik 的台灣圖資為每日更新,基本上要使用時再下載即可。
但若要在一天內更新數次,則需使用 OSMChange (.osc
) 格式的檔案進行 patch。
從不同來源下載的 OSM 原始資料,基本上都會標示Sequence Number
,用以區別生成時間。
可以使用這個數字,去取得更新到最新資料所需的 osc
檔案。
例如,geofabrik 為台灣區提供的 osc 目錄,可在以下網址確認:
http://download.geofabrik.de/asia/taiwan-updates/
# 取得 osmx 內的 Sequence Number
# 若原始資料由 geofabrik 而來,則可能是 3677
osmx query taiwan.osmx | grep Sequence | grep -o '[0-9]+'
# 取得 sequence 為 3678 的 osc 檔案
curl -o 3678.osc http://download.geofabrik.de/asia/taiwan-updates/000/003/678.osc.gz
# 解壓縮
gunzip 3678.osc.gz
# 為原始資料打上 Patch
# 標識 taiwan.osmx 新的 Sequence Number 為3687,並提供時間戳記
osmx update taiwan.osmx 3678.osc 3678 `date --iso-8601` --commit