规划路线

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

  • 路线的多段线

  • 您的路线目标

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

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

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

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

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

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

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

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

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

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

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

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

路线令牌的工作原理

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

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

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

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

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

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

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

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

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

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

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

使用路线令牌规划路线

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

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

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

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

    • Routes Preferred API:computeCustomRoutes。如需详细了解如何在 Routes Preferred API 中请求路线令牌,请参阅规划路线。

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

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

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

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

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

    let routeToken = "route token returned by Routes API"
    

    返回的路线令牌示例:

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

    在应用中设置的出行方式(例如 mapView.travelMode)必须是以下值之一:

    • .driving (GMSNavigationTravelModeDriving):驾车。这是默认值,因此大多数应用无需更改它。
    • .twoWheeler (GMSNavigationTravelModeTwoWheeler):两轮车。

    任何其他出行方式都会导致请求失败,并显示 .travelModeUnsupported (GMSRouteStatusTravelModeUnsupported)。无论使用哪种受支持的值,路线都会使用路线令牌中的出行方式。例如,如果您的应用使用驾车模式,而路线令牌对应的是两轮车路线,则 Navigation SDK 会提供两轮车路线。如需确认路线使用的出行方式,请查看 resolvedParameters.travelMode。如需了解详情,请参阅已解析的路由选项。

  3. 在完成处理程序中检查路线状态。Navigation SDK 完成路线计算后,会将 GMSNavigationRouteDescription 传递给您的完成处理程序。如果它找到从车辆位置到路线令牌中目的地的路线,则路线说明的 routeStatus 为 .OK (GMSRouteStatusOK),您可以开始导航。否则,您的完成处理程序还会收到描述失败的 NSError。例如:

    mapView.navigator?.setDestinationsWithToken(routeToken) { [weak self] routeDescription, error in
      if routeDescription?.routeStatus == .OK {
        self?.mapView.navigator?.isGuidanceActive = true
      }
    }
    

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

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

  1. 确认路由说明的 routeStatus 为 .OK。Navigation SDK 仅在找到路线时提供路线令牌详细信息。如需了解详情,请参阅第 2 步。

  2. 获取路线说明的 routeTokenExecutionDetails,这是一个符合 GMSNavigationRouteTokenExecutionDetails 协议的对象。如果服务器未提供路线令牌详细信息,则此属性为 nil。

  3. 检查执行详情的 tokenExecutionStatus 属性。如果为 .tokenSuccessfullyApplied,则表示该路线与您的计划路线一致。任何其他状态都意味着路线可能与您规划的路线不同。如需详细了解每种状态,请参阅令牌执行状态值。

  4. 可选:如果状态为 .tokenSuccessfullyApplied,请检查同一执行详情的 resolvedParameters 属性,了解路线使用了哪些路线选项,例如是否避开收费路段。如需了解详情,请参阅已解析的路由选项。

令牌执行状态值

如果 routeStatus 为 .OK,您可以在任何令牌执行状态下开始指导。该状态会告知您路线是否遵循您的规划路线。

状态 遵循您规划的路线 说明
.tokenSuccessfullyApplied 是 Navigation SDK 应用了您的路线令牌。
.tokenAppliedWithLocationMismatch 不一定 Navigation SDK 无法重新构建规划的路线,并且设备距离路线令牌中的起点超过 25 米。路线仍会使用路线令牌中的目的地和路线选项。
.tokenIgnoredOther 不一定 Navigation SDK 因其他原因(例如,规划路线上的某条道路已封闭)无法重新构建规划路线。路线仍会使用路线令牌中的目的地和路线选项。
.noTokenProvided 不适用 路线请求不包含路线令牌。
.unknown 未知 状态未知。

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

已解析的路由选项

resolvedParameters 是符合 GMSNavigationRouteTokenResolvedParameters 协议的对象,如果路线选项不可用,则为 nil。它具有以下属性:

  • travelMode:路线使用的出行方式,例如 .driving (GMSNavigationTravelModeDriving)。如果路线使用的出行方式没有匹配的值,或者出行方式不可用,Navigation SDK 也会报告 .driving。
  • avoidTolls:路线是否避开收费站。
  • avoidHighways:路线是否避开高速公路。
  • avoidFerries:路线是否避开轮渡。
  • avoidTunnels:计算路线时是否尽可能避开隧道。
  • avoidVignettes:计算路线时尽可能避开通行费年票的国家/地区,以 Unicode CLDR 两位字母地区代码表示,例如瑞士的代码为 CH。
  • rerouteStrategy:路线规划后端在行程期间用于计算新路线的策略。策略包括 .bestBasedOnTokenParameters (GMSNavigationRerouteStrategyBestBasedOnTokenParameters),它使用路线令牌中的路线参数来计算新路线。

如果令牌执行状态不是 .tokenSuccessfullyApplied,Navigation SDK 仅报告 travelMode、avoidTolls、avoidHighways 和 avoidFerries。其他属性具有默认值,即使您在请求路线令牌时要求避开隧道或收费路段:avoidTunnels 为 false (NO),avoidVignettes 为空,rerouteStrategy 为 .unknown (GMSNavigationRerouteStrategyUnknown)。

示例

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

Swift

let routeToken = "route token returned by Routes API"

mapView.navigator?.setDestinationsWithToken(routeToken) { [weak self] routeDescription, error in
  // Check whether the Navigation SDK found a route.
  guard routeDescription?.routeStatus == .OK else {
    print("Route error: \(error?.localizedDescription ?? "unknown")")
    return
  }

  // Check whether the Navigation SDK applied the route token.
  if let executionDetails = routeDescription?.routeTokenExecutionDetails {
    if executionDetails.tokenExecutionStatus != .tokenSuccessfullyApplied {
      print("The route might differ from your planned route.")
    }
  } else {
    print("Route token details aren't available.")
  }

  self?.mapView.navigator?.isGuidanceActive = true
}

Objective-C

NSString *routeToken = @"route token returned by Routes API";

[mapView.navigator setDestinationsWithToken:routeToken
                          completionHandler:^(id<GMSNavigationRouteDescription> _Nullable routeDescription,
                                              NSError *_Nullable error) {
  // Check whether the Navigation SDK found a route.
  if (routeDescription.routeStatus != GMSRouteStatusOK) {
    NSLog(@"Route error: %@", error.localizedDescription);
    return;
  }

  // Check whether the Navigation SDK applied the route token.
  id<GMSNavigationRouteTokenExecutionDetails> executionDetails =
      routeDescription.routeTokenExecutionDetails;
  if (executionDetails == nil) {
    NSLog(@"Route token details aren't available.");
  } else if (executionDetails.tokenExecutionStatus !=
             GMSNavigationRouteTokenExecutionStatusTokenSuccessfullyApplied) {
    NSLog(@"The route might differ from your planned route.");
  }

  mapView.navigator.guidanceActive = YES;
}];

多站场景

您最多可以配置 25 个航点。

Navigation SDK 不会自动前往下一个目的地。当车辆到达航点时,调用 continueToNextDestinationWithCompletion: 以开始行程的下一路段。这也适用于具有中间航点的路线令牌。当您前往下一个目的地时,Navigation SDK 会继续遵循路线令牌中的路线,而不是规划新路线。

路线令牌和 Navigation SDK 如何交互

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

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

    • avoidsHighways
    • avoidsTolls
    • avoidsFerries
    • licensePlateRestriction
    • 应用中设置的出行模式
  • 在计算或调整路线时遵循以下设置:

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