view flys-artifacts/src/main/java/de/intevation/flys/exports/WstWriter.java @ 2089:0da8874bd378

Added initial state to map artifact to be able to advance and step back. The map artifact overrides describe() to have the complete UI information in the describe response document. flys-artifacts/trunk@3613 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Raimund Renkert <raimund.renkert@intevation.de>
date Fri, 06 Jan 2012 12:02:10 +0000
parents 72bcbc308501
children d9fb3a178be4
line wrap: on
line source
package de.intevation.flys.exports;

import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
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 <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
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<Double, WstLine> lines;

    /** The column names.*/
    protected List<String> columnNames;

    /** 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.columnNames = new ArrayList<String>(cols);
        this.lines       = new HashMap<Double, WstLine>();
        this.qs          = new double[cols];
        this.locale      = Locale.US;
    }


    /**
     * 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)));

        this.qs = new double[cols];

        writeHeader(writer);

        Collection<WstLine> 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]);
    }


    public void addCorrected(double[] wqckms) {
        Double km = wqckms[2];

        WstLine line = lines.get(km);

        if (line == null) {
            line = new WstLine(km.doubleValue());
            lines.put(km, line);
        }

        line.add(wqckms[3], wqckms[1]);
    }


    /**
     * Adds a further column name.
     *
     * @param name The name of the new column.
     */
    public void addColumn(String name) {
        if (name != null) {
            cols++;

            String basename = name;

            int i = 0;
            while (columnNames.contains(name)) {
                name = basename + "_" + i++;

                if (name.length() > 9) {
                    name = name.substring(name.length() - 9);
                }
            }

            columnNames.add(name);
        }
    }


    /**
     * 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);
        writer.print("        ");

        for (String columnName: columnNames) {
            writer.printf(locale, "%9s", columnName);
        }

        writer.println();

        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 < qs.length; 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 :

http://dive4elements.wald.intevation.org