comparison backend/src/main/java/org/dive4elements/river/model/Gauge.java @ 9404:bc9a45d2b1fa

common time range for gauges incl. error messages
author gernotbelger
date Wed, 15 Aug 2018 13:59:09 +0200
parents 5e38e2924c07
children b0520a85739d
comparison
equal deleted inserted replaced
9403:e2da9c8a7c57 9404:bc9a45d2b1fa
6 * documentation coming with Dive4Elements River for details. 6 * documentation coming with Dive4Elements River for details.
7 */ 7 */
8 8
9 package org.dive4elements.river.model; 9 package org.dive4elements.river.model;
10 10
11 import java.io.Serializable;
11 import java.math.BigDecimal; 12 import java.math.BigDecimal;
12
13 import java.io.Serializable;
14
15 import java.util.List; 13 import java.util.List;
16 14
15 import javax.persistence.Column;
17 import javax.persistence.Entity; 16 import javax.persistence.Entity;
17 import javax.persistence.GeneratedValue;
18 import javax.persistence.GenerationType;
18 import javax.persistence.Id; 19 import javax.persistence.Id;
20 import javax.persistence.JoinColumn;
21 import javax.persistence.OneToMany;
22 import javax.persistence.OneToOne;
23 import javax.persistence.SequenceGenerator;
19 import javax.persistence.Table; 24 import javax.persistence.Table;
20 import javax.persistence.GeneratedValue; 25
21 import javax.persistence.Column; 26 import org.apache.log4j.Logger;
22 import javax.persistence.SequenceGenerator; 27 import org.dive4elements.river.backend.SessionHolder;
23 import javax.persistence.GenerationType; 28 import org.hibernate.Query;
24 import javax.persistence.JoinColumn;
25 import javax.persistence.OneToOne;
26 import javax.persistence.OneToMany;
27
28 import org.hibernate.Session; 29 import org.hibernate.Session;
29 import org.hibernate.Query;
30
31 import org.apache.log4j.Logger;
32
33 import org.dive4elements.river.backend.SessionHolder;
34 30
35 /** Database-mapped Gauge with all info about it. */ 31 /** Database-mapped Gauge with all info about it. */
36 @Entity 32 @Entity
37 @Table(name = "gauges") 33 @Table(name = "gauges")
38 public class Gauge 34 public class Gauge implements Serializable, Comparable<Gauge> {
39 implements Serializable, Comparable<Gauge>
40 {
41 private static final Logger log = Logger.getLogger(Gauge.class); 35 private static final Logger log = Logger.getLogger(Gauge.class);
42 36
43 public static final int MASTER_DISCHARGE_TABLE = 0; 37 public static final int MASTER_DISCHARGE_TABLE = 0;
44 38
45 private Integer id; 39 private Integer id;
46 private String name; 40 private String name;
47 private River river; 41 private River river;
48 private BigDecimal station; 42 private BigDecimal station;
49 private BigDecimal aeo; 43 private BigDecimal aeo;
50 private BigDecimal datum; 44 private BigDecimal datum;
51 private Long officialNumber; 45 private Long officialNumber;
52 private Range range; 46 private Range range;
53 47
54 private List<DischargeTable> dischargeTables; 48 private List<DischargeTable> dischargeTables;
55 49
56 /** MainValues at this Gauge. */ 50 /** MainValues at this Gauge. */
57 protected List<MainValue> mainValues; 51 protected List<MainValue> mainValues;
58 52
59 public Gauge() { 53 public Gauge() {
60 } 54 }
61 55
62 public Gauge( 56 public Gauge(final String name, final River river, final BigDecimal station, final BigDecimal aeo, final BigDecimal datum, final Long officialNumber,
63 String name, 57 final Range range) {
64 River river, 58 this.name = name;
65 BigDecimal station, 59 this.river = river;
66 BigDecimal aeo, 60 this.station = station;
67 BigDecimal datum, 61 this.aeo = aeo;
68 Long officialNumber, 62 this.datum = datum;
69 Range range 63 this.officialNumber = officialNumber;
70 ) { 64 this.range = range;
71 this.name = name;
72 this.river = river;
73 this.station = station;
74 this.aeo = aeo;
75 this.datum = datum;
76 this.officialNumber = officialNumber;
77 this.range = range;
78 } 65 }
79 66
80 @Id 67 @Id
81 @SequenceGenerator( 68 @SequenceGenerator(name = "SEQUENCE_GAUGES_ID_SEQ", sequenceName = "GAUGES_ID_SEQ", allocationSize = 1)
82 name = "SEQUENCE_GAUGES_ID_SEQ", 69 @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_GAUGES_ID_SEQ")
83 sequenceName = "GAUGES_ID_SEQ",
84 allocationSize = 1)
85 @GeneratedValue(
86 strategy = GenerationType.SEQUENCE,
87 generator = "SEQUENCE_GAUGES_ID_SEQ")
88 @Column(name = "id") 70 @Column(name = "id")
89 public Integer getId() { 71 public Integer getId() {
90 return id; 72 return this.id;
91 } 73 }
92 74
93 public void setId(Integer id) { 75 public void setId(final Integer id) {
94 this.id = id; 76 this.id = id;
95 } 77 }
96 78
97 @OneToOne 79 @OneToOne
98 @JoinColumn(name = "river_id" ) 80 @JoinColumn(name = "river_id")
99 public River getRiver() { 81 public River getRiver() {
100 return river; 82 return this.river;
101 } 83 }
102 84
103 public void setRiver(River river) { 85 public void setRiver(final River river) {
104 this.river = river; 86 this.river = river;
105 } 87 }
106 88
107 @Column(name = "name") 89 @Column(name = "name")
108 public String getName() { 90 public String getName() {
109 return name; 91 return this.name;
110 } 92 }
111 93
112 public void setName(String name) { 94 public void setName(final String name) {
113 this.name = name; 95 this.name = name;
114 } 96 }
115 97
116 @Column(name = "station") // FIXME: type mapping needed 98 @Column(name = "station") // FIXME: type mapping needed
117 public BigDecimal getStation() { 99 public BigDecimal getStation() {
118 return station; 100 return this.station;
119 } 101 }
120 102
121 public void setStation(BigDecimal station) { 103 public void setStation(final BigDecimal station) {
122 this.station = station; 104 this.station = station;
123 } 105 }
124 106
125 @Column(name = "aeo") // FIXME: type mapping needed 107 @Column(name = "aeo") // FIXME: type mapping needed
126 public BigDecimal getAeo() { 108 public BigDecimal getAeo() {
127 return aeo; 109 return this.aeo;
128 } 110 }
129 111
130 public void setAeo(BigDecimal aeo) { 112 public void setAeo(final BigDecimal aeo) {
131 this.aeo = aeo; 113 this.aeo = aeo;
132 } 114 }
133 115
134 @Column(name = "datum") // FIXME: type mapping needed 116 @Column(name = "datum") // FIXME: type mapping needed
135 public BigDecimal getDatum() { 117 public BigDecimal getDatum() {
136 return datum; 118 return this.datum;
137 } 119 }
138 120
139 public void setDatum(BigDecimal datum) { 121 public void setDatum(final BigDecimal datum) {
140 this.datum = datum; 122 this.datum = datum;
141 } 123 }
142 124
143 @Column(name = "official_number") 125 @Column(name = "official_number")
144 public Long getOfficialNumber() { 126 public Long getOfficialNumber() {
145 return officialNumber; 127 return this.officialNumber;
146 } 128 }
147 129
148 public void setOfficialNumber(Long officialNumber) { 130 public void setOfficialNumber(final Long officialNumber) {
149 this.officialNumber = officialNumber; 131 this.officialNumber = officialNumber;
150 } 132 }
151 133
152 @OneToOne 134 @OneToOne
153 @JoinColumn(name = "range_id" ) 135 @JoinColumn(name = "range_id")
154 public Range getRange() { 136 public Range getRange() {
155 return range; 137 return this.range;
156 } 138 }
157 139
158 public void setRange(Range range) { 140 public void setRange(final Range range) {
159 this.range = range; 141 this.range = range;
160 } 142 }
161 143
162 @OneToMany 144 @OneToMany
163 @JoinColumn(name = "gauge_id") 145 @JoinColumn(name = "gauge_id")
164 public List<DischargeTable> getDischargeTables() { 146 public List<DischargeTable> getDischargeTables() {
165 return dischargeTables; 147 return this.dischargeTables;
166 } 148 }
167 149
168 public void setDischargeTables(List<DischargeTable> dischargeTables) { 150 public void setDischargeTables(final List<DischargeTable> dischargeTables) {
169 this.dischargeTables = dischargeTables; 151 this.dischargeTables = dischargeTables;
170 } 152 }
171
172 153
173 /** 154 /**
174 * Returns min and max W values of this gauge. 155 * Returns min and max W values of this gauge.
175 * 156 *
176 * @return the min and max W value of this gauge [min,max]. 157 * @return the min and max W value of this gauge [min,max].
177 */ 158 */
178 public double[] determineMinMaxW() { 159 public double[] determineMinMaxW() {
179 Session session = SessionHolder.HOLDER.get(); 160 final Session session = SessionHolder.HOLDER.get();
180 161
181 DischargeTable dischargeTable = fetchMasterDischargeTable(); 162 final DischargeTable dischargeTable = fetchMasterDischargeTable();
182 163
183 if (dischargeTable == null) { 164 if (dischargeTable == null) {
184 return null; 165 return null;
185 } 166 }
186 167
187 Query query = session.createQuery( 168 final Query query = session.createQuery("select min(w) as min, max(w) as max from DischargeTableValue " + "where table_id =:table");
188 "select min(w) as min, max(w) as max from DischargeTableValue " +
189 "where table_id =:table");
190 query.setParameter("table", dischargeTable.getId()); 169 query.setParameter("table", dischargeTable.getId());
191 170
192 List<?> results = query.list(); 171 final List<?> results = query.list();
193 if (results.isEmpty()) { 172 if (results.isEmpty()) {
194 log.error("No values in discharge table found."); 173 log.error("No values in discharge table found.");
195 return null; 174 return null;
196 } 175 }
197 176
198 Object[] result = (Object[])results.get(0); 177 final Object[] result = (Object[]) results.get(0);
199 178
200 BigDecimal a = (BigDecimal)result[0]; 179 final BigDecimal a = (BigDecimal) result[0];
201 BigDecimal b = (BigDecimal)result[1]; 180 final BigDecimal b = (BigDecimal) result[1];
202 181
203 return a != null && b != null 182 return a != null && b != null ? new double[] { a.doubleValue(), b.doubleValue() } : null;
204 ? new double [] { a.doubleValue(), b.doubleValue() }
205 : null;
206 } 183 }
207 184
208 @OneToMany 185 @OneToMany
209 @JoinColumn(name = "gauge_id") 186 @JoinColumn(name = "gauge_id")
210 public List<MainValue> getMainValues() { 187 public List<MainValue> getMainValues() {
211 return mainValues; 188 return this.mainValues;
212 } 189 }
213 190
214 public void setMainValues(List<MainValue> mainValues) { 191 public void setMainValues(final List<MainValue> mainValues) {
215 this.mainValues = mainValues; 192 this.mainValues = mainValues;
216 } 193 }
217 194
218 public static Gauge getGaugeByOfficialNumber(long number) { 195 public static Gauge getGaugeByOfficialNumber(final long number) {
219 Session session = SessionHolder.HOLDER.get(); 196 final Session session = SessionHolder.HOLDER.get();
220 197
221 Query query = session.createQuery( 198 final Query query = session.createQuery("from Gauge where officialNumber=:number");
222 "from Gauge where officialNumber=:number");
223 199
224 query.setParameter("number", number); 200 query.setParameter("number", number);
225 201
226 List<Gauge> results = query.list(); 202 final List<Gauge> results = query.list();
227 203
228 return results.isEmpty() ? null : results.get(0); 204 return results.isEmpty() ? null : results.get(0);
229 } 205 }
230 206
231 public static Gauge getGaugeByOfficialNumber( 207 public static Gauge getGaugeByOfficialNumber(final long number, final String river_name) {
232 long number, 208 final Session session = SessionHolder.HOLDER.get();
233 String river_name 209
234 ) { 210 final Query query = session.createQuery("from Gauge as gau " + "where gau.officialNumber=:number and gau.river.name=:river_name");
235 Session session = SessionHolder.HOLDER.get();
236
237 Query query = session.createQuery(
238 "from Gauge as gau " +
239 "where gau.officialNumber=:number and gau.river.name=:river_name");
240 211
241 query.setParameter("number", number); 212 query.setParameter("number", number);
242 query.setParameter("river_name", river_name); 213 query.setParameter("river_name", river_name);
243 214
244 List<Gauge> results = query.list(); 215 final List<Gauge> results = query.list();
245 216
246 return results.isEmpty() ? null : results.get(0); 217 return results.isEmpty() ? null : results.get(0);
247 } 218 }
248 219
220 public static Gauge getGaugeByNameAndRiver(final String gauge_name, final River river) {
221 final Session session = SessionHolder.HOLDER.get();
222
223 final Query query = session.createQuery("from Gauge as gau " + "where gau.name=:name and gau.river=:river");
224
225 query.setParameter("name", gauge_name);
226 query.setParameter("river", river);
227
228 final List<Gauge> results = query.list();
229
230 return results.isEmpty() ? null : results.get(0);
231 }
249 232
250 public DischargeTable fetchMasterDischargeTable() { 233 public DischargeTable fetchMasterDischargeTable() {
251 Session session = SessionHolder.HOLDER.get(); 234 final Session session = SessionHolder.HOLDER.get();
252 235
253 Query query = session.createQuery( 236 final Query query = session.createQuery("from DischargeTable " + "where kind = 0 " + "and gauge = :gauge");
254 "from DischargeTable " +
255 "where kind = 0 " +
256 "and gauge = :gauge");
257 237
258 query.setParameter("gauge", this); 238 query.setParameter("gauge", this);
259 239
260 List<Object> results = query.list(); 240 final List<Object> results = query.list();
261 241
262 return results.isEmpty() 242 return results.isEmpty() ? null : (DischargeTable) results.get(0);
263 ? null
264 : (DischargeTable)results.get(0);
265 } 243 }
266 244
267 /** 245 /**
268 * Returns an array of [days, qs] necessary to create duration curves. 246 * Returns an array of [days, qs] necessary to create duration curves.
269 * 247 *
270 * @return a 2dim array of [days, qs] where days is an int[] and qs is 248 * @return a 2dim array of [days, qs] where days is an int[] and qs is
271 * an double[]. 249 * an double[].
272 */ 250 */
273 public Object[] fetchDurationCurveData() { 251 public Object[] fetchDurationCurveData() {
274 Session session = SessionHolder.HOLDER.get(); 252 final Session session = SessionHolder.HOLDER.get();
275 253
276 Query query = session.createQuery( 254 final Query query = session.createQuery("select cast(nmv.name as integer) as days, mv.value as q " + "from MainValue as mv "
277 "select cast(nmv.name as integer) as days, mv.value as q " + 255 + "join mv.mainValue as nmv " + "join nmv.type mvt " + "where mvt.name = 'D' and mv.gauge.id = :gauge_id " + "order by days");
278 "from MainValue as mv " +
279 "join mv.mainValue as nmv " +
280 "join nmv.type mvt " +
281 "where mvt.name = 'D' and mv.gauge.id = :gauge_id " +
282 "order by days");
283 256
284 query.setParameter("gauge_id", getId()); 257 query.setParameter("gauge_id", getId());
285 258
286 List<Object> results = query.list(); 259 final List<Object> results = query.list();
287 int[] days = new int[results.size()]; 260 final int[] days = new int[results.size()];
288 double[] qs = new double[results.size()]; 261 final double[] qs = new double[results.size()];
289 262
290 int idx = 0; 263 int idx = 0;
291 264
292 for (Object obj: results) { 265 for (final Object obj : results) {
293 Object[] arr = (Object[]) obj; 266 final Object[] arr = (Object[]) obj;
294 267
295 try { 268 try {
296 int day = ((Integer) arr[0]).intValue(); 269 final int day = ((Integer) arr[0]).intValue();
297 double q = ((BigDecimal) arr[1]).doubleValue(); 270 final double q = ((BigDecimal) arr[1]).doubleValue();
298 271
299 days[idx] = day; 272 days[idx] = day;
300 qs[idx++] = q; 273 qs[idx++] = q;
301 } 274 }
302 catch (NumberFormatException nfe) { 275 catch (final NumberFormatException nfe) {
303 } 276 }
304 } 277 }
305 278
306 return new Object[] { days, qs }; 279 return new Object[] { days, qs };
307 } 280 }
310 * Calculates the maximum and minimum W and Q values 283 * Calculates the maximum and minimum W and Q values
311 * 284 *
312 * @return the MaxMinWQ object representing the calculated values 285 * @return the MaxMinWQ object representing the calculated values
313 */ 286 */
314 public MinMaxWQ fetchMaxMinWQ() { 287 public MinMaxWQ fetchMaxMinWQ() {
315 Session session = SessionHolder.HOLDER.get(); 288 final Session session = SessionHolder.HOLDER.get();
316 289
317 Query query = session.createQuery( 290 final Query query = session.createQuery("select max(mv.value) as max, min(mv.value) as min " + "from MainValue as mv " + "join mv.mainValue as nmv "
318 "select max(mv.value) as max, min(mv.value) as min " + 291 + "join nmv.type mvt " + "where mvt.name in ('W', 'Q') " + "and mv.gauge.id = :gauge_id " + "group by mvt.name order by mvt.name");
319 "from MainValue as mv " +
320 "join mv.mainValue as nmv " +
321 "join nmv.type mvt " +
322 "where mvt.name in ('W', 'Q') " +
323 "and mv.gauge.id = :gauge_id " +
324 "group by mvt.name order by mvt.name"
325 );
326 292
327 query.setParameter("gauge_id", getId()); 293 query.setParameter("gauge_id", getId());
328 294
329 List<Object> results = query.list(); 295 final List<Object> results = query.list();
330 if (results.isEmpty()) { 296 if (results.isEmpty()) {
331 // No values found 297 // No values found
332 return new MinMaxWQ(); 298 return new MinMaxWQ();
333 } 299 }
334 300
335 Object[] arr = (Object[]) results.get(0); 301 Object[] arr = (Object[]) results.get(0);
336 BigDecimal maxw = (BigDecimal)arr[0]; 302 final BigDecimal maxw = (BigDecimal) arr[0];
337 BigDecimal minw = (BigDecimal)arr[1]; 303 final BigDecimal minw = (BigDecimal) arr[1];
338 BigDecimal maxq = null; 304 BigDecimal maxq = null;
339 BigDecimal minq = null; 305 BigDecimal minq = null;
340 306
341
342 if (results.size() > 1) { 307 if (results.size() > 1) {
343 arr = (Object[]) results.get(1); 308 arr = (Object[]) results.get(1);
344 maxq = (BigDecimal)arr[0]; 309 maxq = (BigDecimal) arr[0];
345 minq = (BigDecimal)arr[1]; 310 minq = (BigDecimal) arr[1];
346 } 311 }
347 312
348 return new MinMaxWQ(minw, maxw, minq, maxq); 313 return new MinMaxWQ(minw, maxw, minq, maxq);
349 } 314 }
350 315
351 @Override 316 @Override
352 public int compareTo(Gauge o) { 317 public int compareTo(final Gauge o) {
353 return getName().compareTo(o.getName()); 318 return getName().compareTo(o.getName());
354 } 319 }
355 } 320 }
356 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : 321 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org