You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中Mapbox导航如何监听途经点(Waypoint)到达事件?

我之前在做Mapbox Android导航开发时也碰到过这个问题,确实默认的onArrival回调只会在到达最终目的地时触发,不过有两种靠谱的方式可以实现途经点到达的监听,分享给你:

方法一:通过监听导航路段(Leg)完成事件

Mapbox的导航路线会把整个行程拆分成多个Leg——每个Leg对应两个途经点(包括起点和终点)之间的路段。比如你设置了「起点→途经点A→途经点B→终点」,路线就会被拆成3个Leg:起点到A、A到B、B到终点。当某个Leg完成时,就意味着到达了该路段的终点,也就是我们要监听的途经点。

具体实现步骤:

  1. 启动导航前,先保存你的途经点列表(注意排除起点和终点,只保留中间的stop-point)
  2. 注册ProgressChangeListener,监听导航进度变化
  3. 在回调中检查当前Leg是否完成,匹配对应的途经点并执行操作

示例代码(Kotlin):

// 假设你已经构建好包含途经点的RouteOptions
val waypoints = routeOptions.waypoints
// 提取中间的途经点(排除起点和终点)
val stopPoints = if (waypoints.size > 2) waypoints.subList(1, waypoints.size - 1) else emptyList()

// 注册进度监听器
navigationView.registerProgressChangeListener(object : ProgressChangeListener {
    override fun onProgressChange(routeProgress: RouteProgress) {
        val currentLegProgress = routeProgress.currentLegProgress
        // 检查当前路段是否完成
        if (currentLegProgress.isLegComplete) {
            val currentLegIndex = routeProgress.currentLegIndex
            // 匹配对应的途经点(注意Leg索引和途经点索引的对应关系)
            if (currentLegIndex < stopPoints.size) {
                val arrivedStopPoint = stopPoints[currentLegIndex]
                // 这里执行你需要的操作,比如弹窗提示、上报数据等
                Log.d("MapboxNav", "到达途经点:${arrivedStopPoint.name ?: "未命名"}")
                // 可以添加标记避免重复触发,比如用一个集合记录已到达的途经点索引
            }
        }
    }
})
方法二:自定义里程碑(Milestone)实现精准位置触发

如果你需要更精确的触发(比如用户进入途经点周围5米范围内就执行操作),可以用Mapbox的Milestone机制,自定义触发条件来监听途经点位置。

具体实现步骤:

  1. 为每个途经点创建自定义Milestone,设置触发范围(比如5米)
  2. 启动导航时将这些里程碑添加到导航配置中
  3. 在里程碑的回调中执行到达操作

示例代码(Kotlin):

// 提取中间途经点
val waypoints = routeOptions.waypoints
val stopPoints = if (waypoints.size > 2) waypoints.subList(1, waypoints.size - 1) else emptyList()

// 为每个途经点创建自定义里程碑
val stopPointMilestones = stopPoints.mapIndexed { index, waypoint ->
    object : Milestone(
        // 设置触发条件:到达途经点的经纬度,且在5米范围内
        Trigger.all(
            Trigger.latitude(waypoint.latitude()),
            Trigger.longitude(waypoint.longitude()),
            Trigger.range(5.0)
        ),
        "stop_point_milestone_$index"
    ) {
        override fun onTriggered(
            routeProgress: RouteProgress,
            navigator: Navigator,
            navigationOptions: NavigationOptions
        ): MilestoneResult {
            // 执行到达途经点的操作
            Log.d("MapboxNav", "进入途经点范围:${waypoint.name ?: "未命名"}")
            return MilestoneResult.continueNavigation() // 继续导航
        }
    }
}

// 启动导航时添加里程碑
val navigationOptions = NavigationOptions.Builder(context)
    .routeOptions(routeOptions)
    .milestones(stopPointMilestones)
    .build()
navigationView.startNavigation(navigationOptions)

两种方法各有优势:方法一适合按路段完成逻辑触发,不需要精确位置;方法二更灵活,可以自定义触发距离,适合需要精准位置判断的场景。

内容的提问来源于stack exchange,提问作者Kinjal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 03:59:19