diff --git a/platformapi/autonavi/autonavi.go b/platformapi/autonavi/autonavi.go index bcc1a42d..2d39801c 100644 --- a/platformapi/autonavi/autonavi.go +++ b/platformapi/autonavi/autonavi.go @@ -1,386 +1,385 @@ package autonavi -import ( - "bytes" - "crypto/md5" - "fmt" - "net/http" - "sort" - "strings" - - "git.rosy.net.cn/baseapi/platformapi" - "git.rosy.net.cn/baseapi/utils" -) - -const ( - signKey = "sig" - prodURL = "https://restapi.amap.com" - prodURLv3 = "/v3" - prodURLFullv3 = prodURL + prodURLv3 - - batchAPIStr = "batch" -) - -const ( - StatusCodeFailed = "0" - StatusCodeSuccess = "1" -) - -const ( - InfoCode_OK = "10000" - InfoCode_ACCESS_TOO_FREQUENT = "10004" - InfoCode_QPS_HAS_EXCEEDED_THE_LIMIT = "10014" - InfoCode_SERVER_IS_BUSY = "10016" - InfoCode_RESOURCE_UNAVAILABLE = "10017" - InfoCode_CQPS_HAS_EXCEEDED_THE_LIMIT = "10019" - InfoCode_CKQPS_HAS_EXCEEDED_THE_LIMIT = "10020" - InfoCode_CIQPS_HAS_EXCEEDED_THE_LIMIT = "10021" - InfoCode_CIKQPS_HAS_EXCEEDED_THE_LIMIT = "10022" - InfoCode_KQPS_HAS_EXCEEDED_THE_LIMIT = "10023" -) - -const ( - CoordSysAutonavi = "autonavi" - CoordSysGPS = "gps" - CoordSysMapbar = "mapbar" - CoordSysBaidu = "baidu" -) - -const ( - FakeDistrictPadding = 9000000 - MaxConvertCount = 40 -) - -var ( - exceedLimitCodes = map[string]int{ - InfoCode_ACCESS_TOO_FREQUENT: 1, - InfoCode_QPS_HAS_EXCEEDED_THE_LIMIT: 1, - InfoCode_CQPS_HAS_EXCEEDED_THE_LIMIT: 1, - InfoCode_CKQPS_HAS_EXCEEDED_THE_LIMIT: 1, - InfoCode_CIQPS_HAS_EXCEEDED_THE_LIMIT: 1, - InfoCode_CIKQPS_HAS_EXCEEDED_THE_LIMIT: 1, - InfoCode_KQPS_HAS_EXCEEDED_THE_LIMIT: 1, - } - - canRetryCodes = map[string]int{ - InfoCode_SERVER_IS_BUSY: 1, - } -) - -const ( - DistrictLevelCountry = 0 - DistrictLevelProvince = 1 - DistrictLevelCity = 2 - DistrictLevelDistrict = 3 - DistrictLevelStreet = 4 -) - -const ( - RoadLevelAll = 0 // 显示所有道路 - RoadLevelMain = 1 // 过滤非主干道路,仅输出主干道路数据 - - HomeOrCorpDef = 0 // 不对召回的排序策略进行干扰。 - HomeOrCorpPreferHome = 1 // 综合大数据分析将居家相关的 POI 内容优先返回,即优化返回结果中 pois 字段的poi顺序。 - HomeOrCorpPreferCorp = 2 // 综合大数据分析将公司相关的 POI 内容优先返回,即优化返回结果中 pois 字段的poi顺序。 -) - -var ( - levelStr2IntMap = map[string]int{ - "country": DistrictLevelCountry, - "province": DistrictLevelProvince, - "city": DistrictLevelCity, - "district": DistrictLevelDistrict, - "street": DistrictLevelStreet, - } -) - -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"` -} - -type Coordinate struct { - Lng float64 `json:"lng"` - Lat float64 `json:"lat"` -} - -type ResponseResult map[string]interface{} - -type API struct { - platformapi.APICookie - - client *http.Client - config *platformapi.APIConfig - key string -} - -func (a *API) SetKey(key string) { - a.key = key -} - -type BuildingOrNeighborInfo struct { - Name string `json:"name"` - Type string `json:"type"` -} - -type BusinessAreaInfo struct { - ID string `json:"id"` - Location string `json:"location"` - Name string `json:"name"` -} - -type StreetNumberInfo struct { - Direction string `json:"direction"` - Distance string `json:"distance"` - Location string `json:"location"` - Number string `json:"number"` - Street string `json:"street"` -} - -type AoiInfo struct { - Adcode string `json:"adcode"` - Area string `json:"area"` - Distance string `json:"distance"` - ID string `json:"id"` - Location string `json:"location"` - Name string `json:"name"` - Type string `json:"type"` -} - -type PoiInfo struct { - Address string `json:"address"` - Businessarea string `json:"businessarea"` - Direction string `json:"direction"` - Distance string `json:"distance"` - ID string `json:"id"` - Location string `json:"location"` - Name string `json:"name"` - Poiweight string `json:"poiweight"` - Tel string `json:"tel"` - Type string `json:"type"` -} - -type RoadinterInfo struct { - Direction string `json:"direction"` - Distance string `json:"distance"` - FirstID string `json:"first_id"` - FirstName string `json:"first_name"` - Location string `json:"location"` - SecondID string `json:"second_id"` - SecondName string `json:"second_name"` -} - -type RoadInfo struct { - Direction string `json:"direction"` - Distance string `json:"distance"` - ID string `json:"id"` - Location string `json:"location"` - Name string `json:"name"` -} - -type AddressComponentInfo struct { - Adcode string `json:"adcode"` - Building *BuildingOrNeighborInfo `json:"building"` - // BusinessAreas []*BusinessAreaInfo `json:"businessAreas"` - City string `json:"city"` - Citycode string `json:"citycode"` - Country string `json:"country"` - District string `json:"district"` - Neighborhood *BuildingOrNeighborInfo `json:"neighborhood"` - Province string `json:"province"` - StreetNumber *StreetNumberInfo `json:"streetNumber"` - Towncode string `json:"towncode"` - Township string `json:"township"` -} - -type RegeoCodeInfo struct { - AddressComponent *AddressComponentInfo `json:"addressComponent"` - Aois []*AoiInfo `json:"aois"` - FormattedAddress string `json:"formatted_address"` - Pois []*PoiInfo `json:"pois"` - Roadinters []*RoadinterInfo `json:"roadinters"` - 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 { - curConfig = *config[0] - } - return &API{ - key: key, - client: &http.Client{Timeout: curConfig.ClientTimeout}, - config: &curConfig, - } -} - -func (a *API) signParams(mapData map[string]interface{}) string { - keys := make([]string, 0) - for k := range mapData { - if k != signKey { - keys = append(keys, k) - } - } - sort.Strings(keys) - - finalStr := "" - for _, k := range keys { - finalStr += k + "=" + fmt.Sprint(mapData[k]) - } - - return fmt.Sprintf("%X", md5.Sum([]byte(finalStr))) -} - -func coordinate2String(lng, lat float64) (str string) { - return fmt.Sprintf("%.6f,%.6f", lng, lat) -} - -func (a *API) AccessAPI(apiStr string, params map[string]interface{}) (retVal ResponseResult, err error) { - params2 := utils.MergeMaps(utils.Params2Map("key", a.key, "output", "json"), params) - params2[signKey] = a.signParams(params2) - - err = platformapi.AccessPlatformAPIWithRetry(a.client, - func() *http.Request { - request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURLFullv3, 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 := jsonResult1["status"].(string) - if status == StatusCodeSuccess { - retVal = jsonResult1 - return platformapi.ErrLevelSuccess, nil - } - infoCode := jsonResult1["infocode"].(string) - newErr := utils.NewErrorCode(jsonResult1["info"].(string), infoCode) - if _, ok := exceedLimitCodes[infoCode]; ok { - return platformapi.ErrLevelExceedLimit, newErr - } else if _, ok := canRetryCodes[infoCode]; ok { - return platformapi.ErrLevelRecoverableErr, newErr - } else { - return platformapi.ErrLevelCodeIsNotOK, newErr - } - }) - return retVal, err -} - -func (a *API) AccessAPI3(apiStr string, params map[string]interface{}) (retVal ResponseResult, err error) { - err = platformapi.AccessPlatformAPIWithRetry(a.client, - func() *http.Request { - request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(BaseUrl, apiStr, params), 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 := jsonResult1["status"].(string) - if status == StatusCodeSuccess { - retVal = jsonResult1 - return platformapi.ErrLevelSuccess, nil - } - infoCode := jsonResult1["infocode"].(string) - newErr := utils.NewErrorCode(jsonResult1["info"].(string), infoCode) - if _, ok := exceedLimitCodes[infoCode]; ok { - return platformapi.ErrLevelExceedLimit, newErr - } else if _, ok := canRetryCodes[infoCode]; ok { - return platformapi.ErrLevelRecoverableErr, newErr - } else { - return platformapi.ErrLevelCodeIsNotOK, newErr - } - }) - 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 -} +// +//import ( +// "bytes" +// "crypto/md5" +// "fmt" +// "git.rosy.net.cn/baseapi/platformapi" +// "git.rosy.net.cn/baseapi/utils" +// "net/http" +// "sort" +//) +// +//const ( +// signKey = "sig" +// prodURL = "https://restapi.amap.com" +// prodURLv3 = "/v3" +// prodURLFullv3 = prodURL + prodURLv3 +// +// batchAPIStr = "batch" +//) +// +//const ( +// StatusCodeFailed = "0" +// StatusCodeSuccess = "1" +//) +// +//const ( +// InfoCode_OK = "10000" +// InfoCode_ACCESS_TOO_FREQUENT = "10004" +// InfoCode_QPS_HAS_EXCEEDED_THE_LIMIT = "10014" +// InfoCode_SERVER_IS_BUSY = "10016" +// InfoCode_RESOURCE_UNAVAILABLE = "10017" +// InfoCode_CQPS_HAS_EXCEEDED_THE_LIMIT = "10019" +// InfoCode_CKQPS_HAS_EXCEEDED_THE_LIMIT = "10020" +// InfoCode_CIQPS_HAS_EXCEEDED_THE_LIMIT = "10021" +// InfoCode_CIKQPS_HAS_EXCEEDED_THE_LIMIT = "10022" +// InfoCode_KQPS_HAS_EXCEEDED_THE_LIMIT = "10023" +//) +// +//const ( +// CoordSysAutonavi = "autonavi" +// CoordSysGPS = "gps" +// CoordSysMapbar = "mapbar" +// CoordSysBaidu = "baidu" +//) +// +//const ( +// FakeDistrictPadding = 9000000 +// MaxConvertCount = 40 +//) +// +//var ( +// exceedLimitCodes = map[string]int{ +// InfoCode_ACCESS_TOO_FREQUENT: 1, +// InfoCode_QPS_HAS_EXCEEDED_THE_LIMIT: 1, +// InfoCode_CQPS_HAS_EXCEEDED_THE_LIMIT: 1, +// InfoCode_CKQPS_HAS_EXCEEDED_THE_LIMIT: 1, +// InfoCode_CIQPS_HAS_EXCEEDED_THE_LIMIT: 1, +// InfoCode_CIKQPS_HAS_EXCEEDED_THE_LIMIT: 1, +// InfoCode_KQPS_HAS_EXCEEDED_THE_LIMIT: 1, +// } +// +// canRetryCodes = map[string]int{ +// InfoCode_SERVER_IS_BUSY: 1, +// } +//) +// +//const ( +// DistrictLevelCountry = 0 +// DistrictLevelProvince = 1 +// DistrictLevelCity = 2 +// DistrictLevelDistrict = 3 +// DistrictLevelStreet = 4 +//) +// +//const ( +// RoadLevelAll = 0 // 显示所有道路 +// RoadLevelMain = 1 // 过滤非主干道路,仅输出主干道路数据 +// +// HomeOrCorpDef = 0 // 不对召回的排序策略进行干扰。 +// HomeOrCorpPreferHome = 1 // 综合大数据分析将居家相关的 POI 内容优先返回,即优化返回结果中 pois 字段的poi顺序。 +// HomeOrCorpPreferCorp = 2 // 综合大数据分析将公司相关的 POI 内容优先返回,即优化返回结果中 pois 字段的poi顺序。 +//) +// +//var ( +// levelStr2IntMap = map[string]int{ +// "country": DistrictLevelCountry, +// "province": DistrictLevelProvince, +// "city": DistrictLevelCity, +// "district": DistrictLevelDistrict, +// "street": DistrictLevelStreet, +// } +//) +// +//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"` +//} +// +//type Coordinate struct { +// Lng float64 `json:"lng"` +// Lat float64 `json:"lat"` +//} +// +//type ResponseResult map[string]interface{} +// +//type API struct { +// platformapi.APICookie +// +// client *http.Client +// config *platformapi.APIConfig +// key string +//} +// +//func (a *API) SetKey(key string) { +// a.key = key +//} +// +//type BuildingOrNeighborInfo struct { +// Name string `json:"name"` +// Type string `json:"type"` +//} +// +//type BusinessAreaInfo struct { +// ID string `json:"id"` +// Location string `json:"location"` +// Name string `json:"name"` +//} +// +//type StreetNumberInfo struct { +// Direction string `json:"direction"` +// Distance string `json:"distance"` +// Location string `json:"location"` +// Number string `json:"number"` +// Street string `json:"street"` +//} +// +//type AoiInfo struct { +// Adcode string `json:"adcode"` +// Area string `json:"area"` +// Distance string `json:"distance"` +// ID string `json:"id"` +// Location string `json:"location"` +// Name string `json:"name"` +// Type string `json:"type"` +//} +// +//type PoiInfo struct { +// Address string `json:"address"` +// Businessarea string `json:"businessarea"` +// Direction string `json:"direction"` +// Distance string `json:"distance"` +// ID string `json:"id"` +// Location string `json:"location"` +// Name string `json:"name"` +// Poiweight string `json:"poiweight"` +// Tel string `json:"tel"` +// Type string `json:"type"` +//} +// +//type RoadinterInfo struct { +// Direction string `json:"direction"` +// Distance string `json:"distance"` +// FirstID string `json:"first_id"` +// FirstName string `json:"first_name"` +// Location string `json:"location"` +// SecondID string `json:"second_id"` +// SecondName string `json:"second_name"` +//} +// +//type RoadInfo struct { +// Direction string `json:"direction"` +// Distance string `json:"distance"` +// ID string `json:"id"` +// Location string `json:"location"` +// Name string `json:"name"` +//} +// +//type AddressComponentInfo struct { +// Adcode string `json:"adcode"` +// Building *BuildingOrNeighborInfo `json:"building"` +// // BusinessAreas []*BusinessAreaInfo `json:"businessAreas"` +// City string `json:"city"` +// Citycode string `json:"citycode"` +// Country string `json:"country"` +// District string `json:"district"` +// Neighborhood *BuildingOrNeighborInfo `json:"neighborhood"` +// Province string `json:"province"` +// StreetNumber *StreetNumberInfo `json:"streetNumber"` +// Towncode string `json:"towncode"` +// Township string `json:"township"` +//} +// +//type RegeoCodeInfo struct { +// AddressComponent *AddressComponentInfo `json:"addressComponent"` +// Aois []*AoiInfo `json:"aois"` +// FormattedAddress string `json:"formatted_address"` +// Pois []*PoiInfo `json:"pois"` +// Roadinters []*RoadinterInfo `json:"roadinters"` +// 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 { +// curConfig = *config[0] +// } +// return &API{ +// key: key, +// client: &http.Client{Timeout: curConfig.ClientTimeout}, +// config: &curConfig, +// } +//} +// +//func (a *API) signParams(mapData map[string]interface{}) string { +// keys := make([]string, 0) +// for k := range mapData { +// if k != signKey { +// keys = append(keys, k) +// } +// } +// sort.Strings(keys) +// +// finalStr := "" +// for _, k := range keys { +// finalStr += k + "=" + fmt.Sprint(mapData[k]) +// } +// +// return fmt.Sprintf("%X", md5.Sum([]byte(finalStr))) +//} +// +//func coordinate2String(lng, lat float64) (str string) { +// return fmt.Sprintf("%.6f,%.6f", lng, lat) +//} +// +//func (a *API) AccessAPI(apiStr string, params map[string]interface{}) (retVal ResponseResult, err error) { +// params2 := utils.MergeMaps(utils.Params2Map("key", a.key, "output", "json"), params) +// params2[signKey] = a.signParams(params2) +// +// err = platformapi.AccessPlatformAPIWithRetry(a.client, +// func() *http.Request { +// request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURLFullv3, 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 := jsonResult1["status"].(string) +// if status == StatusCodeSuccess { +// retVal = jsonResult1 +// return platformapi.ErrLevelSuccess, nil +// } +// infoCode := jsonResult1["infocode"].(string) +// newErr := utils.NewErrorCode(jsonResult1["info"].(string), infoCode) +// if _, ok := exceedLimitCodes[infoCode]; ok { +// return platformapi.ErrLevelExceedLimit, newErr +// } else if _, ok := canRetryCodes[infoCode]; ok { +// return platformapi.ErrLevelRecoverableErr, newErr +// } else { +// return platformapi.ErrLevelCodeIsNotOK, newErr +// } +// }) +// return retVal, err +//} +// +//func (a *API) AccessAPI3(apiStr string, params map[string]interface{}) (retVal ResponseResult, err error) { +// err = platformapi.AccessPlatformAPIWithRetry(a.client, +// func() *http.Request { +// request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(BaseUrl, apiStr, params), 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 := jsonResult1["status"].(string) +// if status == StatusCodeSuccess { +// retVal = jsonResult1 +// return platformapi.ErrLevelSuccess, nil +// } +// infoCode := jsonResult1["infocode"].(string) +// newErr := utils.NewErrorCode(jsonResult1["info"].(string), infoCode) +// if _, ok := exceedLimitCodes[infoCode]; ok { +// return platformapi.ErrLevelExceedLimit, newErr +// } else if _, ok := canRetryCodes[infoCode]; ok { +// return platformapi.ErrLevelRecoverableErr, newErr +// } else { +// return platformapi.ErrLevelCodeIsNotOK, newErr +// } +// }) +// 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{ // &Coordinate{ // Lng: lng, @@ -409,33 +408,6 @@ func (a *API) CoordinateConvert(lng, lat float64, coordsys string) (retLng, retL return lng, lat, err } -func (a *API) BatchCoordinateConvert(coords []*Coordinate, coordsys string) (outCoords []*Coordinate, err error) { - if coordsys == "" || coordsys == CoordSysAutonavi { - return coords, nil - } - var coordsStrList []string - for _, v := range coords { - coordsStrList = append(coordsStrList, coordinate2String(v.Lng, v.Lat)) - } - params := map[string]interface{}{ - "locations": strings.Join(coordsStrList, "|"), - "coordsys": coordsys, - } - result, err := a.AccessAPI("assistant/coordinate/convert", params) - if err == nil { - coordinate := result["locations"].(string) - retCoordsStrList := strings.Split(coordinate, ";") - for _, v := range retCoordsStrList { - pair := strings.Split(v, ",") - outCoords = append(outCoords, &Coordinate{ - Lng: utils.Str2Float64(pair[0]), - Lat: utils.Str2Float64(pair[1]), - }) - } - } - return outCoords, err -} - func (a *API) GetCoordinateFromAddress(address string, cityInfo string) (lng, lat float64, districtCode int) { params := map[string]interface{}{ "address": address, @@ -486,6 +458,19 @@ func (a *API) GetCoordinateFromAddressAll(address string, cityInfo string) (getC return getCoordinateFromAddressByPageAllResult, err } +func (a *API) GeoCodeRegeoSingle(lng, lat float64, radius int, isExt bool, poiTypes []string, roadLevel, homeOrCorp int) (coordInfo *RegeoCodeInfo, err error) { + coordInfoList, err := a.GeoCodeRegeo([]*Coordinate{ + &Coordinate{ + Lng: lng, + Lat: lat, + }, + }, radius, isExt, poiTypes, roadLevel, homeOrCorp) + if err == nil { + coordInfo = coordInfoList[0] + } + return coordInfo, err +} + func (a *API) GeoCodeRegeo(coords []*Coordinate, radius int, isExt bool, poiTypes []string, roadLevel, homeOrCorp int) (coordInfoList []*RegeoCodeInfo, err error) { coordStrList := make([]string, len(coords)) for k, v := range coords { @@ -520,21 +505,99 @@ func (a *API) GeoCodeRegeo(coords []*Coordinate, radius int, isExt bool, poiType return coordInfoList, err } -func (a *API) GeoCodeRegeoSingle(lng, lat float64, radius int, isExt bool, poiTypes []string, roadLevel, homeOrCorp int) (coordInfo *RegeoCodeInfo, err error) { - coordInfoList, err := a.GeoCodeRegeo([]*Coordinate{ - &Coordinate{ - Lng: lng, - Lat: lat, - }, - }, radius, isExt, poiTypes, roadLevel, homeOrCorp) - if err == nil { - coordInfo = coordInfoList[0] +// 这里的District指的是地点,不是实际上的区,具体级别看level +// 这个函数返回的可能不是同级别的地点 +func (a *API) GetDistricts(subDistrict int, keywords string) (districtList []*District, err error) { + params := map[string]interface{}{ + "subdistrict": subDistrict, } - return coordInfo, err + if keywords != "" { + params["keywords"] = keywords + } + + result, err := a.AccessAPI("config/district", params) + if err == nil { + return a.getDistrictsFromInterface(result["districts"]), nil + } + return nil, err } +func (a *API) getDistrictsFromInterface(districts interface{}) (districtList []*District) { + if districts != nil { + districts2 := districts.([]interface{}) + districtList = make([]*District, len(districts2)) + for k, v := range districts2 { + v2 := v.(map[string]interface{}) + districtList[k] = &District{ + Adcode: utils.Interface2String(v2["adcode"]), + Name: utils.Interface2String(v2["name"]), + Level: GetDistrictLevel(utils.Interface2String(v2["level"])), + } + coordStrNodes := strings.Split(utils.Interface2String(v2["center"]), ",") + if len(coordStrNodes) == 2 { + if coordStrNodes[0] != "" && coordStrNodes[1] != "" { + districtList[k].Lng = utils.Str2Float64(coordStrNodes[0]) + districtList[k].Lat = utils.Str2Float64(coordStrNodes[1]) + } + } + if cityCodeStr, ok := v2["citycode"].(string); ok { + districtList[k].CityCode = cityCodeStr + } + districtList[k].Districts = a.getDistrictsFromInterface(v2["districts"]) + } + } + return districtList +} + +func GetDistrictLevel(levelName string) (level int) { + return levelStr2IntMap[levelName] +} +*/ +// 两点之间的步行距离,单位为米 +/*func (a *API) WalkingDistance(lng1, lat1, lng2, lat2 float64) (distance float64) { + params := map[string]interface{}{ + "origin": coordinate2String(lng1, lat1), + "destination": coordinate2String(lng2, lat2), + } + result, err := a.AccessAPI("direction/walking", params) + if err == nil { + if paths, _ := result["route"].(map[string]interface{})["paths"].([]interface{}); len(paths) > 0 { + distance = utils.Interface2Float64WithDefault(paths[0].(map[string]interface{})["distance"], 0) + } + } + 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 +} +*/ +/*-----------------------------------------------------*/ + // 这里的District指的是实际的District,有些市是没有区的,比如东莞,这种情况下返回的区码是一个假的区域,即市的编码加上9000000 -func (a *API) GetCoordinateDistrictCode(lng, lat float64) (districtCode int) { +/*func (a *API) GetCoordinateDistrictCode(lng, lat float64) (districtCode int) { result, err := a.GetCoordinateAreaInfo(lng, lat) if err == nil { addressComponent := result["regeocode"].(map[string]interface{})["addressComponent"].(map[string]interface{}) @@ -588,93 +651,4 @@ func (a *API) GetCoordinateCityInfo(lng, lat float64) (cityName, cityCode string } return cityName, cityCode } - -// 这里的District指的是地点,不是实际上的区,具体级别看level -// 这个函数返回的可能不是同级别的地点 -func (a *API) GetDistricts(subDistrict int, keywords string) (districtList []*District, err error) { - params := map[string]interface{}{ - "subdistrict": subDistrict, - } - if keywords != "" { - params["keywords"] = keywords - } - - result, err := a.AccessAPI("config/district", params) - // baseapi.SugarLogger.Debug(utils.Format4Output(result, false)) - if err == nil { - return a.getDistrictsFromInterface(result["districts"]), nil - } - return nil, err -} - -func (a *API) getDistrictsFromInterface(districts interface{}) (districtList []*District) { - if districts != nil { - districts2 := districts.([]interface{}) - districtList = make([]*District, len(districts2)) - for k, v := range districts2 { - v2 := v.(map[string]interface{}) - districtList[k] = &District{ - Adcode: utils.Interface2String(v2["adcode"]), - Name: utils.Interface2String(v2["name"]), - Level: GetDistrictLevel(utils.Interface2String(v2["level"])), - } - coordStrNodes := strings.Split(utils.Interface2String(v2["center"]), ",") - if len(coordStrNodes) == 2 { - if coordStrNodes[0] != "" && coordStrNodes[1] != "" { - districtList[k].Lng = utils.Str2Float64(coordStrNodes[0]) - districtList[k].Lat = utils.Str2Float64(coordStrNodes[1]) - } - } - if cityCodeStr, ok := v2["citycode"].(string); ok { - districtList[k].CityCode = cityCodeStr - } - districtList[k].Districts = a.getDistrictsFromInterface(v2["districts"]) - } - } - return districtList -} - -func GetDistrictLevel(levelName string) (level int) { - return levelStr2IntMap[levelName] -} - -// 两点之间的步行距离,单位为米 -func (a *API) WalkingDistance(lng1, lat1, lng2, lat2 float64) (distance float64) { - params := map[string]interface{}{ - "origin": coordinate2String(lng1, lat1), - "destination": coordinate2String(lng2, lat2), - } - result, err := a.AccessAPI("direction/walking", params) - if err == nil { - if paths, _ := result["route"].(map[string]interface{})["paths"].([]interface{}); len(paths) > 0 { - distance = utils.Interface2Float64WithDefault(paths[0].(map[string]interface{})["distance"], 0) - } - } - 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 -} +*/ diff --git a/platformapi/autonavi/autonavi_page.go b/platformapi/autonavi/autonavi_page.go index 2c23b8eb..3cfc132c 100644 --- a/platformapi/autonavi/autonavi_page.go +++ b/platformapi/autonavi/autonavi_page.go @@ -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 } +*/ diff --git a/platformapi/autonavi/autonavi_page_test.go b/platformapi/autonavi/autonavi_page_test.go index 18241c01..549eba69 100644 --- a/platformapi/autonavi/autonavi_page_test.go +++ b/platformapi/autonavi/autonavi_page_test.go @@ -1,5 +1,6 @@ package autonavi +/* import ( "testing" @@ -22,3 +23,4 @@ func TestGetCoordinateFromAddressByPageAll(t *testing.T) { } t.Log(utils.Format4Output(result, false)) } +*/ diff --git a/platformapi/autonavi/autonavi_test.go b/platformapi/autonavi/autonavi_test.go index 15756d4d..1361f33b 100644 --- a/platformapi/autonavi/autonavi_test.go +++ b/platformapi/autonavi/autonavi_test.go @@ -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)) } +*/ diff --git a/platformapi/autonavi/gaode_api.go b/platformapi/autonavi/gaode_api.go index 35331147..ea7ad2dd 100644 --- a/platformapi/autonavi/gaode_api.go +++ b/platformapi/autonavi/gaode_api.go @@ -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 } +*/ diff --git a/platformapi/autonavi/gaode_test.go b/platformapi/autonavi/gaode_test.go index 7ae6bb40..4d02c5bb 100644 --- a/platformapi/autonavi/gaode_test.go +++ b/platformapi/autonavi/gaode_test.go @@ -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) } +*/ diff --git a/platformapi/baidunavi/baidunavi.go b/platformapi/baidunavi/baidunavi.go index a3ba577a..5149200c 100644 --- a/platformapi/baidunavi/baidunavi.go +++ b/platformapi/baidunavi/baidunavi.go @@ -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 } +*/ diff --git a/platformapi/baidunavi/baidunavi_model.go b/platformapi/baidunavi/baidunavi_model.go index 713190d7..923b3b2e 100644 --- a/platformapi/baidunavi/baidunavi_model.go +++ b/platformapi/baidunavi/baidunavi_model.go @@ -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"` diff --git a/platformapi/baidunavi/baidunavi_test.go b/platformapi/baidunavi/baidunavi_test.go index ac6040ee..c8dd4378 100644 --- a/platformapi/baidunavi/baidunavi_test.go +++ b/platformapi/baidunavi/baidunavi_test.go @@ -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 diff --git a/platformapi/ebaiapi/shop_sku_test.go b/platformapi/ebaiapi/shop_sku_test.go index ee4a0e04..9a5581d1 100644 --- a/platformapi/ebaiapi/shop_sku_test.go +++ b/platformapi/ebaiapi/shop_sku_test.go @@ -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) { diff --git a/platformapi/jdapi/jdapi_test.go b/platformapi/jdapi/jdapi_test.go index 8b9adbd1..da640e9b 100644 --- a/platformapi/jdapi/jdapi_test.go +++ b/platformapi/jdapi/jdapi_test.go @@ -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") diff --git a/platformapi/jdapi/order_test.go b/platformapi/jdapi/order_test.go index 976ad3ba..640fdd16 100644 --- a/platformapi/jdapi/order_test.go +++ b/platformapi/jdapi/order_test.go @@ -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, }) diff --git a/platformapi/tencent_map/tencent.go b/platformapi/tencent_map/tencent.go new file mode 100644 index 00000000..bb88ace3 --- /dev/null +++ b/platformapi/tencent_map/tencent.go @@ -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 +} diff --git a/platformapi/tencent_map/tencent_api.go b/platformapi/tencent_map/tencent_api.go new file mode 100644 index 00000000..51b1b1fe --- /dev/null +++ b/platformapi/tencent_map/tencent_api.go @@ -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 +} diff --git a/platformapi/tencent_map/tencent_model.go b/platformapi/tencent_map/tencent_model.go new file mode 100644 index 00000000..fee320d2 --- /dev/null +++ b/platformapi/tencent_map/tencent_model.go @@ -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"` +} diff --git a/platformapi/tencent_map/tencent_test.go b/platformapi/tencent_map/tencent_test.go new file mode 100644 index 00000000..36150c34 --- /dev/null +++ b/platformapi/tencent_map/tencent_test.go @@ -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) +} diff --git a/utils/utils.go b/utils/utils.go index a004458b..69852f6d 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -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 ") }