felix@6668: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde felix@6668: * Software engineering by Intevation GmbH felix@6668: * felix@6668: * This file is Free Software under the GNU AGPL (>=v3) felix@6668: * and comes with ABSOLUTELY NO WARRANTY! Check out the felix@6668: * documentation coming with Dive4Elements River for details. felix@6668: */ felix@6668: felix@6668: package org.dive4elements.river.exports.minfo; felix@6668: felix@6668: import java.util.LinkedList; felix@6668: import java.util.List; andre@8134: import java.util.TreeMap; felix@6668: felix@6668: import java.io.OutputStream; felix@6668: import java.io.IOException; felix@6668: felix@6668: import java.text.NumberFormat; felix@6668: felix@6668: import org.apache.log4j.Logger; felix@6668: aheinecke@7634: import org.dive4elements.river.artifacts.access.SedimentLoadAccess; felix@6668: import org.dive4elements.river.artifacts.model.CalculationResult; andre@8134: import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataResult.Fraction; andre@8134: import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataResult; felix@6668: aheinecke@7634: import org.dive4elements.river.artifacts.D4EArtifact; aheinecke@7634: felix@6668: import org.dive4elements.river.exports.AbstractExporter; felix@6668: felix@6668: import org.dive4elements.river.utils.Formatter; felix@6668: felix@6668: import au.com.bytecode.opencsv.CSVWriter; felix@6668: felix@6676: felix@6759: /** felix@6759: * Do CSV export for sediment load calculations (will also be shown in felix@6676: * client). */ felix@6668: public class SedimentLoadExporter felix@6668: extends AbstractExporter felix@6668: { teichmann@8202: /** Private log. */ teichmann@8202: private static Logger log = Logger.getLogger(SedimentLoadExporter.class); felix@6668: felix@6685: // i18n keys. felix@6685: public static final String CSV_KM = tom@8179: "export.csv.header.km"; felix@6668: felix@6685: public static final String CSV_YEAR = tom@8179: "export.csv.header.year"; felix@6685: felix@6685: public static final String CSV_COARSE = tom@8179: "export.sedimentload.csv.header.coarse"; felix@6685: felix@6685: public static final String CSV_FINEMIDDLE = tom@8179: "export.sedimentload.csv.header.fine_middle"; felix@6685: felix@6685: public static final String CSV_SAND = tom@8179: "export.sedimentload.csv.header.sand"; felix@6685: felix@6685: public static final String CSV_SUSP_SAND = tom@8179: "export.sedimentload.csv.header.susp_sand"; felix@6685: felix@6759: public static final String CSV_SUSP_SAND_BB = tom@8179: "export.sedimentload.csv.header.susp_sand_bed"; felix@6759: felix@6685: public static final String CSV_SUSP_SEDIMENT = tom@8179: "export.sedimentload.csv.header.suspended_sediment"; tom@8179: tom@8179: public static final String CSV_BED_LOAD = tom@8179: "export.sedimentload.csv.header.bed_load"; tom@8179: tom@8179: public static final String CSV_BED_LOAD_SUSP_SAND = tom@8179: "export.sedimentload.csv.header.bed_load_susp_sand"; felix@6685: felix@6685: public static final String CSV_TOTAL = tom@8179: "export.sedimentload.csv.header.total"; felix@6685: andre@8134: private static final String[] FRACTION_ORDER = { andre@8134: "suspended_sediment", andre@8134: "susp_sand", andre@8134: "susp_sand_bed", andre@8134: "sand", andre@8134: "fine_middle", andre@8134: "coarse", tom@8179: "bed_load", tom@8179: "bed_load_susp_sand", andre@8134: "total" andre@8134: }; felix@6685: felix@6685: /** Collected results. */ andre@8134: private SedimentLoadDataResult result; felix@6668: felix@6685: /** Empty constructor. */ felix@6668: public SedimentLoadExporter() { felix@6668: } felix@6668: felix@6668: /** Process all stored data and write csv. */ felix@6668: @Override felix@6668: protected void writeCSVData(CSVWriter writer) throws IOException { andre@8134: if (result == null) { andre@8134: return; andre@8134: } felix@6668: writeCSVHeader(writer); felix@6668: andre@8134: /* Prepare the values. The order of the fractions is given by the andre@8134: * header and thus static. */ andre@8134: tom@8146: /* The result is ordered by the periods. For each period there is tom@8146: * then a map of km-fraction pairs which are the actual result. */ andre@8134: andre@8134: TreeMap > result_map = andre@8134: new TreeMap>(); andre@8136: for (int i = 0; i < FRACTION_ORDER.length; i++) { andre@8136: String name = FRACTION_ORDER[i]; andre@8136: List fractions = result.getFractionsByName(name); andre@8136: if (fractions == null) { andre@8136: continue; andre@8136: } andre@8136: for (Fraction fract: fractions) { andre@8134: String period = fract.getPeriod(); andre@8134: TreeMap cur_map; andre@8134: if (result_map.containsKey(period)) { andre@8134: cur_map = result_map.get(period); andre@8134: } else { andre@8134: cur_map = new TreeMap(); andre@8134: result_map.put(period, cur_map); andre@8134: } andre@8134: double[][] values = fract.getData(); andre@8134: for (int j = 0; j < values[0].length; j++) { andre@8134: Double km = values[0][j]; andre@8134: Double val = values[1][j]; andre@8134: Double[] old = cur_map.get(km); andre@8134: if (old == null) { andre@8134: old = new Double[FRACTION_ORDER.length]; andre@8134: for (int k = 0; k < old.length; k++) { andre@8134: old [k] = Double.NaN; andre@8134: } andre@8134: } andre@8134: old [i] = val; andre@8134: cur_map.put(km, old); andre@8134: } andre@8134: } andre@8134: } andre@8134: for (String period: result_map.keySet()) { andre@8134: TreeMap cur_map = result_map.get(period); andre@8134: for (Double km: cur_map.keySet()) { andre@8134: writeRecord(writer, km, period, cur_map.get(km)); felix@6685: } felix@6685: } felix@6685: } felix@6685: felix@7018: felix@7018: /** Return space when val is NaN, apply NumberFormat otherwise. */ felix@7007: private String numberToString(NumberFormat valf, double val) { felix@7007: if (Double.isNaN(val)) { felix@7011: return " "; felix@7007: } felix@7007: return valf.format(val); felix@7007: } felix@7007: felix@6685: /** Write a line. */ felix@6963: private void writeRecord( felix@6963: CSVWriter writer, felix@6963: double km, felix@6963: String years, andre@8134: Double[] fractions felix@6963: ) { felix@6668: NumberFormat kmf = Formatter.getCalculationKm(context.getMeta()); felix@6685: NumberFormat valf = Formatter.getFormatter(context.getMeta(), 0, 2); tom@8179: tom@8179: String[] record = new String[fractions.length+2]; tom@8179: record[0] = kmf.format(km); tom@8179: record[1] = years; tom@8179: for (int i = 0; i < fractions.length; ++i) { tom@8179: record[i+2] = numberToString(valf, fractions[i]); tom@8179: } tom@8179: tom@8179: writer.writeNext(record); felix@6668: } felix@6668: felix@6668: /** Writes i18ned header for csv file/stream. */ felix@6668: protected void writeCSVHeader(CSVWriter writer) { teichmann@8202: log.debug("writeCSVHeader()"); felix@6668: felix@6668: List header = new LinkedList(); andre@8134: SedimentLoadAccess access = andre@8134: new SedimentLoadAccess((D4EArtifact) master); aheinecke@7634: tom@8179: String unit = msg("state.minfo." + access.getUnit()); andre@8134: tom@8179: header.add(msg(CSV_KM)); tom@8179: header.add(msg(CSV_YEAR)); tom@8179: for (String head: new String[] { tom@8179: CSV_SUSP_SEDIMENT, tom@8179: CSV_SUSP_SAND, tom@8179: CSV_SUSP_SAND_BB, tom@8179: CSV_SAND, tom@8179: CSV_FINEMIDDLE, tom@8179: CSV_COARSE, tom@8179: CSV_BED_LOAD, tom@8179: CSV_BED_LOAD_SUSP_SAND, tom@8179: CSV_TOTAL tom@8179: }) { tom@8179: header.add(msg(head, new Object[] { unit })); tom@8179: } felix@6668: writer.writeNext(header.toArray(new String[header.size()])); felix@6668: } felix@6668: felix@6668: /** Store data internally, accepting only SedimentLoadResults[] in felix@6668: * calculationresults data. */ felix@6668: @Override felix@6668: protected void addData(Object data) { felix@6668: if (!(data instanceof CalculationResult)) { teichmann@8202: log.warn("Invalid data type."); felix@6668: return; felix@6668: } andre@8134: Object d = ((CalculationResult)data).getData(); felix@6668: andre@8134: if (!(d instanceof SedimentLoadDataResult)) { teichmann@8202: log.warn("Invalid result object."); felix@6668: return; felix@6668: } teichmann@8202: log.debug("addData: Data added."); andre@8134: result = (SedimentLoadDataResult)d; felix@6668: } felix@6668: felix@6685: /** Write PDF to outputstream (not implemented yet). */ felix@6668: @Override felix@6668: protected void writePDF(OutputStream out) { teichmann@8202: log.warn("Not implemented."); felix@6668: } felix@6668: } felix@6668: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :