gernotbelger@9145: /* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@9145: * Software engineering by gernotbelger@9145: * Björnsen Beratende Ingenieure GmbH gernotbelger@9145: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@9145: * gernotbelger@9145: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@9145: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@9145: * documentation coming with Dive4Elements River for details. gernotbelger@9145: */ gernotbelger@9145: package org.dive4elements.river.artifacts.sinfo.flood_duration; gernotbelger@9145: gernotbelger@9205: import java.text.NumberFormat; gernotbelger@9150: import java.util.ArrayList; gernotbelger@9145: import java.util.Collection; mschaefer@9202: import java.util.Collections; mschaefer@9202: import java.util.List; gernotbelger@9145: mschaefer@9176: import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult; gernotbelger@9205: import org.dive4elements.river.artifacts.common.AbstractExportContext; gernotbelger@9150: import org.dive4elements.river.artifacts.common.ExportContextCSV; gernotbelger@9195: import org.dive4elements.river.artifacts.common.ExportContextPDF; gernotbelger@9150: import org.dive4elements.river.artifacts.common.GeneralResultType; mschaefer@9202: import org.dive4elements.river.artifacts.common.IResultType; gernotbelger@9150: import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource; gernotbelger@9145: import org.dive4elements.river.artifacts.common.ResultRow; mschaefer@9202: import org.dive4elements.river.artifacts.sinfo.common.SInfoI18NStrings; gernotbelger@9150: import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; gernotbelger@9150: import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; gernotbelger@9208: import org.dive4elements.river.exports.DiagramGenerator; mschaefer@9229: import org.dive4elements.river.model.Attribute.AttributeKey; gernotbelger@9145: mschaefer@9202: import gnu.trove.TDoubleArrayList; mschaefer@9202: gernotbelger@9145: /** mschaefer@9176: * Contains the result of a {@link FloodDurationCalculation}. gernotbelger@9145: * gernotbelger@9145: * @author Gernot Belger gernotbelger@9145: */ mschaefer@9202: public final class FloodDurationCalculationResult extends AbstractCalculationExportableResult { gernotbelger@9145: gernotbelger@9145: private static final long serialVersionUID = 1L; gernotbelger@9150: gernotbelger@9205: private final String[] mainvalueLabels; mschaefer@9176: gernotbelger@9205: // private final WstInfo wstInfo; mschaefer@9229: gernotbelger@9205: private final int maxWaterlevelPdf = 3; gernotbelger@9205: gernotbelger@9208: public interface ValueGetter { gernotbelger@9215: double getValue(DurationWaterlevel waterlevel); gernotbelger@9208: } gernotbelger@9208: gernotbelger@9205: private enum ExportMode { gernotbelger@9205: pdf, csv gernotbelger@9205: } mschaefer@9202: mschaefer@9202: public FloodDurationCalculationResult(final String label, final String[] mainvalueLabels, final Collection rows) { mschaefer@9176: super(label, rows); gernotbelger@9215: this.mainvalueLabels = mainvalueLabels; mschaefer@9202: } mschaefer@9202: mschaefer@9202: /** mschaefer@9202: * Collection of the result rows containing only the rows describing an infrastructure mschaefer@9202: */ mschaefer@9202: @Override mschaefer@9202: public Collection getRows() { mschaefer@9202: final List infrasOnlyRows = new ArrayList<>(); mschaefer@9202: for (final ResultRow row : this.rows) mschaefer@9202: if (row.getValue(SInfoResultType.infrastructuretype) != null) mschaefer@9202: infrasOnlyRows.add(row); mschaefer@9202: return Collections.unmodifiableCollection(infrasOnlyRows); mschaefer@9202: } mschaefer@9202: mschaefer@9176: @Override gernotbelger@9195: protected void writeCSVResultMetadata(final ExportContextCSV exportContextCSV) { mschaefer@9202: if (this.mainvalueLabels.length >= 1) { mschaefer@9202: // "##METADATEN WASSERSPIEGELLAGE" mschaefer@9202: exportContextCSV.writeCSVMetaEntry(SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL); gernotbelger@9205: for (int i = 1; i <= getWaterlevelCount(); // this.mainvalueLabels.length; gernotbelger@9205: i++) { mschaefer@9202: // "# Bezeichnung der Wasserspiegellage: " mschaefer@9202: final String label = this.getMainValueLabel(i - 1); mschaefer@9202: exportContextCSV.writeCSVMetaEntry(SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_NAME, String.format("%d: %s", i, label)); mschaefer@9202: } mschaefer@9202: // "# Bezugspegel: " mschaefer@9229: for (final ResultRow row : this.rows) { mschaefer@9229: exportContextCSV.writeCSVMetaEntry(SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_GAUGE, row.getValue(SInfoResultType.gaugeLabel)); mschaefer@9229: break; mschaefer@9229: } mschaefer@9202: } gernotbelger@9205: exportContextCSV.writeBlankLine(); mschaefer@9176: } mschaefer@9176: mschaefer@9176: @Override mschaefer@9176: protected String getJasperFile() { mschaefer@9229: if (this.getWaterlevelCount() <= 1) gernotbelger@9205: return "/jasper/templates/sinfo.floodduration.jrxml"; gernotbelger@9205: else gernotbelger@9205: return "/jasper/templates/sinfo.floodduration2.jrxml"; mschaefer@9176: } mschaefer@9176: gernotbelger@9205: protected String[] formatRow(final AbstractExportContext exportContextCSV, final ResultRow row, final ExportMode mode) { mschaefer@9176: mschaefer@9176: final Collection lines = new ArrayList<>(10); mschaefer@9176: mschaefer@9176: lines.add(exportContextCSV.formatRowValue(row, GeneralResultType.station)); mschaefer@9176: lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.riverside)); mschaefer@9176: lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.floodDuration)); mschaefer@9176: lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.floodDischarge)); mschaefer@9176: lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.infrastructureHeight)); mschaefer@9176: lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.infrastructuretype)); mschaefer@9176: gernotbelger@9205: final List waterlevelList = (List) row.getValue(SInfoResultType.customMultiRowColWaterlevel); gernotbelger@9205: if (waterlevelList != null) { gernotbelger@9205: final NumberFormat wFormatter = exportContextCSV.getFlowDepthFormatter(); gernotbelger@9205: final NumberFormat qFormatter = exportContextCSV.getQFormatter(); gernotbelger@9205: gernotbelger@9205: for (int i = 0; i < waterlevelList.size(); i++) { gernotbelger@9205: gernotbelger@9205: if (i == this.maxWaterlevelPdf && mode == ExportMode.pdf) gernotbelger@9205: break; gernotbelger@9205: gernotbelger@9205: final DurationWaterlevel item = waterlevelList.get(i); gernotbelger@9205: lines.add(item.getWFormatted(wFormatter)); gernotbelger@9205: lines.add(item.getFloodDurDaysPerYearFormatted()); gernotbelger@9205: lines.add(item.getQFormatted(qFormatter)); gernotbelger@9205: lines.add(item.getBezeichnung()); mschaefer@9202: } mschaefer@9202: } mschaefer@9176: mschaefer@9176: lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.gaugeLabel)); mschaefer@9176: lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.location)); mschaefer@9176: mschaefer@9176: return lines.toArray(new String[lines.size()]); gernotbelger@9150: } gernotbelger@9150: gernotbelger@9150: @Override gernotbelger@9195: public void writeCSVHeader(final ExportContextCSV exportContextCSV, final RiverInfo river) { gernotbelger@9150: mschaefer@9176: final Collection header = new ArrayList<>(20); gernotbelger@9150: gernotbelger@9150: header.add(exportContextCSV.formatCsvHeader(GeneralResultType.station)); gernotbelger@9150: header.add(exportContextCSV.formatCsvHeader(SInfoResultType.riverside)); mschaefer@9176: header.add(exportContextCSV.formatCsvHeader(SInfoResultType.floodDuration)); mschaefer@9176: header.add(exportContextCSV.msgUnitCSV(SInfoResultType.floodDischarge, SInfoResultType.floodDischarge.getUnit())); mschaefer@9176: header.add(exportContextCSV.msgUnitCSV(SInfoResultType.infrastructureHeight, SInfoResultType.infrastructureHeight.getUnit())); gernotbelger@9150: header.add(exportContextCSV.formatCsvHeader(SInfoResultType.infrastructuretype)); gernotbelger@9150: gernotbelger@9205: // add dynamic headers gernotbelger@9205: final int waterlevelCount = // results. gernotbelger@9205: getWaterlevelCount(); gernotbelger@9205: for (int i = 0; i < waterlevelCount; i++) { mschaefer@9229: final String appendIndex = "_" + Integer.toString(i + 1); mschaefer@9229: header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderWCsv(), appendIndex, "results.getRiver().getWstUnit()")); mschaefer@9229: header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderFloodDurPerYearCsv(), appendIndex)); mschaefer@9229: header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderQ(), appendIndex)); mschaefer@9229: header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderBezeichnCsv(), appendIndex)); mschaefer@9202: } gernotbelger@9150: gernotbelger@9150: header.add(exportContextCSV.formatCsvHeader(SInfoResultType.gaugeLabel)); gernotbelger@9150: header.add(exportContextCSV.formatCsvHeader(SInfoResultType.location)); gernotbelger@9150: gernotbelger@9150: exportContextCSV.writeCSVLine(header.toArray(new String[header.size()])); gernotbelger@9145: gernotbelger@9145: } gernotbelger@9145: gernotbelger@9150: @Override gernotbelger@9195: protected String[] formatCSVRow(final ExportContextCSV exportContextCSV, final ResultRow row) { gernotbelger@9150: gernotbelger@9205: return this.formatRow(exportContextCSV, row, ExportMode.csv); gernotbelger@9150: } gernotbelger@9150: gernotbelger@9150: @Override gernotbelger@9195: protected String[] formatPDFRow(final ExportContextPDF exportContextPDF, final ResultRow row) { gernotbelger@9150: gernotbelger@9205: return this.formatRow(exportContextPDF, row, ExportMode.pdf); gernotbelger@9145: } gernotbelger@9145: mschaefer@9176: @Override gernotbelger@9195: protected void addJRTableHeader(final ExportContextPDF exportContextPDF, final MetaAndTableJRDataSource source) { gernotbelger@9150: mschaefer@9176: /* column headings */ mschaefer@9176: exportContextPDF.addJRMetadata(source, "station_header", GeneralResultType.station); mschaefer@9176: exportContextPDF.addJRMetadata(source, "riverside_header", SInfoResultType.riverside); mschaefer@9176: exportContextPDF.addJRMetadata(source, "inundationduration_header", SInfoResultType.floodDuration); mschaefer@9176: exportContextPDF.addJRMetadata(source, "inundationduration_q_header", SInfoResultType.floodDischarge); mschaefer@9202: exportContextPDF.addJRMetadata(source, "infrastructure_height_header", SInfoResultType.infrastructureHeight); mschaefer@9176: exportContextPDF.addJRMetadata(source, "infrastructure_type_header", SInfoResultType.infrastructuretype); gernotbelger@9150: mschaefer@9229: for (int i = 1; i <= this.getWaterlevelCount(); i++) { gernotbelger@9205: mschaefer@9229: final String appendIndex = "_" + Integer.toString(i); mschaefer@9229: exportContextPDF.addJRMetadata(source, getPdfHeader("w", i), exportContextPDF.msg(DurationWaterlevel.getHeaderWPdf(), appendIndex)); mschaefer@9229: exportContextPDF.addJRMetadata(source, getPdfHeader("duration", i), mschaefer@9229: exportContextPDF.msg(DurationWaterlevel.getHeaderFloodDurPerYearPdf(), appendIndex)); mschaefer@9229: exportContextPDF.addJRMetadata(source, getPdfHeader("q", i), exportContextPDF.msg(DurationWaterlevel.getHeaderQ(), appendIndex)); mschaefer@9229: exportContextPDF.addJRMetadata(source, getPdfHeader("bezeichnung", i), mschaefer@9229: exportContextPDF.msg(DurationWaterlevel.getHeaderBezeichnPdf(), appendIndex)); gernotbelger@9205: } gernotbelger@9150: mschaefer@9176: exportContextPDF.addJRMetadata(source, "gauge_header", SInfoResultType.gaugeLabel); mschaefer@9176: exportContextPDF.addJRMetadata(source, "location_header", SInfoResultType.location); gernotbelger@9150: } gernotbelger@9205: gernotbelger@9205: private final String getPdfHeader(final String rootStr, final int index) { gernotbelger@9205: final String hd = "_header"; gernotbelger@9205: final StringBuilder builder = new StringBuilder(); gernotbelger@9205: return builder.append(rootStr).append("_").append(index).append(hd).toString(); gernotbelger@9205: } gernotbelger@9205: mschaefer@9229: public final int getWaterlevelCount() { mschaefer@9229: return (this.mainvalueLabels != null) ? this.mainvalueLabels.length : 0; mschaefer@9229: } mschaefer@9229: gernotbelger@9205: public String getMainValueLabel(final int j) { gernotbelger@9205: if (this.mainvalueLabels != null && j < this.mainvalueLabels.length) gernotbelger@9205: return this.mainvalueLabels[j]; gernotbelger@9205: return ""; gernotbelger@9205: } gernotbelger@9208: mschaefer@9229: /** mschaefer@9229: * Gets the longitudinal section of a result value type for one river side mschaefer@9229: */ mschaefer@9229: public final double[][] getInfrastructurePoints(final IResultType type, final AttributeKey riverside) { mschaefer@9229: mschaefer@9229: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); mschaefer@9229: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); mschaefer@9229: mschaefer@9229: for (final ResultRow row : this.rows) { mschaefer@9229: mschaefer@9229: final double station = row.getDoubleValue(GeneralResultType.station); mschaefer@9229: final double value = row.getDoubleValue(type); mschaefer@9229: if (row.getValue(SInfoResultType.riverside) == riverside) { mschaefer@9229: xPoints.add(station); mschaefer@9229: yPoints.add(value); mschaefer@9229: } mschaefer@9229: } mschaefer@9229: mschaefer@9229: return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; mschaefer@9229: } mschaefer@9229: mschaefer@9229: /** mschaefer@9229: * Gets a longitudinal section of W, Q, or flood duration of one of the waterlevels mschaefer@9229: */ gernotbelger@9215: public final double[][] getMainValueDurationPoints(final DiagramGenerator generator, final ValueGetter valuegetter, final int dataIndex) { gernotbelger@9208: gernotbelger@9208: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@9208: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@9208: gernotbelger@9208: for (final ResultRow row : this.rows) { gernotbelger@9208: gernotbelger@9208: final double station = row.getDoubleValue(GeneralResultType.station); gernotbelger@9208: gernotbelger@9208: final List waterlevels = (List) row.getValue(SInfoResultType.customMultiRowColWaterlevel); gernotbelger@9208: final DurationWaterlevel waterlevel = waterlevels.get(dataIndex); gernotbelger@9208: gernotbelger@9208: final Double value = valuegetter.getValue(waterlevel); gernotbelger@9208: gernotbelger@9208: xPoints.add(station); gernotbelger@9208: yPoints.add(value); gernotbelger@9208: } gernotbelger@9208: gernotbelger@9208: return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; gernotbelger@9208: } gernotbelger@9145: }