Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1292702
  • 博文数量: 79
  • 博客积分: 1959
  • 博客等级: 上尉
  • 技术积分: 2719
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-19 12:07
个人简介

樽中酒不空

文章分类

全部博文(79)

文章存档

2024年(3)

2020年(4)

2019年(1)

2017年(2)

2016年(2)

2015年(7)

2014年(11)

2013年(13)

2012年(18)

2011年(2)

2010年(16)

分类: C/C++

2024-11-07 17:35:18

初学Go, 项目使用Go配置地图信息,使用JSON文件配置的。在解析时发现Go对JSON支持的不是很方便,绕了一点弯路完成,顺手记录一下,或许以后还用的到。当然如果引入第三方包会方便很多。
JSON文件结构大致是这样的:
[
{
"channel": 1,
"colorbegin": 11730812,
"colorend": 11730812,
"fiber_pos": 0,
"index": 1,
"latitude": 37.69512581,
"longitude": 121.03210634,
"mark_name": "YK001",
"physical_pos": 0
},
{
"channel": 1,
"colorbegin": 11730812,
"colorend": 11730812,
"fiber_pos": 174,
"index": 2,
"latitude": 37.69453029,
"longitude": 121.03057064,
"mark_name": "YK002",
"physical_pos": 174
}
]
从文件顺序读出数据来,按顺序对index赋值,然后根据经纬度计算每个点距离起点的位置。

大致DEMO代码如下:


func readJson(file string) error {

    content, err := os.ReadFile(file)
    if err != nil {
        return err
    }

    fmt.Println("file size is ", len(content))

    var data []map[string]interface{}
    if err := json.Unmarshal(content, &data); err != nil {
        fmt.Println(err)
        return err
    }
    fmt.Printf("data :%d,  %+v \n", len(data), data[0])

    //新json数组
    var newDataArray []map[string]interface{}
    var distance int32
    var lastLng float64
    var lastLan float64
    distance = 0
    lastLng = 0
    lastLan = 0

    for i := 0; i < len(data); i++ {
        newData := map[string]interface{}{}
        for k, v := range data[i] {
            newData[k] = v
        if i == 0 {
            distance = 0
            newData["index"] = i + 1
            newData["physical_pos"] = distance
            newData["fiber_pos"] = distance

            lastLng = newData["latitude"].(float64)
            lastLan = newData["longitude"].(float64)

            newDataArray = append(newDataArray, newData)
        } else {
            f1 := newData["latitude"].(float64)
            f2 := newData["longitude"].(float64)


            temp := calculateDistance(f1, f2, lastLng, lastLan)
            distance += temp
            lastLng = f1
            lastLan = f2
            newData["index"] = i + 1
            newData["physical_pos"] = distance
            newData["fiber_pos"] = distance
            newDataArray = append(newDataArray, newData)
        }
    }

    t, err := json.MarshalIndent(newDataArray, "", "\t")
    if err != nil {
        fmt.Println(err)
        return err
    }

    f2, err2 := os.Create("e:/visualmark2.ini")
    if err2 != nil {
        fmt.Println(err2)
        return err2
    }
    w := bufio.NewWriter(f2)
    w.WriteString(string(t))
    w.Flush()

    return err

}

重点在这一句:
var data []map[string]interface{}
if err := json.Unmarshal(content&data); err != nil {
        fmt.Println(err)
        return err
}
这样解析出来的是JSON数组。
然后数组的每一个元素:
  newData := map[string]interface{}{}

 for kv := range data[i] {
            newData[k= v


这样是把原来数组的元素赋值给新的元素。

再重新索引和计算坐标。
再把数组重新转成json,每个数组元素后都可以换行:
terr := json.MarshalIndent(newDataArray"""\t")

写到文件里。
里面有个计算两点间距的函数,网上有很多例子,我这里简单实现,误差比较大,用在地图展示还勉强:



const M_PI = 3.14159265358979323846

func calculateDistance(long1 float64, lat1 float64, long2 float64, lat2 float64) int32 {
    var a, b, R float64
    R = 6378137 // 地球半径
    lat1 = lat1 * M_PI / 180.0
    lat2 = lat2 * M_PI / 180.0
    a = lat1 - lat2
    b = (long1 - long2) * M_PI / 180.0
    var sa2, sb2 float64
    sa2 = math.Sin(a / 2.0)
    sb2 = math.Sin(b / 2.0)
    distance := 2 * R * math.Asin(math.Sqrt(sa2*sa2+math.Cos(lat1)*math.Cos(lat2)*sb2*sb2))
    return int32(distance)
}

短时间使用Go写了个小工具,感觉还是很不错的,和Python接近,某些方面不如Python方便,主要是对第三库还不熟悉。不过在TCP和HTTP服务方面要好的多,下一步准备把几个轻量级的C++ TCP服务使用Go重新实现一下。之前是使用POCO库实现的,使用起来也很简单,不过考虑GO做分布式服务和云服务更方便, 后期新项目准备使用Go。



阅读(63) | 评论(0) | 转发(0) |
0

上一篇:基于poco的小型http服务器

下一篇:没有了

给主人留下些什么吧!~~