63 lines
1.5 KiB
Go
63 lines
1.5 KiB
Go
package gogeouri
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type Geo struct {
|
|
Latitude, Longitude, Altitude float64
|
|
Parameters map[string][]string
|
|
}
|
|
|
|
const scheme = "geo"
|
|
|
|
func Parse(uri string) (*Geo, error) {
|
|
g := &Geo{
|
|
Parameters: map[string][]string{},
|
|
}
|
|
if !strings.HasPrefix(uri, scheme+":") {
|
|
return nil, errors.New("no or wrong scheme")
|
|
}
|
|
uri = strings.TrimPrefix(uri, scheme+":")
|
|
uriParts := strings.Split(uri, ";")
|
|
if len(strings.TrimSpace(uriParts[0])) < 1 {
|
|
return nil, errors.New("empty path")
|
|
}
|
|
coords := strings.Split(uriParts[0], ",")
|
|
if l := len(coords); l < 2 || l > 3 {
|
|
return nil, errors.New("wrong number of coordinates")
|
|
}
|
|
if f, e := strconv.ParseFloat(coords[0], 64); e == nil {
|
|
g.Latitude = f
|
|
} else {
|
|
return nil, errors.New("can't parse latitude")
|
|
}
|
|
if f, e := strconv.ParseFloat(coords[1], 64); e == nil {
|
|
g.Longitude = f
|
|
} else {
|
|
return nil, errors.New("can't parse longitude")
|
|
}
|
|
if len(coords) == 3 {
|
|
if f, e := strconv.ParseFloat(coords[2], 64); e == nil {
|
|
g.Altitude = f
|
|
} else {
|
|
return nil, errors.New("can't parse altitude")
|
|
}
|
|
}
|
|
for _, p := range uriParts[1:] {
|
|
pParts := strings.Split(p, "=")
|
|
if l := len(pParts); l == 1 {
|
|
if _, ok := g.Parameters[pParts[0]]; !ok {
|
|
g.Parameters[pParts[0]] = []string{}
|
|
}
|
|
} else if l == 2 {
|
|
g.Parameters[pParts[0]] = append(g.Parameters[pParts[0]], pParts[1])
|
|
} else {
|
|
return nil, errors.New("wrong parameter")
|
|
}
|
|
}
|
|
return g, nil
|
|
}
|