Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/OfficialLineFinder.java @ 6397:f579e4a80b84
Artifacts: Official lines finder: handle the cases from the state model.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Fri, 21 Jun 2013 17:36:50 +0200 |
parents | d2803cc7a338 |
children | 1e97d2e95410 |
comparison
equal
deleted
inserted
replaced
6396:f1018fd85183 | 6397:f579e4a80b84 |
---|---|
40 public static class ValueRange extends Range { | 40 public static class ValueRange extends Range { |
41 | 41 |
42 private double value; | 42 private double value; |
43 private int wstId; | 43 private int wstId; |
44 private int columnPos; | 44 private int columnPos; |
45 private String name; | |
45 | 46 |
46 public ValueRange( | 47 public ValueRange( |
47 double start, | 48 double start, |
48 double end, | 49 double end, |
49 double value, | 50 double value, |
50 int wstId, | 51 int wstId, |
51 int columnPos | 52 int columnPos, |
53 String name | |
52 ) { | 54 ) { |
53 super(start, end); | 55 super(start, end); |
54 this.value = value; | 56 this.value = value; |
55 this.wstId = wstId; | 57 this.wstId = wstId; |
56 this.columnPos = columnPos; | 58 this.columnPos = columnPos; |
59 this.name = name; | |
57 } | 60 } |
58 | 61 |
59 public boolean sameValue(double value) { | 62 public boolean sameValue(double value) { |
60 return Math.abs(value - this.value) < EPSILON; | 63 return Math.abs(value - this.value) < EPSILON; |
61 } | 64 } |
64 return wstId; | 67 return wstId; |
65 } | 68 } |
66 | 69 |
67 public int getColumnPos() { | 70 public int getColumnPos() { |
68 return columnPos; | 71 return columnPos; |
72 } | |
73 | |
74 public boolean intersectsValueRange(Range r) { | |
75 return r.inside(value); | |
76 } | |
77 | |
78 public String getName() { | |
79 return name; | |
80 } | |
81 | |
82 @Override | |
83 public boolean equals(Object o) { | |
84 if (!(o instanceof ValueRange)) { | |
85 return false; | |
86 } | |
87 ValueRange r = (ValueRange)o; | |
88 return wstId == r.wstId && columnPos == r.columnPos; | |
69 } | 89 } |
70 } | 90 } |
71 | 91 |
72 public OfficialLineFinder() { | 92 public OfficialLineFinder() { |
73 } | 93 } |
119 double to = gauge.getRange().getA().doubleValue(); | 139 double to = gauge.getRange().getA().doubleValue(); |
120 double value = mainValue.getValue().doubleValue(); | 140 double value = mainValue.getValue().doubleValue(); |
121 int wstId = wst.getId(); | 141 int wstId = wst.getId(); |
122 int pos = wc.getPosition(); | 142 int pos = wc.getPosition(); |
123 ValueRange range = | 143 ValueRange range = |
124 new ValueRange(from, to, value, wstId, pos); | 144 new ValueRange(from, to, value, wstId, pos, name); |
125 ranges.add(range); | 145 ranges.add(range); |
126 break; | 146 break; |
127 } | 147 } |
128 } | 148 } |
129 } | 149 } |
184 } | 204 } |
185 } | 205 } |
186 return list; | 206 return list; |
187 } | 207 } |
188 | 208 |
209 private static List<ValueRange> filterByQRange(Range range, List<ValueRange> ranges) { | |
210 List<ValueRange> list = new ArrayList<ValueRange>(ranges.size()); | |
211 for (ValueRange r: ranges) { | |
212 if (r.intersectsValueRange(range) && !list.contains(r)) { | |
213 list.add(r); | |
214 } | |
215 } | |
216 return list; | |
217 } | |
218 | |
189 private static boolean isQ(D4EArtifact artifact) { | 219 private static boolean isQ(D4EArtifact artifact) { |
190 Boolean b = artifact.getDataAsBoolean("wq_isq"); | 220 Boolean b = artifact.getDataAsBoolean("wq_isq"); |
191 return b != null && b; | 221 return b != null && b; |
192 } | 222 } |
193 | 223 |
194 public static List<OfficialLine> findOfficialLines(D4EArtifact artifact) { | 224 private static boolean isRange(D4EArtifact artifact) { |
225 Boolean b = artifact.getDataAsBoolean("wq_isrange"); | |
226 return b != null && b; | |
227 } | |
228 | |
229 public static final Range Q_OUT_OF_RANGE = new Range(-10000, -9999); | |
230 | |
231 private static Range singleQs(D4EArtifact artifact) { | |
232 String singleData = nn(artifact.getDataAsString("wq_single")); | |
233 double min = Double.MAX_VALUE; | |
234 double max = -Double.MAX_VALUE; | |
235 | |
236 for (String value: singleData.split(" ")) { | |
237 try { | |
238 double x = Double.parseDouble(value); | |
239 if (x < min) min = x; | |
240 if (x > max) max = x; | |
241 } | |
242 catch (NumberFormatException nfe) { | |
243 } | |
244 } | |
245 | |
246 return min == Double.MAX_VALUE | |
247 ? Q_OUT_OF_RANGE | |
248 : new Range(min, max); | |
249 | |
250 } | |
251 | |
252 private static Range qRange(D4EArtifact artifact) { | |
253 try { | |
254 Double from = artifact.getDataAsDouble("wq_from"); | |
255 Double to = artifact.getDataAsDouble("wq_to"); | |
256 | |
257 if (from == null || to == null) { | |
258 return Q_OUT_OF_RANGE; | |
259 } | |
260 double f = from; | |
261 double t = to; | |
262 return new Range(Math.min(f, t), Math.max(f, t)); | |
263 } | |
264 catch (NumberFormatException nfe) { | |
265 return Q_OUT_OF_RANGE; | |
266 } | |
267 } | |
268 | |
269 private static Range tripleQRange(D4EArtifact artifact) { | |
270 String rangesData = nn(artifact.getDataAsString("wq_values")); | |
271 | |
272 double min = Double.MAX_VALUE; | |
273 double max = -Double.MAX_VALUE; | |
274 | |
275 for (String range: rangesData.split(":")) { | |
276 String [] parts = range.split(";"); | |
277 if (parts.length < 3) { | |
278 continue; | |
279 } | |
280 String [] values = parts[2].split(","); | |
281 for (String value: values) { | |
282 try { | |
283 double x = Double.parseDouble(value); | |
284 if (x < min) min = x; | |
285 if (x > max) max = x; | |
286 } | |
287 catch (NumberFormatException nfe) { | |
288 } | |
289 } | |
290 } | |
291 | |
292 return min == Double.MAX_VALUE | |
293 ? Q_OUT_OF_RANGE | |
294 : new Range(min, max); | |
295 } | |
296 | |
297 public static List<ValueRange> findOfficialLines(D4EArtifact artifact) { | |
195 | 298 |
196 if (!isQ(artifact)) { // Only handle Q calculations | 299 if (!isQ(artifact)) { // Only handle Q calculations |
197 return Collections.<OfficialLine>emptyList(); | 300 return Collections.<ValueRange>emptyList(); |
198 } | 301 } |
199 | 302 |
200 Map<String, List<ValueRange>> rivers2officialLines = getAll(); | 303 Map<String, List<ValueRange>> rivers2officialLines = getAll(); |
201 | 304 |
202 String riverName = nn(artifact.getDataAsString("river")); | 305 String riverName = nn(artifact.getDataAsString("river")); |
203 | 306 |
204 List<ValueRange> ranges = rivers2officialLines.get(riverName); | 307 List<ValueRange> ranges = rivers2officialLines.get(riverName); |
205 | 308 |
206 if (ranges == null) { | 309 if (ranges == null) { |
207 return Collections.<OfficialLine>emptyList(); | 310 return Collections.<ValueRange>emptyList(); |
208 } | 311 } |
209 | 312 |
210 ranges = filterByRange(extractRange(artifact), ranges); | 313 ranges = filterByRange(extractRange(artifact), ranges); |
211 | 314 |
212 if (ranges.isEmpty()) { | 315 if (ranges.isEmpty()) { |
213 return Collections.<OfficialLine>emptyList(); | 316 return Collections.<ValueRange>emptyList(); |
214 } | 317 } |
215 | 318 |
216 | 319 Range qRange = isRange(artifact) |
217 // TODO: Figure out all the cases here. | 320 ? qRange(artifact) |
218 | 321 : singleQs(artifact); |
219 return Collections.<OfficialLine>emptyList(); | 322 |
323 if (qRange == Q_OUT_OF_RANGE) { | |
324 qRange = tripleQRange(artifact); | |
325 } | |
326 | |
327 return filterByQRange(qRange, ranges); | |
220 } | 328 } |
221 } | 329 } |