规划路线

有时,您可能需要规划应用向用户提供的路线。使用 Routes API 或 Route Optimization API 中的路线令牌,您可以为规划的路线指定以下两项内容:

  • 路线的多段线

  • 您的路线目标

例如,以下是您可能需要实现的一些路线规划目标:

  • 最大限度地缩短送货时间:送餐企业可能希望最大限度地缩短送餐时间。

  • 最大限度地缩短行程时间或减少燃料消耗:物流企业可能希望提高司机的效率并降低燃料成本。

  • 尽可能缩短到达目的地的时间:服务调度操作可能希望尽可能缩短操作员到达作业请求地点所需的时间。

  • 降低成本并提高安全性:拼车业务可能希望找到一条对乘客来说成本更低的路线,并出于安全原因避开某些区域。

如需详细了解如何使用路线令牌规划路线,请参阅 Routes API 中的获取路线令牌和 Route Optimization API 中的过渡多段线和路线令牌。

为何要为路线目标使用路线令牌

借助 Routes API 或 Route Optimization API 提供的路线令牌,您可以更好地控制所提供的路线:

  • 提前规划路线,供 Navigation SDK 使用。

  • 选择 Navigation SDK 要使用的最佳路线。如果您在 Routes API 中生成路线时请求路线令牌,则会为每条生成的路线获得一个路线令牌。然后,您可以选择要使用的路线的令牌,并将其传递给 Navigation SDK。

  • 提前估算价格,包括预计到达时间和距离。虽然实际费用和时间可能会有所不同,但此估算值可缩小预期路线费用与实际路线费用之间的差距。

  • 指定更高级的路线目标,例如环保路线或最短路线。

路线令牌的工作原理

您可以使用 Routes API 或 Route Optimization API,根据路线目标规划路线。您可以将这两个 API 中任一个返回的路线令牌传递给 Navigation SDK,以指导其如何为您的车辆规划路线。

请求和使用路线令牌时,会发生以下情况:

  1. Routes API 或 Route Optimization API 会返回一个加密的路线令牌,其中包含路线多段线和路线目标。

  2. 您需要将路线令牌传递给 Navigation SDK。

  3. Navigation SDK 会在您规划的路线上启动导航,即使有更快的路线也是如此。

  4. 在行程中,如果路况或道路状况发生变化,或者车辆偏离规划路线,Navigation SDK 会根据路线令牌中设置的路线目标和路线选项计算新路线。

此过程可最大限度地缩短实际路线与规划路线之间的距离。

为什么可能无法完全按照规划的路线行驶

导航会从规划的路线开始,但在以下情况下,实际路线可能会与规划的路线不同:

  • 车辆从远离计划起点的位置出发。
  • 行程期间路况或道路状况发生变化。
  • 车辆偏离规划路线。

这些差异可能会影响您规划的距离、预计到达时间和其他重要行程质量。

使用路线令牌规划路线

您可以通过创建路线令牌并将其传递给 Navigation SDK 来规划路线,如以下步骤所述:

第 1 步:使用 Routes API 或 Route Optimization API 创建路线令牌

  1. 使用以下方法之一请求路线令牌:

    • Routes API:computeRoutes。如需详细了解如何在 Routes API 中请求路线令牌,请参阅计算路线和获取路线令牌。

    • Route Optimization API:optimizeTours 或 batchOptimizeTours。如需详细了解如何在 Route Optimization API 中请求路线令牌,请参阅过渡多段线和路线令牌。

  2. 设置 Routes API 请求,以满足使用路线令牌的要求:

    • 将 travelMode 设置为 DRIVE 或 TWO_WHEELER。
    • 将 routingPreference 设置为 TRAFFIC_AWARE 或 TRAFFIC_AWARE_OPTIMAL。
    • 请勿使用 Via 航点。

第 2 步:将路线令牌传递给 Navigation SDK

  1. 存储路线令牌:在 Navigation SDK 中,设置一个字符串来存储路线令牌。例如:

    String routeToken = "route token returned by Routes API";
    

    返回的路线令牌示例:

    {
    // Other fields
    "routeToken": "CqMBCjoKCJQOor5DHcwiEhBon3XpHXFnVvDeWMwd9PpAGgz6wtnFDKIBrAHTARpCApUDSggAAAAACjcrP3gBEAQaTApKChgKDQoCCAERAAAAAACAZkAR3SQGgZUXdUASEggAEAMQBhATEBIYAkIEGgIIBSIYChZ2VEJiWlBPSkk1aU5wUVRzNTV5d0FRKAEiFQBcJuds-Efh-2QZhOMTtUCCxEVL_g",
    }
    
  2. 使用 Navigator.setDestinationsWithToken 方法将路线令牌传递给 Navigation SDK。Navigation SDK 会从路线令牌中获取目的地和路线选项,因此您无需传递航点或出行方式。

    setDestinationsWithToken(String routeToken, RouteDescriptionLoadCallback callback);
    setDestinationsWithToken(String routeToken, DisplayOptions displayOptions, RouteDescriptionLoadCallback callback);
    

  3. 在回调中检查路线状态。Navigation SDK 完成路线计算后,会将 RouteDescription 传递给您的回调。如果找到从车辆位置到路线令牌中目的地的路线,RouteDescription.getRouteStatus 会返回 Navigator.RouteStatus.OK,您可以开始导航。例如:

    navigator.setDestinationsWithToken(
        routeToken,
        routeDescription -> {
          if (routeDescription.getRouteStatus() == Navigator.RouteStatus.OK) {
            navigator.startGuidance();
          }
        });
    

