Mercurial > dive4elements > river
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 : |