changeset 426:c6b7ca0febcb

Fix step to fix issue69: Do the right calculation flys-artifacts/trunk@1924 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 15 May 2011 10:59:08 +0000 (2011-05-15)
parents 1827050bb967
children 909196be11a0
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java
diffstat 2 files changed, 179 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- 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	<sascha.teichmann@intevation.de>
+
+	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 <ingo@intevation.de>
 
 	* Changes: Prepared Changes for the upcoming release 2.3 - see Changes
--- 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<Row>
     {
@@ -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);
     }

http://dive4elements.wald.intevation.org