Mercurial > dive4elements > river
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 :