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 pathwaveforecast.go
137 lines (116 loc) · 5.01 KB
/
waveforecast.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
131
132
133
134
135
136
137
package surfnerd
import (
"encoding/json"
"io/ioutil"
"time"
)
// Container holding a complete WaveWatch forecast with the location, model description, run time, and
// a list of WaveForecastItems holding the data for each timestep. This is more useful for specific front-end
// applications than ModelData because the data map has been parsed into descriptive types. The underlying data is the same however.
type WaveForecast struct {
Location
Model NOAAModel
ForecastData []WaveForecastItem
}
// Converts all of the objects to a given unit system
func (w *WaveForecast) ChangeUnits(newUnits UnitSystem) {
if w.Model.Units == newUnits {
return
}
for index, _ := range w.ForecastData {
(&w.ForecastData[index]).ChangeUnits(newUnits)
}
w.Model.Units = newUnits
}
// Convert Forecast object to a json formatted string
func (w *WaveForecast) ToJSON() ([]byte, error) {
return json.MarshalIndent(w, "", " ")
}
// Export a Forecast object to json file with a given filename
func (w *WaveForecast) ExportAsJSON(filename string) error {
jsonData, jsonErr := w.ToJSON()
if jsonErr != nil {
return jsonErr
}
fileErr := ioutil.WriteFile(filename, jsonData, 0644)
return fileErr
}
// Convert the WaveForecast object into a ModelData container. Usefult for converting to
// a more plottable format
func (w *WaveForecast) ToModelData() *ModelData {
dataCount := len(w.ForecastData)
// Create and initialize the map with the correct variables
dataMap := ModelDataMap{}
dataMap["htsgwsfc"] = make([]float64, dataCount)
dataMap["dirpwsfc"] = make([]float64, dataCount)
dataMap["perpwsfc"] = make([]float64, dataCount)
dataMap["swell_1"] = make([]float64, dataCount)
dataMap["swdir_1"] = make([]float64, dataCount)
dataMap["swper_1"] = make([]float64, dataCount)
dataMap["swell_2"] = make([]float64, dataCount)
dataMap["swdir_2"] = make([]float64, dataCount)
dataMap["swper_2"] = make([]float64, dataCount)
dataMap["wvhgtsfc"] = make([]float64, dataCount)
dataMap["wvdirsfc"] = make([]float64, dataCount)
dataMap["wvpersfc"] = make([]float64, dataCount)
dataMap["windsfc"] = make([]float64, dataCount)
dataMap["wdirsfc"] = make([]float64, dataCount)
for forcIndex, forecast := range w.ForecastData {
dataMap["htsgwsfc"][forcIndex] = forecast.SignificantWaveHeight
dataMap["dirpwsfc"][forcIndex] = forecast.DominantWaveDirection
dataMap["perpwsfc"][forcIndex] = forecast.MeanWavePeriod
dataMap["swell_1"][forcIndex] = forecast.PrimarySwellWaveHeight
dataMap["swdir_1"][forcIndex] = forecast.PrimarySwellDirection
dataMap["swper_1"][forcIndex] = forecast.PrimarySwellPeriod
dataMap["swell_2"][forcIndex] = forecast.SecondarySwellWaveHeight
dataMap["swdir_2"][forcIndex] = forecast.SecondarySwellDirection
dataMap["swper_2"][forcIndex] = forecast.SecondarySwellPeriod
dataMap["wvhgtsfc"][forcIndex] = forecast.WindSwellWaveHeight
dataMap["wvdirsfc"][forcIndex] = forecast.WindSwellDirection
dataMap["wvpersfc"][forcIndex] = forecast.WindSwellPeriod
dataMap["windsfc"][forcIndex] = forecast.SurfaceWindSpeed
dataMap["wdirsfc"][forcIndex] = forecast.SurfaceWindDirection
}
modelData := &ModelData{
Location: w.Location,
Model: w.Model,
Data: dataMap,
}
return modelData
}
// Create a new WaveForecastObject from an existing ModelData object
func WaveForecastFromModelData(modelData *ModelData) *WaveForecast {
if modelData == nil {
return nil
}
itemCount := len(modelData.Data["dirpwsfc"])
forecastItems := make([]WaveForecastItem, itemCount)
modelTime, _ := LatestModelDateTime()
for i := 0; i < itemCount; i++ {
thisForecastItem := WaveForecastItem{}
forecastTime := modelTime.Add(time.Duration(3 * int64(i) * int64(time.Hour)))
thisForecastItem.Date = forecastTime.In(modelData.Model.TimezoneLocation()).Format("Monday January 02, 2006")
thisForecastItem.Time = forecastTime.In(modelData.Model.TimezoneLocation()).Format("03 PM")
thisForecastItem.SignificantWaveHeight = modelData.Data["htsgwsfc"][i]
thisForecastItem.DominantWaveDirection = modelData.Data["dirpwsfc"][i]
thisForecastItem.MeanWavePeriod = modelData.Data["perpwsfc"][i]
thisForecastItem.PrimarySwellWaveHeight = modelData.Data["swell_1"][i]
thisForecastItem.PrimarySwellDirection = modelData.Data["swdir_1"][i]
thisForecastItem.PrimarySwellPeriod = modelData.Data["swper_1"][i]
thisForecastItem.SecondarySwellWaveHeight = modelData.Data["swell_2"][i]
thisForecastItem.SecondarySwellDirection = modelData.Data["swdir_2"][i]
thisForecastItem.SecondarySwellPeriod = modelData.Data["swper_2"][i]
thisForecastItem.WindSwellWaveHeight = modelData.Data["wvhgtsfc"][i]
thisForecastItem.WindSwellDirection = modelData.Data["wvdirsfc"][i]
thisForecastItem.WindSwellPeriod = modelData.Data["wvpersfc"][i]
thisForecastItem.SurfaceWindSpeed = modelData.Data["windsfc"][i]
thisForecastItem.SurfaceWindDirection = modelData.Data["wdirsfc"][i]
forecastItems[i] = thisForecastItem
}
forecast := &WaveForecast{
Location: modelData.Location,
Model: modelData.Model,
ForecastData: forecastItems,
}
return forecast
}