Skip to content

路线渲染

本指南:将算路结果绘制到地图,并管理高亮、路况刷新与已驶过路段消隐。

功能介绍

RoutesController 负责在地图上绘制导航/算路结果,支持多路线、自定义样式、高亮、行驶进度消隐与沿路线路况刷新等。

推荐使用 RouteLine + addRouteLine / addRouteLines 添加路线,并通过 RouteLine.Builder 配置路况、备选路线和分段渲染选项。

路线数据模型来自 telenav-android-map 模块:com.telenav.sdk.map.direction.model.Route 等。

效果示意

路线渲染

获取入口:

1
val routesController = mapView.getRoutesController() ?: return

核心接口一览

分类 接口 说明
添加路线 addRouteLine(routeLine) 添加单条路线
添加路线 addRouteLines(routeLines) 批量添加路线
刷新路线 refresh(routeLine) 重新渲染
刷新路况 refreshAlongRouteTraffic(alongRouteTraffic) 刷新导航沿线路况
移除路线 remove(routeID) 移除单条路线
移除路线 clear() 移除全部路线
进度消隐 updateRouteProgress(routeID) 当前正在导航的路线启用吃路
进度消隐 getLastEatenRoutePoint(routeID) 查询最后已驶过点
高亮 highlight(routeID) 高亮指定路线(同时仅一条)
高亮 unHighlight() 取消高亮
区域适配 region(routeIDs) 获取路线包围区域,用于相机适配
触摸事件 RouteTouchListener 路线点击 / 长按事件,详见 触摸与手势

接口详细说明

1. addRouteLine — 添加单条路线

将一条带渲染选项的路线绘制到地图上,返回引擎生成的路线 ID。后续的高亮、刷新、移除等操作都依赖此 ID。

1
fun addRouteLine(routeLine: RouteLine): String?
参数 类型 说明
routeLine RouteLine 通过 RouteLine.builder(route) 构建的路线对象,包含 Route 与渲染选项
返回值 String? 路线 ID;null 表示添加失败

RouteLine.Builder 配置项(构建 routeLine 时使用):

配置项 类型 默认值 说明
builder(route) Route 必填,算路返回的 Route
styleWithTraffic(enable) Boolean true 是否按路况着色
unreachableEdgeIndex(index) RouteEdgeIndex? null 不可达点(如电量/油量不足)
alternativeRoute(isAlt) Boolean false 是否为备选路线
currentRouteEdgeIndex(index) RouteEdgeIndex? null 起始边;此前路段按 trace 样式绘制
distinguishRouteLegColors(enable) Boolean false waypoint 分段着色(TSS 需 scheme B)

示例代码

1
2
3
4
5
6
7
8
9
val routeLine = RouteLine.builder(route)
    .styleWithTraffic(true)
    .alternativeRoute(false)
    .build()

val routeId: String = routesController.addRouteLine(routeLine) ?: run {
    Log.w(TAG, "add route failed")
    return
}


2. addRouteLines — 批量添加路线

一次性提交多条路线,常用于"主路线 + 多条备选路线"场景。

1
fun addRouteLines(routeLines: List<RouteLine>): List<String>
参数 类型 说明
routeLines List<RouteLine> 路线集合(主线 + 备选);建议主线放第一个
返回值 List<String> 与入参一一对应的路线 ID 列表;失败时返回空列表

示例代码

1
2
3
4
5
6
7
8
9
val mainLine = RouteLine.builder(mainRoute).build()
val altLines = altRoutes.map {
    RouteLine.builder(it)
        .alternativeRoute(true)
        .build()
}

val ids: List<String> = routesController.addRouteLines(listOf(mainLine) + altLines)
val mainRouteId = ids.firstOrNull() ?: return


3. refresh — 刷新已有路线

用于在 路线 ID 不变 的前提下更新已经绘制在地图上的同一条路线,例如:

  • 在原路线上叠加新的渲染选项(如开启 distinguishRouteLegColors、修改 unreachableEdgeIndex 等)。
  • 路况整体刷新或路线几何微调,但仍属于同一条路线。

使用前提refresh 只能在 routeID 保持一致时使用。若新 Route 的 ID 已变化,应 remove(oldRouteId)addRouteLine(newRouteLine),勿用 refresh

1
fun refresh(routeLine: RouteLine): String?
参数 类型 说明
routeLine RouteLine 新的 RouteLine,须携带与原路线 相同 IDRoute,可附带新的渲染选项
返回值 String? 刷新后的路线 ID;失败返回 null

示例代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 场景 A:同一条路线,仅更新渲染选项
val refreshed = RouteLine.builder(sameRoute)
    .styleWithTraffic(true)
    .distinguishRouteLegColors(true)
    .build()

routesController.refresh(refreshed)

// 场景 B:算路返回的是一条新路线(ID 已变化)
// 不要用 refresh,应该先移除旧路线再添加新路线
routesController.remove(oldRouteId)
val newRouteLine = RouteLine.builder(newRoute).build()
val newRouteId = routesController.addRouteLine(newRouteLine)


4. refreshAlongRouteTraffic — 实时刷新导航沿路路况

用于在 导航过程中 实时更新当前路线的沿路 traffic 显示。导航服务(Drive Session)会通过 NavigationEventListener.onAlongRouteTrafficUpdated 周期性推送最新的沿路路况数据,业务方将该数据直接透传给 refreshAlongRouteTraffic 即可让地图按最新路况重新着色,无需 重新算路或重新 addRouteLine

适用场景:

  • 导航过程中前方路段路况由畅通变为拥堵 / 恢复畅通。
  • 接近事故 / 施工区域时引擎下发新的路况切片。
  • 长时间导航中后台周期性的路况增量更新。
1
fun refreshAlongRouteTraffic(alongRouteTraffic: AlongRouteTraffic): String?
参数 类型 说明
alongRouteTraffic AlongRouteTraffic 来自 NavigationEventListener.onAlongRouteTrafficUpdated 的沿路路况对象,业务方原样传入即可
返回值 String? 被刷新的路线 ID;无对应路线时返回 null

示例代码

1
2
3
4
5
6
7
// 仅导航开始后注册一次,导航期间引擎会持续推送
navigationSession.addEventListener(object : NavigationEventListener {
    override fun onAlongRouteTrafficUpdated(traffic: AlongRouteTraffic) {
        // 直接透传给地图模块刷新路线颜色,无需重新算路
        routesController.refreshAlongRouteTraffic(traffic)
    }
})

注意:该接口仅刷新 路况着色,不会修改路线几何形状。


路线路况着色

开启 RouteLine.Builder.styleWithTraffic(true)(默认 true)后,SDK 会按路况为路线分段着色。路况数据来自两类来源:

场景 数据来源 刷新方式
算路预览 / 首次 addRouteLine RouteRouteEdge 上的 liveTrafficLeveltrafficFlow(算路时刻快照) addRouteLine / refresh
导航中实时更新 AlongRouteTraffic.alongRouteTrafficFlowNavigationEventListener.onAlongRouteTrafficUpdated 推送) refreshAlongRouteTraffic

AlongRouteTrafficAlongRouteTrafficFlowSegment 及采集区间字段说明见 沿途交通。导航中应以 onAlongRouteTrafficUpdated 推送的数据为准;算路结果中的交通字段仅作首屏预览。

路况数据模型

AlongRouteTraffic

导航沿路交通的顶层对象,由 onAlongRouteTrafficUpdated 回调下发。地图侧调用 refreshAlongRouteTraffic(alongRouteTraffic) 时,SDK 根据其中的 alongRouteTrafficFlow 重新计算各 edge 的路况等级并刷新着色。

字段 与着色的关系
route 当前导航路线,须与地图上已绘制的路线一致
collectedStartLegIndex / Step / Edge 采集区间起点;区间外 edge 使用算路结果中的 liveTrafficLevel
collectedEndLegIndex / Step / Edge 采集区间终点
alongRouteTrafficFlow 核心字段:分段路况列表,决定区间内各 edge 的 congestionLevel
alongRouteTrafficIncidents 交通事件列表,不参与路线分段着色(供 HMI 展示事件、触发换路等)

AlongRouteTrafficFlowSegment

alongRouteTrafficFlow 列表中的单段路况,通过 startLegIndex / startStepIndex / startEdgeIndexendLegIndex / endStepIndex / endEdgeIndex 描述在路线上的覆盖范围。

