# HG changeset patch
# User gernotbelger
# Date 1520963373 -3600
# Node ID 5d5d482da3e93adf17b535e3a3397c5babaec4af
# Parent 4a6b6a3c279cdd5e02ef29908c3092fb2cce6a33
Implementing SINFO - FlowDepthMinMax calculation
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/doc/conf/artifacts/sinfo.xml
--- a/artifacts/doc/conf/artifacts/sinfo.xml Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/doc/conf/artifacts/sinfo.xml Tue Mar 13 18:49:33 2018 +0100
@@ -83,6 +83,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/doc/conf/generators/generators.xml
--- a/artifacts/doc/conf/generators/generators.xml Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/doc/conf/generators/generators.xml Tue Mar 13 18:49:33 2018 +0100
@@ -62,6 +62,8 @@
+
+
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SINFOArtifact.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SINFOArtifact.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SINFOArtifact.java Tue Mar 13 18:49:33 2018 +0100
@@ -1,6 +1,6 @@
/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- * Björnsen Beratende Ingenieure GmbH
+ * 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)
@@ -17,26 +17,26 @@
*
* @author Gernot Belger
*/
-public class SINFOArtifact
-extends D4EArtifact
-{
+public class SINFOArtifact extends D4EArtifact {
+
+ private static final long serialVersionUID = 1L;
+
/** Error message that is thrown if no mode has been chosen. */
- private static final String ERROR_NO_CALCULATION_MODE =
- "error_feed_no_calculation_mode";
+ private static final String ERROR_NO_CALCULATION_MODE = "error_feed_no_calculation_mode";
- /** Error message that is thrown if an invalid calculation mode has been
- * chosen. */
- private static final String ERROR_INVALID_CALCULATION_MODE =
- "error_feed_invalid_calculation_mode";
+ /**
+ * Error message that is thrown if an invalid calculation mode has been
+ * chosen.
+ */
+ private static final String ERROR_INVALID_CALCULATION_MODE = "error_feed_invalid_calculation_mode";
-
/** The name of the artifact. */
private static final String ARTIFACT_NAME = "sinfo";
private static final String FIELD_RIVER = "river";
private static final String FIELD_MODE = "calculation_mode";
-
+
/**
* Default constructor, because it's serializable.
*/
@@ -52,22 +52,23 @@
public String getName() {
return ARTIFACT_NAME;
}
-
+
public SinfoCalcMode getCalculationMode() {
- final String calc = getDataAsString(FIELD_MODE);
+ final String calc = getDataAsString(FIELD_MODE);
if (calc == null) {
- throw new IllegalArgumentException(ERROR_NO_CALCULATION_MODE);
+ throw new IllegalArgumentException(ERROR_NO_CALCULATION_MODE);
}
try {
- return SinfoCalcMode.valueOf(StringUtils.trimToEmpty(calc).toLowerCase());
- } catch (Exception e) {
- throw new IllegalArgumentException(ERROR_INVALID_CALCULATION_MODE, e);
- }
- }
-
+ return SinfoCalcMode.valueOf(StringUtils.trimToEmpty(calc).toLowerCase());
+ }
+ catch (final Exception e) {
+ throw new IllegalArgumentException(ERROR_INVALID_CALCULATION_MODE, e);
+ }
+ }
+
public String getRiver() {
- return getDataAsString(FIELD_RIVER);
- }
+ return getDataAsString(FIELD_RIVER);
+ }
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java Tue Mar 13 18:49:33 2018 +0100
@@ -16,57 +16,61 @@
*/
public interface SInfoI18NStrings {
- public static final String CSV_META_HEADER_RESULT = "sinfo.export.flow_depth.csv.meta.header.result";
-
- public static final String CSV_META_HEADER_RESULT_LABEL = "sinfo.export.flow_depth.csv.meta.header.result.label";
-
- public static final String CSV_META_VERSION = "sinfo.export.flow_depth.csv.meta.version";
-
- public static final String CSV_META_VERSION_LABEL = "sinfo.export.flow_depth.csv.meta.version.label";
-
- public static final String CSV_META_USER = "sinfo.export.flow_depth.csv.meta.user";
-
- public static final String CSV_META_USER_LABEL = "sinfo.export.flow_depth.csv.meta.user.label";
-
- public static final String CSV_META_CREATION = "sinfo.export.flow_depth.csv.meta.creation";
-
- public static final String CSV_META_CREATION_LABEL = "sinfo.export.flow_depth.csv.meta.creation.label";
-
- public static final String CSV_META_RIVER = "sinfo.export.flow_depth.csv.meta.river";
-
- public static final String CSV_META_RIVER_LABEL = "sinfo.export.flow_depth.csv.meta.river.label";
-
- public static final String CSV_KM_HEADER = "sinfo.export.flow_depth.csv.header.km";
-
- public static final String CSV_MEAN_BED_HEIGHT_HEADER = "sinfo.export.flow_depth.csv.header.mean_bed_height";
-
- public static final String CSV_WATERLEVEL_HEADER = "sinfo.export.flow_depth.csv.header.waterlevel";
+ String CSV_META_HEADER_RESULT = "sinfo.export.flow_depth.csv.meta.header.result";
- public static final String CSV_DISCHARGE_HEADER = "sinfo.export.flow_depth.csv.header.discharge";
-
- public static final String CSV_LABEL_HEADER = "sinfo.export.flow_depth.csv.header.label";
-
- public static final String CSV_GAUGE_HEADER = "sinfo.export.flow_depth.csv.header.gauge";
-
- public static final String CSV_LOCATION_HEADER = "sinfo.export.flow_depth.csv.header.location";
-
- public static final String CSV_META_HEADER_WATERLEVEL = "sinfo.export.flow_depth.csv.meta.header.waterlevel";
-
- public static final String CSV_META_HEADER_WATERLEVEL_NAME = "sinfo.export.flow_depth.csv.meta.header.waterlevel.name";
-
- public static final String CSV_META_HEADER_WATERLEVEL_GAUGE = "sinfo.export.flow_depth.csv.meta.header.waterlevel.gauge";
+ String CSV_META_HEADER_RESULT_LABEL = "sinfo.export.flow_depth.csv.meta.header.result.label";
- public static final String CSV_META_HEADER_WATERLEVEL_YEAR = "sinfo.export.flow_depth.csv.meta.header.waterlevel.year";
-
- public static final String CSV_META_RANGE = "sinfo.export.flow_depth.csv.meta.range";
-
- public static final String CSV_META_RANGE_LABEL = "sinfo.export.flow_depth.csv.meta.range.label";
+ String CSV_META_VERSION = "sinfo.export.flow_depth.csv.meta.version";
- public static final String CSV_META_HEIGHT_UNIT_RIVER = "sinfo.export.flow_depth.csv.meta.height_unit.river";
-
- public static final String UNIT_M = "m";
+ String CSV_META_VERSION_LABEL = "sinfo.export.flow_depth.csv.meta.version.label";
- public static final String UNIT_CM = "cm";
+ String CSV_META_USER = "sinfo.export.flow_depth.csv.meta.user";
- public static final String UNIT_CUBIC_M = "m³/s";
+ String CSV_META_USER_LABEL = "sinfo.export.flow_depth.csv.meta.user.label";
+
+ String CSV_META_CREATION = "sinfo.export.flow_depth.csv.meta.creation";
+
+ String CSV_META_CREATION_LABEL = "sinfo.export.flow_depth.csv.meta.creation.label";
+
+ String CSV_META_RIVER = "sinfo.export.flow_depth.csv.meta.river";
+
+ String CSV_META_RIVER_LABEL = "sinfo.export.flow_depth.csv.meta.river.label";
+
+ String CSV_KM_HEADER = "sinfo.export.flow_depth.csv.header.km";
+
+ String CSV_MEAN_BED_HEIGHT_HEADER = "sinfo.export.flow_depth.csv.header.mean_bed_height";
+
+ String CSV_WATERLEVEL_HEADER = "sinfo.export.flow_depth.csv.header.waterlevel";
+
+ String CSV_DISCHARGE_HEADER = "sinfo.export.flow_depth.csv.header.discharge";
+
+ String CSV_LABEL_HEADER = "sinfo.export.flow_depth.csv.header.label";
+
+ String CSV_GAUGE_HEADER = "sinfo.export.flow_depth.csv.header.gauge";
+
+ String CSV_LOCATION_HEADER = "sinfo.export.flow_depth.csv.header.location";
+
+ String CSV_SOUNDING_HEADER = "sinfo.export.flow_depth.csv.header.sounding";
+
+ 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";
+
+ String CSV_META_HEADER_WATERLEVEL_GAUGE = "sinfo.export.flow_depth.csv.meta.header.waterlevel.gauge";
+
+ String CSV_META_HEADER_WATERLEVEL_YEAR = "sinfo.export.flow_depth.csv.meta.header.waterlevel.year";
+
+ String CSV_META_RANGE = "sinfo.export.flow_depth.csv.meta.range";
+
+ String CSV_META_RANGE_LABEL = "sinfo.export.flow_depth.csv.meta.range.label";
+
+ String CSV_META_HEIGHT_UNIT_RIVER = "sinfo.export.flow_depth.csv.meta.height_unit.river";
+
+ String CSV_MEAN_BED_HEIGHT_HEADER_SHORT = "sinfo.export.flow_depth.csv.header.mean_bed_height.short";
+
+ String UNIT_M = "m";
+
+ String UNIT_CM = "cm";
+
+ String UNIT_CUBIC_M = "m³/s";
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResult.java Tue Mar 13 18:49:33 2018 +0100
@@ -13,13 +13,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
-import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind;
import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
-import gnu.trove.TDoubleArrayList;
-
/**
* @author Gernot Belger
*/
@@ -31,14 +27,11 @@
private final String label;
- private final boolean hasTkh;
-
private final WstInfo wst;
- public AbstractSInfoCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection rows) {
+ public AbstractSInfoCalculationResult(final String label, final WstInfo wst, final Collection rows) {
this.label = label;
this.wst = wst;
- this.hasTkh = hasTkh;
this.rows = new ArrayList<>(rows);
}
@@ -46,10 +39,6 @@
return this.label;
}
- public final boolean hasTkh() {
- return this.hasTkh;
- }
-
public final WstInfo getWst() {
return this.wst;
}
@@ -61,139 +50,4 @@
public final Collection getRows() {
return Collections.unmodifiableCollection(this.rows);
}
-
- public double[][] getFlowDepthPoints() {
-
- final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size());
- final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size());
-
- for (final ROW row : this.rows) {
- xPoints.add(row.getStation());
- yPoints.add(row.getFlowDepth());
- }
-
- return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() };
- }
-
- public double[][] getFlowDepthTkhPoints() {
-
- final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size());
- final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size());
-
- for (final ROW row : this.rows) {
- xPoints.add(row.getStation());
- yPoints.add(row.getFlowDepthWithTkh());
- }
-
- return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() };
- }
-
- public final double[][] getTkhUpPoints() {
- final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size());
- final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size());
- final List kinds = new ArrayList<>(this.rows.size());
-
- for (final ROW row : this.rows) {
- xPoints.add(row.getStation());
- yPoints.add(row.getTkhUp());
- kinds.add(row.getTkhKind());
- }
-
- return adjustTkhVisualization(xPoints, yPoints, kinds);
- }
-
- public final double[][] getTkhDownPoints() {
- final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size());
- final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size());
- final List kinds = new ArrayList<>(this.rows.size());
-
- for (final ROW row : this.rows) {
- xPoints.add(row.getStation());
- yPoints.add(row.getTkhDown());
- kinds.add(row.getTkhKind());
- }
-
- return adjustTkhVisualization(xPoints, yPoints, kinds);
- }
-
- public double[][] getVelocityPoints() {
-
- final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size());
- final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size());
-
- for (final ROW row : this.rows) {
- xPoints.add(row.getStation());
- yPoints.add(row.getVelocity());
- }
-
- return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() };
- }
-
- public double[][] getD50Points() {
-
- final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size());
- final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size());
-
- for (final ROW row : this.rows) {
- xPoints.add(row.getStation());
- yPoints.add(row.getD50());
- }
-
- return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() };
- }
-
- public double[][] getTauPoints() {
-
- final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size());
- final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size());
-
- for (final ROW row : this.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) {
-
- final TDoubleArrayList adjustedX = new TDoubleArrayList(xPoints.size());
- final TDoubleArrayList adjustedY = new TDoubleArrayList(yPoints.size());
-
- adjustedX.add(xPoints.get(0));
- adjustedY.add(yPoints.get(0));
-
- for (int i = 1; i < xPoints.size(); 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 middleX = (x1 + x2) / 2;
-
- // REMARK: we can't produce a 100% vertical line, as the area-renderer will not work correctly
- adjustedX.add(middleX - 0.0001);
- adjustedY.add(y1);
-
- adjustedX.add(middleX + 0.0001);
- adjustedY.add(y2);
- }
-
- /* always add the real point now */
- adjustedX.add(xPoints.get(i));
- adjustedY.add(yPoints.get(i));
- }
-
- return new double[][] { adjustedX.toNativeArray(), adjustedY.toNativeArray() };
- }
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoExporter.java Tue Mar 13 18:49:33 2018 +0100
@@ -10,17 +10,26 @@
package org.dive4elements.river.artifacts.sinfo.common;
import java.io.OutputStream;
+import java.text.DateFormat;
+import java.text.NumberFormat;
import java.util.Collection;
+import java.util.Date;
import java.util.HashMap;
+import java.util.Locale;
import java.util.Map;
+import org.apache.commons.lang.math.DoubleRange;
import org.apache.log4j.Logger;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.artifacts.common.utils.Config;
+import org.dive4elements.river.FLYS;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings;
+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.exports.AbstractExporter;
import au.com.bytecode.opencsv.CSVWriter;
@@ -35,6 +44,20 @@
*/
public abstract class AbstractSInfoExporter, RESULTS extends AbstractSInfoCalculationResults> extends AbstractExporter {
+ private static final String CSV_META_HEADER_SOUNDING = "sinfo.export.flow_depth.csv.meta.header.sounding";
+
+ private static final String CSV_META_HEADER_SOUNDING_YEAR = "sinfo.export.flow_depth.csv.meta.header.sounding.year";
+
+ private static final String CSV_META_HEADER_SOUNDING_TYPE = "sinfo.export.flow_depth.csv.meta.header.sounding.type";
+
+ private static final String CSV_META_HEADER_SOUNDING_EVALUATOR = "sinfo.export.flow_depth.csv.meta.header.sounding.evaluator";
+
+ private static final String CSV_META_HEADER_SOUNDING_PRJ = "sinfo.export.flow_depth.csv.meta.header.sounding.prj";
+
+ private static final String CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL = "sinfo.export.flow_depth.csv.meta.header.sounding.elevationmodel";
+
+ private static final String CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL_ORIGINAL = "sinfo.export.flow_depth.csv.meta.header.sounding.elevationmodel.original";
+
/** The storage that contains the current calculation result. */
private RESULTS data = null;
@@ -173,4 +196,98 @@
}
protected abstract String[] formatPDFRow(RESULTS results, final ROW row);
+
+ protected final void writeCSVGlobalMetadataDefaults(final CSVWriter writer, final AbstractSInfoCalculationResults, ?> results) {
+
+ final String calcModeLabel = results.getCalcModeLabel();
+ final RiverInfo river = results.getRiver();
+ final DoubleRange calcRange = results.getCalcRange();
+
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_RESULT, msg(SInfoI18NStrings.CSV_META_HEADER_RESULT_LABEL), river.getName(), calcModeLabel);
+
+ // "# FLYS-Version: "
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_VERSION, msg(SInfoI18NStrings.CSV_META_VERSION_LABEL), FLYS.VERSION);
+
+ // "# Bearbeiter: "
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_USER, msg(SInfoI18NStrings.CSV_META_USER_LABEL), results.getUser());
+
+ // "# Datum der Erstellung: "
+ final Locale locale = Resources.getLocale(this.context.getMeta());
+ final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_CREATION, msg(SInfoI18NStrings.CSV_META_CREATION_LABEL), df.format(new Date()));
+
+ // "# Gewässer: "
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_RIVER, msg(SInfoI18NStrings.CSV_META_RIVER_LABEL), river.getName());
+
+ // "# Höhensystem des Flusses: "
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEIGHT_UNIT_RIVER, river.getWstUnit());
+
+ // "# Ort/Bereich (km): "
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_RANGE, msg(SInfoI18NStrings.CSV_META_RANGE_LABEL),
+ getKmFormatter().format(calcRange.getMinimumDouble()), getKmFormatter().format(calcRange.getMaximumDouble()));
+ }
+
+ protected final void writeCSVSoundingMetadata(final CSVWriter writer, final BedHeightInfo sounding) {
+ // "##METADATEN PEILUNG"
+ writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING);
+
+ // "# Jahr der Peilung: "
+ writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_YEAR, Integer.toString(sounding.getYear()));
+ // "# Aufnahmeart: "
+ writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_TYPE, sounding.getType());
+ // "# Auswerter: "
+ writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_EVALUATOR, sounding.getEvaluationBy());
+ // "# Lagesystem: "
+ writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_PRJ, sounding.getLocationSystem());
+ // "# Höhensystem: "
+ writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL, sounding.getCurElevationModelUnit());
+ // "# ursprüngliches Höhensystem: "
+ writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL_ORIGINAL, sounding.getOldElevationModelUnit());
+ }
+
+ protected final void writeCSVWaterlevelMetadata(final CSVWriter writer, final WstInfo wst) {
+ // "##METADATEN WASSERSPIEGELLAGE"
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL);
+
+ // "# Bezeichnung der Wasserspiegellage: "
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_NAME, wst.getLabel());
+
+ // "# Bezugspegel: "
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_GAUGE, wst.getGauge());
+
+ // "# Jahr/Zeitraum der Wasserspiegellage: "
+ final int year = wst.getYear();
+ if (year > 0)
+ writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_YEAR, Integer.toString(year));
+ }
+
+ protected final void addJRMetaDataDefaults(final MetaAndTableJRDataSource source, final AbstractSInfoCalculationResults, ?> results) {
+
+ final RiverInfo river = results.getRiver();
+ final String wstUnitName = river.getWstUnit();
+
+ source.addMetaData("header", msg(SInfoI18NStrings.CSV_META_HEADER_RESULT_LABEL));
+ source.addMetaData("calcMode", results.getCalcModeLabel());
+
+ source.addMetaData("version_label", msg(SInfoI18NStrings.CSV_META_VERSION_LABEL));
+ source.addMetaData("version", FLYS.VERSION);
+
+ source.addMetaData("user_label", msg(SInfoI18NStrings.CSV_META_USER_LABEL));
+ source.addMetaData("user", results.getUser());
+
+ final Locale locale = Resources.getLocale(this.context.getMeta());
+ final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+ source.addMetaData("date_label", msg(SInfoI18NStrings.CSV_META_CREATION_LABEL));
+ source.addMetaData("date", df.format(new Date()));
+
+ source.addMetaData("river_label", msg(SInfoI18NStrings.CSV_META_RIVER_LABEL));
+ source.addMetaData("river", river.getName());
+ source.addMetaData("river_unit", wstUnitName);
+
+ final DoubleRange calcRange = results.getCalcRange();
+ final NumberFormat kmFormatter = getKmFormatter();
+ final String rangeValue = String.format("%s - %s", kmFormatter.format(calcRange.getMinimumDouble()), kmFormatter.format(calcRange.getMaximumDouble()));
+ source.addMetaData("range_label", msg(SInfoI18NStrings.CSV_META_RANGE_LABEL));
+ source.addMetaData("range", rangeValue);
+ }
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java Tue Mar 13 18:49:33 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);
@@ -44,7 +44,8 @@
series.putMetaData(metaData, artifact, context);
final String facetName = bundle.getFacetName();
- final AbstractSInfoCalculationResult> data = (AbstractSInfoCalculationResult>) bundle.getData(context);
+ @SuppressWarnings("unchecked")
+ final RESULT data = (RESULT) bundle.getData(context);
if (data == null) {
// Check has been here before so we keep it for security reasons
// this should never happen though.
@@ -74,7 +75,7 @@
return scales.getRadius(river, start, end);
}
- private double[][] generatePoints(final CallContext context, final Artifact artifact, final AbstractSInfoCalculationResult> data,
+ private double[][] generatePoints(final CallContext context, final Artifact artifact, final RESULT data,
final String facetName) {
final double[][] points = doGetPoints(data, facetName);
@@ -87,7 +88,7 @@
return points;
}
- protected abstract double[][] doGetPoints(AbstractSInfoCalculationResult> data, String facetName);
+ protected abstract double[][] doGetPoints(RESULT data, String facetName);
private double[][] movingAverage(final Double radius, final double[][] points) {
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoResultRow.java Tue Mar 13 18:49:33 2018 +0100
@@ -11,9 +11,6 @@
import java.io.Serializable;
-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.
*
@@ -22,49 +19,18 @@
public abstract class AbstractSInfoResultRow implements Serializable {
private static final long serialVersionUID = 1L;
- private final Tkh tkh;
-
private final String waterlevelLabel;
private final String gauge;
private final String location;
- public AbstractSInfoResultRow(final Tkh tkh, final String waterlevelLabel, final String gauge, final String location) {
- this.tkh = tkh;
+ public AbstractSInfoResultRow(final String waterlevelLabel, final String gauge, final String location) {
this.waterlevelLabel = waterlevelLabel;
this.gauge = gauge;
this.location = location;
}
- 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 String getWaterlevelLabel() {
return this.waterlevelLabel;
}
@@ -73,30 +39,6 @@
return this.gauge;
}
- 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();
- }
-
public final String getLocation() {
return this.location;
}
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhCalculationResult.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhCalculationResult.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,189 @@
+/** 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.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind;
+import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
+
+import gnu.trove.TDoubleArrayList;
+
+/**
+ * @author Gernot Belger
+ */
+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) {
+ super(label, wst, rows);
+ this.hasTkh = hasTkh;
+ }
+
+ public final boolean hasTkh() {
+ 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 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());
+ }
+
+ return adjustTkhVisualization(xPoints, yPoints, kinds);
+ }
+
+ public final double[][] getTkhDownPoints() {
+
+ final Collection rows = getRows();
+
+ 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());
+ }
+
+ 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) {
+
+ final TDoubleArrayList adjustedX = new TDoubleArrayList(xPoints.size());
+ final TDoubleArrayList adjustedY = new TDoubleArrayList(yPoints.size());
+
+ adjustedX.add(xPoints.get(0));
+ adjustedY.add(yPoints.get(0));
+
+ for (int i = 1; i < xPoints.size(); 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 middleX = (x1 + x2) / 2;
+
+ // REMARK: we can't produce a 100% vertical line, as the area-renderer will not work correctly
+ adjustedX.add(middleX - 0.0001);
+ adjustedY.add(y1);
+
+ adjustedX.add(middleX + 0.0001);
+ adjustedY.add(y2);
+ }
+
+ /* always add the real point now */
+ adjustedX.add(xPoints.get(i));
+ adjustedY.add(yPoints.get(i));
+ }
+
+ return new double[][] { adjustedX.toNativeArray(), adjustedY.toNativeArray() };
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhResultRow.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractTkhResultRow.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,81 @@
+/** 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 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/D50Processor.java Tue Mar 13 18:49:33 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,7 +40,7 @@
}
@Override
- protected double[][] doGetPoints(final AbstractSInfoCalculationResult> data, final String facetName) {
+ protected double[][] doGetPoints(final AbstractTkhCalculationResult> data, final String facetName) {
if (FACET_TKH_D50_FILTERED.contentEquals(facetName))
return data.getD50Points();
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FlowDepthProcessor.java Tue Mar 13 18:49:33 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,7 +47,7 @@
}
@Override
- protected double[][] doGetPoints(final AbstractSInfoCalculationResult> data, final String facetName) {
+ protected double[][] doGetPoints(final AbstractTkhCalculationResult> data, final String facetName) {
if (FACET_FLOW_DEPTH_FILTERED.contentEquals(facetName))
return data.getFlowDepthPoints();
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TauProcessor.java Tue Mar 13 18:49:33 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,7 +40,7 @@
}
@Override
- protected double[][] doGetPoints(final AbstractSInfoCalculationResult> data, final String facetName) {
+ protected double[][] doGetPoints(final AbstractTkhCalculationResult> data, final String facetName) {
if (FACET_TKH_TAU_FILTERED.contentEquals(facetName))
return data.getTauPoints();
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java Tue Mar 13 18:49:33 2018 +0100
@@ -49,7 +49,7 @@
final CallContext context = generator.getCallContext();
final String facetName = bundle.getFacetName();
- final AbstractSInfoCalculationResult> data = (AbstractSInfoCalculationResult>) 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.
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/VelocityProcessor.java Tue Mar 13 18:49:33 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,7 +40,7 @@
}
@Override
- protected double[][] doGetPoints(final AbstractSInfoCalculationResult> data, final String facetName) {
+ protected double[][] doGetPoints(final AbstractTkhCalculationResult> data, final String facetName) {
if (FACET_TKH_VELOCITY_FILTERED.contentEquals(facetName))
return data.getVelocityPoints();
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthAccess.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthAccess.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthAccess.java Tue Mar 13 18:49:33 2018 +0100
@@ -10,7 +10,6 @@
package org.dive4elements.river.artifacts.sinfo.flowdepth;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -18,7 +17,6 @@
import org.dive4elements.river.artifacts.access.RangeAccess;
import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
import org.dive4elements.river.artifacts.sinfo.SinfoCalcMode;
-import org.dive4elements.river.backend.utils.StringUtil;
/**
* Access to the flow depth calculation type specific SInfo artifact data.
@@ -29,23 +27,8 @@
* @author Gernot Belger
*/
final class FlowDepthAccess extends RangeAccess {
- public static class DifferencesPair {
- private final String wstId;
- private final String soundingId;
- public DifferencesPair(final String wstId, final String soundingId) {
- this.wstId = wstId;
- this.soundingId = soundingId;
- }
-
- public String getWstId() {
- return this.wstId;
- }
-
- public String getSoundingId() {
- return this.soundingId;
- }
- }
+ private static final String FIELD_DIFFIDS = "diffids";
private static final String FIELD_USE_TKH = "use_transport_bodies"; //$NON-NLS-1$
@@ -68,25 +51,15 @@
return useTkh == null ? false : useTkh;
}
- public Collection getDifferencePairs() {
+ public Collection getDifferencePairs() {
- final Collection diffPairs = new ArrayList<>();
-
- final String diffids = super.getString("diffids");
+ final String diffids = getString(FIELD_DIFFIDS);
if (diffids == null) {
// Should never happen as this is handled by the ui
return Collections.emptyList();
}
- // FIXME: this way of parsing the datacage-ids is repeated all over flys!
- final String datas[] = diffids.split("#");
- for (int i = 0; i < datas.length; i += 2) {
- final String leftId = StringUtil.unbracket(datas[i]);
- final String rightId = StringUtil.unbracket(datas[i + 1]);
-
- diffPairs.add(new DifferencesPair(leftId, rightId));
- }
-
- return Collections.unmodifiableCollection(diffPairs);
+ final Collection pairs = WstSoundingIdPair.parsePairs(diffids);
+ return pairs;
}
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Tue Mar 13 18:49:33 2018 +0100
@@ -13,16 +13,15 @@
import org.apache.commons.lang.math.DoubleRange;
import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.BedHeightsArtifact;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.WKms;
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.flowdepth.FlowDepthAccess.DifferencesPair;
import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder;
import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator;
+import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder;
import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
@@ -30,7 +29,6 @@
import org.dive4elements.river.artifacts.states.WaterlevelData;
import org.dive4elements.river.artifacts.states.WaterlevelFetcher;
import org.dive4elements.river.model.River;
-import org.dive4elements.river.utils.RiverUtils;
class FlowDepthCalculation {
@@ -51,7 +49,7 @@
final River river = access.getRiver();
final RiverInfo riverInfo = new RiverInfo(river);
- final Collection diffPairs = access.getDifferencePairs();
+ final Collection diffPairs = access.getDifferencePairs();
final DoubleRange calcRange = access.getRange();
@@ -66,7 +64,7 @@
final FlowDepthCalculationResults results = new FlowDepthCalculationResults(calcModeLabel, user, riverInfo, calcRange, useTkh);
- for (final DifferencesPair diffPair : diffPairs) {
+ for (final WstSoundingIdPair diffPair : diffPairs) {
final FlowDepthCalculationResult result = calculateResult(calcRange, diffPair, problems, infoProvider, useTkh);
if (result != null)
results.addResult(result);
@@ -80,34 +78,29 @@
*
* @param infoProvider
*/
- private FlowDepthCalculationResult calculateResult(final DoubleRange calcRange, final DifferencesPair diffPair,
- final Calculation problems, final RiverInfoProvider infoProvider, final boolean useTkh) {
+ private FlowDepthCalculationResult calculateResult(final DoubleRange calcRange, final WstSoundingIdPair diffPair, final Calculation problems,
+ final RiverInfoProvider infoProvider, final boolean useTkh) {
/* access real input data from database */
final String soundingId = diffPair.getSoundingId();
final String wstId = diffPair.getWstId();
- final BedHeightsFinder bedHeight = loadBedHeight(soundingId, calcRange);
- if (bedHeight == null) {
- final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", soundingId);
- problems.addProblem(message);
+ final BedHeightsFinder bedHeight = BedHeightsFinder.forId(this.context, soundingId, calcRange, problems);
+ if (bedHeight == null)
return null;
- }
/* REMARK: fetch ALL wst kms, because we want to determine the original reference gauge */
- final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN);
- if (waterlevel == null) {
- final String message = Resources.format(this.context.getMeta(), "Failed to access waterlevel with id '{0}'", wstId);
- problems.addProblem(message);
+ final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN, problems);
+ if (waterlevel == null)
return null;
- }
+
final WKms wstKms = waterlevel.getWkms();
final String wspLabel = wstKms.getName();
final String soundingLabel = bedHeight.getInfo().getDescription();
final String label = String.format("%s - %s", wspLabel, soundingLabel);
- checkYearDifference(label, waterlevel, bedHeight.getInfo().getYear(), problems);
+ FlowDepthUtils.checkYearDifference(label, waterlevel, bedHeight.getInfo().getYear(), problems);
checkWaterlevelDiscretisation(wstKms, calcRange, problems);
// TODO: prüfen, ob sohlhöhen die calcRange abdecken/überschneiden
@@ -117,61 +110,19 @@
final int wspYear = waterlevel.getYear();
final WstInfo wstInfo = new WstInfo(wspLabel, wspYear, riverInfoProvider.getReferenceGauge());
+ final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(wstKms);
final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wstKms);
final River river = riverInfoProvider.getRiver();
- final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(useTkh, this.context, problems, label, river, calcRange, dischargeProvider,
+ final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(useTkh, this.context, problems, label, river, calcRange, waterlevelProvider,
+ dischargeProvider,
bedHeight);
- final FlowDepthCalculator calculator = new FlowDepthCalculator(riverInfoProvider, wstKms, dischargeProvider, bedHeight, tkhCalculator);
+ final FlowDepthCalculator calculator = new FlowDepthCalculator(riverInfoProvider, wspLabel, bedHeight, tkhCalculator);
return calculator.execute(label, wstInfo, calcRange);
}
-
- /**
- * Checks the year difference between waterlevels and sounding, and issues a warning if too big.
- *
- * Zeitraum Zeitliche Differenz [a]
- * X ≥ 1998 ± 3
- * 1958 ≤ X < 1998 ± 6
- * 1918 ≤ X < 1958 ± 12
- * X < 1918 ± 25
- */
- private void checkYearDifference(final String label, final WaterlevelData waterlevel, final Integer soundingYear, final Calculation problems) {
- if (soundingYear == null)
- return;
-
- final int wstYear = waterlevel.getYear();
- if (wstYear < 0)
- return;
-
- final int maxDifference = getMaxDifferenceYears(soundingYear);
-
- final int difference = Math.abs(soundingYear - wstYear);
- if (difference > maxDifference) {
- final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.year_difference", null, label, wstYear,
- soundingYear);
- problems.addProblem(message);
- }
- }
-
- private int getMaxDifferenceYears(final int year) {
-
- if (year < 1918)
- return 25;
-
- if (1918 <= year && year < 1958)
- return 12;
-
- if (1958 <= year && year < 1998)
- return 6;
-
- /* >= 1998 */
- return 3;
- }
-
/* Checks if the discretisation of the waterlevel exceeds 1000m */
-
private void checkWaterlevelDiscretisation(final WKms wstKms, final DoubleRange calcRange, final Calculation problems) {
final int size = wstKms.size();
@@ -190,37 +141,4 @@
}
}
}
-
- private BedHeightsFinder loadBedHeight(final String soundingId, final DoubleRange calcRange) {
-
- // REMARK: absolutely unbelievable....
- // The way how bed-heights (and other data too) is accessed is different for nearly every calculation-type
- // throughout flys.
- // The knowledge on how to parse the datacage-ids is spread through the complete code-base...
-
- // We use here the way on how bed-heights are accessed by the BedDifferenceAccess/BedDifferenceCalculation, but
- // this is plain random
- final String[] parts = soundingId.split(";");
-
- final BedHeightsArtifact artifact = (BedHeightsArtifact) RiverUtils.getArtifact(parts[0], this.context);
-
- final Integer bedheightId = artifact.getDataAsInteger("height_id");
- if (bedheightId == null) {
- // FIXME: error message!
- return null;
- }
-
- // REMARK: this only works with type 'single'; unclear on how to distinguish from epoch data (or whatever the
- // other type means)
- // Luckily, the requirement is to only access 'single' data here.
- // final String bedheightType = artifact.getDataAsString("type");
-
- // REMARK: BedDifferences uses this, but we also need the metadata of the BedHeight
- // REMARK: second absolutely awful thing: BedHeight is a hibernate binding class, accessing the database via
- // hibernate stuff
- // BedHeightFactory uses its own (direct) way of accessing the data, with its own implemented data classes.
- // return BedHeightFactory.getHeight(bedheightType, bedheightId, from, to);
-
- return BedHeightsFinder.forId(bedheightId, calcRange);
- }
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Tue Mar 13 18:49:33 2018 +0100
@@ -11,7 +11,7 @@
import java.util.Collection;
-import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResult;
+import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhCalculationResult;
import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo;
import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
@@ -20,7 +20,7 @@
*
* @author Gernot Belger
*/
-final class FlowDepthCalculationResult extends AbstractSInfoCalculationResult {
+final class FlowDepthCalculationResult extends AbstractTkhCalculationResult {
private static final long serialVersionUID = 1L;
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java Tue Mar 13 18:49:33 2018 +0100
@@ -13,16 +13,11 @@
import java.util.Collection;
import org.apache.commons.lang.math.DoubleRange;
-import org.apache.commons.math.FunctionEvaluationException;
-import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
-import org.dive4elements.river.artifacts.model.WKms;
import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
-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.tkhstate.BedHeightsFinder;
import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
-import org.dive4elements.river.utils.DoubleUtil;
/**
* @author Gernot Belger
@@ -31,33 +26,26 @@
private final Collection rows = new ArrayList<>();
- private final DischargeValuesFinder dischargeProvider;
-
private final BedHeightsFinder bedHeight;
private final TkhCalculator tkhCalculator;
- private final PolynomialSplineFunction wstInterpolator;
-
private final RiverInfoProvider riverInfoProvider;
private final String bedHeightLabel;
private final String wstLabel;
- public FlowDepthCalculator(final RiverInfoProvider riverInfoProvider, final WKms wstKms,
- final DischargeValuesFinder dischargeProvider, final BedHeightsFinder bedHeight, final TkhCalculator tkhCalculator) {
+ public FlowDepthCalculator(final RiverInfoProvider riverInfoProvider, final String wstLabel, final BedHeightsFinder bedHeight,
+ final TkhCalculator tkhCalculator) {
this.riverInfoProvider = riverInfoProvider;
+ this.wstLabel = wstLabel;
- this.dischargeProvider = dischargeProvider;
this.bedHeight = bedHeight;
this.tkhCalculator = tkhCalculator;
- this.wstInterpolator = DoubleUtil.getLinearInterpolator(wstKms.allKms(), wstKms.allWs());
-
this.bedHeightLabel = bedHeight.getInfo().getDescription();
- this.wstLabel = wstKms.getName();
}
public FlowDepthCalculationResult execute(final String label, final WstInfo wstInfo, final DoubleRange calcRange) {
@@ -68,40 +56,21 @@
calculateResultRow(station);
}
- return new FlowDepthCalculationResult(label, wstInfo, this.bedHeight.getInfo(), this.tkhCalculator != null, this.rows);
+ final boolean hasTkh = this.tkhCalculator.hasTkh();
+
+ return new FlowDepthCalculationResult(label, wstInfo, this.bedHeight.getInfo(), hasTkh, this.rows);
}
private void calculateResultRow(final double station) {
- try {
- // FIXME: check out of range of waterlevel?
- final double wst = this.wstInterpolator.value(station);
-
- final Tkh tkh = calculateTkh(station, wst);
-
- // REMARK: access the location once only during calculation
- final String location = this.riverInfoProvider.getLocation(station);
-
- // REMARK: access the gauge once only during calculation
- final String gaugeLabel = this.riverInfoProvider.findGauge(station);
+ final Tkh tkh = this.tkhCalculator.getTkh(station);
- this.rows.add(new FlowDepthRow(tkh, this.wstLabel, gaugeLabel, this.bedHeightLabel, location));
- }
- catch (final FunctionEvaluationException e) {
- /* should only happen if out of range */
- e.printStackTrace();
- /* simply ignore */
- }
- }
+ // REMARK: access the location once only during calculation
+ final String location = this.riverInfoProvider.getLocation(station);
- private Tkh calculateTkh(final double station, final double wst) throws FunctionEvaluationException {
- if (this.tkhCalculator == null) {
- final double discharge = this.dischargeProvider.getDischarge(station);
- final double meanBedHeight = this.bedHeight.getMeanBedHeight(station);
- final double flowDepth = wst - meanBedHeight;
- return new Tkh(station, wst, meanBedHeight, flowDepth, discharge);
- }
+ // REMARK: access the gauge once only during calculation
+ final String gaugeLabel = this.riverInfoProvider.findGauge(station);
- return this.tkhCalculator.getTkh(station, wst);
+ this.rows.add(new FlowDepthRow(tkh, this.wstLabel, gaugeLabel, this.bedHeightLabel, location));
}
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java Tue Mar 13 18:49:33 2018 +0100
@@ -8,18 +8,11 @@
package org.dive4elements.river.artifacts.sinfo.flowdepth;
-import java.text.DateFormat;
-import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Date;
-import java.util.Locale;
import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.math.DoubleRange;
import org.apache.log4j.Logger;
-import org.dive4elements.river.FLYS;
-import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings;
import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter;
import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo;
@@ -31,7 +24,7 @@
import au.com.bytecode.opencsv.CSVWriter;
/**
- * Generates different output formats (csv, pdf) of data that resulted from a flow depths computation.
+ * Generates different output formats (csv, pdf) of data that resulted from a flow depths min/max computation.
*
* @author Ingo Weinzierl
* @author Gernot Belger
@@ -42,28 +35,13 @@
/** The log used in this exporter. */
private static Logger log = Logger.getLogger(FlowDepthExporter.class);
- private static final String CSV_FLOWDEPTH_HEADER = "sinfo.export.flow_depth.csv.header.flowdepth";
- private static final String CSV_FLOWDEPTHTKH_HEADER = "sinfo.export.flow_depth.csv.header.flowdepthTkh";
+ 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 CSV_MEAN_BED_HEIGHT_HEADER_SHORT = "sinfo.export.flow_depth.csv.header.mean_bed_height.short";
- private static final String CSV_SOUNDING_HEADER = "sinfo.export.flow_depth.csv.header.sounding";
-
- private static final String CSV_META_HEADER_SOUNDING = "sinfo.export.flow_depth.csv.meta.header.sounding";
-
- private static final String CSV_META_HEADER_SOUNDING_YEAR = "sinfo.export.flow_depth.csv.meta.header.sounding.year";
-
- private static final String CSV_META_HEADER_SOUNDING_TYPE = "sinfo.export.flow_depth.csv.meta.header.sounding.type";
-
- private static final String CSV_META_HEADER_SOUNDING_EVALUATOR = "sinfo.export.flow_depth.csv.meta.header.sounding.evaluator";
-
- private static final String CSV_META_HEADER_SOUNDING_PRJ = "sinfo.export.flow_depth.csv.meta.header.sounding.prj";
-
- private static final String CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL = "sinfo.export.flow_depth.csv.meta.header.sounding.elevationmodel";
-
- private static final String CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL_ORIGINAL = "sinfo.export.flow_depth.csv.meta.header.sounding.elevationmodel.original";
-
- private static final String JASPER_FILE = "/jasper/sinfo.flowdepth.jasper";
+ private static final String JASPER_FILE = "/jasper/sinfo.flowdepthminmax.jasper";
@Override
protected Logger getLog() {
@@ -71,70 +49,22 @@
}
@Override
- protected void writeCSVResultMetadata(final CSVWriter writer, final FlowDepthCalculationResults results, final FlowDepthCalculationResult result) {
-
- /* first some specific metadata */
- final BedHeightInfo sounding = result.getSounding();
- final WstInfo wst = result.getWst();
-
- // "##METADATEN PEILUNG"
- writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING);
+ protected void writeCSVGlobalMetadata(final CSVWriter writer, final FlowDepthCalculationResults results) {
+ log.info("FlowDepthExporter.writeCSVMeta");
- // "# Jahr der Peilung: "
- writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_YEAR, Integer.toString(sounding.getYear()));
- // "# Aufnahmeart: "
- writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_TYPE, sounding.getType());
- // "# Auswerter: "
- writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_EVALUATOR, sounding.getEvaluationBy());
- // "# Lagesystem: "
- writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_PRJ, sounding.getLocationSystem());
- // "# Höhensystem: "
- writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL, sounding.getCurElevationModelUnit());
- // "# ursprüngliches Höhensystem: "
- writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL_ORIGINAL, sounding.getOldElevationModelUnit());
+ super.writeCSVGlobalMetadataDefaults(writer, results);
- // "##METADATEN WASSERSPIEGELLAGE"
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL);
- // "# Bezeichnung der Wasserspiegellage: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_NAME, wst.getLabel());
- // "# Bezugspegel: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_GAUGE, wst.getGauge());
- // "# Jahr/Zeitraum der Wasserspiegellage: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_YEAR, Integer.toString(wst.getYear()));
+ writer.writeNext(new String[] { "" });
}
@Override
- protected void writeCSVGlobalMetadata(final CSVWriter writer, final FlowDepthCalculationResults results) {
- log.info("FlowDepthExporter.writeCSVMeta");
-
- final String calcModeLabel = results.getCalcModeLabel();
- final RiverInfo river = results.getRiver();
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_RESULT, msg(SInfoI18NStrings.CSV_META_HEADER_RESULT_LABEL), river.getName(), calcModeLabel);
-
- // "# FLYS-Version: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_VERSION, msg(SInfoI18NStrings.CSV_META_VERSION_LABEL), FLYS.VERSION);
-
- // "# Bearbeiter: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_USER, msg(SInfoI18NStrings.CSV_META_USER_LABEL), results.getUser());
+ protected void writeCSVResultMetadata(final CSVWriter writer, final FlowDepthCalculationResults results, final FlowDepthCalculationResult result) {
- // "# Datum der Erstellung: "
- final Locale locale = Resources.getLocale(this.context.getMeta());
- final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_CREATION, msg(SInfoI18NStrings.CSV_META_CREATION_LABEL), df.format(new Date()));
-
- // "# Gewässer: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_RIVER, msg(SInfoI18NStrings.CSV_META_RIVER_LABEL), river.getName());
+ final BedHeightInfo sounding = result.getSounding();
+ super.writeCSVSoundingMetadata(writer, sounding);
- // "# Höhensystem des Flusses: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEIGHT_UNIT_RIVER, river.getWstUnit());
-
- // "# Ort/Bereich (km): "
- final DoubleRange calcRange = results.getCalcRange();
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_RANGE, msg(SInfoI18NStrings.CSV_META_RANGE_LABEL),
- getKmFormatter().format(calcRange.getMinimumDouble()),
- getKmFormatter().format(calcRange.getMaximumDouble()));
-
- writer.writeNext(new String[] { "" });
+ final WstInfo wst = result.getWst();
+ super.writeCSVWaterlevelMetadata(writer, wst);
}
/**
@@ -152,9 +82,9 @@
final Collection header = new ArrayList<>(11);
header.add(msg(SInfoI18NStrings.CSV_KM_HEADER));
- header.add(msgUnit(CSV_FLOWDEPTH_HEADER, SInfoI18NStrings.UNIT_M));
+ header.add(msgUnit(CSV_FLOWDEPTHMINMAX_HEADER, SInfoI18NStrings.UNIT_M));
if (getData().isUseTkh()) {
- header.add(msgUnit(CSV_FLOWDEPTHTKH_HEADER, SInfoI18NStrings.UNIT_M));
+ header.add(msgUnit(CSV_FLOWDEPTHTKHMINMAX_HEADER, SInfoI18NStrings.UNIT_M));
header.add(msgUnit(CSV_TKH_HEADER, SInfoI18NStrings.UNIT_CM));
}
@@ -163,7 +93,7 @@
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(CSV_SOUNDING_HEADER));
+ header.add(msg(SInfoI18NStrings.CSV_SOUNDING_HEADER));
header.add(msg(SInfoI18NStrings.CSV_LOCATION_HEADER));
writer.writeNext(header.toArray(new String[header.size()]));
@@ -235,45 +165,20 @@
@Override
protected final void addJRMetaData(final MetaAndTableJRDataSource source, final FlowDepthCalculationResults results) {
- final RiverInfo river = results.getRiver();
- final String wstUnitName = river.getWstUnit();
-
/* general metadata */
- source.addMetaData("header", msg(SInfoI18NStrings.CSV_META_HEADER_RESULT_LABEL));
- source.addMetaData("calcMode", results.getCalcModeLabel());
-
- source.addMetaData("version_label", msg(SInfoI18NStrings.CSV_META_VERSION_LABEL));
- source.addMetaData("version", FLYS.VERSION);
-
- source.addMetaData("user_label", msg(SInfoI18NStrings.CSV_META_USER_LABEL));
- source.addMetaData("user", results.getUser());
-
- final Locale locale = Resources.getLocale(this.context.getMeta());
- final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
- source.addMetaData("date_label", msg(SInfoI18NStrings.CSV_META_CREATION_LABEL));
- source.addMetaData("date", df.format(new Date()));
-
- source.addMetaData("river_label", msg(SInfoI18NStrings.CSV_META_RIVER_LABEL));
- source.addMetaData("river", river.getName());
-
- final DoubleRange calcRange = results.getCalcRange();
- final NumberFormat kmFormatter = getKmFormatter();
- final String rangeValue = String.format("%s - %s", kmFormatter.format(calcRange.getMinimumDouble()), kmFormatter.format(calcRange.getMaximumDouble()));
- source.addMetaData("range_label", msg(SInfoI18NStrings.CSV_META_RANGE_LABEL));
- source.addMetaData("range", rangeValue);
+ super.addJRMetaDataDefaults(source, results);
/* column headings */
source.addMetaData("station_header", msg(SInfoI18NStrings.CSV_KM_HEADER));
- source.addMetaData("flowdepth_header", msg(CSV_FLOWDEPTH_HEADER));
- source.addMetaData("flowdepth_tkh_header", msg(CSV_FLOWDEPTHTKH_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("river_unit", wstUnitName);
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(CSV_MEAN_BED_HEIGHT_HEADER_SHORT));
- source.addMetaData("sounding_name_header", msg(CSV_SOUNDING_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));
}
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthPairSelectState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthPairSelectState.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthPairSelectState.java Tue Mar 13 18:49:33 2018 +0100
@@ -1,6 +1,6 @@
/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- * Björnsen Beratende Ingenieure GmbH
+ * 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)
@@ -15,13 +15,15 @@
* @author Gernot Belger
*
*/
-public class FlowDepthPairSelectState
-// FIXME: very ugly; but probably we will break the serialization of WaterlevelPairSelectState if we introduce an abstraction
-extends WaterlevelPairSelectState {
+// FIXME: very ugly; but probably we will break the serialization of WaterlevelPairSelectState if we introduce an
+// abstraction
+public final class FlowDepthPairSelectState extends WaterlevelPairSelectState {
+
+ private static final long serialVersionUID = 1L;
/** Specify to display a datacage_twin_panel. */
@Override
protected String getUIProvider() {
return "sinfo_flowdepth_twin_panel";
}
-}
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthRow.java Tue Mar 13 18:49:33 2018 +0100
@@ -9,7 +9,7 @@
*/
package org.dive4elements.river.artifacts.sinfo.flowdepth;
-import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoResultRow;
+import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhResultRow;
import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh;
/**
@@ -17,7 +17,7 @@
*
* @author Gernot Belger
*/
-final class FlowDepthRow extends AbstractSInfoResultRow {
+final class FlowDepthRow extends AbstractTkhResultRow {
private static final long serialVersionUID = 1L;
private final String soundingLabel;
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthUtils.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthUtils.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,61 @@
+/** 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.model.Calculation;
+import org.dive4elements.river.artifacts.states.WaterlevelData;
+
+/**
+ * @author Gernot Belger
+ */
+public final class FlowDepthUtils {
+
+ private FlowDepthUtils() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Checks the year difference between waterlevels and sounding, and issues a warning if too big.
+ *
+ * Zeitraum Zeitliche Differenz [a]
+ * X ≥ 1998 ± 3
+ * 1958 ≤ X < 1998 ± 6
+ * 1918 ≤ X < 1958 ± 12
+ * X < 1918 ± 25
+ */
+ public static void checkYearDifference(final String label, final WaterlevelData waterlevel, final int soundingYear, final Calculation problems) {
+
+ final int wstYear = waterlevel.getYear();
+ if (wstYear < 0)
+ return;
+
+ final int maxDifference = getMaxDifferenceYears(soundingYear);
+
+ final int difference = Math.abs(soundingYear - wstYear);
+ if (difference > maxDifference) {
+ problems.addProblem("sinfo_calc_flow_depth.warning.year_difference", label, wstYear, soundingYear);
+ }
+ }
+
+ public static int getMaxDifferenceYears(final int year) {
+
+ if (year < 1918)
+ return 25;
+
+ if (1918 <= year && year < 1958)
+ return 12;
+
+ if (1958 <= year && year < 1998)
+ return 6;
+
+ /* >= 1998 */
+ return 3;
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/UseTransportBodiesChoice.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/UseTransportBodiesChoice.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/UseTransportBodiesChoice.java Tue Mar 13 18:49:33 2018 +0100
@@ -15,7 +15,9 @@
*/
public class UseTransportBodiesChoice extends BooleanChoiceState {
+ private static final long serialVersionUID = 1L;
+
public UseTransportBodiesChoice() {
- super( "useTransportBodies.option", "useTransportBodies.active", "useTransportBodies.inactive" );
- }
+ super( "useTransportBodies.option", "useTransportBodies.active", "useTransportBodies.inactive" );
+ }
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/WstSoundingIdPair.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/WstSoundingIdPair.java Tue Mar 13 18:49:33 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.flowdepth;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.dive4elements.river.backend.utils.StringUtil;
+
+/**
+ * @author Gernot Belger
+ */
+public final class WstSoundingIdPair {
+
+ private final String wstId;
+
+ private final String soundingId;
+
+ public WstSoundingIdPair(final String wstId, final String soundingId) {
+ this.wstId = wstId;
+ this.soundingId = soundingId;
+ }
+
+ public String getWstId() {
+ return this.wstId;
+ }
+
+ public String getSoundingId() {
+ return this.soundingId;
+ }
+
+ public static List parsePairs(final String diffids) {
+
+ // FIXME: this way of parsing the datacage-ids is repeated all over flys!
+ final String datas[] = diffids.split("#");
+
+ final List diffPairs = new ArrayList<>(datas.length);
+
+ for (int i = 0; i < datas.length; i += 2) {
+ final String leftId = StringUtil.unbracket(datas[i]);
+ final String rightId = StringUtil.unbracket(datas[i + 1]);
+
+ diffPairs.add(new WstSoundingIdPair(leftId, rightId));
+ }
+
+ return Collections.unmodifiableList(diffPairs);
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxAccess.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxAccess.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,105 @@
+/* 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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.river.artifacts.access.RangeAccess;
+import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.sinfo.SinfoCalcMode;
+import org.dive4elements.river.artifacts.sinfo.flowdepth.WstSoundingIdPair;
+
+/**
+ * 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
+ * reference to the artifact instance.
+ * Hence we do NOT cache any data.
+ *
+ * @author Gernot Belger
+ */
+final class FlowDepthMinMaxAccess extends RangeAccess {
+
+ public static class MinMaxIdPair {
+
+ private final String wstId;
+
+ private final String minSoundingId;
+
+ private final String maxSoundingId;
+
+ public MinMaxIdPair(final String wstId, final String minSoundingId, final String maxSoundingId) {
+ this.wstId = wstId;
+ this.minSoundingId = minSoundingId;
+ this.maxSoundingId = maxSoundingId;
+ }
+
+ public String getWstId() {
+ return this.wstId;
+ }
+
+ public String getMinSoundingId() {
+ return this.minSoundingId;
+ }
+
+ public String getMaxSoundingId() {
+ return this.maxSoundingId;
+ }
+ }
+
+ private static final String FIELD_DIFFIDS = "diffids";
+
+ public FlowDepthMinMaxAccess(final SINFOArtifact artifact) {
+ super(artifact);
+
+ /* assert calculation mode */
+ final SinfoCalcMode calculationMode = artifact.getCalculationMode();
+ assert (calculationMode == SinfoCalcMode.sinfo_calc_flow_depth_minmax);
+ }
+
+ public DoubleRange getRange() {
+ final double from = getFrom();
+ final double to = getTo();
+ return new DoubleRange(from, to);
+ }
+
+ public Collection getMinMaxPairs() {
+
+ final String diffids = getString(FIELD_DIFFIDS);
+
+ /* fetch the raw configured pairs */
+ final List diffPairs = WstSoundingIdPair.parsePairs(diffids);
+
+ /* now sort eleemnts into pairs of TL/KL */
+ // FIXME: use sounding-ids to determine how pairs fit together
+ // or, let the ui already enforce it somehow
+
+ final List minMaxPairs = new ArrayList<>(diffPairs.size());
+ // FIXME: at the moment, we simply pair by order
+ for (int i = 0; i < diffPairs.size(); i++) {
+
+ final WstSoundingIdPair minPair = diffPairs.get(i);
+
+ if (i < diffPairs.size() - 1) {
+ final WstSoundingIdPair maxPair = diffPairs.get(i + 1);
+ minMaxPairs.add(new MinMaxIdPair(minPair.getWstId(), minPair.getSoundingId(), maxPair.getSoundingId()));
+ i++;
+ } else {
+ minMaxPairs.add(new MinMaxIdPair(minPair.getWstId(), minPair.getSoundingId(), null));
+ }
+ }
+
+ return Collections.unmodifiableCollection(minMaxPairs);
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,201 @@
+/** 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 java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.WKms;
+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.flowdepth.FlowDepthUtils;
+import org.dive4elements.river.artifacts.sinfo.flowdepthminmax.FlowDepthMinMaxAccess.MinMaxIdPair;
+import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder;
+import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder;
+import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
+import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo;
+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.artifacts.states.WaterlevelData;
+import org.dive4elements.river.artifacts.states.WaterlevelFetcher;
+import org.dive4elements.river.model.River;
+
+/**
+ * @author Gernot Belger
+ */
+final class FlowDepthMinMaxCalculation {
+
+ private final CallContext context;
+
+ public FlowDepthMinMaxCalculation(final CallContext context) {
+ this.context = context;
+ }
+
+ public CalculationResult calculate(final SINFOArtifact sinfo) {
+
+ final String user = CalculationUtils.findArtifactUser(this.context, sinfo);
+
+ /* access input data */
+ final FlowDepthMinMaxAccess access = new FlowDepthMinMaxAccess(sinfo);
+ final River river = access.getRiver();
+ final RiverInfo riverInfo = new RiverInfo(river);
+
+ final Collection minMaxPairs = access.getMinMaxPairs();
+
+ final DoubleRange calcRange = access.getRange();
+
+ /* calculate results for each diff pair */
+ final Calculation problems = new Calculation();
+
+ final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange);
+
+ final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name());
+
+ final FlowDepthMinMaxCalculationResults results = new FlowDepthMinMaxCalculationResults(calcModeLabel, user, riverInfo, calcRange);
+
+ for (final MinMaxIdPair minMaxPair : minMaxPairs) {
+ final FlowDepthMinMaxCalculationResult result = calculateResult(calcRange, minMaxPair, problems, infoProvider);
+ if (result != null)
+ results.addResult(result);
+ }
+
+ return new CalculationResult(results, problems);
+ }
+
+ /**
+ * Calculates one W-MSH differences pair.
+ *
+ * @param infoProvider
+ */
+ private FlowDepthMinMaxCalculationResult calculateResult(final DoubleRange calcRange, final MinMaxIdPair minMaxPair, final Calculation problems,
+ final RiverInfoProvider infoProvider) {
+
+ /* access real input data from database */
+ final String wstId = minMaxPair.getWstId();
+ final String minSoundingId = minMaxPair.getMinSoundingId();
+ final String maxSoundingId = minMaxPair.getMinSoundingId();
+
+ 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);
+ if (minBedHeight == null && maxBedHeight == null)
+ return null;
+
+ /* REMARK: fetch ALL wst kms, because we want to determine the original reference gauge */
+ final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN, problems);
+ if (waterlevel == null)
+ return null;
+
+ final String label = createLabel(waterlevel, minBedHeight, maxBedHeight);
+
+ final WKms wstKms = waterlevel.getWkms();
+
+ final int soundingYear = checkSoundingYear(minBedHeight, maxBedHeight, problems);
+ FlowDepthUtils.checkYearDifference(label, waterlevel, soundingYear, problems);
+ // FIXME
+ // checkWaterlevelDiscretisation(wstKms, calcRange, problems);
+ // TODO: prüfen, ob sohlhöhen die calcRange abdecken/überschneiden
+
+ /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */
+ final RiverInfoProvider riverInfoProvider = infoProvider.forWaterlevel(waterlevel);
+
+ final int wspYear = waterlevel.getYear();
+ final WstInfo wstInfo = new WstInfo(waterlevel.getName(), wspYear, riverInfoProvider.getReferenceGauge());
+
+ final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(wstKms);
+ final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wstKms);
+
+ final String waterlevelLabel = waterlevel.getName();
+ final String soundingLabel = buildSoundingLabel(minBedHeight, maxBedHeight);
+
+ /* real calculation loop */
+ final Collection rows = new ArrayList<>();
+
+ // FIXME: determine what is the spatial discretisation that we will use...
+ final double[] allKms = wstKms.allKms().toNativeArray();
+ for (final double station : allKms) {
+ if (calcRange.containsDouble(station)) {
+
+ final double wst = waterlevelProvider.getWaterlevel(station);
+ final double discharge = dischargeProvider.getDischarge(station);
+
+ final double minBedHeightValue = minBedHeight == null ? Double.NaN : minBedHeight.getMeanBedHeight(station);
+ final double maxBedHeightValue = maxBedHeight == null ? Double.NaN : maxBedHeight.getMeanBedHeight(station);
+
+ final double minFlowDepth = wst - minBedHeightValue;
+ final double maxFlowDepth = wst - maxBedHeightValue;
+
+ // FIXME: unclear what is meant here...
+ final double meanBedHeight = Double.NaN;
+
+ // REMARK: access the location once only during calculation
+ final String location = riverInfoProvider.getLocation(station);
+
+ // 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 BedHeightInfo minBedHeightInfo = minBedHeight == null ? null : minBedHeight.getInfo();
+ final BedHeightInfo maxBedHeightInfo = maxBedHeight == null ? null : maxBedHeight.getInfo();
+ return new FlowDepthMinMaxCalculationResult(label, wstInfo, minBedHeightInfo, maxBedHeightInfo, rows);
+ }
+
+ private String buildSoundingLabel(final BedHeightsFinder minBedHeight, final BedHeightsFinder maxBedHeight) {
+
+ if (minBedHeight == null)
+ return maxBedHeight.getInfo().getDescription();
+
+ if (maxBedHeight == null)
+ return minBedHeight.getInfo().getDescription();
+
+ return String.format("%s / %s", minBedHeight.getInfo().getDescription(), maxBedHeight.getInfo().getDescription());
+ }
+
+ private String createLabel(final WaterlevelData waterlevel, final BedHeightsFinder minBedHeight, final BedHeightsFinder maxBedHeight) {
+
+ final StringBuilder buffer = new StringBuilder(waterlevel.getName());
+
+ if (minBedHeight != null)
+ buffer.append(" - "). //
+ append(minBedHeight.getInfo().getDescription());
+
+ if (maxBedHeight != null)
+ buffer.append(" - "). //
+ append(maxBedHeight.getInfo().getDescription());
+
+ return buffer.toString();
+ }
+
+ private int checkSoundingYear(final BedHeightsFinder minBedHeight, final BedHeightsFinder maxBedHeight, final Calculation problems) {
+
+ if (maxBedHeight == null)
+ return minBedHeight.getInfo().getYear();
+
+ if (minBedHeight == null)
+ return maxBedHeight.getInfo().getYear();
+
+ final int minYear = minBedHeight.getInfo().getYear();
+ final int maxYear = minBedHeight.getInfo().getYear();
+
+ if (minYear != maxYear)
+ problems.addProblem("sinfo.flowdepthminmaxcalculation.soundingyear.different");
+
+ return minYear;
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResult.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResult.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,53 @@
+/* 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 java.util.Collection;
+
+import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResult;
+import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo;
+import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
+
+/**
+ * Contains the results of a {@link FlowDepthCalculation}.
+ *
+ * @author Gernot Belger
+ */
+final class FlowDepthMinMaxCalculationResult extends AbstractSInfoCalculationResult {
+
+ private static final long serialVersionUID = 1L;
+
+ private final BedHeightInfo minSounding;
+
+ private final BedHeightInfo maxSounding;
+
+ public FlowDepthMinMaxCalculationResult(final String label, final WstInfo wst, final BedHeightInfo minSounding, final BedHeightInfo maxSounding,
+ final Collection rows) {
+ super(label, wst, rows);
+
+ this.minSounding = minSounding;
+ this.maxSounding = maxSounding;
+ }
+
+ public BedHeightInfo getMinSounding() {
+ return this.minSounding;
+ }
+
+ public BedHeightInfo getMaxSounding() {
+ return this.maxSounding;
+ }
+
+ public BedHeightInfo getAnySounding() {
+ if (this.minSounding != null)
+ return this.minSounding;
+
+ return this.maxSounding;
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResults.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculationResults.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,26 @@
+/** 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.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 FlowDepthMinMaxCalculationResults extends AbstractSInfoCalculationResults {
+
+ private static final long serialVersionUID = 1L;
+
+ public FlowDepthMinMaxCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) {
+ super(calcModeLabel, user, river, calcRange);
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxExporter.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxExporter.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,179 @@
+/* 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.flowdepthminmax;
+
+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.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;
+
+/**
+ * Generates different output formats (csv, pdf) of data that resulted from a flow depths computation.
+ *
+ * @author Ingo Weinzierl
+ * @author Gernot Belger
+ */
+// REMARK: must be public because its registered in generators.xml
+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";
+
+ @Override
+ protected Logger getLog() {
+ return log;
+ }
+
+ @Override
+ protected void writeCSVResultMetadata(final CSVWriter writer, final FlowDepthMinMaxCalculationResults results,
+ final FlowDepthMinMaxCalculationResult result) {
+
+ final BedHeightInfo sounding = result.getAnySounding();
+ super.writeCSVSoundingMetadata(writer, sounding);
+
+ final WstInfo wst = result.getWst();
+ writeCSVWaterlevelMetadata(writer, wst);
+ }
+
+ @Override
+ protected void writeCSVGlobalMetadata(final CSVWriter writer, final FlowDepthMinMaxCalculationResults results) {
+
+ super.writeCSVGlobalMetadataDefaults(writer, results);
+
+ writer.writeNext(new String[] { "" });
+ }
+
+ /**
+ * 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 FlowDepthMinMaxCalculationResults 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_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));
+
+ writer.writeNext(header.toArray(new String[header.size()]));
+ }
+
+ @Override
+ protected String[] formatCSVRow(final FlowDepthMinMaxCalculationResults results, final FlowDepthMinMaxRow row) {
+ return formatFlowDepthRow(row);
+ }
+
+ /**
+ * Format a row of a flow depth result into an array of string, both used by csv and pdf
+ *
+ * @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()));
+
+ // 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());
+
+ return lines.toArray(new String[lines.size()]);
+ }
+
+ @Override
+ protected final String getJasperFile() {
+ return JASPER_FILE;
+ }
+
+ @Override
+ protected final void addJRMetaData(final MetaAndTableJRDataSource source, final FlowDepthMinMaxCalculationResults results) {
+
+ /* general metadata */
+ 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));
+ }
+
+ @Override
+ protected String[] formatPDFRow(final FlowDepthMinMaxCalculationResults results, final FlowDepthMinMaxRow row) {
+ return formatFlowDepthRow(row);
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxRow.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxRow.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,81 @@
+/* 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 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxState.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxState.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,109 @@
+/* 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.flowdepthminmax;
+
+import java.util.List;
+
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.ChartArtifact;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.Calculation;
+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.model.ReportFacet;
+import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.states.DefaultState;
+
+/** State in which a waterlevel has been calculated. */
+public class FlowDepthMinMaxState extends DefaultState {
+
+ /// ** The log that is used in this state. */
+ // private static Logger log = Logger.getLogger(FlowDepthState.class);
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * From this state can only be continued trivially.
+ */
+ @Override
+ protected String getUIProvider() {
+ return "continue";
+ }
+
+ @Override
+ public Object computeFeed(final D4EArtifact artifact, final String hash, final CallContext context, final List facets, final Object old) {
+ // FIXME: why is this necessary?
+ if (artifact instanceof ChartArtifact) {
+ facets.add(new EmptyFacet());
+ return null;
+ }
+
+ return compute((SINFOArtifact) artifact, context, hash, facets, old);
+ }
+
+ @Override
+ public Object computeAdvance(final D4EArtifact artifact, final String hash, final CallContext context, final List facets, final Object old) {
+ if (artifact instanceof ChartArtifact) {
+ facets.add(new EmptyFacet());
+ return null;
+ }
+ return compute((SINFOArtifact) artifact, context, hash, facets, old);
+ }
+
+ /**
+ * Compute result or returned object from cache, create facets.
+ *
+ * @param old
+ * Object that was cached.
+ */
+ private Object compute(final SINFOArtifact sinfo, final CallContext context, final String hash, final List facets, final Object old) {
+
+ final CalculationResult res = doCompute(sinfo, context, old);
+
+ if (facets == null)
+ return res;
+
+ final FlowDepthMinMaxCalculationResults results = (FlowDepthMinMaxCalculationResults) res.getData();
+
+ /* add themes for chart, for each result */
+ final List resultList = results.getResults();
+ for (int index = 0; index < resultList.size(); index++) {
+
+ final FlowDepthMinMaxCalculationResult result = resultList.get(index);
+
+ /* filtered (zoom dependent mean) flow depth */
+ // facets.add(FlowDepthProcessor.createFlowDepthFacet(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())
+ facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
+
+ return res;
+ }
+
+ private CalculationResult doCompute(final SINFOArtifact sinfo, final CallContext context, final Object old) {
+ if (old instanceof CalculationResult)
+ return (CalculationResult) old;
+
+ return new FlowDepthMinMaxCalculation(context).calculate(sinfo);
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/DischargeValuesFinder.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/DischargeValuesFinder.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/DischargeValuesFinder.java Tue Mar 13 18:49:33 2018 +0100
@@ -46,14 +46,20 @@
public DischargeValuesFinder(final QKms qKms) {
this.qKms = qKms;
- this.qInterpolator = qKms == null ? null : DoubleUtil.getLinearInterpolator(qKms.allKms(), qKms.allQs());
-
- this.exactValues = new TDoubleDoubleHashMap(qKms.size());
- for (int i = 0; i < qKms.size(); i++) {
- final double station = qKms.getKm(i);
- final double discharge = qKms.getQ(i);
- this.exactValues.put(station, discharge);
+ if (qKms == null) {
+ this.qInterpolator = null;
+ this.exactValues = null;
+ } else {
+ this.qInterpolator = DoubleUtil.getLinearInterpolator(qKms.allKms(), qKms.allQs());
+
+ this.exactValues = new TDoubleDoubleHashMap(qKms.size());
+
+ for (int i = 0; i < qKms.size(); i++) {
+ final double station = qKms.getKm(i);
+ final double discharge = qKms.getQ(i);
+ this.exactValues.put(station, discharge);
+ }
}
}
@@ -68,14 +74,23 @@
return new DoubleRange(this.qKms.allQs().min(), this.qKms.allQs().max());
}
- public double getDischarge(final double station) throws FunctionEvaluationException {
+ public double getDischarge(final double station) {
- // IMPORTANT: we first try to retreive the exact value if it is present, to avoid rounding changes due to interpolation.
- // This is important because in the WaterlevelExporter code, these values are double-compared (with '==' ...) in order
- // to find the corresponding main-value.
- if (this.exactValues.contains(station))
- return this.exactValues.get(station);
+ try {
+ // IMPORTANT: we first try to retrieve the exact value if it is present, to avoid rounding changes due to interpolation.
+ // This is important because in the WaterlevelExporter code, these values are double-compared (with '==' ...) in order
+ // to find the corresponding main-value.
+ if (this.exactValues != null && this.exactValues.contains(station))
+ return this.exactValues.get(station);
- return this.qInterpolator.value(station);
+ if (this.qInterpolator == null)
+ return Double.NaN;
+
+ return this.qInterpolator.value(station);
+ }
+ catch (final FunctionEvaluationException e) {
+ e.printStackTrace();
+ return Double.NaN;
+ }
}
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java Tue Mar 13 18:49:33 2018 +0100
@@ -11,7 +11,6 @@
import org.apache.commons.lang.math.DoubleRange;
import org.apache.commons.math.ArgumentOutsideDomainException;
-import org.apache.commons.math.FunctionEvaluationException;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.resources.Resources;
@@ -37,30 +36,33 @@
private final BedHeightsFinder bedHeightsProvider;
+ private final WaterlevelValuesFinder waterlevelProvider;
+
private final DischargeValuesFinder dischargeProvider;
private final FlowVelocityModelKmValueFinder flowVelocitiesFinder;
public static TkhCalculator buildTkhCalculator(final boolean useTkh, final CallContext context, final Calculation problems, final String label,
- final River river, final DoubleRange calcRange, final DischargeValuesFinder dischargeProvider, final BedHeightsFinder bedHeightsProvider) {
+ final River river, final DoubleRange calcRange, final WaterlevelValuesFinder waterlevelProvider, final DischargeValuesFinder dischargeProvider,
+ final BedHeightsFinder bedHeightsProvider) {
if (!useTkh)
- return null;
+ return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
if (!dischargeProvider.isValid()) {
final String message = Resources.getMsg(context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, label);
problems.addProblem(message);
- return null;
+ return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
}
- final Integer soundingYear = bedHeightsProvider.getInfo().getYear();
+ final int soundingYear = bedHeightsProvider.getInfo().getYear();
final BedQualityD50KmValueFinder bedMeasurementsFinder = BedQualityD50KmValueFinder.loadBedMeasurements(river, calcRange, soundingYear,
VALID_BED_MEASUREMENT_YEARS);
if (bedMeasurementsFinder == null) {
final String message = Resources.getMsg(context.getMeta(), "sinfo_calc_flow_depth.warning.missingD50", null, label);
problems.addProblem(message);
- return null;
+ return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
}
// FIXME: wie wird ggf. interpoliert? prüfung ob werte vorhanden?
@@ -68,7 +70,7 @@
if (soilKindFinder == null) {
final String message = Resources.getMsg(context.getMeta(), "sinfo_calc_flow_depth.warning.missingSoilKind", null, label);
problems.addProblem(message);
- return null;
+ return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
}
final DoubleRange qRange = dischargeProvider.getRange();
@@ -76,35 +78,43 @@
if (flowVelocitiesFinder == null) {
final String message = Resources.getMsg(context.getMeta(), "sinfo_calc_flow_depth.warning.missingVelocity", null, label);
problems.addProblem(message);
- return null;
+ return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
}
- return new TkhCalculator(problems, label, context, bedMeasurementsFinder, dischargeProvider, bedHeightsProvider, soilKindFinder, flowVelocitiesFinder);
+ return new TkhCalculator(problems, label, context, bedMeasurementsFinder, waterlevelProvider, dischargeProvider, bedHeightsProvider, soilKindFinder,
+ flowVelocitiesFinder);
}
private TkhCalculator(final Calculation problems, final String problemLabel, final CallContext context,
- final BedQualityD50KmValueFinder bedMeasurementsFinder, final DischargeValuesFinder dischargeProvider, final BedHeightsFinder bedHeightsProvider,
- final SoilKindKmValueFinder soilKindFinder,
+ final BedQualityD50KmValueFinder bedMeasurementsFinder, final WaterlevelValuesFinder waterlevelProvider,
+ final DischargeValuesFinder dischargeProvider, final BedHeightsFinder bedHeightsProvider, final SoilKindKmValueFinder soilKindFinder,
final FlowVelocityModelKmValueFinder flowVelocitiesFinder) {
this.problems = problems;
this.problemLabel = problemLabel;
this.context = context;
this.bedMeasurementsFinder = bedMeasurementsFinder;
+ this.waterlevelProvider = waterlevelProvider;
this.dischargeProvider = dischargeProvider;
this.bedHeightsProvider = bedHeightsProvider;
this.soilKindFinder = soilKindFinder;
this.flowVelocitiesFinder = flowVelocitiesFinder;
}
- private double getDischarge(final double km) {
+ public boolean hasTkh() {
- try {
- return this.dischargeProvider.getDischarge(km);
- }
- catch (final FunctionEvaluationException e) {
- // TODO: exceptions nicht komplett schlucken? evtl. mit log.debug(e) ausgeben
- return Double.NaN;
- }
+ if (this.dischargeProvider == null || !this.dischargeProvider.isValid())
+ return false;
+
+ if (this.bedMeasurementsFinder == null)
+ return false;
+
+ if (this.soilKindFinder == null)
+ return false;
+
+ if (this.flowVelocitiesFinder == null)
+ return false;
+
+ return true;
}
private SoilKind getSoilKind(final double km) {
@@ -134,26 +144,22 @@
}
}
- public Tkh getTkh(final double km, final double wst) {
+ public Tkh getTkh(final double km) {
final SoilKind kind = getSoilKind(km);
+ final double wst = this.waterlevelProvider.getWaterlevel(km);
+
final double meanBedHeight = this.bedHeightsProvider.getMeanBedHeight(km);
final double flowDepth = wst - meanBedHeight;
- final double discharge = getDischarge(km);
- if (Double.isNaN(discharge)) {
+ final double discharge = this.dischargeProvider.getDischarge(km);
+ if (Double.isNaN(discharge))
+ return new Tkh(km, wst, meanBedHeight, flowDepth, Double.NaN, kind);
- // final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null,
- // this.problemLabel);
- // this.problems.addProblem(km, message);
-
- // TODO: nochmal gemeinsam überlegen welche probleme wir loggen, an dieser stelle müsste man ggf. die station
- // mitausgeben
-
+ if (!this.hasTkh())
return new Tkh(km, wst, meanBedHeight, flowDepth, Double.NaN, kind);
- }
final double d50 = getBedMeasurement(km);
if (Double.isNaN(d50))
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/WaterlevelValuesFinder.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/WaterlevelValuesFinder.java Tue Mar 13 18:49:33 2018 +0100
@@ -0,0 +1,43 @@
+/** 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.tkhcalculation;
+
+import org.apache.commons.math.ArgumentOutsideDomainException;
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.utils.DoubleUtil;
+
+/**
+ * Abstraction for access to waterlevels by station.
+ *
+ * @author Gernot Belger
+ */
+public class WaterlevelValuesFinder {
+
+ public static WaterlevelValuesFinder fromKms(final WKms wkms) {
+ return new WaterlevelValuesFinder(wkms);
+ }
+
+ private final PolynomialSplineFunction wstInterpolator;
+
+ private WaterlevelValuesFinder(final WKms wkms) {
+ this.wstInterpolator = DoubleUtil.getLinearInterpolator(wkms.allKms(), wkms.allWs());
+ }
+
+ public double getWaterlevel(final double km) {
+ try {
+ return this.wstInterpolator.value(km);
+ }
+ catch (final ArgumentOutsideDomainException e) {
+ e.printStackTrace();
+ return Double.NaN;
+ }
+ }
+}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedHeightsFinder.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedHeightsFinder.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedHeightsFinder.java Tue Mar 13 18:49:33 2018 +0100
@@ -17,10 +17,14 @@
import java.util.TreeMap;
import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.BedHeightsArtifact;
import org.dive4elements.river.artifacts.math.Linear;
+import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo;
import org.dive4elements.river.model.BedHeight;
import org.dive4elements.river.model.BedHeightValue;
+import org.dive4elements.river.utils.RiverUtils;
/**
* Provides bed heigts for vcarious calculations.
@@ -47,12 +51,47 @@
return result;
}
+ public static BedHeightsFinder forId(final CallContext context, final String soundingId, final DoubleRange calcRange, final Calculation problems) {
+
+ // REMARK: absolutely unbelievable....
+ // The way how bed-heights (and other data too) is accessed is different for nearly every calculation-type
+ // throughout flys.
+ // The knowledge on how to parse the datacage-ids is spread through the complete code-base...
+
+ // We use here the way on how bed-heights are accessed by the BedDifferenceAccess/BedDifferenceCalculation, but
+ // this is plain random
+ final String[] parts = soundingId.split(";");
+
+ final BedHeightsArtifact artifact = (BedHeightsArtifact) RiverUtils.getArtifact(parts[0], context);
+
+ final Integer bedheightId = artifact.getDataAsInteger("height_id");
+
+ // REMARK: this only works with type 'single'; unclear on how to distinguish from epoch data (or whatever the
+ // other type means)
+ // Luckily, the requirement is to only access 'single' data here.
+ // final String bedheightType = artifact.getDataAsString("type");
+
+ // REMARK: BedDifferences uses this, but we also need the metadata of the BedHeight
+ // REMARK: second absolutely awful thing: BedHeight is a hibernate binding class, accessing the database via
+ // hibernate stuff
+ // BedHeightFactory uses its own (direct) way of accessing the data, with its own implemented data classes.
+ // return BedHeightFactory.getHeight(bedheightType, bedheightId, from, to);
+
+ final BedHeightsFinder bedHeight = bedheightId == null ? null : BedHeightsFinder.forId(bedheightId, calcRange);
+ if (bedHeight != null)
+ return bedHeight;
+
+ // FIXME: 10n
+ problems.addProblem("Failed to access sounding with id '{0}'", soundingId);
+ return null;
+ }
+
/**
* Creates a {@link BedHeightsFinder} for a dataset from the database, specified by its id.
*
* @return null
if no bed height with the given id exists.
*/
- public static BedHeightsFinder forId(final int id, final DoubleRange range) {
+ private static BedHeightsFinder forId(final int id, final DoubleRange range) {
final BedHeight bedHeight = BedHeight.getBedHeightById(id);
if (bedHeight == null)
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java Tue Mar 13 18:49:33 2018 +0100
@@ -31,6 +31,7 @@
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;
import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
@@ -143,14 +144,13 @@
for (int i = 0; i < size; i++) {
final double station = wkms.getKm(i);
- final double wst = wkms.getW(i);
/* find the right calculator (i.e. bedheigh) depending on station, there should only be one maximal */
final TkhCalculator tkhCalculator = findCalculator(calculatorsByRanges, station);
if (tkhCalculator == null)
continue;
- final Tkh tkh = tkhCalculator.getTkh(station, wst);
+ final Tkh tkh = tkhCalculator.getTkh(station);
final String description = descBuilder.getDesc(wkms);
final String gaugeLabel = riverInfoProvider.findGauge(station);
@@ -185,11 +185,12 @@
final NumberRange range = new NumberRange(info.getFrom(), info.getTo());
+ final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(wkms);
final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wkms);
/* initialize tkh calculator */
final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(true, this.context, problems, wstLabel, riverInfoProvider.getRiver(),
- calcRange, dischargeProvider, bedHeightsProvider);
+ calcRange, waterlevelProvider, dischargeProvider, bedHeightsProvider);
if (tkhCalculator != null) {
/* just ignore null ones, problems have already been updated by buildTkhCalculator() */
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResult.java Tue Mar 13 18:49:33 2018 +0100
@@ -11,7 +11,7 @@
import java.util.Collection;
-import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResult;
+import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhCalculationResult;
import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
/**
@@ -19,7 +19,7 @@
*
* @author Gernot Belger
*/
-final class TkhCalculationResult extends AbstractSInfoCalculationResult {
+final class TkhCalculationResult extends AbstractTkhCalculationResult {
private static final long serialVersionUID = 1L;
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhExporter.java Tue Mar 13 18:49:33 2018 +0100
@@ -8,17 +8,10 @@
package org.dive4elements.river.artifacts.sinfo.tkhstate;
-import java.text.DateFormat;
-import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Date;
-import java.util.Locale;
-import org.apache.commons.lang.math.DoubleRange;
import org.apache.log4j.Logger;
-import org.dive4elements.river.FLYS;
-import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.artifacts.sinfo.SInfoI18NStrings;
import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter;
import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource;
@@ -64,31 +57,7 @@
protected void writeCSVGlobalMetadata(final CSVWriter writer, final TkhCalculationResults results) {
log.info("TkhExporter.writeCSVMeta");
- final String calcModeLabel = results.getCalcModeLabel();
- final RiverInfo river = results.getRiver();
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_RESULT, msg(SInfoI18NStrings.CSV_META_HEADER_RESULT_LABEL), river.getName(), calcModeLabel);
-
- // "# FLYS-Version: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_VERSION, msg(SInfoI18NStrings.CSV_META_VERSION_LABEL), FLYS.VERSION);
-
- // "# Bearbeiter: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_USER, msg(SInfoI18NStrings.CSV_META_USER_LABEL), results.getUser());
-
- // "# Datum der Erstellung: "
- final Locale locale = Resources.getLocale(this.context.getMeta());
- final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_CREATION, msg(SInfoI18NStrings.CSV_META_CREATION_LABEL), df.format(new Date()));
-
- // "# Gewässer: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_RIVER, msg(SInfoI18NStrings.CSV_META_RIVER_LABEL), river.getName());
-
- // "# Höhensystem des Flusses: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEIGHT_UNIT_RIVER, river.getWstUnit());
-
- // "# Ort/Bereich (km): "
- final DoubleRange calcRange = results.getCalcRange();
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_RANGE, msg(SInfoI18NStrings.CSV_META_RANGE_LABEL),
- getKmFormatter().format(calcRange.getMinimumDouble()), getKmFormatter().format(calcRange.getMaximumDouble()));
+ super.writeCSVGlobalMetadataDefaults(writer, results);
// "# Berechnungsgrundlage: Gleichung nach GILL (1971)"
writeCSVMetaEntry(writer, CSV_META_CALCULATION_FORMULA);
@@ -128,17 +97,12 @@
// FIXME: rename
protected void writeCSVResultMetadata(final CSVWriter writer, final TkhCalculationResults results, final TkhCalculationResult result) {
- /* first some specific metadata */
final WstInfo wst = result.getWst();
+ super.writeCSVWaterlevelMetadata(writer, wst);
- // "##METADATEN WASSERSPIEGELLAGE"
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL);
- // "# Bezeichnung der Wasserspiegellage: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_NAME, wst.getLabel());
- // "# Bezugspegel: "
- writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_GAUGE, wst.getGauge());
- // // "# Jahr/Zeitraum der Wasserspiegellage: "
- // writeCSVMetaEntry(writer, SInfoI18NStrings.CSV_META_HEADER_WATERLEVEL_YEAR, Integer.toString(wst.getYear()));
+ // TODO:
+ // "# W/Pegel [cm]: " (nur bei Eingabe des Wasserstands am Pegel)
+ // "# Q (m³/s): " (nur bei Eingabe des Durchflusses)
}
@Override
@@ -199,33 +163,8 @@
@Override
protected final void addJRMetaData(final MetaAndTableJRDataSource source, final TkhCalculationResults results) {
- final RiverInfo river = results.getRiver();
- final String wstUnitName = river.getWstUnit();
-
/* general metadata */
- source.addMetaData("header", msg(SInfoI18NStrings.CSV_META_HEADER_RESULT_LABEL));
- source.addMetaData("calcMode", results.getCalcModeLabel());
-
- source.addMetaData("version_label", msg(SInfoI18NStrings.CSV_META_VERSION_LABEL));
- source.addMetaData("version", FLYS.VERSION);
-
- source.addMetaData("user_label", msg(SInfoI18NStrings.CSV_META_USER_LABEL));
- source.addMetaData("user", results.getUser());
-
- final Locale locale = Resources.getLocale(this.context.getMeta());
- final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
- source.addMetaData("date_label", msg(SInfoI18NStrings.CSV_META_CREATION_LABEL));
- source.addMetaData("date", df.format(new Date()));
-
- source.addMetaData("river_label", msg(SInfoI18NStrings.CSV_META_RIVER_LABEL));
- source.addMetaData("river", river.getName());
- source.addMetaData("river_unit", wstUnitName);
-
- final DoubleRange calcRange = results.getCalcRange();
- final NumberFormat kmFormatter = getKmFormatter();
- final String rangeValue = String.format("%s - %s", kmFormatter.format(calcRange.getMinimumDouble()), kmFormatter.format(calcRange.getMaximumDouble()));
- source.addMetaData("range_label", msg(SInfoI18NStrings.CSV_META_RANGE_LABEL));
- source.addMetaData("range", rangeValue);
+ super.addJRMetaDataDefaults(source, results);
/* column headings */
source.addMetaData("station_header", msg(SInfoI18NStrings.CSV_KM_HEADER));
diff -r 4a6b6a3c279c -r 5d5d482da3e9 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 Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhResultRow.java Tue Mar 13 18:49:33 2018 +0100
@@ -9,13 +9,13 @@
*/
package org.dive4elements.river.artifacts.sinfo.tkhstate;
-import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoResultRow;
+import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhResultRow;
import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh;
/**
* @author Gernot Belger
*/
-final class TkhResultRow extends AbstractSInfoResultRow {
+final class TkhResultRow extends AbstractTkhResultRow {
private static final long serialVersionUID = 1L;
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/BedHeightInfo.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/BedHeightInfo.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/BedHeightInfo.java Tue Mar 13 18:49:33 2018 +0100
@@ -23,7 +23,7 @@
private static final long serialVersionUID = 1L;
- private final Integer year;
+ private final int year;
private final String description;
@@ -58,7 +58,7 @@
this.to = bedHeight.getRange().getB();
}
- public Integer getYear() {
+ public int getYear() {
return this.year;
}
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/MetaAndTableJRDataSource.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/MetaAndTableJRDataSource.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/MetaAndTableJRDataSource.java Tue Mar 13 18:49:33 2018 +0100
@@ -1,6 +1,6 @@
/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- * Björnsen Beratende Ingenieure GmbH
+ * 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)
@@ -21,16 +21,16 @@
/**
* @author Raimund Renkert
*/
-public final class MetaAndTableJRDataSource implements JRDataSource
-{
- private List data = new ArrayList<>();
+public final class MetaAndTableJRDataSource implements JRDataSource {
- private Map metaData = new HashMap<>();
+ private final List data = new ArrayList<>();
+
+ private final Map metaData = new HashMap<>();
private int index = -1;
- public void addData(final String[] data) {
- this.data.add(data);
+ public void addData(final String[] row) {
+ this.data.add(row);
}
public void addMetaData(final String key, final String value) {
@@ -38,27 +38,24 @@
}
@Override
- public boolean next() throws JRException
- {
- index++;
+ public boolean next() throws JRException {
+ this.index++;
- return index < data.size();
+ return this.index < this.data.size();
}
@Override
- public Object getFieldValue(final JRField field) throws JRException
- {
+ public Object getFieldValue(final JRField field) throws JRException {
final String fieldName = field.getName();
-
- if( fieldName.startsWith("meta:"))
- return metaData.get(fieldName.substring("meta:".length()));
- if( fieldName.startsWith("data:"))
- {
- int column = Integer.valueOf(fieldName.substring("data:".length()));
- return data.get(index)[column];
+ if (fieldName.startsWith("meta:"))
+ return this.metaData.get(fieldName.substring("meta:".length()));
+
+ if (fieldName.startsWith("data:")) {
+ final int column = Integer.valueOf(fieldName.substring("data:".length()));
+ return this.data.get(this.index)[column];
}
-
+
return null;
}
}
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/states/WaterlevelFetcher.java Tue Mar 13 18:49:33 2018 +0100
@@ -19,6 +19,7 @@
import org.dive4elements.river.artifacts.StaticWQKmsArtifact;
import org.dive4elements.river.artifacts.WINFOArtifact;
import org.dive4elements.river.artifacts.access.FixRealizingAccess;
+import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.Segment;
import org.dive4elements.river.artifacts.model.WKms;
@@ -39,7 +40,7 @@
private static Logger log = Logger.getLogger(WaterlevelFetcher.class);
public WaterlevelData findWaterlevel(final CallContext context, final String mingle, final double from,
- final double to) {
+ final double to, final Calculation problems) {
final String[] def = mingle.split(";");
final String uuid = def[0];
@@ -48,7 +49,11 @@
final D4EArtifact d4eArtifact = RiverUtils.getArtifact(uuid, context);
final WaterlevelData data = fetchWaterlevelFromArtifact(context, d4eArtifact, idx, from, to);
- return data.withName(name);
+ if (data != null)
+ return data.withName(name);
+
+ problems.addProblem("waterlevelfetcher.missing'", mingle);
+ return null;
}
private WaterlevelData fetchWaterlevelFromArtifact(final CallContext context, final D4EArtifact d4eArtifact,
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/resources/messages.properties
--- a/artifacts/src/main/resources/messages.properties Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/resources/messages.properties Tue Mar 13 18:49:33 2018 +0100
@@ -886,4 +886,11 @@
sinfo.chart.tkh_d50.section.yaxis.label = Sohlbeschaffenheit D50 [mm]
sinfo.chart.tkh_d50.yaxis.label = Sohlbeschaffenheit D50 [mm]
-sinfo.facet.tkh_d50.filtered.description = Sohlbeschaffenheit D50 ({0})
\ No newline at end of file
+sinfo.facet.tkh_d50.filtered.description = Sohlbeschaffenheit D50 ({0})
+
+sinfo.flowdepthminmaxcalculation.soundingyear.different = Die Peiljahre von Talweg und Kammlage untersheiden sich
+
+sinfo.export.flow_depth_minmax.csv.header.min = Minimale Flie\u00dftiefe
+sinfo.export.flow_depth_minmax.csv.header.max = Maximale Flie\u00dftiefe
+
+waterlevelfetcher.missing = Failed to access waterlevel with id '{0}'
\ No newline at end of file
diff -r 4a6b6a3c279c -r 5d5d482da3e9 artifacts/src/main/resources/messages_de.properties
--- a/artifacts/src/main/resources/messages_de.properties Tue Mar 13 09:55:53 2018 +0100
+++ b/artifacts/src/main/resources/messages_de.properties Tue Mar 13 18:49:33 2018 +0100
@@ -886,4 +886,11 @@
sinfo.chart.tkh_d50.section.yaxis.label = Sohlbeschaffenheit D50 [mm]
sinfo.chart.tkh_d50.yaxis.label = Sohlbeschaffenheit D50 [mm]
-sinfo.facet.tkh_d50.filtered.description = Sohlbeschaffenheit D50 ({0})
\ No newline at end of file
+sinfo.facet.tkh_d50.filtered.description = Sohlbeschaffenheit D50 ({0})
+
+sinfo.flowdepthminmaxcalculation.soundingyear.different = Die Peiljahre von Talweg und Kammlage untersheiden sich
+
+sinfo.export.flow_depth_minmax.csv.header.min = Minimale Flie\u00dftiefe
+sinfo.export.flow_depth_minmax.csv.header.max = Maximale Flie\u00dftiefe
+
+waterlevelfetcher.missing = Fehler beim Zugriff auf Wasserspiegel mit id '{0}'
\ No newline at end of file