在用戶端中觸發地理圍欄,使用 Nav SDK 追蹤行動素材資源

本文件說明用戶端地理柵欄功能,以及何時使用、如何在行動應用程式中應用。本教學課程也會說明如何使用 Google Navigation SDK 在 Android 上實作範例。

支援地理圍欄偵測的 Nav SDK
Nav SDK 搭配地理圍欄偵測功能

公司經常需要知道行動裝置何時進入或離開特定區域。這項功能會透過維持虛擬地理邊界 (或地理圍欄) 來達成,讓軟體在裝置越過邊界時觸發事件。

瞭解特定車輛何時穿越邊界,對於多種用途而言十分重要,例如:

  • 客戶參與度:商家可以使用地理圍欄功能,向使用者傳送有關特價優惠、活動或新產品的推播通知。
  • 安全性:企業可以使用地理圍欄功能,在資料中心或倉庫等敏感區域周圍建立虛擬邊界,並在有人進入或離開該區域時通知保全人員。
  • 運輸業:商家可以使用地理圍欄追蹤車輛位置,並改善路線和時間表。

因此,您必須瞭解如何在面向用戶端的應用程式中呈現這些區域 (多邊形)。此應用程式應追蹤裝置位置,並檢查是否違反特定地理圍欄。

範圍

本文件著重於用戶端實作地理圍欄。也就是說,用戶端應用程式必須具備:

  1. 需要檢查是否有違規情形的多邊形;
  2. 使用者的即時位置
  3. 用於檢查目前位置是否位於任一多邊形內或外部的邏輯。

本指南提供 Android 版範例,但 iOS 版也有類似的做法。Android 位置服務內建圓形地理圍欄實作項目,詳情請參閱這篇文章。下方的參考程式碼和說明可做為更複雜實作項目的起點。

Navigation SDK 是新增至駕駛員應用程式的原生 Android / iOS 程式庫,負責執行以下工作:

  • 從執行應用程式的應用程式中取得路徑對齊位置。這比 Android 的 FusedLocationProvider (FLP) 更精確,因為它會使用 Google 的道路網路,將位置資訊與最近的路段進行對齊,進而提高預估到達時間的準確度,並提供 FLP 的其他資訊。
  • 即時路線規劃功能,可讓駕駛人考量即時交通狀況和其他路線限制,有效地從 A 點前往 B 點。
  • 透過事件監聽器和已註冊的回呼觸發事件。

事件監聽器

Navigation SDK 提供許多可用的事件監聽器。以下列舉幾個例子:

  • 透過 RoadSnappedLocation 供應器變更位置。
  • 透過 ReroutingListener 重新導航事件 (使用者錯過迴轉、左轉等,並偏離建議路線)。
  • 透過 ArrivalListener 觸發到達事件 (使用者抵達預定目的地)。
  • 透過 RemainingTimeOrDistanceChangedListener 可取得剩餘距離和預估到達時間事件 (在駕駛員即將抵達目的地時收到通知 - 以公尺為單位,在駕駛員即將抵達目的地時收到通知 - 以時間為單位)

本指南僅使用 RoadSnappedLocationProvider 及其 LocationListener。

用戶端地理圍欄解決方案

接下來,我們將逐步說明如何建構用戶端地理柵欄功能。在下方範例中,Navigation SDK 會以即時路線模式運作,路線中定義的多邊形則代表地理圍欄。

功能圖
功能圖

  1. 地理圍欄會儲存在 BigQuery 中,並由後端拉取。
  2. 後端會定期將地理圍欄推送至駕駛應用程式。
  3. 駕駛員導航時,駕駛員應用程式會定期檢查地理邊界是否觸發。
  4. 駕駛員應用程式會通知後端觸發事件,以便後端採取行動。

車輛沿著路線行駛時,應用程式會定期檢查是否越過多邊形。當應用程式偵測到跨越地理圍欄時,UI 上會顯示「Geofence breached」訊息。

設定 Android-Maps-Utils 的依附元件

這項解決方案使用 Android-Maps-Utils,這是一個開放原始碼程式庫,其中包含公用程式,可用於各種使用 Google 地圖 Android API 的應用程式。

這個程式庫是公開的,並託管在 GitHub 上,您可以前往以下網址存取:

  • Android:https://github.com/googlemaps/android-maps-utils
  • iOS:https://github.com/googlemaps/google-maps-ios-utils

如要在 Android 應用程式 (本文件的範圍) 中加入這個程式庫,您應修改 build.gradle 檔案,以便加入該程式庫。請注意,這個 build.gradle 檔案是用於您要建構的模組 (應用程式),而非專案層級。

dependencies {
   ...
   // Utilities for Maps SDK for Android (requires Google Play Services)
   implementation 'com.google.maps.android:android-maps-utils:2.3.0'
}

接著,在 Gradle 與最新的 build.gradle 檔案同步後,您就可以在 Java 檔案中匯入 com.google.maps.android.PolyUtil:

