Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

GPX 路線轉成軌跡後,點名與時間還在嗎?

里程不為零只是其中一項檢查。gpxpy 1.6.2 實測顯示,點欄位與重疊路徑仍須分別驗收。

原創示意圖:四種受控 GPX 容器範例及二維總長,其中混合範例刻意含有重疊路徑。
原創示意圖:四種受控 GPX 容器範例及二維總長,其中混合範例刻意含有重疊路徑。 Watch at Ease

gpxpy 對含有路線的檔案回傳零里程時,應先辨認檔案結構。轉成軌跡可以得到距離,也可能同時改變其他資訊。保留原檔,以重新開啟後的內容判斷結果,不要只看轉換成功訊息。

我們使用 Python 3.12.14 與已發布的 gpxpy 1.6.2 測試四份人工建立的 GPX 1.1 檔案:只有航點、只有路線、只有軌跡,以及路線和軌跡刻意使用相同座標的混合檔。這些不是實際行程,也不是導航裝置測試。

1. 先數容器,再決定處理方式

解析可信的本機副本後,檢查 len(gpx.waypoints)、len(gpx.routes)、len(gpx.tracks),以及每條軌跡的分段。GPX 1.1 區分獨立航點、有序路線點及軌跡分段。檔案中某處存在三個點,不能證明它記錄了一條軌跡,也不能證明獨立航點預期如何連接。

安裝套件中的全域長度方法會遍歷軌跡。如果只需要現有路線的二維長度,先對選定路線分別檢查 route.length()。它回傳公尺,不必轉換檔案。這不是路線爬升或三維距離的解法。

2. 有用的輔助函式也可能只保留少數欄位

gpxpy issue 290 的真實提問已說明路線檔案為何得到零值,也提供轉換輔助函式:以經緯度及海拔建立軌跡點,把路線層名稱當作軌跡名,再移除原路線。它未複製所有點欄位。基本問題已有答案。

我們的路線範例緯度都是 0,經度為 0、0.01、0.02,海拔為 10、20、30 公尺,每點各有一個時間、名稱、說明與自訂擴充。重現該函式語意後,軌跡距離變成非零,但儲存並重新開啟時,四類欄位數量均由三個降為零。路線層名稱仍在,點名已經不在。

3. 以一般儲存對照區分遺失來源

我們也在不轉換路線的情況下儲存並重新開啟檔案。GPX 1.1 對照保留三個時間、點名、說明與擴充元素。這項比較把範例中的變化定位到欄位有限的輔助函式,不能用來指責所有匯出操作或整個函式庫。

轉換前,為要保留的具體點建立欄位清單:座標、海拔、時間、點名、說明與必要擴充。轉換後重新開啟新檔,比較值、數量和預期順序,不要只確認是否存在任何名稱或時間。軌跡名和點名必須分別核對。

4. 明確決定哪些路徑只應計算一次

混合範例刻意讓一條路線與一條軌跡擁有相同座標。起初全域方法只計算既有軌跡;附加路線轉換出的軌跡後,檔案有兩條軌跡,二維總長由 2,226.39 公尺變為 4,452.78 公尺。這是人工建立的重疊情境,不代表所有混合檔都會重複計算。

加入測量軌跡前,先判斷路線是計畫、替代路線,還是同一路徑的另一種表示。保留所需分段邊界,避免在無關片段之間虛構連接路段。檢查路徑預覽,寫明哪些幾何物件計入長度;總數看起來合理,不能證明選擇正確。

5. 依明確清單驗收重新開啟的檔案

現有工具已公開轉換取捨。GPSBabel 1.10.0 文件說明刪除來源資料可避免重複,timeless 選項會影響時間複製。GPXAnalyzer 的獨立航點工具說明排序與可選點名,會省略說明及符號,也不能轉換只有路線的檔案。這些是文件範圍,我們沒有執行這些工具。

輸出請用新檔名,保留原始雜湊值與未修改副本。只有容器及分段數、選定路徑、必要點欄位值與名稱、單位及連接順序符合目標時,才接受結果。出現意外變化就停止並保留兩份檔案。本次原檔位元組完全未變;沒有驗證真實行駛距離或嚴格綱要符合性,也未測試 Garmin、BMW、Strava 或 GPSBabel 的執行表現。

原創示意圖:欄位有限的路線轉換遺失四類點欄位,一般 GPX 1.1 儲存對照則保留這些欄位。
原創示意圖:欄位有限的路線轉換遺失四類點欄位,一般 GPX 1.1 儲存對照則保留這些欄位。 Watch at Ease