+autonavi.BatchWalkingDistance
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package autonavi
|
package autonavi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -12,8 +13,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
signKey = "sig"
|
signKey = "sig"
|
||||||
prodURL = "https://restapi.amap.com/v3"
|
prodURL = "https://restapi.amap.com"
|
||||||
|
prodURLv3 = "/v3"
|
||||||
|
prodURLFullv3 = prodURL + prodURLv3
|
||||||
|
|
||||||
|
batchAPIStr = "batch"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -196,6 +201,16 @@ type RegeoCodeInfo struct {
|
|||||||
Roads []*RoadInfo `json:"roads"`
|
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 {
|
func New(key string, config ...*platformapi.APIConfig) *API {
|
||||||
curConfig := platformapi.DefAPIConfig
|
curConfig := platformapi.DefAPIConfig
|
||||||
if len(config) > 0 {
|
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,
|
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||||||
func() *http.Request {
|
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
|
return request
|
||||||
},
|
},
|
||||||
a.config,
|
a.config,
|
||||||
@@ -262,6 +277,74 @@ func (a *API) AccessAPI(apiStr string, params map[string]interface{}) (retVal Re
|
|||||||
return retVal, err
|
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) {
|
func (a *API) CoordinateConvert(lng, lat float64, coordsys string) (retLng, retLat float64, err error) {
|
||||||
// outCoords, err := a.BatchCoordinateConvert([]*Coordinate{
|
// outCoords, err := a.BatchCoordinateConvert([]*Coordinate{
|
||||||
@@ -484,3 +567,29 @@ func (a *API) WalkingDistance(lng1, lat1, lng2, lat2 float64) (distance float64)
|
|||||||
}
|
}
|
||||||
return distance
|
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))
|
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 // 可恢复类错误(一般指网络错),最大重试次数
|
DefMaxRecoverableRetryCount = 1 // 可恢复类错误(一般指网络错),最大重试次数
|
||||||
|
|
||||||
KeyTrackInfo = "TrackInfo"
|
KeyTrackInfo = "TrackInfo"
|
||||||
|
KeyData = "fakeData"
|
||||||
)
|
)
|
||||||
|
|
||||||
type APIRetryConfig struct {
|
type APIRetryConfig struct {
|
||||||
@@ -147,6 +148,7 @@ func AccessPlatformAPIWithRetry(client *http.Client, handleRequest func() *http.
|
|||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
errLevel string
|
errLevel string
|
||||||
|
bodyGeneral interface{}
|
||||||
bodyMap map[string]interface{}
|
bodyMap map[string]interface{}
|
||||||
parseJSONErr error
|
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)
|
baseapi.SugarLogger.Errorf("AccessPlatformAPIWithRetry:%s ioutil.ReadAll failed, url:%v, request:%v, error:%v", trackInfo, request.URL, getClonedData(request.URL, savedBuf), err)
|
||||||
errLevel = ErrLevelRecoverableErr // 读取数据错误,或数据格式错误认为是偶发情况,重试
|
errLevel = ErrLevelRecoverableErr // 读取数据错误,或数据格式错误认为是偶发情况,重试
|
||||||
} else {
|
} else {
|
||||||
if err = utils.TryUnmarshalUseNumber(bodyData, &bodyMap); err != nil {
|
if err = utils.TryUnmarshalUseNumber(bodyData, &bodyGeneral); err != nil {
|
||||||
parseJSONErr = err
|
parseJSONErr = err
|
||||||
err = nil // 尝试忽略解析成json错
|
err = nil // 尝试忽略解析成json错
|
||||||
} else {
|
} 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)
|
errLevel, err = handleResponse(response, string(bodyData), bodyMap)
|
||||||
if err != nil && parseJSONErr != nil {
|
if err != nil && parseJSONErr != nil {
|
||||||
const maxOutputLen = 200
|
const maxOutputLen = 2000
|
||||||
bodyDataLen := len(bodyData)
|
bodyDataLen := len(bodyData)
|
||||||
bodyData2 := bodyData
|
bodyData2 := bodyData
|
||||||
if bodyDataLen > maxOutputLen {
|
if bodyDataLen > maxOutputLen {
|
||||||
|
|||||||
Reference in New Issue
Block a user