Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java @ 686:3dc61e00385e facets-slt
Merged with trunk and introduced hashing of computed values.
flys-artifacts/branches/facets-slt@2126 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Wed, 15 Jun 2011 15:28:54 +0000 |
parents | fdc898a134a7 |
children | 06689035024c |
comparison
equal
deleted
inserted
replaced
667:434146596838 | 686:3dc61e00385e |
---|---|
1 package de.intevation.flys.artifacts; | 1 package de.intevation.flys.artifacts; |
2 | 2 |
3 import java.util.List; | 3 import java.util.List; |
4 import java.util.Set; | |
5 import java.util.HashSet; | |
6 import java.util.ArrayList; | |
7 | 4 |
8 import org.w3c.dom.Document; | 5 import org.w3c.dom.Document; |
9 import org.w3c.dom.Element; | 6 import org.w3c.dom.Element; |
10 import org.w3c.dom.Node; | 7 import org.w3c.dom.Node; |
11 | 8 |
23 import de.intevation.artifacts.common.utils.XMLUtils; | 20 import de.intevation.artifacts.common.utils.XMLUtils; |
24 | 21 |
25 import de.intevation.flys.model.Gauge; | 22 import de.intevation.flys.model.Gauge; |
26 import de.intevation.flys.model.River; | 23 import de.intevation.flys.model.River; |
27 | 24 |
25 import de.intevation.flys.artifacts.states.CalculationSelect; | |
28 import de.intevation.flys.artifacts.states.DefaultState; | 26 import de.intevation.flys.artifacts.states.DefaultState; |
29 import de.intevation.flys.artifacts.context.FLYSContext; | 27 import de.intevation.flys.artifacts.context.FLYSContext; |
30 | 28 |
29 import de.intevation.flys.artifacts.model.ComputeCallback; | |
31 import de.intevation.flys.artifacts.model.MainValuesFactory; | 30 import de.intevation.flys.artifacts.model.MainValuesFactory; |
32 import de.intevation.flys.artifacts.model.WQDay; | 31 import de.intevation.flys.artifacts.model.WQDay; |
33 import de.intevation.flys.artifacts.model.WQKms; | 32 import de.intevation.flys.artifacts.model.WQKms; |
34 import de.intevation.flys.artifacts.model.WstValueTable; | 33 import de.intevation.flys.artifacts.model.WstValueTable; |
35 import de.intevation.flys.artifacts.model.WstValueTable.QPosition; | |
36 import de.intevation.flys.artifacts.model.WstValueTableFactory; | 34 import de.intevation.flys.artifacts.model.WstValueTableFactory; |
35 import de.intevation.flys.artifacts.model.Calculation1; | |
36 import de.intevation.flys.artifacts.model.Calculation2; | |
37 import de.intevation.flys.artifacts.model.Calculation3; | |
37 import de.intevation.flys.artifacts.model.Calculation4; | 38 import de.intevation.flys.artifacts.model.Calculation4; |
38 import de.intevation.flys.artifacts.model.Segment; | 39 import de.intevation.flys.artifacts.model.Segment; |
39 | 40 |
40 import gnu.trove.TDoubleArrayList; | 41 import gnu.trove.TDoubleArrayList; |
41 | 42 |
239 | 240 |
240 // | 241 // |
241 // METHODS FOR RETRIEVING COMPUTED DATA FOR DIFFERENT CHART TYPES | 242 // METHODS FOR RETRIEVING COMPUTED DATA FOR DIFFERENT CHART TYPES |
242 // | 243 // |
243 | 244 |
245 | |
246 public Object compute() { | |
247 return compute(hash()); | |
248 } | |
249 | |
250 | |
251 public Object compute(String hash) { | |
252 String calc = (String) getData(CalculationSelect.FIELD_MODE).getValue(); | |
253 | |
254 ComputeCallback callback = null; | |
255 | |
256 if (calc.equals(CalculationSelect.CALCULATION_SURFACE_CURVE)) { | |
257 callback = createSurfaceCurveCallback(); | |
258 } | |
259 else if (calc.equals(CalculationSelect.CALCULATION_DURATION_CURVE)) { | |
260 callback = createDurationCurveCallback(); | |
261 } | |
262 else if ( | |
263 calc.equals( | |
264 CalculationSelect.CALCULATION_DISCHARGE_LONGITUDINAL_CURVE)) | |
265 { | |
266 callback = createDischargeLongitudinalCurveCallback(); | |
267 } | |
268 else if (calc.equals(CalculationSelect.CALCULATION_DISCHARGE_CURVE)) { | |
269 callback = createDischargeCurveCallback(); | |
270 } | |
271 else { | |
272 return null; | |
273 } | |
274 | |
275 return compute(hash, callback); | |
276 } | |
277 | |
278 | |
279 protected ComputeCallback createSurfaceCurveCallback() { | |
280 return new ComputeCallback() { | |
281 public Object compute() { | |
282 return getWaterlevelData(); | |
283 } | |
284 }; | |
285 } | |
286 | |
287 | |
288 protected ComputeCallback createDurationCurveCallback() { | |
289 return new ComputeCallback() { | |
290 public Object compute() { | |
291 return getDurationCurveData(); | |
292 } | |
293 }; | |
294 } | |
295 | |
296 | |
297 protected ComputeCallback createDischargeLongitudinalCurveCallback() { | |
298 return new ComputeCallback() { | |
299 public Object compute() { | |
300 return getDischargeLongitudinalSectionData(); | |
301 } | |
302 }; | |
303 } | |
304 | |
305 | |
306 protected ComputeCallback createDischargeCurveCallback() { | |
307 return new ComputeCallback() { | |
308 public Object compute() { | |
309 return getComputedDischargeCurveData(); | |
310 } | |
311 }; | |
312 } | |
313 | |
314 | |
244 /** | 315 /** |
245 * Returns the data that is computed by a waterlevel computation. | 316 * Returns the data that is computed by a waterlevel computation. |
246 * | 317 * |
247 * @return an array of data triples that consist of W, Q and Kms. | 318 * @return an array of data triples that consist of W, Q and Kms. |
248 */ | 319 */ |
275 WstValueTable wst = WstValueTableFactory.getTable(river); | 346 WstValueTable wst = WstValueTableFactory.getTable(river); |
276 if (wst == null) { | 347 if (wst == null) { |
277 throw new NullPointerException("No Wst found for selected river."); | 348 throw new NullPointerException("No Wst found for selected river."); |
278 } | 349 } |
279 | 350 |
280 HashSet<Integer> failed = new HashSet<Integer>(); | |
281 | |
282 WQKms[] results = computeWaterlevelData( | 351 WQKms[] results = computeWaterlevelData( |
283 kms, qs, wst, river.getKmUp(), failed); | 352 kms, qs, ws, wst, river.getKmUp()); |
284 | |
285 // TODO Introduce a caching mechanism here! | |
286 | |
287 setWaterlevelNames( | |
288 results, qSel ? qs : ws, qSel ? "Q" : "W", failed); | |
289 | 353 |
290 return results; | 354 return results; |
291 } | 355 } |
292 | |
293 | |
294 /** | |
295 * Sets the name for waterlevels where each WQKms in <i>r</i> represents a | |
296 * column. | |
297 * | |
298 * @param r The waterlevel columns. | |
299 * @param v The input values of the computations. | |
300 * @param wq The WQ mode - can be one of "W" or "Q". | |
301 */ | |
302 public static void setWaterlevelNames( | |
303 WQKms[] r, | |
304 double[] v, | |
305 String wq, | |
306 Set failed | |
307 ) { | |
308 int pos = 0; | |
309 for (int i = 0; i < v.length; i++) { | |
310 if (!failed.contains(i)) { | |
311 r[pos++].setName(wq + "=" + v[i]); | |
312 } | |
313 } | |
314 } | |
315 | |
316 | 356 |
317 /** | 357 /** |
318 * Computes the data of a waterlevel computation based on the interpolation | 358 * Computes the data of a waterlevel computation based on the interpolation |
319 * in WstValueTable. | 359 * in WstValueTable. |
320 * | 360 * |
323 * @param wst The WstValueTable used for the interpolation. | 363 * @param wst The WstValueTable used for the interpolation. |
324 * | 364 * |
325 * @return an array of data triples that consist of W, Q and Kms. | 365 * @return an array of data triples that consist of W, Q and Kms. |
326 */ | 366 */ |
327 public static WQKms[] computeWaterlevelData( | 367 public static WQKms[] computeWaterlevelData( |
328 double[] kms, | 368 double [] kms, |
329 double[] qs, | 369 double [] qs, |
370 double [] ws, | |
330 WstValueTable wst, | 371 WstValueTable wst, |
331 boolean up, | 372 boolean up |
332 Set<Integer> failed | |
333 ) { | 373 ) { |
334 logger.info("WINFOArtifact.computeWaterlevelData"); | 374 logger.info("WINFOArtifact.computeWaterlevelData"); |
335 | 375 |
336 WQKms[] wqkms = new WQKms[qs.length]; | 376 Calculation1 calculation = new Calculation1(kms, qs, ws, up); |
337 | 377 |
338 ArrayList<WQKms> results = new ArrayList<WQKms>(); | 378 WQKms[] wqkms = calculation.calculate(wst); |
339 | 379 |
340 int referenceIndex = up ? 0 : kms.length-1; | 380 return wqkms; |
341 | |
342 for (int i = 0; i < qs.length; i++) { | |
343 double [] oqs = new double[kms.length]; | |
344 double [] ows = new double[kms.length]; | |
345 WstValueTable.QPosition qPosition = | |
346 wst.interpolate(qs[i], kms[referenceIndex], kms, ows, oqs); | |
347 if (qPosition != null) { | |
348 results.add(new WQKms(kms, oqs, ows)); | |
349 } | |
350 else { | |
351 logger.warn("interpolation failed for q = " + qs[i]); | |
352 failed.add(i); | |
353 } | |
354 } | |
355 | |
356 return results.toArray(new WQKms[results.size()]); | |
357 } | 381 } |
358 | 382 |
359 | 383 |
360 /** | 384 /** |
361 * Returns the data that is computed by a duration curve computation. | 385 * Returns the data that is computed by a duration curve computation. |
387 | 411 |
388 WstValueTable wst = WstValueTableFactory.getTable(r); | 412 WstValueTable wst = WstValueTableFactory.getTable(r); |
389 if (wst == null) { | 413 if (wst == null) { |
390 throw new NullPointerException("No Wst found for selected river."); | 414 throw new NullPointerException("No Wst found for selected river."); |
391 } | 415 } |
392 | |
393 // TODO Introduce a caching mechanism here! | |
394 | 416 |
395 return computeDurationCurveData(g, wst, locations[0]); | 417 return computeDurationCurveData(g, wst, locations[0]); |
396 } | 418 } |
397 | 419 |
398 | 420 |
414 Object[] obj = MainValuesFactory.getDurationCurveData(gauge); | 436 Object[] obj = MainValuesFactory.getDurationCurveData(gauge); |
415 | 437 |
416 int[] days = (int[]) obj[0]; | 438 int[] days = (int[]) obj[0]; |
417 double[] qs = (double[]) obj[1]; | 439 double[] qs = (double[]) obj[1]; |
418 | 440 |
419 double[] interpolatedW = new double[qs.length]; | 441 Calculation3 calculation = new Calculation3(location, days, qs); |
420 interpolatedW = wst.interpolateW(location, qs, interpolatedW); | 442 |
421 | 443 // TODO: report the errors to the user. |
422 WQDay wqday = new WQDay(qs.length); | 444 return calculation.calculate(wst); |
423 | |
424 for (int i = 0; i < days.length; i++) { | |
425 wqday.add(days[i], interpolatedW[i], qs[i]); | |
426 } | |
427 | |
428 return wqday; | |
429 } | 445 } |
430 | 446 |
431 | 447 |
432 /** | 448 /** |
433 * Returns the data that is computed by a discharge curve computation. | 449 * Returns the data that is computed by a discharge curve computation. |
456 throw new NullPointerException("No Wst found for selected river."); | 472 throw new NullPointerException("No Wst found for selected river."); |
457 } | 473 } |
458 | 474 |
459 WQKms wqkms = computeDischargeCurveData(wst, locations[0]); | 475 WQKms wqkms = computeDischargeCurveData(wst, locations[0]); |
460 | 476 |
461 // TODO Introduce a caching mechanism here! | |
462 | |
463 setComputedDischargeCurveNames(wqkms, locations[0]); | |
464 | |
465 return wqkms; | 477 return wqkms; |
466 } | |
467 | |
468 | |
469 /** | |
470 * Sets the name of the computed discharge curve data. | |
471 * | |
472 * @param wqkms The computed WQKms object. | |
473 * @param l The location used for the computation. | |
474 */ | |
475 public static void setComputedDischargeCurveNames(WQKms wqkms, double l) { | |
476 wqkms.setName(Double.toString(l)); | |
477 } | 478 } |
478 | 479 |
479 | 480 |
480 /** | 481 /** |
481 * Computes the data used to create computed discharge curves. | 482 * Computes the data used to create computed discharge curves. |
490 WstValueTable wst, | 491 WstValueTable wst, |
491 double location) | 492 double location) |
492 { | 493 { |
493 logger.info("WINFOArtifact.computeDischargeCurveData"); | 494 logger.info("WINFOArtifact.computeDischargeCurveData"); |
494 | 495 |
495 double[][] wqs = wst.interpolateWQ(location); | 496 Calculation2 calculation = new Calculation2(location); |
496 | 497 |
497 if (wqs == null) { | 498 WQKms wqkms = calculation.calculate(wst); |
498 logger.error("Cannot compute discharge curve data."); | 499 |
499 return null; | 500 // TODO: Report errors to the user |
500 } | |
501 | |
502 double[] ws = wqs[0]; | |
503 double[] qs = wqs[1]; | |
504 | |
505 WQKms wqkms = new WQKms(ws.length); | |
506 | |
507 for (int i = 0; i < ws.length; i++) { | |
508 wqkms.add(ws[i], qs[i], location); | |
509 } | |
510 | 501 |
511 return wqkms; | 502 return wqkms; |
512 } | 503 } |
513 | 504 |
514 private static final double [] getBounds(double [][] segments) { | 505 private static final double [] getBounds(double [][] segments) { |