feiyu02
2024-07-04 022af485fbd77bc3d6b01f9f779248b3c189dad2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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 java.nio.charset.Charset
 
/**
 * 高德地图Web服务API
 */
object AMapService {
 
    private const val TAG = "AMapService"
    private const val KEY = "520c5e5cf44c7793104e500cbf0ed711"
 
    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,
    )
 
    /**
     * 地理逆编码
     * @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}")
        }
    }
 
    /**
     * 坐标转换
     * @param locations 原始坐标
     * @param coordsys 原坐标系,可选值:gps;mapbar;baidu;autonavi(不进行转换)
     */
    fun coordinateConvert(locations: List<Pair<Double, Double>>, coordsys:String="gps"): List<Pair<Double, Double>> {
        val res = httpMethod.get("/v3/assistant/coordinate/convert", listOf(
            "key" to KEY,
            "locations" to locations.joinToString("|") { "${it.first},${it.second}" },
            "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 = if (res.m.responseCharSet == "utf-8") {
//                res.m.responseBodyAsString
//            } else {
//                String(res.m.responseBody, Charset.forName("utf-8"))
//            }
            val str = res.m.responseBodyAsString
            val json = JsonParser.parseString(str)
            return resCheck(json)
        } else {
            throw BizException("高德API网路链接错误,状态码:${res.m.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
    }
}