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

How to extract route GPX from a Google Maps route?

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

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

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

由于我提到的两个工具还需要提供 Google 地图 API 键并启用方向 API,我的初步猜测是这些工具首先解析网页对于 waypoints,然后在 Directions API 调用中使用那些 waypoints 来获取所有路线轨迹点。

谢谢

解决方案在于 google 地图路线 link 的扩展 url 中的“数据”参数 link。

让我们以这个 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

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

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

//
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)]

一旦我们有了所有的经纬度对,我们就可以简单地启动 Google 地图方向 API 调用并在 link 中重新创建路线并将其导出为 GPX文件。