# HG changeset patch # User gernotbelger # Date 1521033032 -3600 # Node ID a4f1ac81f26db2eb4f7fb18209e58abe591c4052 # Parent 86650594f051fce387e411af135096258a18ab42 Work on SINFO-FlowDepthMinMax. Also rework of result row stuff, in order to reduce abstraction, using result type concept diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java Wed Mar 14 14:10:32 2018 +0100 @@ -52,6 +52,18 @@ String CSV_SOUNDING_HEADER = "sinfo.export.flow_depth.csv.header.sounding"; + String CSV_FLOWDEPTH_HEADER = "sinfo.export.flow_depth.csv.header.flowdepth"; + + String CSV_FLOWDEPTHTKH_HEADER = "sinfo.export.flow_depth.csv.header.flowdepthTkh"; + + String CSV_FLOWDEPTH_MIN_HEADER = "sinfo.export.flow_depth_minmax.csv.header.min"; + + String CSV_FLOWDEPTH_MAX_HEADER = "sinfo.export.flow_depth_minmax.csv.header.max"; + + String CSV_TKH_HEADER = "sinfo.export.tkh.csv.header.tkh"; + + String CSV_TKHKIND_HEADER = "sinfo.export.tkh.csv.header.tkhkind"; + String CSV_META_HEADER_WATERLEVEL = "sinfo.export.flow_depth.csv.meta.header.waterlevel"; String CSV_META_HEADER_WATERLEVEL_NAME = "sinfo.export.flow_depth.csv.meta.header.waterlevel.name"; @@ -68,8 +80,14 @@ String CSV_MEAN_BED_HEIGHT_HEADER_SHORT = "sinfo.export.flow_depth.csv.header.mean_bed_height.short"; + String PREFIX_TKH_KIND = "sinfo.export.tkh.soilkind."; + + String UNIT_NONE = "-"; + String UNIT_M = "m"; + String UNIT_KM = "km"; + String UNIT_CM = "cm"; String UNIT_CUBIC_M = "m³/s"; diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResult.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResult.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResult.java Wed Mar 14 14:10:32 2018 +0100 @@ -13,23 +13,26 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.List; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; +import gnu.trove.TDoubleArrayList; + /** * @author Gernot Belger */ -public abstract class AbstractSInfoCalculationResult implements Serializable { +public abstract class AbstractSInfoCalculationResult implements Serializable { private static final long serialVersionUID = 1L; - private final Collection rows; + private final Collection rows; private final String label; private final WstInfo wst; - public AbstractSInfoCalculationResult(final String label, final WstInfo wst, final Collection rows) { + public AbstractSInfoCalculationResult(final String label, final WstInfo wst, final Collection rows) { this.label = label; this.wst = wst; this.rows = new ArrayList<>(rows); @@ -43,11 +46,41 @@ return this.wst; } - public final void addRow(final ROW resultRow) { + public final void addRow(final SInfoResultRow resultRow) { this.rows.add(resultRow); } - public final Collection getRows() { + public final Collection getRows() { return Collections.unmodifiableCollection(this.rows); } + + public final double[][] getStationPoints(final SInfoResultType type) { + + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + + for (final SInfoResultRow row : this.rows) { + + final double station = row.getDoubleValue(SInfoResultType.station); + final double value = row.getDoubleValue(type); + + xPoints.add(station); + yPoints.add(value); + } + + return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; + } + + protected final List getValues(final SInfoResultType type) { + + final List values = new ArrayList<>(); + + for (final SInfoResultRow row : this.rows) { + @SuppressWarnings("unchecked") + final TYPE value = (TYPE) row.getValue(type); + values.add(value); + } + + return values; + } } \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResults.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResults.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResults.java Wed Mar 14 14:10:32 2018 +0100 @@ -20,7 +20,7 @@ /** * @author Gernot Belger */ -public abstract class AbstractSInfoCalculationResults> implements Serializable { +public abstract class AbstractSInfoCalculationResults implements Serializable { private static final long serialVersionUID = 1L; diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoExporter.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoExporter.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoExporter.java Wed Mar 14 14:10:32 2018 +0100 @@ -42,7 +42,7 @@ /** * @author Gernot Belger */ -public abstract class AbstractSInfoExporter, RESULTS extends AbstractSInfoCalculationResults> extends AbstractExporter { +public abstract class AbstractSInfoExporter> extends AbstractExporter { private static final String CSV_META_HEADER_SOUNDING = "sinfo.export.flow_depth.csv.meta.header.sounding"; @@ -120,9 +120,9 @@ writeCSVResultMetadata(writer, results, result); /* nwo the value rows */ - final Collection rows = result.getRows(); - for (final ROW row : rows) { - writeCSVRow(writer, results, row); + final Collection rows = result.getRows(); + for (final SInfoResultRow row : rows) { + writeCSVRow(writer, results, result, row); } } @@ -131,14 +131,14 @@ */ protected abstract void writeCSVResultMetadata(CSVWriter writer, RESULTS results, RESULT result); - protected final void writeCSVRow(final CSVWriter writer, final RESULTS results, final ROW row) { + protected final void writeCSVRow(final CSVWriter writer, final RESULTS results, final RESULT result, final SInfoResultRow row) { getLog().debug("writeCSVFlowDepthRow"); - final String[] formattedRow = formatCSVRow(results, row); + final String[] formattedRow = formatCSVRow(results, result, row); writer.writeNext(formattedRow); } - protected abstract String[] formatCSVRow(RESULTS results, final ROW row); + protected abstract String[] formatCSVRow(RESULTS results, RESULT result, final SInfoResultRow row); @Override protected final void writePDF(final OutputStream outStream) { @@ -186,18 +186,18 @@ protected final void addJRTableData(final MetaAndTableJRDataSource source, final RESULTS results, final RESULT result) { - final Collection rows = result.getRows(); + final Collection rows = result.getRows(); - for (final ROW row : rows) { + for (final SInfoResultRow row : rows) { final String[] formattedRow = formatPDFRow(results, row); source.addData(formattedRow); } } - protected abstract String[] formatPDFRow(RESULTS results, final ROW row); + protected abstract String[] formatPDFRow(RESULTS results, final SInfoResultRow row); - protected final void writeCSVGlobalMetadataDefaults(final CSVWriter writer, final AbstractSInfoCalculationResults results) { + protected final void writeCSVGlobalMetadataDefaults(final CSVWriter writer, final AbstractSInfoCalculationResults results) { final String calcModeLabel = results.getCalcModeLabel(); final RiverInfo river = results.getRiver(); @@ -261,7 +261,7 @@ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_YEAR, Integer.toString(year)); } - protected final void addJRMetaDataDefaults(final MetaAndTableJRDataSource source, final AbstractSInfoCalculationResults results) { + protected final void addJRMetaDataDefaults(final MetaAndTableJRDataSource source, final AbstractSInfoCalculationResults results) { final RiverInfo river = results.getRiver(); final String wstUnitName = river.getWstUnit(); diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java Wed Mar 14 14:10:32 2018 +0100 @@ -26,7 +26,7 @@ import org.dive4elements.river.jfree.StyledXYSeries; import org.dive4elements.river.themes.ThemeDocument; -abstract class AbstractSInfoLineProcessor> extends AbstractSInfoProcessor { +abstract class AbstractSInfoLineProcessor extends AbstractSInfoProcessor { public AbstractSInfoLineProcessor(final String i18nAxisLabel, final Set handledFacetType) { super(i18nAxisLabel, handledFacetType); diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoResultRow.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoResultRow.java Wed Mar 14 14:09:33 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/** 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.common; - -import java.io.Serializable; - -/** - * Contains common result data of flow-depth- and tkh-calculations. - * - * @author Gernot Belger - */ -public abstract class AbstractSInfoResultRow implements Serializable { - private static final long serialVersionUID = 1L; - - private final String waterlevelLabel; - - private final String gauge; - - private final String location; - - public AbstractSInfoResultRow(final String waterlevelLabel, final String gauge, final String location) { - this.waterlevelLabel = waterlevelLabel; - this.gauge = gauge; - this.location = location; - } - - public final String getWaterlevelLabel() { - return this.waterlevelLabel; - } - - public final String getGauge() { - return this.gauge; - } - - public final String getLocation() { - return this.location; - } -} \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhCalculationResult.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhCalculationResult.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhCalculationResult.java Wed Mar 14 14:10:32 2018 +0100 @@ -9,7 +9,6 @@ */ package org.dive4elements.river.artifacts.sinfo.common; -import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -21,14 +20,15 @@ /** * @author Gernot Belger */ -public abstract class AbstractTkhCalculationResult extends AbstractSInfoCalculationResult { +public abstract class AbstractTkhCalculationResult extends AbstractSInfoCalculationResult { private static final long serialVersionUID = 1L; private final boolean hasTkh; - public AbstractTkhCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection rows) { + public AbstractTkhCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection rows) { super(label, wst, rows); + this.hasTkh = hasTkh; } @@ -36,138 +36,51 @@ return this.hasTkh; } - public double[][] getFlowDepthPoints() { - - final Collection rows = getRows(); - - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - - for (final ROW row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getFlowDepth()); - } - - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } - - public double[][] getFlowDepthTkhPoints() { - - final Collection rows = getRows(); - - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - - for (final ROW row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getFlowDepthWithTkh()); - } - - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } - public final double[][] getTkhUpPoints() { - final Collection rows = getRows(); + final double[][] points = getStationPoints(SInfoResultType.tkhup); + final List kinds = getValues(SInfoResultType.soilkind); - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - final List kinds = new ArrayList<>(rows.size()); - - for (final ROW row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getTkhUp()); - kinds.add(row.getTkhKind()); - } + final double[] xPoints = points[0]; + final double[] yPoints = points[1]; return adjustTkhVisualization(xPoints, yPoints, kinds); } public final double[][] getTkhDownPoints() { - final Collection rows = getRows(); + final double[][] points = getStationPoints(SInfoResultType.tkhdown); + final List kinds = getValues(SInfoResultType.soilkind); - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - final List kinds = new ArrayList<>(rows.size()); - - for (final ROW row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getTkhDown()); - kinds.add(row.getTkhKind()); - } + final double[] xPoints = points[0]; + final double[] yPoints = points[1]; return adjustTkhVisualization(xPoints, yPoints, kinds); } - public double[][] getVelocityPoints() { - - final Collection rows = getRows(); - - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - - for (final ROW row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getVelocity()); - } - - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } - - public double[][] getD50Points() { - - final Collection rows = getRows(); - - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - - for (final ROW row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getD50()); - } - - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } - - public double[][] getTauPoints() { - - final Collection rows = getRows(); - - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - - for (final ROW row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getTau()); - } - - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } - /** * the up and down points must be further adjusted for visualization, see Mail Hr. Reiß * basically we need to introduce extra points when the kind changes, so we get vertical lines in that case */ - private double[][] adjustTkhVisualization(final TDoubleArrayList xPoints, final TDoubleArrayList yPoints, final List kinds) { + private double[][] adjustTkhVisualization(final double[] xPoints, final double[] yPoints, final List kinds) { - final TDoubleArrayList adjustedX = new TDoubleArrayList(xPoints.size()); - final TDoubleArrayList adjustedY = new TDoubleArrayList(yPoints.size()); + final TDoubleArrayList adjustedX = new TDoubleArrayList(xPoints.length); + final TDoubleArrayList adjustedY = new TDoubleArrayList(yPoints.length); - adjustedX.add(xPoints.get(0)); - adjustedY.add(yPoints.get(0)); + adjustedX.add(xPoints[0]); + adjustedY.add(yPoints[0]); - for (int i = 1; i < xPoints.size(); i++) { + for (int i = 1; i < xPoints.length; i++) { final SoilKind kind1 = kinds.get(i - 1); final SoilKind kind2 = kinds.get(i); if (kind1 != kind2) { /* introduce two extra points in order to create a vertical line in the middle of the two adjacent points */ - final double x1 = xPoints.get(i - 1); - final double y1 = yPoints.get(i - 1); - final double x2 = xPoints.get(i); - final double y2 = yPoints.get(i); + final double x1 = xPoints[i - 1]; + final double y1 = yPoints[i - 1]; + final double x2 = xPoints[i]; + final double y2 = yPoints[i]; final double middleX = (x1 + x2) / 2; @@ -180,8 +93,8 @@ } /* always add the real point now */ - adjustedX.add(xPoints.get(i)); - adjustedY.add(yPoints.get(i)); + adjustedX.add(xPoints[i]); + adjustedY.add(yPoints[i]); } return new double[][] { adjustedX.toNativeArray(), adjustedY.toNativeArray() }; diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhResultRow.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhResultRow.java Wed Mar 14 14:09:33 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/** 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.common; - -import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind; -import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh; - -/** - * Contains common result data of flow-depth- and tkh-calculations. - * - * @author Gernot Belger - */ -public abstract class AbstractTkhResultRow extends AbstractSInfoResultRow { - private static final long serialVersionUID = 1L; - - private final Tkh tkh; - - public AbstractTkhResultRow(final Tkh tkh, final String waterlevelLabel, final String gauge, final String location) { - super(waterlevelLabel, gauge, location); - this.tkh = tkh; - } - - public final double getStation() { - return this.tkh.getStation(); - } - - public final SoilKind getTkhKind() { - return this.tkh.getKind(); - } - - public final double getTkh() { - return this.tkh.getTkh(); - } - - public final double getTkhUp() { - return this.tkh.getUp(); - } - - public final double getTkhDown() { - return this.tkh.getDown(); - } - - public final double getWaterlevel() { - return this.tkh.getWaterlevel(); - } - - public final double getDischarge() { - return this.tkh.getDischarge(); - } - - public final double getMeanBedHeight() { - return this.tkh.getMeanBedHeight(); - } - - public final double getFlowDepth() { - return this.tkh.getFlowDepth(); - } - - public double getFlowDepthWithTkh() { - return this.tkh.getFlowDepthTkh(); - } - - public double getVelocity() { - return this.tkh.getVelocity(); - } - - public double getD50() { - return this.tkh.getD50(); - } - - public double getTau() { - return this.tkh.getTau(); - } -} \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/D50Processor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/D50Processor.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/D50Processor.java Wed Mar 14 14:10:32 2018 +0100 @@ -18,7 +18,7 @@ import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; -public final class D50Processor extends AbstractSInfoLineProcessor> { +public final class D50Processor extends AbstractSInfoLineProcessor { // FIXME: check: filtered or not? public static final String FACET_TKH_D50_FILTERED = "sinfo_facet_d50.filtered"; @@ -40,16 +40,16 @@ } @Override - protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) { + protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) { if (FACET_TKH_D50_FILTERED.contentEquals(facetName)) - return data.getD50Points(); + return data.getStationPoints(SInfoResultType.d50); final String error = String.format("Unknown facet name: %s", facetName); throw new UnsupportedOperationException(error); } - public static Facet createD50Facet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, + public static Facet createD50Facet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, final int index) { final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_D50_FILTERED_DESCRIPTION, I18N_FACET_TKH_D50_FILTERED_DESCRIPTION, result.getLabel()); diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FlowDepthProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FlowDepthProcessor.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FlowDepthProcessor.java Wed Mar 14 14:10:32 2018 +0100 @@ -18,7 +18,7 @@ import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; -public final class FlowDepthProcessor extends AbstractSInfoLineProcessor> { +public final class FlowDepthProcessor extends AbstractSInfoLineProcessor { private static final String I18N_AXIS_LABEL = "sinfo.chart.flow_depth.section.yaxis.label"; @@ -47,19 +47,19 @@ } @Override - protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) { + protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) { if (FACET_FLOW_DEPTH_FILTERED.contentEquals(facetName)) - return data.getFlowDepthPoints(); + return data.getStationPoints(SInfoResultType.flowdepth); if (FACET_FLOW_DEPTH_TKH_FILTERED.contentEquals(facetName)) - return data.getFlowDepthTkhPoints(); + return data.getStationPoints(SInfoResultType.flowdepthtkh); final String error = String.format("Unknown facet name: %s", facetName); throw new UnsupportedOperationException(error); } - public static Facet createFlowDepthFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, + public static Facet createFlowDepthFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, final int index) { final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, result.getLabel()); @@ -67,7 +67,7 @@ ComputeType.ADVANCE, id, hash); } - public static Facet createFlowDepthTkhFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, + public static Facet createFlowDepthTkhFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, final int index) { final String facetFlowDepthTkhFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION, I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION, result.getLabel()); diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultFacet.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultFacet.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultFacet.java Wed Mar 14 14:10:32 2018 +0100 @@ -45,7 +45,7 @@ final CalculationResult res = (CalculationResult) flys.compute(context, this.hash, this.stateId, this.type, false); - final AbstractSInfoCalculationResults data = (AbstractSInfoCalculationResults) res.getData(); + final AbstractSInfoCalculationResults data = (AbstractSInfoCalculationResults) res.getData(); return data.getResults().get(this.index); } diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultRow.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultRow.java Wed Mar 14 14:10:32 2018 +0100 @@ -0,0 +1,56 @@ +/** 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.common; + +import java.io.Serializable; +import java.util.EnumMap; +import java.util.Map; + +import org.dive4elements.artifacts.CallContext; + +/** + * Generic container for results that come in rows. + * + * @author Gernot Belger + */ +public final class SInfoResultRow implements Serializable { + private static final long serialVersionUID = 1L; + + private final Map values = new EnumMap<>(SInfoResultType.class); + + public static SInfoResultRow create() { + return new SInfoResultRow(); + } + + private SInfoResultRow() { + } + + public SInfoResultRow putValue(final SInfoResultType type, final Object value) { + + this.values.put(type, value); + + /* chain me */ + return this; + } + + public String exportValue(final CallContext context, final SInfoResultType type) { + final Object value = this.values.get(type); + return type.exportValue(context, value); + } + + public double getDoubleValue(final SInfoResultType type) { + final Object value = this.values.get(type); + return type.asDouble(value); + } + + public Object getValue(final SInfoResultType type) { + return this.values.get(type); + } +} \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Wed Mar 14 14:10:32 2018 +0100 @@ -0,0 +1,339 @@ +/** 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.common; + +import java.text.NumberFormat; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.artifacts.CallMeta; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings; +import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind; +import org.dive4elements.river.utils.Formatter; +import org.dive4elements.river.utils.RiverUtils; + +/** + * Result type for data that goes into {@link SInfoResultRow}s. + * + * @author Gernot Belger + */ +public enum SInfoResultType { + + station(SInfoI18NStrings.UNIT_KM, SInfoI18NStrings.CSV_KM_HEADER) { + @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.getWaterlevelKM(context); + } + }, + + waterlevel(null, SInfoI18NStrings.CSV_WATERLEVEL_HEADER) { + @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) { + // REMARK: other modules use Formatter.getWaterlevelW(context) instead, but that format with a variable number of + // digits. + return Formatter.getFlowDepth(context); + } + }, + + waterlevelLabel(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_LABEL_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + return exportStringValue(value); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + throw new UnsupportedOperationException(); + } + }, + + discharge(SInfoI18NStrings.UNIT_CUBIC_M, SInfoI18NStrings.CSV_DISCHARGE_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + final double roundedDischarge = RiverUtils.roundQ(doubleValue); + return exportDoubleValue(context, roundedDischarge); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getWaterlevelQ(context); + } + }, + + meanBedHeight(null, SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_HEADER) { + @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.getMeanBedHeight(context); + } + }, + + soundingLabel(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_SOUNDING_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + return exportStringValue(value); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + throw new UnsupportedOperationException(); + } + }, + + flowdepthmin(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTH_MIN_HEADER) { + @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.getFlowDepth(context); + } + }, + + flowdepthmax(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTH_MAX_HEADER) { + @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.getFlowDepth(context); + } + }, + + gaugeLabel(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_GAUGE_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + return exportStringValue(value); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + throw new UnsupportedOperationException(); + } + }, + + location(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_LOCATION_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + return exportStringValue(value); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + throw new UnsupportedOperationException(); + } + }, + soilkind(SInfoI18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_TKHKIND_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + + if (value == null) + return StringUtils.EMPTY; + + final SoilKind kind = (SoilKind) value; + + final String key = SInfoI18NStrings.PREFIX_TKH_KIND + kind.name(); + return Resources.getMsg(context.getMeta(), key, key); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + throw new UnsupportedOperationException(); + } + }, + flowdepth(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTH_HEADER) { + @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.getFlowDepth(context); + } + }, + d50(null, null) { + @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) { + throw new UnsupportedOperationException(); + } + }, + velocity(null, null) { + @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) { + throw new UnsupportedOperationException(); + } + }, + tau(null, null) { + @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) { + throw new UnsupportedOperationException(); + } + }, + tkh(SInfoI18NStrings.UNIT_CM, SInfoI18NStrings.CSV_TKH_HEADER) { + @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.getTkh(context); + } + }, + tkhup(SInfoI18NStrings.UNIT_CM, null) { + @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) { + throw new UnsupportedOperationException(); + } + }, + tkhdown(SInfoI18NStrings.UNIT_CM, null) { + @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) { + throw new UnsupportedOperationException(); + } + }, + flowdepthtkh(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTHTKH_HEADER) { + @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.getFlowDepth(context); + } + }; + + /* Cache for formatters because Formatter will always create new formats (which is very expensive) */ + private final Map formatters = new HashMap<>(); + + private final String unit; + + private final String csvHeader; + + private SInfoResultType(final String untit, final String csvHeader) { + this.unit = untit; + this.csvHeader = csvHeader; + } + + public abstract String exportValue(final CallContext context, final Object value); + + protected final String exportStringValue(final Object value) { + + if (value == null) + return StringUtils.EMPTY; + + if (!(value instanceof String)) + throw new IllegalStateException(); + + return (String) value; + } + + protected final double asDouble(final Object value) { + if (value == null) + return Double.NaN; + + if (!(value instanceof Number)) + throw new IllegalStateException(); + + final Number number = (Number) value; + return number.doubleValue(); + } + + protected final String exportDoubleValue(final CallContext context, final double value) { + if (Double.isNaN(value)) + return StringUtils.EMPTY; + + final NumberFormat formatter = getFormatter(context); + return formatter.format(value); + } + + private NumberFormat getFormatter(final CallContext context) { + final CallMeta meta = context.getMeta(); + final Locale locale = Resources.getLocale(meta); + + if (!this.formatters.containsKey(locale)) + this.formatters.put(locale, createFormatter(context)); + + return this.formatters.get(locale); + } + + protected abstract NumberFormat createFormatter(CallContext context); + + public final String getCsvHeader() { + return this.csvHeader; + } + + public final String getUnit() { + return this.unit; + } +} \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TauProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TauProcessor.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TauProcessor.java Wed Mar 14 14:10:32 2018 +0100 @@ -18,7 +18,7 @@ import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; -public final class TauProcessor extends AbstractSInfoLineProcessor> { +public final class TauProcessor extends AbstractSInfoLineProcessor { // FIXME: check: filtered or not? public static final String FACET_TKH_TAU_FILTERED = "sinfo_facet_tau.filtered"; @@ -40,16 +40,16 @@ } @Override - protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) { + protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) { if (FACET_TKH_TAU_FILTERED.contentEquals(facetName)) - return data.getTauPoints(); + return data.getStationPoints(SInfoResultType.tau); final String error = String.format("Unknown facet name: %s", facetName); throw new UnsupportedOperationException(error); } - public static Facet createTauFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, + public static Facet createTauFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, final int index) { final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_TAU_FILTERED_DESCRIPTION, I18N_FACET_TKH_TAU_FILTERED_DESCRIPTION, result.getLabel()); diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java Wed Mar 14 14:10:32 2018 +0100 @@ -49,7 +49,7 @@ final CallContext context = generator.getCallContext(); final String facetName = bundle.getFacetName(); - final AbstractTkhCalculationResult data = (AbstractTkhCalculationResult) bundle.getData(context); + final AbstractTkhCalculationResult data = (AbstractTkhCalculationResult) bundle.getData(context); if (data == null) { // Check has been here before so we keep it for security reasons // this should never happen though. @@ -75,7 +75,7 @@ return null; } - public static Facet createTkhFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, + public static Facet createTkhFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, final int index) { final String facetTkhDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_DESCRIPTION, I18N_FACET_TKH_DESCRIPTION, diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/VelocityProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/VelocityProcessor.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/VelocityProcessor.java Wed Mar 14 14:10:32 2018 +0100 @@ -18,7 +18,7 @@ import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; -public final class VelocityProcessor extends AbstractSInfoLineProcessor> { +public final class VelocityProcessor extends AbstractSInfoLineProcessor { // FIXME: check: filtered or not? public static final String FACET_TKH_VELOCITY_FILTERED = "sinfo_facet_velocity.filtered"; @@ -40,16 +40,16 @@ } @Override - protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) { + protected double[][] doGetPoints(final AbstractTkhCalculationResult data, final String facetName) { if (FACET_TKH_VELOCITY_FILTERED.contentEquals(facetName)) - return data.getVelocityPoints(); + return data.getStationPoints(SInfoResultType.velocity); final String error = String.format("Unknown facet name: %s", facetName); throw new UnsupportedOperationException(error); } - public static Facet createVelocityFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, + public static Facet createVelocityFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult result, final int index) { final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_VELOCITY_FILTERED_DESCRIPTION, I18N_FACET_TKH_VELOCITY_FILTERED_DESCRIPTION, result.getLabel()); diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Wed Mar 14 14:10:32 2018 +0100 @@ -12,6 +12,7 @@ import java.util.Collection; import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhCalculationResult; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; @@ -20,14 +21,14 @@ * * @author Gernot Belger */ -final class FlowDepthCalculationResult extends AbstractTkhCalculationResult { +final class FlowDepthCalculationResult extends AbstractTkhCalculationResult { private static final long serialVersionUID = 1L; private final BedHeightInfo sounding; public FlowDepthCalculationResult(final String label, final WstInfo wst, final BedHeightInfo sounding, final boolean hasTkh, - final Collection rows) { + final Collection rows) { super(label, wst, hasTkh, rows); this.sounding = sounding; diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java Wed Mar 14 14:10:32 2018 +0100 @@ -16,7 +16,7 @@ /** * @author Gernot Belger */ -final class FlowDepthCalculationResults extends AbstractSInfoCalculationResults { +final class FlowDepthCalculationResults extends AbstractSInfoCalculationResults { private static final long serialVersionUID = 1L; diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java Wed Mar 14 14:10:32 2018 +0100 @@ -14,7 +14,8 @@ import org.apache.commons.lang.math.DoubleRange; import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; -import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; @@ -24,7 +25,7 @@ */ final class FlowDepthCalculator { - private final Collection rows = new ArrayList<>(); + private final Collection rows = new ArrayList<>(); private final BedHeightsFinder bedHeight; @@ -63,14 +64,21 @@ private void calculateResultRow(final double station) { - final Tkh tkh = this.tkhCalculator.getTkh(station); + final SInfoResultRow row = SInfoResultRow.create(); + + row.putValue(SInfoResultType.waterlevelLabel, this.wstLabel); + row.putValue(SInfoResultType.soundingLabel, this.bedHeightLabel); + + // REMARK: access the gauge once only during calculation + final String gaugeLabel = this.riverInfoProvider.findGauge(station); + row.putValue(SInfoResultType.gaugeLabel, gaugeLabel); // REMARK: access the location once only during calculation final String location = this.riverInfoProvider.getLocation(station); + row.putValue(SInfoResultType.location, location); - // REMARK: access the gauge once only during calculation - final String gaugeLabel = this.riverInfoProvider.findGauge(station); + this.tkhCalculator.calculateTkh(station, row); - this.rows.add(new FlowDepthRow(tkh, this.wstLabel, gaugeLabel, this.bedHeightLabel, location)); + this.rows.add(row); } } \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java Wed Mar 14 14:10:32 2018 +0100 @@ -11,15 +11,14 @@ import java.util.ArrayList; import java.util.Collection; -import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings; import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; -import org.dive4elements.river.utils.RiverUtils; import au.com.bytecode.opencsv.CSVWriter; @@ -30,18 +29,12 @@ * @author Gernot Belger */ // REMARK: must be public because its registered in generators.xml -public class FlowDepthExporter extends AbstractSInfoExporter { +public class FlowDepthExporter extends AbstractSInfoExporter { /** The log used in this exporter. */ private static Logger log = Logger.getLogger(FlowDepthExporter.class); - private static final String CSV_FLOWDEPTHMINMAX_HEADER = "sinfo.export.flow_depth_minmax.csv.header.flowdepthminmax"; - - private static final String CSV_FLOWDEPTHTKHMINMAX_HEADER = "sinfo.export.flow_depth_minmax.csv.header.flowdepthTkh"; - - private static final String CSV_TKH_HEADER = "sinfo.export.flow_depth.csv.header.tkh"; - - private static final String JASPER_FILE = "/jasper/sinfo.flowdepthminmax.jasper"; + private static final String JASPER_FILE = "/jasper/sinfo.flowdepth.jasper"; @Override protected Logger getLog() { @@ -74,34 +67,34 @@ * @param river * @param useTkh */ - @Override protected void writeCSVHeader(final CSVWriter writer, final FlowDepthCalculationResults results, final RiverInfo river) { log.info("FlowDepthExporter.writeCSVHeader"); final Collection header = new ArrayList<>(11); - header.add(msg(SInfoI18NStrings.CSV_KM_HEADER)); - header.add(msgUnit(CSV_FLOWDEPTHMINMAX_HEADER, SInfoI18NStrings.UNIT_M)); - if (getData().isUseTkh()) { - header.add(msgUnit(CSV_FLOWDEPTHTKHMINMAX_HEADER, SInfoI18NStrings.UNIT_M)); - header.add(msgUnit(CSV_TKH_HEADER, SInfoI18NStrings.UNIT_CM)); + header.add(msg(SInfoResultType.station.getCsvHeader())); + header.add(msgUnit(SInfoResultType.flowdepth.getCsvHeader(), SInfoResultType.flowdepth.getUnit())); + + if (results.isUseTkh()) { + header.add(msgUnit(SInfoResultType.flowdepthtkh.getCsvHeader(), SInfoResultType.flowdepthtkh.getUnit())); + header.add(msgUnit(SInfoResultType.tkh.getCsvHeader(), SInfoResultType.tkh.getUnit())); } - header.add(msgUnit(SInfoI18NStrings.CSV_WATERLEVEL_HEADER, river.getWstUnit())); - header.add(msgUnit(SInfoI18NStrings.CSV_DISCHARGE_HEADER, SInfoI18NStrings.UNIT_CUBIC_M)); - header.add(msg(SInfoI18NStrings.CSV_LABEL_HEADER)); - header.add(msg(SInfoI18NStrings.CSV_GAUGE_HEADER)); - header.add(msgUnit(SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_HEADER, river.getWstUnit())); - header.add(msg(SInfoI18NStrings.CSV_SOUNDING_HEADER)); - header.add(msg(SInfoI18NStrings.CSV_LOCATION_HEADER)); + header.add(msgUnit(SInfoResultType.waterlevel.getCsvHeader(), river.getWstUnit())); + header.add(msgUnit(SInfoResultType.discharge.getCsvHeader(), SInfoResultType.discharge.getUnit())); + header.add(msg(SInfoResultType.waterlevelLabel.getCsvHeader())); + header.add(msg(SInfoResultType.gaugeLabel.getCsvHeader())); + header.add(msgUnit(SInfoResultType.meanBedHeight.getCsvHeader(), river.getWstUnit())); + header.add(msg(SInfoResultType.soundingLabel.getCsvHeader())); + header.add(msg(SInfoResultType.location.getCsvHeader())); writer.writeNext(header.toArray(new String[header.size()])); } @Override - protected String[] formatCSVRow(final FlowDepthCalculationResults results, final FlowDepthRow row) { - return formatFlowDepthRow(row); + protected String[] formatCSVRow(final FlowDepthCalculationResults results, final FlowDepthCalculationResult result, final SInfoResultRow row) { + return formatRow(row); } /** @@ -109,50 +102,25 @@ * * @param useTkh */ - private String[] formatFlowDepthRow(final FlowDepthRow row) { + private String[] formatRow(final SInfoResultRow row) { final Collection lines = new ArrayList<>(11); - // Fluss-km - lines.add(getKmFormatter().format(row.getStation())); - - // Fließtiefe [m] - lines.add(getFlowDepthFormatter().format(row.getFlowDepth())); + lines.add(row.exportValue(this.context, SInfoResultType.station)); + lines.add(row.exportValue(this.context, SInfoResultType.flowdepth)); if (getData().isUseTkh()) { - // Fließtiefe mit TKH [m] - lines.add(getFlowDepthFormatter().format(row.getFlowDepthWithTkh())); - - // TKH [cm] - lines.add(getTkhFormatter().format(row.getTkh())); + lines.add(row.exportValue(this.context, SInfoResultType.flowdepthtkh)); + lines.add(row.exportValue(this.context, SInfoResultType.tkh)); } - // Wasserstand [NN + m] - lines.add(getW2Formatter().format(row.getWaterlevel())); - - // Q [m³/s] - final double discharge = row.getDischarge(); - if (Double.isNaN(discharge)) - lines.add(StringUtils.EMPTY); - else { - final double roundedDischarge = RiverUtils.roundQ(discharge); - lines.add(getQFormatter().format(roundedDischarge)); - } - - // Bezeichnung - lines.add(row.getWaterlevelLabel()); - - // Bezugspegel - lines.add(row.getGauge()); - - // Mittlere Sohlhöhe [NN + m] - lines.add(getMeanBedHeighFormatter().format(row.getMeanBedHeight())); - - // Peilung/Epoche - lines.add(row.getSoundageLabel()); - - // Lage - lines.add(row.getLocation()); + lines.add(row.exportValue(this.context, SInfoResultType.waterlevel)); + lines.add(row.exportValue(this.context, SInfoResultType.discharge)); + lines.add(row.exportValue(this.context, SInfoResultType.waterlevelLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.gaugeLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.meanBedHeight)); + lines.add(row.exportValue(this.context, SInfoResultType.soundingLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.location)); return lines.toArray(new String[lines.size()]); } @@ -169,21 +137,22 @@ super.addJRMetaDataDefaults(source, results); /* column headings */ - source.addMetaData("station_header", msg(SInfoI18NStrings.CSV_KM_HEADER)); - source.addMetaData("flowdepth_header", msg(CSV_FLOWDEPTHMINMAX_HEADER)); - source.addMetaData("flowdepth_tkh_header", msg(CSV_FLOWDEPTHTKHMINMAX_HEADER)); - source.addMetaData("tkh_header", msg(CSV_TKH_HEADER)); - source.addMetaData("waterlevel_header", msg(SInfoI18NStrings.CSV_WATERLEVEL_HEADER)); - source.addMetaData("discharge_header", msg(SInfoI18NStrings.CSV_DISCHARGE_HEADER)); - source.addMetaData("waterlevel_name_header", msg(SInfoI18NStrings.CSV_LABEL_HEADER)); - source.addMetaData("gauge_header", msg(SInfoI18NStrings.CSV_GAUGE_HEADER)); - source.addMetaData("bedheight_header", msg(SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_HEADER_SHORT)); - source.addMetaData("sounding_name_header", msg(SInfoI18NStrings.CSV_SOUNDING_HEADER)); - source.addMetaData("location_header", msg(SInfoI18NStrings.CSV_LOCATION_HEADER)); + + source.addMetaData("station_header", msg(SInfoResultType.station.getCsvHeader())); + source.addMetaData("flowdepth_header", msg(SInfoResultType.flowdepth.getCsvHeader())); + source.addMetaData("flowdepth_tkh_header", msg(SInfoResultType.flowdepthtkh.getCsvHeader())); + source.addMetaData("tkh_header", msg(SInfoResultType.tkh.getCsvHeader())); + source.addMetaData("waterlevel_header", msg(SInfoResultType.waterlevel.getCsvHeader())); + source.addMetaData("discharge_header", msg(SInfoResultType.discharge.getCsvHeader())); + source.addMetaData("waterlevel_name_header", msg(SInfoResultType.waterlevelLabel.getCsvHeader())); + source.addMetaData("gauge_header", msg(SInfoResultType.gaugeLabel.getCsvHeader())); + source.addMetaData("bedheight_header", msg(SInfoResultType.meanBedHeight.getCsvHeader())); + source.addMetaData("sounding_name_header", msg(SInfoResultType.soundingLabel.getCsvHeader())); + source.addMetaData("location_header", msg(SInfoResultType.location.getCsvHeader())); } @Override - protected String[] formatPDFRow(final FlowDepthCalculationResults results, final FlowDepthRow row) { - return formatFlowDepthRow(row); + protected String[] formatPDFRow(final FlowDepthCalculationResults results, final SInfoResultRow row) { + return formatRow(row); } } \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthRow.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthRow.java Wed Mar 14 14:09:33 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* 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.flowdepth; - -import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhResultRow; -import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh; - -/** - * Part of {@link FlowDepthCalculationResult} which represents one calculated row of flow depth data. - * - * @author Gernot Belger - */ -final class FlowDepthRow extends AbstractTkhResultRow { - private static final long serialVersionUID = 1L; - - private final String soundingLabel; - - public FlowDepthRow(final Tkh tkh, final String waterlevelLabel, - final String gauge, final String soundingLabel, final String location) { - - super(tkh, waterlevelLabel, gauge, location); - - this.soundingLabel = soundingLabel; - } - - public String getSoundageLabel() { - return this.soundingLabel; - } -} \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java Wed Mar 14 14:10:32 2018 +0100 @@ -20,6 +20,8 @@ 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.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthUtils; import org.dive4elements.river.artifacts.sinfo.flowdepthminmax.FlowDepthMinMaxAccess.MinMaxIdPair; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder; @@ -86,7 +88,7 @@ /* access real input data from database */ final String wstId = minMaxPair.getWstId(); final String minSoundingId = minMaxPair.getMinSoundingId(); - final String maxSoundingId = minMaxPair.getMinSoundingId(); + final String maxSoundingId = minMaxPair.getMaxSoundingId(); final BedHeightsFinder minBedHeight = minSoundingId == null ? null : BedHeightsFinder.forId(this.context, minSoundingId, calcRange, problems); final BedHeightsFinder maxBedHeight = maxSoundingId == null ? null : BedHeightsFinder.forId(this.context, maxSoundingId, calcRange, problems); @@ -121,7 +123,7 @@ final String soundingLabel = buildSoundingLabel(minBedHeight, maxBedHeight); /* real calculation loop */ - final Collection rows = new ArrayList<>(); + final Collection rows = new ArrayList<>(); // FIXME: determine what is the spatial discretisation that we will use... final double[] allKms = wstKms.allKms().toNativeArray(); @@ -146,13 +148,24 @@ // REMARK: access the gauge once only during calculation final String gaugeLabel = riverInfoProvider.findGauge(station); - rows.add(new FlowDepthMinMaxRow(station, minFlowDepth, maxFlowDepth, wst, discharge, waterlevelLabel, gaugeLabel, meanBedHeight, soundingLabel, - location)); + final SInfoResultRow row = SInfoResultRow.create().// + putValue(SInfoResultType.station, station). // + putValue(SInfoResultType.flowdepthmin, minFlowDepth). // + putValue(SInfoResultType.flowdepthmax, maxFlowDepth). // + putValue(SInfoResultType.waterlevel, wst). // + putValue(SInfoResultType.discharge, discharge). // + putValue(SInfoResultType.waterlevelLabel, waterlevelLabel). // + putValue(SInfoResultType.gaugeLabel, gaugeLabel). // + putValue(SInfoResultType.meanBedHeight, meanBedHeight). // + putValue(SInfoResultType.soundingLabel, soundingLabel). // + putValue(SInfoResultType.location, location); + rows.add(row); } } final BedHeightInfo minBedHeightInfo = minBedHeight == null ? null : minBedHeight.getInfo(); final BedHeightInfo maxBedHeightInfo = maxBedHeight == null ? null : maxBedHeight.getInfo(); + return new FlowDepthMinMaxCalculationResult(label, wstInfo, minBedHeightInfo, maxBedHeightInfo, rows); } diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResult.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResult.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResult.java Wed Mar 14 14:10:32 2018 +0100 @@ -12,6 +12,7 @@ import java.util.Collection; import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResult; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; @@ -20,7 +21,7 @@ * * @author Gernot Belger */ -final class FlowDepthMinMaxCalculationResult extends AbstractSInfoCalculationResult { +final class FlowDepthMinMaxCalculationResult extends AbstractSInfoCalculationResult { private static final long serialVersionUID = 1L; @@ -29,7 +30,7 @@ private final BedHeightInfo maxSounding; public FlowDepthMinMaxCalculationResult(final String label, final WstInfo wst, final BedHeightInfo minSounding, final BedHeightInfo maxSounding, - final Collection rows) { + final Collection rows) { super(label, wst, rows); this.minSounding = minSounding; diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResults.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResults.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResults.java Wed Mar 14 14:10:32 2018 +0100 @@ -16,7 +16,7 @@ /** * @author Gernot Belger */ -final class FlowDepthMinMaxCalculationResults extends AbstractSInfoCalculationResults { +final class FlowDepthMinMaxCalculationResults extends AbstractSInfoCalculationResults { private static final long serialVersionUID = 1L; diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxExporter.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxExporter.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxExporter.java Wed Mar 14 14:10:32 2018 +0100 @@ -11,15 +11,14 @@ import java.util.ArrayList; import java.util.Collection; -import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings; import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; -import org.dive4elements.river.utils.RiverUtils; import au.com.bytecode.opencsv.CSVWriter; @@ -30,16 +29,12 @@ * @author Gernot Belger */ // REMARK: must be public because its registered in generators.xml -public class FlowDepthMinMaxExporter extends AbstractSInfoExporter { +public class FlowDepthMinMaxExporter extends AbstractSInfoExporter { /** The log used in this exporter. */ private static Logger log = Logger.getLogger(FlowDepthMinMaxExporter.class); - private static final String CSV_FLOWDEPTH_MIN_HEADER = "sinfo.export.flow_depth_minmax.csv.header.min"; - - private static final String CSV_FLOWDEPTH_MAX_HEADER = "sinfo.export.flow_depth_minmax.csv.header.max"; - - private static final String JASPER_FILE = "/jasper/sinfo.flowdepth.jasper"; + private static final String JASPER_FILE = "/jasper/sinfo.flowdepthminmax.jasper"; @Override protected Logger getLog() { @@ -78,72 +73,53 @@ final Collection header = new ArrayList<>(11); - header.add(msg(SInfoI18NStrings.CSV_KM_HEADER)); - - header.add(msgUnit(CSV_FLOWDEPTH_MIN_HEADER, SInfoI18NStrings.UNIT_M)); - header.add(msgUnit(CSV_FLOWDEPTH_MAX_HEADER, SInfoI18NStrings.UNIT_M)); - - header.add(msgUnit(SInfoI18NStrings.CSV_WATERLEVEL_HEADER, river.getWstUnit())); - header.add(msgUnit(SInfoI18NStrings.CSV_DISCHARGE_HEADER, SInfoI18NStrings.UNIT_CUBIC_M)); - header.add(msg(SInfoI18NStrings.CSV_LABEL_HEADER)); - header.add(msg(SInfoI18NStrings.CSV_GAUGE_HEADER)); - header.add(msgUnit(SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_HEADER, river.getWstUnit())); - header.add(msg(SInfoI18NStrings.CSV_SOUNDING_HEADER)); - header.add(msg(SInfoI18NStrings.CSV_LOCATION_HEADER)); + header.add(msg(SInfoResultType.station.getCsvHeader())); + header.add(msgUnit(SInfoResultType.flowdepthmin.getCsvHeader(), SInfoResultType.flowdepthmin.getUnit())); + header.add(msgUnit(SInfoResultType.flowdepthmax.getCsvHeader(), SInfoResultType.flowdepthmax.getUnit())); + header.add(msgUnit(SInfoResultType.waterlevel.getCsvHeader(), river.getWstUnit())); + header.add(msgUnit(SInfoResultType.discharge.getCsvHeader(), SInfoResultType.discharge.getUnit())); + header.add(msg(SInfoResultType.waterlevelLabel.getCsvHeader())); + header.add(msg(SInfoResultType.gaugeLabel.getCsvHeader())); + header.add(msgUnit(SInfoResultType.meanBedHeight.getCsvHeader(), river.getWstUnit())); + header.add(msg(SInfoResultType.soundingLabel.getCsvHeader())); + header.add(msg(SInfoResultType.location.getCsvHeader())); writer.writeNext(header.toArray(new String[header.size()])); } @Override - protected String[] formatCSVRow(final FlowDepthMinMaxCalculationResults results, final FlowDepthMinMaxRow row) { - return formatFlowDepthRow(row); + protected String[] formatCSVRow(final FlowDepthMinMaxCalculationResults results, final FlowDepthMinMaxCalculationResult result, final SInfoResultRow row) { + return formatRow(result, row); } /** * Format a row of a flow depth result into an array of string, both used by csv and pdf * + * @param result + * * @param useTkh */ - private String[] formatFlowDepthRow(final FlowDepthMinMaxRow row) { - - final Collection lines = new ArrayList<>(11); - - // Fluss-km - lines.add(getKmFormatter().format(row.getStation())); - - // FIXME: spalten weglassen, wenn min oder max fehlt - - // Minimale Fließtiefe [m] - lines.add(getFlowDepthFormatter().format(row.getMinFlowDepth())); - // Maximale Fließtiefe [m] - lines.add(getFlowDepthFormatter().format(row.getMaxFlowDepth())); - - // Wasserstand [NN + m] - lines.add(getW2Formatter().format(row.getWaterlevel())); + private String[] formatRow(final FlowDepthMinMaxCalculationResult result, final SInfoResultRow row) { - // Q [m³/s] - final double discharge = row.getDischarge(); - if (Double.isNaN(discharge)) - lines.add(StringUtils.EMPTY); - else { - final double roundedDischarge = RiverUtils.roundQ(discharge); - lines.add(getQFormatter().format(roundedDischarge)); - } + final Collection lines = new ArrayList<>(10); - // Bezeichnung - lines.add(row.getWaterlevelLabel()); - - // Bezugspegel - lines.add(row.getGauge()); + lines.add(row.exportValue(this.context, SInfoResultType.station)); - // Mittlere Sohlhöhe [NN + m] - lines.add(getMeanBedHeighFormatter().format(row.getMeanBedHeight())); + // REMARK: null check as pdf will call this with null and in that case we show all columns (to avoid multiple jasper + // FIXME: does not work like this: we may have several pairs of min/max; so we need to look at all of them? + // templates) + // if (result == null || result.getMinSounding() != null) + lines.add(row.exportValue(this.context, SInfoResultType.flowdepthmin)); + // if (result == null || result.getMaxSounding() != null) + lines.add(row.exportValue(this.context, SInfoResultType.flowdepthmax)); - // Peilung/Epoche - lines.add(row.getSoundageLabel()); - - // Lage - lines.add(row.getLocation()); + lines.add(row.exportValue(this.context, SInfoResultType.waterlevel)); + lines.add(row.exportValue(this.context, SInfoResultType.discharge)); + lines.add(row.exportValue(this.context, SInfoResultType.waterlevelLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.gaugeLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.meanBedHeight)); + lines.add(row.exportValue(this.context, SInfoResultType.soundingLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.location)); return lines.toArray(new String[lines.size()]); } @@ -160,20 +136,20 @@ super.addJRMetaDataDefaults(source, results); /* column headings */ - source.addMetaData("station_header", msg(SInfoI18NStrings.CSV_KM_HEADER)); - source.addMetaData("flowdepthmin_header", msg(CSV_FLOWDEPTH_MIN_HEADER)); - source.addMetaData("flowdepthmax_header", msg(CSV_FLOWDEPTH_MAX_HEADER)); - source.addMetaData("waterlevel_header", msg(SInfoI18NStrings.CSV_WATERLEVEL_HEADER)); - source.addMetaData("discharge_header", msg(SInfoI18NStrings.CSV_DISCHARGE_HEADER)); - source.addMetaData("waterlevel_name_header", msg(SInfoI18NStrings.CSV_LABEL_HEADER)); - source.addMetaData("gauge_header", msg(SInfoI18NStrings.CSV_GAUGE_HEADER)); - source.addMetaData("bedheight_header", msg(SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_HEADER_SHORT)); - source.addMetaData("sounding_name_header", msg(SInfoI18NStrings.CSV_SOUNDING_HEADER)); - source.addMetaData("location_header", msg(SInfoI18NStrings.CSV_LOCATION_HEADER)); + source.addMetaData("station_header", msg(SInfoResultType.station.getCsvHeader())); + source.addMetaData("flowdepthmin_header", msg(SInfoResultType.flowdepthmin.getCsvHeader())); + source.addMetaData("flowdepthmax_header", msg(SInfoResultType.flowdepthmax.getCsvHeader())); + source.addMetaData("waterlevel_header", msg(SInfoResultType.waterlevel.getCsvHeader())); + source.addMetaData("discharge_header", msg(SInfoResultType.discharge.getCsvHeader())); + source.addMetaData("waterlevel_name_header", msg(SInfoResultType.waterlevelLabel.getCsvHeader())); + source.addMetaData("gauge_header", msg(SInfoResultType.gaugeLabel.getCsvHeader())); + source.addMetaData("bedheight_header", msg(SInfoResultType.meanBedHeight.getCsvHeader())); + source.addMetaData("sounding_name_header", msg(SInfoResultType.soundingLabel.getCsvHeader())); + source.addMetaData("location_header", msg(SInfoResultType.location.getCsvHeader())); } @Override - protected String[] formatPDFRow(final FlowDepthMinMaxCalculationResults results, final FlowDepthMinMaxRow row) { - return formatFlowDepthRow(row); + protected String[] formatPDFRow(final FlowDepthMinMaxCalculationResults results, final SInfoResultRow row) { + return formatRow(null, row); } } \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxRow.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxRow.java Wed Mar 14 14:09:33 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* 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.flowdepthminmax; - -import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoResultRow; - -/** - * Part of {@link FlowDepthMinMaxCalculationResult} which represents one calculated row of flow depth data. - * - * @author Gernot Belger - */ -final class FlowDepthMinMaxRow extends AbstractSInfoResultRow { - private static final long serialVersionUID = 1L; - - private final double station; - - private final double minFlowDepth; - - private final double maxFlowDepth; - - private final double waterlevel; - - private final double discharge; - - private final double meanBedHeight; - - private final String soundingLabel; - - public FlowDepthMinMaxRow(final double station, final double minFlowDepth, final double maxFlowDepth, final double waterlevel, final double discharge, - final String waterlevelLabel, final String gauge, final double meanBedHeight, final String soundingLabel, final String location) { - - super(waterlevelLabel, gauge, location); - - this.station = station; - this.minFlowDepth = minFlowDepth; - this.maxFlowDepth = maxFlowDepth; - this.waterlevel = waterlevel; - this.discharge = discharge; - this.meanBedHeight = meanBedHeight; - this.soundingLabel = soundingLabel; - } - - public String getSoundageLabel() { - return this.soundingLabel; - } - - public double getStation() { - return this.station; - } - - public double getMinFlowDepth() { - return this.minFlowDepth; - } - - public double getMaxFlowDepth() { - return this.maxFlowDepth; - } - - public double getWaterlevel() { - return this.waterlevel; - } - - public double getDischarge() { - return this.discharge; - } - - public double getMeanBedHeight() { - return this.meanBedHeight; - } - - public String getSoundingLabel() { - return this.soundingLabel; - } -} \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java Wed Mar 14 14:10:32 2018 +0100 @@ -14,6 +14,8 @@ import org.dive4elements.artifacts.CallContext; import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; import org.dive4elements.river.model.River; @@ -144,57 +146,67 @@ } } - public Tkh getTkh(final double km) { + public void calculateTkh(final double km, final SInfoResultRow row) { + + row.putValue(SInfoResultType.station, km); final SoilKind kind = getSoilKind(km); + row.putValue(SInfoResultType.soilkind, kind); final double wst = this.waterlevelProvider.getWaterlevel(km); + row.putValue(SInfoResultType.waterlevel, wst); final double meanBedHeight = this.bedHeightsProvider.getMeanBedHeight(km); + row.putValue(SInfoResultType.meanBedHeight, meanBedHeight); final double flowDepth = wst - meanBedHeight; + row.putValue(SInfoResultType.flowdepth, flowDepth); final double discharge = this.dischargeProvider.getDischarge(km); + row.putValue(SInfoResultType.discharge, discharge); if (Double.isNaN(discharge)) - return new Tkh(km, wst, meanBedHeight, flowDepth, Double.NaN, kind); + return; if (!this.hasTkh()) - return new Tkh(km, wst, meanBedHeight, flowDepth, Double.NaN, kind); + return; final double d50 = getBedMeasurement(km); if (Double.isNaN(d50)) - return new Tkh(km, wst, meanBedHeight, flowDepth, discharge, kind); + return; + row.putValue(SInfoResultType.d50, d50); if (!this.flowVelocitiesFinder.findKmQValues(km, discharge)) { // TODO: ggf. station in Fehlermeldung? final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingVelocity", null, this.problemLabel); this.problems.addProblem(km, message); // FIXME: cumulate problems to one message? - return new Tkh(km, wst, meanBedHeight, flowDepth, discharge, kind); + return; } final double velocity = this.flowVelocitiesFinder.getFindVmainFound(); + row.putValue(SInfoResultType.velocity, velocity); + final double tau = this.flowVelocitiesFinder.getFindTauFound(); + row.putValue(SInfoResultType.tau, tau); final double tkh = calculateTkh(wst - meanBedHeight, velocity, d50, tau); - double tkhUp; - double tkhDown; + row.putValue(SInfoResultType.tkh, tkh); + switch (kind) { case starr: - tkhUp = tkh; - tkhDown = 0; + row.putValue(SInfoResultType.tkhup, tkh); + row.putValue(SInfoResultType.tkhdown, 0.0); break; case mobil: default: - tkhUp = tkh / 2; - tkhDown = -tkh / 2; + row.putValue(SInfoResultType.tkhup, tkh / 2); + row.putValue(SInfoResultType.tkhdown, -tkh / 2); break; } - final double flowDepthTkh = calculateFlowDepthTkh(tkhUp, kind, wst, meanBedHeight); - - return new Tkh(km, wst, meanBedHeight, flowDepth, flowDepthTkh, discharge, kind, tkh, tkhUp, tkhDown, velocity, d50, tau); + final double flowDepthTkh = calculateFlowDepthTkh(tkh, kind, wst, meanBedHeight); + row.putValue(SInfoResultType.flowdepthtkh, flowDepthTkh); } /** diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java Wed Mar 14 14:10:32 2018 +0100 @@ -28,8 +28,9 @@ 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.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder; -import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder; import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; @@ -134,7 +135,7 @@ return null; } - final Collection rows = new ArrayList<>(); + final Collection rows = new ArrayList<>(); /* using wst-kms as basis, because we know that they are generated wst's with a fixed km-step */ // FIXME: das führt dazu, das aktuell die Sohlhöhen beliebig linear interpolierrt werden. ist das immer richtig? z.b. @@ -150,13 +151,15 @@ if (tkhCalculator == null) continue; - final Tkh tkh = tkhCalculator.getTkh(station); + final SInfoResultRow row = SInfoResultRow.create(); - final String description = descBuilder.getDesc(wkms); - final String gaugeLabel = riverInfoProvider.findGauge(station); - final String location = riverInfoProvider.getLocation(station); + row.putValue(SInfoResultType.waterlevelLabel, descBuilder.getDesc(wkms)); + row.putValue(SInfoResultType.gaugeLabel, riverInfoProvider.findGauge(station)); + row.putValue(SInfoResultType.location, riverInfoProvider.getLocation(station)); - rows.add(new TkhResultRow(tkh, description, gaugeLabel, location)); + tkhCalculator.calculateTkh(station, row); + + rows.add(row); } return new TkhCalculationResult(wstLabel, wstInfo, true, rows); diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResult.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResult.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResult.java Wed Mar 14 14:10:32 2018 +0100 @@ -12,6 +12,7 @@ import java.util.Collection; import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhCalculationResult; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; /** @@ -19,11 +20,11 @@ * * @author Gernot Belger */ -final class TkhCalculationResult extends AbstractTkhCalculationResult { +final class TkhCalculationResult extends AbstractTkhCalculationResult { private static final long serialVersionUID = 1L; - public TkhCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection rows) { + public TkhCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection rows) { super(label, wst, hasTkh, rows); } } \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResults.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResults.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResults.java Wed Mar 14 14:10:32 2018 +0100 @@ -16,7 +16,7 @@ /** * @author Gernot Belger */ -final class TkhCalculationResults extends AbstractSInfoCalculationResults { +final class TkhCalculationResults extends AbstractSInfoCalculationResults { private static final long serialVersionUID = 1L; diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhExporter.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhExporter.java Wed Mar 14 14:09:33 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhExporter.java Wed Mar 14 14:10:32 2018 +0100 @@ -12,12 +12,12 @@ import java.util.Collection; import org.apache.log4j.Logger; -import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings; import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; -import org.dive4elements.river.utils.RiverUtils; import au.com.bytecode.opencsv.CSVWriter; @@ -27,7 +27,7 @@ * @author Gernot Belger */ // REMARK: must be public because its registered in generators.xml -public class TkhExporter extends AbstractSInfoExporter { +public class TkhExporter extends AbstractSInfoExporter { private static enum ExportMode { pdf, csv @@ -38,12 +38,7 @@ private static final String CSV_META_CALCULATION_FORMULA = "sinfo.export.tkh.calculation.formula"; - private static final String CSV_TKH_HEADER = "sinfo.export.tkh.csv.header.tkh"; - - private static final String CSV_TKHKIND_HEADER = "sinfo.export.tkh.csv.header.tkhkind"; - - private static final String PREFIX_TKH_KIND = "sinfo.export.tkh.soilkind."; - + // FIXME: use pgetPdfHeader instead of getCsvHeader private static final String CSV_MEAN_BED_HEIGHT_HEADER_SHORT = "sinfo.export.flow_depth.csv.header.mean_bed_height.short"; private static final String JASPER_FILE = "/jasper/sinfo.flowdepth.jasper"; @@ -75,20 +70,19 @@ final Collection header = new ArrayList<>(11); - header.add(msg(SInfoI18NStrings.CSV_KM_HEADER)); - header.add(msgUnit(CSV_TKH_HEADER, SInfoI18NStrings.UNIT_CM)); - header.add(msg(CSV_TKHKIND_HEADER)); - header.add(msgUnit(SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_HEADER, river.getWstUnit())); - - header.add(msgUnit(SInfoI18NStrings.CSV_WATERLEVEL_HEADER, river.getWstUnit())); - header.add(msgUnit(SInfoI18NStrings.CSV_DISCHARGE_HEADER, SInfoI18NStrings.UNIT_CUBIC_M)); + header.add(msg(SInfoResultType.station.getCsvHeader())); + header.add(msgUnit(SInfoResultType.tkh.getCsvHeader(), SInfoResultType.tkh.getUnit())); + header.add(msg(SInfoResultType.soilkind.getCsvHeader())); + header.add(msgUnit(SInfoResultType.meanBedHeight.getCsvHeader(), river.getWstUnit())); + header.add(msgUnit(SInfoResultType.waterlevel.getCsvHeader(), river.getWstUnit())); + header.add(msgUnit(SInfoResultType.discharge.getCsvHeader(), SInfoResultType.discharge.getUnit())); final String descriptionHeader = results.getDescriptionHeader(); if (descriptionHeader != null) header.add(msg(descriptionHeader)); - header.add(msg(SInfoI18NStrings.CSV_GAUGE_HEADER)); - header.add(msg(SInfoI18NStrings.CSV_LOCATION_HEADER)); + header.add(msg(SInfoResultType.gaugeLabel.getCsvHeader())); + header.add(msg(SInfoResultType.location.getCsvHeader())); writer.writeNext(header.toArray(new String[header.size()])); } @@ -100,13 +94,13 @@ final WstInfo wst = result.getWst(); super.writeCSVWaterlevelMetadata(writer, wst); - // TODO: + // FIXME: // "# W/Pegel [cm]: " (nur bei Eingabe des Wasserstands am Pegel) // "# Q (m³/s): " (nur bei Eingabe des Durchflusses) } @Override - protected String[] formatCSVRow(final TkhCalculationResults results, final TkhResultRow row) { + protected String[] formatCSVRow(final TkhCalculationResults results, final TkhCalculationResult result, final SInfoResultRow row) { return formatRow(results, row, ExportMode.csv); } @@ -117,40 +111,23 @@ * * @param useTkh */ - private String[] formatRow(final TkhCalculationResults results, final TkhResultRow row, final ExportMode mode) { + private String[] formatRow(final TkhCalculationResults results, final SInfoResultRow row, final ExportMode mode) { final Collection lines = new ArrayList<>(11); - // Fluss-km - lines.add(getKmFormatter().format(row.getStation())); - - // TKH [cm] - lines.add(getTkhFormatter().format(row.getTkh())); - - // Einteilung der Gewässersohle (starr/mobil) - lines.add(msg(PREFIX_TKH_KIND + row.getTkhKind().name())); + lines.add(row.exportValue(this.context, SInfoResultType.station)); + lines.add(row.exportValue(this.context, SInfoResultType.tkh)); + lines.add(row.exportValue(this.context, SInfoResultType.soilkind)); + lines.add(row.exportValue(this.context, SInfoResultType.meanBedHeight)); + lines.add(row.exportValue(this.context, SInfoResultType.waterlevel)); + lines.add(row.exportValue(this.context, SInfoResultType.discharge)); - // Mittlere Sohlhöhe [NN + m] - lines.add(getMeanBedHeighFormatter().format(row.getMeanBedHeight())); - - // Wasserstand [NN + m] - lines.add(getW2Formatter().format(row.getWaterlevel())); - - // Q [m³/s] - final double discharge = row.getDischarge(); - final double roundedDischarge = RiverUtils.roundQ(discharge); - lines.add(getQFormatter().format(roundedDischarge)); - - // Bezeichnung // REMARK: always export this column in pdf-mode, because WInfo also does it (no need for two jasper-templates). if (results.getDescriptionHeader() != null || mode == ExportMode.pdf) - lines.add(row.getWaterlevelLabel()); + lines.add(row.exportValue(this.context, SInfoResultType.waterlevelLabel)); - // Bezugspegel - lines.add(row.getGauge()); - - // Lage - lines.add(row.getLocation()); + lines.add(row.exportValue(this.context, SInfoResultType.gaugeLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.location)); return lines.toArray(new String[lines.size()]); } @@ -167,24 +144,24 @@ super.addJRMetaDataDefaults(source, results); /* column headings */ - source.addMetaData("station_header", msg(SInfoI18NStrings.CSV_KM_HEADER)); - source.addMetaData("tkh_header", msg(CSV_TKH_HEADER)); - source.addMetaData("bedheight_header", msg(CSV_MEAN_BED_HEIGHT_HEADER_SHORT)); - source.addMetaData("waterlevel_header", msg(SInfoI18NStrings.CSV_WATERLEVEL_HEADER)); - source.addMetaData("discharge_header", msg(SInfoI18NStrings.CSV_DISCHARGE_HEADER)); + source.addMetaData("station_header", msg( SInfoResultType.station.getCsvHeader())); + source.addMetaData("tkh_header", msg(SInfoResultType.tkh.getCsvHeader())); + source.addMetaData("bedheight_header", msg(SInfoResultType.meanBedHeight.getCsvHeader())); + source.addMetaData("waterlevel_header", msg(SInfoResultType.waterlevel.getCsvHeader())); + source.addMetaData("discharge_header", msg(SInfoResultType.discharge.getCsvHeader())); // REMARK: actually the column makes no sense if description header is null. But (software symmetry...) WINFO also // writes an empty column into the pdf in that case (most probably to avoid the need for two jasper templates). final String descriptionHeader = results.getDescriptionHeader(); - final String waterlevelNameHeader = descriptionHeader == null ? msg(SInfoI18NStrings.CSV_LABEL_HEADER) : descriptionHeader; + final String waterlevelNameHeader = descriptionHeader == null ? msg(SInfoResultType.waterlevelLabel.getCsvHeader()) : descriptionHeader; source.addMetaData("waterlevel_name_header", waterlevelNameHeader); - source.addMetaData("gauge_header", msg(SInfoI18NStrings.CSV_GAUGE_HEADER)); - source.addMetaData("location_header", msg(SInfoI18NStrings.CSV_LOCATION_HEADER)); + source.addMetaData("gauge_header", msg(SInfoResultType.gaugeLabel.getCsvHeader())); + source.addMetaData("location_header", msg(SInfoResultType.location.getCsvHeader())); } @Override - protected String[] formatPDFRow(final TkhCalculationResults results, final TkhResultRow row) { + protected String[] formatPDFRow(final TkhCalculationResults results, final SInfoResultRow row) { return formatRow(results, row, ExportMode.pdf); } } \ No newline at end of file diff -r 86650594f051 -r a4f1ac81f26d artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhResultRow.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhResultRow.java Wed Mar 14 14:09:33 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/** 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.tkhstate; - -import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhResultRow; -import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh; - -/** - * @author Gernot Belger - */ -final class TkhResultRow extends AbstractTkhResultRow { - - private static final long serialVersionUID = 1L; - - public TkhResultRow(final Tkh tkh, final String waterlevelLabel, final String gauge, final String location) { - super(tkh, waterlevelLabel, gauge, location); - } -} \ No newline at end of file