Skip to content

算路请求

1. 算路模式(Hybrid)

通过 NavigationService.createNavigableRouteTask 发起算路。该接口 不区分 Onboard 与 Cloud,由 SDK 在内部执行 Hybrid 求路:综合当前网络连接、地图数据可用性(本地/云端/流式)等因素,自动选择最终适用的 Route

要点 说明
求路入口 NavigationService.createNavigableRouteTask(request)
算路策略 Hybrid,由 SDK 自动选择车端/云端算路方式
任务类型 Task<RouteResponse>
执行任务 runAsyncrunSync
可选配置 HybridClientConfig(第二个参数,可传 null 使用默认)

1.1 创建任务并执行(异步)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
val navigationService = NavigationService.Factory.createInstance()

val request = RouteRequest.Builder(
    GeoLocation(37.386300, -122.005090),
    GeoLocation(37.398760, -121.977360)
)
    .routeStyle(RouteStyle.FASTEST)
    .contentLevel(ContentLevel.FULL)
    .build()

val task = navigationService.createNavigableRouteTask(request)

task.runAsync { routeResponse ->
    val status = routeResponse.response.status
    val routes = routeResponse.response.result

    if (status != DirectionErrorCode.OK || routes.isNullOrEmpty()) {
        // 处理算路失败
        task.dispose()
        return@runAsync
    }

    // 使用 routes:绘制路线、展示备选方案等
    val selectedRoute: Route = routes[0]

    task.dispose()
}

1.2 创建任务并执行(同步)

在后台线程中可使用 runSync 阻塞等待结果:

1
2
3
4
5
6
7
8
9
val task = navigationService.createNavigableRouteTask(request)

task.runSync { routeResponse ->
    if (routeResponse.response.status == DirectionErrorCode.OK) {
        val routes = routeResponse.response.result
        // 处理 routes
    }
    task.dispose()
}

回调内 仅可调用 task.dispose(),不宜在回调中再次发起其它阻塞型 SDK 调用,否则可能导致死锁。

1.3 传入 HybridClientConfig

Hybrid 算路会并发发起本地(Onboard)与云端(Cloud)请求。若本地先返回,SDK 仍会等待云端结果一段时间(云端质量通常更好),等待时长由路线距离等因素决定。可通过 HybridClientConfig 调整各场景下的等待超时;不传该参数(null)时使用 SDK 内置默认值。

1
2
3
4
5
6
7
8
9
val hybridClientConfig = HybridClientConfig.Builder()
    .setTimeoutForShortRoute(2000L)
    .setTimeoutForMediumRoute(3000L)
    .setTimeoutForLongRoute(5000L)
    .setTimeoutForOldEmbeddedDataVersion(15000L)
    .setMaxOnboardRouteCount(2)
    .build()

val task = navigationService.createNavigableRouteTask(request, hybridClientConfig)

不传配置时:

1
val task = navigationService.createNavigableRouteTask(request) // 等价于 config = null
参数 / Builder 方法 类型 默认值 说明
timeoutForShortRoute / setTimeoutForShortRoute Long(毫秒) 2000 短途路线(0~50 km):本地先返回后,等待云端结果的最长时间
timeoutForMediumRoute / setTimeoutForMediumRoute Long(毫秒) 3000 中途路线(50~1000 km):同上
timeoutForLongRoute / setTimeoutForLongRoute Long(毫秒) 5000 长途路线(≥1000 km):同上
timeoutForOldEmbeddedDataVersion / setTimeoutForOldEmbeddedDataVersion Long(毫秒) 15000 本地先返回但使用的是旧版本嵌入式地图数据时,等待云端结果的最长时间
maxOnboardRouteCount / setMaxOnboardRouteCount Int -1(未限制) 本地算路请求的最大路线条数;有效值为 123。设置后会覆盖 RouteRequest 中的 routeCount 对本地算路的上限;未设置或无效值时,以 RouteRequest.routeCount 为准

说明:

  • 上述超时均为可选配置,单位为毫秒;传入 ≤0 的值会被忽略,保留对应默认值。
  • setMaxOnboardRouteCount 传入 13 以外的值会被忽略(等同于未设置)。
  • 一般集成使用默认配置即可;仅在需要缩短首包等待、或限制本地备选路线数量时再按需调整。

1.4 Onboard 与 Cloud 策略差异

Onboard 算路与 Cloud算路在功能能力上保持一致:同一套 RouteRequestRouteStyleRoutePreferences 和车辆配置均可用于两种算路方式,返回的 Route 结果也遵循同一套模型。开发者通常不需要在业务侧手动区分两者,SDK 会通过 Hybrid 策略自动选择最终使用的路线结果。

