# HG changeset patch # User Ingo Weinzierl # Date 1305649867 0 # Node ID c0bec245f6083c062178abfa7a84ef1916f0c569 # Parent a7947972fdeb91c3473310df598c3b9047b4678c Implemented writer that creates WSTs and enabled the WaterlevelExporter to create those. flys-artifacts/trunk@1938 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r a7947972fdeb -r c0bec245f608 flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Tue May 17 14:22:27 2011 +0000 +++ b/flys-artifacts/ChangeLog Tue May 17 16:31:07 2011 +0000 @@ -1,3 +1,19 @@ +2011-05-17 Ingo Weinzierl + + * src/main/java/de/intevation/flys/artifacts/model/WstLine.java: New. This + class is used to store the W/Q values of a specific kilometer of a WST. + + * src/main/java/de/intevation/flys/exports/WstWriter.java: New. A writer + that creates WSTs. + + TODO: The header of the WSTs is not finished. The Q descriptions are + missing. + + * src/main/java/de/intevation/flys/exports/WaterlevelExporter.java: + Enabled WST exports. + + * doc/conf/artifacts/winfo.xml: Registered the WST export for waterlevels. + 2011-05-17 Ingo Weinzierl * src/main/java/de/intevation/flys/utils/Formatter.java: New. This class diff -r a7947972fdeb -r c0bec245f608 flys-artifacts/doc/conf/artifacts/winfo.xml --- a/flys-artifacts/doc/conf/artifacts/winfo.xml Tue May 17 14:22:27 2011 +0000 +++ b/flys-artifacts/doc/conf/artifacts/winfo.xml Tue May 17 16:31:07 2011 +0000 @@ -162,6 +162,7 @@ + diff -r a7947972fdeb -r c0bec245f608 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstLine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstLine.java Tue May 17 16:31:07 2011 +0000 @@ -0,0 +1,88 @@ +package de.intevation.flys.artifacts.model; + +import gnu.trove.TDoubleArrayList; + + +/** + * A model class that is used to store a line of a WST. + * + * @author Ingo Weinzierl + */ +public class WstLine { + + /** The kilometer value of the line.*/ + protected double km; + + /** The W values.*/ + protected TDoubleArrayList ws; + + /** The Q values.*/ + protected TDoubleArrayList qs; + + + /** + * A constructor that builds a new WstLine for a specific kilometer. + * + * @param km The kilometer. + */ + public WstLine(double km) { + this.km = km; + this.ws = new TDoubleArrayList(); + this.qs = new TDoubleArrayList(); + } + + + /** + * Adds a pair of W/Q to this line. + * + * @param w The W value. + * @param q The Q value. + */ + public void add(double w, double q) { + ws.add(w); + qs.add(q); + } + + + /** + * Returns the kilometer of this line. + * + * @return the kilomter of this line. + */ + public double getKm() { + return km; + } + + + /** + * Returns the W value at index idx of this line. + * + * @param idx The position of the desired W value. + * + * @return the W at position idx. + */ + public double getW(int idx) { + return ws.size() > idx ? ws.get(idx) : -1d; + } + + + /** + * Returns the Q values of this line. + * + * @return the Q values of this line. + */ + public double[] getQs() { + return qs.toNativeArray(); + } + + + /** + * Returns the number of columns this line consists of. + * + * @return the columns this line consists of. + */ + public int getSize() { + return qs.size(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r a7947972fdeb -r c0bec245f608 flys-artifacts/src/main/java/de/intevation/flys/exports/WaterlevelExporter.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/WaterlevelExporter.java Tue May 17 14:22:27 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/WaterlevelExporter.java Tue May 17 16:31:07 2011 +0000 @@ -1,5 +1,6 @@ package de.intevation.flys.exports; +import java.io.IOException; import java.io.OutputStream; import java.text.NumberFormat; import java.util.ArrayList; @@ -28,6 +29,9 @@ private static Logger logger = Logger.getLogger(WaterlevelExporter.class); + public static final String FACET_WST = "wst"; + + public static final String CSV_KM_HEADER = "export.waterlevel.csv.header.km"; @@ -55,6 +59,24 @@ } + @Override + public void generate() + throws IOException + { + logger.debug("WaterlevelExporter.generate"); + + if (facet != null && facet.equals(AbstractExporter.FACET_CSV)) { + generateCSV(); + } + else if (facet != null && facet.equals(FACET_WST)) { + generateWST(); + } + else { + throw new IOException("invalid facet for exporter"); + } + } + + protected void addData(Artifact artifact) { data.add(getWaterlevelData(artifact)); } @@ -124,6 +146,42 @@ /** + * Generates the output in WST format. + */ + protected void generateWST() + throws IOException + { + logger.info("WaterlevelExporter.generateWST"); + + int cols = data.get(0).length; + WstWriter writer = new WstWriter(cols); + + writeWSTData(writer); + + writer.write(out); + } + + + protected void writeWSTData(WstWriter writer) { + logger.debug("WaterlevelExporter.writeWSTData"); + + double[] result = new double[3]; + + for (WQKms[] tmp: data) { + for (WQKms wqkms: tmp) { + int size = wqkms != null ? wqkms.size() : 0; + + for (int i = 0; i < size; i++) { + result = wqkms.get(i, result); + + writer.add(result); + } + } + } + } + + + /** * Returns the number formatter for kilometer values. * * @return the number formatter for kilometer values. diff -r a7947972fdeb -r c0bec245f608 flys-artifacts/src/main/java/de/intevation/flys/exports/WstWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/WstWriter.java Tue May 17 16:31:07 2011 +0000 @@ -0,0 +1,187 @@ +package de.intevation.flys.exports; + +import java.io.BufferedWriter; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.log4j.Logger; + +import de.intevation.flys.artifacts.model.WstLine; + + +/** + * A writer that creates WSTs. + * + * @author Ingo Weinzierl + */ +public class WstWriter { + + /** The logger used in this class.*/ + private static Logger logger = Logger.getLogger(WstWriter.class); + + + /** The default unit that is written into the header of the WST.*/ + public static final String DEFAULT_UNIT = "Wassserstand [NN + m]"; + + + /** The lines that need to be included for the export.*/ + protected Map lines; + + /** The locale used to format the values.*/ + protected Locale locale; + + /** The number of discharge columns.*/ + protected int cols; + + /** The last Q values.*/ + protected double[] qs; + + + + /** + * This constructor creates a new WstWriter with an OutputStream and a + * number of Q columns. + * + * @param out The output stream where the WST is written to. + * @param cols The number of columns of the resulting WST. + */ + public WstWriter(int cols) { + this.cols = cols; + this.qs = new double[cols]; + this.locale = Locale.US; + this.lines = new HashMap(); + + } + + + /** + * This method is used to create the WST from the data that has been + * inserted using add(double[]) before. + */ + public void write(OutputStream out) { + logger.info("WstWriter.write"); + + PrintWriter writer = new PrintWriter( + new BufferedWriter( + new OutputStreamWriter(out))); + + writeHeader(writer); + + Collection collection = new TreeMap(lines).values(); + + for (WstLine line: collection) { + writeWLine(writer, line); + } + + writer.flush(); + writer.close(); + } + + + /** + * This method is used to add a new line to the WST. + * + * @param wqkms A 3dim double array with [W,Q, KM]. + */ + public void add(double[] wqkms) { + Double km = wqkms[2]; + + WstLine line = lines.get(km); + + if (line == null) { + line = new WstLine(km.doubleValue()); + lines.put(km, line); + } + + line.add(wqkms[0], wqkms[1]); + } + + + /** + * This method writes the header of the WST. + * + * @param writer The PrintWriter that creates the output. + */ + protected void writeHeader(PrintWriter writer) { + logger.debug("WstWriter.writeHeader"); + + writer.println(cols); + + // TODO WRITE DISCHARGE COLUMNS + + writer.write("* KM "); + writer.write(DEFAULT_UNIT); + writer.println(); + } + + + /** + * This method writes a line with W values and a certain kilometer. + * + * @param writer The PrintWriter that is used to create the output. + * @param line The WstLine that should be written to the output. + */ + protected void writeWLine(PrintWriter writer, WstLine line) { + double km = line.getKm(); + double[] qs = line.getQs(); + int num = line.getSize(); + + if (dischargesChanged(qs)) { + writeQLine(writer, qs); + } + + writer.printf(locale, "%8.3f", km); + + for (int i = 0; i < num; i++) { + writer.printf(locale, "%9.2f", line.getW(i)); + } + + writer.println(); + } + + + /** + * Writes a discharge line (Q values) into a WST. + * + * @param qs the Q values for the next range. + */ + protected void writeQLine(PrintWriter writer, double[] qs) { + writer.write("*\u001f "); + + for (int i = 0; i < cols; i++) { + this.qs[i] = qs[i]; + + writer.printf(locale, "%9.2f", qs[i]); + } + + writer.println(); + } + + + /** + * This method determines if a Q has changed from the last line to the + * current one. + * + * @param newQs The Q values of the next line. + * + * @return true, if a Q value have changed, otherwise false. + */ + protected boolean dischargesChanged(double[] newQs) { + // XXX maybe there is a way to do this faster + for (int i = 0; i < cols; i++) { + if (Math.abs(newQs[i] - qs[i]) >= 0.001) { + return true; + } + } + + return false; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :