在客户端触发地理围栏以使用 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 的其他信息。
  • 精细导航体验,可让司机在考虑实时路况和其他路线限制的情况下,高效地从一个地点前往另一个地点。
  • 通过事件监听器和注册的回调触发事件。

监听器

Navigation SDK 提供了许多可供您使用的监听器。下面列举了一些:

  • 通过 RoadSnappedLocation 提供程序更改位置信息。
  • 通过 ReroutingListener 重新路由事件(用户错过调头、左转弯等,并偏离建议的路线)。
  • 通过 ArrivalListener 到达目的地事件(用户到达预定目的地)。
  • 剩余距离和预计到达事件(在司机即将到达目的地时收到通知 - 根据米数,在司机即将到达目的地时收到通知,以时间为准)均可通过 .RemainingTimeOrDistanceChangedListener 获取

在本指南中,仅使用 RoadSnappedLocation 提供程序及其 LocationListener。

客户端地理围栏解决方案

现在,我们来逐步构建客户端地理围栏功能。在以下示例中,我们将 Navigation SDK 运行在精细导航模式下,并在路线中定义了表示地理围栏的多边形。

功能图
功能图

  1. 地理围栏存储在 BigQuery 中,并由您的后端拉取。
  2. 后端会定期将地理围栏推送到云端硬盘应用。
  3. 驾驶员导航,驾驶应用会定期检查地理围栏是否存在触发器。
  4. Driver 应用将触发事件通知后端,以便其执行操作。

当车辆沿路线行驶时,应用会定期检查多边形是否已突破。当应用检测到跨越地理围栏时,界面上会显示一条消息:“地理围栏已泄露”。

配置 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 检查收到的位置是否在预定义的多边形内。在以下示例中,我们使用了表示地理围栏的预定义多边形,但实际上,您可能拥有多个多边形并需要一个环路。

替代方法

本文重点介绍一个面向客户端的应用,该应用可检查是否存在自定义地理围栏(多边形)违规事件。但在某些情况下,您可能需要对后端进行此类检查。

这意味着应用将向后端报告位置更新,然后此后端会检查车辆是否破坏了某个多边形,因此不会依赖客户端应用进行验证。

可能的解决方案如下所示:

[执行环境] 服务器端地理围栏架构

展示服务器端地理围栏方法的示例架构。

服务器端解决方案
服务器端解决方案

  1. 驱动程序应用使用驱动程序 SDK 向 Fleet Engine 发送位置信息更新。位置信息更新和应用内导航通过 Navigation SDK 实现。
  2. Fleet Engine 会将这些更新输出到 Cloud Logging 或 Pub/Sub。
  3. 后端会收集这些地理位置信号。
  4. 地理围栏存储在 BigQuery 中,以供后端进行分析。
  5. 触发地理围栏后,系统会向驾驶员应用发送提醒。

在此架构中,使用 Driver SDK 和 Fleet Engine。Fleet Engine 可以发出 PubSub 更新,并在 Cloud Logging 中生成日志条目。在这两种情况下,都可以检索车辆位置。

然后,后端可以监控 PubSub 队列或读取日志并监控车辆更新。然后,每当更新时(或者每几秒、几分钟一次,具体取决于更新的重要性),后端都可以调用 BigQuery GIS 函数来确定指定车辆是在地理围栏内部还是外部。如果一个或多个地理围栏遭到入侵,后端可以采取行动并触发内部管道或其他相关工作流。

总结

地理围栏是一个强大的工具,可用于多种用途。企业可以使用地理围栏向最终用户投放相关的广告和促销信息,提供基于地理位置的服务,以及提高安全性。

Navigation SDK 提供了实用的事件监听器,可检测行程中的许多重要时刻。公司通常需要针对特定用例使用自定义地理围栏。在本文档中,我们演示了实现这一目标的方法,但可能性是无穷无尽的。我们期待看到您的创意。

后续操作

建议深入阅读: