このドキュメントでは、クライアントサイドのジオフェンシングとは何か、いつ使用するか、モバイル アプリケーションのユースケースに適用する方法について説明します。また、Google Navigation SDK を使用して Android に例を実装する方法についても説明します。
企業は、モバイル デバイスが特定のエリアに出入りしたタイミングを把握する必要があることがよくあります。これは、仮想的な地理的境界(ジオフェンス)を維持することで実現できます。ソフトウェアは、デバイスが境界を越えるとイベントをトリガーします。
特定の車両が境界を通過したタイミングを把握することは、次のような複数のユースケースで重要です。
- 顧客エンゲージメント: 企業はジオフェンシングを使用して、特別オファー、イベント、新製品に関するプッシュ通知をエンドユーザーに送信できます。
- セキュリティと安全性: 企業はジオフェンシングを使用して、データセンターや倉庫などの機密エリアの周囲に仮想的な境界を作成し、誰かがエリアに出入りしたときに警備員にアラートを送信できます。
- 輸送: 企業はジオフェンシングを使用して、車両の位置情報を追跡し、ルートとスケジュールを最適化できます。
そのため、クライアント向けアプリ内でこれらのゾーン(ポリゴン)をどのように表現するかを知っておくことが重要です。このアプリは、デバイスの位置情報を追跡し、特定のジオフェンスに違反したかどうかを確認する必要があります。
スコープ
このドキュメントでは、ジオフェンシングのクライアントサイドの実装に焦点を当てています。つまり、クライアント アプリには次のものが必要です。
- 違反がないか確認する必要があるポリゴン。
- ユーザーのリアルタイムの位置情報
- 現在の位置情報がポリゴンの内側にあるか外側にあるかを確認するロジック。
このガイドには Android の例が含まれていますが、iOS でも同様の方法で実現できます。Android Location Service には、円形のジオフェンスの組み込み実装があります。詳細はこちらをご覧ください。以下のリファレンス コードと説明は、より複雑な実装の出発点となります。
Navigation SDK
Navigation SDK は、ドライバー アプリに追加されたネイティブ Android / iOS ライブラリです。次の役割を担います。
- 実行中のアプリから道路にスナップされた位置情報を取得します。Google の道路ネットワークを使用して位置情報を最寄りの道路セグメントにスナップするため、Android の FusedLocationProvider(FLP)よりも正確です。これにより、到着予定時刻が大幅に正確になり、FLP から他の情報も取得できます。
- リアルタイムの交通状況やその他のルート制限を考慮して、ドライバーが効率的に地点 A から地点 B に移動できるターンバイターン方式のナビゲーション。
- イベント リスナーと登録されたコールバックを介してイベントを発生させます。
リスナー
Navigation SDK には、使用できるリスナーが多数あります。たとえば
- RoadSnappedLocation プロバイダによる位置情報の変更。
- ReroutingListener
- ArrivalListener
- 残り距離と到着予定時刻のイベント(ドライバーが目的地に到着する直前に通知を受け取る - メートル単位、ドライバーが目的地に到着する直前に通知を受け取る - 時間単位)は、どちらも .RemainingTimeOrDistanceChangedListener を介して利用できます。
このガイドでは、RoadSnappedLocationProvider とその LocationListener のみを使用します。
クライアントサイドのジオフェンシング ソリューション
次に、クライアントサイドのジオフェンシング機能を構築する手順について説明します。以下の例では、Navigation SDK がターンバイターン モードで動作し、ルートにジオフェンスを表すポリゴンが定義されています。
- ジオフェンスは BigQuery に保存され、バックエンドによってプルされます。
- バックエンドは、ジオフェンスをドライブ アプリに定期的にプッシュします。
- ドライバーがナビゲーションを行い、ドライバー アプリがトリガーのジオフェンスを定期的にチェックします。
- ドライバー アプリは、トリガー イベントをバックエンドに通知して、対応できるようにします。
車両がルートに沿って移動すると、アプリはポリゴンが侵害されたかどうかを定期的に確認します。アプリがジオフェンスを越えたことを検出すると、UI に「ジオフェンス違反」 というメッセージが表示されます。
Android-Maps-Utils の依存関係を構成する
このソリューションでは、Android-Maps-Utils を使用します。これは、Google Maps 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 を使用して、受信した位置情報が事前定義されたポリゴンの内側にあるかどうかを確認できます。以下の例では、ジオフェンスを表す事前定義されたポリゴンが使用されていますが、実際には複数のポリゴンが存在する可能性があり、ループが必要になります。
別の方法
このドキュメントでは、カスタム ジオフェンス(ポリゴン)の違反を確認するクライアント向けアプリケーションに焦点を当てています。ただし、バックエンドでこのようなチェックを行う必要があるシナリオもあります。
つまり、アプリは位置情報の更新をバックエンドに報告し、このバックエンドは車両が特定のポリゴンに違反したかどうかを確認します。そのため、検証をクライアント アプリに依存しません。
考えられる解決策は次のとおりです。
[実行環境] サーバーサイドのジオフェンシング アーキテクチャ
ジオフェンシングに対するサーバーサイド アプローチを示すアーキテクチャの例。
- ドライバー アプリは、Driver SDK を使用して、Fleet Engine に位置情報の更新を送信します。位置情報の更新とアプリ内ナビゲーションは Navigation SDK を介して行われます。
- Fleet Engine は、これらの更新を Cloud Logging または Pub/Sub に出力します。
- バックエンドは、これらの位置情報シグナルを収集します。
- ジオフェンスは、バックエンドによる分析のために BigQuery に保存されます。
- ジオフェンスがトリガーされると、アラートがドライバー アプリに送信されます。
このアーキテクチャでは、Driver SDK と Fleet Engine が使用されます。Fleet Engine は、Pub/Sub の更新を生成し、Cloud Logging にログエントリを生成できます。どちらの場合も、車両の位置情報を取得できます。
バックエンドは、Pub/Sub キューをモニタリングするか、ログを読み取って車両の更新を監視できます。更新が発生するたびに(または数秒、数分ごと。重要度によって異なります)、バックエンドは BigQuery GIS 関数 を呼び出して、特定の車両がジオフェンスの内側にあるか外側にあるかを判断できます。1 つ以上のジオフェンスが侵害された場合、バックエンドは内部パイプラインやその他の関連するワークフローをトリガーできます。
まとめ
ジオフェンシングは、さまざまな目的に使用できる強力なツールです。企業はジオフェンシングを使用して、関連性の高い広告やプロモーションでエンドユーザーをターゲットにしたり、位置情報に基づくサービスを提供したり、セキュリティと安全性を向上させたりできます。
Navigation SDK には、移動中の重要な瞬間を検出できる便利なイベント リスナーが用意されています。企業は、特定のユースケースでカスタム ジオフェンスを必要とすることがよくあります。このドキュメントでは、これを実現する方法を示しましたが、可能性は無限大です。皆様がどのようなデザインを生み出すのか、楽しみにしています。
次のアクション
- Google Maps Platform でできることの紹介ウェビナーをご覧ください。
おすすめのドキュメント: