diff flys-artifacts/src/main/java/org/dive4elements/river/exports/ATWriter.java @ 5831:bd047b71ab37

Repaired internal references
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 12:06:39 +0200
parents flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java@a929d9a9fa1e
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/org/dive4elements/river/exports/ATWriter.java	Thu Apr 25 12:06:39 2013 +0200
@@ -0,0 +1,204 @@
+package org.dive4elements.river.exports;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.io.PrintWriter;
+import java.math.BigDecimal;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import org.dive4elements.artifacts.CallMeta;
+
+import org.dive4elements.river.artifacts.model.WQ;
+import org.dive4elements.river.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;
+
+/** Write AT files. */
+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 I18N_AT_GAUGE_HEADER =
+        "export.discharge.curve.at.gauge.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 printGaugeHeader(
+        PrintWriter out,
+        CallMeta    callMeta,
+        String      river,
+        double      km,
+        String      gName,
+        BigDecimal  datum,
+        Date        date
+    ) {
+        DateFormat f = DateFormat.getDateInstance();
+        out.print(Resources.getMsg(
+            callMeta,
+            I18N_AT_GAUGE_HEADER,
+            I18N_AT_GAUGE_HEADER,
+            new Object[] { river, gName, f.format(date), datum } ));
+        out.print("\r\n");
+    }
+
+    protected static void printHeader(
+        PrintWriter out,
+        CallMeta    callMeta,
+        String      river,
+        double      km
+    ) {
+        out.print(Resources.getMsg(
+            callMeta,
+            I18N_AT_HEADER,
+            I18N_AT_HEADER,
+            new Object[] { river, km } ));
+        out.print("\r\n");
+    }
+
+    public void write(
+        Writer writer,
+        CallMeta meta,
+        String river,
+        double km,
+        String gName,
+        BigDecimal datum,
+        Date date,
+        double scale)
+    throws IOException
+    {
+        PrintWriter out = new PrintWriter(writer);
+
+        // A header is required, because the desktop version of FLYS will skip
+        // the first row.
+        if (gName != null) {
+            printGaugeHeader(out, meta, river, km, gName, datum, date);
+        }
+        else {
+            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 * scale));
+            }
+
+            if (w < minW) {
+                out.print(EMPTY);
+            }
+            else {
+                printQ(out, getQ(w));
+            }
+
+            if (++col >= COLUMNS) {
+                out.print("\r\n");
+                col = 0;
+            }
+        }
+
+        if (col > 0) {
+            out.print("\r\n");
+        }
+
+        out.flush();
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org