把 App 的主要功能完成後,實際跑了一段散步流程,發現 GPS 每次收到新的 point 後,後面還會連帶做不少事情。
但這些工作其實不一定都需要跟著 GPS 一起更新。
例如地圖 Polyline、Camera、Navigation Step,甚至一些 SQLite 和畫面更新,都可以再看看是不是每個 point 都真的有必要處理。
所以這次主要整理的是 GPS point 收到之後的處理流程。
GPS 本身沒有調整:
desiredAccuracy:high
interval:5 秒
fastestInterval:2.5 秒
distanceFilter:5 公尺
GPS point 該怎麼記錄還是維持原本的方式,這次主要是把後面的工作分開看,哪些需要即時處理,哪些其實可以不用每次都做。
原本 DisplayTrackBuffer 就已經有控制更新頻率,這次只是把 updateIntervalMs: 1500 改成 updateIntervalMs: 4000,GPS point 還是照原本流程處理,也還是會正常保存到 SQLite。
差別只有地圖上的綠線不用更新得那麼頻繁。
GPS point
↓
DisplayTrackBuffer
↓
每 4 秒更新一次
↓
Map Polyline
所以這次沒有減少 GPS point,也沒有修改原本的軌跡簡化。
只是讓 MapView 少做一些 Polyline 更新。
Camera Follow 原本就有時間和距離兩個條件,用來決定什麼時候需要讓地圖鏡頭跟著使用者移動。
這次把這兩個條件的門檻調高。
原本是距離上次 Camera 移動不到 1.2 秒 或 使用者移動不到 1 公尺 → 不更新 Camera
改成距離上次 Camera 移動不到 3 秒 或 使用者移動不到 5 公尺 → 不更新 Camera
也就是必須同時經過 3 秒,而且移動至少 5 公尺,才會執行 animateCamera。
例如使用者只是正常往前走,GPS 持續收到新的位置:
GPS point
↓
移動 1 公尺
→ Camera 不動
GPS point
↓
又移動 2 公尺
→ Camera 不動
繼續走
↓
累積超過 5 公尺
且
距離上次 Camera 更新超過 3 秒
↓
Camera Follow
GPS 還是照原本的頻率取得位置,地圖上的使用者位置也沒有因此停止更新。
這次單純是讓 animateCamera 不需要因為每個 GPS point 的小幅位移就執行一次。
推薦路線模式下,GPS point 還是會正常進行 Route Matching 和 Off-route Detection。
這兩個沒有改。
有改的是 Navigation Step。
原本每個 point 都會重新計算目前的 step 和剩餘距離。
這次增加兩個條件:
符合其中一個才重新計算。如果兩個條件都還沒到,就直接使用上一次的計算結果。
這樣可以避免使用者只是往前走了一小段距離,就重新做一次 Navigation Step 的計算。
導航狀態會保存到 walk_navigation_state。
原本每個處理過的 GPS point 都會寫一次。
但 GPS point 本身已經另外保存到 walk_points,導航狀態沒有必要也跟著每個 point 寫一次。
所以這次改成一般情況下最多每 8 秒保存一次。
遇到重要事件則立即保存,例如:
所以一般情況:
GPS point
↓
還沒到 8 秒
↓
不寫 checkpoint
重要事件:
重要事件
↓
立即保存 checkpoint
這樣減少的是 walk_navigation_state 的 SQLite 寫入。
walk_points 仍然是每個 GPS point 立即保存,沒有改。
這次 SQLite 還有一個地方有調整,但不是 GPS point 的保存。
原本每收到一個 GPS point,在寫入 walk_points 的同時,還會順便檢查 sync_queue。
也就是每個 point 都會多做一次同步相關的資料庫操作。
這次把它分開。
GPS point:
GPS point
↓
Filter
↓
立即寫入 walk_points
同步工作則不需要每個 point 都檢查,而是在累積一定資料或經過一段時間後再處理。
Pause 和 Stop 時也會先處理剩餘的同步資料,避免散步結束時還有資料沒有排進同步流程。
這裡沒有改 GPS point 的保存方式。
改的是:
GPS point 不需要每次都順便處理 Sync Queue。
推薦路線的 Route Matching 還是每個 accepted GPS point 都會執行。
這次改的是後面的畫面更新。
如果新的 Route Progress 和上一次完全一樣,就不再執行 setProgress(...)
會比較:
progress
distance
completed
remaining
如果都沒有變化,就跳過更新。
所以流程變成:
GPS point
↓
Route Matching
↓
計算 Route Progress
↓
結果有變化?
├─ 是 → setProgress
└─ 否 → 不更新
Route Matching 本身沒有因此降低頻率。
整理一下,今天這次真正有動的主要是這幾個地方:
| 項目 | 原本 | 現在 |
|---|---|---|
| Map Polyline | 每 1.5 秒 | 每 4 秒 |
| Camera Follow | 1.2 秒 + 1 公尺 | 3 秒 + 5 公尺 |
| Navigation Step | 每個 point 重算 | 4 秒或 8 公尺 |
| Navigation Checkpoint | 每個 point 保存 | 最多 8 秒,重要事件立即保存 |
| Sync Queue | 每個 point 檢查 | 累積資料或經過一段時間再處理 |
| Route Progress UI | 每次都 setProgress |
結果沒變就跳過 |
而這些東西都沒有改:
5 秒 / 2.5 秒 / 5 公尺 / high accuracy
walk_points 每個 GPS point 立即保存所以這次不是把 GPS 調慢,也不是減少 GPS point。
主要就是把幾個原本跟著 GPS point 一起做的工作調整一下,這樣可以少做一些不必要的更新。