字段 说明
congestionLevel 本段拥堵等级,取值为 TrafficLevel 常量
flowSpeed 平均速度(米/秒);0 表示阻塞
flowLength 本段长度(米)
startEdgeOffset / endEdgeOffset edge 内起止偏移(米);同一 edge 上可存在多个不同路况的子段

TrafficLevel — 拥堵等级

TrafficLevel 定义于 com.telenav.sdk.map.content.model.TrafficLevel,为 @IntDef 注解,用于标注路况等级整型常量:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@IntDef({CLOSED, CONGESTED, QUEUING, SLOW_SPEED, HEAVY, FREE_FLOW, UNKNOWN_LEVEL})
@Retention(RetentionPolicy.SOURCE)
public @interface TrafficLevel {
    int CLOSED = 1;
    int CONGESTED = 3;
    int QUEUING = 4;
    int SLOW_SPEED = 5;
    int HEAVY = 6;
    int FREE_FLOW = 7;
    int UNKNOWN_LEVEL = 10;
}
常量 含义 当前数据是否下发
CLOSED 1 封闭
CONGESTED 3 拥堵
QUEUING 4 严重拥堵
SLOW_SPEED 5 缓行
HEAVY 6 行驶缓慢
FREE_FLOW 7 畅通
UNKNOWN_LEVEL 10 未知 / 无数据

当前沿路交通数据仅会下发 CLOSED(1)、CONGESTED(3)、SLOW_SPEED(5)、FREE_FLOW(7)、UNKNOWN_LEVEL(10)五种等级。 QUEUING(4)与 HEAVY(6)在 TrafficLevel 中有定义,但现阶段服务端不会输出。地图路线着色与 congestionLevel 一一对应,因此实际展示的也是上述五种路况颜色。

数值越小表示路况越差(CLOSED 最严重,FREE_FLOW 最畅通)。

着色逻辑摘要

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
addRouteLine(styleWithTraffic=true)
        ↓
遍历 Route 各 RouteEdge
        ↓
导航中且 edge 在 AlongRouteTraffic 采集区间内?
  ├─ 是 → 查 alongRouteTrafficFlow,取 congestionLevel
  │        未命中任何 flow 段 → UNKNOWN_LEVEL (10)
  └─ 否 → 使用 RouteEdge.liveTrafficLevel(算路快照)
        ↓
TSS routes-traffic layer 按 congestionLevel 渲染对应颜色

5. remove — 移除指定路线

1
fun remove(routeID: String)
参数 类型 说明
routeID String 要移除的路线 ID,来自 addRouteLine / addRouteLines 的返回值

示例代码

1
routesController.remove(routeId)


6. clear — 移除全部路线

1
fun clear()

一次性清除地图上所有路线,常用于退出导航、切换 trip 时。

示例代码

1
routesController.clear()


7. updateRouteProgress — 启用导航吃路(已驶过路段消隐)

用于 导航过程中的"吃路"效果:启用后,引擎随车辆行驶自动隐藏(或置灰,可按产品定制)已驶过路段,无需每帧或每次定位更新时重复调用。

1
fun updateRouteProgress(routeID: String)
参数 类型 说明
routeID String 当前正在导航、且已添加到地图的路线 ID(addRouteLine 返回值)

调用时机:凡是通过 addRouteLine 画到地图上、且正在被导航服务使用的路线,添加后 调用一次。Better route、偏航重算等导致导航 Route / routeId 变化时,对新路线再调用一次。

场景 是否调用 说明
首次开始导航 addRouteLine 后、导航启动时调用一次
Better route / 偏航重算,导航路线切换 route.id 变化;remove 旧线 → addRouteLine 新线 → 对新 routeId 再调用
routeIdrefresh 更新路况或几何 吃路状态会延续
备选路线、算路预览 非当前导航路线勿调用

启用后,引擎根据 自车图标显示 中的车辆位置持续消隐已驶过段,直到 remove(routeId) / clear() 或导航结束。

示例:首次导航

1
2
3
val navRouteId = routesController.addRouteLine(RouteLine.builder(navRoute).build()) ?: return
navigationSession.start(navRoute)
routesController.updateRouteProgress(navRouteId)  // 导航路线加入地图后调用一次

示例:Better route 切换导航路线

