comparison flys-backend/src/main/java/de/intevation/flys/model/River.java @ 2877:f0a67bc0e777 2.7

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

http://dive4elements.wald.intevation.org