diff options
Diffstat (limited to 'vendor/github.com/flopp/go-coordsparser/coordsparser.go')
| -rw-r--r-- | vendor/github.com/flopp/go-coordsparser/coordsparser.go | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/vendor/github.com/flopp/go-coordsparser/coordsparser.go b/vendor/github.com/flopp/go-coordsparser/coordsparser.go new file mode 100644 index 0000000..6836892 --- /dev/null +++ b/vendor/github.com/flopp/go-coordsparser/coordsparser.go @@ -0,0 +1,172 @@ +// Copyright 2016 Florian Pigorsch. All rights reserved. +// +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +// Package coordsparser is a library for parsing (geographic) coordinates in various string formats +package coordsparser + +import ( + "fmt" + "regexp" + "strconv" +) + +// Parse parses a coordinate string and returns a lat/lng pair or an error +func Parse(s string) (float64, float64, error) { + lat, lng, err := ParseD(s) + if err == nil { + return lat, lng, nil + } + + lat, lng, err = ParseHD(s) + if err == nil { + return lat, lng, nil + } + + lat, lng, err = ParseHDM(s) + if err == nil { + return lat, lng, nil + } + + lat, lng, err = ParseHDMS(s) + if err == nil { + return lat, lng, nil + } + + return 0, 0, fmt.Errorf("Cannot parse coordinates: %s", s) +} + +// ParseD parses a coordinate string of the form "D.DDDD D.DDDD" and returns a lat/lng pair or an error +func ParseD(s string) (float64, float64, error) { + re := regexp.MustCompile(`^\s*([+-]?[\d\.]+)\s*(,|;|:|\s)\s*([+-]?[\d\.]+)\s*$`) + + matches := re.FindStringSubmatch(s) + if matches == nil { + return 0, 0, fmt.Errorf("Cannot parse 'D' string: %s", s) + } + + lat, err := strconv.ParseFloat(matches[1], 64) + if err != nil || lat < -90 || lat > 90 { + return 0, 0, fmt.Errorf("Cannot parse 'D' string: %s", s) + } + + lng, err := strconv.ParseFloat(matches[3], 64) + if err != nil || lng < -180 || lng > 180 { + return 0, 0, fmt.Errorf("Cannot parse 'D' string: %s", s) + } + + return lat, lng, nil +} + +// ParseHD parses a coordinate string of the form "H D.DDDD H D.DDDD" and returns a lat/lng pair or an error +func ParseHD(s string) (float64, float64, error) { + re := regexp.MustCompile(`^\s*([NnSs])\s*([\d\.]+)\s+([EeWw])\s*([\d\.]+)\s*$`) + + matches := re.FindStringSubmatch(s) + if matches == nil { + return 0, 0, fmt.Errorf("Cannot parse 'HD' string: %s", s) + } + + lat, err := strconv.ParseFloat(matches[2], 64) + if err != nil || lat > 90 { + return 0, 0, fmt.Errorf("Cannot parse 'HD' string: %s", s) + } + if matches[1] == "S" || matches[1] == "s" { + lat = -lat + } + + lng, err := strconv.ParseFloat(matches[4], 64) + if err != nil || lng > 180 { + return 0, 0, fmt.Errorf("Cannot parse 'HD' string: %s", s) + } + if matches[3] == "W" || matches[3] == "w" { + lng = -lng + } + + return lat, lng, nil +} + +// ParseHDM parses a coordinate string of the form "H D M.MMM H D M.MMM" and returns a lat/lng pair or an error +func ParseHDM(s string) (float64, float64, error) { + re := regexp.MustCompile(`^\s*([NnSs])\s*([\d]+)\s+([\d.]+)\s+([EeWw])\s*([\d]+)\s+([\d.]+)\s*$`) + + matches := re.FindStringSubmatch(s) + if matches == nil { + return 0, 0, fmt.Errorf("Cannot parse 'HDM' string: %s", s) + } + + latDeg, err := strconv.ParseFloat(matches[2], 64) + if err != nil || latDeg > 90 { + return 0, 0, fmt.Errorf("Cannot parse 'HDM' string: %s", s) + } + latMin, err := strconv.ParseFloat(matches[3], 64) + if err != nil || latMin >= 60 { + return 0, 0, fmt.Errorf("Cannot parse 'HDM' string: %s", s) + } + lat := latDeg + latMin/60.0 + if matches[1] == "S" || matches[1] == "s" { + lat = -lat + } + + lngDeg, err := strconv.ParseFloat(matches[5], 64) + if err != nil || lngDeg > 180 { + return 0, 0, fmt.Errorf("Cannot parse 'HDM' string: %s", s) + } + lngMin, err := strconv.ParseFloat(matches[6], 64) + if err != nil || lngMin >= 60 { + return 0, 0, fmt.Errorf("Cannot parse 'HDM' string: %s", s) + } + lng := lngDeg + lngMin/60.0 + if matches[4] == "W" || matches[4] == "w" { + lng = -lng + } + + return lat, lng, nil +} + +// ParseHDMS parses a coordinate string of the form "H D M S.SSS H D M S.SSS" and returns a lat/lng pair or an error +func ParseHDMS(s string) (float64, float64, error) { + re := regexp.MustCompile(`^\s*([NnSs])\s*([\d]+)\s+([\d]+)\s+([\d.]+)\s+([EeWw])\s*([\d]+)\s+([\d]+)\s+([\d.]+)\s*$`) + + matches := re.FindStringSubmatch(s) + if matches == nil { + return 0, 0, fmt.Errorf("Cannot parse 'HDMS' string: %s", s) + } + + latDeg, err := strconv.ParseFloat(matches[2], 64) + if err != nil || latDeg > 90 { + return 0, 0, fmt.Errorf("Cannot parse 'HDMS' string: %s", s) + } + latMin, err := strconv.ParseFloat(matches[3], 64) + if err != nil || latMin >= 60 { + return 0, 0, fmt.Errorf("Cannot parse 'HDMS' string: %s", s) + } + latSec, err := strconv.ParseFloat(matches[4], 64) + if err != nil || latSec >= 60 { + return 0, 0, fmt.Errorf("Cannot parse 'HDMS' string: %s", s) + } + lat := latDeg + latMin/60.0 + latSec/3600.0 + if matches[1] == "S" || matches[1] == "s" { + lat = -lat + } + + lngDeg, err := strconv.ParseFloat(matches[6], 64) + if err != nil || lngDeg > 180 { + return 0, 0, fmt.Errorf("Cannot parse 'HDMS' string: %s", s) + } + lngMin, err := strconv.ParseFloat(matches[7], 64) + if err != nil || lngMin >= 60 { + return 0, 0, fmt.Errorf("Cannot parse 'HDMS' string: %s", s) + } + lngSec, err := strconv.ParseFloat(matches[8], 64) + if err != nil || lngSec >= 60 { + return 0, 0, fmt.Errorf("Cannot parse 'HDMS' string: %s", s) + } + lng := lngDeg + lngMin/60.0 + lngSec/3600.0 + if matches[5] == "W" || matches[5] == "w" { + lng = -lng + } + + return lat, lng, nil +} |
