# HG changeset patch
# User mschaefer
# Date 1529947271 -7200
# Node ID 1614cb14308f380b72e4d8026f9b1a35cf6591ff
# Parent 34dc0163ad2d3d1829a38be51cd6c6f506081576
Work on calculations for S-Info flood duration workflow
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/doc/conf/artifacts/manualpoints.xml
--- a/artifacts/doc/conf/artifacts/manualpoints.xml Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/doc/conf/artifacts/manualpoints.xml Mon Jun 25 19:21:11 2018 +0200
@@ -42,6 +42,7 @@
+
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/doc/conf/artifacts/sinfo.xml
--- a/artifacts/doc/conf/artifacts/sinfo.xml Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/doc/conf/artifacts/sinfo.xml Mon Jun 25 19:21:11 2018 +0200
@@ -335,8 +335,6 @@
-
-
@@ -359,7 +357,29 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml
--- a/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml Mon Jun 25 19:21:11 2018 +0200
@@ -19,6 +19,7 @@
+
@@ -57,6 +58,7 @@
+
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/doc/conf/generators/longitudinal-diagrams.xml
--- a/artifacts/doc/conf/generators/longitudinal-diagrams.xml Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/doc/conf/generators/longitudinal-diagrams.xml Mon Jun 25 19:21:11 2018 +0200
@@ -165,5 +165,18 @@
+
+
+
+ &longitudinal-defaults;
+
+
+
+
+
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/doc/conf/meta-data.xml
--- a/artifacts/doc/conf/meta-data.xml Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/doc/conf/meta-data.xml Mon Jun 25 19:21:11 2018 +0200
@@ -136,6 +136,15 @@
+
+
+
+
+
+
+
+
+
@@ -303,6 +312,15 @@
+
+
+
+
+
+
+
+
+
@@ -1653,6 +1671,7 @@
+
WINFO/DIFF/FIX
@@ -3414,6 +3433,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/doc/conf/themes.xml
--- a/artifacts/doc/conf/themes.xml Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/doc/conf/themes.xml Mon Jun 25 19:21:11 2018 +0200
@@ -442,6 +442,7 @@
+
@@ -458,5 +459,6 @@
+
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/doc/conf/themes/default.xml
--- a/artifacts/doc/conf/themes/default.xml Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/doc/conf/themes/default.xml Mon Jun 25 19:21:11 2018 +0200
@@ -3063,4 +3063,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/doc/conf/themes/second.xml
--- a/artifacts/doc/conf/themes/second.xml Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/doc/conf/themes/second.xml Mon Jun 25 19:21:11 2018 +0200
@@ -3050,4 +3050,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractResultType.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractResultType.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractResultType.java Mon Jun 25 19:21:11 2018 +0200
@@ -86,14 +86,14 @@
return this.formatters.get(locale);
}
+ protected abstract NumberFormat createFormatter(CallContext context);
+
protected final String exportDateValue(final CallContext context, final Date value) {
final Locale locale = Resources.getLocale(context.getMeta());
final DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
return df.format(value);
}
- protected abstract NumberFormat createFormatter(CallContext context);
-
@Override
public final String getCsvHeader() {
return this.csvHeader;
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcDetailResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcDetailResult.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcDetailResult.java Mon Jun 25 19:21:11 2018 +0200
@@ -45,16 +45,16 @@
final int colSize = 6;
exportContextCSV.writeTitleForTabs("sinfo.export.csv.title.collision.detail", 6); // Voraussetzung für Tabs ist, dass der Titel vor den Headern
- // geschrieben wird.
+ // geschrieben wird.
// Das ist etwas doof.
final Collection header = new ArrayList<>(colSize);
header.add(exportContextCSV.formatCsvHeader(GeneralResultType.station));
header.add(exportContextCSV.formatCsvHeader(GeneralResultType.date));
- header.add(exportContextCSV.formatCsvHeader(SInfoResultType.collisionGaugeW));
+ header.add(exportContextCSV.msgUnitCSV(SInfoResultType.collisionGaugeW, SInfoResultType.collisionGaugeW.getUnit()));
header.add(exportContextCSV.formatCsvHeader(SInfoResultType.gaugeLabel));
- header.add(exportContextCSV.msgUnitCSV(SInfoResultType.discharge));
+ header.add(exportContextCSV.msgUnitCSV(SInfoResultType.discharge, SInfoResultType.discharge.getUnit()));
header.add(exportContextCSV.formatCsvHeader(SInfoResultType.dischargeZone));
exportContextCSV.writeCSVLine(header.toArray(new String[colSize]));
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java Mon Jun 25 19:21:11 2018 +0200
@@ -23,12 +23,15 @@
import org.dive4elements.river.artifacts.model.DateRange;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.sinfo.common.GaugeDischargeValuesFinder;
+import org.dive4elements.river.artifacts.sinfo.common.GaugeMainValueNameFinder;
import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
import org.dive4elements.river.backend.utils.DateUtil;
import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
import org.dive4elements.river.model.River;
import org.dive4elements.river.model.sinfo.CollisionAggregateValue;
import org.dive4elements.river.model.sinfo.CollisionValue;
@@ -77,10 +80,10 @@
// create q-for-w-finders for all gauges of the calculation km range
final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange);
final Map qFinders = new HashMap<>();
- final Map zoneFinders = new HashMap<>();
+ final Map zoneFinders = new HashMap<>();
for (final Gauge gauge : river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble())) {
qFinders.put(gauge, GaugeDischargeValuesFinder.loadValues(gauge, problems));
- zoneFinders.put(gauge, GaugeDischargeZoneFinder.loadValues(gauge, problems));
+ zoneFinders.put(gauge, GaugeMainValueNameFinder.loadValues(MainValueTypeKey.Q, gauge, problems));
}
final Collection detailsRows = new ArrayList<>();
@@ -118,7 +121,7 @@
*/
private void calculateDetails(final Collection rows, final RiverInfoProvider riverInfo, final double fromKm, final double toKm,
final int fromYear, final int toYear, final Map qFinders,
- final Map zoneFinders) {
+ final Map zoneFinders) {
for (final CollisionValue collision : CollisionValue.getValues(riverInfo.getRiver(), fromKm, toKm, DateUtil.getStartDateFromYear(fromYear),
DateUtil.getEndDateFromYear(toYear))) {
final Gauge gauge = riverInfo.getGauge(collision.getStation(), true);
@@ -129,7 +132,7 @@
.putValue(SInfoResultType.collisionGaugeW, collision.getGaugeW())
.putValue(SInfoResultType.gaugeLabel, collision.getGaugeName())
.putValue(SInfoResultType.discharge, qOut)
- .putValue(SInfoResultType.dischargeZone, zoneFinders.get(gauge).getDischargeZone(q)));
+ .putValue(SInfoResultType.dischargeZone, zoneFinders.get(gauge).getZoneName(q)));
}
}
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FloodDurationProcessor.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FloodDurationProcessor.java Mon Jun 25 19:21:11 2018 +0200
@@ -0,0 +1,73 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.common;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+
+/**
+ * Processor to generate the facet and data series of infrastructure flood durations
+ *
+ * @author Matthias Schäfer
+ *
+ */
+public final class FloodDurationProcessor extends AbstractSInfoLineProcessor {
+
+ public static final String FACET_FLOOD_DURATION = "sinfo_facet_flood_duration";
+
+ public static final String FACET_FLOOD_DURATION_DESCRIPTION = "sinfo_facet_flood_duration.description";
+
+ public static final String FACET_MAIN_VALUE_1_DURATION = "mainvalue.1.duration";
+
+ public static final String FACET_MAIN_VALUE_DURATION_DESCRIPTION = "mainvalue.duration.description";
+
+ private static final String I18N_AXIS_LABEL = "sinfo.chart.flood_duration.section.yaxis.label";
+
+ private static final Set HANDLED_FACET_TYPES = new HashSet<>();
+
+ static {
+ HANDLED_FACET_TYPES.add(FACET_FLOOD_DURATION);
+ HANDLED_FACET_TYPES.add(FACET_MAIN_VALUE_1_DURATION);
+ }
+
+ public FloodDurationProcessor() {
+ super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES);
+ }
+
+
+ @Override
+ protected double[][] doGetPoints(final AbstractCalculationResult data, final String facetName) {
+ if (FACET_FLOOD_DURATION.contentEquals(facetName))
+ return data.getStationPoints(SInfoResultType.floodDuration);
+
+ if (FACET_MAIN_VALUE_1_DURATION.contentEquals(facetName))
+ return data.getStationPoints(SInfoResultType.mainValue1Duration);
+
+ final String error = String.format("Unknown facet name: %s", facetName);
+ throw new UnsupportedOperationException(error);
+ }
+
+ public static Facet createFloodDurationFacet(final CallContext context, final String hash, final String id,
+ final AbstractCalculationResult result, final int index) {
+ return AbstractSInfoLineProcessor.createFacet(context, hash, id, result, index, I18N_AXIS_LABEL,
+ FACET_MAIN_VALUE_1_DURATION, FACET_MAIN_VALUE_DURATION_DESCRIPTION);
+ }
+
+ public static Facet createMainValueDurationFacet(final CallContext context, final String hash, final String id,
+ final AbstractCalculationResult result, final int index) {
+ return AbstractSInfoLineProcessor.createFacet(context, hash, id, result, index, I18N_AXIS_LABEL,
+ FACET_FLOOD_DURATION, FACET_FLOOD_DURATION_DESCRIPTION);
+ }
+}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDischargeValuesFinder.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDischargeValuesFinder.java Mon Jun 25 19:21:11 2018 +0200
@@ -0,0 +1,118 @@
+/** 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.apache.commons.lang.math.DoubleRange;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.interpolation.LinearInterpolator;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.model.DischargeTable;
+import org.dive4elements.river.model.DischargeTableValue;
+import org.dive4elements.river.model.Gauge;
+
+import gnu.trove.TDoubleArrayList;
+
+/**
+ * Loading and search/interpolation of a gauge's discharge table (.at)
+ *
+ * @author Matthias Schäfer
+ *
+ */
+public final class GaugeDischargeValuesFinder {
+
+ /***** FIELDS *****/
+
+ // private static Logger log = Logger.getLogger(GaugeDischargeValuesFinder.class);
+
+ private final Gauge gauge;
+
+ private Calculation problems;
+
+ private final UnivariateRealFunction wInterpolator;
+
+ private final DoubleRange wRange;
+
+
+ /***** CONSTRUCTORS *****/
+
+ private GaugeDischargeValuesFinder(final Gauge gauge, final Calculation problems, final DischargeTable dischargeTable) {
+ this.gauge = gauge;
+ this.problems = problems;
+ final TDoubleArrayList ws = new TDoubleArrayList();
+ final TDoubleArrayList qs = new TDoubleArrayList();
+ for (final DischargeTableValue v : DischargeTable.getValuesSortedByW(dischargeTable)) {
+ ws.add(v.getW().doubleValue());
+ qs.add(v.getQ().doubleValue());
+ }
+ if (ws.size() >= 2) {
+ this.wInterpolator = new LinearInterpolator().interpolate(ws.toNativeArray(), qs.toNativeArray());
+ this.wRange = new DoubleRange(ws.get(0), ws.get(ws.size() - 1));
+ }
+ else {
+ this.wInterpolator = null;
+ this.wRange = null;
+ }
+ if ((this.wInterpolator == null) && (this.problems != null)) {
+ this.problems.addProblem("gauge_discharge_table.missing", gauge.getName());
+ // Report only once
+ this.problems = null;
+ }
+ }
+
+
+ /***** METHODS *****/
+
+ /**
+ * Loads the the main discharge table of a gauge (GAUGE.at)
+ *
+ * @return The discharge table values finder of the gauge, or null
+ */
+ public static GaugeDischargeValuesFinder loadValues(final Gauge gauge, final Calculation problems) {
+ final DischargeTable table = DischargeTable.getGaugeMainDischargeTable(gauge);
+ if ((table == null) || (table.getDischargeTableValues().size() == 0)) {
+ problems.addProblem("gauge_discharge_table.missing", gauge.getName());
+ return null;
+ }
+ else
+ return new GaugeDischargeValuesFinder(gauge, problems, table);
+ }
+
+ /**
+ * If this provider may return valid data at all.
+ */
+ public boolean isValid() {
+ return (this.wInterpolator != null);
+ }
+
+ /**
+ * Discharge for a W
+ *
+ * @param w
+ * W in cm above gauge datum
+ * @return Q, or NegInf for w less than all, or PosInf for w greater then all, or NaN in case of exception
+ */
+ public double getDischarge(final double w) {
+ try {
+ if (this.wInterpolator == null)
+ return Double.NaN;
+ else if (w < this.wRange.getMinimumDouble())
+ return Double.NEGATIVE_INFINITY;
+ else if (w > this.wRange.getMaximumDouble())
+ return Double.POSITIVE_INFINITY;
+ else
+ return this.wInterpolator.value(w);
+ }
+ catch (@SuppressWarnings("unused") final FunctionEvaluationException e) {
+ // ignore exception because this can/will happen regularly
+ return Double.NaN;
+ }
+ }
+}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDurationValuesFinder.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDurationValuesFinder.java Mon Jun 25 19:21:11 2018 +0200
@@ -0,0 +1,152 @@
+/** 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.apache.commons.lang.math.DoubleRange;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.interpolation.LinearInterpolator;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.MainValue;
+import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
+
+import gnu.trove.TDoubleArrayList;
+
+/**
+ * Loading and search/interpolate the duration main values of a gauge
+ *
+ * @author Matthias Schäfer
+ *
+ */
+public final class GaugeDurationValuesFinder {
+
+ /***** FIELDS *****/
+
+ // private static Logger log = Logger.getLogger(GaugeDurationValuesFinder.class);
+
+ private final Gauge gauge;
+
+ private Calculation problems;
+
+ private UnivariateRealFunction qInterpolator;
+
+ private DoubleRange qRange;
+
+ private UnivariateRealFunction durInterpolator;
+
+ private DoubleRange durRange;
+
+ private final String approxPrefix = "ca."; // "\u2248" geht wohl nicht
+
+
+ /***** CONSTRUCTORS *****/
+
+ private GaugeDurationValuesFinder(final Gauge gauge, final Calculation problems) {
+ this.gauge = gauge;
+ this.problems = problems;
+ final TDoubleArrayList qs = new TDoubleArrayList();
+ final TDoubleArrayList durs = new TDoubleArrayList();
+ for (final MainValue v : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.DURATION)) {
+ qs.add(v.getValue().doubleValue());
+ durs.add(Integer.valueOf(v.getMainValue().getName()).doubleValue());
+ }
+ try {
+ this.qInterpolator = new LinearInterpolator().interpolate(qs.toNativeArray(), durs.toNativeArray());
+ this.qRange = new DoubleRange(qs.get(0), qs.get(qs.size() - 1));
+ }
+ catch (final Exception e) {
+ this.qInterpolator = null;
+ this.qRange = null;
+ }
+ qs.clear();
+ durs.clear();
+ for (final MainValue v : MainValue.getDurationDischargesOfGauge(gauge)) {
+ durs.add(Integer.valueOf(v.getMainValue().getName()).doubleValue());
+ qs.add(v.getValue().doubleValue());
+ }
+ try {
+ this.durInterpolator = new LinearInterpolator().interpolate(durs.toNativeArray(), qs.toNativeArray());
+ this.durRange = new DoubleRange(durs.get(0), durs.get(durs.size() - 1));
+ }
+ catch (final Exception e) {
+ this.durInterpolator = null;
+ this.durRange = null;
+ }
+ if (((this.qInterpolator == null) || (this.durInterpolator == null)) && (this.problems != null)) {
+ this.problems.addProblem("gauge_duration.missing", gauge.getName());
+ // Report only once
+ this.problems = null;
+ }
+ }
+
+
+ /***** METHODS *****/
+
+ /**
+ * Loads the the discharge-duration table of a gauge (GAUGE.glt)
+ *
+ * @return The main values finder of a a gauge, or null
+ */
+ public static GaugeDurationValuesFinder loadValues(final Gauge gauge, final Calculation problems) {
+ return new GaugeDurationValuesFinder(gauge, problems);
+ }
+
+ /**
+ * If this provider may return valid data at all.
+ */
+ public boolean isValid() {
+ return (this.qInterpolator != null);
+ }
+
+ /**
+ * Discharge for a duration
+ *
+ * @return Q, or NegInf for duration less than all, or PosInf for duration greater then all, or NaN in case of exception
+ */
+ public double getDischarge(final int duration) {
+ try {
+ if (this.durInterpolator == null)
+ return Double.NaN;
+ else if (duration < this.durRange.getMinimumDouble())
+ return Double.NEGATIVE_INFINITY;
+ else if (duration > this.durRange.getMaximumDouble())
+ return Double.POSITIVE_INFINITY;
+ else
+ return this.durInterpolator.value(duration);
+ }
+ catch (@SuppressWarnings("unused") final FunctionEvaluationException e) {
+ // ignore exception because this can/will happen regularly
+ return Double.NaN;
+ }
+ }
+
+ /**
+ * Duration for a discharge
+ *
+ * @return duration, or 0 for Q less than all, or 365 for duration greater then all, or -1 in case of exception
+ */
+ public double getDuration(final double q) {
+ try {
+ if (this.qInterpolator == null)
+ return -1;
+ else if (q < this.qRange.getMinimumDouble())
+ return 0;
+ else if (q > this.qRange.getMaximumDouble())
+ return 365;
+ else
+ return this.qInterpolator.value(q);
+ }
+ catch (@SuppressWarnings("unused") final FunctionEvaluationException e) {
+ // ignore exception because this can/will happen regularly
+ return -1;
+ }
+ }
+}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeMainValueNameFinder.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeMainValueNameFinder.java Mon Jun 25 19:21:11 2018 +0200
@@ -0,0 +1,115 @@
+/** 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.Map.Entry;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.MainValue;
+import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
+
+/**
+ * Loading and search the main values of a gauge to find and build a name
+ *
+ * @author Matthias Schäfer
+ *
+ */
+public final class GaugeMainValueNameFinder {
+
+ /***** FIELDS *****/
+
+ // private static Logger log = Logger.getLogger(GaugeMainValueNameFinder.class);
+
+ private final Gauge gauge;
+
+ private Calculation problems;
+
+ private final NavigableMap mainValues;
+
+ private final String approxPrefix = "ca."; // "\u2248" geht wohl nicht
+
+
+ /***** CONSTRUCTORS *****/
+
+ private GaugeMainValueNameFinder(final MainValueTypeKey type, final Gauge gauge, final Calculation problems) {
+ this.gauge = gauge;
+ this.problems = problems;
+ this.mainValues = new TreeMap<>();
+ for (final MainValue mainValue : MainValue.getValuesOfGaugeAndType(gauge, type))
+ this.mainValues.put(Double.valueOf(mainValue.getValue().doubleValue()), mainValue);
+ if (this.mainValues.isEmpty() && (this.problems != null)) {
+ this.problems.addProblem("gauge_main_values.missing", gauge.getName());
+ // Report only once
+ this.problems = null;
+ }
+ }
+
+
+ /***** METHODS *****/
+
+ /**
+ * Loads the the main values table of a type and a gauge (GAUGE.glt)
+ *
+ * @return The main values finder of a type and a gauge, or null
+ */
+ public static GaugeMainValueNameFinder loadValues(final MainValueTypeKey type, final Gauge gauge, final Calculation problems) {
+ return new GaugeMainValueNameFinder(type, gauge, problems);
+ }
+
+ /**
+ * If this provider may return valid data at all.
+ */
+ public boolean isValid() {
+ return (this.mainValues != null);
+ }
+
+ /**
+ * Main value zone for a value.
+ */
+ public String getZoneName(final double value) {
+ if (!this.isValid())
+ return "";
+ if (Double.isNaN(value))
+ return "";
+
+ // Exact match
+ if (this.mainValues.containsKey(Double.valueOf(value)))
+ return this.mainValues.get(Double.valueOf(value)).getMainValue().getName();
+
+ // Clearly below or just (max. 10%) below lowest named value
+ final Entry lowerZone = this.mainValues.floorEntry(Double.valueOf(value));
+ if (lowerZone == null) {
+ if (value >= this.mainValues.firstKey().doubleValue() * 0.9)
+ return this.approxPrefix + this.mainValues.firstEntry().getValue().getMainValue().getName();
+ else
+ return "<" + this.mainValues.firstEntry().getValue().getMainValue().getName();
+ }
+
+ // Clearly above or just (max. 10%) above highest named value
+ final Entry higherZone = this.mainValues.ceilingEntry(Double.valueOf(value));
+ if (higherZone == null) {
+ if (value <= this.mainValues.lastKey().doubleValue() * 1.1)
+ return this.approxPrefix + this.mainValues.lastEntry().getValue().getMainValue().getName();
+ else
+ return ">" + this.mainValues.lastEntry().getValue().getMainValue().getName();
+ }
+
+ // Near (10%) one of the borders of a zone interval, or clearly within a zone
+ if (value <= lowerZone.getKey().doubleValue() * 1.1)
+ return this.approxPrefix + lowerZone.getValue().getMainValue().getName();
+ else if (value >= higherZone.getKey().doubleValue() * 0.9)
+ return this.approxPrefix + higherZone.getValue().getMainValue().getName();
+ else
+ return lowerZone.getValue().getMainValue().getName() + "-" + higherZone.getValue().getMainValue().getName();
+ }
+}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Mon Jun 25 19:21:11 2018 +0200
@@ -55,20 +55,14 @@
};
- public static final SInfoResultType inundationdurationq = new SInfoResultType(null, "sinfo.export.flood_duration.csv.header.inundation_duration_q",
- "sinfo.export.flood_duration.pdf.header.inundation_duration_q") {
+ public static final SInfoResultType floodDischarge = new SInfoResultType(I18NStrings.UNIT_CUBIC_M, "sinfo.export.flood_duration.csv.header.discharge",
+ "sinfo.export.flood_duration.pdf.header.discharge") {
private static final long serialVersionUID = 1L;
@Override
public String exportValue(final CallContext context, final Object value) {
final double doubleValue = asDouble(value);
- return exportDoubleValue(context, doubleValue); // integer
- // als
- // double?
- // finde
- // gerade
- // kein
- // int-beispiel
+ return exportDoubleValue(context, doubleValue);
}
@Override
@@ -77,20 +71,30 @@
}
};
- public static final SInfoResultType inundationduration = new SInfoResultType(null, "sinfo.export.flood_duration.csv.header.inundation_duration",
- "sinfo.export.flood_duration.pdf.header.inundation_duration") {
+ public static final SInfoResultType floodDuration = new SInfoResultType(null, "sinfo.export.flood_duration.csv.header.duration",
+ "sinfo.export.flood_duration.pdf.header.duration") {
private static final long serialVersionUID = 1L;
@Override
public String exportValue(final CallContext context, final Object value) {
final double doubleValue = asDouble(value);
- return exportDoubleValue(context, doubleValue); // integer
- // als
- // double?
- // finde
- // gerade
- // kein
- // int-beispiel
+ return exportDoubleValue(context, doubleValue);
+ }
+
+ @Override
+ protected NumberFormat createFormatter(final CallContext context) {
+ return Formatter.getIntegerFormatter(context);
+ }
+ };
+
+ public static final SInfoResultType mainValue1Duration = new SInfoResultType(null, "sinfo.export.main_value_1_duration.csv.header.duration",
+ "sinfo.export.main_value_1_duration.pdf.header.duration") {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public String exportValue(final CallContext context, final Object value) {
+ final double doubleValue = asDouble(value);
+ return exportDoubleValue(context, doubleValue);
}
@Override
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/WQBaseTableFinder.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/WQBaseTableFinder.java Mon Jun 25 19:21:11 2018 +0200
@@ -0,0 +1,185 @@
+/** 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.List;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.interpolation.LinearInterpolator;
+import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
+import org.dive4elements.river.artifacts.math.Linear;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.backend.SessionHolder;
+import org.dive4elements.river.model.River;
+import org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.type.StandardBasicTypes;
+
+import gnu.trove.TDoubleArrayList;
+
+/**
+ * Loading and search/interpolation of a W/Q base table of a river
+ *
+ * @author Matthias Schäfer
+ *
+ */
+public final class WQBaseTableFinder {
+
+ /***** FIELDS *****/
+
+ // private static Logger log = Logger.getLogger(WQTableFinder.class);
+
+ private final River river;
+
+ private Calculation problems;
+
+ private final List columnNames;
+
+ private final NavigableMap kmWs;
+
+ private final NavigableMap kmQs;
+
+ private static final String SQLCOLUMNS = "SELECT wc.position AS colindex, wc.name AS qzone"
+ + " FROM wsts w"
+ + " INNER JOIN wst_columns wc ON w.id=wc.wst_id"
+ + " WHERE w.river_id = :river_id"
+ + " AND w.kind = 0"
+ + " ORDER BY wc.position ASC";
+
+ private static final String SQLMAIN = "SELECT wcv.position AS station, wc.position AS colindex, wcv.w, wqr.q"
+ + " FROM wsts w"
+ + " INNER JOIN wst_columns wc ON w.id=wc.wst_id"
+ + " INNER JOIN wst_column_values wcv ON wc.id=wcv.wst_column_id"
+ + " INNER JOIN wst_column_q_ranges wcqr ON wc.id=wcqr.wst_column_id"
+ + " INNER JOIN wst_q_ranges wqr ON wcqr.wst_q_range_id=wqr.id"
+ + " INNER JOIN ranges r ON wqr.range_id=r.id AND wcv.position BETWEEN r.a AND r.b"
+ + " WHERE w.river_id = :river_id"
+ + " AND w.kind = 0"
+ + " AND r.river_id = :river_id"
+ + " AND wcv.position BETWEEN :kmfrom - 1 AND :kmto + 1" // some tolerance for start and end of list
+ + " ORDER BY wcv.position ASC, "
+ + " wc.position ASC";
+
+
+ /***** CONSTRUCTORS *****/
+
+ private WQBaseTableFinder(final River river, final Calculation problems, final List