两者的主要差异体现在路线质量和响应性能上。一般情况下,Cloud算路会优于 Onboard(本地)算路:

对比项 Onboard Cloud
功能能力 与 Cloud 保持一致,支持路线风格、避让条件、车辆信息等配置 与 Onboard 保持一致,使用同样的请求和结果模型
路网搜索范围 受本地地图数据和车端资源限制,搜索范围相对有限 云端可在更大范围的路网中搜索,更容易找到更合适的道路类型和路线组合
实时交通 依赖车端可用的交通数据与更新时机 Routing Service 收到 live traffic 变更后,可立即反映到当时的求路结果中,交通时效性更好
收费避让 支持 avoidTollRoads(true),可根据本地地图数据避开收费道路 支持同样的收费避让能力,并会结合 toll zone 及其规则变化;云端定期更新 toll zone 规则,并反映到 avoidTollRoads(true) 的求路结果中
性能 在本地执行,适合网络不可用或云端结果超时时作为可靠兜底 服务器计算资源更强,通常能更快完成复杂路线搜索和代价计算

因此,Hybrid 算路在本地先返回时仍可能继续等待云端结果一段时间:如果 Cloud算路在等待窗口内返回,SDK 可优先使用质量和性能表现更好的云端路线;如果网络不可用、云端超时或其它条件不满足,则使用 Onboard 路线保证基础算路能力可用。

2. 算路策略

通过 RouteStyle 表达路线风格,通过 RoutePreferences 表达避让和增强选项。两者可以组合使用。

2.1 RouteStyle

RouteStyle 说明
RouteStyle.FASTEST 时间优先。耗时是最重要因素,也是主要考虑实时交通的路线风格。
RouteStyle.SHORTEST 距离优先。更偏向较短距离,但距离不是唯一因素。
RouteStyle.ECO 经济优先。更偏向低油耗或低能耗路线。
RouteStyle.EASY 易驾驶优先。更偏向少转弯、道路更宽的路线。

示例代码:

1
2
3
4
5
6
7
8
9
val request = RouteRequest.Builder(
    GeoLocation(37.386300, -122.005090),
    GeoLocation(37.398760, -121.977360)
)
    .routeStyle(RouteStyle.FASTEST)
    .routeCount(3)
    .build()

val task = navigationService.createNavigableRouteTask(request)

2.2 RoutePreferences

配置项 说明
avoidHovLanes(true) 避开 HOV 车道。
avoidHighways(true) 尽量避开高速道路。
avoidTollRoads(true) 尽量避开收费道路。
avoidFerries(true) 尽量避开轮渡路线。
avoidCarTrains(true) 避开汽车列车渡运。
avoidUnpavedRoads(true) 尽量避开砂石路、土路、草地等非坚实路面。
avoidTunnels(true) 尽量避开隧道。
avoidTrafficCongestion(true) 在交通信息可用时,尽量避开拥堵道路。默认值为 true
avoidTrafficClosures(true) 严格避开交通封闭道路。默认值为 true;当该项为 true 时,导航过程中通常不会因交通封闭触发自动换路。
avoidCountryBorders(true) 避免跨越国境。
avoidSharpTurns(true) 尽量避开急转弯,适合大型车辆场景。
avoidPermitRequiredRoads(true) 避开需要通行许可的道路。默认值为 true
avoidSeasonalRestrictions(true) 避开季节性关闭道路。默认值为 true
enableRouteSafety(true) 在能力支持时请求路线安全相关信息。
enableServiceRoadEntries(true) 返回路线附近服务区道路入口信息。
allowRestrictionBypass(true) 必要时允许绕行部分道路限制。
preferUsingNavPoints(true) 目的地或途经点匹配时优先使用 GeoLocation.navPoints

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
val preferences = RoutePreferences.Builder()
    .avoidHighways(true)
    .avoidTollRoads(true)
    .avoidTrafficCongestion(true)
    .enableServiceRoadEntries(true)
    .build()

val request = RouteRequest.Builder(
    GeoLocation(37.386300, -122.005090),
    GeoLocation(37.398760, -121.977360)
)
    .routePreferences(preferences)
    .build()

val task = navigationService.createNavigableRouteTask(request)

3. 经纬度算路

