活用 GIS 格式 M 值資料結構

在 GIS 格式中,我們最熟悉的是 X、Y 平面坐標;如果再加入 Z(高程),就成為 X、Y、Z 三維坐標。不過,比較少人知道的是,GIS 幾何其實還可以帶有另一個維度:M 值(Measure value)。M 值並不是高度,也不是另一個空間坐標,而是附加在每個節點(vertex)上的一個「量測值」。因此 GIS 幾何除了常見的 XY、XYZ 外,也可以有 XYM 或 XYZM。

M 值最典型的用途,是表達道路、鐵路、河川、管線等線性地物上「沿著線所在的位置」。例如,可以將每個節點的 M 值設定為距離路線起點的里程,形成所謂的 Linear Referencing System(LRS,線性參照系統)。白話來說,就是不用經緯度,而是用「沿著這條線走到哪裡」來描述位置。

例如一條高速公路採用 LineStringM 格式,其 geometry 可以表示為:

LINESTRING M (
(X1 Y1 0),
(X2 Y2 10),
(X3 Y3 20),
(X4 Y4 30)
)

每組坐標最後一個數值就是 M 值;若 M 值的單位設定為公里,上述節點就分別代表 0K、10K、20K、30K。M 可以理解成附著在 XY(或 XYZ)節點上的一維參數。它和在屬性資料表中另外建立一個「里程」欄位最大的不同,在於 M 是 geometry 本身的一部分,GIS 軟體因此可以直接依據相鄰節點的 M 值進行內插,支援線性參照以及 Dynamic Segmentation(動態分段)等應用。

例如現在有一起事故發生在:國道一號 120.650K。如果國道一號本身是一條具有正確 M 值的 LineStringM,在 QGIS 中便可以直接利用:

line_interpolate_point_by_m( $geometry, 120.65 )

取得 M=120.65 所對應的事故位置,而不必事先知道或另外測量該事故點的 X、Y 坐標。

這種資料模型特別適合描述公里樁、交通事故、速限、路面品質、施工區間、鐵路里程、河川測站或管線設施等資訊。例如一段道路施工區間只需要記錄:

From M = 120.65
To M   = 122.30

GIS 就可以依照道路 geometry,將 120.65K~122.30K 之間的實際空間位置動態呈現出來。

值得注意的是,M 值不一定等於 GIS 根據 XY 坐標所計算出的幾何距離。例如道路曾經改線、截彎取直,行政管理上沿用的公里牌里程仍可能保持原有編號,因此「道路里程」和「目前幾何線長」可能並不完全相同。這也正是 M value 存在的重要意義:它保存的是某套業務或管理上的線性參照系統,而不只是單純的幾何距離。

目前許多 GIS 格式與資料模型都能支援 M,包括 Shapefile、OGC WKT/WKB、GeoPackage、Esri File Geodatabase、PostGIS geometry,以及 JSON-FG 1.0 等。相較之下,網頁 GIS 常用的傳統 GeoJSON(RFC 7946)並沒有正式定義 M coordinate 的語意,這也是近年 JSON-FG 擴充 GeoJSON 能力時值得注意的一項特色。

QGIS 以及大部份空間資料庫對 M coordinate 的支援其實相當完整。除了可以讀寫 XYM/XYZM 幾何,也能直接編輯每個 vertex 的 M value、依指定 M 值定位線上位置,並將 M 用於幾何運算。因此,如果手上的資料本來就是以「道路幾公里」、「鐵路幾 K」、「河川距河口多少公里」來描述位置,那麼與其先將這些資料全部轉換成 X、Y 坐標,直接建立一套具有 M value 的線性參照資料,往往反而更符合資料原本的使用邏輯。

QGIS 活用案例

目前在政府資料開放平臺上,直接提供 M value(Measure value) 的 GIS 資料集並不常見。不過,如果既有資料本身包含明確的里程資訊,其實可以進一步自行建立具有 M 值的線資料。例如政府資料開放平臺提供的「國道百公尺里程樁」(https://data.gov.tw/dataset/95016),就是一個很適合的例子。這份資料沿著國道主線,每隔約 100 公尺設置一個點來表示里程位置,採用 KML 格式,坐標參考系統為 EPSG:4326(WGS 84),其中屬性欄位 Name 記錄該點所代表的道路里程,例如:014K+400,代表國道里程 14 公里 400 公尺

國道百公尺里程樁 KML是點資料型態,使用屬性資料表方式儲存里程數

由於這些點本身已經具有明確的線性里程順序,因此可以將各里程樁依序連接成線,並把原本記錄在屬性欄位中的里程資訊轉換成幾何本身的 M value。例如:014K+400 → M = 14.4 km。如此就可以把原本只有 XY 坐標的百公尺里程樁點資料,轉換成 PolyLineM(XYM) 線資料,讓道路里程正式成為 geometry 的一部分,而不只是存在屬性表中。

這類格式轉換現在也可以直接透過 LLM 協助處理。例如上傳 KML 檔案後,可以使用以下提示文字:

「這是一份國道百公尺里程樁 KML 點資料,坐標參考系統為 EPSG:4326。屬性欄位 Name 為道路里程,以 014K+400 這類格式表示。請將所有點依里程由小到大排序並連接成線,轉換為 GeoPackage  的 PolyLineM(XYM) 格式。」

下載:國道1號_PolyLineM.gpkg

轉檔後「國道1號_PolyLineM.gpkg」是線資料型態,原本的百公尺里程樁點位成為節點,里程數轉換為線資料幾何 M 值。

查詢事故點所在位置

  1. 將先前製作的「國道1號_PolyLineM.gpkg」載入 QGIS。
  2. 打開 處理工具箱(Processing Toolbox)
  3. 搜尋:
    Geometry by expression
    中文介面可能顯示為「依表達式建立幾何」或類似名稱。
  4. 設定參數:
    • Input layer:國道1號_PolyLineM
    • Output geometry typePoint
    • Output geometry has Z values:不勾
    • Output geometry has M values:不一定需要;如果只是定位顯示可不勾
    • Geometry expression:輸入:line_interpolate_point_by_m ($geometry, 120.65)
  5. 執行

QGIS 便會產生一個新的點圖層,該點即代表「國道 1 號 120K+650」所對應的實際地理位置。整個過程不需要另外撰寫程式,也無須進行複雜的空間分析。

直接查詢「國道 1 號 120K+650」所在地理位置

原本「國道百公尺里程樁 KML」資料只提供每 100 公尺一個點位,例如 120K+600 與 120K+700;若進一步將這些里程控制點與實際國道路線幾何結合,建立具有 M value 的 PolyLineM(LineStringM),就可以利用 M 值沿線內插的特性,取得兩個已知里程樁之間任意里程位置,例如 120K+650、120K+673 等。

這種方法的優點是,定位並不是單純在 120K+600 與 120K+700 兩個點之間畫一直線後進行比例內插,而是沿著實際道路的線形 geometry 計算。因此,即使道路具有彎道、曲折或交流道路段,只要 PolyLineM 本身正確反映實際道路中心線及其里程 M 值,GIS 就能沿著道路線形找到指定里程所在的位置,而不必事先為每一個里程數建立點位資料。

若進一步結合 AI 助理、自然語言查詢或簡易的里程查詢介面,使用者只要輸入里程數,即可快速定位到道路上的對應位置,對道路設施、事故地點、工程位置與里程管理等應用都十分方便。

直接在 QGIS Python Console 建立「里程定位」功能視窗,使用上十分便利。
使用者透過「里程定位」視窗輸入里程數就可以快速定位