Google Maps Directions API路线折线与实际道路不匹配问题
问题根因
当前绘制的路线与道路不贴合、长距离场景偏差明显的核心原因是你当前使用的overview_polyline是API默认返回的抽稀概略线:
- Google Directions API默认返回的
overview_polyline会对折线点做大幅度抽稀,只保留能勾勒路线大致走向的最少点位,天生不适合高精度渲染 - 短距离路线抽稀后点位密度尚可,因此偏差不明显;长距离下点位间距可达数公里,自然无法匹配道路曲率
- 你之前在MapBox中通过
overview=full解决同类问题的方案在Google Directions API中同样适用,只是当前接口定义未传入该参数,同时解析逻辑取的是默认概略线。
解决步骤
1. 接口新增overview参数,请求高精度全路线折线
Google Directions API原生支持overview请求参数,和MapBox逻辑一致,可选值如下:
full:返回未做过度抽稀的全路线高精度折线,点密度足够支撑常规路线渲染simplified:默认值,即你当前拿到的概略抽稀线,仅适合小视图下看全局走向false:不返回顶层概略折线,需要逐段拼接step级折线,精度最高
修改你的API接口定义,新增该参数:
@GET("directions/json") suspend fun getDirectionFromGoogle( @Query("origin") origin: String, @Query("destination") destination: String, @Query("key") apiKey: String, @Query("mode") mode: String = "driving", @Query("overview") overview: String = "full" // 新增参数,默认请求高精度折线 ): Response<String>
2. (最高精度方案)替换解析逻辑,逐step拼接导航级折线
如果传overview=full后长距离路线仍有细微偏差,直接放弃顶层overview_polyline,遍历所有路段的step,将每个step自带的高精度折线按顺序拼接,得到的是和导航引导完全一致的路线点,100%贴合道路。
将原有解析逻辑中读取overview_polyline的代码替换为以下逻辑:
// 删除原有概略线读取逻辑 // val ovPolyline = firstRoute.getJSONObject("overview_polyline") // val polyline = ovPolyline.getString("points") // 逐段拼接step级高精度折线 val polylinePoints = mutableListOf<LatLng>() val routes = responseObject.getJSONArray("routes") val firstRoute = routes.getJSONObject(0) val legs = firstRoute.getJSONArray("legs") for (legIdx in 0 until legs.length()) { val currentLeg = legs.getJSONObject(legIdx) val steps = currentLeg.getJSONArray("steps") for (stepIdx in 0 until steps.length()) { val step = steps.getJSONObject(stepIdx) val stepPolyPoints = PolyUtil.decode(step.getJSONObject("polyline").getString("points")) // 去掉相邻段的重复点,避免折线出现异常拐点 if (polylinePoints.isNotEmpty() && stepPolyPoints.isNotEmpty()) { polylinePoints.addAll(stepPolyPoints.drop(1)) } else { polylinePoints.addAll(stepPolyPoints) } } } emit(DataState.Success(polylinePoints))
3. 调整折线渲染配置
将折线配置中的geodesic(false)改为geodesic(true),跨大经纬度范围的长距离路线下,测地线绘制模式会适配地图投影规则,避免平面直线带来的投影偏差。
修改后的折线配置参考:
val directionPolyline = mMap.addPolyline( PolylineOptions() .color(ContextCompat.getColor(requireContext(), R.color.colorPrimaryDark)) .geodesic(true) // 改为测地线模式 .endCap(RoundCap()) .startCap(RoundCap()) .addAll(listOfPoints) )
效果说明
修改后长距离路线返回的折线点密度是默认概略线的3-10倍,逐step拼接的方案点密度可达米级,完全贴合实际道路,不会出现折线飘出道路的问题。
内容的提问来源于stack exchange,提问作者mohit48
相关产品推荐
相关产品推荐

