# HG changeset patch # User gernotbelger # Date 1528791803 -7200 # Node ID e6b63b2b41b9609d96642b8a1d3b2446546bcaa3 # Parent 7879c2ca8bd3a46184de260994fc1212853e4b87 sinfo.flood_duration pdf, csv, ui diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/doc/conf/artifacts/sinfo.xml --- a/artifacts/doc/conf/artifacts/sinfo.xml Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/doc/conf/artifacts/sinfo.xml Tue Jun 12 10:23:23 2018 +0200 @@ -222,6 +222,9 @@ + + + @@ -340,6 +343,8 @@ + + @@ -362,28 +367,18 @@ - - + - - + + diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/common/JasperDesigner.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/JasperDesigner.java Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/JasperDesigner.java Tue Jun 12 10:23:23 2018 +0200 @@ -60,14 +60,9 @@ } // width auf letzte spalte schlagen - final JRElement elementColLast = colchildren.getElements()[colchildren.getElements().length - 1]; - if (elementColLast != null) { - elementColLast.setWidth(elementColLast.getWidth() + width); - } - final JRElement elementDataLast = datachildren.getElements()[datachildren.getElements().length - 1]; - if (elementDataLast != null) { - elementDataLast.setWidth(elementDataLast.getWidth() + width); - } + addWidthToElement(colchildren.getElements()[colchildren.getElements().length - 1], width); + addWidthToElement(datachildren.getElements()[datachildren.getElements().length - 1], width); + } else { // TODO: LOG System.out.print("Column not found for key: " + key); @@ -75,6 +70,11 @@ } + private void addWidthToElement(final JRElement element, final int width) { + if (element != null) + element.setWidth(element.getWidth() + width); + } + JasperDesign getDesign() { return this.design; } diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/common/MetaAndTableJRDataSource.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/MetaAndTableJRDataSource.java Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/MetaAndTableJRDataSource.java Tue Jun 12 10:23:23 2018 +0200 @@ -53,6 +53,8 @@ if (fieldName.startsWith("data:")) { final int column = Integer.valueOf(fieldName.substring("data:".length())); + if (column >= this.data.get(this.index).length) + return null; return this.data.get(this.index)[column]; } return null; diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Tue Jun 12 10:23:23 2018 +0200 @@ -37,6 +37,68 @@ super(unit, csvHeader, pdfHeader); } + public static final SInfoResultType customMultiRowColWaterlevel = new SInfoResultType(null, SInfoI18NStrings.CSV_WATERLEVEL_HEADER, + "sinfo.export.flow_depth.pdf.header.waterlevel") { + private static final long serialVersionUID = 1L; + + @Override + public String exportValue(final CallContext context, final Object value) { + // TODO Auto-generated method stub + return null; + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + // TODO Auto-generated method stub + return null; + } + + }; + + public static final SInfoResultType inundationdurationq = new SInfoResultType(null, "sinfo.export.flood_duration.csv.header.inundation_duration_q", + "sinfo.export.flood_duration.pdf.header.inundation_duration_q") { + private static final long serialVersionUID = 1L; + + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); // integer + // als + // double? + // finde + // gerade + // kein + // int-beispiel + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getWaterlevelQ(context); + } + }; + + public static final SInfoResultType inundationduration = new SInfoResultType(null, "sinfo.export.flood_duration.csv.header.inundation_duration", + "sinfo.export.flood_duration.pdf.header.inundation_duration") { + private static final long serialVersionUID = 1L; + + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); // integer + // als + // double? + // finde + // gerade + // kein + // int-beispiel + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getIntegerFormatter(context); + } + }; + public static final SInfoResultType waterlevel = new SInfoResultType(null, SInfoI18NStrings.CSV_WATERLEVEL_HEADER, "sinfo.export.flow_depth.pdf.header.waterlevel") { private static final long serialVersionUID = 1L; @@ -69,6 +131,21 @@ } }; + public static final SInfoResultType infrastructuretype = new SInfoResultType(I18NStrings.UNIT_NONE, + "sinfo.export.flood_duration.csv.header.infrastructure_type", "sinfo.export.flood_duration.pdf.header.infrastructure_type") { + private static final long serialVersionUID = 1L; + + @Override + public String exportValue(final CallContext context, final Object value) { + return exportStringValue(value); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + throw new UnsupportedOperationException(); + } + }; + public static final SInfoResultType discharge = new SInfoResultType(I18NStrings.UNIT_CUBIC_M, SInfoI18NStrings.CSV_DISCHARGE_HEADER) { private static final long serialVersionUID = 1L; @@ -160,6 +237,20 @@ } }; + public static final SInfoResultType riverside = new SInfoResultType(I18NStrings.UNIT_NONE, "sinfo.export.flood_duration.csv.header.riverside") { + private static final long serialVersionUID = 1L; + + @Override + public String exportValue(final CallContext context, final Object value) { + return exportStringValue(value); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + throw new UnsupportedOperationException(); + } + }; + public static final SInfoResultType gaugeLabel = new SInfoResultType(I18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_GAUGE_HEADER) { private static final long serialVersionUID = 1L; @@ -450,6 +541,22 @@ } }; + public static final SInfoResultType infrastructureHeightFloodDur = new SInfoResultType(I18NStrings.UNIT_M, + "sinfo.export.flood_duration.csv.header.infrastructure.height", "sinfo.export.flood_duration.pdf.header.infrastructure.height") { + private static final long serialVersionUID = 1L; + + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getInfrastructureHeight(context); + } + }; + public static final SInfoResultType infrastructureHeight = new SInfoResultType(I18NStrings.UNIT_M, SInfoI18NStrings.CSV_INFRASTRUCTURE_HEIGHT_HEADER) { private static final long serialVersionUID = 1L; diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/DurationWaterlevel.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/DurationWaterlevel.java Tue Jun 12 10:23:23 2018 +0200 @@ -0,0 +1,66 @@ +/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * 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.artifacts.sinfo.flood_duration; + +import java.io.Serializable; +import java.text.NumberFormat; + +/** + * @author Domenico Nardi Tironi + * + */ +public class DurationWaterlevel implements Serializable { + + private static final long serialVersionUID = 1L; + + private final double w; + private final double q; + private final String bezeichnung; + private final int floodDurDaysPerYear; + + public DurationWaterlevel(final double w, final int floodDurDaysPerYear, final double q, final String bezeichnung) { + this.w = w; + this.q = q; + this.bezeichnung = bezeichnung; + this.floodDurDaysPerYear = floodDurDaysPerYear; + } + + public String getFloodDurDaysPerYearFormatted() { + return String.valueOf(this.floodDurDaysPerYear); + } + + public String getBezeichnung() { + return this.bezeichnung; + } + + public String getQFormatted(final NumberFormat qFormatter) { + return qFormatter.format(this.q); + } + + public String getWFormatted(final NumberFormat wFormatter) { + return wFormatter.format(this.w); + } + + public static final String getHeaderQ() { + return "sinfo.flood_duration.header.q_index"; // kein extra-String für pdf + } + + public static final String getHeaderW() { + return "sinfo.flood_duration.header.pdf.w_index"; + } + + public static final String getHeaderBezeichn() { + return "sinfo.flood_duration.header.pdf.bezeichnung_index"; + } + + public static final String getHeaderFloodDurPerYear() { + return "sinfo.flood_duration.header.pdf.fd_per_year_index"; + } +} diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationAccess.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationAccess.java Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationAccess.java Tue Jun 12 10:23:23 2018 +0200 @@ -16,8 +16,6 @@ import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; import org.dive4elements.river.artifacts.sinfo.SinfoCalcMode; -import gnu.trove.TDoubleArrayList; - /** * Access to the flow depth calculation type specific SInfo artifact data. * REMARK: this class is NOT intended to be hold in the results (or anywhere else), in order to avoid a permanent @@ -32,20 +30,6 @@ private final EpochYearAccessHelper helper; - /// Fields from state: - - // calculation_mode (String), sollte sinfo_calc_flood_duration sein - // ld_from, ld_to, ld_step - // riverside, mögliche werte: "state.sinfo.riverside.left" "state.sinfo.riverside.right" "state.sinfo.riverside.both" - // wspl - // State.sinfo.WQ: - // - // - // - // - // - // - // public FloodDurationAccess(final SINFOArtifact artifact) { super(artifact); @@ -64,86 +48,4 @@ return super.getString("riverside"); } - public Boolean getWspl() { - return super.getBoolean("wspl"); - } - - public Boolean getWqIsQ() { - if (!getWspl()) { - return null;// - } - return super.getBoolean("wq_isq"); - } - - public Boolean getWqIsFree() { - if (!getWspl()) { - return null;// - } - return super.getBoolean("wq_isfree"); - } - - public Boolean getWqIsRange() { - if (!getWspl()) { - return null;// - } - return super.getBoolean("wq_isrange"); - } - - public Double getWqFrom() { - if (!getWspl()) { - return null;// - } - if (!getWqIsRange()) - return null; - - return super.getDouble("wq_from"); - } - - public Double getWqTo() { - if (!getWspl()) { - return null;// - } - if (!getWqIsRange()) - return null; - return super.getDouble("wq_to"); - } - - public Double getWqStep() { - if (!getWspl()) { - return null; - } - if (!getWqIsRange()) - return null; - - return super.getDouble("wq_step"); - } - - public double[] getWqSingle() { - if (!getWspl()) { - return null;// - } - if (getWqIsRange()) - return null; - - final String wqSingles = super.getString("wq_single"); - - if (wqSingles == null || wqSingles.isEmpty()) { - log.warn("No wqSingles provided"); - return null; - } - final TDoubleArrayList doubles = new gnu.trove.TDoubleArrayList(); - for (final String value : wqSingles.split(" ")) { - try { - - doubles.add(Double.parseDouble(value));// Punkt/komma? - } - catch (final NumberFormatException e) { - /* Client should prevent this */ - log.warn("Invalid wqsingle value: " + value); - continue; - } - } - return doubles.toNativeArray(); - } - } \ No newline at end of file diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Tue Jun 12 10:23:23 2018 +0200 @@ -16,8 +16,10 @@ import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; +import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; import org.dive4elements.river.model.River; class FloodDurationCalculation { @@ -49,20 +51,31 @@ final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); final String riverside = access.getRiverside(); - + final FloodDurationCalculationResults results = new FloodDurationCalculationResults(calcModeLabel, user, riverInfo, calcRange, riverside); // TODO: add + // more // TODO: mis- ups.. re-use WINFO Artifact as in TkhState + final WinfoArtifactWrapper winfo = new WinfoArtifactWrapper(sinfo); + // winfo.computeWaterlevelData(); + final FloodDurationCalculationResult result = calculateResult(calcRange, infoProvider, problems); - final double step = access.getStep(); - final boolean wspl = access.getWspl(); - final Boolean wqisfree = access.getWqIsFree(); - final Boolean wqIsQ = access.getWqIsQ(); - final Boolean wqIsRange = access.getWqIsRange(); - final Double wqFrom = access.getWqFrom(); - final Double wqTo = access.getWqTo(); - final Double wqStep = access.getWqStep(); - final double[] wqSingle = access.getWqSingle(); + results.addResult(result, problems); - return null; // new CalculationResult(results, problems); + return new CalculationResult(results, problems); + } + + /** + * Calculates FAKE Flood Duration + * + * @param infoProvider + */ + private FloodDurationCalculationResult calculateResult(final DoubleRange calcRange, final RiverInfoProvider riverInfoProvider, final Calculation problems) { + + final FloodDurationCalculator calculator = new FloodDurationCalculator(riverInfoProvider); + final String wspLabel = "WSP-Name";// wstKms.getName(); + final int wspYear = 9999; // waterlevel.getYear(); + final WstInfo wstInfo = new WstInfo(wspLabel, wspYear, riverInfoProvider.getReferenceGauge()); + final String label = String.format("%s - %s", wspLabel, " soundingLabel"); + return calculator.execute(label, wstInfo, calcRange); } } \ No newline at end of file diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java Tue Jun 12 10:23:23 2018 +0200 @@ -0,0 +1,38 @@ +/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * 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.artifacts.sinfo.flood_duration; + +import java.util.Collection; + +import org.dive4elements.river.artifacts.common.ResultRow; +import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResult; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; + +/** + * Contains the results of a {@link FloodDurationCalculation}. + * + * @author Gernot Belger + */ +final class FloodDurationCalculationResult extends AbstractSInfoCalculationResult { + + private static final long serialVersionUID = 1L; + private final int waterlevelCount; + + public FloodDurationCalculationResult(final String label, final WstInfo wstInfo, final Collection rows, final int waterlevelCount) { + super(label, wstInfo, rows); + this.waterlevelCount = waterlevelCount; + + } + + public int getWaterlevelCount() { + return this.waterlevelCount; + } + +} \ No newline at end of file diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResults.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResults.java Tue Jun 12 10:23:23 2018 +0200 @@ -0,0 +1,31 @@ +/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * 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.artifacts.sinfo.flood_duration; + +import org.apache.commons.lang.math.DoubleRange; +import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResults; +import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; + +/** + * @author Gernot Belger + */ +final class FloodDurationCalculationResults extends AbstractSInfoCalculationResults { + + private static final long serialVersionUID = 1L; + + private final String riverside; + + public FloodDurationCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange, + final String riverside) { + super(calcModeLabel, user, river, calcRange); + this.riverside = riverside; + } + +} \ No newline at end of file diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Tue Jun 12 10:23:23 2018 +0200 @@ -0,0 +1,73 @@ +/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * 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.artifacts.sinfo.flood_duration; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.lang.math.DoubleRange; +import org.dive4elements.river.artifacts.common.GeneralResultType; +import org.dive4elements.river.artifacts.common.ResultRow; +import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; + +/** + * @author Gernot Belger + */ +final class FloodDurationCalculator { + + private final Collection rows = new ArrayList<>(); + + private final RiverInfoProvider riverInfoProvider; + + public FloodDurationCalculator(final RiverInfoProvider riverInfoProvider) { + + this.riverInfoProvider = riverInfoProvider; + + } + + public FloodDurationCalculationResult execute(final String label, final WstInfo wstInfo, final DoubleRange calcRange) { + + calculateResultRow(8888.888); + calculateResultRow(99); + calculateResultRow(77); + return new FloodDurationCalculationResult(label, wstInfo, this.rows, 4); + } + + private void calculateResultRow(final double station) { + + final ResultRow row = ResultRow.create(); + + // REMARK: access the location once only during calculation + final String location = this.riverInfoProvider.getLocation(station); + row.putValue(GeneralResultType.station, station); + row.putValue(SInfoResultType.riverside, "todo:getRiverside"); + row.putValue(SInfoResultType.inundationduration, 44); + row.putValue(SInfoResultType.inundationdurationq, 444); + row.putValue(SInfoResultType.infrastructureHeight, 55); + row.putValue(SInfoResultType.infrastructuretype, "todo_get_infrastructureType"); + + // custom type; each entry produces 4 Columns + final List rowWsps = new ArrayList<>(); + + rowWsps.add(new DurationWaterlevel(222, 30, 666, "1. Test")); + rowWsps.add(new DurationWaterlevel(111, 40, 555, "2. Test")); + rowWsps.add(new DurationWaterlevel(123, 333, 33, "3. Test")); + rowWsps.add(new DurationWaterlevel(444, 452, 55, "4. Test")); + row.putValue(SInfoResultType.customMultiRowColWaterlevel, rowWsps); + + row.putValue(SInfoResultType.gaugeLabel, "todo:getReferencedGauge"); + row.putValue(SInfoResultType.location, "location"); + + this.rows.add(row); + } +} \ No newline at end of file diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationExporter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationExporter.java Tue Jun 12 10:23:23 2018 +0200 @@ -0,0 +1,237 @@ +/* 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.artifacts.sinfo.flood_duration; + +import java.io.OutputStream; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.log4j.Logger; +import org.dive4elements.river.artifacts.common.GeneralResultType; +import org.dive4elements.river.artifacts.common.JasperDesigner; +import org.dive4elements.river.artifacts.common.JasperReporter; +import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource; +import org.dive4elements.river.artifacts.common.ResultRow; +import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; +import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; + +import au.com.bytecode.opencsv.CSVWriter; +import net.sf.jasperreports.engine.JRException; + +/** + * Generates different output formats (csv, pdf) of data that resulted from a flow depths min/max computation. + * + * @author Ingo Weinzierl + * @author Gernot Belger + */ +// REMARK: must be public because its registered in generators.xml +public class FloodDurationExporter extends AbstractSInfoExporter { + + /** The log used in this exporter. */ + private static Logger log = Logger.getLogger(FloodDurationExporter.class); + + private final String getJasperFile(final int waterlevelCount) { + if (waterlevelCount <= 1) + return "/jasper/templates/sinfo.floodduration.jrxml"; // TODO use jrxml-path all over the project + else + return "/jasper/templates/sinfo.floodduration2.jrxml"; + } + + private static final int maxPdfWspls = 3; + + @Override + protected Logger getLog() { + return log; + } + + @Override + protected void writeCSVGlobalMetadata(final CSVWriter writer, final FloodDurationCalculationResults results) { + log.info("FloodDurationExporter.writeCSVMeta"); + super.writeCSVGlobalMetadataDefaults(writer, results); + } + + @Override + protected void writeCSVResultMetadata(final CSVWriter writer, final FloodDurationCalculationResults results, final FloodDurationCalculationResult result) { + + final WstInfo wst = result.getWst(); + super.writeCSVWaterlevelMetadata(writer, wst); // TODO: Abweichend vom Allgemeinen werden hier andere Felder benötigt bei den Wasserspiegellagen + + writer.writeNext(new String[] { "" }); // break line + + } + + /** + * Write the header, with different headings depending on whether at a + * gauge or at a location. + * + * @param river + * @param useTkh + */ + @Override + protected void writeCSVHeader(final CSVWriter writer, final FloodDurationCalculationResults results, final RiverInfo river) { + log.info("FloodDurationExporter.writeCSVHeader"); + + final Collection header = new ArrayList<>(99); + + header.add(msg(GeneralResultType.station.getCsvHeader())); + header.add(msg(SInfoResultType.riverside.getCsvHeader())); + header.add(msg(SInfoResultType.inundationduration.getCsvHeader())); + header.add(msg(SInfoResultType.inundationdurationq.getCsvHeader())); + header.add(msg(SInfoResultType.infrastructureHeight.getCsvHeader())); + header.add(msg(SInfoResultType.infrastructuretype.getCsvHeader())); + // add dynamic headers + final int waterlevelCount = getWaterlevelCount(); + for (int i = 0; i < waterlevelCount; i++) { + final int naturalIndex = i + 1; + final String appendIndex = new StringBuilder().append("_").append(naturalIndex).toString(); + final Object[] args = new Object[] { appendIndex }; + // new StringBuilder().append('\u2081').toString(); // schlechter UTF-8-Support für subscript ints + header.add(msg(DurationWaterlevel.getHeaderW(), new Object[] { appendIndex, "results.getRiver().getWstUnit()" })); + header.add(msg(DurationWaterlevel.getHeaderFloodDurPerYear(), args)); + header.add(msg(DurationWaterlevel.getHeaderQ(), args)); + header.add(msg(DurationWaterlevel.getHeaderBezeichn(), args)); + } + + header.add(msg(SInfoResultType.gaugeLabel.getCsvHeader())); + header.add(msg(SInfoResultType.location.getCsvHeader())); + + writer.writeNext(header.toArray(new String[header.size()])); + } + + private int getWaterlevelCount() { + final FloodDurationCalculationResults results = getData(); + if (results != null) { + final List list = results.getResults(); + if (list != null && list.size() > 0) { + final FloodDurationCalculationResult result = list.get(0); + return result.getWaterlevelCount(); + } + } + return 0; + } + + @Override + protected String[] formatRow(final FloodDurationCalculationResults results, final ResultRow row, final ExportMode mode) { + + final Collection lines = new ArrayList<>(99); + + lines.add(row.exportValue(this.context, GeneralResultType.station)); + lines.add(row.exportValue(this.context, SInfoResultType.riverside)); + lines.add(row.exportValue(this.context, SInfoResultType.inundationduration)); + lines.add(row.exportValue(this.context, SInfoResultType.inundationdurationq)); + lines.add(row.exportValue(this.context, SInfoResultType.infrastructureHeight)); + lines.add(row.exportValue(this.context, SInfoResultType.infrastructuretype)); + + final int waterlevelcount = this.getWaterlevelCount(); + + final List waterlevelList = (List) row.getValue(SInfoResultType.customMultiRowColWaterlevel); + if (waterlevelList != null) { + final NumberFormat wFormatter = getFlowDepthFormatter(); + final NumberFormat qFormatter = getQFormatter(); + + for (int i = 0; i < waterlevelList.size(); i++) { + + if (i == FloodDurationExporter.maxPdfWspls && mode == ExportMode.pdf) + break; + + final DurationWaterlevel item = waterlevelList.get(i); + lines.add(item.getWFormatted(wFormatter)); + lines.add(item.getFloodDurDaysPerYearFormatted()); + lines.add(item.getQFormatted(qFormatter)); + lines.add(item.getBezeichnung()); + } + } + + if ((waterlevelcount == 0 || waterlevelcount == 2) && mode == ExportMode.pdf) { + lines.add("dummy"); + lines.add("dummy"); + lines.add("dummy"); + lines.add("dummy"); + } + + lines.add(row.exportValue(this.context, SInfoResultType.gaugeLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.location)); + return lines.toArray(new String[lines.size()]); + } + + @Override + protected void writePDF(final OutputStream out) { + + try { + final MetaAndTableJRDataSource source = createJRData(this.data); + final JasperReporter reporter = new JasperReporter(); + final int waterlevelCount = getWaterlevelCount(); + final JasperDesigner design = reporter.addReport(getJasperFile(waterlevelCount), source); + + if (waterlevelCount == 0 || waterlevelCount == 2) { + design.removeColumn("wOpt"); + design.removeColumn("qOpt"); + design.removeColumn("bezOpt"); + design.removeColumn("durOpt"); + } + + reporter.exportPDF(out); + } + catch (final JRException je) { + getLog().warn("Error generating PDF Report!", je); + } + } + + @Override + protected final void addJRMetaData(final MetaAndTableJRDataSource source, final FloodDurationCalculationResults results) { + + /* general metadata */ + super.addJRMetaData(source, results); + + /* column headings */ + source.addMetaData("station_header", GeneralResultType.station.getPdfHeader(this.context.getMeta())); + source.addMetaData("riverside_header", SInfoResultType.riverside.getPdfHeader(this.context.getMeta())); + source.addMetaData("inundationduration_header", SInfoResultType.inundationduration.getPdfHeader(this.context.getMeta())); + source.addMetaData("inundationduration_q_header", SInfoResultType.inundationdurationq.getPdfHeader(this.context.getMeta())); + source.addMetaData("infrastructure_height_header", SInfoResultType.infrastructureHeightFloodDur.getPdfHeader(this.context.getMeta())); + source.addMetaData("infrastructure_type_header", SInfoResultType.infrastructuretype.getPdfHeader(this.context.getMeta())); + + // add dynamic headers + + final int waterlevelCount = getWaterlevelCount() > FloodDurationExporter.maxPdfWspls ? FloodDurationExporter.maxPdfWspls : getWaterlevelCount(); + + if (waterlevelCount == 0 || waterlevelCount == 2) { + source.addMetaData("dummy", "dummy"); + source.addMetaData("dummy", "dummy"); + source.addMetaData("dummy", "dummy"); + source.addMetaData("dummy", "dummy"); + } + + for (int i = 0; i < waterlevelCount; i++) { + final int naturalIndex = i + 1; + + final Object[] args = new String[] { new StringBuilder().append("_").append(naturalIndex).toString() }; + source.addMetaData(getPdfHeader("w", naturalIndex), msg(DurationWaterlevel.getHeaderW(), args)); + source.addMetaData(getPdfHeader("duration", naturalIndex), msg(DurationWaterlevel.getHeaderFloodDurPerYear(), args)); + source.addMetaData(getPdfHeader("q", naturalIndex), msg(DurationWaterlevel.getHeaderQ(), args)); + source.addMetaData(getPdfHeader("bezeichnung", naturalIndex), msg(DurationWaterlevel.getHeaderBezeichn(), args)); + + } + + source.addMetaData("gauge_header", SInfoResultType.gaugeLabel.getPdfHeader(this.context.getMeta())); + source.addMetaData("location_header", SInfoResultType.location.getPdfHeader(this.context.getMeta())); + + } + + private String getPdfHeader(final String rootStr, final int index) { + final String hd = "_header"; + final StringBuilder builder = new StringBuilder(); + return builder.append(rootStr).append("_").append(index).append(hd).toString(); + } + +} \ No newline at end of file diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Tue Jun 12 10:23:23 2018 +0200 @@ -15,7 +15,9 @@ import org.dive4elements.river.artifacts.ChartArtifact; import org.dive4elements.river.artifacts.D4EArtifact; import org.dive4elements.river.artifacts.model.CalculationResult; +import org.dive4elements.river.artifacts.model.DataFacet; import org.dive4elements.river.artifacts.model.EmptyFacet; +import org.dive4elements.river.artifacts.model.FacetTypes; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; import org.dive4elements.river.artifacts.states.DefaultState; @@ -66,36 +68,29 @@ if (facets == null) return res; - // - // final FlowDepthCalculationResults results = (FlowDepthCalculationResults) res.getData(); - // - // /* add themes for chart, for each result */ - // final List resultList = results.getResults(); - // for (int index = 0; index < resultList.size(); index++) { - // - // final FlowDepthCalculationResult result = resultList.get(index); - // - // /* filtered (zoom dependent mean) flow depth */ - // facets.add(FlowDepthProcessor.createFlowDepthFilteredFacet(context, hash, this.id, result, index)); - // facets.add(FlowDepthProcessor.createFlowDepthRawFacet(context, hash, this.id, result, index)); - // - // if (results.isUseTkh()) { - // /* filtered (zoom dependent mean) flow depth including tkh */ - // facets.add(FlowDepthProcessor.createFlowDepthTkhFilteredFacet(context, hash, this.id, result, index)); - // facets.add(FlowDepthProcessor.createFlowDepthTkhRawFacet(context, hash, this.id, result, index)); - // - // facets.add(TkhProcessor.createTkhFacet(context, hash, this.id, result, index)); - // } - // } - // if (!resultList.isEmpty()) { - // final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id); - // final Facet pdf = new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id); - // - // facets.add(csv); - // facets.add(pdf); - // } - // + final FloodDurationCalculationResults results = (FloodDurationCalculationResults) res.getData(); + + /* add themes for chart, for each result */ + final List resultList = results.getResults(); + for (int index = 0; index < resultList.size(); index++) { + + final FloodDurationCalculationResult result = resultList.get(index); + + /* filtered (zoom dependent mean) flow depth TODO: */ + // facets.add(FloodDurationProcessor.createFlowDepthFilteredFacet(context, hash, this.id, result, index)); + // facets.add(FloodDurationProcessor.createFlowDepthRawFacet(context, hash, this.id, result, index)); + + } + + if (!resultList.isEmpty()) { + final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id); + final Facet pdf = new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id); + + facets.add(csv); + facets.add(pdf); + } + // final Calculation report = res.getReport(); // // if (report.hasProblems()) { diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/WinfoArtifactWrapper.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/WinfoArtifactWrapper.java Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/WinfoArtifactWrapper.java Tue Jun 12 10:23:23 2018 +0200 @@ -22,7 +22,7 @@ * * @author Gernot Belger */ -class WinfoArtifactWrapper extends WINFOArtifact { +public final class WinfoArtifactWrapper extends WINFOArtifact { private static final long serialVersionUID = 1L; diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java --- a/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java Tue Jun 12 10:23:23 2018 +0200 @@ -415,6 +415,10 @@ return getFormatter(context.getMeta(), 2, 2); } + public static NumberFormat getIntegerFormatter(final CallContext context) { + return getFormatter(context.getMeta(), 0, 0); + } + public static NumberFormat getCollisionCount(final CallContext context) { return getFormatter(context.getMeta(), 0, 0); } diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/resources/messages.properties --- a/artifacts/src/main/resources/messages.properties Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/resources/messages.properties Tue Jun 12 10:23:23 2018 +0200 @@ -920,6 +920,15 @@ sinfo.export.flow_depth.csv.header.mean_bed_height.short = Mittlere Sohl- sinfo.export.flow_depth.csv.header.sounding = Peilung/Epoche sinfo.export.flow_depth.csv.header.location = Lage +sinfo.export.flood_duration.csv.header.riverside = Uferseite +sinfo.export.flood_duration.csv.header.infrastructure.height = H\u00f6he der Infrastruktur +sinfo.export.flood_duration.csv.header.inundation_duration = \u00dcberflutungsdauer [d/a] +sinfo.export.flood_duration.csv.header.inundation_duration_q = \u00dcberflutungsdauerabfluss Q[m\u00b3/s] +sinfo.export.flood_duration.csv.header.infrastructure_type = Infrastrukturtyp +sinfo.export.flood_duration.pdf.header.inundation_duration = \u00dcberflu-tungs-dauer [d/a] +sinfo.export.flood_duration.pdf.header.inundation_duration_q = \u00dcberflu-tungs-dauer-abfluss Q[m\u00b3/s] +sinfo.export.flood_duration.pdf.header.infrastructure_type = Infra-struktur-typ +sinfo.export.flood_duration.pdf.header.infrastructure.height = H\u00f6he der Infra-struktur sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt @@ -991,6 +1000,15 @@ sinfo.facet.flow_depth_historical.filtered.description = h-historisch ({0}) sinfo.facet.flow_depth_historical.raw.description = h-historisch ({0}) (raw) +sinfo.flood_duration.header.bezeichnung_index = Bezeichnung{0} +sinfo.flood_duration.header.pdf.bezeichnung_index = Bezeich-nung{0} +sinfo.flood_duration.header.fd_per_year_index = \u00dcberflutungsdauer WSPL{0} [d/a] +sinfo.flood_duration.header.pdf.fd_per_year_index = \u00dcberflu-tungs-dauer WSPL{0} [d/a] +sinfo.flood_duration.header.pdf.fd_per_year_index = \u00dcberflu-tungs-dauer WSPL{0} [d/a] +sinfo.flood_duration.header.w_index = Wasser-stand/Wasser-spiegel-lage{0} +sinfo.flood_duration.header.pdf.w_index = Wasser-stand/ Wasser-spiegel-lage{0} +sinfo.flood_duration.header.q_index = Q{0} [m\u00b3/sec] + sinfo.export.flow_depth_minmax.csv.header.min = Minimale Flie\u00dftiefe sinfo.export.flow_depth_minmax.csv.header.max = Maximale Flie\u00dftiefe diff -r 7879c2ca8bd3 -r e6b63b2b41b9 artifacts/src/main/resources/messages_de.properties --- a/artifacts/src/main/resources/messages_de.properties Mon Jun 11 09:55:35 2018 +0200 +++ b/artifacts/src/main/resources/messages_de.properties Tue Jun 12 10:23:23 2018 +0200 @@ -920,6 +920,15 @@ sinfo.export.flow_depth.csv.header.mean_bed_height.short = Mittlere Sohl- sinfo.export.flow_depth.csv.header.sounding = Peilung/Epoche sinfo.export.flow_depth.csv.header.location = Lage +sinfo.export.flood_duration.csv.header.riverside = Uferseite +sinfo.export.flood_duration.csv.header.infrastructure.height = H\u00f6he der Infrastruktur +sinfo.export.flood_duration.csv.header.inundation_duration = \u00dcberflutungsdauer [d/a] +sinfo.export.flood_duration.csv.header.inundation_duration_q = \u00dcberflutungsdauerabfluss Q[m\u00b3/s] +sinfo.export.flood_duration.csv.header.infrastructure_type = Infrastrukturtyp +sinfo.export.flood_duration.pdf.header.inundation_duration = \u00dcberflu-tungs-dauer [d/a] +sinfo.export.flood_duration.pdf.header.inundation_duration_q = \u00dcberflu-tungs-dauer-abfluss Q[m\u00b3/s] +sinfo.export.flood_duration.pdf.header.infrastructure_type = Infra-struktur-typ +sinfo.export.flood_duration.pdf.header.infrastructure.height = H\u00f6he der Infra-struktur sinfo.chart.flow_depth.section.title=h-L\u00e4ngsschnitt @@ -991,6 +1000,15 @@ sinfo.facet.flow_depth_historical.filtered.description = h-historisch ({0}) sinfo.facet.flow_depth_historical.raw.description = h-historisch ({0}) (Rohdaten) +sinfo.flood_duration.header.bezeichnung_index = Bezeichnung{0} +sinfo.flood_duration.header.pdf.bezeichnung_index = Bezeich-nung{0} +sinfo.flood_duration.header.fd_per_year_index = \u00dcberflutungsdauer WSPL{0} [d/a] +sinfo.flood_duration.header.pdf.fd_per_year_index = \u00dcberflu-tungs-dauer WSPL{0} [d/a] +sinfo.flood_duration.header.pdf.fd_per_year_index = \u00dcberflu-tungs-dauer WSPL{0} [d/a] +sinfo.flood_duration.header.w_index = Wasser-stand/Wasser-spiegel-lage{0} +sinfo.flood_duration.header.pdf.w_index = Wasser-stand/ Wasser-spiegel-lage{0} +sinfo.flood_duration.header.q_index = Q{0} [m\u00b3/sec] + sinfo.export.flow_depth_minmax.csv.header.min = Minimale Flie\u00dftiefe sinfo.export.flow_depth_minmax.csv.header.max = Maximale Flie\u00dftiefe diff -r 7879c2ca8bd3 -r e6b63b2b41b9 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java --- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Mon Jun 11 09:55:35 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Tue Jun 12 10:23:23 2018 +0200 @@ -1534,4 +1534,8 @@ String chart_settings_export_metadata(); String sinfo_flow_depth_development_twin_panel_max_count_msg(); + + String sinfo_floodduration_export(); + + String sinfo_floodduration_report(); } \ No newline at end of file diff -r 7879c2ca8bd3 -r e6b63b2b41b9 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties --- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Mon Jun 11 09:55:35 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Tue Jun 12 10:23:23 2018 +0200 @@ -298,6 +298,8 @@ events = Events kmchart = W/Q-Preview fix_waterlevel_export = Fixing analysis export +sinfo_floodduration_export = \u00dcberflutungsdauern Infrastrukturen BWaStr Export +sinfo_floodduration_report = \u00dcberflutungsdauern Infrastrukturen BWaStr Report chart_themepanel_header_themes = Theme chart_themepanel_header_actions = Actions diff -r 7879c2ca8bd3 -r e6b63b2b41b9 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties --- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Mon Jun 11 09:55:35 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Tue Jun 12 10:23:23 2018 +0200 @@ -298,6 +298,8 @@ events = Ereignisse kmchart = W/Q-Vorschau fix_waterlevel_export = Fixierungsanalysen Export +sinfo_floodduration_export = \u00dcberflutungsdauern Infrastrukturen BWaStr Export +sinfo_floodduration_report = \u00dcberflutungsdauern Infrastrukturen BWaStr Bericht chart_themepanel_header_themes = Thema chart_themepanel_header_actions = Aktionen