增加地址解析

This commit is contained in:
yuguojian
2025-07-17 17:16:49 +08:00
parent aee7202752
commit d0d264d1e7
3 changed files with 189 additions and 73 deletions

View File

@@ -16,13 +16,13 @@ import (
type AnNaQiGpsClient struct {
AppCode string
Host string
host string
}
func NewAnNaQiGpsClient(appCode string) *AnNaQiGpsClient {
return &AnNaQiGpsClient{
AppCode: appCode,
Host: "https://jmgeocode.market.alicloudapi.com",
host: "https://jmgeocode.market.alicloudapi.com",
}
}
@@ -32,7 +32,7 @@ func (n *AnNaQiGpsClient) GetGpsInfo(longitude, latitude float64) (res *AddressC
location := lo + "," + la
// 拼接URL
var fullURL string
fullURL, err = url.JoinPath(n.Host, "geocode/regeo_query")
fullURL, err = url.JoinPath(n.host, "geocode/regeo_query")
if err != nil {
return nil, errors.Wrapf(err, "获取gps:%s信息失败拼接路径错误", location)
}
@@ -56,6 +56,9 @@ func (n *AnNaQiGpsClient) GetGpsInfo(longitude, latitude float64) (res *AddressC
if err != nil {
return nil, errors.Wrapf(err, "获取gps:%s信息失败发送请求失败", location)
}
if resp.StatusCode != http.StatusOK {
return nil, errors.New(fmt.Sprintf("获取gps:%s信息失败%+v", location, resp.Status))
}
defer func(Body io.ReadCloser) {
err = Body.Close()
if err != nil {
@@ -76,67 +79,67 @@ func (n *AnNaQiGpsClient) GetGpsInfo(longitude, latitude float64) (res *AddressC
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 apiResult.Code == 200 {
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"`
}
func (n *AnNaQiGpsClient) GetLocation(city, region, address string) (res *[]Geocode, err error) {
values := url.Values{}
values.Set("city", city)
values.Set("address", region+address)
type Data struct {
Regeocodes []Regeocode `json:"regeocodes"`
}
// 创建请求
var req *http.Request
req, err = http.NewRequest(http.MethodPost, n.host+"/geocode/geo/query", bytes.NewBuffer([]byte(values.Encode())))
if err != nil {
return nil, errors.Wrapf(err, "获取经纬度失败,创建请求失败")
}
// 设置请求头
req.Header.Add("Authorization", "APPCODE "+n.AppCode)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
type Regeocode struct {
FormattedAddress string `json:"formatted_address"`
AddressComponent AddressComponent `json:"addressComponent"`
}
// 发送请求
// 创建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, "获取经纬度失败,发送请求失败")
}
if resp.StatusCode != http.StatusOK {
return nil, errors.New(fmt.Sprintf("获取经纬度失败,%+v", resp.Status))
}
defer func(Body io.ReadCloser) {
err = Body.Close()
if err != nil {
log.Printf("关闭获取经纬度响应体失败: %+v\n", err)
}
}(resp.Body)
// 读取响应体
var body []byte
body, err = io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrapf(err, "获取经纬度失败,读取响应体失败")
}
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"`
}
// 解析JSON响应
var locationInfo LocationInfo
err = json.Unmarshal(body, &locationInfo)
if err != nil {
return nil, errors.Wrapf(err, "获取经纬度失败解析JSON响应失败%s", string(body))
}
// 检查API返回状态
if locationInfo.Code == 200 {
if len(locationInfo.Data.Geocodes) > 0 {
return &locationInfo.Data.Geocodes, nil
}
}
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"`
return nil, errors.New(fmt.Sprintf("获取经纬度失败,%+v", locationInfo.Msg))
}

View File

@@ -2,6 +2,7 @@ package gps_tool
import (
"log"
"reflect"
"testing"
)
@@ -25,7 +26,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test1",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 113.419152,
@@ -37,7 +37,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test2",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 110.165223,
@@ -48,7 +47,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test2",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 115.928973,
@@ -60,7 +58,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test3",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 107.397284,
@@ -72,7 +69,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test4",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 115.929015,
@@ -84,7 +80,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test5",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 115.929100,
@@ -96,7 +91,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test6",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 126.587051,
@@ -108,7 +102,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test7",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 126.595051,
@@ -120,7 +113,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test8",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 125.342693,
@@ -132,7 +124,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test9",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 112.485550,
@@ -144,7 +135,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test10",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 115.928821,
@@ -156,7 +146,6 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
name: "test11",
fields: fields{
AppCode: "",
Host: "https://jmgeocode.market.alicloudapi.com",
},
args: args{
longitude: 115.928821,
@@ -166,12 +155,55 @@ func TestAnNaQiGpsClient_GetGpsInfo(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
n := &AnNaQiGpsClient{
AppCode: tt.fields.AppCode,
Host: tt.fields.Host,
}
n := NewAnNaQiGpsClient(tt.fields.AppCode)
gotRes, err := n.GetGpsInfo(tt.args.longitude, tt.args.latitude)
log.Println(gotRes, err)
})
}
}
func TestAnNaQiGpsClient_GetLocation(t *testing.T) {
type fields struct {
AppCode string
Host string
}
type args struct {
city string
region string
address string
}
tests := []struct {
name string
fields fields
args args
wantRes *[]Geocode
wantErr bool
}{
{
name: "奥园城市天地",
fields: fields{
AppCode: "",
},
args: args{
city: "广州",
region: "番禺",
address: "奥园城市天地9区2栋",
},
wantRes: nil,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
n := NewAnNaQiGpsClient(tt.fields.AppCode)
gotRes, err := n.GetLocation(tt.args.city, tt.args.region, tt.args.address)
if (err != nil) != tt.wantErr {
t.Errorf("GetLocation() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotRes, tt.wantRes) {
t.Errorf("GetLocation() gotRes = %v, want %v", gotRes, tt.wantRes)
}
})
}
}

81
gps_tool/response.go Normal file
View File

@@ -0,0 +1,81 @@
package gps_tool
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"`
}
type LocationInfo struct {
Data LocationDatum `json:"data"`
Msg string `json:"msg"`
Success bool `json:"success"`
Code int `json:"code"`
TaskNo string `json:"taskNo"`
}
type LocationDatum struct {
Count int `json:"count"`
Geocodes []Geocode `json:"geocodes"`
}
type Geocode struct {
Country string `json:"country"`
FormattedAddress string `json:"formatted_address"`
City string `json:"city"`
Adcode string `json:"adcode"`
Level string `json:"level"`
Province string `json:"province"`
Citycode string `json:"citycode"`
District string `json:"district"`
Location string `json:"location"`
}