+autonavi.BatchWalkingDistance
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package autonavi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -12,8 +13,12 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
signKey = "sig"
|
||||
prodURL = "https://restapi.amap.com/v3"
|
||||
signKey = "sig"
|
||||
prodURL = "https://restapi.amap.com"
|
||||
prodURLv3 = "/v3"
|
||||
prodURLFullv3 = prodURL + prodURLv3
|
||||
|
||||
batchAPIStr = "batch"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -196,6 +201,16 @@ type RegeoCodeInfo struct {
|
||||
Roads []*RoadInfo `json:"roads"`
|
||||
}
|
||||
|
||||
type tBatchAPIParams struct {
|
||||
APIStr string
|
||||
APIParams map[string]interface{}
|
||||
}
|
||||
|
||||
type tBatchAPIResponse struct {
|
||||
Result ResponseResult
|
||||
Err error
|
||||
}
|
||||
|
||||
func New(key string, config ...*platformapi.APIConfig) *API {
|
||||
curConfig := platformapi.DefAPIConfig
|
||||
if len(config) > 0 {
|
||||
@@ -236,7 +251,7 @@ func (a *API) AccessAPI(apiStr string, params map[string]interface{}) (retVal Re
|
||||
|
||||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||||
func() *http.Request {
|
||||
request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params2), nil)
|
||||
request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURLFullv3, apiStr, params2), nil)
|
||||
return request
|
||||
},
|
||||
a.config,
|
||||
@@ -262,6 +277,74 @@ func (a *API) AccessAPI(apiStr string, params map[string]interface{}) (retVal Re
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
func (a *API) BatchAccessAPI(apiList []*tBatchAPIParams) (retVal []*tBatchAPIResponse, err error) {
|
||||
if len(apiList) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var ops []map[string]interface{}
|
||||
for _, v := range apiList {
|
||||
params2 := utils.MergeMaps(utils.Params2Map("key", a.key, "output", "json"), v.APIParams)
|
||||
params2[signKey] = a.signParams(params2)
|
||||
op := make(map[string]interface{})
|
||||
op["url"] = utils.GenerateGetURL(prodURLv3, v.APIStr, params2)
|
||||
ops = append(ops, op)
|
||||
}
|
||||
params2 := map[string]interface{}{
|
||||
"ops": ops,
|
||||
}
|
||||
|
||||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||||
func() *http.Request {
|
||||
request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURLFullv3, batchAPIStr, utils.Params2Map("key", a.key)),
|
||||
bytes.NewReader(utils.MustMarshal(params2)))
|
||||
request.Header.Set("charset", "UTF-8")
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
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")
|
||||
}
|
||||
if resultList, ok := jsonResult1[platformapi.KeyData].([]interface{}); ok {
|
||||
for _, v := range resultList {
|
||||
jsonResult1 := v.(map[string]interface{})
|
||||
status := int(utils.ForceInterface2Int64(jsonResult1["status"]))
|
||||
if status == http.StatusOK {
|
||||
jsonResult1 := v.(map[string]interface{})["body"].(map[string]interface{})
|
||||
var retVal2 map[string]interface{}
|
||||
var err2 error
|
||||
status := jsonResult1["status"].(string)
|
||||
if status == StatusCodeSuccess {
|
||||
retVal2 = jsonResult1
|
||||
} else {
|
||||
infoCode := jsonResult1["infocode"].(string)
|
||||
err2 = utils.NewErrorCode(jsonResult1["info"].(string), infoCode)
|
||||
}
|
||||
retVal = append(retVal, &tBatchAPIResponse{
|
||||
Result: retVal2,
|
||||
Err: err2,
|
||||
})
|
||||
}
|
||||
}
|
||||
errLevel = platformapi.ErrLevelSuccess
|
||||
} else {
|
||||
infoCode := jsonResult1["infocode"].(string)
|
||||
err = utils.NewErrorCode(jsonResult1["info"].(string), infoCode)
|
||||
if _, ok := exceedLimitCodes[infoCode]; ok {
|
||||
errLevel = platformapi.ErrLevelExceedLimit
|
||||
} else if _, ok := canRetryCodes[infoCode]; ok {
|
||||
errLevel = platformapi.ErrLevelRecoverableErr
|
||||
} else {
|
||||
errLevel = platformapi.ErrLevelCodeIsNotOK
|
||||
}
|
||||
}
|
||||
return errLevel, err
|
||||
})
|
||||
return retVal, err
|
||||
}
|
||||
|
||||
// 为了方便调用者编码,如果失败,也会返回未转换的原始值
|
||||
func (a *API) CoordinateConvert(lng, lat float64, coordsys string) (retLng, retLat float64, err error) {
|
||||
// outCoords, err := a.BatchCoordinateConvert([]*Coordinate{
|
||||
@@ -484,3 +567,29 @@ func (a *API) WalkingDistance(lng1, lat1, lng2, lat2 float64) (distance float64)
|
||||
}
|
||||
return distance
|
||||
}
|
||||
|
||||
func (a *API) BatchWalkingDistance(srcLng, srcLat float64, destCoords []*Coordinate) (distanceList []float64, err error) {
|
||||
var reqList []*tBatchAPIParams
|
||||
for _, v := range destCoords {
|
||||
reqList = append(reqList, &tBatchAPIParams{
|
||||
APIStr: "direction/walking",
|
||||
APIParams: map[string]interface{}{
|
||||
"origin": coordinate2String(srcLng, srcLat),
|
||||
"destination": coordinate2String(v.Lng, v.Lat),
|
||||
},
|
||||
})
|
||||
}
|
||||
resultList, err := a.BatchAccessAPI(reqList)
|
||||
if err == nil {
|
||||
for _, v := range resultList {
|
||||
distance := float64(9527123)
|
||||
if v.Err == nil {
|
||||
if paths, _ := v.Result["route"].(map[string]interface{})["paths"].([]interface{}); len(paths) > 0 {
|
||||
distance = utils.Interface2Float64WithDefault(paths[0].(map[string]interface{})["distance"], 0)
|
||||
}
|
||||
}
|
||||
distanceList = append(distanceList, distance)
|
||||
}
|
||||
}
|
||||
return distanceList, err
|
||||
}
|
||||
|
||||
@@ -112,3 +112,40 @@ func TestGeoCodeRegeo(t *testing.T) {
|
||||
}
|
||||
t.Log(utils.Format4Output(result, false))
|
||||
}
|
||||
|
||||
func TestBatchWalkingDistance(t *testing.T) {
|
||||
result, err := autonaviAPI.BatchWalkingDistance(104.052756, 30.685203, []*Coordinate{
|
||||
&Coordinate{
|
||||
Lng: 104.052756,
|
||||
Lat: 30.687203,
|
||||
},
|
||||
&Coordinate{
|
||||
Lng: 104.032756,
|
||||
Lat: 30.685203,
|
||||
},
|
||||
&Coordinate{
|
||||
Lng: 104.032756,
|
||||
Lat: 30.685203,
|
||||
},
|
||||
&Coordinate{
|
||||
Lng: 104.032756,
|
||||
Lat: 30.685203,
|
||||
},
|
||||
&Coordinate{
|
||||
Lng: 104.032756,
|
||||
Lat: 30.685203,
|
||||
},
|
||||
&Coordinate{
|
||||
Lng: 104.032756,
|
||||
Lat: 30.685203,
|
||||
},
|
||||
&Coordinate{
|
||||
Lng: 104.032756,
|
||||
Lat: 30.685203,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(utils.Format4Output(result, false))
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ const (
|
||||
DefMaxRecoverableRetryCount = 1 // 可恢复类错误(一般指网络错),最大重试次数
|
||||
|
||||
KeyTrackInfo = "TrackInfo"
|
||||
KeyData = "fakeData"
|
||||
)
|
||||
|
||||
type APIRetryConfig struct {
|
||||
@@ -147,6 +148,7 @@ func AccessPlatformAPIWithRetry(client *http.Client, handleRequest func() *http.
|
||||
}
|
||||
var (
|
||||
errLevel string
|
||||
bodyGeneral interface{}
|
||||
bodyMap map[string]interface{}
|
||||
parseJSONErr error
|
||||
)
|
||||
@@ -155,15 +157,23 @@ func AccessPlatformAPIWithRetry(client *http.Client, handleRequest func() *http.
|
||||
baseapi.SugarLogger.Errorf("AccessPlatformAPIWithRetry:%s ioutil.ReadAll failed, url:%v, request:%v, error:%v", trackInfo, request.URL, getClonedData(request.URL, savedBuf), err)
|
||||
errLevel = ErrLevelRecoverableErr // 读取数据错误,或数据格式错误认为是偶发情况,重试
|
||||
} else {
|
||||
if err = utils.TryUnmarshalUseNumber(bodyData, &bodyMap); err != nil {
|
||||
if err = utils.TryUnmarshalUseNumber(bodyData, &bodyGeneral); err != nil {
|
||||
parseJSONErr = err
|
||||
err = nil // 尝试忽略解析成json错
|
||||
} else {
|
||||
baseapi.SugarLogger.Debugf("AccessPlatformAPIWithRetry:%s url:%v, response:%s", trackInfo, request.URL, utils.Format4Output(bodyMap, true))
|
||||
baseapi.SugarLogger.Debugf("AccessPlatformAPIWithRetry:%s url:%v, response:%s", trackInfo, request.URL, utils.Format4Output(bodyGeneral, true))
|
||||
}
|
||||
// 临时处理返回值居然不是map的情况
|
||||
if bodyMap2, ok := bodyGeneral.(map[string]interface{}); ok {
|
||||
bodyMap = bodyMap2
|
||||
} else {
|
||||
bodyMap = map[string]interface{}{
|
||||
KeyData: bodyGeneral,
|
||||
}
|
||||
}
|
||||
errLevel, err = handleResponse(response, string(bodyData), bodyMap)
|
||||
if err != nil && parseJSONErr != nil {
|
||||
const maxOutputLen = 200
|
||||
const maxOutputLen = 2000
|
||||
bodyDataLen := len(bodyData)
|
||||
bodyData2 := bodyData
|
||||
if bodyDataLen > maxOutputLen {
|
||||
|
||||
Reference in New Issue
Block a user