导航服务接受更优路线或重算路后,会下发新的 Routeroute.id 通常与旧路线不同)。地图侧需同步替换显示,并对新路线重新启用吃路:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 监听 NavigationEventListener.onNavigationRouteUpdating 或观察导航 Route 更新
override fun onNavigationRouteUpdating(progress: BetterRouteUpdateProgress) {
    if (progress.status != BetterRouteUpdateProgress.Status.SUCCEEDED) return

    val newRoute = progress.newRoute ?: return

    // 1) 移除地图上旧的导航路线
    oldNavRouteId?.let { routesController.remove(it) }

    // 2) 将新的导航路线画到地图(addRouteLine 或 refresh,视是否已有同 id 路线而定)
    val routeLine = RouteLine.builder(newRoute).build()
    val newRouteId = routesController.addRouteLine(routeLine) ?: return

    // 3) 新导航路线加入地图后,对新 routeId 调用一次吃路
    if (newRouteId != oldNavRouteId) {
        routesController.updateRouteProgress(newRouteId)
        oldNavRouteId = newRouteId
    }
}

若业务回调统一收到导航 Route 更新,可在 route.id 变化时执行:remove(旧 id)addRouteLine(新路线)updateRouteProgress(新 routeId)


8. getLastEatenRoutePoint — 查询最后已驶过点

1
fun getLastEatenRoutePoint(routeID: String): Location?
参数 类型 说明
routeID String 查询的路线 ID
返回值 Location? 最近一次被引擎"吃掉"的路线点;未启用吃路时为 null

示例代码

1
2
val lastEaten: Location? = routesController.getLastEatenRoutePoint(routeId)
lastEaten?.let { Log.d(TAG, "current progress: ${it.latitude}, ${it.longitude}") }


9. highlight — 高亮指定路线

同一时刻只能有一条路线处于高亮态,常用于备选路线选中、点击路线切换等场景。

1
fun highlight(routeID: String)
参数 类型 说明
routeID String 要高亮的路线 ID

10. unHighlight — 取消高亮

1
fun unHighlight()

取消当前高亮,无参数。

示例代码

1
2
routesController.highlight(altRouteId)
routesController.unHighlight()

11. region — 获取路线包围区域

返回能完整覆盖指定路线的经纬度包围盒,常配合 CameraController.showRegion 做路线全览。

1
fun region(routeIDs: List<String?>): Camera.Region?
参数 类型 说明
routeIDs List<String?> 需要纳入区域的路线 ID 集合,可包含多条
返回值 Camera.Region? 路线包围区域;无有效路线时为 null

示例代码

1
2
3
4
5
6
val region = routesController.region(listOf(routeId))
region?.let {
    mapView.getCameraController()?.showRegion(it)
}

// 若需要带 HMI 面板边距,可用 showRegion(region, marginRect / pixelMargins / percentageMargins)

更推荐 CameraController.showRegionForRoutes(RegionForRoutesInfo),可直接指定屏幕矩形、是否包含 CVP、是否仅看最近 leg 等;详见 显示模式与视角


12. 路线触摸事件

通过 MapView.setOnRouteTouchListener 监听路线点击/长按,常见用法是点击备选路线后高亮切换。回调签名与注册方式见 触摸与手势

回调参数 类型 说明
touchType TouchType 触摸类型(短按 / 长按等)
position TouchPosition 触摸点屏幕与地理坐标
routeID String 被触摸的路线 ID

示例代码

1
2
3
4
mapView.setOnRouteTouchListener { _, _, touchedRouteId ->
    //  高亮用户点中的路线(同时仅一条处于高亮态)
    routesController.highlight(touchedRouteId)
}

注意事项

  • 算路由 Direction 模块完成,本模块仅负责 渲染
  • updateRouteProgress:每条正在导航的路线在 addRouteLine 后调用一次即可;Better route、偏航重算等导致导航 Route / routeId 变化时,需对新路线再调用一次。无需每帧重复调用。
  • 显示模式与视角 配合:showRegionForRoutes 适配路线区域时 layout offset 须为 0。
  • 自车图标显示 配合:车辆位置更新会驱动路线进度与已驶过路段展示。
  • 转弯箭头(Turn Arrow)由 SDK 内部根据导航状态自动管理,业务方无需调用相关接口。

相关指南