You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将Google Maps交通数据解析为JSON?安卓路径规划应用求助

解决Google Maps交通数据解析为JSON并实现最优路径的方案

Hey there! Let's break down how you can parse Google Maps Traffic data into JSON and build that optimal path feature for your campus Android app—here's a practical, step-by-step approach:

1. 先搞懂要用哪个API

你需要用Google Maps Directions API,它本身就会返回带实时/预测交通数据的JSON响应,完全不需要自己去“解析”原始交通数据(Google已经帮你封装好啦)。这个API能直接返回考虑交通状况的路径时长、距离,甚至多条路线供你对比选最优。

2. 准备工作:启用API并获取密钥

  • 去Google Cloud Console启用「Directions API」
  • 创建一个受限制的API密钥(强烈建议:只允许你的安卓应用包名+SHA-1指纹访问,避免密钥被盗用)

3. 构造API请求(直接获取JSON格式的交通路径数据)

你需要发送一个GET请求到以下地址,替换参数为你的实际数据:

https://maps.googleapis.com/maps/api/directions/json?origin=当前位置经纬度&destination=目的地经纬度&departure_time=now&traffic_model=best_guess&key=你的API密钥

参数解释:

  • departure_time=now:告诉API获取实时交通数据(如果要预测未来时间的交通,换成对应的Unix时间戳)
  • traffic_model:可选值best_guess(默认,最准确的预测)、pessimistic(最坏情况)、optimistic(最佳情况)

4. 在安卓里发送请求并解析JSON

推荐用Retrofit+Gson来做网络请求和自动解析,比手动写JSONObject简洁太多。下面是具体代码示例:

第一步:添加依赖

在你的app模块build.gradle里加入:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

第二步:定义API接口

interface DirectionsApi {
    @GET("maps/api/directions/json")
    suspend fun getOptimalRoute(
        @Query("origin") origin: String, // 格式:"纬度,经度",比如"39.9042,116.4074"
        @Query("destination") destination: String,
        @Query("departure_time") departureTime: Long = System.currentTimeMillis() / 1000, // 转成Unix时间戳(秒)
        @Query("traffic_model") trafficModel: String = "best_guess",
        @Query("key") apiKey: String
    ): Response<RouteResponse>
}

第三步:定义对应JSON结构的数据模型

Gson会自动把JSON响应映射到这些类里:

data class RouteResponse(
    val routes: List<Route> // API可能返回多条路线
)

data class Route(
    val legs: List<Leg> // 每条路线的分段(比如从起点到终点的整个路段)
)

data class Leg(
    val distance: Distance, // 总距离(无视交通)
    val duration: Duration, // 总时长(无视交通)
    val duration_in_traffic: DurationInTraffic, // 考虑交通的总时长(核心!用来选最优路径)
    val steps: List<Step> // 路径的每一步细节
)

// 辅助数据类
data class Distance(val text: String, val value: Int) // value是米数
data class Duration(val text: String, val value: Int) // value是秒数
data class DurationInTraffic(val text: String, val value: Int)
data class Step(val html_instructions: String, val distance: Distance, val duration: Duration)

第四步:发起请求并处理结果

在ViewModel或者Repository里用协程调用(避免阻塞主线程):

// 初始化Retrofit
val retrofit = Retrofit.Builder()
    .baseUrl("https://maps.googleapis.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

val directionsApi = retrofit.create(DirectionsApi::class.java)

// 在协程中执行请求
viewModelScope.launch {
    try {
        // 替换成你实际获取的当前位置和目的地经纬度
        val currentLocation = "${location.latitude},${location.longitude}"
        val destination = "39.9526,116.3972" // 示例坐标

        val response = directionsApi.getOptimalRoute(
            origin = currentLocation,
            destination = destination,
            apiKey = "YOUR_RESTRICTED_API_KEY"
        )

        if (response.isSuccessful) {
            val routeResponse = response.body()
            routeResponse?.let {
                // 从多条路线中选最优:找duration_in_traffic最小的那条
                val optimalRoute = it.routes.minByOrNull { route ->
                    route.legs.firstOrNull()?.duration_in_traffic?.value ?: Int.MAX_VALUE
                }

                optimalRoute?.legs?.firstOrNull()?.let { leg ->
                    // 拿到最优路径的关键数据
                    val trafficAwareDuration = leg.duration_in_traffic.text
                    val totalDistance = leg.distance.text
                    // 这里把数据更新到你的地图UI上,比如显示"预计15分钟(交通拥堵)"
                    updateMapWithOptimalPath(leg.steps) // 可以把steps解析成地图上的路线点
                }
            }
        } else {
            Log.e("DirectionsError", "请求失败: ${response.errorBody()?.string()}")
        }
    } catch (e: Exception) {
        Log.e("NetworkError", "网络异常: ${e.message}")
    }
}

5. 关键注意事项

  • 权限:别忘了在AndroidManifest.xml里添加ACCESS_FINE_LOCATIONINTERNET权限,还要动态请求位置权限。
  • 密钥安全:绝对不要把API密钥硬编码在代码里!把它放在local.properties里,通过gradle引用,或者用Google Cloud的API限制功能。
  • 多条路线选择:如果API返回多条routes,对比每条的duration_in_traffic.value(秒数),最小的就是交通状况下的最优路径。

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

火山引擎 最新活动