diff flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java @ 3318:dbe2f85bf160

merged flys-artifacts/2.8
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:35 +0200
parents 0c8a6145098b
children 67bbcee26e21
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java	Fri Sep 28 12:14:35 2012 +0200
@@ -0,0 +1,166 @@
+package de.intevation.flys.exports;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.io.PrintWriter;
+
+import java.util.Locale;
+
+import de.intevation.artifacts.CallMeta;
+
+import de.intevation.flys.artifacts.model.WQ;
+import de.intevation.flys.artifacts.resources.Resources;
+
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+import org.apache.commons.math.analysis.interpolation.SplineInterpolator;
+import org.apache.commons.math.analysis.interpolation.LinearInterpolator;
+
+import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+import org.apache.log4j.Logger;
+
+public class ATWriter
+{
+    private static Logger logger = Logger.getLogger(ATWriter.class);
+
+    public static final int COLUMNS = 10;
+
+    public static final String I18N_AT_HEADER =
+        "export.discharge.curve.at.header";
+
+    public static final String EMPTY = "         ";
+
+    protected double minW;
+    protected double maxW;
+    protected double minQ;
+    protected double maxQ;
+
+    protected UnivariateRealFunction qFunc;
+
+    public ATWriter() {
+    }
+
+    public ATWriter(WQ wq) throws IllegalArgumentException {
+
+        int [] bounds = wq.longestIncreasingWRangeIndices();
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("exporting w between indices " +
+                bounds[0] + " and " + bounds[1] + " (" +
+                wq.getW(bounds[0]) + ", " + wq.getW(bounds[1]));
+        }
+
+        if (bounds[1]-bounds[0] < 1) { // Only first w can be written out.
+            minW = maxW = wq.getW(bounds[0]);
+            minQ = maxQ = wq.getQ(bounds[0]);
+            // constant function
+            qFunc = new PolynomialFunction(new double [] { minQ });
+            return;
+        }
+
+        double [] ws = new double[bounds[1]-bounds[0]];
+        double [] qs = new double[ws.length];
+
+        for (int i = 0; i < ws.length; ++i) {
+            int idx = bounds[0]+i;
+            ws[i] = wq.getW(idx);
+            qs[i] = wq.getQ(idx);
+        }
+
+        qFunc = ws.length < 3
+            ? new LinearInterpolator().interpolate(ws, qs)
+            : new SplineInterpolator().interpolate(ws, qs);
+
+        minW = wq.getW(bounds[0]);
+        maxW = wq.getW(bounds[1]);
+        minQ = wq.getQ(bounds[0]);
+        maxQ = wq.getQ(bounds[1]);
+    }
+
+    public double getQ(double w) {
+
+        try {
+            return qFunc.value(w);
+        }
+        catch (FunctionEvaluationException aode) {
+            // should not happen
+            logger.warn("spline interpolation failed", aode);
+            return w <= minW ? minQ : maxQ;
+        }
+    }
+
+    public static void printQ(PrintWriter out, double q) {
+        String format;
+             if (q <   1d) format = " % 8.3f";
+        else if (q <  10d) format = " % 8.2f";
+        else if (q < 100d) format = " % 8.1f";
+        else {
+            format = " % 8.0f";
+            if (q > 1000d) q = Math.rint(q/10d)*10d;
+        }
+        out.printf(Locale.US, format, q);
+    }
+
+
+    protected static void printHeader(
+        PrintWriter out,
+        CallMeta    callMeta,
+        String      river,
+        double      km
+    ) {
+        out.println(Resources.getMsg(
+            callMeta,
+            I18N_AT_HEADER,
+            I18N_AT_HEADER,
+            new Object[] { river, km } ));
+    }
+
+
+    public void write(Writer writer, CallMeta meta, String river, double km)
+    throws IOException
+    {
+        PrintWriter out = new PrintWriter(writer);
+
+        // a header is required, because the desktop version of FLYS will skip
+        // the first row.
+        printHeader(out, meta, river, km);
+
+        double rest = (minW * 100.0) % 10.0;
+
+        double startW = Math.rint((minW - rest*0.01)*10.0)*0.1;
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("startW: " + startW);
+            logger.debug("rest: " + rest);
+        }
+
+        int col = 0;
+        for (double w = startW; w <= maxW; w += 0.01) {
+            if (col == 0) {
+                out.printf(Locale.US, "%8d", (int)Math.round(w*100.0));
+            }
+
+            if (w < minW) {
+                out.print(EMPTY);
+            }
+            else {
+                printQ(out, getQ(w));
+            }
+
+            if (++col >= COLUMNS) {
+                out.println();
+                col = 0;
+            }
+        }
+
+        if (col > 0) {
+            out.println();
+        }
+
+        out.flush();
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org