iT邦幫忙

2026 iThome 鐵人賽

DAY 29
0
佛心分享-SideProject30

30 天開發一款真正能每天使用的散步 App系列 第 29

優化 GPS 收到點位後的處理流程

  • 分享至 

  • xImage
  •  

把 App 的主要功能完成後,實際跑了一段散步流程,發現 GPS 每次收到新的 point 後,後面還會連帶做不少事情。

但這些工作其實不一定都需要跟著 GPS 一起更新。

例如地圖 Polyline、Camera、Navigation Step,甚至一些 SQLite 和畫面更新,都可以再看看是不是每個 point 都真的有必要處理。

所以這次主要整理的是 GPS point 收到之後的處理流程

GPS 本身沒有調整:

  • desiredAccuracyhigh
  • interval5 秒
  • fastestInterval2.5 秒
  • distanceFilter5 公尺

GPS point 該怎麼記錄還是維持原本的方式,這次主要是把後面的工作分開看,哪些需要即時處理,哪些其實可以不用每次都做。

Map Polyline 不需要更新得那麼頻繁

原本 DisplayTrackBuffer 就已經有控制更新頻率,這次只是把 updateIntervalMs: 1500 改成 updateIntervalMs: 4000,GPS point 還是照原本流程處理,也還是會正常保存到 SQLite。

差別只有地圖上的綠線不用更新得那麼頻繁。

GPS point
↓
DisplayTrackBuffer
↓
每 4 秒更新一次
↓
Map Polyline

所以這次沒有減少 GPS point,也沒有修改原本的軌跡簡化。

只是讓 MapView 少做一些 Polyline 更新。

Camera Follow 不需要一直跟著 GPS 移動

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 的小幅位移就執行一次。

Navigation Step 不需要每個 GPS point 都重算

推薦路線模式下,GPS point 還是會正常進行 Route Matching 和 Off-route Detection。

這兩個沒有改。

有改的是 Navigation Step。

原本每個 point 都會重新計算目前的 step 和剩餘距離。

這次增加兩個條件:

  • 距離上次計算至少 4 秒
  • 或移動至少 8 公尺

符合其中一個才重新計算。如果兩個條件都還沒到,就直接使用上一次的計算結果。

這樣可以避免使用者只是往前走了一小段距離,就重新做一次 Navigation Step 的計算。

Navigation Checkpoint 不需要每個 point 都保存

導航狀態會保存到 walk_navigation_state

原本每個處理過的 GPS point 都會寫一次。

但 GPS point 本身已經另外保存到 walk_points,導航狀態沒有必要也跟著每個 point 寫一次。

所以這次改成一般情況下最多每 8 秒保存一次。

遇到重要事件則立即保存,例如:

  • 初始化
  • Pause
  • 偏離狀態改變
  • Navigation announce
  • 換步
  • 抵達

所以一般情況:

GPS point
↓
還沒到 8 秒
↓
不寫 checkpoint

重要事件:

重要事件
↓
立即保存 checkpoint

這樣減少的是 walk_navigation_state 的 SQLite 寫入。

walk_points 仍然是每個 GPS point 立即保存,沒有改。

GPS point 和 Sync Queue 分開處理

這次 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 Progress 沒變就不更新畫面

推薦路線的 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 結果沒變就跳過

而這些東西都沒有改:

  • GPS 5 秒 / 2.5 秒 / 5 公尺 / high accuracy
  • walk_points 每個 GPS point 立即保存
  • Distance / Speed
  • Route Matching
  • Off-route Detection

所以這次不是把 GPS 調慢,也不是減少 GPS point。

主要就是把幾個原本跟著 GPS point 一起做的工作調整一下,這樣可以少做一些不必要的更新。


上一篇
AI 散步分析(3)——根據分析結果產生推薦路線
系列文
30 天開發一款真正能每天使用的散步 App29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言