sascha@729: package de.intevation.flys.exports; sascha@729: sascha@729: import java.io.IOException; sascha@729: import java.io.Writer; sascha@729: import java.io.PrintWriter; rrenkert@4938: import java.math.BigDecimal; sascha@729: rrenkert@4938: import java.text.DateFormat; rrenkert@4938: import java.util.Date; sascha@729: import java.util.Locale; sascha@729: ingo@1658: import de.intevation.artifacts.CallMeta; ingo@1658: sascha@729: import de.intevation.flys.artifacts.model.WQ; ingo@1658: import de.intevation.flys.artifacts.resources.Resources; sascha@729: sascha@732: import org.apache.commons.math.analysis.UnivariateRealFunction; sascha@729: sascha@732: import org.apache.commons.math.analysis.interpolation.SplineInterpolator; sascha@732: import org.apache.commons.math.analysis.interpolation.LinearInterpolator; sascha@729: sascha@732: import org.apache.commons.math.analysis.polynomials.PolynomialFunction; sascha@732: sascha@732: import org.apache.commons.math.FunctionEvaluationException; sascha@729: sascha@729: import org.apache.log4j.Logger; sascha@729: sascha@729: public class ATWriter sascha@729: { sascha@729: private static Logger logger = Logger.getLogger(ATWriter.class); sascha@729: sascha@729: public static final int COLUMNS = 10; sascha@729: ingo@1658: public static final String I18N_AT_HEADER = ingo@1658: "export.discharge.curve.at.header"; ingo@1658: rrenkert@4941: public static final String I18N_AT_GAUGE_HEADER = rrenkert@4941: "export.discharge.curve.at.gauge.header"; rrenkert@4941: sascha@732: public static final String EMPTY = " "; sascha@729: sascha@729: protected double minW; sascha@729: protected double maxW; sascha@729: protected double minQ; sascha@729: protected double maxQ; sascha@729: sascha@732: protected UnivariateRealFunction qFunc; sascha@729: sascha@729: public ATWriter() { sascha@729: } sascha@729: sascha@729: public ATWriter(WQ wq) throws IllegalArgumentException { sascha@729: sascha@1033: int [] bounds = wq.longestIncreasingWRangeIndices(); sascha@729: sascha@1033: if (logger.isDebugEnabled()) { sascha@1033: logger.debug("exporting w between indices " + sascha@1033: bounds[0] + " and " + bounds[1] + " (" + sascha@1033: wq.getW(bounds[0]) + ", " + wq.getW(bounds[1])); sascha@1033: } sascha@1033: sascha@1033: if (bounds[1]-bounds[0] < 1) { // Only first w can be written out. sascha@1033: minW = maxW = wq.getW(bounds[0]); sascha@1033: minQ = maxQ = wq.getQ(bounds[0]); sascha@732: // constant function sascha@732: qFunc = new PolynomialFunction(new double [] { minQ }); sascha@729: return; sascha@729: } sascha@729: sascha@1033: double [] ws = new double[bounds[1]-bounds[0]]; sascha@729: double [] qs = new double[ws.length]; sascha@729: sascha@729: for (int i = 0; i < ws.length; ++i) { sascha@1033: int idx = bounds[0]+i; sascha@1033: ws[i] = wq.getW(idx); sascha@1033: qs[i] = wq.getQ(idx); sascha@729: } sascha@729: sascha@732: qFunc = ws.length < 3 sascha@732: ? new LinearInterpolator().interpolate(ws, qs) sascha@732: : new SplineInterpolator().interpolate(ws, qs); sascha@729: sascha@1033: minW = wq.getW(bounds[0]); sascha@1033: maxW = wq.getW(bounds[1]); sascha@1033: minQ = wq.getQ(bounds[0]); sascha@1033: maxQ = wq.getQ(bounds[1]); sascha@729: } sascha@729: sascha@729: public double getQ(double w) { sascha@729: sascha@729: try { sascha@729: return qFunc.value(w); sascha@729: } sascha@732: catch (FunctionEvaluationException aode) { sascha@729: // should not happen sascha@729: logger.warn("spline interpolation failed", aode); sascha@729: return w <= minW ? minQ : maxQ; sascha@729: } sascha@729: } sascha@729: sascha@3220: public static void printQ(PrintWriter out, double q) { sascha@729: String format; sascha@732: if (q < 1d) format = " % 8.3f"; sascha@732: else if (q < 10d) format = " % 8.2f"; sascha@732: else if (q < 100d) format = " % 8.1f"; sascha@729: else { sascha@729: format = " % 8.0f"; sascha@732: if (q > 1000d) q = Math.rint(q/10d)*10d; sascha@729: } sascha@729: out.printf(Locale.US, format, q); sascha@729: } sascha@729: sascha@729: rrenkert@4941: protected static void printGaugeHeader( ingo@1658: PrintWriter out, ingo@1658: CallMeta callMeta, ingo@1658: String river, rrenkert@4938: double km, rrenkert@4938: String gName, rrenkert@4938: BigDecimal datum, rrenkert@4938: Date date ingo@1658: ) { rrenkert@4938: DateFormat f = DateFormat.getDateInstance(); rrenkert@4911: out.print(Resources.getMsg( ingo@1658: callMeta, rrenkert@4941: I18N_AT_GAUGE_HEADER, rrenkert@4941: I18N_AT_GAUGE_HEADER, rrenkert@4938: new Object[] { river, gName, f.format(date), datum } )); rrenkert@4911: out.print("\r\n"); ingo@1658: } ingo@1658: rrenkert@4941: protected static void printHeader( rrenkert@4941: PrintWriter out, rrenkert@4941: CallMeta callMeta, rrenkert@4941: String river, rrenkert@4941: double km rrenkert@4941: ) { rrenkert@4941: out.print(Resources.getMsg( rrenkert@4941: callMeta, rrenkert@4941: I18N_AT_HEADER, rrenkert@4941: I18N_AT_HEADER, rrenkert@4941: new Object[] { river, km } )); rrenkert@4941: out.print("\r\n"); rrenkert@4941: } ingo@1658: rrenkert@4938: public void write( rrenkert@4938: Writer writer, rrenkert@4938: CallMeta meta, rrenkert@4938: String river, rrenkert@4938: double km, rrenkert@4938: String gName, rrenkert@4938: BigDecimal datum, rrenkert@4941: Date date, rrenkert@4941: double scale) ingo@1658: throws IOException ingo@1658: { sascha@729: PrintWriter out = new PrintWriter(writer); sascha@729: ingo@1658: // a header is required, because the desktop version of FLYS will skip ingo@1658: // the first row. rrenkert@4941: if (gName != null) { rrenkert@4941: printGaugeHeader(out, meta, river, km, gName, datum, date); rrenkert@4941: } rrenkert@4941: else { rrenkert@4941: printHeader(out, meta, river, km); rrenkert@4941: } rrenkert@4911: sascha@1682: double rest = (minW * 100.0) % 10.0; sascha@729: sascha@1682: double startW = Math.rint((minW - rest*0.01)*10.0)*0.1; sascha@1682: sascha@1682: if (logger.isDebugEnabled()) { sascha@1682: logger.debug("startW: " + startW); sascha@1682: logger.debug("rest: " + rest); sascha@729: } sascha@729: sascha@729: int col = 0; sascha@732: for (double w = startW; w <= maxW; w += 0.01) { sascha@732: if (col == 0) { rrenkert@4941: out.printf(Locale.US, "%8d", (int)Math.round(w * scale)); sascha@732: } sascha@729: sascha@1682: if (w < minW) { sascha@1682: out.print(EMPTY); sascha@1682: } sascha@1682: else { sascha@1682: printQ(out, getQ(w)); sascha@1682: } sascha@729: sascha@729: if (++col >= COLUMNS) { teichmann@4947: out.print("\r\n"); sascha@729: col = 0; sascha@729: } sascha@729: } sascha@729: sascha@729: if (col > 0) { teichmann@4947: out.print("\r\n"); sascha@729: } sascha@729: sascha@729: out.flush(); sascha@729: } sascha@729: } sascha@729: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :