将所有地图改为腾讯地图

This commit is contained in:
邹宗楠
2024-07-31 11:08:32 +08:00
parent 7d7abf2678
commit 8533b94f24
17 changed files with 1279 additions and 681 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
package autonavi
import (
/*import (
"fmt"
"net/http"
"strings"
@@ -120,3 +120,4 @@ func (a *API) GetCoordinateFromAddressByPageAll(address string, cityCode int) (g
}
return getCoordinateFromAddressByPageAllResult, err
}
*/

View File

@@ -1,5 +1,6 @@
package autonavi
/*
import (
"testing"
@@ -22,3 +23,4 @@ func TestGetCoordinateFromAddressByPageAll(t *testing.T) {
}
t.Log(utils.Format4Output(result, false))
}
*/

View File

@@ -1,14 +1,6 @@
package autonavi
import (
"testing"
"git.rosy.net.cn/baseapi"
"git.rosy.net.cn/baseapi/utils"
"go.uber.org/zap"
)
/*
var (
autonaviAPI *API
sugarLogger *zap.SugaredLogger
@@ -158,3 +150,4 @@ func TestAA(t *testing.T) {
}
t.Log(utils.Format4Output(result, false))
}
*/

View File

@@ -1,13 +1,7 @@
package autonavi
import (
"fmt"
"git.rosy.net.cn/baseapi/utils"
"strings"
)
// GetCyclingPlan 获取骑手的骑行计划
func (a *API) GetCyclingPlan(origin, destination string) ([]string, int64, int64, error) {
/*func (a *API) GetCyclingPlan(origin, destination string) ([]string, int64, int64, error) {
param := map[string]interface{}{
"key": a.key,
"origin": origin,
@@ -45,3 +39,4 @@ func (a *API) GetCyclingPlan(origin, destination string) ([]string, int64, int64
return polyLineList, distance, duration, nil
}
*/

View File

@@ -1,10 +1,6 @@
package autonavi
import (
"fmt"
"testing"
)
/*
func TestGetCyclingPlan(t *testing.T) {
key := "cb4ea3516f88c0fd8fed73f92aeddffa"
a := New(key)
@@ -19,3 +15,4 @@ func TestLng(t *testing.T) {
origin := fmt.Sprintf("%f,%f", 113.854912, 22.601450)
fmt.Println(origin)
}
*/

View File

@@ -1,20 +1,5 @@
package baidunavi
import (
"crypto/md5"
"encoding/json"
"errors"
"fmt"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
"io/ioutil"
"net/http"
"net/url"
"sort"
"strings"
"time"
)
const (
signKey = "sn"
resultKey = "result"
@@ -33,6 +18,11 @@ const (
StatusCodeExceedConcurrentQuota = 402 // 当前并发量已经超过约定并发配额,并且服务总并发量也已经超过设定的总并发配额,限制访问
)
//bd09ll表示百度经纬度坐标
//bd09mc表示百度墨卡托坐标
//gcj02表示经过国测局加密的坐标
//wgs84表示gps获取的坐标
const (
CoordSysWGS84 = 1 // GPS设备获取的角度坐标WGS84坐标
CoordSysGCJ02 = 3 // google地图、soso地图、aliyun地图、mapabc地图和amap地图所用坐标国测局GCJ02坐标
@@ -42,6 +32,7 @@ const (
CoordSysBaidu2Gaode = "5" // 百度坐标转高德坐标
)
/*
const (
MaxCoordsConvBatchSize = 100
)
@@ -163,39 +154,6 @@ func genGetURL(baseURL, apiStr string, params map[string]interface{}) string {
return baseURL + queryString
}
/*func (a *API) AccessAPI(apiStr string, params map[string]interface{}) (retVal interface{}, err error) {
apiStr += "/"
params2 := utils.MergeMaps(utils.Params2Map("ak", a.ak, "output", "json"), params)
params2[signKey] = a.signParams(apiStr, params2)
err = platformapi.AccessPlatformAPIWithRetry(a.client,
func() *http.Request {
//request, _ := http.NewRequest(http.MethodGet, genGetURL(prodURL, apiStr, params2), nil)
request, _ := http.NewRequest(http.MethodGet, genGetURL(prodURL2, apiStr, params2), nil)
return request
},
a.config,
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
status := int(utils.MustInterface2Int64(jsonResult1["status"]))
if status == StatusCodeSuccess {
retVal = jsonResult1[resultKey]
return platformapi.ErrLevelSuccess, nil
}
newErr := utils.NewErrorIntCode(utils.Interface2String(jsonResult1["message"]), status)
if _, ok := exceedLimitCodes[status]; ok {
return platformapi.ErrLevelRecoverableErr, newErr
} else if _, ok := canRetryCodes[status]; ok {
return platformapi.ErrLevelRecoverableErr, newErr
} else {
return platformapi.ErrLevelCodeIsNotOK, newErr
}
})
return retVal, err
}*/
func (a *API) AccessAPI2(apiStr string, param url.Values) (retVal map[string]interface{}, err error) {
for _, v := range BaiduAKList {
@@ -229,29 +187,6 @@ func (a *API) AccessAPI2(apiStr string, param url.Values) (retVal map[string]int
return nil, errors.New("所有百度应用额度均用完")
}
// BatchCoordinateConvert 坐标转换
//func (a *API) BatchCoordinateConvert(coords []*Coordinate, fromCoordSys, toCoordSys int) (outCoords []*Coordinate, err error) {
// if fromCoordSys == toCoordSys {
// return coords, nil
// }
// var coordsStrList []string
// for _, v := range coords {
// coordsStrList = append(coordsStrList, fmt.Sprintf("%.6f,%.6f", v.Lng, v.Lat))
// }
//
// params := url.Values{
// "coords": []string{strings.Join(coordsStrList, ";")},
// "from": []string{utils.Int2Str(fromCoordSys)},
// "to": []string{utils.Int2Str(toCoordSys)},
// }
//
// result, err := a.AccessAPI2("geoconv/v1/", params)
// if err == nil {
// err = utils.Map2StructByJson(result[resultKey], &outCoords, false)
// }
// return outCoords, err
//}
// BatchCoordinateConvert 坐标转换
func (a *API) BatchCoordinateConvert(coords []*Coordinate, changeType string) (outCoords []*Coordinate, err error) {
var coordsStrList []string
@@ -273,20 +208,6 @@ func (a *API) BatchCoordinateConvert(coords []*Coordinate, changeType string) (o
return outCoords, err
}
// BatchCoordinateConvertBai2Gao 百度转高德
func (a *API) BatchCoordinateConvertBai2Gao(coords []string, changeType string) (outCoords []*Coordinate, err error) {
params := url.Values{
"coords": []string{strings.Join(coords, ";")},
"model": []string{changeType}, // 1:高德转百度 5:百度转高德
}
result, err := a.AccessAPI2("geoconv/v2/", params)
if err == nil {
err = utils.Map2StructByJson(result[resultKey], &outCoords, false)
}
return outCoords, err
}
// DirectionLiteRide 获取骑行距离
func (a *API) DirectionLiteRide(coords []*Coordinate) (retVal interface{}, err error) {
var (
@@ -309,3 +230,4 @@ func (a *API) DirectionLiteRide(coords []*Coordinate) (retVal interface{}, err e
return nil, nil
}
*/

View File

@@ -1,40 +1,5 @@
package baidunavi
// RiderPath 骑行路线
//type RiderPath struct {
// Status int `json:"status"` // 状态码 0-成功,1-服务器内部错误,2-参数无效,7-无结果返回
// Message string `json:"message"` // 状态码对应的信息
// Result struct {
// RiderResult
// Routes []struct {
// Distance int `json:"distance"` // 距离米
// Duration int `json:"duration"` // 时间秒
// Steps []struct {
// Distance int `json:"distance"`
// Duration int `json:"duration"`
// Direction int `json:"direction"`
// TurnType string `json:"turn_type"`
// Name string `json:"name"`
// Instruction string `json:"instruction"`
// RestrictionsInfo string `json:"restrictions_info"`
// Path string `json:"path"`
// StartLocation RiderCoordinate `json:"start_location"`
// EndLocation RiderCoordinate `json:"end_location"`
// } `json:"steps"`
// } `json:"routes"`
// } `json:"result"`
//}
//
//type RiderResult struct {
// Origin RiderCoordinate `json:"origin"` // 起点经纬度
// Destination RiderCoordinate `json:"destination"` // 终点经纬度
//}
//
//type RiderCoordinate struct {
// Lng float64 `json:"lng"` // 经度
// Lat float64 `json:"lat"` // 纬度
//}
type RiderPath struct {
Destination struct {
Lat float64 `json:"lat"`

View File

@@ -1354,13 +1354,6 @@ var cc []string = []string{
"104.05971492107,30.624174347628",
}
func TestBatchCoordinateConvertBai2Gao(t *testing.T) {
fmt.Println(len(cc))
result, err := api.BatchCoordinateConvertBai2Gao(cc[0:100], "5")
fmt.Println(err)
fmt.Println(result)
}
// 1290 104.00734814129,30.660267081943
func TestName(t *testing.T) {
var bd_lng = 104.00734814129

View File

@@ -26,7 +26,9 @@ func TestShopCategoryGet(t *testing.T) {
}
func TestShopGet222(t *testing.T) {
api.ShopGet("669168", 0)
data, err := api.ShopGet("", 32267258844)
fmt.Println(data)
fmt.Println(err)
}
func TestShopCategoryUpdate(t *testing.T) {

View File

@@ -29,11 +29,11 @@ func init() {
// 天天果园
//api = New("c45e6510-00ba-4be2-977e-bcb9c9792cc7", "5d5577a2506f41b8b4ec520ba83490f5", "0b01b9eeb15b41dab1c3d05d95c17a26")
// 京东果园 320406
//api = New("c454ef86-2213-4860-9a31-f2ef7e883386", "1dba76d40cac446ca500c0391a0b6c9d", "a88d031a1e7b462cb1579f12e97fe7f4")
api = New("1e87595b-e850-4ba4-9ee0-53bcfe383a4f", "1dba76d40cac446ca500c0391a0b6c9d", "a88d031a1e7b462cb1579f12e97fe7f4")
// 果切 379599
//api = New("ad4061a1-6a5c-43f9-bf51-b1232fd9499d", "f2ed33075faf4773a47e065acd79532b", "aed14cbbecac4456843570e90c5f46ec")
// 381564
api = New("8d9e4443-3536-41ae-b6c7-677f90f1978b", "d2d1e2e3213d4320bc2712a684307831", "1750f5b9848d4a6492c1c20b487074da")
//api = New("8d9e4443-3536-41ae-b6c7-677f90f1978b", "d2d1e2e3213d4320bc2712a684307831", "1750f5b9848d4a6492c1c20b487074da")
// 384633
///api = New("02a3f772-89f3-46f1-bbd5-74be346cba54", "e496a0f9b88a407297fea283b8dc9e29", "9bb82ffbec144c4b8fc8d627e5ca6a35")

View File

@@ -133,9 +133,9 @@ func TestOrderAddTips(t *testing.T) {
func TestOrderQuery2(t *testing.T) {
orderList, _, err := api.OrderQuery2(&OrderQueryParam{
OrderPurchaseTimeBegin: "2024-04-09 00:00:00",
OrderPurchaseTimeEnd: "2024-04-09 23:59:59",
DeliveryStationNo: "12781207",
OrderPurchaseTimeBegin: "2024-07-20 00:00:00",
OrderPurchaseTimeEnd: "2024-07-29 23:59:59",
DeliveryStationNo: "12297793",
PageNo: 1,
PageSize: 99999,
})

View File

@@ -0,0 +1,146 @@
package tencent_map
import (
"crypto/md5"
"encoding/json"
"fmt"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
"net/http"
"sort"
"strings"
)
const (
signKey = "sig"
BaseUrl = `https://apis.map.qq.com` // 基础访问链接
TencentCoordinateApi = "/ws/coord/v1/translate" // 坐标转换API
TencentCyclingPlanning = "/ws/direction/v1/ebicycling" // 电动骑行车规划API
TencentWalkingPlanning = "/ws/direction/v1/walking" // 步行规划API
TencentGeoAddress2Code = "/ws/geocoder/v1" // 地址解析,地址逆转坐标 // https://lbs.qq.com/service/webService/webServiceGuide/address/Geocoder
TencentCoder2Address = "/ws/geocoder/v1" // 地址逆解析,坐标转地址 // https://lbs.qq.com/service/webService/webServiceGuide/address/Gcoder
TencentGetDistrictList = "/ws/district/v1/list" // 本接口用于获取全部省市区三级行政区划列表。
TencentGetChildrenList = "/ws/district/v1/getchildren" // 根据父级code获取行政区划
// 坐标转换类型(输入类型)
CoordinateChangeTypeGPS = 1 // GPS坐标
CoordinateChangeTypeSoGou = 2 // 搜狗坐标
CoordinateChangeTypeBaidu = 3 // 百度坐标
CoordinateChangeTypeMapbar = 4 // mapbar
CoordinateChangeTypeGaoDe = 5 // [默认]腾讯、google、高德坐标
CoordinateChangeTypeSoGouMt = 6 // 搜狗墨脱
DistrictLevelCountry = 0 // 国家
DistrictLevelProvince = 1 // 省
DistrictLevelCity = 2 // 市
DistrictLevelDistrict = 3 // 县
DistrictLevelStreet = 4 // 街道
MaxConvertCount = 40
)
type API struct {
platformapi.APICookie
client *http.Client
config *platformapi.APIConfig
key string
sk string
}
func (a *API) SetKey(key string) {
a.key = key
}
func (a *API) GetKey() string {
return a.key
}
func (a *API) SetSK(sk string) {
a.sk = sk
}
func (a *API) GetSK() string {
return a.sk
}
func New(key, sk string, config ...*platformapi.APIConfig) *API {
curConfig := platformapi.DefAPIConfig
if len(config) > 0 {
curConfig = *config[0]
}
return &API{
key: key,
sk: sk,
client: &http.Client{Timeout: curConfig.ClientTimeout},
config: &curConfig,
}
}
func (a *API) signParams(params map[string]interface{}, url string) string {
if params["key"] == nil || params["key"].(string) == "" {
params["key"] = a.GetKey()
}
params2 := utils.Map2URLValues(params)
keys := make([]string, 0)
for k := range params2 {
if k != signKey {
keys = append(keys, k)
}
}
sort.Strings(keys)
finalStr := ""
for index, key := range keys {
valStr := strings.Join(params2[key], "")
if valStr != "" {
finalStr += key + "=" + valStr
if index+1 != len(keys) {
finalStr += "&"
}
}
}
sign := url + "?" + finalStr + a.GetSK()
return fmt.Sprintf("%x", md5.Sum([]byte(sign)))
}
func (a *API) AccessAPI(baseUrl, actionApi, method string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
if bizParams["key"] == nil || bizParams["key"].(string) == "" {
bizParams["key"] = a.GetKey()
}
// 序列化
data, err := json.Marshal(bizParams)
if err != nil {
return nil, err
}
// 发送请求
sendUrl := func() *http.Request {
var request *http.Request
if http.MethodPost == method {
request, _ = http.NewRequest(http.MethodPost, utils.GenerateGetURL(baseUrl, actionApi, nil), strings.NewReader(string(data)))
} else {
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(baseUrl, actionApi, bizParams), nil)
}
request.Header.Set("Content-Type", "application/json")
return request
}
// 数据解析
dataMarshal := func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
if jsonResult1 == nil {
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
}
if err != nil {
return "", err
}
if utils.MustInterface2Int64(jsonResult1["status"]) != 0 {
errLevel = platformapi.ErrLevelGeneralFail
err = utils.NewErrorCode(jsonResult1["message"].(string), utils.Int64ToStr(utils.MustInterface2Int64(jsonResult1["status"])))
}
retVal = jsonResult1
return errLevel, err
}
err = platformapi.AccessPlatformAPIWithRetry(a.client, sendUrl, a.config, dataMarshal)
return retVal, err
}

View File

@@ -0,0 +1,314 @@
package tencent_map
import (
"encoding/json"
"fmt"
"git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/globals"
"net/http"
)
// TencentCoordinateChange 腾讯坐标转换(其他坐标转换为腾讯坐标)
func (a *API) TencentCoordinateChange(param *TencentCoordinateChangeReq) ([]*LocationsCoordinateObj, error) {
requestParam := utils.Struct2Map(param, "", false)
requestParam["sig"] = a.signParams(requestParam, TencentCoordinateApi)
result, err := a.AccessAPI(BaseUrl, TencentCoordinateApi, http.MethodGet, requestParam)
if err != nil {
return nil, err
}
resultByte, err := json.Marshal(result)
if err != nil {
return nil, err
}
data := &TencentCoordinateChangeRes{}
if err = json.Unmarshal(resultByte, data); err != nil {
return nil, err
}
if data.Status != 0 {
return nil, fmt.Errorf("%s", data.Message)
}
locations := make([]*LocationsCoordinateObj, 0, 0)
for _, v := range data.Locations {
locations = append(locations, &LocationsCoordinateObj{
Lat: v.Lat.String(),
Lng: v.Lng.String(),
})
}
return locations, nil
}
// TencentCyclingPlanning 腾讯电动车骑行规划
func (a *API) TencentCyclingPlanning(param *TencentCyclingPlanningReq) (distance int64, duration int64, coordinatePoint []string, err error) {
requestParam := utils.Struct2Map(param, "", false)
requestParam["sig"] = a.signParams(requestParam, TencentCyclingPlanning)
result, err := a.AccessAPI(BaseUrl, TencentCyclingPlanning, http.MethodGet, requestParam)
if err != nil {
return 0, 0, nil, err
}
resultByte, err := json.Marshal(result)
if err != nil {
return 0, 0, nil, err
}
data := &TencentCyclingPlanningRes{}
if err = json.Unmarshal(resultByte, data); err != nil {
return 0, 0, nil, err
}
if data.Status != 0 {
return 0, 0, nil, err
}
for _, v := range data.Result["routes"] {
distance = v.Distance
duration = v.Duration
pointList := make([]string, 0, len(v.Polyline))
pointList = append(pointList, v.Polyline[0].String())
pointList = append(pointList, v.Polyline[1].String())
for i := 2; i < len(v.Polyline); i++ {
point1 := utils.Str2Float64(pointList[i-2])
point2, _ := v.Polyline[i].Float64()
pointList = append(pointList, fmt.Sprintf("%.6f", point1+point2/float64(1000000)))
}
for i := 0; i < len(pointList); i += 2 {
coordinatePoint = append(coordinatePoint, fmt.Sprintf("%s,%s", pointList[i+1], pointList[i]))
}
globals.SugarLogger.Debugf("调换后 : %s", utils.Format4Output(coordinatePoint, false))
return distance, duration, coordinatePoint, nil
}
return 0, 0, nil, fmt.Errorf("骑行计划获取异常")
}
// WalkingDistance 获取两点之间的步行距离
func (a *API) WalkingDistance(param *TencentCyclingPlanningReq) (distance int64, err error) {
requestParam := utils.Struct2Map(param, "", false)
requestParam["sig"] = a.signParams(requestParam, TencentWalkingPlanning)
result, err := a.AccessAPI(BaseUrl, TencentWalkingPlanning, http.MethodGet, requestParam)
if err != nil {
return 0, err
}
resultByte, err := json.Marshal(result)
if err != nil {
return 0, err
}
data := &TencentCyclingPlanningRes{}
if err = json.Unmarshal(resultByte, data); err != nil {
return 0, err
}
if data.Status != 0 {
return 0, err
}
for _, v := range data.Result["routes"] {
return v.Distance, nil
//duration = v.Duration
//
//pointList := make([]string, 0, len(v.Polyline))
//pointList = append(pointList, v.Polyline[0].String())
//pointList = append(pointList, v.Polyline[1].String())
//for i := 2; i < len(v.Polyline); i++ {
// point1 := utils.Str2Float64(pointList[i-2])
// point2, _ := v.Polyline[i].Float64()
// pointList = append(pointList, fmt.Sprintf("%.6f", point1+point2/float64(1000000)))
//}
//
//for i := 0; i < len(pointList); i += 2 {
// coordinatePoint = append(coordinatePoint, fmt.Sprintf("%s,%s", pointList[i+1], pointList[i]))
//}
//globals.SugarLogger.Debugf("调换后 : %s", utils.Format4Output(coordinatePoint, false))
//
//return distance, duration, coordinatePoint, nil
}
return 0, fmt.Errorf("步行计划获取异常")
}
// GetCoordinateFromAddress 根据地址或者城市code获取坐标已经城市编码
func (a *API) GetCoordinateFromAddress(address string, cityInfo string) (lng, lat float64, districtCode int, districtName string, err error) {
if address == "" {
return 0, 0, 0, "", fmt.Errorf("地址信息不能为空")
}
requestParam := map[string]interface{}{
"address": address,
"key": a.key,
}
requestParam["sig"] = a.signParams(requestParam, TencentGeoAddress2Code)
result, err := a.AccessAPI(BaseUrl, TencentGeoAddress2Code, http.MethodGet, requestParam)
if err != nil {
return 0, 0, 0, "", err
}
data := &AddressGeoCoderChangeRes{}
if err := utils.Map2StructByJson(result, data, false); err != nil {
return 0, 0, 0, "", err
}
lng, _ = data.Result.Location.Lng.Float64()
lat, _ = data.Result.Location.Lat.Float64()
return lng, lat, utils.Str2Int(data.Result.AdInfo.AdCode), data.Result.AddressComponents.District, nil
}
// GeoCodeRegeoSingle 根据坐标获取地址信息
func (a *API) GeoCodeRegeoSingle(lng, lat float64, radius int, isExt bool, poiTypes []string, roadLevel, homeOrCorp int) (coordInfo *Codes2AddressRes, err error) {
param := map[string]interface{}{
"location": utils.Float64ToStr(lat) + "," + utils.Float64ToStr(lng),
"key": a.key,
}
param["sig"] = a.signParams(param, TencentCoder2Address)
result, err := a.AccessAPI(BaseUrl, TencentCoder2Address, http.MethodGet, param)
resultByte, err := json.Marshal(result)
if err != nil {
return nil, err
}
if err = json.Unmarshal(resultByte, &coordInfo); err != nil {
return nil, err
}
return coordInfo, err
}
// GetDistricts 行政区划查询 subdistrict子级行政区 keywords 关键字
func (a *API) GetDistricts(subDistrict int, keywords string, level int) (districtList []*District, err error) {
// 之前是使用的高德地图更新的,高德更新的地图在直辖市的时候,比腾讯地图多了一行数据
// 行政区划长时间不会改变,所以不在更新本地存储的行政区划直接跳过
// 110000 北京市 0 1 010 100001 131 1 0 1 0
// 110100 北京市 110000 2 010 1 0 1 730 0 0
if subDistrict == 3 && keywords == "" {
return nil, fmt.Errorf("高德转腾讯,暂时不做修改")
/*param := map[string]interface{}{
"struct_type": 1,
"key": a.key,
}
param["sig"] = a.signParams(param, TencentGetDistrictList)
result, err := a.AccessAPI(BaseUrl, TencentGetDistrictList, http.MethodGet, param)
resultByte, err := json.Marshal(result)
if err != nil {
return nil, err
}
administrativeDivision := &AdministrativeDivision{}
if err = json.Unmarshal(resultByte, administrativeDivision); err != nil {
return nil, err
}
return administrativeDivision.Result, err*/
}
if keywords != "" {
return a.GetSecondaryDivision(subDistrict, keywords, level)
}
return nil, fmt.Errorf("参数异常")
}
// GetSecondaryDivision 获取二级行政区划 keywords 是父级code
func (a *API) GetSecondaryDivision(number int, keywords string, level int) ([]*District, error) {
param := map[string]interface{}{
"key": a.key,
"id": keywords,
}
param["sig"] = a.signParams(param, TencentGetChildrenList)
result, err := a.AccessAPI(BaseUrl, TencentGetChildrenList, http.MethodGet, param)
if err != nil {
return nil, err
}
resultByte, err := json.Marshal(result)
if err != nil {
return nil, err
}
districtGetChildren := &DistrictGetChildren{}
if err = json.Unmarshal(resultByte, districtGetChildren); err != nil {
return nil, err
}
if districtGetChildren.Status != 0 {
return nil, fmt.Errorf("%s", districtGetChildren.Message)
}
resultData := make([]*District, 0, 0)
for _, v := range districtGetChildren.Result[0] {
parentCode := &District{
Adcode: v.Id,
Lng: 0.0,
Lat: 0.0,
CityCode: "",
Level: level,
Name: v.Fullname,
Districts: nil,
}
parentCode.Lng, _ = v.Location.Lng.Float64()
parentCode.Lat, _ = v.Location.Lat.Float64()
if number == 2 {
parentCode.Districts, _ = a.GetSecondaryDivision(1, v.Id, level+1)
}
resultData = append(resultData, parentCode)
}
return resultData, nil
}
// BatchWalkingDistance 批量获取两点之间的步行距离
func (a *API) BatchWalkingDistance(srcLng, srcLat float64, destCoords []*Coordinate) (distanceList []float64, err error) {
for _, v := range destCoords {
distance, err := a.WalkingDistance(&TencentCyclingPlanningReq{
Key: a.key,
From: fmt.Sprintf("%f,%f", srcLat, srcLng),
To: fmt.Sprintf("%f,%f", v.Lat, v.Lng),
})
if err != nil {
return nil, err
}
distanceList = append(distanceList, utils.Int64ToFloat64(distance))
}
return distanceList, err
}
// GetCoordinateDistrictCode 获取坐标点所在行政区划
func (a *API) GetCoordinateDistrictCode(lng, lat float64) (districtCode int) {
result, err := a.GeoCodeRegeoSingle(lng, lat, 0, false, nil, 0, 0)
if err == nil {
districtCode = utils.Str2Int(result.Result.AdInfo.Adcode)
// 这个是因为老代码使用搞的地图获取这两个市的时候没有分区,place表做了一个假的分区,这边为了统一
if result.Result.AdInfo.District == "东莞市" || result.Result.AdInfo.District == "中山市" {
districtCode += 9000000 // FakeDistrictPadding
}
return
}
return 0
}
// GetCoordinateTownInfo 根据坐标获取城市名称和坐标
func (a *API) GetCoordinateTownInfo(lng, lat float64) (townName, townCode string) {
result, err := a.GeoCodeRegeoSingle(lng, lat, 0, false, nil, 0, 0)
if err == nil {
if name, ok := result.Result.AddressReference.(map[string]interface{})["town"].(map[string]interface{})["title"]; ok {
townName = name.(string)
}
if name, ok := result.Result.AddressReference.(map[string]interface{})["town"].(map[string]interface{})["id"]; ok {
townCode = name.(string) + "000"
}
}
return
}
// GetCoordinateCityInfo 根据坐标获取
func (a *API) GetCoordinateCityInfo(lng, lat float64) (cityName, cityCode string) {
result, err := a.GeoCodeRegeoSingle(lng, lat, 0, false, nil, 0, 0)
if err == nil {
cityName = result.Result.AdInfo.City
// cityCode 老版本高德地图获取到的是电话的区号,但是这个返回值没有使用,暂时不做处理
cityCode = result.Result.AdInfo.CityCode
}
return
}

View File

@@ -0,0 +1,202 @@
package tencent_map
import "encoding/json"
//#region 坐标转换参数
// TencentCoordinateChangeReq 坐标转换请求参数
type TencentCoordinateChangeReq struct {
Key string `json:"key" binding:"required"` // 开发秘钥
Locations string `json:"locations" binding:"required"` // 预转换的坐标,支持批量转换, 格式:纬度前,经度后,纬度和经度之间用",“分隔,每组坐标之间使用”;"分隔; 批量支持坐标个数以HTTP GET方法请求上限为准
Type int `json:"type" binding:"required"` // 输入的locations的坐标类型可选值 1 GPS坐标2 sogou经纬度3 baidu经纬度4 mapbar经纬度6 sogou墨卡托
//Output string `json:"output"` // 返回格式支持JSON/JSONP默认JSON
}
// TencentCoordinateChangeRes 坐标转换返回参数
type TencentCoordinateChangeRes struct {
Status int64 `json:"status"` //状态码0为正常其它为异常详细请参阅状态码说明
Message string `json:"message"` // 对status的描述
Locations []*LocationsCoordinate `json:"locations"` // 坐标列
}
type LocationsCoordinate struct {
Lat json.Number `json:"lat"` // 纬度
Lng json.Number `json:"lng"` // 经度
}
type LocationsCoordinateObj struct {
Lat string `json:"lat"` // 纬度
Lng string `json:"lng"` // 经度
}
//#endregion
//#region 获取腾讯骑行计划
// TencentCyclingPlanningReq 获取骑行计划参数
type TencentCyclingPlanningReq struct {
Key string `json:"key" binding:"required"` // 开发秘钥
From string `json:"from" binding:"required"` // 起点位置坐标,纬度在前,经度在后 from=39.915285,116.403857
To string `json:"to" binding:"required"` // 终点位置坐标,纬度在前,经度在后 from=39.915285,116.403857
}
// TencentCyclingPlanningRes 获取骑行计划返回值
type TencentCyclingPlanningRes struct {
Status int64 `json:"status"` //状态码0为正常其它为异常详细请参阅状态码说明
Message string `json:"message"` // 对status的描述
Result map[string][]*Routers `json:"result"` // 搜索结果
}
// Routers 骑行计划详细返回值
type Routers struct {
Mode string `json:"mode"` // 方案交通方式固定值“EBICYCLING”
Distance int64 `json:"distance"` // 方案整体距离,单位:米
Duration int64 `json:"duration"` // 方案估算时间,单位:分钟
Direction string `json:"direction"` // 方案整体方向
Polyline []json.Number `json:"polyline"` // 方案路线坐标点串
Steps interface{} `json:"steps"` // 路线步骤
}
//#endregion
//#region 地址转坐标解析
// AddressGeoCoderChangeRes 地址转坐标解析返回参数
type AddressGeoCoderChangeRes struct {
Status int64 `json:"status"` //状态码0为正常其它为异常详细请参阅状态码说明
Message string `json:"message"` // 对status的描述
Result *ResultDetail `json:"result"` // 搜索结果
}
type ResultDetail struct {
Title string `json:"title"` // 废弃
Location LocationsCoordinate `json:"location"` // 解析到的坐标
AddressComponents struct {
Province string `json:"province"` // 省
City string `json:"city"` // 市
District string `json:"district"` // 区
Street string `json:"street"` // 街道
StreetNumber string `json:"street_number"` // 门派
} `json:"address_components"` // 解析后地址部件
AdInfo struct {
AdCode string `json:"adcode"` // 行政区划代码
} `json:"ad_info"` // 行政区划
Similarity json.Number `json:"similarity"` // 下线
Deviation json.Number `json:"deviation"` // 下线
Reliability json.Number `json:"reliability"` // 可信度参考:值范围 1 <低可信> - 10 <高可信>我们根据用户输入地址的准确程度,在解析过程中,将解析结果的可信度(质量)由低到高分为1 - 10级该值>=7时解析结果较为准确<7时会存各类不可靠因
Level json.Number `json:"level"` // 解析精度级别分为11个级别一般>=9即可采用定位到点精度较高 也可根据实际业务需求自行调
}
//#endregion
//#region 坐标转地址
type Codes2AddressRes struct {
Status int `json:"status"`
Message string `json:"message"`
RequestId string `json:"request_id"`
Result Code2AddressResultDetail `json:"result"`
}
type Code2AddressResultDetail struct {
Address string `json:"address"` // 以行政区划+道路+门牌号等信息组成的标准格式化地址
FormattedAddresses struct {
Recommend string `json:"recommend"` // 推荐使用的地址描述,描述精确性较高
Rough string `json:"rough"` // 粗略位置描述
StandardAddress string `json:"standard_address"` // address
} `json:"formatted_addresses"` // 结合知名地点形成的描述性地址,更具人性化特点
AddressComponent struct {
Nation string `json:"nation"` // 国家
Province string `json:"province"` // 省
City string `json:"city"` // 市如果当前城市为省直辖县级区划city与district字段均会返回此城市
District string `json:"district"` // 区
Street string `json:"street"` // 道路
StreetNumber string `json:"street_number"` // 门牌
} `json:"address_component"` // 地址部件address不满足需求时可自行拼接
AdInfo struct {
NationCode string `json:"nation_code"` // 国家代码
Adcode string `json:"adcode"` // 行政区划代码
PhoneAreaCode string `json:"phone_area_code"` //
CityCode string `json:"city_code"` // 城市代码
Name string `json:"name"` // 行政区划名称
Location LocationsCoordinate `json:"location"` //
Nation string `json:"nation"` // 国家
Province string `json:"province"` // 省 / 直辖市
City string `json:"city"` // 市
District string `json:"district"` // 区
Distance int `json:"_distance"`
} `json:"ad_info"` // 行政区划信息
AddressReference interface{} `json:"address_reference"` // 坐标相对位置参考,暂时忽略掉
PoiCount int `json:"poi_count"` // 查询的周边poi的总数仅在传入参数get_poi=1时返回
Pois []struct {
Id string `json:"id"` // 地点POI唯一标识
Title string `json:"title"` // 名称
Address string `json:"address"` // 地址
Category string `json:"category"` // 地点信息分类
Location LocationsCoordinate `json:"location"`
AdInfo struct {
Adcode string `json:"adcode"` // 行政区划代码
Province string `json:"province"` // 省
City string `json:"city"` //市
District string `json:"district"` // 区
} `json:"ad_info"` // 行政区划信息
Distance float64 `json:"_distance"` // 该POI/AOI到逆地址解析传入的坐标的直线距离
DirDesc string `json:"_dir_desc,omitempty"` // 该POI/AOI在逆地址解析传入的坐标的相对方位描述包括东、东南、南、西南、西、西北、北、东北、内输入经纬度在AOI范围内
} `json:"pois"`
Location LocationsCoordinate `json:"location"`
}
//#endregion
//#region 行政区划获取
// AdministrativeDivision 获取全国的行政区划
//type AdministrativeDivision struct {
// Status int `json:"status"`
// Message string `json:"message"`
// RequestId string `json:"request_id"`
// DataVersion string `json:"data_version"` // 行政区划数据版本,便于您判断更新
// Result []*DistrictsList `json:"result"` // 全国行政区划
//}
//
//type DistrictsList struct {
// Id string `json:"id"` // 行政区划唯一标识adcode
// Name string `json:"name"` // 简称
// Level int `json:"level"` // 行政区划级别
// FullMame string `json:"fullname"` // 全称
// Pinyin []string `json:"pinyin"` // 拼音
// Location LocationsCoordinate `json:"location"` // 坐标
// DistrictsList []*DistrictsList `json:"districts"`
//}
// DistrictGetChildren 获取指定城市行政区划
type DistrictGetChildren struct {
Status int `json:"status"`
Message string `json:"message"`
RequestId string `json:"request_id"`
DataVersion string `json:"data_version"`
Result [][]struct {
Id string `json:"id"`
Name string `json:"name"`
Fullname string `json:"fullname"`
Pinyin []string `json:"pinyin"`
Location LocationsCoordinate `json:"location"`
} `json:"result"`
}
type District struct {
Adcode string `json:"adcode"` // 国家行政编码
Lng float64 `json:"lng"`
Lat float64 `json:"lat"`
CityCode string `json:"citycode"` // 电话区号
Level int `json:"level"`
Name string `json:"name"`
Districts []*District `json:"districts"`
}
//#endregion
type Coordinate struct {
Lng float64 `json:"lng"`
Lat float64 `json:"lat"`
}

View File

@@ -0,0 +1,111 @@
package tencent_map
import (
"git.rosy.net.cn/baseapi"
"go.uber.org/zap"
"testing"
)
var (
tencent *API
sugarLogger *zap.SugaredLogger
)
func init() {
logger, _ := zap.NewDevelopment()
sugarLogger = logger.Sugar()
baseapi.Init(sugarLogger)
tencent = New("Q2KBZ-YXFLN-LEVFD-STWQY-6RBBE-A4FLF", "vIO9yPPnp4pWmIywsR1DHCu0OFpQONeW")
}
// 坐标转换
func TestCoordinateChange(t *testing.T) {
result, err := tencent.TencentCoordinateChange(&TencentCoordinateChangeReq{
Locations: "34.260369,117.138444",
Type: CoordinateChangeTypeGaoDe,
//Output: "json",
})
if err != nil {
t.Log(err)
} else {
t.Log(result)
}
}
// 骑行规划
func TestTencentCyclingPlanning(t *testing.T) {
distance, duration, point, err := tencent.TencentCyclingPlanning(&TencentCyclingPlanningReq{
Key: tencent.key,
From: "30.637486,103.919896",
To: "30.604708,103.913647",
})
if err != nil {
t.Log(err)
} else {
t.Log(distance)
t.Log(duration)
t.Log(point)
}
}
// 地址解析坐标
func TestGetCoordinateFromAddress(t *testing.T) {
lng, lat, code, name, err := tencent.GetCoordinateFromAddress("四川省成都市双流区九江街道中国浩森国际装饰建材城-13幢", "")
if err != nil {
t.Log(err)
} else {
t.Log(lng)
t.Log(lat)
t.Log(code)
t.Log(name)
}
}
// 坐标解析地址
func TestGeoCodeRegeoSingle(t *testing.T) {
tencent.GeoCodeRegeoSingle(116.307490, 39.984154, 0, false, nil, 0, 0)
}
// 获取全国行政区划 List
func TestGetDistricts(t *testing.T) {
result, err := tencent.GetDistricts(2, "510000", 2)
if err != nil {
t.Log(err)
} else {
t.Log(result)
}
}
// 根据ID获取部分行政区划
func TestGetSecondaryDivision(t *testing.T) {
data, err := tencent.GetSecondaryDivision(2, "511300", 2)
if err != nil {
t.Log(err)
} else {
t.Log(data)
}
}
// 批量获取距离
func TestBatchWalkingDistance(t *testing.T) {
tencent.BatchWalkingDistance(103.913647, 30.604708, append([]*Coordinate{}, &Coordinate{
Lng: 103.914001,
Lat: 30.611431,
}))
}
// 根据坐标获取地址和区域代买
func TestGetCoordinateTownInfo(t *testing.T) {
name, code := tencent.GetCoordinateTownInfo(113.756791, 23.041187)
t.Log(name)
t.Log(code)
}
// 获取定位市区坐标
func TestGetCoordinateCityInfo(t *testing.T) {
name, code := tencent.GetCoordinateCityInfo(113.756791, 23.041187)
t.Log(name)
t.Log(code)
}

View File

@@ -6,7 +6,6 @@ import (
"fmt"
"git.rosy.net.cn/baseapi"
uuid "github.com/satori/go.uuid"
"math"
"net/http"
"reflect"
"strings"
@@ -264,24 +263,6 @@ func FilterEmoji(content string) string {
return newContent.String()
}
// BaiDuCoord2Gaode2 将百度坐标转换为高德坐标
func BaiDuCoord2Gaode2(baiduCoordinat []string) []string {
gaoCoordinat := make([]string, 0, 0)
for _, v := range baiduCoordinat {
var XPI = math.Pi * 3000.0 / 180.0
coords := strings.Split(v, ",")
var x = Str2Float64(coords[0]) - 0.0065
var y = Str2Float64(coords[1]) - 0.006
var z = math.Sqrt(x*x+y*y) - 0.00002*math.Sin(y*XPI)
var theta = math.Atan2(y, x) - 0.000003*math.Cos(x*XPI)
var gg_lng = z * math.Cos(theta)
var gg_lat = z * math.Sin(theta)
gaoCoordinat = append(gaoCoordinat, fmt.Sprintf("%.6f,%.6f", gg_lng, gg_lat))
}
return gaoCoordinat
}
func TrimBlankChar(str string) string {
return strings.Trim(str, "\u202C\n\r\t ")
}