teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.exports.fixings; sascha@3216: sascha@3216: import java.io.IOException; sascha@3216: import java.io.OutputStream; sascha@3216: import java.text.DateFormat; sascha@3398: import java.text.MessageFormat; sascha@3216: import java.text.NumberFormat; sascha@3216: import java.util.ArrayList; sascha@3216: import java.util.List; teichmann@5603: import java.util.TreeMap; sascha@3216: sascha@3216: import org.apache.log4j.Logger; gernotbelger@9082: import org.dive4elements.artifacts.CallMeta; gernotbelger@9082: import org.dive4elements.river.artifacts.D4EArtifact; gernotbelger@9306: import org.dive4elements.river.artifacts.access.RangeAccess; gernotbelger@9082: import org.dive4elements.river.artifacts.access.RiverAccess; gernotbelger@9306: import org.dive4elements.river.artifacts.common.DefaultCalculationResults; gernotbelger@9306: import org.dive4elements.river.artifacts.common.ExportContextPDF; gernotbelger@9306: import org.dive4elements.river.artifacts.common.GeneralResultType; gernotbelger@9306: import org.dive4elements.river.artifacts.common.JasperReporter; gernotbelger@9306: import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource; gernotbelger@9082: import org.dive4elements.river.artifacts.model.CalculationResult; gernotbelger@9082: import org.dive4elements.river.artifacts.model.fixings.AnalysisPeriod; gernotbelger@9082: import org.dive4elements.river.artifacts.model.fixings.FixAnalysisResult; gernotbelger@9082: import org.dive4elements.river.artifacts.model.fixings.QWD; gernotbelger@9082: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@9306: import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; gernotbelger@9306: import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; gernotbelger@9082: import org.dive4elements.river.exports.AbstractExporter; gernotbelger@9082: import org.dive4elements.river.utils.Formatter; gernotbelger@9082: import org.dive4elements.river.utils.KMIndex; gernotbelger@9082: gernotbelger@9082: import au.com.bytecode.opencsv.CSVWriter; gernotbelger@9306: import net.sf.jasperreports.engine.JRException; sascha@3216: felix@3644: /** Exports fixation analysis deltaw(t) computation results to csv. */ gernotbelger@9082: public class DeltaWtExporter extends AbstractExporter { teichmann@8202: /** Private log. */ sascha@3216: private static Logger log = Logger.getLogger(DeltaWtExporter.class); sascha@3216: gernotbelger@9306: private static final String JASPER_FILE = "/jasper/templates/fixanalysis.delta_wt.jrxml"; gernotbelger@9306: gernotbelger@9082: public static final String CSV_KM_HEADER = "export.fixings.deltawt.csv.header.km"; sascha@3397: gernotbelger@9082: public static final String CSV_DELTA_W_HEADER = "export.fixings.deltawt.csv.header.deltaw"; sascha@3402: gernotbelger@9082: public static final String CSV_Q_HEADER = "export.fixings.deltawt.csv.header.q"; sascha@3398: gernotbelger@9082: public static final String CSV_W_HEADER = "export.fixings.deltawt.csv.header.w"; sascha@3216: gernotbelger@9082: public static final String CSV_TRANGE_HEADER = "export.fixings.deltawt.csv.header.time.range"; gernotbelger@9082: gernotbelger@9082: public static final String CSV_T_HEADER = "export.fixings.deltawt.csv.header.t"; gernotbelger@9082: gernotbelger@9082: public static final String CSV_T_FORMAT = "export.fixings.deltawt.csv.t.format"; sascha@3216: sascha@3216: public static final String DEFAULT_CSV_KM_HEADER = "km"; sascha@3216: sascha@3216: public static final String DEFAULT_CSV_DELTA_W_HEADER = "\u0394 W [cm]"; sascha@3216: sascha@3402: public static final String DEFAULT_CSV_W_HEADER = "Wasserstand [m]"; sascha@3402: sascha@3397: public static final String DEFAULT_CSV_Q_HEADER = "Abfluss [m\u00b3/s]"; sascha@3397: sascha@3216: public static final String DEFAULT_CSV_T_HEADER = "Datum"; sascha@3216: gernotbelger@9082: public static final String DEFAULT_CSV_TRANGE_DESC_HEADER = "Status"; sascha@3398: gernotbelger@9082: public static final String CSV_REFERENCE = "export.fixings.deltawt.csv.reference"; sascha@3398: gernotbelger@9082: public static final String CSV_ANALYSIS = "export.fixings.deltawt.csv.analysis"; sascha@3402: gernotbelger@9082: public static final String DEFAULT_CSV_REFERENCE = "B"; sascha@3398: gernotbelger@9082: public static final String DEFAULT_CSV_ANALYSIS = "A{0,number,integer}"; gernotbelger@9082: gernotbelger@9082: public static final String DEFAULT_CSV_T_FORMAT = "dd.MM.yyyy"; gernotbelger@9082: gernotbelger@9082: protected List> analysisPeriods; sascha@3216: sascha@3216: protected List> referenceEvents; sascha@3216: teichmann@7077: public DeltaWtExporter() { gernotbelger@9082: this.analysisPeriods = new ArrayList<>(); gernotbelger@9082: this.referenceEvents = new ArrayList<>(); sascha@3216: } sascha@3216: sascha@3216: @Override gernotbelger@9082: protected void addData(final Object d) { sascha@3216: log.debug("DeltaWtExporter.addData"); sascha@3216: if (!(d instanceof CalculationResult)) { sascha@3216: log.warn("Invalid data type"); sascha@3216: return; sascha@3216: } sascha@3216: gernotbelger@9082: final Object data = ((CalculationResult) d).getData(); sascha@3415: if (!(data instanceof FixAnalysisResult)) { sascha@3216: log.warn("Invalid data stored in result."); sascha@3216: } gernotbelger@9082: final FixAnalysisResult result = (FixAnalysisResult) data; gernotbelger@9082: this.analysisPeriods.add(result.getAnalysisPeriods()); gernotbelger@9082: this.referenceEvents.add(result.getReferenced()); sascha@3216: } sascha@3216: sascha@3216: @Override gernotbelger@9082: protected void writeCSVData(final CSVWriter writer) throws IOException { sascha@3216: gernotbelger@9082: final boolean debug = log.isDebugEnabled(); sascha@3216: sascha@3216: writeCSVHeader(writer); sascha@3216: gernotbelger@9306: final TreeMap> sorted = getRows(); gernotbelger@9306: for (final ArrayList list : sorted.values()) { gernotbelger@9306: for (final String[] row : list) { gernotbelger@9306: writer.writeNext(row); gernotbelger@9306: } gernotbelger@9306: } gernotbelger@9306: gernotbelger@9306: writer.flush(); gernotbelger@9306: } gernotbelger@9306: gernotbelger@9306: private TreeMap> getRows() { gernotbelger@9082: final NumberFormat kmF = getKMFormatter(); gernotbelger@9082: final NumberFormat dwF = getDeltaWFormatter(); gernotbelger@9082: final NumberFormat qF = getQFormatter(); gernotbelger@9082: final NumberFormat wF = getWFormatter(); sascha@3216: gernotbelger@9082: final DateFormat dF = getDateFormatter(); sascha@3398: gernotbelger@9082: final TreeMap> sorted = new TreeMap<>(); sascha@3216: gernotbelger@9082: final String referenceS = getReference(); sascha@3216: gernotbelger@9082: for (final KMIndex reference : this.referenceEvents) { teichmann@5603: gernotbelger@9082: for (final KMIndex.Entry kmEntry : reference) { gernotbelger@9082: gernotbelger@9082: final Double km = kmEntry.getKm(); gernotbelger@9082: gernotbelger@9082: ArrayList list = sorted.get(km); teichmann@5603: teichmann@5603: if (list == null) { gernotbelger@9082: list = new ArrayList<>(); teichmann@5603: sorted.put(km, list); teichmann@5603: } teichmann@5603: gernotbelger@9082: final String kmS = kmF.format(kmEntry.getKm()); gernotbelger@9082: for (final QWD qwd : kmEntry.getValue()) { gernotbelger@9082: final String deltaWS = dwF.format(qwd.getDeltaW()); gernotbelger@9082: final String qS = qF.format(qwd.getQ()); gernotbelger@9082: final String wS = wF.format(qwd.getW()); gernotbelger@9082: final String dateS = dF.format(qwd.getDate()); sascha@3216: gernotbelger@9082: list.add(new String[] { kmS, dateS, qS, wS, referenceS, deltaWS }); teichmann@5603: } sascha@3216: } sascha@3216: } sascha@3216: gernotbelger@9306: // if (debug) { gernotbelger@9306: // log.debug("AnalysisPeriods: " + this.analysisPeriods.size()); gernotbelger@9306: // } sascha@3216: gernotbelger@9082: final String analysisTemplate = getAnalysisTemplate(); sascha@3216: gernotbelger@9082: for (final KMIndex periods : this.analysisPeriods) { teichmann@4736: gernotbelger@9082: for (final KMIndex.Entry kmEntry : periods) { teichmann@5603: gernotbelger@9082: final Double km = kmEntry.getKm(); gernotbelger@9082: gernotbelger@9082: ArrayList list = sorted.get(km); teichmann@5603: teichmann@5603: if (list == null) { gernotbelger@9082: list = new ArrayList<>(); teichmann@5603: sorted.put(km, list); teichmann@5603: } teichmann@5603: gernotbelger@9082: final String kmS = kmF.format(kmEntry.getKm()); felix@4238: int analysisCount = 1; sascha@3216: gernotbelger@9082: for (final AnalysisPeriod period : kmEntry.getValue()) { felix@4238: // Typically resulting in A1,A2... gernotbelger@9082: final String analyisS = MessageFormat.format(analysisTemplate, analysisCount); gernotbelger@9082: final QWD[] qwds = period.getQWDs(); felix@3644: sascha@3216: if (qwds != null) { gernotbelger@9082: for (final QWD qwd : qwds) { gernotbelger@9082: final String deltaWS = dwF.format(qwd.getDeltaW()); gernotbelger@9082: final String qS = qF.format(qwd.getQ()); gernotbelger@9082: final String wS = wF.format(qwd.getW()); gernotbelger@9082: final String dateS = dF.format(qwd.getDate()); sascha@3216: gernotbelger@9082: list.add(new String[] { kmS, dateS, qS, wS, analyisS, deltaWS }); sascha@3216: } sascha@3216: } felix@4238: ++analysisCount; sascha@3216: } sascha@3216: } sascha@3216: } gernotbelger@9306: return sorted; teichmann@5603: sascha@3216: } sascha@3216: felix@3644: /** Template to create "State" strings like A1,A2... */ sascha@3398: protected String getAnalysisTemplate() { gernotbelger@9082: return Resources.getMsg(this.context.getMeta(), CSV_ANALYSIS, DEFAULT_CSV_ANALYSIS); sascha@3398: } sascha@3398: sascha@3398: protected String getReference() { gernotbelger@9082: return Resources.getMsg(this.context.getMeta(), CSV_REFERENCE, DEFAULT_CSV_REFERENCE); sascha@3398: } sascha@3216: sascha@3216: protected NumberFormat getKMFormatter() { gernotbelger@9082: return Formatter.getFixDeltaWKM(this.context); sascha@3216: } sascha@3216: sascha@3216: protected NumberFormat getDeltaWFormatter() { gernotbelger@9082: return Formatter.getFixDeltaWDeltaW(this.context); sascha@3216: } sascha@3216: gernotbelger@9082: @Override sascha@3397: protected NumberFormat getQFormatter() { gernotbelger@9082: return Formatter.getFixDeltaWQ(this.context); sascha@3397: } sascha@3397: gernotbelger@9082: @Override sascha@3402: protected NumberFormat getWFormatter() { gernotbelger@9082: return Formatter.getFixDeltaWW(this.context); sascha@3402: } sascha@3402: sascha@3402: protected DateFormat getDateFormatter() { gernotbelger@9082: final CallMeta meta = this.context.getMeta(); gernotbelger@9082: return Formatter.getDateFormatter(meta, Resources.getMsg(meta, CSV_T_FORMAT, DEFAULT_CSV_T_FORMAT)); sascha@3402: } sascha@3402: gernotbelger@9082: protected void writeCSVHeader(final CSVWriter writer) { sascha@3216: log.debug("DeltaWtExporter.writeCSVHeader"); sascha@3216: gernotbelger@9082: /* gernotbelger@9082: * issue825 gernotbelger@9082: * km; Ereignis, Abfluss, GEMESSENER Wasserstand; gernotbelger@9082: * Status (RECHTSBÜNDIG), del W gernotbelger@9082: */ gernotbelger@9082: final RiverAccess river = new RiverAccess((D4EArtifact) this.master); gernotbelger@9082: final String unit = river.getRiver().getWstUnit().getName(); felix@3644: gernotbelger@9082: writer.writeNext(new String[] { msg(CSV_KM_HEADER, DEFAULT_CSV_KM_HEADER), msg(CSV_T_HEADER, DEFAULT_CSV_T_HEADER), gernotbelger@9082: msg(CSV_Q_HEADER, DEFAULT_CSV_Q_HEADER), msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER, new Object[] { unit }), gernotbelger@9082: msg(CSV_TRANGE_HEADER, DEFAULT_CSV_TRANGE_DESC_HEADER), msg(CSV_DELTA_W_HEADER, DEFAULT_CSV_DELTA_W_HEADER) }); sascha@3216: } sascha@3216: gernotbelger@9306: private void addMetaData(final MetaAndTableJRDataSource source) { gernotbelger@9306: final D4EArtifact flys = (D4EArtifact) this.master; gernotbelger@9306: final String user = CalculationUtils.findArtifactUser(this.context, flys); gernotbelger@9306: final RangeAccess ra = new RangeAccess(flys); gernotbelger@9306: final RiverInfo ri = new RiverInfo(ra.getRiver()); gernotbelger@9306: gernotbelger@9306: final DefaultCalculationResults results = new DefaultCalculationResults(msg("calculation.analysis"), user, ri, ra.getRange()); gernotbelger@9306: final ExportContextPDF contextPdf = new ExportContextPDF(this.context, results); gernotbelger@9306: contextPdf.addJRMetaDataDefaults(source); gernotbelger@9322: contextPdf.addJRMetaDataForModules(source); gernotbelger@9306: gernotbelger@9306: /* column headings */ gernotbelger@9306: contextPdf.addJRMetadata(source, "station_header", GeneralResultType.station); gernotbelger@9306: contextPdf.addJRMetadata(source, "fix_date", msg(CSV_T_HEADER)); gernotbelger@9306: contextPdf.addJRMetadata(source, "fix_q", msg(CSV_Q_HEADER)); gernotbelger@9306: contextPdf.addJRMetadata(source, "fix_w", msg(CSV_W_HEADER, DEFAULT_CSV_W_HEADER, new Object[] { ri.getWstUnit() })); gernotbelger@9306: contextPdf.addJRMetadata(source, "fix_state", msg(CSV_TRANGE_HEADER)); gernotbelger@9306: contextPdf.addJRMetadata(source, "fix_delta_w", msg(CSV_DELTA_W_HEADER)); gernotbelger@9306: } gernotbelger@9306: sascha@3216: @Override gernotbelger@9082: protected void writePDF(final OutputStream out) { gernotbelger@9306: final MetaAndTableJRDataSource source = new MetaAndTableJRDataSource(); gernotbelger@9306: final String jasperFile = Resources.getMsg(this.context.getMeta(), JASPER_FILE); gernotbelger@9306: addMetaData(source); gernotbelger@9306: try { gernotbelger@9306: final TreeMap> sorted = getRows(); // Custom Result could be nice, too... gernotbelger@9306: for (final ArrayList list : sorted.values()) { gernotbelger@9306: for (final String[] row : list) { gernotbelger@9306: source.addData(row); gernotbelger@9306: } gernotbelger@9306: } gernotbelger@9306: final JasperReporter reporter = new JasperReporter(); gernotbelger@9306: reporter.addReport(jasperFile, source); gernotbelger@9306: reporter.exportPDF(out); gernotbelger@9306: } gernotbelger@9306: catch (final JRException je) { gernotbelger@9306: log.warn("Error generating PDF Report!", je); gernotbelger@9306: } sascha@3216: } gernotbelger@9306: }