检查 Navigation SDK 是否应用了路线令牌

路线状态为 OK 表示 Navigation SDK 找到了路线,但不一定是您规划的路线。如需检查路线是否与您的规划路线一致,请在回调中按以下步骤操作:

  1. 确认 RouteDescription.getRouteStatus 返回 Navigator.RouteStatus.OK。Navigation SDK 仅在找到路线时提供路线令牌详细信息。如需了解详情,请参阅第 2 步。

  2. 调用 RouteDescription.getRouteTokenExecutionDetails 以获取 RouteTokenExecutionDetails 对象。如果服务器未提供路线令牌详细信息,此方法会返回 null。

  3. 对 RouteTokenExecutionDetails 对象调用 getTokenExecutionStatus。如果返回 TOKEN_SUCCESSFULLY_APPLIED,则表示该路线与您的规划路线一致。任何其他状态都表示路线可能与您规划的路线不同。如需详细了解每种状态,请参阅令牌执行状态值。

  4. 可选:如果状态为 TOKEN_SUCCESSFULLY_APPLIED,请对同一 RouteTokenExecutionDetails 对象调用 getResolvedParameters,以检查路线使用的路线选项,例如是否避开收费站。如需了解详情,请参阅已解析的路由选项。

令牌执行状态值

如果路线状态为 OK,则无论令牌执行状态如何,您都可以开始导航。该状态会告知您路线是否遵循您的规划路线。

状态 遵循您规划的路线 说明
TOKEN_SUCCESSFULLY_APPLIED 是 Navigation SDK 应用了您的路线令牌。
TOKEN_APPLIED_WITH_LOCATION_MISMATCH 不一定 Navigation SDK 无法重新构建您规划的路线,因为路线请求中的某个位置与路线令牌中的匹配位置相距超过 25 米。对于 setDestinationsWithToken,这意味着设备与路线令牌中的起点相距超过 25 米。路线仍会通往目的地,但 Navigation SDK 无法确认该路线是否使用了路线令牌中的路线选项(例如避开收费路段)。
TOKEN_IGNORED_OTHER 不一定 Navigation SDK 因其他原因(例如,规划路线上的某条道路已封闭)无法重新构建规划路线。路线仍会通往目的地,但 Navigation SDK 无法确认该路线是否使用了路线令牌中的路线选项(例如避开收费路段)。
NO_TOKEN_PROVIDED 不适用 路线请求不包含路线令牌。
UNKNOWN 未知 状态未知。

如果路线不一定遵循您的规划路线,并且确切路线很重要(例如,因为您使用它来计算价格),请记录状态或从车辆的当前位置请求新的路线令牌。

已解析的路由选项

getResolvedParameters 会返回一个 RouteTokenResolvedParameters 对象,如果路线选项不可用,则返回 null。RouteTokenResolvedParameters 具有以下方法:

  • getTravelMode:路线使用的出行方式,例如 RoutingOptions.TravelMode.DRIVING。当路线使用的出行方式没有匹配的值,或者出行方式不可用时,Navigation SDK 也会报告 RoutingOptions.TravelMode.DRIVING。
  • getAvoidTolls:路线是否避开收费站。
  • getAvoidHighways:路线是否避开高速公路。
  • getAvoidFerries:路线是否避开轮渡。

示例

以下代码示例演示了如何使用路线令牌规划路线、检查 Navigation SDK 是否应用了该令牌,以及启动导航。

String routeToken = "route token returned by Routes API";

// Existing flow to get a Navigator.
NavigationApi.getNavigator(...);

// Handle the result of the route calculation.
RouteDescriptionLoadCallback callback =
    routeDescription -> {
      // Check whether the Navigation SDK found a route.
      if (routeDescription.getRouteStatus() != Navigator.RouteStatus.OK) {
        Log.w(TAG, "Route status: " + routeDescription.getRouteStatus());
        return;
      }

      // Check whether the Navigation SDK applied the route token.
      RouteTokenExecutionDetails executionDetails =
          routeDescription.getRouteTokenExecutionDetails();
      if (executionDetails == null) {
        Log.i(TAG, "Route token details aren't available.");
      } else if (executionDetails.getTokenExecutionStatus()
          != RouteTokenExecutionDetails.TokenExecutionStatus.TOKEN_SUCCESSFULLY_APPLIED) {
        Log.w(TAG, "The route might differ from your planned route.");
      }

      navigator.startGuidance();
    };

// Set destinations using the route token.
navigator.setDestinationsWithToken(routeToken, callback);

// Or with display options.
DisplayOptions displayOptions = new DisplayOptions();
navigator.setDestinationsWithToken(routeToken, displayOptions, callback);

路线令牌和 Navigation SDK 如何交互

Navigation SDK 会按以下方式处理您规划的路线:

  • 使用路线令牌中设置的路线选项,而不是应用中的以下设置,包括在行程期间计算新路线时:

    • RoutingOptions.avoidHighways
    • RoutingOptions.avoidTolls
    • RoutingOptions.avoidFerries
    • Navigator.setLicensePlateRestrictionInfo
    • 应用中设置的出行模式
  • 在计算或调整路线时遵循以下设置:

    • 路线令牌中的路线目标,例如环保路线或最短路线。如果 Navigation SDK 必须调整路线,它会使用您在请求路线令牌时指定的路线目标。
    • 路线令牌中与航点相关的选项,例如道路一侧偏好设置。