diff flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java @ 1190:f514894ec2fd

merged flys-artifacts/2.5
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:17 +0200
parents 821aaceb2776
children 7d11ad5a52d5
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:17 2012 +0200
@@ -0,0 +1,143 @@
+package de.intevation.flys.exports;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.io.PrintWriter;
+
+import java.util.Locale;
+
+import de.intevation.flys.artifacts.model.WQ;
+
+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 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;
+        }
+    }
+
+    protected 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);
+    }
+
+    public void write(Writer writer) throws IOException {
+
+        PrintWriter out = new PrintWriter(writer);
+
+        double rest = Math.abs(minW % COLUMNS);
+
+        double startW = Math.round(minW*10.0)/10.0;
+        if (rest >= 1d) {
+            startW -= 0.1;
+            out.printf(Locale.US, "%8d", (int)Math.round(startW*100.0));
+            int columns = (int)Math.floor(rest);
+            for (int i = columns; i < COLUMNS; ++i) {
+                out.print(EMPTY);
+            }
+            for (int i = COLUMNS-columns; i < COLUMNS; ++i) {
+                printQ(out, getQ(startW + i*0.01));
+            }
+            out.println();
+            startW += 0.1;
+        }
+
+        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));
+            }
+
+            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