-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathcoordinates.go
91 lines (77 loc) · 2.5 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
// Copyright (c) 2015, Marios Andreopoulos.
//
// This file is part of aislib.
//
// Aislib is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Aislib is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with aislib. If not, see <http://www.gnu.org/licenses/>.
package aislib
import (
"fmt"
"math"
)
// CoordinatesMin2Deg translates coordinates (lon, lat) in decimal minutes (×10^4) to decimal degrees.
// AIS data use decimal minutes but decimal degrees (DD) is a more universal format and easier to
// handle. Almost every third party asks for this format.
func CoordinatesMin2Deg(minLon, minLat float64) (float64, float64) {
lonSign := 1.0
latSign := 1.0
if math.Signbit(minLon) {
minLon = -minLon
lonSign = -1
}
if math.Signbit(minLat) {
minLat = -minLat
latSign = -1
}
degrees := float64(int(minLon / 600000))
minutes := float64(minLon-600000*degrees) / 10000
lon := degrees + minutes/60
degrees = float64(int(minLat / 600000))
minutes = float64(minLat-600000*degrees) / 10000
lat := degrees + minutes/60
return lonSign * lon, latSign * lat
}
// CoordinatesDeg2Human takes coordinates (lon, lat) in decimal degrees (DD),
// formats them as degrees minutes and returns them as string.
func CoordinatesDeg2Human(degLon, degLat float64) string {
lonSign := 1.0
latSign := 1.0
coordinates := ""
if math.Signbit(degLon) {
degLon = -degLon
lonSign = -1
}
if math.Signbit(degLat) {
degLat = -degLat
latSign = -1
}
degrees := math.Floor(degLon)
minutes := 60 * (degLon - degrees)
if degrees > 180 {
coordinates = "longitude not available, "
} else if lonSign > 0 {
coordinates = fmt.Sprintf("%3.0f°%07.4f'%s", degrees, minutes, "E")
} else {
coordinates = fmt.Sprintf("%3.0f°%07.4f'%s", degrees, minutes, "W")
}
degrees = math.Floor(degLat)
minutes = 60 * (degLat - degrees)
if degrees > 90 {
coordinates += "latitude not available"
} else if latSign > 0 {
coordinates += fmt.Sprintf(" %3.0f°%07.4f%s", degrees, minutes, "N")
} else {
coordinates += fmt.Sprintf(" %3.0f°%07.4f%s", degrees, minutes, "S")
}
return coordinates
}