Thursday, March 16, 2017

關於累計爬升的小實驗

在天氣好的時候,回家後只要還有空,幾乎都會騎單車沿著行義路騎到陽明山的小七當作日常運動。同時,我幾乎都會打開 Runkeeper 來作紀錄。某天忽然注意到,當儲存活動時它圖表裡的海拔爬升會先是 0,然後過一會兒才出現數值。

後來用估狗一查,發現原來 Runkeeper 要先把座標送到一個叫作 Topocoding 的網路服務,取得海拔 (Elevation) 之後才開始計算爬升值。

Runkeeper 的圖表
那麼為什麼不直接用 GPS 紀錄到的高度值 (Altitude) 呢?GPS 不準嗎?我想應該不是每台GPS都不準,猜測主要是因為 Runkeeper 為了要讓你跟自己的其它行程比較,或跟朋友進行比較,因此需要一個共同的海拔基準。意思就是,即便 Topocoding 的海拔本身沒有很準 (在台灣),至少拿來比較是可以比較出活動強度的。

一時興起拿了幾個軟體來計算兩筆 GPS 航跡,這兩筆分別是從兩支不同手機裡的同一個 APP 所紀錄下來。APP 並未對原始數據進行處理,但紀錄者是否有調整過最短距離及最少時間則不得而知。其一是單車從天母沿行義路往上騎至陽明山總站旁的小七,另一則是從南安登山口健行瓦拉米。第一個行程的原始數據基本上還蠻平滑的,即使各家數據有差但尚可接受。然而第二個數據原始數據看起來很「跳」,各家呈現的結果也非常戲劇化。

行義路單車

瓦拉米健行
怎麼會差這麼多?走過瓦拉米的山友大概都會覺得爬升 2870 甚至是 2026 都有點誇張!

為了滿足好奇心,DIY 寫了支可以讀取 KML 來計算統計值的程式,其中加入了海拔修正的功能,因此跑出來的數據包含:
至於 Topocoding 則因為它只能在網站裡執行因此在這裡無法列入比較。

首先來看一下最高及最低海拔的部份。

行義路單車
瓦拉米健行
從實驗結果大概可以發現,OruxMaps 及綠野遊蹤都沒有進行海拔修正,即使我在 OruxMaps 中加入了「在線高度服務」或在綠野遊蹤中加入了 HGT 檔,統計結果都沒有改變,猜想這部份的修正只會套用在正在紀錄的航跡。而 Google Earth 看起來是會修正海拔的,而且數值跟使用 Google Elevation API 一致。合理推測,即使不是使用 Google Elevation API,至少數據來源相同。

問題來了:如果 Google Earth 有進行海拔修正,而且修正的結果也跟內政部DTM差不多,基本上修正的準確度應該是足夠的。然而瓦拉米健行的爬升值還是令人感到意外,到底海拔修正對於統計值到底有沒有幫助?我們直接使用手邊最正確的海拔資料來源,也就是內政部20公尺網格DTM來進行比較。

行義路單車

瓦拉米健行
結果非常出人意表:經過最精確修正的海拔竟然算出最誇張的結果。難道海拔修正是豬隊友嗎?我們展開海拔值來看看。
行義路單車
瓦拉米健行
從行義路單車的圖表看來,GPS 在一開始時海拔錯誤很大,這部份套用了海拔修正是有幫助的。另外我們也可以發現,相較於 MapQuest Elevation API,Google Elevation API 比較接近內政部DTM而且也比較平滑。而 MapQuest Elevation API 不只誤差有點大,而且修正完比原本更「跳」;除此之外同是線上服務,MapQuest Elevation API 的速度非常慢,真的可以說是豬隊友。

此外,修正完的結果似乎也打臉了 Runkeeper。在最前面的手機截圖中我們可以看到行義路單車的高度剖面是未修正的。至於為何與網站上宣稱的不同,也許是 Topocoding 沒有台灣的資料?其根本原因就不在本文的討論範圍內了。

接下來,我們來比較一下不同日期同一路線同一支手機紀錄下來的行義路航跡。

行義路單車


從圖表來看海拔修正真的是有幫助的。原本明明是同一路線,但一開始的海拔差異還蠻大的;在經過海拔修正後,兩者的差異就變小許多。

所以除了 MapQuest 之外,海拔修正不應該是豬隊友。為了更深入探討,在程式計算累計爬升及下降時加入了低通濾波器,用來進行曲線平滑化。其中的 Alpha 參數由 0.1~1.0,值愈小愈平滑,1.0 則代表不做平滑處理。

行義路單車
瓦拉米健行
從數據上大概可以看出,OruxMaps 的統計值大約等於 Alpha 值 0.2 的結果。而綠野遊蹤的統計值大約等於 Alpha 值 0.9~1.0 的結果。而 Google Earth 這邊有點特別,即使可以推測是採用 Google Elevation API 的 DTM,但卻無法對應到某個 Alpha 值。

從手邊另一筆有問題的航跡來推測,原因可能是因為 Google Earth 有進行 Resampling 的處理。

武嶺單車
剖面圖中被選取的部份是 GPS 紀錄因為不明原因中斷的路程,如果直接使用原始資料的話,剖面圖應該會是一條直直的斜坡才對。然而在 Google Earth 上則在地圖上畫出一條沿地表投影的紅線,然後在剖面圖中是有高低起伏的。然而若要考慮 Resampling 則需要更多的時間另開支線任務來討論,在此就先行打住。

綜合以上的實驗,大概可以觀察出:
  1. OruxMaps 的統計值「未進行海拔修正」且「經過高度平滑處理」。
  2. 綠野遊蹤的統計值「未進行海拔修正」且「經過低度或無平滑處理」。
  3. Google Earth 的統計值「有進行海拔修正」且「重新取樣過」,但平滑處理尚未能得知。
也能歸納出一些結論:
  1. 相同的 GPS 裝置即使在相同路線也可能會紀錄出差異很大的航跡,更不要說是不同型號的機器了;另外,也不能排除某些裝置在紀錄時已經做過海拔修正甚至是平滑處理的可能性,畢竟低通濾波器在訊號處理中是極為常見的。
  2. 海拔修正不能確保「統計值」的正確性,但可以確保「海拔值」的正確性,也能讓不同航跡在進行比較時有「一致性」。
  3. 要取得合理的統計結果,某程度的平滑處理是必要的。但 OruxMaps 採取的高度平滑處理或許過猶不及,可能會低估像聖稜線這樣在短距離內有很多起伏的路線。
因此,當自己的航跡要提供給其它人參考,或取得其它人的航跡來參考時,建議先進行海拔校正來取得一致性。然而在比較的時候,最好是使用相同的程式。

簡單地說,就是當你想要比較北一段跟北二段的總爬升時,不要拿北一段在 OruxMaps 裡的統計值跟北二段在 Google Earth 裡的統計值做比較。

註:目前 GPS Visualizer 有提供線上服務可以上傳 KML 或 GPX 轉為海拔修正過的 GPX 格式。但測試程式暫時只能讀取 KML 所以無從與內政部20公尺網格DTM作比較。

(原始統計數據請參考:Google Drive)