最基本的路线规划只需要传入起点和终点经纬度。使用 GeoLocation(latitude, longitude)GeoLocation(LatLon) 可直接设置 displayPoint

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
val request = RouteRequest.Builder(
    GeoLocation(37.386300, -122.005090),
    GeoLocation(37.398760, -121.977360)
)
    .routeStyle(RouteStyle.FASTEST)
    .contentLevel(ContentLevel.FULL)
    .build()

val task = navigationService.createNavigableRouteTask(request)
task.runAsync { /* 见 1.1 */ }

4. POI / 地点信息算路

GeoLocation 封装算路所需的地点信息。除经纬度外,还可携带 POI 标识、地址、导航候选点、线状位置等,以提升道路匹配与到达点选择准确性。

根据数据来源与业务场景,选用对应的 初始化方法(构造函数):

场景 推荐初始化方式
起点为当前车位(从车辆实时位置出发求路) 将定位引擎回调 PositionEventListener.onLocationUpdated第一个参数 vehicleLocationLocation)传入 GeoLocation(Location),作为起点。SDK 会读取 Map matching 后的 wayId,确保求路起点与车辆实际所在道路一致;若未在 RouteRequest 上单独设置 heading / speedInMps,还会使用 bearingspeed
终点或途经点来自 Search 结果 尽量同时提供 navigation pointsnavPoints)与 address,必要时附带 displayPoint。使用 GeoLocation(displayPoint, navPoints, address)
终点或途经点为 OnStreetParking(仅在具有 OnStreetParking 功能时支持) 使用主构造函数,并设置 lineLocationReference,描述有序形状点及到达侧。例如:GeoLocation(displayPoint = ..., lineLocationReference = lineRef)(见 4.3 节)。
EV 模式下目的地为充电桩 必须为充电桩设置 placeID(来自 Search / Entity 返回的充电桩标识),建议配合 displayPointnavPointsaddress 一并传入:GeoLocation(placeID, displayPoint, navPoints, address)
仅已知经纬度(无 Search、无定位对象、无线性位置参考) GeoLocation(lat, lon)GeoLocation(LatLon),将坐标作为 displayPoint。适用于简单起终点或信息不全时的兜底场景。

通用字段说明:

字段 说明
displayPoint 地图展示点,匹配道路的必填位置
placeID 地点唯一标识;EV 模式下充电桩目的地必填(见 4.4 节)
address 地址信息;途经点/目的地用于匹配,起点会忽略
navPoints 额外导航候选点,适合大型建筑、停车场、多出入口 POI
location 定位引擎返回的 Android Location;SDK 读取 Map matching 后的 wayId 及坐标、航向、速度
lineLocationReference 路边停车(OnStreetParking)等线状位置;将 Search 返回的线状参考传入

下文 4.1~4.5 各小节顺序与上表一致。

4.1 起点为当前车位(GeoLocation(Location)

从车辆实时位置出发求路时,应将定位引擎回调中的车位信息作为起点传入,而不是仅使用裸经纬度。

  • 使用 PositionEventListener.onLocationUpdated第一个参数 vehicleLocationLocation)构造 GeoLocation(Location)
  • SDK 会读取 Map matching 后的 wayId,确保求路起点与车辆实际所在道路一致。
  • RouteRequest 未单独设置 heading / speedInMps,SDK 会使用 Location 中的 bearingspeed(见第 5 节)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 在 PositionEventListener 中保存最新车位
var latestVehicleLocation: Location? = null

val positionListener = object : PositionEventListener {
    override fun onLocationUpdated(vehicleLocation: Location, positionInfo: PositionInfo) {
        latestVehicleLocation = vehicleLocation
    }
    // ...
}

// 用户发起求路时,用最新 vehicleLocation 作为起点
fun requestRouteFromCurrentPosition(destination: GeoLocation) {
    val originLocation = latestVehicleLocation ?: return

    val request = RouteRequest.Builder(
        GeoLocation(originLocation),
        destination
    ).build()

    val task = navigationService.createNavigableRouteTask(request)
    task.runAsync { /* 见 1.1 */ }
}

4.2 终点或途经点来自 Search(navPoints + address

终点或途经点来自 Search / Entity 检索结果时,应尽量提供 navigation pointsnavPoints)与 address,并设置 displayPoint,以提升道路匹配与到达点选择准确性。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
val destination = GeoLocation(
    displayPoint = LatLon(searchResult.lat, searchResult.lon),
    navPoints = searchResult.navPoints,
    addr = searchResult.address
)

val request = RouteRequest.Builder(
    GeoLocation(latestVehicleLocation!!),  // 起点见 4.1
    destination
).build()

