amap.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package amap
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "git.qianqiusoft.com/qianqiusoft/light-apiengine/utils"
  6. "errors"
  7. "math"
  8. )
  9. const(
  10. __AMAP_API_ENDPOINT = "https://restapi.amap.com"
  11. __KEY = "427befed1b2db94d6753b679d7330772"
  12. )
  13. type AMapClient struct{
  14. Key string
  15. }
  16. /**
  17. * @brief: 逆地理编码
  18. * @param1 lngLats: 经纬度列表,{lng1,lat1,lng2,lat2}
  19. * @return1: 逆转换结果
  20. * @return2: 错误信息
  21. */
  22. func (a *AMapClient)Regeo(lngLats []string)(*RegeoResult, error){
  23. if lngLats == nil || len(lngLats) == 0{
  24. return nil, errors.New("参数lnglats为空")
  25. }
  26. if len(lngLats) % 2 != 0{
  27. return nil, errors.New("参数lnglats长度必须为2的倍数")
  28. }
  29. path := "/geocode/regeo"
  30. location := ""
  31. location = fmt.Sprintf("%s,%s", lngLats[0], lngLats[1])
  32. for i := 2; i < len(lngLats); i += 2 {
  33. location += "|" + fmt.Sprintf("%s,%s", lngLats[i], lngLats[i+1])
  34. }
  35. params := make(map[string]string)
  36. params["location"] = location
  37. params["batch"] = "true"
  38. fullUrl := a.getFullUrl(path, params)
  39. bytess, err := utils.NewHttpUtil().Get(fullUrl, nil, nil)
  40. if err != nil{
  41. return nil, err
  42. }
  43. regeoResult := &RegeoResult{}
  44. err = json.Unmarshal(bytess, regeoResult)
  45. if err != nil{
  46. return nil, err
  47. }
  48. return regeoResult, nil
  49. }
  50. /**
  51. * @brief: 坐标转换(通过请求高德接口)
  52. * @param1 lngLats: 经纬度列表
  53. * @param2 coordType: 坐标类型 gps;mapbar;baidu;autonavi
  54. * @return1: 坐标转回结果
  55. * @return2: 错误信息
  56. */
  57. func (a *AMapClient)ConvCoord(lngLats []string, coordType string)(*ConvCoordResult, error){
  58. locations := a.getLocations(lngLats)
  59. params := make(map[string]string)
  60. params["locations"] = locations
  61. params["coordsys"] = coordType
  62. path := "/assistant/coordinate/convert"
  63. fullUrl := a.getFullUrl(path, params)
  64. bytess, err := utils.NewHttpUtil().Get(fullUrl, nil, nil)
  65. if err != nil{
  66. return nil, err
  67. }
  68. result := &ConvCoordResult{}
  69. err = json.Unmarshal(bytess, result)
  70. if err != nil{
  71. return nil, err
  72. }
  73. return result, nil
  74. }
  75. /**
  76. * @brief: 把gps转成高德地图坐标
  77. * @param1 gpsLng: gps 经度
  78. * @param2 gpsLat: gps 纬度
  79. * @return1: 高德地图经度
  80. * @return2: 高德地图纬度
  81. */
  82. func (aa *AMapClient)ConvGpsToAMap(gpsLng, gpsLat float64)(float64, float64, bool){
  83. if outOfChinal(gpsLng, gpsLat){
  84. return gpsLng, gpsLat, false
  85. }
  86. dLat := transformLat(gpsLng - 105.0, gpsLat - 35.0)
  87. dLon := transformLon(gpsLng - 105.0, gpsLat - 35.0)
  88. radLat := gpsLat / 180.0 * pi
  89. magic := math.Sin(radLat)
  90. magic = 1 - ee * magic * magic
  91. sqrtMagic := math.Sqrt(magic)
  92. dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi)
  93. dLon = (dLon * 180.0) / (a / sqrtMagic * math.Cos(radLat) * pi)
  94. return gpsLng + dLon, gpsLat + dLat, true
  95. }
  96. /**
  97. * @brief: 获取天气
  98. * @param1 city: 区编码
  99. * @param2 forecast: 是否预报天汽水
  100. * @return1: 天气结果
  101. * @return2: 错误信息
  102. */
  103. func (a *AMapClient)FetchWeather(city string, live bool)(*WeatherResult, error){
  104. params := make(map[string]string)
  105. params["city"] = city
  106. if !live{
  107. params["extensions"] = "all"
  108. }
  109. path := "/weather/weatherInfo"
  110. fullUrl := a.getFullUrl(path, params)
  111. bytess, err := utils.NewHttpUtil().Get(fullUrl, nil, nil)
  112. if err != nil{
  113. return nil, err
  114. }
  115. result := &WeatherResult{}
  116. err = json.Unmarshal(bytess, result)
  117. if err != nil{
  118. return nil, err
  119. }
  120. return result, nil
  121. }
  122. /**
  123. * @brief: 根据ip获取地址信息
  124. * @param1 ip: ip,空标识使用请求ip获取地址
  125. */
  126. func (a *AMapClient)FectionLocationByIp(ip string)(*IpResult, error){
  127. if ip == ""{
  128. return nil, errors.New("ip不能为空")
  129. }
  130. params := make(map[string]string)
  131. params["ip"] = ip
  132. path := "/ip"
  133. fullUrl := a.getFullUrl(path, params)
  134. bytess, err := utils.NewHttpUtil().Get(fullUrl, nil, nil)
  135. if err != nil{
  136. return nil, err
  137. }
  138. result := &IpResult{}
  139. err = json.Unmarshal(bytess, result)
  140. if err != nil{
  141. return nil, err
  142. }
  143. return result, nil
  144. }
  145. /**
  146. * @brief: 获取完全url
  147. * @param1 path: 请求path
  148. * @param2 params: 参数
  149. */
  150. func (a *AMapClient)getFullUrl(path string, params map[string]string)string{
  151. version := "v3"
  152. paramsStr := ""
  153. params["key"] = a.Key
  154. for k, v := range params{
  155. paramsStr += fmt.Sprintf("%s=%s&", k, v)
  156. }
  157. return __AMAP_API_ENDPOINT + "/" + version + path + "?" + paramsStr
  158. }
  159. /**
  160. * @brief: 多个坐标转换程参数形式
  161. * @param1 lngLats: 坐标列表
  162. * @return1: 坐标结果 lng1,lat1|lng2,lat2
  163. */
  164. func (a *AMapClient)getLocations(lngLats []string)string{
  165. location := ""
  166. location = fmt.Sprintf("%s,%s", lngLats[0], lngLats[1])
  167. for i := 2; i < len(lngLats); i += 2 {
  168. location += "|" + fmt.Sprintf("%s,%s", lngLats[i], lngLats[i+1])
  169. }
  170. return location
  171. }
  172. //////////////////////////工具函数///////////////////////////////
  173. const(
  174. pi = 3.14159265358979324
  175. a = 6378245.0
  176. ee = 0.00669342162296594323
  177. )
  178. func outOfChinal(gpsLng, gpsLat float64)bool{
  179. if gpsLng < 72.004 || gpsLng > 137.8347{
  180. return true;
  181. }
  182. if gpsLat < 0.8293 || gpsLat > 55.8271{
  183. return true;
  184. }
  185. return false;
  186. }
  187. func transformLat(x, y float64) float64 {
  188. ret := -100.0 + 2.0*x + 3.0*y + 0.2*y*y + 0.1*x*y + 0.2*math.Sqrt(math.Abs(x))
  189. ret += (20.0*math.Sin(6.0*x*pi) + 20.0*math.Sin(2.0*x*pi)) * 2.0 / 3.0
  190. ret += (20.0*math.Sin(y*pi) + 40.0*math.Sin(y/3.0*pi)) * 2.0 / 3.0
  191. ret += (160.0*math.Sin(y/12.0*pi) + 320*math.Sin(y*pi/30.0)) * 2.0 / 3.0
  192. return ret
  193. }
  194. func transformLon(x, y float64) float64 {
  195. ret := 300.0 + x + 2.0*y + 0.1*x*x + 0.1*x*y + 0.1*math.Sqrt(math.Abs(x))
  196. ret += (20.0*math.Sin(6.0*x*pi) + 20.0*math.Sin(2.0*x*pi)) * 2.0 / 3.0
  197. ret += (20.0*math.Sin(x*pi) + 40.0*math.Sin(x/3.0*pi)) * 2.0 / 3.0
  198. ret += (150.0*math.Sin(x/12.0*pi) + 300.0*math.Sin(x/30.0*pi)) * 2.0 / 3.0
  199. return ret
  200. }