如何从谷歌地图路线中提取路线 GPX?

Posted

技术标签:

【中文标题】如何从谷歌地图路线中提取路线 GPX?【英文标题】:How to extract route GPX from a Google Maps route? 【发布时间】:2021-12-19 12:54:52 【问题描述】:

我的目标是将某些用户在 Google 地图上创建的路线提取到包含纬度经度的 GPX 文件中,以便在其他应用程序中进一步使用。

路线将通过这样的链接共享 - https://goo.gl/maps/HcikiDXFwN2coeFN8

有趣的是,这个应用程序已经在做我想做的事情了 - https://mapstogpx.com/ 和 https://www.gpsvisualizer.com/convert_input?convert_format=gpx。我只是想知道他们是如何做到的,以便我可以根据自己的需要模仿它。

由于我提到的这两个工具还需要提供启用了方向 API 的 Google Maps API 密钥,我最初的猜测是这些工具首先解析网页中的航点,然后在 Directions API 调用中使用这些航点获取所有路线跟踪点。

谢谢

【问题讨论】:

【参考方案1】:

解决方案在于谷歌地图路线链接的扩展网址中的“数据”参数。

让我们以这个 URL 为例 - https://goo.gl/maps/zrcP5gL1cd2AHGoq8

这扩展为https://www.google.com/maps/dir/Eiffel+Tower,+Paris,+France/Palais+Garnier,+Pl.+de+l'Op%C3%A9ra,+75009+Paris,+France/@48.8606129,2.2961092,14z/am=t/data=!4m29!4m28!1m20!1m1!1s0x47e6701f7e8337b5:0xa2cb58dd28914524!2m2!1d2.2930458!2d48.8560934!3m4!1m2!1d2.3122286!2d48.8490916!3s0x47e6702fa62d0bc5:0xd2d94ed604f2e5a0!3m4!1m2!1d2.3035972!2d48.8729816!3s0x47e66fc1755cf609:0x3c5040f902b41a5f!3m4!1m2!1d2.3235117!2d48.8581242!3s0x47e66e2ac3bca3ed:0x1c289763e3096e61!1m5!1m1!1s0x47e66e30d4668339:0xa9abf21c286d0767!2m2!1d2.3316014!2d48.8719697!3e0

仔细检查后,您会发现数据参数中嵌入了 lat-lng 坐标。例如这个 !1d2.2930458!2d48.8560934!1d2.3122286!2d48.8490916。这些是代表路线上各种航路点的经纬度对。经度始终以!1d 开头并以!2d 结尾,纬度以!2d 开头并以!3 结尾。

这是一个提取所有坐标的小 kotlin 方法:

//https://***.com/a/62191093/3090120
fun String?.indexesOf(pat: String, ignoreCase: Boolean = true): List<Int> =
        pat.toRegex(if (ignoreCase) setOf(RegexOption.IGNORE_CASE) else emptySet())
                .findAll(this ?: "")
                .map  it.range.first 
                .toList()

fun extractCoordinates(expandedUrl: String): List<LatLng> 
    val latLngList = arrayListOf<LatLng>()
    val indexes = expandedUrl.indexesOf("!1d")

    indexes.forEach 
        val coordinatesStr = expandedUrl.substring(it + 3).substringBefore("!3").split("!2d")
        latLngList.add(LatLng(coordinatesStr[1].toDouble(), coordinatesStr[0].toDouble()))
    

    return latLngList

这个字符串的结果是 [lat/lng: (48.8560934,2.2930458), lat/lng: (48.8490916,2.3122286), lat/lng: (48.8729816,2.3035972), lat/lng: (48.8581242,2.3235117), lat/lng: (48.8719697,2.3316014)]

一旦我们有了所有的 lat-lng 对,我们就可以简单地启动 Google Maps Directions API 调用并在链接中重新创建路线并将其导出为 GPX 文件。

【讨论】:

以上是关于如何从谷歌地图路线中提取路线 GPX?的主要内容,如果未能解决你的问题,请参考以下文章

如何在谷歌地图中绘制gpx文件

如何从谷歌地图API获取拥堵信息

如何使用谷歌方向 API 在苹果地图上快速绘制路线?

Android,在谷歌地图上绘制路线

谷歌地图 - 将嵌入移动到静态

在谷歌地图中做“沿途的兴趣点”