val task = navigationService.createNavigableRouteTask(request)

4.3 终点或途经点为 OnStreetParking(lineLocationReference

终点或途经点为 OnStreetParking(路边停车)检索结果时,除 displayPoint 外需设置 lineLocationReference,传入 Search 返回的有序形状点及到达侧信息。

  • 形状点数量建议 少于 50 个,线段总长度建议 少于 500 米
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// lineLocationReference 通常来自 OnStreetParking 的 Search 结果
val lineRef = searchResult.lineLocationReference  // 或自行构造 LineLocationReference

val onStreetParking = GeoLocation(
    displayPoint = LatLon(searchResult.lat, searchResult.lon),
    navPoints = searchResult.navPoints,
    address = searchResult.address,
    lineLocationReference = lineRef
)

val request = RouteRequest.Builder(
    GeoLocation(latestVehicleLocation!!),
    onStreetParking
).build()

val task = navigationService.createNavigableRouteTask(request)

4.4 EV 模式下目的地为充电桩(placeID

EV 路线规划中,目的地为充电桩时,必须设置充电桩的 placeID(来自 Search / Entity 返回的充电桩标识)。建议同时传入 displayPointnavPointsaddress

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
val chargerDestination = GeoLocation(
    placeID = chargerSearchResult.placeId,  // 必填
    displayPoint = LatLon(chargerSearchResult.lat, chargerSearchResult.lon),
    navPoints = chargerSearchResult.navPoints,
    addr = chargerSearchResult.address
)

val request = RouteRequest.Builder(
    GeoLocation(latestVehicleLocation!!),
    chargerDestination
)
    // EV 相关 RouteRequest 参数按项目配置
    .build()

val task = navigationService.createNavigableRouteTask(request)

4.5 仅已知经纬度(GeoLocation(lat, lon) / GeoLocation(LatLon)

无 Search 结果、无定位 Location 对象、无线性位置参考时的兜底方式。仅将 WGS84 坐标设为 displayPoint,匹配精度低于 4.1~4.4。与第 3 节用法相同。

1
2
3
4
5
6
7
8
9
// 方式一:直接传入纬度和经度
val origin = GeoLocation(37.386300, -122.005090)
val destination = GeoLocation(37.398760, -121.977360)

// 方式二:传入 LatLon
val destination2 = GeoLocation(LatLon(37.398760, -121.977360))

val request = RouteRequest.Builder(origin, destination).build()
val task = navigationService.createNavigableRouteTask(request)

5. 起点角度和速度算路

当车辆已经在行驶中,建议传入当前车头朝向和速度。SDK 会结合车辆方向和速度,尽量避免刚开始就立即转弯,选择更合理的起步路线。

  • heading(heading):车头朝向,以正北为 0 度,顺时针;默认 -1 表示未知。若起点使用带 bearingLocation 构造 GeoLocation,Builder 可能自动读取。
  • speedInMps(speed):车辆速度,单位 m/s;默认 0

示例代码:

1
2
3
4
5
6
7
8
9
val request = RouteRequest.Builder(
    GeoLocation(37.386300, -122.005090),
    GeoLocation(37.398760, -121.977360)
)
    .heading(180)
    .speedInMps(5)
    .build()

val task = navigationService.createNavigableRouteTask(request)

6. 途经点算路

使用 Waypoint 设置途经点。途经点按列表顺序依次经过,路线结果中的 Route.getRouteLegList() 会按照起点、途经点和终点拆分为多个 leg。

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
val waypoints = arrayListOf(
    Waypoint(GeoLocation(37.398160, -121.977160)),
    Waypoint(GeoLocation(37.328760, -121.927360))
)

val request = RouteRequest.Builder(
    GeoLocation(37.386300, -122.005090),
    GeoLocation(37.398760, -121.977360)
)
    .stopPoints(waypoints)
    .contentLevel(ContentLevel.FULL)
    .build()

val task = navigationService.createNavigableRouteTask(request)

7. 设置车辆信息

路线规划会参考系统中的车辆信息,例如车辆类型、四驱能力、货车尺寸和重量、电动车能耗等。车辆信息通过 SDK.getInstance().vehicleInfoProvider 设置,应在算路前完成配置。

示例代码:

1
2
3
4
val provider = SDK.getInstance().vehicleInfoProvider

provider.setVehicleCategory(VehicleCategory.AUTO)
provider.setDrivetrainType(DrivetrainType.FOUR_WHEEL_DRIVE)

注意:车辆信息应在算路前设置。对于已经创建的任务,后续更新车辆信息不一定会影响当前结果。

8. 货车路线规划

货车路线规划与普通驾车路线规划使用相同的算路接口。区别在于:算路前需要将车辆类型设置为货车,并配置货车尺寸信息。路线规划会根据货车高度、宽度、重量、总质量等信息判断道路限制。

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// 算路前配置货车信息:
val provider = SDK.getInstance().vehicleInfoProvider

val dimensions = VehicleDimensions(
    length = 500,
    width = 300,
    height = 270,
    weight = 2950,
    grossVehicleMass = 4250
)

provider.setDimensions(dimensions)
provider.setVehicleCategory(VehicleCategory.TRUCK)

// 随后创建货车路线请求:
val task = navigationService.createNavigableRouteTask(request)

处理结果时,可通过 Route.getTruckRestrictionRecords() 获取货车限制记录:

1
2
3
4
5
6
7
8
9
task.runAsync { routeResponse ->
    if (routeResponse.response.status != DirectionErrorCode.OK) return@runAsync

    for (route in routeResponse.response.result) {
        val restrictions = route.truckRestrictionRecords
        // 根据 restrictions 提示用户
    }
    task.dispose()
}

注意:货车信息必须在算路前设置。如果在一次路线计算完成后修改车辆信息,需要重新发起路线计算,新车辆信息才会生效。

9. 房车拖车路线规划

房车路线规划与货车路线规划使用相同的算路接口和车辆参数模型。区别在于:算路前需将车辆类型设置为 VehicleCategory.RV,并按实际车型配置尺寸与重量信息。

示例代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// 算路前配置房车信息:
val provider = SDK.getInstance().vehicleInfoProvider

val dimensions = VehicleDimensions(
    length = 532,
    width = 203,
    height = 195,
    weight = 1360,
    grossVehicleMass = 3000
)

provider.setDimensions(dimensions)
provider.setVehicleCategory(VehicleCategory.RV)

// 随后创建房车路线请求:
val task = navigationService.createNavigableRouteTask(request)

处理结果时,可同样通过 Route.getTruckRestrictionRecords() 读取沿途限制记录(如限高、限重等)用于提示:

1
2
3
4
5
6
7
8
9
task.runAsync { routeResponse ->
    if (routeResponse.response.status != DirectionErrorCode.OK) return@runAsync

    for (route in routeResponse.response.result) {
        val restrictions = route.truckRestrictionRecords
        // 根据 restrictions 提示用户
    }
    task.dispose()
}

注意:房车信息必须在算路前设置。如果在一次路线计算完成后修改车辆信息,需要重新发起路线计算,新车辆信息才会生效。

10. 云端鉴权与 Hybrid 算路

使用 createNavigableRouteTask无需 手动指定云端或车端模式。SDK 在 Hybrid 模式下会根据网络与地图数据状态自动选择算路来源。

云端能力(如 enableRouteSafety)依赖 SDK 初始化时的鉴权与云端地址配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
val sdkOptions = SDKOptions.builder()
    .setApiKey("<YOUR_API_KEY>")
    .setApiSecret("<YOUR_API_SECRET>")
    .setCloudEndPoint("<YOUR_CLOUD_ENDPOINT>")
    .setRegion("<YOUR_REGION>")
    .build()

SDK.getInstance().initialize(context, NavSDKOptions.builder(sdkOptions).build())

val navigationService = NavigationService.Factory.createInstance()
val task = navigationService.createNavigableRouteTask(request)

11. 常见注意事项

  • 起点和终点是必填项,缺失时无法发起有效算路请求。
  • 求路请使用 createNavigableRouteTask,由 SDK 自动 Hybrid 选路,无需手动指定 Onboard / Cloud。
  • 如果只需要 ETA 或路线预览,可使用较低的 ContentLevel;完整导航数据请使用 ContentLevel.FULLcreateNavigableRouteTask 会自动提升)。
  • 多路线数量只是请求上限,实际返回数量取决于路线差异、性能限制和途经点设置。
  • avoidTrafficCongestionfalse 时,普通拥堵不会主导选路,但封闭道路等阻断交通仍可能被避开。
  • avoidTrafficClosuresfalse 时,结果可能包含封闭道路,应结合 trafficClosures 展示或提示。
  • 货车路线应先设置完整车辆类型、尺寸和重量。
  • 任务使用完毕后务必调用 task.dispose();已 dispose 的任务不可再次 runAsync / runSync
  • 需要取消进行中的算路时,可调用 task.cancel(isBlocking)