comparison artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java @ 9599:4c73fe16533d

Softwaretests...20181219 10.1: changed handling of special cases at km range limits according to added specification by BfG
author mschaefer
date Tue, 12 Feb 2019 10:34:33 +0100
parents 17414e70746e
children
comparison
equal deleted inserted replaced
9598:17414e70746e 9599:4c73fe16533d
327 } else { 327 } else {
328 volumes.add(Double.valueOf(0.0)); 328 volumes.add(Double.valueOf(0.0));
329 areas.add(Double.valueOf(0.0)); 329 areas.add(Double.valueOf(0.0));
330 } 330 }
331 if (chDepth - getFieldValue(i, BunduResultType.depthFields, j) > 0.0001) { 331 if (chDepth - getFieldValue(i, BunduResultType.depthFields, j) > 0.0001) {
332 vExcav += computeMissingVolume(null, null, i, first, last, j, ExcavationMissingAreaComputer.Instance); 332 vExcav += computeMissingVolume(null, null, i, first, last, j, ExcavationMissingHeightComputer.Instance);
333 } 333 }
334 } 334 }
335 final double[] meanBedVolumeArea = computeMeanBedMissingAreaAndVolume(i, first, last); 335 final double[] meanBedVolumeArea = computeMeanBedMissingAreaAndVolume(i, first, last);
336 this.rows.get(i).putValue(BunduResultType.missVolumeMeanBed, meanBedVolumeArea[0]); 336 this.rows.get(i).putValue(BunduResultType.missVolumeMeanBed, meanBedVolumeArea[0]);
337 this.rows.get(i).putValue(BunduResultType.missAreaMeanBed, meanBedVolumeArea[1]); 337 this.rows.get(i).putValue(BunduResultType.missAreaMeanBed, meanBedVolumeArea[1]);
350 final int field, final MissingHeightComputer heightcomputer) { 350 final int field, final MissingHeightComputer heightcomputer) {
351 351
352 final double dhCurr = heightcomputer.missingHeight(this.rows.get(current), current, first, last, field); 352 final double dhCurr = heightcomputer.missingHeight(this.rows.get(current), current, first, last, field);
353 final double dhPrev = heightcomputer.missingHeight(this.rows.get(current - 1), current - 1, first, last, field); 353 final double dhPrev = heightcomputer.missingHeight(this.rows.get(current - 1), current - 1, first, last, field);
354 final double dhNext = heightcomputer.missingHeight(this.rows.get(current + 1), current + 1, first, last, field); 354 final double dhNext = heightcomputer.missingHeight(this.rows.get(current + 1), current + 1, first, last, field);
355 final double kmCurr = missingKm(current); 355 final double kmCurr = kmOfRow(current);
356 final double kmPrev = missingKm(current - 1); 356 final double kmPrev = kmOfRow(current - 1);
357 final double kmNext = missingKm(current + 1); 357 final double kmNext = kmOfRow(current + 1);
358 final double width = getFieldValue(current, BunduResultType.missWidthFields, field); 358 final double width = getFieldValue(current, BunduResultType.missWidthFields, field);
359 final double area1 = Double.isNaN(kmPrev) ? 0.0 : (0.25 * dhPrev + 0.75 * dhCurr) * width; 359 final double area1 = (0.25 * dhPrev + 0.75 * dhCurr) * width;
360 final double area2 = Double.isNaN(kmNext) ? 0.0 : (0.75 * dhCurr + 0.25 * dhNext) * width; 360 final double dist1 = Double.isNaN(kmPrev) ? 0.0 : Math.abs(kmCurr - kmPrev) * KM_TO_M / 2;
361 final double volume = Double.valueOf((Math.abs(kmCurr - kmPrev) * KM_TO_M / 2 * area1) + (Math.abs(kmNext - kmCurr) * KM_TO_M / 2 * area2)); 361 final double area2 = (0.75 * dhCurr + 0.25 * dhNext) * width;
362 final double dist2 = Double.isNaN(kmNext) ? 0.0 : Math.abs(kmNext - kmCurr) * KM_TO_M / 2;
363 final double volume = dist1 * area1 + dist2 * area2;
362 if (volumes != null) 364 if (volumes != null)
363 volumes.add(volume); 365 volumes.add(volume);
364 if (areas != null) { 366 if (areas != null) {
365 if (!Double.isNaN(volume)) 367 if (!Double.isNaN(volume))
366 areas.add(Double.valueOf(area1 + area2)); 368 areas.add(Double.valueOf(area1 + area2));
369 } 371 }
370 return volume; 372 return volume;
371 } 373 }
372 374
373 /** 375 /**
374 * Interface for the function that computes the missing height of a field 376 * Interface for the function that computes/gets the missing height of a field
375 */ 377 */
376 private interface MissingHeightComputer { 378 private interface MissingHeightComputer {
377 /** 379 /**
378 * Gets the missing area of a field and a row if in range, otherwise 0.0 380 * Gets the missing height of a field and a row if in range, otherwise 0.0
379 */ 381 */
380 double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex); 382 double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex);
383 /**
384 * Gets the mean missing height of a row if in range, otherwise 0.0
385 */
386 double missingMeanHeight(final ResultRow row, final int rowIndex, final int first, final int last);
381 } 387 }
382 388
383 /** 389 /**
384 * Computation of the actual missing height of a field 390 * Computation of the actual missing height of a field
385 */ 391 */
391 */ 397 */
392 @SuppressWarnings("unchecked") 398 @SuppressWarnings("unchecked")
393 @Override 399 @Override
394 public double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex) { 400 public double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex) {
395 if ((first <= rowIndex) && (rowIndex <= last)) { 401 if ((first <= rowIndex) && (rowIndex <= last)) {
396 return ((List<Double>) row.getValue(BunduResultType.missDepthFields)).get(fieldIndex - 1).doubleValue(); 402 final double dh = ((List<Double>) row.getValue(BunduResultType.missDepthFields)).get(fieldIndex - 1).doubleValue();
403 return (!Double.isNaN(dh) ? dh : 0.0);
397 } 404 }
398 else 405 else
399 return 0.0; 406 return 0.0;
400 } 407 }
408
409 /**
410 * Gets the missing mean height of a row if in range, otherwise 0.0
411 */
412 @Override
413 public double missingMeanHeight(final ResultRow row, final int rowIndex, final int first, final int last) {
414 if ((first <= rowIndex) && (rowIndex <= last)) {
415 final double dh = row.getDoubleValue(BunduResultType.missDepthMeanBed);
416 return (!Double.isNaN(dh) ? dh : 0.0);
417 }
418 else
419 return 0.0;
420 }
401 } 421 }
402 422
403 /** 423 /**
404 * Computation of the excavation height of a field 424 * Computation of the excavation height of a field
405 */ 425 */
406 private static class ExcavationMissingAreaComputer implements MissingHeightComputer { 426 private static class ExcavationMissingHeightComputer implements MissingHeightComputer {
407 public static MissingHeightComputer Instance = new ExcavationMissingAreaComputer(); 427 public static MissingHeightComputer Instance = new ExcavationMissingHeightComputer();
408 428
409 /** 429 /**
410 * Gets the excavation height of a field and a row if in range, otherwise 0.0 430 * Gets the excavation height of a field and a row if in range, otherwise 0.0
411 */ 431 */
412 @SuppressWarnings("unchecked") 432 @SuppressWarnings("unchecked")
413 @Override 433 @Override
414 public double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex) { 434 public double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex) {
415 if ((first <= rowIndex) && (rowIndex <= last)) { 435 if ((first <= rowIndex) && (rowIndex <= last)) {
416 final double channeldepth = row.getDoubleValue(BunduResultType.channelDepth) + EXCAVATION_DEPTH; 436 final double channeldepth = row.getDoubleValue(BunduResultType.channelDepth) + EXCAVATION_DEPTH;
417 final double fielddepth = ((List<Double>) row.getValue(BunduResultType.depthFields)).get(fieldIndex - 1).doubleValue(); 437 final double fielddepth = ((List<Double>) row.getValue(BunduResultType.depthFields)).get(fieldIndex - 1).doubleValue();
418 return (channeldepth - fielddepth); 438 return (!Double.isNaN(channeldepth - fielddepth) ? Math.max(channeldepth - fielddepth, 0.0) : 0.0);
419 } 439 }
420 else 440 else
421 return 0.0; 441 return 0.0;
422 } 442 }
443
444 /**
445 * Gets the excavation mean height of a row if in range, otherwise 0.0
446 */
447 @Override
448 public double missingMeanHeight(final ResultRow row, final int rowIndex, final int first, final int last) {
449 if ((first <= rowIndex) && (rowIndex <= last)) {
450 final double channeldepth = row.getDoubleValue(BunduResultType.channelDepth) + EXCAVATION_DEPTH;
451 final double flowdepth = row.getDoubleValue(BunduResultType.flowdepthMeanBed);
452 return (!Double.isNaN(channeldepth - flowdepth) ? Math.max(channeldepth - flowdepth, 0.0) : 0.0);
453 }
454 else
455 return 0.0;
456 }
423 } 457 }
424 458
425 /** 459 /**
426 * Computes the missing area and volume of the mean bed level of a km row 460 * Computes the missing area and volume of the mean bed level of a km row
427 */ 461 */
428 private double[] computeMeanBedMissingAreaAndVolume(final int current, final int first, final int last) { 462 private double[] computeMeanBedMissingAreaAndVolume(final int current, final int first, final int last) {
429 463
430 final double dhCurr = meanBedMissingHeight(current, first, last); 464 final double dhCurr = ActualMissingHeightComputer.Instance.missingMeanHeight(this.rows.get(current), current, first, last);
431 if (dhCurr < 0.0001) 465 if (dhCurr < 0.0001)
432 return new double[] { 0.0, 0.0 }; 466 return new double[] { 0.0, 0.0 };
433 final double dhPrev = meanBedMissingHeight(current - 1, first, last); 467 final double dhPrev = ActualMissingHeightComputer.Instance.missingMeanHeight(this.rows.get(current - 1), current - 1, first, last);
434 final double dhNext = meanBedMissingHeight(current + 1, first, last); 468 final double dhNext = ActualMissingHeightComputer.Instance.missingMeanHeight(this.rows.get(current + 1), current + 1, first, last);
435 final double kmCurr = missingKm(current); 469 final double kmCurr = kmOfRow(current);
436 final double kmPrev = missingKm(current - 1); 470 final double kmPrev = kmOfRow(current - 1);
437 final double kmNext = missingKm(current + 1); 471 final double kmNext = kmOfRow(current + 1);
438 final double width = this.rows.get(current).getDoubleValue(BunduResultType.channelWidth); 472 final double width = this.rows.get(current).getDoubleValue(BunduResultType.channelWidth);
439 final double area1 = Double.isNaN(kmPrev) ? 0.0 : (0.25 * dhPrev + 0.75 * dhCurr) * width; 473 final double area1 = (0.25 * dhPrev + 0.75 * dhCurr) * width;
440 final double area2 = Double.isNaN(kmNext) ? 0.0 : (0.75 * dhCurr + 0.25 * dhNext) * width; 474 final double dist1 = Double.isNaN(kmPrev) ? 0.0 : Math.abs(kmCurr - kmPrev) * KM_TO_M / 2;
441 final double volume = Double.valueOf((Math.abs(kmCurr - kmPrev) * KM_TO_M / 2 * area1) + (Math.abs(kmNext - kmCurr) * KM_TO_M / 2 * area2)); 475 final double area2 = (0.75 * dhCurr + 0.25 * dhNext) * width;
442 final double area = Double.isNaN(volume) ? Double.NaN : Double.valueOf(area1 + area2); 476 final double dist2 = Double.isNaN(kmNext) ? 0.0 : Math.abs(kmNext - kmCurr) * KM_TO_M / 2;
477 final double volume = dist1 * area1 + dist2 * area2;
478 final double area = Double.isNaN(volume) ? Double.NaN : area1 + area2;
443 return new double[] { volume, area }; 479 return new double[] { volume, area };
444 } 480 }
445 481
446 /** 482 /**
447 * Gets the missing height of the mean bed level and a row if in range, otherwise 0.0 483 * Gets the km of a row index if within range, otherwise NaN
448 */ 484 */
449 private double meanBedMissingHeight(final int rowIndex, final int first, final int last) { 485 private double kmOfRow(final int rowIndex) {
450 if ((first <= rowIndex) && (rowIndex <= last)) { 486 if ((0 <= rowIndex) && (rowIndex <= this.rows.size() - 1)) // && (this.rows.get(rowIndex).getValue(BunduResultType.hasMissingDepth) != null))
451 final double dh = this.rows.get(rowIndex).getDoubleValue(BunduResultType.channelDepth)
452 - this.rows.get(rowIndex).getDoubleValue(BunduResultType.flowdepthMeanBed);
453 if (dh > 0.0)
454 return dh;
455 return 0.0;
456 }
457 return 0.0;
458 }
459
460 /**
461 * Gets the km of a row if within range, otherwise NaN
462 */
463 private double missingKm(final int rowIndex) {
464 if ((0 <= rowIndex) && (rowIndex <= this.rows.size() - 1) && (this.rows.get(rowIndex).getValue(BunduResultType.hasMissingDepth) != null))
465 return this.rows.get(rowIndex).getDoubleValue(GeneralResultType.station); 487 return this.rows.get(rowIndex).getDoubleValue(GeneralResultType.station);
466 return Double.NaN; 488 return Double.NaN;
467 } 489 }
468 490
469 /** 491 /**

http://dive4elements.wald.intevation.org