package ditu import ( "math" "strings" "git.rosy.net.cn/baseapi/platformapi/autonavi" "git.rosy.net.cn/baseapi/utils" "git.rosy.net.cn/jx-callback/business/jxutils" "git.rosy.net.cn/jx-callback/globals/api" ) const ( keyMultiple = 1000000 ) type Coordinate struct { Lng float64 Lat float64 } func roundCoordinate(lng, lat float64, roundLng, roundLat int) (lng2, lat2 int) { lng2 = jxutils.StandardCoordinate2Int(lng+jxutils.IntCoordinate2Standard(roundLng)/2) / roundLng * roundLng lat2 = jxutils.StandardCoordinate2Int(lat+jxutils.IntCoordinate2Standard(roundLat)/2) / roundLat * roundLat return lng2, lat2 } func (c *Coordinate) GetMapKey() int64 { return int64(c.Lng*keyMultiple*keyMultiple + c.Lat*keyMultiple) } func GetRound4Radius(lng, lat float64, gridWith int) (roundLng, roundLat int) { lng2, _ := jxutils.ConvertDistanceToLogLat(lng, lat, float64(gridWith), 90) _, lat2 := jxutils.ConvertDistanceToLogLat(lng, lat, float64(gridWith), 0) // globals.SugarLogger.Debugf("GetRound4Radius gridWith:%d, lng:%f, lat:%f, lng2:%f, lat2:%f", gridWith, lng, lat, lng2, lat2) return jxutils.StandardCoordinate2Int(math.Abs(lng2 - lng)), jxutils.StandardCoordinate2Int(math.Abs(lat2 - lat)) } func GetGridsFromCoordinate(lng, lat float64, radius int, roundLng, roundLat int) (coordList []*Coordinate) { if lng != 0 && lat != 0 { beginLng, _ := jxutils.ConvertDistanceToLogLat(lng, lat, float64(radius), 270) _, beginLat := jxutils.ConvertDistanceToLogLat(lng, lat, float64(radius), 180) intBeginLng, intBeginLat := roundCoordinate(beginLng, beginLat, roundLng, roundLat) endLng, _ := jxutils.ConvertDistanceToLogLat(lng, lat, float64(radius), 90) _, endLat := jxutils.ConvertDistanceToLogLat(lng, lat, float64(radius), 0) intEndLng, intEndLat := roundCoordinate(endLng, endLat, roundLng, roundLat) for intLng := intBeginLng; intLng <= intEndLng; intLng += roundLng { for intLat := intBeginLat; intLat <= intEndLat; intLat += roundLat { coordList = append(coordList, &Coordinate{ Lng: jxutils.IntCoordinate2Standard(intLng), Lat: jxutils.IntCoordinate2Standard(intLat), }) } } } return coordList } func GetDistrictCoordinateList(districtCode int, radius, gridWith int) (coordList []*Coordinate) { districts, err := api.AutonaviAPI.GetDistricts(1, utils.Int2Str(districtCode)) if err == nil { if len(districts) > 0 { roundLng, roundLat := GetRound4Radius(districts[0].Lng, districts[0].Lat, gridWith) tmpCoordList := getDistrictCoordinateList(districts, radius, gridWith, roundLng, roundLat) if len(tmpCoordList) > 0 { coordList = append(coordList, &Coordinate{ Lng: districts[0].Lng, Lat: districts[0].Lat, }) coordList = append(coordList, tmpCoordList...) } } } return coordList } func GetCityCoordinateList(cityCode int, radius, gridWith int) (coordList []*Coordinate) { districts, err := api.AutonaviAPI.GetDistricts(2, utils.Int2Str(cityCode)) if err == nil { if len(districts) > 0 { roundLng, roundLat := GetRound4Radius(districts[0].Lng, districts[0].Lat, gridWith) tmpCoordList := getDistrictCoordinateList(districts, radius, gridWith, roundLng, roundLat) if len(tmpCoordList) > 0 { coordList = append(coordList, &Coordinate{ Lng: districts[0].Lng, Lat: districts[0].Lat, }) coordList = append(coordList, tmpCoordList...) } } } return coordList } func needCheckTown(place *autonavi.District) bool { for _, v := range []string{"街道", "镇"} { if strings.Index(place.Name, v) >= 0 { return true } } return false } func getDistrictCoordinateList(districtList []*autonavi.District, radius, gridWith, roundLng, roundLat int) (coordList []*Coordinate) { coordMap := make(map[int64]*Coordinate) for _, v := range districtList { if (v.Level <= 3 || (v.Level == 4 && needCheckTown(v))) && v.Lng != 0 && v.Lat != 0 { realRadius := radius if v.Level == 2 { realRadius = 2 * radius } else if v.Level == 2 { realRadius = radius / 2 } tmpCoordList := GetGridsFromCoordinate(v.Lng, v.Lat, realRadius, roundLng, roundLat) if v.Level <= 3 { tmpCoordList = append(tmpCoordList, getDistrictCoordinateList(v.Districts, radius, gridWith, roundLng, roundLat)...) } for _, coord := range tmpCoordList { coordMap[coord.GetMapKey()] = coord } } } for _, coord := range coordMap { coordList = append(coordList, coord) } return coordList }