comparison backend/src/main/java/org/dive4elements/river/model/River.java @ 5838:5aa05a7a34b7

Rename modules to more fitting names.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 15:23:37 +0200
parents flys-backend/src/main/java/org/dive4elements/river/model/River.java@18619c1e7c2a
children 4dd33b86dc61
comparison
equal deleted inserted replaced
5837:d9901a08d0a6 5838:5aa05a7a34b7
1 package org.dive4elements.river.model;
2
3 import org.dive4elements.river.backend.SessionHolder;
4
5 import java.io.Serializable;
6 import java.math.BigDecimal;
7 import java.math.MathContext;
8 import java.util.Comparator;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.TreeMap;
12
13 import javax.persistence.Column;
14 import javax.persistence.Entity;
15 import javax.persistence.GeneratedValue;
16 import javax.persistence.GenerationType;
17 import javax.persistence.Id;
18 import javax.persistence.JoinColumn;
19 import javax.persistence.OneToMany;
20 import javax.persistence.OneToOne;
21 import javax.persistence.OrderBy;
22 import javax.persistence.SequenceGenerator;
23 import javax.persistence.Table;
24
25 import org.hibernate.Query;
26 import org.hibernate.Session;
27
28
29 @Entity
30 @Table(name = "rivers")
31 public class River
32 implements Serializable
33 {
34 public static final MathContext PRECISION = new MathContext(6);
35
36 public static final double EPSILON = 1e-5;
37
38 public static final Comparator<Double> KM_CMP = new Comparator<Double>() {
39 @Override
40 public int compare(Double a, Double b) {
41 double diff = a - b;
42 if (diff < -EPSILON) return -1;
43 if (diff > EPSILON) return +1;
44 return 0;
45 }
46 };
47
48 private Integer id;
49
50 private Long officialNumber;
51
52 private String name;
53
54 private boolean kmUp;
55
56 private List<Gauge> gauges;
57
58 private List<MeasurementStation> measurementstations;
59
60 private Unit wstUnit;
61
62 @Id
63 @SequenceGenerator(
64 name = "SEQUENCE_RIVERS_ID_SEQ",
65 sequenceName = "RIVERS_ID_SEQ",
66 allocationSize = 1)
67 @GeneratedValue(
68 strategy = GenerationType.SEQUENCE,
69 generator = "SEQUENCE_RIVERS_ID_SEQ")
70 @Column(name = "id")
71 public Integer getId() {
72 return id;
73 }
74
75 public void setId(Integer id) {
76 this.id = id;
77 }
78
79 @Column(name = "official_number")
80 public Long getOfficialNumber() {
81 return officialNumber;
82 }
83
84 public void setOfficialNumber(Long officialNumber) {
85 this.officialNumber = officialNumber;
86 }
87
88 @Column(name = "name")
89 public String getName() {
90 return name;
91 }
92
93 public void setName(String name) {
94 this.name = name;
95 }
96
97 @Column(name = "km_up")
98 public boolean getKmUp() {
99 return kmUp;
100 }
101
102 public void setKmUp(boolean kmUp) {
103 this.kmUp = kmUp;
104 }
105
106 public River() {
107 }
108
109 public River(String name, Unit wstUnit) {
110 this.name = name;
111 this.wstUnit = wstUnit;
112 }
113
114 @OneToMany
115 @JoinColumn(name="river_id")
116 public List<Gauge> getGauges() {
117 return gauges;
118 }
119
120 public void setGauges(List<Gauge> gauges) {
121 this.gauges = gauges;
122 }
123
124
125 @OneToMany
126 @OrderBy("station")
127 @JoinColumn(name="river_id")
128 public List<MeasurementStation> getMeasurementStations() {
129 return measurementstations;
130 }
131
132 public void setMeasurementStations(List<MeasurementStation> mstations) {
133 this.measurementstations = mstations;
134 }
135
136 @OneToOne
137 @JoinColumn(name = "wst_unit_id" )
138 public Unit getWstUnit() {
139 return wstUnit;
140 }
141
142 public void setWstUnit(Unit wstUnit) {
143 this.wstUnit = wstUnit;
144 }
145
146
147
148 @Override
149 public String toString() {
150 return name != null ? name : "";
151 }
152
153
154 /**
155 * This method returns the gauges that intersect with <i>a</i> and
156 * <i>b</i>,
157 *
158 * @param a A start point.
159 * @param b An end point.
160 *
161 * @return the intersecting gauges.
162 */
163 public List<Gauge> determineGauges(double a, double b) {
164 Session session = SessionHolder.HOLDER.get();
165
166 if (a > b) { double t = a; a = b; b = t; }
167
168 Query query = session.createQuery(
169 "from Gauge where river=:river " +
170 "and not (range.a > :b or range.b < :a) order by a");
171 query.setParameter("river", this);
172 query.setParameter("a", new BigDecimal(a, PRECISION));
173 query.setParameter("b", new BigDecimal(b, PRECISION));
174
175 return query.list();
176 }
177
178 public Gauge maxOverlap(double a, double b) {
179 List<Gauge> gauges = determineGauges(a, b);
180 if (gauges == null) {
181 return null;
182 }
183
184 if (a > b) { double t = a; a = b; b = t; }
185
186 double max = -Double.MAX_VALUE;
187
188 Gauge result = null;
189
190 for (Gauge gauge: gauges) {
191 Range r = gauge.getRange();
192 double c = r.getA().doubleValue();
193 double d = r.getB().doubleValue();
194
195 double start = c >= a ? c : a;
196 double stop = d <= b ? d : b;
197
198 double length = stop - start;
199
200 if (length > max) {
201 max = length;
202 result = gauge;
203 }
204 }
205
206 return result;
207 }
208
209 public Gauge determineGaugeByName(String name) {
210 Session session = SessionHolder.HOLDER.get();
211 Query query = session.createQuery(
212 "from Gauge where river=:river and name=:name");
213 query.setParameter("river", this);
214 query.setParameter("name", name);
215 List<Gauge> gauges = query.list();
216 return gauges.isEmpty() ? null : gauges.get(0);
217 }
218
219 public Gauge determineGaugeByPosition(double p) {
220 Session session = SessionHolder.HOLDER.get();
221 Query query = session.createQuery(
222 "from Gauge g where river=:river " +
223 "and :p between g.range.a and g.range.b");
224 query.setParameter("river", this);
225 query.setParameter("p", new BigDecimal(p, PRECISION));
226 List<Gauge> gauges = query.list();
227 return gauges.isEmpty() ? null : gauges.get(0);
228 }
229
230 public Gauge determineGaugeByStation(double a, double b) {
231
232 if (a > b) { double t = a; a = b; b = t; }
233
234 Session session = SessionHolder.HOLDER.get();
235
236 Query query = session.createQuery(
237 "from Gauge where river.id=:river " +
238 "and station between :a and :b");
239 query.setParameter("river", getId());
240 query.setParameter("a", new BigDecimal(a));
241 query.setParameter("b", new BigDecimal(b));
242
243 List<Gauge> gauges = query.list();
244 return gauges.isEmpty() ? null : gauges.get(0);
245 }
246
247 public double[] determineMinMaxQ() {
248 Session session = SessionHolder.HOLDER.get();
249
250 Query query = session.createQuery(
251 "select min(wqr.q) as min, max(wqr.q) as max " +
252 "from Wst as w " +
253 "join w.columns as wc " +
254 "join wc.columnQRanges as wcqr " +
255 "join wcqr.wstQRange as wqr " +
256 "where w.kind = 0 and river_id = :river");
257
258 query.setParameter("river", getId());
259
260 double minmax[] = new double[] { Double.MAX_VALUE, Double.MIN_VALUE };
261
262 List<Object> results = query.list();
263
264 if (!results.isEmpty()) {
265 Object[] arr = (Object[]) results.get(0);
266 BigDecimal minq = (BigDecimal)arr[0];
267 BigDecimal maxq = (BigDecimal)arr[1];
268 minmax[0] = minq.doubleValue();
269 minmax[1] = maxq.doubleValue();
270 }
271
272 return minmax;
273 }
274
275
276 /**
277 * This method returns the first gauge that is intersected by <i>a</i> and
278 * <i>b</i>,
279 *
280 * @param a A start point.
281 * @param b An end point.
282 *
283 * @return the first intersecting gauge.
284 */
285 public Gauge determineGauge(double a, double b) {
286 List<Gauge> gauges = determineGauges(a, b);
287
288 int idx = a < b ? 0 : gauges.size() - 1;
289
290 return gauges.isEmpty() ? null : gauges.get(idx);
291 }
292
293 /**
294 * Returns the min and max distance of this river. The first position in the
295 * resulting array contains the min distance, the second position the max
296 * distance.
297 *
298 * @return the min and max distance of this river.
299 */
300 public double[] determineMinMaxDistance() {
301 List<Gauge> gauges = getGauges();
302
303 if (gauges == null || gauges.isEmpty()) {
304 return null;
305 }
306
307 double minmax[] = new double[] { Double.MAX_VALUE, Double.MIN_VALUE };
308
309 for (Gauge g: gauges) {
310 Range r = g.getRange();
311
312 if (r == null) {
313 continue;
314 }
315
316 double a = r.getA().doubleValue();
317 minmax[0] = minmax[0] < a ? minmax[0] : a;
318
319 BigDecimal bigB = r.getB();
320 if (bigB != null) {
321 double b = bigB.doubleValue();
322 minmax[1] = minmax[1] > b ? minmax[1] : b;
323 }
324 }
325
326 return minmax;
327 }
328
329 public Map<Double, Double> queryGaugeDatumsKMs() {
330 List<Gauge> gauges = getGauges();
331 Map result = new TreeMap<Double, Double>(KM_CMP);
332
333 for (Gauge gauge: gauges) {
334 BigDecimal km = gauge.getStation();
335 BigDecimal datum = gauge.getDatum();
336 if (km != null && datum != null) {
337 result.put(km.doubleValue(), datum.doubleValue());
338 }
339 }
340
341 return result;
342 }
343
344 }
345 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org