需求
现有一条公路,有公里桩和百米桩对应的经纬度数据;需要根据这个数据得到,输入一个经纬度得到对应的桩号,或者输入一个桩号得到对应的经纬度
实现思路
- 根据原始数据的公里桩和百米桩对应的经纬度数据,打断获取到一米对应一个经纬度,即每米的桩号对应的经纬度
- 根据第一步得到的结果值,编写查询服务接口,输入经纬度得到桩号、输入桩号得到经纬度。
具体实现
var stepNum int32 = 1
func main() {
fileName := "./zh_data_02.csv"
// 读取csv文件
zhDataList := readCSV(fileName)
// 按照一米打断
resultDataList := insertPoint(zhDataList)
//保存成csv文件
saveToFile(resultDataList)
}
- 读取原桩号CSV文件
func readCSV(fileName string) []bean.CsvZHData {
zhDataList := make([]bean.CsvZHData, 0)
fs, err := os.Open(fileName)
if err != nil {
log.Fatalf("can not open the file, err is %+v", err)
}
defer fs.Close()
r := csv.NewReader(fs)
//针对大文件,一行一行的读取文件
for {
row, err := r.Read()
if err != nil && err != io.EOF {
log.Fatalf("can not read, err is %+v", err)
}
if err == io.EOF {
break
}
zhStr := row[0]
lonStr := row[1]
latStr := row[2]
eleStr := row[3]
zh, err := strconv.ParseFloat(zhStr, 64)
lon, err := strconv.ParseFloat(lonStr, 64)
lat, err := strconv.ParseFloat(latStr, 64)
ele, err := strconv.ParseFloat(eleStr, 64)
zhDataList = append(zhDataList, bean.CsvZHData{ZHStr: zhStr, LonStr: lonStr, LatStr: latStr, EleStr: eleStr,
ZH: zh, Lon: lon, Lat: lat, Ele: ele})
}
return zhDataList
}
- 按1米打断
func insertPoint(zhDataList []bean.CsvZHData) []bean.CsvZHData {
resultZHList := make([]bean.CsvZHData, 0)
size := len(zhDataList)
for i := 0; i < size; i++ {
zhPoint := zhDataList[i]
endPoint := bean.CsvZHData{}
if i == (size - 1) {
endPoint = zhDataList[i]
} else {
resultZHList = append(resultZHList, zhPoint)
endPoint = zhDataList[i+1]
}
startLon := zhPoint.Lon
startLat := zhPoint.Lat
startZH := zhPoint.ZH
endLon := endPoint.Lon
endLat := endPoint.Lat
endZH := endPoint.ZH
distance := endZH - startZH
azimuth := mytools.ComputeAzimuth(startLon, startLat, endLon, endLat)
if distance <= 1000 { // 只有百米桩在计算,其他超过1百米情况不计算
for addLen := 0.0; addLen < distance-1; {
addLen = addLen + 1
stepLenKM := addLen / 1000
lonlat := mytools.ConvertDistanceToLogLat(startLon, startLat, stepLenKM, azimuth)
lonlatArr := strings.Split(lonlat, ",")
lon, _ := strconv.ParseFloat(lonlatArr[0], 64)
lat, _ := strconv.ParseFloat(lonlatArr[1], 64)
zh := startZH + addLen
//startLon = lon
//startLat = lat
resultZHList = append(resultZHList, bean.CsvZHData{Lon: lon, Lat: lat, Ele: 0, ZH: zh})
}
} else {
}
//resultZHList = append(resultZHList, endPoint)
}
resultZHList = append(resultZHList, zhDataList[len(zhDataList)-1])
return resultZHList
}
- 保存成CSV
func saveToFile(zhList []bean.CsvZHData) {
OUT_FILE_NAME := "over_zh_data_02.csv"
fileCSV, err := os.OpenFile(OUT_FILE_NAME, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0666)
if err != nil {
log.Fatal(err)
}
// 关闭文件
defer fileCSV.Close()
for _, zhBean := range zhList {
//fileCSV.WriteString(string(result) + "," + "\r\n")
zhStr := strconv.FormatFloat(zhBean.ZH, 'f', -1, 32)
lonStr := strconv.FormatFloat(zhBean.Lon, 'f', -1, 64)
latStr := strconv.FormatFloat(zhBean.Lat, 'f', -1, 64)
eleStr := strconv.FormatFloat(zhBean.Ele, 'f', -1, 64)
fileCSV.WriteString(zhStr + "," + lonStr + "," + latStr + "," + eleStr + "\r\n")
}
}
- 经纬度转桩号服务
router.GET("/tozh", func(c *gin.Context) {
lonStr := c.Query("lon")
latStr := c.Query("lat")
precisionStr := c.Query("precision")
fmt.Println("lon=", lonStr, " lat=", latStr)
resultObj := make(map[string]interface{})
if lonStr == "" || latStr == "" {
resultObj["msg"] = "请传入正确的经纬度!"
resultObj["code"] = 401
c.JSON(200, resultObj)
} else {
lon, err := strconv.ParseFloat(lonStr, 64)
lat, err := strconv.ParseFloat(latStr, 64)
if err != nil {
fmt.Println(err)
}
var precision float64
if precisionStr == "" {
precision = 50
}
zhGJD02 := myConfig.ZH_GJD_02
zhList, _ := myUtils.ReadGJDZH(zhGJD02)
zhBean := myUtils.LonlatToZH(bean.LonLatToZHParamBean{Lon: lon, Lat: lat, Precision: precision}, zhList)
c.JSON(200, zhBean)
}
})
- 桩号转经纬度服务
router.GET("/zhto", func(c *gin.Context) {
zhStr := c.Query("zh")
roadCode := c.Query("roadCode")
resultObj := make(map[string]interface{})
if zhStr == "" {
resultObj["msg"] = "请传入正确的经纬度!"
resultObj["code"] = 401
c.JSON(200, resultObj)
} else {
if roadCode == "" {
roadCode = "G320"
}
zhGJD02 := myConfig.ZH_GJD_02
_, zhMap := myUtils.ReadGJDZH(zhGJD02)
zhint, err := strconv.ParseInt(zhStr, 10, 64)
if err != nil {
fmt.Println(err)
}
lonlatBean := myUtils.ZhToLonLat(bean.ZHToLonLatParamBean{
RoadCode: roadCode,
ZHInt: zhint,
}, zhMap)
c.JSON(200, lonlatBean)
}
})