view artifacts/src/main/java/org/dive4elements/river/exports/minfo/BedQualityExporter.java @ 7691:fa4fbd66e752

(issue1579) Fix axes syncronisation at Gauges The SyncNumberAxis was completely broken. It only synced in one direction and even that did not work correctly when data was added to the axis (and the syncAxis rescaled but forgot the old axis) then there were lots of ways to bypass that scaling. And i also think the trans calculation was wrong. It has been replaced by a "mostly" simple method to just keep the W in M and W in CM+Datum axes in sync. I say "Mostly" because it had to deal with the Bounds interface.
author Andre Heinecke <aheinecke@intevation.de>
date Fri, 13 Dec 2013 19:03:00 +0100
parents b24ce5b2141c
children e4606eae8ea5
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 gnu.trove.TDoubleArrayList;

import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import au.com.bytecode.opencsv.CSVWriter;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.minfo.BedDiameterResult;
import org.dive4elements.river.artifacts.model.minfo.BedParametersResult;
import org.dive4elements.river.artifacts.model.minfo.BedQualityResult;
import org.dive4elements.river.artifacts.model.minfo.BedloadDiameterResult;
import org.dive4elements.river.exports.AbstractExporter;
import org.dive4elements.river.utils.Formatter;


public class BedQualityExporter
extends AbstractExporter
{
    /** Private logger. */
    private static Logger logger = Logger.getLogger(BedQualityExporter.class);

    private static final String CSV_HEADER_KM =
        "export.minfo.bedquality.km";
    private static final String CSV_HEADER_DENSITY_CAP =
        "export.minfo.bedquality.density_cap";
    private static final String CSV_HEADER_DENSITY_SUB =
        "export.minfo.bedquality.density_sub";
    private static final String CSV_HEADER_POROSITY_CAP =
        "export.minfo.bedquality.porosity_cap";
    private static final String CSV_HEADER_POROSITY_SUB =
        "export.minfo.bedquality.porosity_sub";
    private static final String CSV_HEADER_BEDLOAD =
        "export.minfo.bedquality.bedload";
    private static final String CSV_HEADER_BED_CAP =
        "export.minfo.bedquality.bed_cap";
    private static final String CSV_HEADER_BED_SUB =
        "export.minfo.bedquality.bed_sub";

    private BedQualityResult[] results;

    public BedQualityExporter() {
        results = new BedQualityResult[0];
    }

    /** Populate param kms with kms from param beds and loads, return it. */
    private TDoubleArrayList populateKmList(BedDiameterResult[] beds,
        BedloadDiameterResult[] loads,
        TDoubleArrayList kms) {
        for (int j = 0; j < beds.length; j++) {
            TDoubleArrayList bkms = beds[j].getKms();
            for (int k = 0, K = bkms.size(); k < K; k++) {
                double km = bkms.get(k);
                if (!kms.contains(km)) { // XXX: O(N^2)
                    kms.add(km);
                }
            }
        }
        for (int j = 0; j < loads.length; j++) {
            TDoubleArrayList lkms = loads[j].getKms();
            for (int k = 0, L = lkms.size(); k < L; k++) {
                double km = lkms.get(k);
                if (!kms.contains(km)) { // XXX: O(N^2)
                    kms.add(km);
                }
            }
        }
        return kms;
    }

    /** Create double[] containing the data for rows in csv. */
    private List<double[]> createDataRows() {
        // Calculate how many columns and rows we need.
        TDoubleArrayList kms = new TDoubleArrayList();

        int cols = 1;
        for (BedQualityResult result : results) {
            BedDiameterResult[]     beds  = result.getBedResults();
            BedloadDiameterResult[] loads = result.getBedloadResults();

            kms = populateKmList(beds, loads, kms);

            cols += beds.length * 2;
            if (beds.length > 0) {
                cols += 4;
            }
            cols += loads.length;
        }

        kms.sort();

        List<double[]> rows = new ArrayList<double[]>(kms.size());
        for (int i = 0, K = kms.size(); i < K; i++) {
            double[] row = new double[cols];
            double km = kms.get(i);
            row[0] = km;
            for (int j = 0; j < results.length; j++) {
                BedloadDiameterResult[] loads = results[j].getBedloadResults();

                for(int k = 0; k < loads.length; k++) {
                    // k + 1: shift km column.
                    // j* loads.length: shift periods.
                    row[(k + 1) + (j * loads.length)] =
                        loads[k].getDiameter(km);
                }
                BedDiameterResult[] beds = results[j].getBedResults();
                if (beds.length == 0) {
                    continue;
                }
                for (int k = 0; k < beds.length; k++) {
                    // k * 2 + 1: shift km column.
                    // j * beds.length * 2: shift periods.
                    // loads.length * results.length: shift bed load columns.
                    int ndx = (k * 2 + 1) + (j * beds.length * 2) + (loads.length * results.length);
                    row[ndx] = beds[k].getDiameterCap(km);
                    row[ndx + 1] = beds[k].getDiameterSub(km);
                }
                BedParametersResult[] params = results[j].getParameters();
                for(int k = 0; k < params.length; k++) {
                    // loads.length + (beds.lenght * 2) * (j + 1): shift bed and bedload columns.
                    int ndx = 1 + (loads.length + (beds.length * 2) * (j + 1));
                    row[ndx] = params[k].getLoadDensityCap(km);
                    row[ndx + 1] = params[k].getLoadDensitySub(km);
                    row[ndx + 2] = params[k].getPorosityCap(km);
                    row[ndx + 3] = params[k].getPorositySub(km);
                }
            }
            rows.add(row);
        }

        return rows;
    }

    @Override
    protected void writeCSVData(CSVWriter writer) throws IOException {
        // TODO Auto-generated method stub
        writeCSVHeader(writer);

        NumberFormat nf = Formatter.getFormatter(context, 1, 3);

        for (double[] d : createDataRows()) {
            logger.debug("row + " + Arrays.toString(d));
            List<String> cells = new ArrayList<String>(d.length);
            for (int i = 0; i < d.length; i++) {
                if (!Double.isNaN(d[i])) {
                    cells.add(nf.format(d[i]));
                }
                else {
                    cells.add("");
                }
            }
            writer.writeNext(cells.toArray(new String[cells.size()]));
        }
    }

    @Override
    protected void writePDF(OutputStream out) {
        // TODO Auto-generated method stub

    }

    @Override
    protected void addData(Object data) {
        // TODO Auto-generated method stub
        logger.debug("addData()");
        if (!(data instanceof CalculationResult)) {
            logger.warn("Invalid data type.");
            return;
        }
        Object[] d = (Object[])((CalculationResult)data).getData();

        if (!(d instanceof BedQualityResult[])) {
            logger.warn("Invalid result object.");
            return;
        }
        results = (BedQualityResult[])d;
    }

    protected void writeCSVHeader(CSVWriter writer) {
        logger.debug("writeCSVHeader()");

        List<String> header = new ArrayList<String>();
        if (results != null)  {
            header.add(msg(CSV_HEADER_KM, "km"));
            for (int i = 0; i < results.length; i++) {
                DateFormat df = Formatter.getDateFormatter(context.getMeta(), "dd.MM.yyyy");
                String d1 = df.format(results[i].getDateRange().getFrom());
                String d2 = df.format(results[i].getDateRange().getTo());
                BedloadDiameterResult[] loads = results[i].getBedloadResults();
                BedDiameterResult[] beds = results[i].getBedResults();
                BedParametersResult[] params = results[i].getParameters();
                for (int j = 0; j < loads.length; j++) {
                    header.add(msg(CSV_HEADER_BEDLOAD, CSV_HEADER_BEDLOAD) +
                        " - " +
                        msg(loads[j].getType().toString(),
                            loads[j].getType().toString()) + " - " +
                        d1 + "-" + d2);
                }
                for (int j = 0; j < beds.length; j++) {
                    header.add(msg(CSV_HEADER_BED_CAP, CSV_HEADER_BED_CAP) + " - " +
                        msg(beds[j].getType().toString(),
                            beds[j].getType().toString()) + " - " +
                        d1 + "-" + d2);
                    header.add(msg(CSV_HEADER_BED_SUB, CSV_HEADER_BED_SUB) + " - " +
                        msg(beds[j].getType().toString(),
                            beds[j].getType().toString()) + " - " +
                        d1 + "-" + d2);
                }
                if (beds.length == 0) {
                    continue;
                }
                if (params.length > 0) {
                    header.add(
                        msg(CSV_HEADER_DENSITY_CAP, CSV_HEADER_DENSITY_CAP) +
                        " - " + d1 + "-" + d2);
                    header.add(
                        msg(CSV_HEADER_DENSITY_SUB, CSV_HEADER_DENSITY_SUB) +
                        " - " + d1 + "-" + d2);
                    header.add(
                        msg(CSV_HEADER_POROSITY_CAP, CSV_HEADER_POROSITY_CAP) +
                        " - " + d1 + "-" + d2);
                    header.add(
                        msg(CSV_HEADER_POROSITY_SUB, CSV_HEADER_POROSITY_SUB) +
                        " - " + d1 + "-" + d2);
                }
            }
        }
        writer.writeNext(header.toArray(new String[header.size()]));
    }
}

http://dive4elements.wald.intevation.org