package com.flightfeather.uav.common.net
|
|
import com.flightfeather.uav.common.exception.BizException
|
import com.google.gson.Gson
|
import com.google.gson.JsonElement
|
import com.google.gson.JsonObject
|
import com.google.gson.JsonParser
|
import org.apache.http.util.EntityUtils
|
import java.net.URLEncoder
|
import java.nio.charset.Charset
|
|
/**
|
* 高德地图Web服务API
|
* Date: 2024/07/14
|
*/
|
object AMapService {
|
|
private const val TAG = "AMapService"
|
private const val KEY = "b36a93bac8950d3d7c6c06f21133de51"
|
|
private val httpMethod = HttpMethod("restapi.amap.com", 443, true)
|
|
data class AMapAddress(
|
val country: String,
|
val province: String,
|
val city: String,
|
val citycode: String,
|
val district: String,
|
val adcode: String,
|
val township: String,
|
val towncode: String,
|
val street: String,
|
)
|
|
data class AMapDirection(
|
// 路线类型,driving: 驾车;
|
val type: String,
|
// 起点经纬度
|
val origin: Pair<Double, Double>,
|
// 终点经纬度
|
val destination: Pair<Double, Double>,
|
// 途径路线经纬度(不包括起点终点)
|
val paths: List<Pair<Double, Double>>,
|
// 方案距离,单位:米
|
val distance: String
|
)
|
|
/**
|
* 驾车路线规划
|
*/
|
fun directionDriving(origin: Pair<Double, Double>, destination: Pair<Double, Double>):AMapDirection {
|
val res = httpMethod.get(
|
"/v5/direction/driving", listOf(
|
"key" to KEY,
|
"origin" to "${origin.first},${origin.second}",
|
"destination" to "${destination.first},${destination.second}",
|
"show_fields" to "polyline"
|
)
|
)
|
val obj = handleRes(res)
|
try {
|
val count = obj["count"].asString.toIntOrNull()
|
if (count != null && count > 0) {
|
val path = obj["route"].asJsonObject["paths"].asJsonArray.get(0).asJsonObject
|
val finalPaths = mutableListOf<Pair<Double,Double>>()
|
path["steps"].asJsonArray.forEach {
|
finalPaths.addAll(
|
it.asJsonObject["polyline"].asString.split(";").map { str->
|
val strArr = str.split(",")
|
strArr[0].toDouble() to strArr[1].toDouble()
|
}
|
)
|
}
|
return AMapDirection("driving", origin, destination, finalPaths, path["distance"].asString)
|
} else {
|
throw BizException("高德API驾车路线规划失败,没有找到可行的路线")
|
}
|
} catch (e: Exception) {
|
throw BizException("高德API驾车路线规划错误,${e.message}")
|
}
|
}
|
|
/**
|
* 地理逆编码
|
* @param location 坐标点
|
* @return 所在街道
|
*/
|
fun reGeo(location:Pair<Double, Double>):AMapAddress {
|
val res = httpMethod.get("/v3/geocode/regeo", listOf(
|
"key" to KEY,
|
"location" to "${location.first},${location.second}"
|
))
|
val obj = handleRes(res)
|
try {
|
val a = obj["regeocode"].asJsonObject["addressComponent"].asJsonObject
|
return AMapAddress(
|
a["country"].asString,
|
a["province"].asString,
|
"",
|
a["citycode"].asString,
|
a["district"].asString,
|
a["adcode"].asString,
|
a["township"].asString,
|
a["towncode"].asString,
|
a["streetNumber"].asJsonObject["street"].asString,
|
)
|
} catch (e: Exception) {
|
throw BizException("高德API坐标转换错误,${e.message}", e.cause)
|
}
|
}
|
|
/**
|
* 坐标转换
|
* @param locations 原始坐标
|
* @param coordsys 原坐标系,可选值:gps;mapbar;baidu;autonavi(不进行转换)
|
*/
|
fun coordinateConvert(locations: List<Pair<Double, Double>>, coordsys:String="gps"): List<Pair<Double, Double>> {
|
val locationsStr = URLEncoder.encode(locations.joinToString("|") { "${it.first},${it.second}" }, "UTF-8")
|
val res = httpMethod.get("/v3/assistant/coordinate/convert", listOf(
|
"key" to KEY,
|
"locations" to locationsStr,
|
"coordsys" to coordsys
|
))
|
val obj = handleRes(res)
|
try {
|
return obj["locations"].asString.split(";").map {
|
val l = it.split(",")
|
l[0].toDouble() to l[1].toDouble()
|
}
|
} catch (e: Exception) {
|
throw BizException("高德API坐标转换错误,${e.message}")
|
}
|
}
|
|
private fun handleRes(res: HttpMethod.MyResponse):JsonObject {
|
if (res.success) {
|
val str = EntityUtils.toString(res.m.entity)
|
val json = JsonParser.parseString(str)
|
return resCheck(json)
|
} else {
|
throw BizException("高德API网路链接错误,状态码:${res.m.statusLine.statusCode}")
|
}
|
}
|
|
private fun resCheck(json: JsonElement): JsonObject {
|
if (!json.isJsonObject) throw BizException("高德API失败,返回值不是一个object")
|
|
val jo = json.asJsonObject
|
if (jo["status"].asInt != 1) throw BizException("高德API失败,错误${jo["info"]}")
|
|
return jo
|
}
|
}
|