This repository has been archived by the owner on Jan 22, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbuoystations.go
130 lines (107 loc) · 3.08 KB
/
buoystations.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package surfnerd
import (
"encoding/json"
"encoding/xml"
"strings"
)
const (
ActiveBuoysURL = "http://www.ndbc.noaa.gov/activestations.xml"
)
// Container to hold all of the buoy locations that are reported by NOAA in their
// active stations xml file. Works as an in
type BuoyStations struct {
XMLName xml.Name `xml:"stations"`
CreationDate string `xml:"created,attr"`
StationCount int `xml:"count,attr"`
Stations []*Buoy `xml:"station"`
}
// Fetch all of the buoy stations in xml format from the NOAA endpoint and parse them into buoy objects.
// Returns true if the buoys were successfully parsed into the Stations variable
func (b *BuoyStations) GetAllActiveBuoyStations() error {
rawStations, dlErr := fetchRawDataFromURL(ActiveBuoysURL)
if dlErr != nil {
return dlErr
}
xml.Unmarshal(rawStations, b)
return nil
}
// Searches the list of buoys linearly to find a buoy matching the given station id.
func (b *BuoyStations) FindBuoyByID(stationID string) *Buoy {
for _, buoy := range b.Stations {
if strings.ToLower(buoy.StationID) == strings.ToLower(stationID) {
return buoy
}
}
return nil
}
// Finds and returns the closest buoy to a given location
// Lat and long should be in relative, not absolute (41.0, -71) not (41.5, 289)
func (b *BuoyStations) FindClosestActiveBuoy(loc Location) *Buoy {
if len(b.Stations) < 1 {
return nil
}
var closestBuoy *Buoy = nil
closestDistance := 9999999999.9
for _, buoy := range b.Stations {
if !buoy.IsBuoyActive() {
continue
}
dist := loc.DistanceTo(*buoy.Location)
if dist < closestDistance {
closestBuoy = buoy
closestDistance = dist
}
}
return closestBuoy
}
// Finds and returns the closest buoy with wave data to a given location
// Lat and long should be in relative, not absolute (41.0, -71) not (41.5, 289)
func (b *BuoyStations) FindClosestActiveWaveBuoy(loc Location) *Buoy {
if len(b.Stations) < 1 {
return nil
}
var closestBuoy *Buoy = nil
closestDistance := 9999999999.9
for _, buoy := range b.Stations {
if !buoy.IsBuoyActive() {
continue
} else if buoy.Type != "buoy" {
continue
}
dist := loc.DistanceTo(*buoy.Location)
if dist < closestDistance {
closestBuoy = buoy
closestDistance = dist
}
}
return closestBuoy
}
// Finds and returns the 3 closest buoys with wave data to a given location
// Lat and long should be in relative, not absolute (41.0, -71) not (41.5, 289)
func (b *BuoyStations) FindClosestActiveWaveBuoys(loc Location) []*Buoy {
if len(b.Stations) < 1 {
return nil
}
closestBuoys := make([]*Buoy, 3, 3)
closestDistances := [...]float64{9999999.999, 9999999.999, 9999999.999}
for _, buoy := range b.Stations {
if !buoy.IsBuoyActive() {
continue
} else if buoy.Type != "buoy" {
continue
}
dist := loc.DistanceTo(*buoy.Location)
for i := 0; i < 3; i++ {
if dist < closestDistances[i] {
closestBuoys[i] = buoy
closestDistances[i] = dist
break
}
}
}
return closestBuoys
}
// Convert a Buoy object to a json formatted string
func (b *BuoyStations) ToJSON() ([]byte, error) {
return json.MarshalIndent(b, "", " ")
}