duancai7002
2017-04-15 18:53 阅读 108
已采纳

如何在golang中解析ISO6709坐标?

Some examples from Wikipedia on 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/

What's the way to parse this since there's no consistent delimiting character? Regex? Read and parse it byte by byte?

To clarify: the desired output is a pair of float32 latitude and longitudes. So for e.g:

input: +40.6894-074.0447/
output: 40.6894 and -074.0447

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

1条回答 默认 最新

  • 已采纳
    duanpin2034 duanpin2034 2017-04-15 19:52

    I'm not sure which pieces you would want to extract but the following regex works within your examples to select them all.

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

    It does work it out in pieces, and depends on the last / as being a terminator, though if it isn't there would be other ways around it.

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

    Does not rely on the / terminator.

    To provide a perfect answer, the context of the coordinates would be required.

    here is the code to implement, given a string as input:

    import (
        "fmt"
        "regexp"
    )
    
    func main() {
        toSearch := "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/"
        ISOCoord := regexp.MustCompile(`(\+|-)\d+\.?\d+(\+|-)\d+\.?\d+(\+|-)?[A-Z_\d]*`)
        result := ISOCoord.FindAll([]byte(toSearch), 11)
        for _, v := range result {
            fmt.Printf("%s
    ", v)
        }
    }
    

    returns:

    +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
    

    Given the new idea that you want the 2 sepearate coords, this approch works:

    import (
        "fmt"
        "regexp"
        "strconv"
    )
    
    type coord struct {
        lat, long float64
    }
    
    func main() {
        toSearch := "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/"
        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)
    }
    

    The regex is doubled so that it is a little more robust, but it would be faster to only do it once, if it were possible given the input.

    The code also should have error checking on the conversions, but you can add that.

    Also worth noting that it trims 0's. If you want to maintain those as stated, ie. if 012.1 is not the same as 12.1, you could just leave out the conversion to float and work with the strings.

    Code produces as 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}]
    

    or

    [{+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

    点赞 评论 复制链接分享

相关推荐