如何在golang中解析ISO6709坐标?

时间:2017-04-15 18:53:43

标签: go

来自维基百科的ISO 6709的一些例子:

Atlantic Ocean +00-025/
France +46+002/
Paris +48.52+002.20/
Eiffel Tower +48.8577+002.295/
Mount Everest +27.5916+086.5640+8850CRSWGS_84/
North Pole +90+000/
Pacific Ocean +00-160/
South Pole -90+000+2800CRSWGS_84/
United States +38-097/
New York City +40.75-074.00/
Statue of Liberty +40.6894-074.0447/

解析这个问题的方法是什么,因为没有一致的分隔符?正则表达式?逐字节读取并解析它?

澄清:所需的输出是一对float32纬度和经度。所以对于例如:

输入:+ 40.6894-074.0447 /
输出:40.6894和-074.0447

1 个答案:

答案 0 :(得分:2)

我不确定您想要提取哪些部分,但以下正则表达式适用于您的示例中以便全部选择它们。

(\+|-)\d+\.?\d+(\+|-)\d+\.?[\d]+(\+|-)?[^/]*

它确实可以分解,并且取决于最后一个/作为终结者,但如果它没有其他方法可以解决它。

(\+|-)\d+\.?\d+(\+|-)\d+\.?\d+(\+|-)?[A-Z_\d]*

不依赖于/终止符。

为了提供完美的答案,需要坐标的上下文。

这是要实现的代码,给定一个字符串作为输入:

import (
    "fmt"
    "regexp"
)

func main() {
    toSearch := "Atlantic Ocean +00-025/\nFrance +46+002/\nParis +48.52+002.20/\nEiffel Tower +48.8577+002.295/\nMount Everest +27.5916+086.5640+8850CRSWGS_84/\nNorth Pole +90+000/\nPacific Ocean +00-160/\nSouth Pole -90+000+2800CRSWGS_84/\nUnited States +38-097/\nNew York City +40.75-074.00/\nStatue of Liberty +40.6894-074.0447/"
    ISOCoord := regexp.MustCompile(`(\+|-)\d+\.?\d+(\+|-)\d+\.?\d+(\+|-)?[A-Z_\d]*`)
    result := ISOCoord.FindAll([]byte(toSearch), 11)
    for _, v := range result {
        fmt.Printf("%s\n", v)
    }
}

返回:

+00-025
+46+002
+48.52+002.20
+48.8577+002.295
+27.5916+086.5640+8850CRSWGS_84
+90+000
+00-160
-90+000+2800CRSWGS_84
+38-097
+40.75-074.00
+40.6894-074.0447

鉴于你想要2个单独的coords的新想法,这个approch工作:

import (
    "fmt"
    "regexp"
    "strconv"
)

type coord struct {
    lat, long float64
}

func main() {
    toSearch := "Atlantic Ocean +00-025/\nFrance +46+002/\nParis +48.52+002.20/\nEiffel Tower +48.8577+002.295/\nMount Everest +27.5916+086.5640+8850CRSWGS_84/\nNorth Pole +90+000/\nPacific Ocean +00-160/\nSouth Pole -90+000+2800CRSWGS_84/\nUnited States +38-097/\nNew York City +40.75-074.00/\nStatue of Liberty +40.6894-074.0447/"
    ISOCoord := regexp.MustCompile(`((\+|-)\d+\.?\d*){2}`)
    result := ISOCoord.FindAllString(toSearch, -1)
    INDCoord := regexp.MustCompile(`(\+|-)\d+\.?\d*`)
    answer := make([]coord, 11)

    for i, v := range result {
        temp := INDCoord.FindAllString(v, 2)
        lat, _ := strconv.ParseFloat(temp[0], 64)
        lon, _ := strconv.ParseFloat(temp[1], 64)
        answer[i] = coord{lat, lon}
    }
    fmt.Println(answer)
}

正则表达式加倍,因此它更加健壮,但如果可以给出输入,那么只执行一次会更快。

代码也应该对转换进行错误检查,但您可以添加它。

另外值得注意的是它减少了0。如果你想保持那些陈述,即。如果012.1与12.1不同,你可以省略转换为float并使用字符串。

代码生成为float:

[{0 -25} {46 2} {48.52 2.2} {48.8577 2.295} {27.5916 86.564} {90 0} {0 -160} {-90 0} {38 -97} {40.75 -74} {40.6894 -74.0447}]

[{+00 -025} {+46 +002} {+48.52 +002.20} {+48.8577 +002.295} {+27.5916 +086.5640} {+90 +000} {+00 -160} {-90 +000} {+38 -097} {+40.75 -074.00} {+40.6894 -074.0447}]

as string