package gps_tool import ( "bytes" "encoding/json" "fmt" "io" "log" "net/http" "net/url" "strconv" "time" "github.com/pkg/errors" ) type AnNaQiGpsClient struct { AppCode string Host string } func NewAnNaQiGpsClient(appCode string) *AnNaQiGpsClient { return &AnNaQiGpsClient{ AppCode: appCode, Host: "https://jmgeocode.market.alicloudapi.com", } } func (n *AnNaQiGpsClient) GetGpsInfo(longitude, latitude float64) (res *AddressComponent, err error) { lo := strconv.FormatFloat(longitude, 'f', 6, 64) la := strconv.FormatFloat(latitude, 'f', 6, 64) location := lo + "," + la // 拼接URL var fullURL string fullURL, err = url.JoinPath(n.Host, "geocode/regeo_query") if err != nil { return nil, errors.Wrapf(err, "获取gps:%s信息失败,拼接路径错误", location) } param := "location=" + location // 创建请求 var req *http.Request req, err = http.NewRequest(http.MethodPost, fullURL, bytes.NewBuffer([]byte(param))) if err != nil { return nil, errors.Wrapf(err, "获取gps:%s信息失败,创建请求失败", location) } // 设置请求头 req.Header.Add("Authorization", "APPCODE "+n.AppCode) req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8") // 发送请求 // 创建HTTP客户端 client := &http.Client{} client.Timeout = 5 * time.Second var resp *http.Response resp, err = client.Do(req) if err != nil { return nil, errors.Wrapf(err, "获取gps:%s信息失败,发送请求失败", location) } defer func(Body io.ReadCloser) { err = Body.Close() if err != nil { log.Printf("获取gps:%s信息,关闭响应体失败: %+v\n", location, err) } }(resp.Body) // 读取响应体 var body []byte body, err = io.ReadAll(resp.Body) if err != nil { return nil, errors.Wrapf(err, "获取gps:%s信息失败,读取响应体失败", location) } // 解析JSON响应 var apiResult ApiResult err = json.Unmarshal(body, &apiResult) if err != nil { return nil, errors.Wrapf(err, "获取gps:%s信息失败,解析JSON响应失败,%s", location, string(body)) } // 检查API返回状态 if apiResult.Code != 200 { return nil, errors.New(fmt.Sprintf("获取gps:%s信息失败,%+v", location, apiResult)) } if len(apiResult.Data.Regeocodes) > 0 { return &apiResult.Data.Regeocodes[0].AddressComponent, nil } return nil, errors.New(fmt.Sprintf("获取gps:%s信息失败,%+v", location, apiResult)) } type ApiResult struct { Data Data `json:"data"` Msg string `json:"msg"` Success bool `json:"success"` Code int `json:"code"` TaskNo string `json:"taskNo"` } type Data struct { Regeocodes []Regeocode `json:"regeocodes"` } type Regeocode struct { FormattedAddress string `json:"formatted_address"` AddressComponent AddressComponent `json:"addressComponent"` } type AddressComponent struct { // BusinessAreas []interface{} `json:"businessAreas"` Country string `json:"country"` Province string `json:"province"` Citycode string `json:"citycode"` City string `json:"city"` Adcode string `json:"adcode"` // StreetNumber StreetNumber `json:"streetNumber"` // Towncode string `json:"towncode"` // District string `json:"district"` // Neighborhood Neighborhood `json:"neighborhood"` // Township string `json:"township"` // Building Building `json:"building"` } type BusinessArea struct { Name string `json:"name"` Location string `json:"location"` Id string `json:"id"` } type StreetNumber struct { Number string `json:"number"` Distance string `json:"distance"` Street string `json:"street"` Location string `json:"location"` Direction string `json:"direction"` } type Neighborhood struct { Name interface{} `json:"name"` Type interface{} `json:"type"` } type Building struct { Name interface{} `json:"name"` Type interface{} `json:"type"` }