-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWeatherStation.java
More file actions
393 lines (362 loc) · 12.2 KB
/
Copy pathWeatherStation.java
File metadata and controls
393 lines (362 loc) · 12.2 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
import java.util.ArrayList;
/**
* class WeatherStation represents weather stations and their associated observations.
*
* @author (Chris)
*/
public class WeatherStation
{
private String name;
private LatLong position;
private int seaLevel;
private int yearOfOpen;
private int yearOfClosing;
private ArrayList<WeatherObservation> observations;
/**
* Constructor for objects of class WeatherStation
*
* @param name New value for the weather station.
* @param seaLevel New value for a height above mean sea level(e.g. 242) in metres.
* @param yo New value for a year of opening of the weather station.
* @param yc New value for a year of closing of the weather station.
* @param position New value for the weather station's position.
*/
public WeatherStation(String name, int seaLevel, int yo, int yc, LatLong position){
this.name=name;
yearOfOpen=yo;
yearOfClosing=yc;
this.position=position;
this.seaLevel=seaLevel;
observations = new ArrayList<WeatherObservation>();
}
/**
* Constructor for objects of WeatherStation
*
* @param format New value for the WeatherStation .
*
*/
public WeatherStation(String format) throws InvalidDataException {
String[] pArray = format.trim().split("\\s+");
observations = new ArrayList<WeatherObservation>();
yearOfOpen=Integer.MAX_VALUE;
yearOfClosing=Integer.MIN_VALUE;
try { //"Eskdalemuir Location 3234E 6026N 242m amsl"
name = pArray[0];
position = new LatLong (pArray[2] + " " + pArray[3]);
seaLevel = Integer.parseInt(pArray[4].substring(0, pArray[4].length()-1));
} catch (IndexOutOfBoundsException e) {
throw new InvalidDataException ("WeatherStation : Data is not complete");
} catch (NumberFormatException e) {
throw new InvalidDataException ("WeatherStation : Digital number format error.");
} catch (InvalidDataException e) {
throw new InvalidDataException ("WeatherStation -> " + e.getMessage());
}
}
/**
* A get method - name of the weather station.
*
* @return The current value of the name of the weather station
*/
public String getName ()
{
return name;
}
/**
* A set method - name of the weather station.
*
* @param name New value for the name of the weather station.
*/
public void setName (String name)
{
this.name = name;
}
/**
* A get method - position of the weather station.
*
* @return The current value of the position of the weather station
*/
public LatLong getPosition ()
{
return position;
}
/**
* A get method - a height above mean sea level of the weather station.
*
* @return The current value of the height above mean sea level of the weather station
*/
public int getSeaLevel()
{
return seaLevel;
}
/**
* to save observations
*
* @return The current value of observatons.
*/
public ArrayList<WeatherObservation> observations ()
{
return observations;
}
/**
* Add an observation to the station.
*
* @param o The observatoin to be added.
*/
public void addObservation (WeatherObservation o) throws InvalidDataException
{
int year = o.getYear();
if (observations.contains (o))
{
throw new InvalidDataException("This year/month already been added");
}
yearOfOpen = ( yearOfOpen > year) ? year : yearOfOpen;
yearOfClosing = (yearOfClosing> year) ? yearOfClosing : year;
for (int i = 0; i < observations.size(); i++)
{
if (o.compareTo ( observations.get(i) ) < 0 )
{
observations.add (i, o);
return;
}
}
observations.add(o);
}
/**
* A get method - to get an observation for a given month and year
*
* @return If the year and month is exsit, return the value of observation, if cannot find the data, return null
*/
public WeatherObservation getObservation(int month, int year)
{
for (WeatherObservation search: observations)
{
if (search.getYear() == year && search.getMonth() == month)
{
return search;
}
}
return null;
}
/**
* A get method - to find the total rainfall for a given month.
*
* @return The current value of the total rainfall for a given month of the weather station
*/
public double getTRain(int year) throws InvalidDataException
{
double sum=0;
int i=0;
for (WeatherObservation r: observations)
{
if (r.getYear() == year) {
if((r.getTRain()==WeatherObservation.missingData ))
{
throw new InvalidDataException("missing data");
}
sum += r.getTRain();
i++;
}
if (i!=12){
throw new InvalidDataException("missing data");
}
}
return sum;
}
/**
* A get method - to find the wettest year(highest total rainfall)
*
* @return The current value of maxYear which is the wettest year of the weather station
*/
public int getWettestYear ()throws InvalidDataException
{
double maxRain = -1;
double sumRain = 0;
int maxYear = 0;
int year = this.yearOfOpen;
if (observations.size() == 0)
{
throw new InvalidDataException("missing data");
}
for (WeatherObservation o : observations)
{
if (o.getYear() != year)
{
maxYear = (sumRain > maxRain) ? year : maxYear;
maxRain = (sumRain > maxRain) ? sumRain : maxRain;
year = o.getYear();
sumRain = 0;
}
sumRain += ((o.getTRain() != WeatherObservation.missingData) ? o.getTRain() : 0);
}
maxYear = (sumRain > maxRain) ? year : maxYear;
return maxYear;
}
/**
* A get method - to find the month which is sunniest on average
*
* @return The current value of maxMonthSun which is sunniest month on average of the weather station
*/
public int getSunniestMonth()throws InvalidDataException
{
int month;
int [] months=new int [12];
double []tSun=new double[12];
double[]aSun= new double[12];
int maxMonthSun=0;
if (observations.size() == 0)
{
throw new InvalidDataException("missing data");
}
for(WeatherObservation o: observations ) // get total sunshine in every month
{
month= o.getMonth()-1;
tSun[month]+=o.getTSunshine();
months[month]++;
}
for(int i=0; i<12 ; i++){
if( months[i] > 0)
{
aSun[i] = tSun[i] / months[i];
}
else
{
aSun[i]=Double.NEGATIVE_INFINITY;
}
maxMonthSun= (aSun[i]> aSun[maxMonthSun])? i:maxMonthSun;
}
return maxMonthSun;
}
/**
* A completion method - to find data completion percentage of the weather station.
*
* @return The current value of the weather station's data completion percentage.
*/
public double completion ()
{
double sum = 0;
int first = 0;
int last = 0;
if (observations.size() == 0)
{
return WeatherObservation.missingData;
}
for (WeatherObservation o : observations)
{
sum += o.completion();
}
first = (observations.get(0).getYear() * 12) + observations.get(0).getMonth();
last = (observations.get(observations.size()-1).getYear() * 12) + observations.get(observations.size()-1).getMonth();
return sum / (last - first + 1);
}
/**
* A euqals method - The method determines whether the Number object that invokes the method is equal to the object that is passed as argument.
*
* @return The methods returns True if the argument is not null and is an object of the same type and with the same numeric value.
*/
public boolean equals (Object object)
{
boolean same = false;
if (object != null && object instanceof WeatherStation)
{
same = ((WeatherStation) object).getName().equals (this.name);
}
return same;
}
/**
* A get method - to find the averaged mean monthly temperature
*
* @return The current value of aTemp which is the averaged mean monthly temperature the weather station
*/
public double getAvgMeanMonthlyTemp ()
{
double sumTemp = 0;
int total= 0;
double aTemp;
for (WeatherObservation o : observations)
{
double temp = o.getMMTemp();
sumTemp += (temp == WeatherObservation.missingData) ? 0 : temp;
total += (temp == WeatherObservation.missingData) ? 0 : 1;
}
if(total>0)
{
aTemp= sumTemp/total;
}
else
{
aTemp=WeatherObservation.missingData;
}
return aTemp;
}
/**
* A get method - to find the averaged monthly rainfall
*
* @return The current value of aRain which is the averaged monthly rainfall of the weather station
*/
public double getAvgMonthlyRainFull ()
{
double sumRain = 0;
int total = 0;
double aRain;
for (WeatherObservation o : observations)
{
double rain = o.getTRain();
sumRain += (rain == WeatherObservation.missingData) ? 0 : rain;
total += (rain == WeatherObservation.missingData) ? 0 : 1;
}
if(total>0)
{
aRain= sumRain/total;
}
else
{
aRain=WeatherObservation.missingData;
}
return aRain;
}
/**
* A get method - to find the averaged monthly sunshine
*
* @return The current value of aRain which is the averaged monthly sunshine of the weather station
*/
public double getAvgMonthlySunShine ()
{
double sumSun = 0;
int total = 0;
double aSun;
for (WeatherObservation o : observations)
{
double sun = o.getTSunshine();
sumSun += (sun == WeatherObservation.missingData) ? 0 : sun;
total += (sun == WeatherObservation.missingData) ? 0 : 1;
}
if(total>0)
{
aSun= sumSun/total;
}
else
{
aSun=WeatherObservation.missingData;
}
return aSun;
}
/**
* A toString method - gives a string representation of the station,
* including its name and position and observation summary statistics of
* the averaged mean monthly temperature, the averaged monthly rainfall and the averaged monthly sunshine of the weather station.
*
* @return A string representation of the averaged mean monthly temperature, the averaged monthly rainfall and the averaged monthly sunshine of the weather station.
*/
public String toString ()
{
String strNewLine = System.getProperty("line.separator");
String strAvgRainFull = (getAvgMonthlyRainFull() == WeatherObservation.missingData) ? "---" : String.format ("%.2f", getAvgMonthlyRainFull());
String strAvgMeanTemp = (getAvgMeanMonthlyTemp() == WeatherObservation.missingData) ? "---" : String.format ("%.2f", getAvgMeanMonthlyTemp());
String strAvgSunShine = (getAvgMonthlySunShine() == WeatherObservation.missingData) ? "---" : String.format ("%.2f", getAvgMonthlySunShine());
return name + " station : " + strNewLine +
" - Position : " + position.toString() + strNewLine +
" - Average mean monthly temperature : " + strAvgMeanTemp + strNewLine +
" - Average monthly rain fail : " + strAvgRainFull + strNewLine +
" - Average monthly sun shine : " + strAvgSunShine;
}
}