GIS经纬度转桩号工具

需求

现有一条公路,有公里桩和百米桩对应的经纬度数据;需要根据这个数据得到,输入一个经纬度得到对应的桩号,或者输入一个桩号得到对应的经纬度

实现思路

  1. 根据原始数据的公里桩和百米桩对应的经纬度数据,打断获取到一米对应一个经纬度,即每米的桩号对应的经纬度
  2. 根据第一步得到的结果值,编写查询服务接口,输入经纬度得到桩号、输入桩号得到经纬度。

具体实现

go 复制代码
var stepNum int32 = 1

func main() {
   fileName := "./zh_data_02.csv"
   // 读取csv文件
   zhDataList := readCSV(fileName)
   // 按照一米打断
   resultDataList := insertPoint(zhDataList)
   //保存成csv文件
   saveToFile(resultDataList)

}
  • 读取原桩号CSV文件
go 复制代码
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米打断
go 复制代码
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
go 复制代码
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")

   }
}
  • 经纬度转桩号服务
go 复制代码
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)
   }

})
  • 桩号转经纬度服务
go 复制代码
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)
   }

})

最终编译成的工具

工具下载

相关推荐
垚垚学技术_聚焦云原生1 小时前
K8s Pod 完整生命周期详解
后端
JavaGuide1 小时前
Github 史诗级故障,与此同时,Cursor 版「GitHub」正式上线!
前端·后端
不一样的少年_1 小时前
修了 Bug、做了重构,为什么老板还是觉得你没产出?
前端·后端·程序员
水深火乐1 小时前
安全地生成验证码、密码和 Token
后端
小强19881 小时前
SQL Server 慢查询怎么定位?一套从“卡”到“快”的完整排查流程
后端
水深火乐1 小时前
interface和any
后端
步行cgn1 小时前
MyBatis Error evaluating expression ‘ids‘. Return value (3) was not iterable 错误详
java·后端
神奇小汤圆1 小时前
Spring Boot + LangChain4j实现RAG——从零搭建企业级知识库问答系统
后端
H_Peak2 小时前
Python运算符与流程控制:if条件判断
后端
H_Peak2 小时前
Python字符串操作:从基础到正则入门
后端