# HG changeset patch # User Sascha L. Teichmann # Date 1305457148 0 # Node ID c6b7ca0febcb1665896d8fdd467649afc5b4988b # Parent 1827050bb967f87beb53ae9f954e6e2d5562374d Fix step to fix issue69: Do the right calculation flys-artifacts/trunk@1924 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 1827050bb967 -r c6b7ca0febcb flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Fri May 13 11:26:29 2011 +0000 +++ b/flys-artifacts/ChangeLog Sun May 15 10:59:08 2011 +0000 @@ -1,3 +1,11 @@ +2011-05-10 Sascha L. Teichmann + + First step to fix flys/issue69 + + * src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java: + New code path to implement the calculation of "Wasserstand/Wasspiegellage" + correctly. TODO 1: Use new path in UI. TODO 2: Remove unused old code. + 2011-05-13 Ingo Weinzierl * Changes: Prepared Changes for the upcoming release 2.3 - see Changes diff -r 1827050bb967 -r c6b7ca0febcb flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java Fri May 13 11:26:29 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java Sun May 15 10:59:08 2011 +0000 @@ -70,6 +70,22 @@ } // class Column + public static class QPosition { + + protected double q; + protected int index; + protected double weight; + + public QPosition() { + } + + public QPosition(double q, int index, double weight) { + this.index = index; + this.weight = weight; + } + + } // class Position + public static class Row implements Serializable, Comparable { @@ -333,6 +349,98 @@ return new double [][] { outWs, outQs }; } + + public QPosition getQPosition(double q) { + int qIndex = getQIndex(q); + + if (qIndex >= 0) { + // direct column match + return new QPosition(q, qIndex, 1.0); + } + + qIndex = -qIndex -1; + + if (qIndex < 0 || qIndex >= qs.length-1) { + // do not extrapolate + return null; + } + + return new QPosition( + q, qIndex, factor(q, qs[qIndex-1], qs[qIndex])); + } + + public QPosition getQPosition(Row other, double km, double q) { + + QPosition qpt = getQPosition(q); + QPosition qpo = other.getQPosition(q); + + if (qpt == null || qpo == null) { + return null; + } + + double kmWeight = factor(km, this.km, other.km); + + // XXX: Index interpolation is a bit sticky here! + + int index = (int)Math.round( + weight(kmWeight, qpt.index, qpo.index)); + + double weight = weight(kmWeight, qpt.weight, qpo.weight); + + return new QPosition(q, index, weight); + } + + public void storeWQ( + QPosition qPosition, + double [] ows, + double [] oqs, + int index + ) { + int qIdx = qPosition.index; + double qWeight = qPosition.weight; + + if (qWeight == 1.0) { + oqs[index] = qs[qIdx]; + ows[index] = ws[qIdx]; + } + else { + oqs[index] = weight(qWeight, qs[qIdx-1], qs[qIdx]); + ows[index] = weight(qWeight, ws[qIdx-1], ws[qIdx]); + } + } + + public void storeWQ( + Row other, + double km, + QPosition qPosition, + double [] ows, + double [] oqs, + int index + ) { + double kmWeight = factor(km, this.km, other.km); + + double tq, tw; + double oq, ow; + + int qIdx = qPosition.index; + double qWeight = qPosition.weight; + + if (qWeight == 1.0) { + tq = qs[qIdx]; + tw = ws[qIdx]; + oq = other.qs[qIdx]; + ow = other.ws[qIdx]; + } + else { + tq = weight(qWeight, qs[qIdx-1], qs[qIdx]); + tw = weight(qWeight, ws[qIdx-1], ws[qIdx]); + oq = weight(qWeight, other.qs[qIdx-1], other.qs[qIdx]); + ow = weight(qWeight, other.ws[qIdx-1], other.ws[qIdx]); + } + + oqs[index] = weight(kmWeight, oq, tq); + ows[index] = weight(kmWeight, ow, tw); + } } // class Row @@ -407,6 +515,69 @@ return r1.interpolateWQ(r2, km, steps); } + public boolean interpolate( + double q, + int referenceIndex, + double [] kms, + double [] ws, + double [] qs + ) { + Row kmKey = new Row(kms[referenceIndex]); + + int rowIndex = Collections.binarySearch(rows, kmKey); + + int R1 = rows.size()-1; + + QPosition qPosition = null; + + if (rowIndex >= 0) { // direct row match + qPosition = rows.get(rowIndex).getQPosition(q); + } + else { + rowIndex = -rowIndex -1; + + if (rowIndex < 1 || rowIndex >= R1) { + // do not extrapolate + return false; + } + + // interpolation case + Row r1 = rows.get(rowIndex-1); + Row r2 = rows.get(rowIndex); + + qPosition = r1.getQPosition(r2, kms[referenceIndex], q); + } + + if (qPosition == null) { + // we cannot locate q in reference row + return false; + } + + for (int i = 0; i < kms.length; ++i) { + kmKey.km = kms[i]; + rowIndex = Collections.binarySearch(rows, kmKey); + + if (rowIndex >= 0) { + // direct row match + rows.get(rowIndex).storeWQ(qPosition, ws, qs, i); + continue; + } + + rowIndex = -rowIndex -1; + + if (rowIndex < 1 || rowIndex >= R1) { + // do not extrapolate + ws[i] = qs[i] = Double.NaN; + continue; + } + Row r1 = rows.get(rowIndex-1); + Row r2 = rows.get(rowIndex); + r1.storeWQ(r2, kms[i], qPosition, ws, qs, i); + } + + return true; + } + public static WstValueTable getTable(River river) { return getTable(river, 0); }