Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java @ 2418:899ca89f497e
Another partial fix for flys/issue499: Do the W to Q conversions
needed for 'W am Pegel' correctly.
flys-artifacts/trunk@4052 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Tue, 14 Feb 2012 16:48:13 +0000 |
parents | 59af81364eb1 |
children | 02254d763bc0 |
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java Tue Feb 14 09:02:51 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java Tue Feb 14 16:48:13 2012 +0000 @@ -4,7 +4,6 @@ import java.util.Map; import java.util.HashMap; import java.util.Arrays; -import java.util.Comparator; import java.io.Serializable; @@ -18,6 +17,8 @@ import de.intevation.flys.model.DischargeTable; import de.intevation.flys.model.DischargeTableValue; +import gnu.trove.TDoubleArrayList; + public class DischargeTables implements Serializable { @@ -124,42 +125,9 @@ // TODO: Filter by time interval DischargeTable table = tables.get(0); - boolean qSorted = true; - - final double[][] vs = - loadDischargeTableValues(table, scale, qSorted); - - if (!qSorted) { - log.debug("need to sort by q values"); - // TODO: Do this db level. - // XXX: This is so ugly :-( - Integer [] indices = new Integer[vs[0].length]; - for (int i = 0; i < indices.length; ++i) { - indices[i] = i; - } + double [][] vs = loadDischargeTableValues(table, scale); - Arrays.sort(indices, new Comparator<Integer>() { - public int compare(Integer a, Integer b) { - double va = vs[1][a]; - double vb = vs[1][b]; - double d = va - vb; - if (d < 0.0) return -1; - if (d > 0.0) return +1; - return 0; - } - }); - - double [][] vs2 = new double[2][vs[0].length]; - for (int i = 0; i < indices.length; ++i) { - vs2[0][i] = vs[0][indices[i]]; - vs2[1][i] = vs[1][indices[i]]; - } - values.put(gaugeName, vs2); - } - else { - values.put(gaugeName, vs); - } - + values.put(gaugeName, vs); } return values; @@ -176,82 +144,92 @@ */ public static double[][] loadDischargeTableValues( DischargeTable table, - double scale, - boolean qSorted + double scale ) { List<DischargeTableValue> dtvs = table.getDischargeTableValues(); final double [][] vs = new double[2][dtvs.size()]; - double lastQ = -Double.MAX_VALUE; - int idx = 0; for (DischargeTableValue dtv: dtvs) { double q = dtv.getQ().doubleValue(); vs[0][idx] = q * scale; vs[1][idx] = dtv.getW().doubleValue() * scale; ++idx; - - if (qSorted && lastQ > q) { - qSorted = false; - } - lastQ = q; } return vs; } + private static final double EPSILON = 1e-5; - public static double getQForW(double [][] values, double w) { + private static final boolean epsEquals(double a, double b) { + return Math.abs(a - b) < EPSILON; + } + + private static final boolean between(double a, double b, double x) { + if (a > b) { double t = a; a = b; b = t; } + return x > a && x < b; + } + + public static double [] getQsForW(double [][] values, double w) { boolean debug = log.isDebugEnabled(); if (debug) { - log.debug("calculating getQForW(" + w + ")"); - } - - int index = Arrays.binarySearch(values[1], w); - if (index >= 0) { - return values[0][index]; - } - - index = -index - 1; // insert position - - if (index < 1 || index >= values[0].length) { - // do not extraploate - if (debug) { - log.debug("we do not extrapolate: NaN"); - } - return Double.NaN; + log.debug("getQsForW: W = " + w); } - double w1 = values[1][index-1]; - double w2 = values[1][index ]; - double q1 = values[0][index-1]; - double q2 = values[0][index ]; + double [] qs = values[0]; + double [] ws = values[1]; - // q1 = m*w1 + b - // q2 = m*w2 + b - // q2 - q1 = m*(w2 - w1) - // m = (q2 - q1)/(w2 - w1) # w2 != w1 - // b = q1 - m*w1 + int N = Math.min(qs.length, ws.length); - double q; - if (w1 == w2) { - q = 0.5*(q1 + q2); + if (N == 0) { if (debug) { - log.debug("same w1 and w2: " + w1); + log.debug("Q(" + w + ") = []"); + } + return new double [0]; + } + + TDoubleArrayList outQs = new TDoubleArrayList(); + + if (epsEquals(ws[0], w)) { + outQs.add(qs[0]); + } + + for (int i = 1; i < N; ++i) { + if (epsEquals(ws[i], w)) { + outQs.add(qs[i]); + } + else if (between(ws[i-1], ws[i], w)) { + double w1 = ws[i-1]; + double w2 = ws[i]; + double q1 = qs[i-1]; + double q2 = qs[i]; + + // q1 = m*w1 + b + // q2 = m*w2 + b + // q2 - q1 = m*(w2 - w1) + // m = (q2 - q1)/(w2 - w1) # w2 != w1 + // b = q1 - m*w1 + // w1 != w2 + + double m = (q2 - q1)/(w2 - w1); + double b = q1 - m*w1; + double q = w*m + b; + + outQs.add(q); } } - else { - double m = (q2 - q1)/(w2 - w1); - double b = q1 - m*w1; - q = w*m + b; + + double [] result = outQs.toNativeArray(); + + if (debug) { + log.debug("Q(" + w + ") = " + Arrays.toString(result)); } - if (debug) { - log.debug("Q(" + w + ") = " + q); - } - return q; + + return result; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :