如何从 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
仔细检查,您会发现数据参数中嵌入了经纬度坐标。例如这个
!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文件。
我的 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
仔细检查,您会发现数据参数中嵌入了经纬度坐标。例如这个
!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文件。