Files
jx-callback/business/jxutils/ditu/ditu.go
2024-07-31 11:09:07 +08:00

160 lines
5.3 KiB
Go

package ditu
import (
"git.rosy.net.cn/baseapi/platformapi/tencent_map"
"git.rosy.net.cn/jx-callback/business/model/dao"
"math"
"strings"
"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)
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) {
place, err := dao.GetPlaces(dao.GetDB(), []int{cityCode})
if err != nil {
return nil
}
districts, err := api.TencentMapAPI.GetDistricts(2, utils.Int2Str(cityCode), int(place[0].Level+1))
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 *tencent_map.District) bool {
for _, v := range []string{"街道", "镇"} {
if strings.Index(place.Name, v) >= 0 {
return true
}
}
return false
}
func getDistrictCoordinateList(districtList []*tencent_map.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
}
// 老版本
//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
//}