view artifacts/src/main/java/org/dive4elements/river/exports/minfo/SedimentLoadExporter.java @ 7076:7f600001c807 generator-refactoring

Add LTR inversion code to diagram generator. This code is used in serveral diagrams and as it modifies a whole diagram it should be central. (This should also make maintenance easier). This function can be called by processors to make sure that their data is plotted with an LTR waterflow.
author Andre Heinecke <aheinecke@intevation.de>
date Fri, 20 Sep 2013 16:33:22 +0200
parents acb63fd3c8d3
children 0a337f0005c2
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.exports.minfo;

import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;

import java.io.OutputStream;
import java.io.IOException;

import java.text.NumberFormat;

import org.w3c.dom.Document;

import org.apache.log4j.Logger;

import org.dive4elements.artifacts.CallContext;

import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.minfo.SedimentLoad;
import org.dive4elements.river.artifacts.model.minfo.SedimentLoadFraction;
import org.dive4elements.river.artifacts.model.minfo.SedimentLoadResult;

import org.dive4elements.river.exports.AbstractExporter;

import org.dive4elements.river.utils.Formatter;

import au.com.bytecode.opencsv.CSVWriter;


/**
 * Do CSV export for sediment load calculations (will also be shown in
 * client). */
public class SedimentLoadExporter
extends      AbstractExporter
{
    /** Private logger. */
    private static Logger logger = Logger.getLogger(SedimentLoadExporter.class);

    // i18n keys.
    public static final String CSV_KM =
        "export.sedimentload_ls.csv.header.km";

    public static final String CSV_YEAR =
        "export.sedimentload_ls.csv.header.year";

    public static final String CSV_COARSE =
        "export.sedimentload_ls.csv.header.coarse";

    public static final String CSV_FINEMIDDLE =
        "export.sedimentload_ls.csv.header.finemiddle";

    public static final String CSV_SAND =
        "export.sedimentload_ls.csv.header.sand";

    public static final String CSV_SUSP_SAND =
        "export.sedimentload_ls.csv.header.suspsand";

    public static final String CSV_SUSP_SAND_BB =
        "export.sedimentload_ls.csv.header.suspsandbb";

    public static final String CSV_SUSP_SEDIMENT =
        "export.sedimentload_ls.csv.header.suspsediment";

    public static final String CSV_TOTAL =
        "export.sedimentload_ls.csv.header.total";


    /** Collected results. */
    private SedimentLoadResult[] results;

    /** Empty constructor. */
    public SedimentLoadExporter() {
    }

    /** Trivial init. */
    @Override
    public void init(Document request, OutputStream out, CallContext context) {
        super.init(request, out, context);
        logger.debug("init");
        results = new SedimentLoadResult[0];
    }


    /** Process all stored data and write csv. */
    @Override
    protected void writeCSVData(CSVWriter writer) throws IOException {
        writeCSVHeader(writer);

        for (SedimentLoadResult result: results) {
            String years = (result.getEndYear() == 0)
                    ? result.getStartYear() + " "
                    : result.getStartYear() + "-" + result.getEndYear();
            SedimentLoad load = result.getLoad();
            // Put load.getName()+load.getDescription()}); somewhere?
            for (double km: new TreeSet<Double>(load.getKms())) {
                SedimentLoadFraction fraction = load.getFraction(km);
                writeRecord(writer, km, years, fraction);
            }
        }
    }


    /** Return space when val is NaN, apply NumberFormat otherwise. */
    private String numberToString(NumberFormat valf, double val) {
        if (Double.isNaN(val)) {
            return " ";
        }
        return valf.format(val);
    }

    /** Return space when val is NaN or zero, apply NumberFormat otherwise. */
    private String nonZeroToString(NumberFormat valf, double val) {
        if (Double.isNaN(val) || val == 0d) {
            return " ";
        }
        return valf.format(val);
    }

    /** Write a line. */
    private void writeRecord(
        CSVWriter writer,
        double km,
        String years,
        SedimentLoadFraction fraction
    ) {
        // year, total, susp sed, susp sandbed suspsand, sand, finemiddle, coarse
        NumberFormat kmf = Formatter.getCalculationKm(context.getMeta());
        NumberFormat valf = Formatter.getFormatter(context.getMeta(), 0, 2);
        writer.writeNext(new String[] {
            kmf.format(km),
            years,
            numberToString(valf, fraction.getSuspSediment()),
            numberToString(valf, fraction.getSuspSand()),
            numberToString(valf, fraction.getSuspSandBed()),
            numberToString(valf, fraction.getSand()),
            numberToString(valf, fraction.getFineMiddle()),
            numberToString(valf, fraction.getCoarse()),
            nonZeroToString(valf, fraction.getTotal())
        });
    }

    /** Writes i18ned header for csv file/stream. */
    protected void writeCSVHeader(CSVWriter writer) {
        logger.debug("writeCSVHeader()");

        List<String> header = new LinkedList<String>();
        if (results != null)  {
            header.add(msg(CSV_KM,          "km"));
            header.add(msg(CSV_YEAR,        "Jahr"));
            header.add(msg(CSV_SUSP_SEDIMENT, "Schwebst."));
            header.add(msg(CSV_SUSP_SAND,   "Susp.Sand"));
            header.add(msg(CSV_SUSP_SAND_BB, "Susp.Sand(BB)"));
            header.add(msg(CSV_SAND,        "Sand"));
            header.add(msg(CSV_FINEMIDDLE,  "Kies(f+m)"));
            header.add(msg(CSV_COARSE,      "Kies(g)"));
            header.add(msg(CSV_TOTAL,       "Gesamt"));
        }
        writer.writeNext(header.toArray(new String[header.size()]));
    }

    /** Store data internally, accepting only SedimentLoadResults[] in
     * calculationresults data. */
    @Override
    protected void addData(Object data) {
        if (!(data instanceof CalculationResult)) {
            logger.warn("Invalid data type.");
            return;
        }
        Object[] d = (Object[])((CalculationResult)data).getData();

        if (!(d instanceof SedimentLoadResult[])) {
            logger.warn("Invalid result object.");
            return;
        }
        logger.debug("addData: Data added.");
        results = (SedimentLoadResult[])d;
    }

    /** Write PDF to outputstream (not implemented yet). */
    @Override
    protected void writePDF(OutputStream out) {
        logger.warn("Not implemented.");
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org