Where am I?-Part III-用 Geolocation API 以及 Offline Storage 實現導航與離線儲存

app screenshot

之前在 Eric [1] 與 Owen 的文章 [2] 已經介紹了如何使用 Geolocation API [3] 開發地圖應用,在這篇文章中我們要進一步介紹如何用 Geolocation API 實現導航。另外考慮到定位服務需要一定的時間才能完成,為了避免使用者每次開啟 App 時候都要花時間重新尋找所在位置,因此我們要利用離線儲存的函式庫 —  localForage [4] 來紀錄使用者最後出現的地點,如此一來即使定位緩慢的時候依然能快速把地圖移到最近的位置。

導航 — watchPosition()

聲明:我們在此只會實作一個能夠隨著使用者走動更新現在位置的App, 並沒有要實作規劃路徑或是行車提醒。

之前在 Owen的文章 [1] 中介紹了如何使用 geolocation.getCurrentPosition() 取得手機所在的位置。但是getCurrentPosition()只會回傳一次位置,而且為了減少等待時間,getCurrentPosition() 會傾向於比較快速但是比較不準確的 WiFi 或 IP 定位。假設我們希望每當位置資訊更新(可能是手機移動,或是更精確的 GPS 定位完成)的時候都能更新現在位置符號,那就必須要使用 watchPosition() 函式 [5]

watchPosition()的參數包括一個成功時呼叫的回調函式 (callback function),一個失敗時呼叫的回調函數,以及一些相關的設定值。使用起來如下:

每當系統底層抓到最新的位置時(不論是從WiFi或是GPS),on_success()就會被呼叫,此時就可以利用傳入的經緯度來畫出現在位置的標誌。細部的設定我們不深入介紹,讀者可以參考MDN上的介紹 [5]

watchPosition() 只要被啟動以後,就會不斷的呼叫 on_success() 直到天荒地老。要停止一個進行中的 watchPosition() 就必須在啟動時記住它回傳的 watchID。只要把 watchID 傳給geolocation 中的 clearWatch() 就可以停止它繼續動作。(若是熟悉 JavaScript 的讀者會發現這很類似 setInterval() 的用法)

有了watchPosition()的幫助,我們就可以輕鬆的在使用者走動的時候,把最新的位置畫到地圖上,達成導航的功能。

想實際體驗 Geolocation API 的讀者可以 fork/clone 這份 GitHub Repository [8] 來實驗。

 

記得我在哪嗎? — Offline Storage

不論 Geolocation API 使用什麼樣的技術,總是需要幾秒鐘甚至幾分鐘的時間才能定位成功,因此 App 啟動時就必須要等待許久才能讓地圖移動到正確位置。但是我們可以合理的推測使用者開啟 App 時,並不會離上次關閉 App 前的最後位置差太遠。若是App能夠記得上次 App 關閉前的最後位置,就能在下次啟動時直接顯示最後位置附近的地圖,將會大大改善使用者的體驗。

Web 平台上提供本地儲存的技術有很多種 (IndexedDB, WebSQL, localStorage, etc.),在各種瀏覽器上支援的程度也不一。我們推薦使用 Mozilla 開發的 localForage 函式庫 [4],localForage 讓您可以不必擔心平台的差異,利用一套統一的 API,localForage 就會自動根據平台來使用不同的技術。

localForage 的安裝非常容易,只要從GitHub [4] 下載最新的 localforage.js (也可以使用 npm 或 bower ),然後在 App 的 html 檔案中加入

有了localForage,我們就可以在每次獲得新位置資訊的時候把它存起來:

localForage 是使用 key-value 的格式來儲存資料,我們可以把 Geolocation API 回傳的 position 變數當作 value 儲存,並且給它一個字串 'position' 作為 key,之後要存取的時候就可以用 key 來搜尋。

值得注意的一點是 localForage 的 API 都是非同步的 (Asynchronous),當 localforage.setItem()執行以後並不會阻塞 (blocking) 等到儲存完畢,而是會直接繼續往下執行do_something(),等到儲存真的完成時才會呼叫 successCallback

當程式啟動時,我們可以優先從localForage取出上次儲存的位置,而不用慢慢的等 Geolocation API 回傳。存取的方法如下

注意到 getItem() 也是非同步的,當 position 成功的從本機的儲存中被取出的時候,successCallback 就會被呼叫。

localForage 當然還支援更新、刪除等資料庫常用的功能,不過我們只需要這兩個函式就足以建構我們的 App 了,對於 localForage 的其他功能可以參考 [6]

想要動手試試看的讀者可以參考這個 GitHub Repository [9],它示範如何用 localForage 離線暫存 Ubike 的可借車數資訊。

以上我們介紹了如何使用 Geolocation API 的 watchPosition() 來持續不斷的得到位置資訊,以及如何使用 localForage 來輕鬆的幫 App 加上離線儲存的功能。有了這兩個利器,我們已經可以建構出功能相當完整的地圖 App 了。您也有更多的創意嗎?歡迎留言與大家分享吧!

Reference

[1] Where am I?-Part I-使用 Google Maps 地圖快速簡單查看你的位置 http://tech.mozilla.com.tw/?p=5762

[2] Where am I? – Part II 在 Google Maps 標記地圖資訊 http://tech.mozilla.com.tw/?p=5765

[3] Geolocation API https://developer.mozilla.org/zh-TW/docs/Using_geolocation

[4] localForage (GitHub) https://github.com/mozilla/localForage

[5] watchPosition() https://developer.mozilla.org/en-US/docs/Web/API/Geolocation.watchPosition

[6] localForage API Documentation http://mozilla.github.io/localForage/

[7] localForage Intro on Mozilla Hack https://hacks.mozilla.org/2014/02/localforage-offline-storage-improved/

[8]Geolocation API Demo (GitHub) https://github.com/shinglyu/geolocation_demo

[9] Offline App Demo (GitHub) https://github.com/shinglyu/offline_app_demo

您可能也會喜歡

目前找不到相關文章

對此文章發表回應

你的電子郵件位址並不會被公開。 必要欄位標記為 *