changeset 329:0b2358bc716d

Discharge table: Added static method getWForQ() to interpolate a w value for a given q value based on a given discharge table. flys-artifacts/trunk@1727 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 19 Apr 2011 11:05:27 +0000
parents 07e642030172
children 4791fd92a208
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java
diffstat 2 files changed, 64 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Tue Apr 19 10:32:31 2011 +0000
+++ b/flys-artifacts/ChangeLog	Tue Apr 19 11:05:27 2011 +0000
@@ -1,3 +1,9 @@
+2011-04-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java:
+	  Added static method getWForQ() to interpolate a w value for
+	  a given q value based on a given discharge table.
+	
 2011-04-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java	Tue Apr 19 10:32:31 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java	Tue Apr 19 11:05:27 2011 +0000
@@ -4,6 +4,7 @@
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Arrays;
+import java.util.Comparator;
 
 import java.io.Serializable;
 
@@ -20,11 +21,23 @@
 public class DischargeTables
 implements   Serializable
 {
+    private static Logger log = Logger.getLogger(DischargeTables.class);
+
     public static final double DEFAULT_SCALE = 100.0;
 
     public static final int MASTER = 0;
 
-    private static Logger log = Logger.getLogger(DischargeTables.class);
+    public static final double EPSILON = 1e-5;
+
+    public static Comparator<double []> Q_COMPARATOR = 
+        new Comparator<double []>() {
+            public int compare(double [] a, double [] b) {
+                double d = a[0] - b[0];
+                if (d < -EPSILON) return -1;
+                if (d > +EPSILON) return +1;
+                return 0;
+            }
+        };
 
     protected List<String> gaugeNames;
 
@@ -133,10 +146,54 @@
                 ++idx;
             }
 
+            // TODO: Do this db level.
+            Arrays.sort(vs, Q_COMPARATOR);
+
             values.put(gaugeName, vs);
         }
 
         return values;
     }
+
+    public static boolean getWForQ(
+        double [][] values, 
+        double q,  
+        double [] result
+    ) {
+        int index = Arrays.binarySearch(values, new double [] { q }, Q_COMPARATOR);
+        if (index >= 0) {
+            result[0] = values[1][index];
+            return true;
+        }
+
+        index = -index - 1; // insert position
+
+        if (index == 0 || index+1 >= values.length) {
+            // do not extraploate
+            return false;
+        }
+
+        double q1 = values[index  ][0];
+        double q2 = values[index+1][0];
+        double w1 = values[index  ][1];
+        double w2 = values[index+1][1];
+
+        // w1 = m*q1 + b
+        // w2 = m*q2 + b
+        // w2 - w1 = m*(q2 - q1)
+        // m = (w2 - w1)/(q2 - q1) # q2 != q1
+        // b = w1 - m*q1
+
+        if (q1 == q2) {
+            result[0] = 0.5*(w1 + w2);
+        }
+        else {
+            double m = (w2 - w1)/(q2 - q1);
+            double b = w1 - m*q1;
+            result[0] = q*m + b;
+        }
+
+        return true;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org