comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java @ 1888:abf5da3b285c

Added new (at fixed columns) interpolation mechanism. flys-artifacts/trunk@3248 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Tue, 15 Nov 2011 14:05:50 +0000
parents d2e217f438bc
children d002198c64a2
comparison
equal deleted inserted replaced
1887:d2e217f438bc 1888:abf5da3b285c
614 if (rowIndex < 1 || rowIndex > R1) { 614 if (rowIndex < 1 || rowIndex > R1) {
615 // do not extrapolate 615 // do not extrapolate
616 if (errors != null) { 616 if (errors != null) {
617 errors.addProblem(kms[i], "cannot find km"); 617 errors.addProblem(kms[i], "cannot find km");
618 } 618 }
619 ws[i] = Double.NaN; 619 ws[i] = Double.NaN;
620 continue; 620 continue;
621 } 621 }
622 Row r1 = rows.get(rowIndex-1); 622 Row r1 = rows.get(rowIndex-1);
623 Row r2 = rows.get(rowIndex); 623 Row r2 = rows.get(rowIndex);
624 624
627 errors.addProblem(kms[i], "cannot find w"); 627 errors.addProblem(kms[i], "cannot find w");
628 } 628 }
629 } 629 }
630 630
631 return qPosition; 631 return qPosition;
632 }
633
634 /**
635 * Linearly interpolate w at a km at a column of two rows.
636 *
637 * @param km position for which to interpolate.
638 * @param row1 first row.
639 * @param row2 second row.
640 * @param col column-index at which to look.
641 *
642 * @return Linearly interpolated w, NaN if one of the given rows was null.
643 */
644 public static double linearW(double km, Row row1, Row row2, int col) {
645 if (row1 == null || row2 == null) {
646 return Double.NaN;
647 }
648
649 return Linear.linear(km,
650 row1.km, row2.km,
651 row1.ws[col], row2.ws[col]);
652 }
653
654 /**
655 * Do interpolation/lookup of W and Q within columns (i.e. ignoring values
656 * of other columns).
657 * @param km position (km) at which to interpolate/lookup.
658 * @return [[q0, q1, .. qx] , [w0, w1, .. wx]] (can contain NaNs)
659 */
660 public double [][] interpolateWQColumnwise(double km) {
661 double [] qs = new double[columns.length];
662 double [] ws = new double[columns.length];
663
664 // Find out row from where we will start searching.
665 int rowIndex = Collections.binarySearch(rows, new Row(km));
666
667 if (rowIndex < 0) {
668 rowIndex = -rowIndex -1;
669 }
670
671 Row startRow = rows.get(rowIndex);
672
673 for (int col = 0; col < columns.length; col++) {
674 qs[col] = columns[col].getQRangeTree().findQ(km);
675 if (startRow.km == km && startRow.ws[col] != Double.NaN) {
676 // Great. W is defined at km.
677 ws[col] = startRow.ws[col];
678 continue;
679 }
680
681 // Search neighbouring rows that define w at this col.
682 Row rowBefore = null;
683 Row rowAfter = null;
684 for (int before = rowIndex; before >= 0; before--) {
685 if (!Double.isNaN(rows.get(before).ws[col])) {
686 rowBefore = rows.get(before);
687 break;
688 }
689 }
690 for (int after = rowIndex; after < rows.size(); after++) {
691 if (!Double.isNaN(rows.get(after).ws[col])) {
692 log.error("rows.get(after).ws[col] " + rows.get(after).ws[col]);
693 rowAfter = rows.get(after);
694 break;
695 }
696 }
697
698 ws[col] = linearW(km, rowBefore, rowAfter, col);
699 }
700
701 return new double [][] {qs, ws};
632 } 702 }
633 703
634 public QPosition getQPosition(double km, double q) { 704 public QPosition getQPosition(double km, double q) {
635 return getQPosition(km, q, new QPosition()); 705 return getQPosition(km, q, new QPosition());
636 } 706 }

http://dive4elements.wald.intevation.org