-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcoordinates.go
108 lines (92 loc) · 2.35 KB
/
coordinates.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package osgb
import (
"fmt"
"math"
)
const (
degreeInRadians = 180 / math.Pi
radianInDegrees = 1 / degreeInRadians
)
type direction string
const (
north direction = "N"
south direction = "S"
east direction = "E"
west direction = "W"
)
// ETRS89Coordinate represents a coordinate position in
// the ETRS89 geodetic datum. Whilst not being identical
// this can be treated as a GPS coordinate.
type ETRS89Coordinate struct {
// Longitude in decimal degrees
Lon float64
// Latitude in decimal degrees
Lat float64
// Height in metres
Height float64
}
// NewETRS89Coord creates a new coordinate position in the ETRS89 geodetic datum.
func NewETRS89Coord(lon, lat, height float64) *ETRS89Coordinate {
return &ETRS89Coordinate{
Lon: lon,
Lat: lat,
Height: height,
}
}
// OSGB36Coordinate represents a coordinate position in
// the OSGB36/ODN geodetic datum.
type OSGB36Coordinate struct {
// Easting in metres
Easting float64
// Northing in metres
Northing float64
// Height in metres
Height float64
}
// NewOSGB36Coord creates a new coordinate position in the OSGB36/ODN geodetic datum.
func NewOSGB36Coord(easting, northing, height float64) *OSGB36Coordinate {
return &OSGB36Coordinate{
Easting: easting,
Northing: northing,
Height: height,
}
}
type geographicCoord struct {
lat, lon, height float64
}
type cartesianCoord struct {
x, y, z float64
}
type planeCoord struct {
easting, northing float64
}
func dmsToDecimal(degrees, minutes, seconds float64, direction direction) (float64, error) {
if direction == "N" || direction == "S" {
if degrees < 0 || degrees > 90 {
return 0, fmt.Errorf("invalid latitude degrees %f", degrees)
}
} else if direction == "E" || direction == "W" {
if degrees < 0 || degrees > 180 {
return 0, fmt.Errorf("invalid longitude degrees %f", degrees)
}
} else {
return 0, fmt.Errorf("invalid direction %s", direction)
}
if minutes < 0 || minutes > 60 {
return 0, fmt.Errorf("invalid minutes %f", minutes)
}
if seconds < 0 || seconds > 60 {
return 0, fmt.Errorf("invalid secondss %f", seconds)
}
rad := (degrees + minutes/60 + seconds/3600)
if direction == "N" || direction == "E" {
return rad, nil
}
return rad * -1, nil
}
func radiansToDegrees(rad float64) float64 {
return rad * degreeInRadians
}
func degreesToRadians(degrees float64) float64 {
return degrees * radianInDegrees
}