import com.google.android.gms.maps.model.PolygonOptions;
import com.google.maps.android.PolyUtil;

定義地理圍欄

請注意,這裡也會匯入 PolygonOptions。原因是這會用於代表多邊形:

mPolygonOptions = new PolygonOptions()
       .add(new LatLng(29.4264525,-98.4948758))
       .add(new LatLng(29.4267029,-98.4948758))
       .add(new LatLng(29.4273742,-98.4945822))
       .add(new LatLng(29.4264562,-98.4943592))
       .fillColor(0x0000ff36)
       .strokePattern(Arrays.asList(new Dash(45.0f), new Gap(10.0f)))
       .strokeColor(Color.BLUE)
       .strokeWidth(5);

如上所示,我們在此定義固定多邊形,並使用預先建立的座標 (緯度、經度) 組合。不過,在實際情境中,這些座標和多邊形定義大多來自後端端點,且可能會遠端擷取。也就是說,應用程式必須即時建立多邊形。

如要進一步瞭解可在 PolygonOptions 中指定的內容,請參閱這篇文章

您應在建立 Fragment 或 Activity 時定義多邊形。例如:

protected void onCreate(Bundle savedInstanceState) {
   ...
   mPolygonOptions = new PolygonOptions()
           .add(new LatLng(29.4264525,-98.4948758))
           .add(new LatLng(29.4267029,-98.4948758))
           .add(new LatLng(29.4273742,-98.4945822))
           .add(new LatLng(29.4264562,-98.4943592))
           .fillColor(0x0000ff36)
           .strokePattern(Arrays.asList(new Dash(45.0f), new Gap(10.0f)))
           .strokeColor(Color.BLUE)
           .strokeWidth(5);

   ...// more code here
}

監聽位置更新

定義地理圍欄後,您只需建立位置更新事件監聽器,即可在 Navigation SDK 中訂閱上述事件 (稱為 RoadSnappedLocationProvider),該事件會傳回裝置的最新位置。

mLocListener = new RoadSnappedLocationProvider.LocationListener() {
   @Override
   public void onLocationChanged(Location snapped) {
       LatLng snappedL = new LatLng(snapped.getLatitude(), snapped.getLongitude());
       if(PolyUtil.containsLocation(snappedL, mPolygonOptions.getPoints(), true) && !mGeofenceBreached){
           Log.d("Geofence", "Vehicle has breached the polygon");
       }
   }
   @Override
   public void onRawLocationUpdate(Location location) {
   }
};

有了 Android-Maps-Utils,您就可以使用 PolyUtil.containsLocation 檢查收到的位置是否位於預先定義的多邊形內。在下方範例中,我們使用了代表地理圍欄的預先定義多邊形,但實際上您可能會有多個多邊形,因此需要使用迴圈。

替代做法

本文著重於介面面向用戶端的應用程式,該應用程式會檢查是否有自訂地理圍欄 (多邊形) 違規情形。不過,在某些情況下,您可能會想要在後端進行這類檢查。

也就是說,應用程式會將位置更新回報給後端,而後端會檢查該車輛是否違反特定多邊形,因此不必仰賴用戶端應用程式進行驗證。

可能的解決方法如下:

[執行環境] 伺服器端地理區域封鎖架構

範例架構:說明地理圍欄的伺服器端方法。

伺服器端解決方案
伺服器端解決方案

  1. 駕駛員應用程式會使用 Driver SDK,將位置更新資料傳送至 Fleet Engine。地點更新和應用程式內導航功能會透過 Navigation SDK 執行。
  2. Fleet Engine 會將這些更新輸出至 Cloud Logging 或 Pub/Sub。
  3. 後端會收集這些位置信號。
  4. 地理圍欄會儲存在 BigQuery 中,供後端進行分析。
  5. 觸發地理圍欄後,系統會傳送快訊到駕駛應用程式。

在這個架構中,會使用 Driver SDK 和 Fleet Engine。Fleet Engine 可在 Cloud Logging 中發出 Pub/Sub 更新,並產生記錄項目。在上述兩種情況下,您都可以擷取車輛位置。

後端接著可以監控 Pub/Sub 佇列或讀取記錄,並監控車輛更新。接著,每當發生更新 (或每隔幾秒、幾分鐘,視其重要性而定),後端就能呼叫 BigQuery GIS 函式,判斷特定車輛是否位於地理圍欄內或外。如果有一個或多個地理邊界遭到侵犯,後端可以採取行動並觸發內部管道或其他相關工作流程。

結論

地理圍欄是一項強大的工具,可用於多種用途。商家可以使用地理圍欄功能,向指定區域內的使用者放送相關廣告和促銷活動,提供適地性服務,並提升安全性。

Navigation SDK 提供實用的事件監聽器,可偵測行程中的許多重要時刻。企業通常會根據特定用途需求,建立自訂地理圍欄。本文件中示範了達成這項目標的方法,但實際上還有無限的可能性。期待看到你發揮創意,

後續行動

建議參閱以下文章: