package amap import ( "encoding/json" "fmt" "git.qianqiusoft.com/qianqiusoft/light-apiengine/utils" "errors" "math" ) const( __AMAP_API_ENDPOINT = "https://restapi.amap.com" __KEY = "427befed1b2db94d6753b679d7330772" ) type AMapClient struct{ Key string } /** * @brief: 逆地理编码 * @param1 lngLats: 经纬度列表,{lng1,lat1,lng2,lat2} * @return1: 逆转换结果 * @return2: 错误信息 */ func (a *AMapClient)Regeo(lngLats []string)(*RegeoResult, error){ if lngLats == nil || len(lngLats) == 0{ return nil, errors.New("参数lnglats为空") } if len(lngLats) % 2 != 0{ return nil, errors.New("参数lnglats长度必须为2的倍数") } path := "/geocode/regeo" location := "" location = fmt.Sprintf("%s,%s", lngLats[0], lngLats[1]) for i := 2; i < len(lngLats); i += 2 { location += "|" + fmt.Sprintf("%s,%s", lngLats[i], lngLats[i+1]) } params := make(map[string]string) params["location"] = location params["batch"] = "true" fullUrl := a.getFullUrl(path, params) bytess, err := utils.NewHttpUtil().Get(fullUrl, nil, nil) if err != nil{ return nil, err } regeoResult := &RegeoResult{} err = json.Unmarshal(bytess, regeoResult) if err != nil{ return nil, err } return regeoResult, nil } /** * @brief: 坐标转换(通过请求高德接口) * @param1 lngLats: 经纬度列表 * @param2 coordType: 坐标类型 gps;mapbar;baidu;autonavi * @return1: 坐标转回结果 * @return2: 错误信息 */ func (a *AMapClient)ConvCoord(lngLats []string, coordType string)(*ConvCoordResult, error){ locations := a.getLocations(lngLats) params := make(map[string]string) params["locations"] = locations params["coordsys"] = coordType path := "/assistant/coordinate/convert" fullUrl := a.getFullUrl(path, params) bytess, err := utils.NewHttpUtil().Get(fullUrl, nil, nil) if err != nil{ return nil, err } result := &ConvCoordResult{} err = json.Unmarshal(bytess, result) if err != nil{ return nil, err } return result, nil } /** * @brief: 把gps转成高德地图坐标 * @param1 gpsLng: gps 经度 * @param2 gpsLat: gps 纬度 * @return1: 高德地图经度 * @return2: 高德地图纬度 */ func (aa *AMapClient)ConvGpsToAMap(gpsLng, gpsLat float64)(float64, float64){ if outOfChinal(gpsLng, gpsLat){ return gpsLng, gpsLat } dLat := transformLat(gpsLng - 105.0, gpsLat - 35.0) dLon := transformLon(gpsLng - 105.0, gpsLat - 35.0) radLat := gpsLat / 180.0 * pi magic := math.Sin(radLat) magic = 1 - ee * magic * magic sqrtMagic := math.Sqrt(magic) dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi) dLon = (dLon * 180.0) / (a / sqrtMagic * math.Cos(radLat) * pi) return gpsLng + dLon, gpsLat + dLat } /** * @brief: 获取天气 * @param1 city: 区编码 * @param2 forecast: 是否预报天汽水 * @return1: 天气结果 * @return2: 错误信息 */ func (a *AMapClient)FetchWeather(city string, live bool)(*WeatherResult, error){ params := make(map[string]string) params["city"] = city if !live{ params["extensions"] = "all" } path := "/weather/weatherInfo" fullUrl := a.getFullUrl(path, params) bytess, err := utils.NewHttpUtil().Get(fullUrl, nil, nil) if err != nil{ return nil, err } result := &WeatherResult{} err = json.Unmarshal(bytess, result) if err != nil{ return nil, err } return result, nil } /** * @brief: 根据ip获取地址信息 * @param1 ip: ip,空标识使用请求ip获取地址 */ func (a *AMapClient)FectionLocationByIp(ip string)(*IpResult, error){ if ip == ""{ return nil, errors.New("ip不能为空") } params := make(map[string]string) params["ip"] = ip path := "/ip" fullUrl := a.getFullUrl(path, params) bytess, err := utils.NewHttpUtil().Get(fullUrl, nil, nil) if err != nil{ return nil, err } result := &IpResult{} err = json.Unmarshal(bytess, result) if err != nil{ return nil, err } return result, nil } /** * @brief: 获取完全url * @param1 path: 请求path * @param2 params: 参数 */ func (a *AMapClient)getFullUrl(path string, params map[string]string)string{ version := "v3" paramsStr := "" params["key"] = a.Key for k, v := range params{ paramsStr += fmt.Sprintf("%s=%s&", k, v) } return __AMAP_API_ENDPOINT + "/" + version + path + "?" + paramsStr } /** * @brief: 多个坐标转换程参数形式 * @param1 lngLats: 坐标列表 * @return1: 坐标结果 lng1,lat1|lng2,lat2 */ func (a *AMapClient)getLocations(lngLats []string)string{ location := "" location = fmt.Sprintf("%s,%s", lngLats[0], lngLats[1]) for i := 2; i < len(lngLats); i += 2 { location += "|" + fmt.Sprintf("%s,%s", lngLats[i], lngLats[i+1]) } return location } //////////////////////////工具函数/////////////////////////////// const( pi = 3.14159265358979324 a = 6378245.0 ee = 0.00669342162296594323 ) func outOfChinal(gpsLng, gpsLat float64)bool{ if gpsLng < 72.004 || gpsLng > 137.8347{ return true; } if gpsLat < 0.8293 || gpsLat > 55.8271{ return true; } return false; } func transformLat(x, y float64) float64 { ret := -100.0 + 2.0*x + 3.0*y + 0.2*y*y + 0.1*x*y + 0.2*math.Sqrt(math.Abs(x)) ret += (20.0*math.Sin(6.0*x*pi) + 20.0*math.Sin(2.0*x*pi)) * 2.0 / 3.0 ret += (20.0*math.Sin(y*pi) + 40.0*math.Sin(y/3.0*pi)) * 2.0 / 3.0 ret += (160.0*math.Sin(y/12.0*pi) + 320*math.Sin(y*pi/30.0)) * 2.0 / 3.0 return ret } func transformLon(x, y float64) float64 { ret := 300.0 + x + 2.0*y + 0.1*x*x + 0.1*x*y + 0.1*math.Sqrt(math.Abs(x)) ret += (20.0*math.Sin(6.0*x*pi) + 20.0*math.Sin(2.0*x*pi)) * 2.0 / 3.0 ret += (20.0*math.Sin(x*pi) + 40.0*math.Sin(x/3.0*pi)) * 2.0 / 3.0 ret += (150.0*math.Sin(x/12.0*pi) + 300.0*math.Sin(x/30.0*pi)) * 2.0 / 3.0 return ret }