Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java @ 5442:9575264f801d
Only create one FunctionResolver per BuildHelper. Creatin new ones over and over again is excessive.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Tue, 26 Mar 2013 21:55:23 +0100 |
parents | a929d9a9fa1e |
children |
line wrap: on
line source
package de.intevation.flys.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 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; /** 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 :