153 lines
4.0 KiB
Go
153 lines
4.0 KiB
Go
package utils
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"io/ioutil"
|
||
"net/http"
|
||
"net/url"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
const baiduIPLocationAPI = "https://api.map.baidu.com/location/ip"
|
||
|
||
// 建议把 ak 放配置;这里先保留你给的 key,后续可改为从配置读取。
|
||
const baiduMapAK = "T8DGBYxbZ1iAeXx1J57McKigyHJHulPQ"
|
||
|
||
type baiduIPResp struct {
|
||
Status int `json:"status"`
|
||
Address string `json:"address"`
|
||
Content struct {
|
||
Address string `json:"address"`
|
||
} `json:"content"`
|
||
Message string `json:"message"`
|
||
}
|
||
type ReverseGeocodingReq struct {
|
||
Ak string `json:"ak"`
|
||
Coordtype string `json:"coordtype"`
|
||
RetCoordtype string `json:"retCoordtype"`
|
||
Location string `json:"location"`
|
||
Output string `json:"output"`
|
||
Language string `json:"language"`
|
||
}
|
||
|
||
type ReverseGeocodingRes struct {
|
||
Status int `json:"status"`
|
||
Result struct {
|
||
Location struct {
|
||
Lng float64 `json:"lng"`
|
||
Lat float64 `json:"lat"`
|
||
} `json:"location"`
|
||
FormattedAddress string `json:"formatted_address"`
|
||
Edz struct {
|
||
Name string `json:"name"`
|
||
} `json:"edz"`
|
||
Business string `json:"business"`
|
||
AddressComponent struct {
|
||
Country string `json:"country"`
|
||
CountryCodeIso string `json:"country_code_iso"`
|
||
CountryCodeIso2 string `json:"country_code_iso2"`
|
||
CountryCode int `json:"country_code"`
|
||
Province string `json:"province"`
|
||
City string `json:"city"`
|
||
CityLevel int `json:"city_level"`
|
||
District string `json:"district"`
|
||
Town string `json:"town"`
|
||
TownCode string `json:"town_code"`
|
||
Distance string `json:"distance"`
|
||
Direction string `json:"direction"`
|
||
Adcode string `json:"adcode"`
|
||
Street string `json:"street"`
|
||
StreetNumber string `json:"street_number"`
|
||
} `json:"addressComponent"`
|
||
} `json:"result"`
|
||
}
|
||
|
||
// ReverseGeo 经纬度逆编码
|
||
func ReverseGeo(longitude, latitude string, language string) (address string, err error) {
|
||
var reverseGeocodingReq ReverseGeocodingReq
|
||
|
||
reverseGeocodingReq.Ak = "3bAjKGA0pv7qvszGe98RsVZ04Ob5r4ZZ"
|
||
reverseGeocodingReq.Coordtype = "gcj02ll"
|
||
reverseGeocodingReq.Output = "json"
|
||
reverseGeocodingReq.RetCoordtype = "gcj02ll"
|
||
reverseGeocodingReq.Location = strings.Join([]string{latitude, longitude}, ",")
|
||
reverseGeocodingReq.Language = language
|
||
|
||
url := "https://api.map.baidu.com/reverse_geocoding/v3/?ak=" + reverseGeocodingReq.Ak + "&output=" + reverseGeocodingReq.Output + "&coordtype=" + reverseGeocodingReq.Coordtype + "&location=" + reverseGeocodingReq.Location + "&ret_coordtype=" + reverseGeocodingReq.RetCoordtype + "&language=" + reverseGeocodingReq.Language
|
||
resp, err := http.Get(url)
|
||
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
defer resp.Body.Close()
|
||
body, err := ioutil.ReadAll(resp.Body)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
var results ReverseGeocodingRes
|
||
err = json.Unmarshal(body, &results)
|
||
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
if results.Status != 0 {
|
||
address = "未知地址"
|
||
return address, err
|
||
}
|
||
|
||
address = results.Result.FormattedAddress
|
||
|
||
return address, nil
|
||
}
|
||
func GetAddressByIP(ip string) (string, error) {
|
||
ip = strings.TrimSpace(ip)
|
||
if ip == "" {
|
||
return "", fmt.Errorf("ip is empty")
|
||
}
|
||
|
||
q := url.Values{}
|
||
q.Set("ip", ip)
|
||
q.Set("coor", "bd09ll")
|
||
q.Set("ak", baiduMapAK)
|
||
|
||
reqURL := baiduIPLocationAPI + "?" + q.Encode()
|
||
client := &http.Client{Timeout: 5 * time.Second}
|
||
resp, err := client.Get(reqURL)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
if resp.StatusCode != http.StatusOK {
|
||
return "", fmt.Errorf("baidu api status: %d", resp.StatusCode)
|
||
}
|
||
|
||
body, err := io.ReadAll(resp.Body)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
var r baiduIPResp
|
||
if err := json.Unmarshal(body, &r); err != nil {
|
||
return "", err
|
||
}
|
||
if r.Status != 0 {
|
||
if r.Message == "" {
|
||
r.Message = "baidu api error"
|
||
}
|
||
return "", fmt.Errorf("%s", r.Message)
|
||
}
|
||
|
||
if strings.TrimSpace(r.Content.Address) != "" {
|
||
return r.Content.Address, nil
|
||
}
|
||
if strings.TrimSpace(r.Address) != "" {
|
||
return r.Address, nil
|
||
}
|
||
return "", nil
|
||
}
|