[PATCH] Work on calculations for S-Info flood duration workflow
Wald Commits
scm-commit at wald.intevation.org
Mon Jun 25 19:21:41 CEST 2018
# 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 @@
<facet name="sinfo_flow_depth_development_peryear.manualpoints" />
<facet name="sinfo_tkk" />
<facet name="sinfo_collision.manualpoints" />
+ <facet name="sinfo_flood_duration.manualpoints" />
</facets>
</outputmode>
</outputmodes>
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 @@
<condition data="calculation_mode" value="sinfo_calc_flood_duration" operator="equal" />
</transition>
-
-
<transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
<from state="state.sinfo.wspl" />
<to state="state.sinfo.wq" />
@@ -359,7 +357,29 @@
<outputmodes>
<outputmode name="sinfo_flood_duration" description="output.sinfo_flood_duration" mime-type="image/png" type="chart">
<facets>
-
+ <facet name="sinfo_facet_flood_duration" description="flood duration of the heights of the infrastructures (points)"/>
+ <facet name="mainvalue.1.duration" description="flood duration of first W main value"/>
+ <facet name="mainvalue.2.duration" description="flood duration of second W main value"/>
+ <facet name="mainvalue.3.duration" description="flood duration of third W main value"/>
+ </facets>
+ </outputmode>
+ <outputmode name="sinfo_flood_height" description="output.sinfo_flood_height" mime-type="image/png" type="chart">
+ <facets>
+ <facet name="infrastructure.flood.height" description="flood heights of the infrastructures (points)"/>
+ <facet name="mainvalue.1.w" description="W of first main value"/>
+ <facet name="mainvalue.2.w" description="W of second main value"/>
+ <facet name="mainvalue.3.w" description="W of third main value"/>
+ </facets>
+ </outputmode>
+ <outputmode name="sinfo_flood_duration_curve" description="output.sinfo_duration_curve" mime-type="image/png" type="chart">
+ <facets>
+ <facet name="duration_curve.w" description="facet.duration_curve.w"/>
+ <facet name="duration_curve.q" description="facet.duration_curve.q"/>
+ <facet name="infrastructure.w" description="geodetic height of the infrastructure"/>
+ <facet name="mainvalues.w" description="W Main Values"/>
+ <facet name="mainvalues.q" description="Q Main Values at optional second axis"/>
+ <facet name="infrastructure.q" description="discharge of the infrastructure height"/>
+ <facet name="duration_curve.manualpoints" description="Manuelle Punkte"/>
</facets>
</outputmode>
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 @@
<axis name="flowdepthDevelopmentAxis"/>
<axis name="flowdepthDevelopmentPerYearAxis"/>
<axis name="countAxis" include-zero="true"/>
+ <axis name="durationAxis" include-zero="true"/>
<domain-axis key="chart.longitudinal.section.xaxis.label" default="Fluss-Km" inverted="org.dive4elements.river.exports.IsKmUpEvaluator()">
<arg expr="artifact.river"/>
@@ -57,6 +58,7 @@
<processor class="org.dive4elements.river.artifacts.sinfo.common.FlowDepthDevelopmentProcessor" axis="flowdepthDevelopmentAxis"/>
<processor class="org.dive4elements.river.artifacts.sinfo.common.FlowDepthDevelopmentPerYearProcessor" axis="flowdepthDevelopmentPerYearAxis"/>
<processor class="org.dive4elements.river.artifacts.sinfo.common.CollisionCalcProcessor" axis="countAxis"/>
+ <processor class="org.dive4elements.river.artifacts.sinfo.common.FloodDurationProcessor" axis="durationAxis"/>
<processor class="org.dive4elements.river.artifacts.sinfo.common.PredefinedChannelWidthProcessor" axis="Width"/>
<processor class="org.dive4elements.river.artifacts.sinfo.common.PredefinedChannelDepthProcessor" axis="flowdepthAxis"/>
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 @@
<arg expr="artifact.river"/>
</subtitle>
</output-generator>
+
+ <output-generator
+ names="sinfo_flood_duration,sinfo_flood_duration_chartinfo"
+ class="org.dive4elements.river.exports.LongitudinalSectionGenerator2"
+ converter="org.dive4elements.river.exports.DiagramAttributes">
+ <title key="sinfo.chart.flood_duration.section.title" default="Überflutungsdauer Infrastruktur BWaStr (DEFAULT)"/>
+ &longitudinal-defaults;
+ <processor class="org.dive4elements.river.exports.process.ManualPointsProcessor"
+ axis="durationAxis"/>
+ <subtitle key="chart.w_differences.subtitle" default="-">
+ <arg expr="artifact.river"/>
+ </subtitle>
+ </output-generator>
</longitudinal-diagrams>
\ 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 @@
<dc:when test="$out = 'sinfo_collision'">
<dc:call-macro name="annotations" />
</dc:when>
+ <dc:when test="$out = 'sinfo_flood_duration'">
+ <dc:call-macro name="annotations" />
+ </dc:when>
+ <dc:when test="$out = 'sinfo_flood_height'">
+ <dc:call-macro name="annotations" />
+ </dc:when>
+ <dc:when test="$out = 'sinfo_flood_duration_curve'">
+ <dc:call-macro name="annotations" />
+ </dc:when>
</dc:choose>
</dc:iterate>
</dc:when>
@@ -303,6 +312,15 @@
<dc:when test="$out = 'sinfo_collision'">
<dc:call-macro name="longitudinal-section-prototype" />
</dc:when>
+ <dc:when test="$out = 'sinfo_flood_duration'">
+ <dc:call-macro name="longitudinal-section-prototype" />
+ </dc:when>
+ <dc:when test="$out = 'sinfo_flood_height'">
+ <dc:call-macro name="longitudinal-section-prototype" />
+ </dc:when>
+ <dc:when test="$out = 'sinfo_flood_duration_curve'">
+ <dc:call-macro name="longitudinal-section-prototype" />
+ </dc:when>
</dc:choose>
</dc:iterate>
</dc:otherwise>
@@ -1653,6 +1671,7 @@
<dc:call-macro name="sinfo_flow_depth_development" />
<dc:call-macro name="sinfo_tkh" />
<dc:call-macro name="sinfo_collision" />
+ <dc:call-macro name="sinfo_flood_duration" />
<dc:comment> WINFO/DIFF/FIX </dc:comment>
<dc:call-macro name="longitudinal" />
@@ -3414,6 +3433,24 @@
</dc:filter>
</dc:macro>
+ <dc:macro name="sinfo_flood_duration">
+ <dc:filter expr="$a_state = 'state.sinfo.flood_duration'">
+ <dc:if test="dc:has-result()">
+ <sinfo_flood_duration>
+ <dc:for-each>
+ <dc:element name="${facet_name}">
+ <dc:attribute name="factory" value="sinfo" />
+ <dc:attribute name="target_out" value="${out}" />
+ <dc:attribute name="description" value="${facet_description}" />
+ <dc:attribute name="ids" value="${facet_num}" />
+ <dc:attribute name="artifact-id" value="${a_gid}" />
+ <dc:attribute name="out" value="${out_name}" />
+ </dc:element>
+ </dc:for-each>
+ </sinfo_flood_duration>
+ </dc:if>
+ </dc:filter>
+ </dc:macro>
<!-- channel size imported from CSV-files for S-INFO -->
<dc:macro name="sinfo_predefined_channel">
<dc:context>
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 @@
<mapping from="sinfo_facet_bedheight_difference.filtered" to="SInfoBedHeightDifference" />
<mapping from ="sinfo_facet_collision_calc_count" to="SInfoCollisionCount" />
+ <mapping from ="sinfo_facet_flood_duration" to="SInfoFloodDuration" />
<mapping from="sinfo_facet_predefined_channel_width" to="SInfoPredefinedChannelWidth" />
<mapping from="sinfo_facet_predefined_channel_depth" to="SInfoPredefinedChannelDepth" />
@@ -458,5 +459,6 @@
<mapping from="sinfo_flow_depth_development_peryear.manualpoints" to="ManualPoints" />
<mapping from="sinfo_tkk" to="ManualPoints" />
<mapping from="sinfo_collision.manualpoints" to="ManualPoints" />
+ <mapping from="sinfo_flood_duration.manualpoints" to="ManualPoints" />
</mappings>
</themes>
\ 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 @@
<field name="pointcolor" type="Color" display="Punktfarbe" default="48, 96, 255" />
</fields>
</theme>
+ <theme name="SInfoFloodDuration">
+ <inherits>
+ <inherit from="LongitudinalSectionPoints" />
+ </inherits>
+ <fields>
+ <field name="pointsize" type="int" display="Punktdicke" default="3" />
+ <field name="pointcolor" type="Color" display="Punktfarbe" default="68, 216, 40" />
+ </fields>
+ </theme>
</themegroup>
\ 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 @@
<field name="pointcolor" type="Color" display="Punktfarbe" default="48, 96, 192" />
</fields>
</theme>
+ <theme name="SInfoFloodDuration">
+ <inherits>
+ <inherit from="LongitudinalSectionPoints" />
+ </inherits>
+ <fields>
+ <field name="pointsize" type="int" display="Punktdicke" default="3" />
+ <field name="pointcolor" type="Color" display="Punktfarbe" default="68, 192, 40" />
+ </fields>
+ </theme>
</themegroup>
\ 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<String> 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<Gauge, GaugeDischargeValuesFinder> qFinders = new HashMap<>();
- final Map<Gauge, GaugeDischargeZoneFinder> zoneFinders = new HashMap<>();
+ final Map<Gauge, GaugeMainValueNameFinder> 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<ResultRow> detailsRows = new ArrayList<>();
@@ -118,7 +121,7 @@
*/
private void calculateDetails(final Collection<ResultRow> rows, final RiverInfoProvider riverInfo, final double fromKm, final double toKm,
final int fromYear, final int toYear, final Map<Gauge, GaugeDischargeValuesFinder> qFinders,
- final Map<Gauge, GaugeDischargeZoneFinder> zoneFinders) {
+ final Map<Gauge, GaugeMainValueNameFinder> 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<AbstractCalculationResult> {
+
+ 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<String> 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<Double, MainValue> 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<Double, MainValue> 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<Double, MainValue> 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<String> columnNames;
+
+ private final NavigableMap<Double, PolynomialSplineFunction> kmWs;
+
+ private final NavigableMap<Double, PolynomialSplineFunction> 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<Object[]> colnames, final List<Object[]> rows) {
+ this.river = river;
+ this.problems = problems;
+ this.columnNames = new ArrayList<>();
+ for (final Object[] colname : colnames)
+ this.columnNames.add(colname[1].toString());
+ this.kmWs = new TreeMap<>();
+ this.kmQs = new TreeMap<>();
+ final TDoubleArrayList ws = new TDoubleArrayList();
+ final TDoubleArrayList qs = new TDoubleArrayList();
+ double km = Double.NaN;
+ for (int i = 0; i <= rows.size() - 1; i++) {
+ if (ws.isEmpty() || ((double) rows.get(i)[0] <= km + 0.0001)) {
+ if (ws.isEmpty())
+ km = (double) rows.get(i)[0];
+ ws.add((double) rows.get(i)[2]);
+ qs.add((double) rows.get(i)[3]);
+ }
+ if ((i == rows.size() - 1) || ((double) rows.get(i)[0] > km + 0.0001)) {
+ try {
+ this.kmWs.put(km, new LinearInterpolator().interpolate(ws.toNativeArray(), qs.toNativeArray()));
+ this.kmQs.put(km, new LinearInterpolator().interpolate(qs.toNativeArray(), ws.toNativeArray()));
+ }
+ catch (final Exception e) {
+ if (this.problems != null) {
+ this.problems.addProblem(km, "wq_base_data.missing");
+ // Report only once
+ this.problems = null;
+ }
+ }
+ ws.clear();
+ qs.clear();
+ km = (double) rows.get(i)[0];
+ ws.add((double) rows.get(i)[2]);
+ qs.add((double) rows.get(i)[3]);
+ }
+ }
+ }
+
+
+ /***** METHODS *****/
+
+ /**
+ * Loads the the W/Q tables of a km range of a river
+ *
+ * @return The W/Q table finder of the river, or null
+ */
+ public static WQBaseTableFinder loadValues(final River river, final double fromKm, final double toKm, final Calculation problems) {
+ final Session session = SessionHolder.HOLDER.get();
+ final SQLQuery colQuery = session.createSQLQuery(SQLCOLUMNS)
+ .addScalar("colindex", StandardBasicTypes.INTEGER)
+ .addScalar("qzone", StandardBasicTypes.STRING);
+ colQuery.setParameter("river_id", river.getId());
+ final List<Object[]> colnames = colQuery.list();
+ if ((colnames == null) || colnames.isEmpty()) {
+ problems.addProblem("wq_table.missing");
+ return null;
+ }
+ final SQLQuery wqQuery = session.createSQLQuery(SQLMAIN)
+ .addScalar("station", StandardBasicTypes.DOUBLE)
+ .addScalar("colindex", StandardBasicTypes.INTEGER)
+ .addScalar("w", StandardBasicTypes.DOUBLE)
+ .addScalar("q", StandardBasicTypes.DOUBLE);
+ wqQuery.setParameter("river_id", river.getId());
+ wqQuery.setParameter("kmfrom", fromKm);
+ wqQuery.setParameter("kmto", toKm);
+ final List<Object[]> rows = wqQuery.list();
+ if ((rows != null) && !rows.isEmpty())
+ return new WQBaseTableFinder(river, problems, colnames, rows);
+ else {
+ problems.addProblem("wq_table.missing");
+ return null;
+ }
+ }
+
+ /**
+ * If this provider may return valid data at all.
+ */
+ public boolean isValid() {
+ return (this.kmWs != null);
+ }
+
+ /**
+ * Discharge for a W
+ *
+ * @param station
+ * station to find or interpolate
+ * @param w
+ * W in m+NN or m+NHN
+ * @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 station, final double w) {
+ if (this.kmWs == null)
+ return Double.NaN;
+ final Entry<Double, PolynomialSplineFunction> lowerEntry = this.kmWs.floorEntry(Double.valueOf(station));
+ final Entry<Double, PolynomialSplineFunction> upperEntry = this.kmWs.ceilingEntry(Double.valueOf(station));
+ if ((lowerEntry == null) || (upperEntry == null))
+ return Double.NaN;
+ try {
+ final double lowerQ = lowerEntry.getValue().value(w);
+ final double upperQ = upperEntry.getValue().value(w);
+ return Linear.linear(station, lowerEntry.getKey().doubleValue(), upperEntry.getKey().doubleValue(), lowerQ, upperQ);
+ }
+ 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/flood_duration/FloodDurationAccess.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationAccess.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationAccess.java Mon Jun 25 19:21:11 2018 +0200
@@ -12,12 +12,11 @@
import org.apache.log4j.Logger;
import org.dive4elements.river.artifacts.access.RangeAccess;
-import org.dive4elements.river.artifacts.common.EpochYearAccessHelper;
import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
import org.dive4elements.river.artifacts.sinfo.SinfoCalcMode;
/**
- * Access to the flow depth calculation type specific SInfo artifact data.
+ * Access to the flood duration 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.
@@ -28,14 +27,11 @@
private static Logger log = Logger.getLogger(FloodDurationAccess.class);
- private final EpochYearAccessHelper helper;
-
public FloodDurationAccess(final SINFOArtifact artifact) {
super(artifact);
/* assert calculation mode */
final SinfoCalcMode calculationMode = artifact.getCalculationMode();
- this.helper = new EpochYearAccessHelper(artifact);
assert (calculationMode == SinfoCalcMode.sinfo_calc_flood_duration);
}
@@ -47,5 +43,4 @@
public String getRiverside() {
return super.getString("riverside");
}
-
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Mon Jun 25 19:21:11 2018 +0200
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+/** 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
@@ -11,19 +11,25 @@
import org.apache.commons.lang.math.DoubleRange;
import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.WINFOArtifact;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.model.CalculationResult;
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.flood_duration.RiversideRadioChoice.RiversideChoiceKey;
import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper;
import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
-import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
import org.dive4elements.river.model.River;
+import org.dive4elements.river.model.sinfo.Infrastructure;
-class FloodDurationCalculation {
-
- // private static Logger log = Logger.getLogger(FloodDurationCalculation.class);
+/**
+ * Calculation of the flood durations of the infrastructures of the km range of a river
+ *
+ * @author Matthias Schäfer
+ */
+final class FloodDurationCalculation {
private final CallContext context;
@@ -38,44 +44,39 @@
/* access input data */
final FloodDurationAccess access = new FloodDurationAccess(sinfo);
final River river = access.getRiver();
-
+ final RiverInfo riverInfo = new RiverInfo(river);
final DoubleRange calcRange = access.getRange();
- /* calculate results for each diff pair */
+ final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange);
+ final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name());
+ final String riverside = Resources.getMsg(this.context.getMeta(), access.getRiverside());
+ final Infrastructure infrasSeries = Infrastructure.getSeries(river);
+ final String infrasType = (infrasSeries != null) ? infrasSeries.getType().getName() : "?";
+
final Calculation problems = new Calculation();
- final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange);
+ final FloodDurationCalculationResults results = new FloodDurationCalculationResults(calcModeLabel, user, riverInfo, calcRange);
- final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name());
+ final FloodDurationCalculationResult result = calculateResult(calcModeLabel, infrasType, riverside, calcRange, infoProvider,
+ RiversideChoiceKey.fromKey(access.getRiverside()), user, problems);
+ results.addResult(result, problems);
- // TODO: use enum for riverside
- final String riverside = access.getRiverside();
- // more
- // TODO: mis- ups.. re-use WINFO Artifact as in TkhState
- final WinfoArtifactWrapper winfo = new WinfoArtifactWrapper(sinfo);
- // winfo.computeWaterlevelData();
- final FloodDurationCalculationResults results = calculateResult(calcModeLabel, riverside, calcRange, infoProvider, user, problems);
+ // Calculate the selected main values, if any
+ /* misuse winfo-artifact to calculate waterlevels in the same way */
+ final WINFOArtifact winfo = new WinfoArtifactWrapper(sinfo);
return new CalculationResult(results, problems);
}
/**
- * Calculates FAKE Flood Duration
- *
- * @param riverside
- * @param calcModeLabel
- * @param user
- *
- * @param infoProvider
+ * Calculates the flood durations of the infrastructures of a km range of a river
*/
- private FloodDurationCalculationResults calculateResult(final String calcModeLabel, final String riverside, final DoubleRange calcRange,
- final RiverInfoProvider riverInfoProvider, final String user, final Calculation problems) {
+ private FloodDurationCalculationResult calculateResult(final String calcModeLabel, final String infrastructureType, final String riverside,
+ final DoubleRange calcRange, final RiverInfoProvider riverInfoProvider, final RiversideChoiceKey riversideKey, final String user,
+ final Calculation problems) {
final FloodDurationCalculator calculator = new FloodDurationCalculator(this.context, riverInfoProvider);
- final String wspLabel = "WSP-Name";// wstKms.getName();
- final int wspYear = 9999; // waterlevel.getYear();
- final WstInfo wstInfo = new WstInfo(wspLabel, wspYear, riverInfoProvider.getReferenceGauge());
- final String label = String.format("%s - %s", wspLabel, " soundingLabel");
- return calculator.execute(problems, label, wstInfo, calcModeLabel, calcRange, riverside, user);
+ final String label = infrastructureType + ", " + riverside;
+ return calculator.execute(problems, label, calcModeLabel, calcRange, riversideKey, user).getResult();
}
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResult.java Mon Jun 25 19:21:11 2018 +0200
@@ -9,191 +9,115 @@
*/
package org.dive4elements.river.artifacts.sinfo.flood_duration;
-import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
+import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult;
import org.dive4elements.river.artifacts.common.ExportContextCSV;
import org.dive4elements.river.artifacts.common.GeneralResultType;
import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
import org.dive4elements.river.artifacts.common.ResultRow;
-import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhCalculationResult;
import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
/**
- * Contains the results of a {@link FloodDurationCalculation}.
+ * Contains the result of a {@link FloodDurationCalculation}.
*
* @author Gernot Belger
*/
-final class FloodDurationCalculationResult extends AbstractTkhCalculationResult<FloodDurationCalculationResults> {
+final class FloodDurationCalculationResult extends AbstractCalculationExportableResult<FloodDurationCalculationResults> {
private static final long serialVersionUID = 1L;
- private final int waterlevelCount; // TODO: ggf 2 verschiedene Result-Klassen?
- // private final WstInfo wstInfo;
- private final int maxWaterlevelPdf = 3;
- private enum ExportMode {
- pdf, csv
+ private static final String JASPER_FILE = "/jasper/templates/sinfo.floodduration.jrxml";
+
+
+ public FloodDurationCalculationResult(final String label, final Collection<ResultRow> rows) {
+ super(label, rows);
}
- public FloodDurationCalculationResult(final String label, final WstInfo wstInfo, final Collection<ResultRow> rows, final boolean hasTkh,
- final int waterlevelCount) {
- super(label, wstInfo, hasTkh, rows);
- this.waterlevelCount = waterlevelCount;
- // this.wstInfo = wstInfo;
+
+ @Override
+ protected void writeCSVResultMetadata(final ExportContextCSV exportContextCSV, final FloodDurationCalculationResults results) {
+ // TODO Metadaten der Wasserspiegellage(n) falls gewählt
+ // exportContextCSV.writeCSVWaterlevelMetadata(this.wstInfo);
+ // exportContextCSV.writeBlankLine();
+ // writer.writeNext(new String[] { "" }); // break line
+ }
+
+ @Override
+ protected String getJasperFile() {
+ // TODO Variante mit Wasserspiegellage(n)
+ return JASPER_FILE;
+ }
+
+ protected String[] formatRow(final ExportContextCSV exportContextCSV, final FloodDurationCalculationResults results, final ResultRow row) {
+
+ final Collection<String> lines = new ArrayList<>(10);
+
+ lines.add(exportContextCSV.formatRowValue(row, GeneralResultType.station));
+ lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.riverside));
+ lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.floodDuration));
+ lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.floodDischarge));
+ lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.infrastructureHeight));
+ lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.infrastructuretype));
+
+ // TODO Wasserspiegellage(n) und Dauerzahlen falls gewählt
+
+ lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.gaugeLabel));
+ lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.location));
+
+ return lines.toArray(new String[lines.size()]);
}
@Override
public void writeCSVHeader(final ExportContextCSV exportContextCSV, final FloodDurationCalculationResults results, final RiverInfo river) {
- final Collection<String> header = new ArrayList<>(99);
+ final Collection<String> header = new ArrayList<>(20);
header.add(exportContextCSV.formatCsvHeader(GeneralResultType.station));
header.add(exportContextCSV.formatCsvHeader(SInfoResultType.riverside));
- header.add(exportContextCSV.formatCsvHeader(SInfoResultType.inundationduration));
- header.add(exportContextCSV.formatCsvHeader(SInfoResultType.inundationdurationq));
- header.add(exportContextCSV.formatCsvHeader(SInfoResultType.infrastructureHeight));
+ header.add(exportContextCSV.formatCsvHeader(SInfoResultType.floodDuration));
+ header.add(exportContextCSV.msgUnitCSV(SInfoResultType.floodDischarge, SInfoResultType.floodDischarge.getUnit()));
+ header.add(exportContextCSV.msgUnitCSV(SInfoResultType.infrastructureHeight, SInfoResultType.infrastructureHeight.getUnit()));
header.add(exportContextCSV.formatCsvHeader(SInfoResultType.infrastructuretype));
- // add dynamic headers
- final int waterlevelCount = // results.
- getWaterlevelCount();
- for (int i = 0; i < waterlevelCount; i++) {
- final int naturalIndex = i + 1;
- final String appendIndex = new StringBuilder().append("_").append(naturalIndex).toString();
- final Object[] args = new Object[] { appendIndex };
- // new StringBuilder().append('\u2081').toString(); // schlechter UTF-8-Support für subscript ints
- header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderW(), new Object[] { appendIndex, "results.getRiver().getWstUnit()" }));
- header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderFloodDurPerYear(), args));
- header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderQ(), args));
- header.add(exportContextCSV.msg(DurationWaterlevel.getHeaderBezeichn(), args));
- }
+ // TODO Je vier Spalten der bis zu drei Wasserspiegellagen
header.add(exportContextCSV.formatCsvHeader(SInfoResultType.gaugeLabel));
header.add(exportContextCSV.formatCsvHeader(SInfoResultType.location));
exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
- }
-
- @Override
- protected void writeCSVResultMetadata(final ExportContextCSV exportContextCSV, final FloodDurationCalculationResults results) {
-
- exportContextCSV.writeCSVWaterlevelMetadata(super.getWst()); // -> export in super? -> TODO
- exportContextCSV.writeBlankLine();
- // writer.writeNext(new String[] { "" }); // break line
}
@Override
protected String[] formatCSVRow(final ExportContextCSV exportContextCSV, final FloodDurationCalculationResults results, final ResultRow row) {
- // TODO Auto-generated method stub
- return formatRow(exportContextCSV, results, row, ExportMode.csv);
+
+ return this.formatRow(exportContextCSV, results, row);
}
@Override
- protected String[] formatPDFRow(final ExportContextCSV exportContextCSV, final FloodDurationCalculationResults results, final ResultRow row) {
+ protected String[] formatPDFRow(final ExportContextCSV exportContextPDF, final FloodDurationCalculationResults results, final ResultRow row) {
- return formatRow(exportContextCSV, results, row, ExportMode.pdf);
+ return this.formatRow(exportContextPDF, results, row);
}
@Override
- protected String getJasperFile() {
- if (this.waterlevelCount <= 1)
- return "/jasper/templates/sinfo.floodduration.jrxml"; // TODO 2 different result-classes?
- else
- return "/jasper/templates/sinfo.floodduration2.jrxml";
- }
+ protected void addJRTableHeader(final ExportContextCSV exportContextPDF, final MetaAndTableJRDataSource source,
+ final FloodDurationCalculationResults results) {
- @Override
- protected void addJRTableHeader(final ExportContextCSV exportContextCSV, final MetaAndTableJRDataSource source,
- final FloodDurationCalculationResults results) {
/* column headings */
- exportContextCSV.addJRMetadata(source, "station_header", GeneralResultType.station);
- exportContextCSV.addJRMetadata(source, "riverside_header", SInfoResultType.riverside);
- exportContextCSV.addJRMetadata(source, "inundationduration_header", SInfoResultType.inundationduration);
- exportContextCSV.addJRMetadata(source, "inundationduration_q_header", SInfoResultType.inundationdurationq);
- exportContextCSV.addJRMetadata(source, "infrastructure_height_header", SInfoResultType.infrastructureHeightFloodDur);
- exportContextCSV.addJRMetadata(source, "infrastructure_type_header", SInfoResultType.infrastructuretype);
+ exportContextPDF.addJRMetadata(source, "station_header", GeneralResultType.station);
+ exportContextPDF.addJRMetadata(source, "riverside_header", SInfoResultType.riverside);
+ exportContextPDF.addJRMetadata(source, "inundationduration_header", SInfoResultType.floodDuration);
+ exportContextPDF.addJRMetadata(source, "inundationduration_q_header", SInfoResultType.floodDischarge);
+ exportContextPDF.addJRMetadata(source, "infrastructure_height_header", SInfoResultType.infrastructureHeightFloodDur);
+ exportContextPDF.addJRMetadata(source, "infrastructure_type_header", SInfoResultType.infrastructuretype);
- // add dynamic headers
+ // TODO Je vier Spalten der bis zu drei Wasserspiegellagen
- if (this.waterlevelCount == 0 || this.waterlevelCount == 2) {
- source.addMetaData("dummy", "dummy");
- source.addMetaData("dummy", "dummy");
- source.addMetaData("dummy", "dummy");
- source.addMetaData("dummy", "dummy");
- }
-
- for (int i = 0; i < this.waterlevelCount; i++) {
- final int naturalIndex = i + 1;
-
- final Object[] args = new String[] { new StringBuilder().append("_").append(naturalIndex).toString() };
- exportContextCSV.addJRMetadata(source, getPdfHeader("w", naturalIndex), exportContextCSV.msg(DurationWaterlevel.getHeaderW(), args));
- exportContextCSV.addJRMetadata(source, getPdfHeader("duration", naturalIndex),
- exportContextCSV.msg(DurationWaterlevel.getHeaderFloodDurPerYear(), args));
- exportContextCSV.addJRMetadata(source, getPdfHeader("q", naturalIndex), exportContextCSV.msg(DurationWaterlevel.getHeaderQ(), args));
- exportContextCSV.addJRMetadata(source, getPdfHeader("bezeichnung", naturalIndex),
- exportContextCSV.msg(DurationWaterlevel.getHeaderBezeichn(), args));
-
- }
-
- exportContextCSV.addJRMetadata(source, "gauge_header", SInfoResultType.gaugeLabel);
- exportContextCSV.addJRMetadata(source, "location_header", SInfoResultType.location);
-
- }
-
- public int getWaterlevelCount() { // der exporter muss daran, um spalten auszublenden
- return this.waterlevelCount;
- }
-
- private String[] formatRow(final ExportContextCSV exportContextCSV, final FloodDurationCalculationResults results, final ResultRow row,
- final ExportMode mode) {
-
- final Collection<String> lines = new ArrayList<>(99);
-
- lines.add(exportContextCSV.formatRowValue(row, GeneralResultType.station));
- lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.riverside));
- lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.inundationduration));
- lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.inundationdurationq));
- lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.infrastructureHeight));
- lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.infrastructuretype));
-
- final List<DurationWaterlevel> waterlevelList = (List<DurationWaterlevel>) row.getValue(SInfoResultType.customMultiRowColWaterlevel);
- if (waterlevelList != null) {
- final NumberFormat wFormatter = exportContextCSV.getFlowDepthFormatter();
- final NumberFormat qFormatter = exportContextCSV.getQFormatter();
-
- for (int i = 0; i < waterlevelList.size(); i++) {
-
- if (i == this.maxWaterlevelPdf && mode == ExportMode.pdf)
- break;
-
- final DurationWaterlevel item = waterlevelList.get(i);
- lines.add(item.getWFormatted(wFormatter));
- lines.add(item.getFloodDurDaysPerYearFormatted());
- lines.add(item.getQFormatted(qFormatter));
- lines.add(item.getBezeichnung());
- }
- }
-
- if ((this.waterlevelCount == 0 || this.waterlevelCount == 2) && mode == ExportMode.pdf) {
- lines.add("dummy");
- lines.add("dummy");
- lines.add("dummy");
- lines.add("dummy");
- }
-
- lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.gaugeLabel));
- lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.location));
- return lines.toArray(new String[lines.size()]);
- }
-
- private String getPdfHeader(final String rootStr, final int index) {
- final String hd = "_header";
- final StringBuilder builder = new StringBuilder();
- return builder.append(rootStr).append("_").append(index).append(hd).toString();
+ exportContextPDF.addJRMetadata(source, "gauge_header", SInfoResultType.gaugeLabel);
+ exportContextPDF.addJRMetadata(source, "location_header", SInfoResultType.location);
}
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResults.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResults.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResults.java Mon Jun 25 19:21:11 2018 +0200
@@ -9,6 +9,8 @@
*/
package org.dive4elements.river.artifacts.sinfo.flood_duration;
+import java.util.List;
+
import org.apache.commons.lang.math.DoubleRange;
import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult;
import org.dive4elements.river.artifacts.common.AbstractCalculationResults;
@@ -21,12 +23,18 @@
private static final long serialVersionUID = 1L;
- private final String riverside;
-
- public FloodDurationCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange,
- final String riverside) {
+ public FloodDurationCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) {
super(calcModeLabel, user, river, calcRange);
- this.riverside = riverside; // lieber in Result?
}
+ /**
+ * We know that this type of results only has one result member, so we can directly access it.
+ */
+ public FloodDurationCalculationResult getResult() {
+ final List<AbstractCalculationExportableResult<FloodDurationCalculationResults>> results = getResults();
+ if (results.size() < 1)
+ return null;
+
+ return (FloodDurationCalculationResult) results.get(0);
+ }
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Mon Jun 25 19:21:11 2018 +0200
@@ -11,20 +11,29 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.commons.lang.math.DoubleRange;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.common.GeneralResultType;
import org.dive4elements.river.artifacts.common.ResultRow;
import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder;
import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
+import org.dive4elements.river.artifacts.sinfo.common.WQBaseTableFinder;
+import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey;
import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
-import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
+import org.dive4elements.river.model.Attribute.AttributeKey;
+import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.sinfo.InfrastructureValue;
/**
- * @author Gernot Belger
+ * Calculation of the result rows of the flood duration of the infrastructures in a river km range
+ * and selected main value durations
+ *
+ * @author Matthias Schäfer
*/
final class FloodDurationCalculator {
@@ -34,52 +43,66 @@
private final CallContext context;
+
public FloodDurationCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) {
this.context = context;
this.riverInfoProvider = riverInfoProvider;
}
- public FloodDurationCalculationResults execute(final Calculation problems, final String label, final WstInfo wstInfo, final String calcModeLabel,
- final DoubleRange calcRange, final String riverside, final String user) {
+ /**
+ * Calculate the result rows
+ *
+ * @return a result collection with one result
+ */
+ public FloodDurationCalculationResults execute(final Calculation problems, final String label, final String calcModeLabel,
+ final DoubleRange calcRange, final RiversideChoiceKey riverside, final String user) {
- calculateResultRow(8888.888);
- calculateResultRow(99);
- calculateResultRow(77);
- final boolean hasTkh = false; // TODO tkh richtig machen, oder anderen result-Type wählen als super-klasse für FloodDurationCalculationResult
+ final WQBaseTableFinder wqFinder = WQBaseTableFinder.loadValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(),
+ calcRange.getMaximumDouble(), problems);
+ final Map<Gauge, GaugeDurationValuesFinder> durFinders = new HashMap<>();
+ for (final Gauge gauge : this.riverInfoProvider.getRiver().determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble())) {
+ durFinders.put(gauge, GaugeDurationValuesFinder.loadValues(gauge, problems));
+ }
+ final AttributeKey bankKey = riverside.getAttributeKey();
+ for (final InfrastructureValue infrastructure : InfrastructureValue.getValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(),
+ calcRange.getMaximumDouble(), bankKey)) {
+ calculateResultRow(infrastructure, wqFinder, durFinders);
+ }
- final FloodDurationCalculationResult result = new FloodDurationCalculationResult(label, wstInfo, this.rows, false, 4);
+ final FloodDurationCalculationResult result = new FloodDurationCalculationResult(label, this.rows);
final RiverInfo riverInfo = new RiverInfo(this.riverInfoProvider.getRiver());
- final FloodDurationCalculationResults results = new FloodDurationCalculationResults(calcModeLabel, user, riverInfo, calcRange, riverside);
+ final FloodDurationCalculationResults results = new FloodDurationCalculationResults(calcModeLabel, user, riverInfo, calcRange);
results.addResult(result, problems);
return results;
}
- private void calculateResultRow(final double station) {
+ /**
+ * Calculate the result row for one infrastructure
+ */
+ private void calculateResultRow(final InfrastructureValue infrastructure, final WQBaseTableFinder wqFinder,
+ final Map<Gauge, GaugeDurationValuesFinder> durFinders) {
final ResultRow row = ResultRow.create();
+ final Gauge gauge = this.riverInfoProvider.getGauge(infrastructure.getStation(), true);
+ final double q = wqFinder.getDischarge(infrastructure.getStation(), infrastructure.getHeight());
+ final double qOut = Double.isInfinite(q) ? Double.NaN : q;
// REMARK: access the location once only during calculation
- final String location = this.riverInfoProvider.getLocation(station);
- row.putValue(GeneralResultType.station, station);
- row.putValue(SInfoResultType.riverside, "todo:getRiverside");
- row.putValue(SInfoResultType.inundationduration, 44);
- row.putValue(SInfoResultType.inundationdurationq, 444);
- row.putValue(SInfoResultType.infrastructureHeight, 55);
- row.putValue(SInfoResultType.infrastructuretype, "todo_get_infrastructureType");
+ final String location = this.riverInfoProvider.getLocation(infrastructure.getStation());
+ row.putValue(GeneralResultType.station, infrastructure.getStation());
+ row.putValue(SInfoResultType.riverside, infrastructure.getAttributeKey().getName()); // TODO i18n
+ row.putValue(SInfoResultType.floodDuration, 365 - durFinders.get(gauge).getDuration(q));
+ row.putValue(SInfoResultType.floodDischarge, qOut);
+ row.putValue(SInfoResultType.infrastructureHeight, infrastructure.getHeight());
+ row.putValue(SInfoResultType.infrastructuretype, infrastructure.getInfrastructure().getType().getName());
- // custom type; each entry produces 4 Columns
- final List<DurationWaterlevel> rowWsps = new ArrayList<>();
+ // TODO Berechne W, Überflutungsdauer, Q und Bezeichnung von bis zu drei WSPL
+ // row.putValue(SInfoResultType.customMultiRowColWaterlevel, rowWsps);
- rowWsps.add(new DurationWaterlevel(222, 30, 666, "1. Test"));
- rowWsps.add(new DurationWaterlevel(111, 40, 555, "2. Test"));
- rowWsps.add(new DurationWaterlevel(123, 333, 33, "3. Test"));
- rowWsps.add(new DurationWaterlevel(444, 452, 55, "4. Test"));
- row.putValue(SInfoResultType.customMultiRowColWaterlevel, rowWsps);
-
- row.putValue(SInfoResultType.gaugeLabel, "todo:getReferencedGauge");
- row.putValue(SInfoResultType.location, "location");
+ row.putValue(SInfoResultType.gaugeLabel, gauge.getName());
+ row.putValue(SInfoResultType.location, location);
this.rows.add(row);
}
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationExporter.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationExporter.java Mon Jun 25 19:21:11 2018 +0200
@@ -31,39 +31,6 @@
public class FloodDurationExporter extends AbstractCommonExporter<FloodDurationCalculationResults> {
@Override
- protected void doWritePdf(final OutputStream out, final FloodDurationCalculationResults results) {
-
- // TODO: Move to super (hier ist aber spezieller code drin...)
- try {
- final ExportContextCSV exportContextCSV = new ExportContextCSV(this.context, null);
-
- final JasperReporter reporter = new JasperReporter();
-
- for (final AbstractCalculationExportableResult<FloodDurationCalculationResults> result : results.getResults()) {
- final MetaAndTableJRDataSource source = new MetaAndTableJRDataSource();
- getHelper().addJRMetaDataUSINFO(source, results);
-
- final JasperDesigner design = result.addReport(exportContextCSV, results, reporter, source);
- if (result instanceof FloodDurationCalculationResult) {
- final int wlCount = ((FloodDurationCalculationResult) result).getWaterlevelCount();
- if (wlCount == 0 || wlCount == 2) {
- design.removeColumn("wOpt");
- design.removeColumn("qOpt");
- design.removeColumn("bezOpt");
- design.removeColumn("durOpt");
- }
- }
- }
-
- reporter.exportPDF(out);
- }
- catch (final JRException je) {
- getLog().warn("Error generating PDF Report!", je);
- }
-
- }
-
- @Override
protected void doWriteCSVData(final CSVWriter writer, final FloodDurationCalculationResults results) {
// TODO: Diesen Ablauf in super?
@@ -96,4 +63,36 @@
}
+ @Override
+ protected void doWritePdf(final OutputStream out, final FloodDurationCalculationResults results) {
+
+ // TODO: Move to super (hier ist aber spezieller code drin...)
+ try {
+ final ExportContextCSV exportContextCSV = new ExportContextCSV(this.context, null);
+
+ final JasperReporter reporter = new JasperReporter();
+
+ for (final AbstractCalculationExportableResult<FloodDurationCalculationResults> result : results.getResults()) {
+ final MetaAndTableJRDataSource source = new MetaAndTableJRDataSource();
+ getHelper().addJRMetaDataUSINFO(source, results);
+
+ final JasperDesigner design = result.addReport(exportContextCSV, results, reporter, source);
+ if (result instanceof FloodDurationCalculationResult) {
+ // final int wlCount = ((FloodDurationCalculationResult) result).getWaterlevelCount();
+ // if (wlCount == 0 || wlCount == 2) {
+ design.removeColumn("wOpt");
+ design.removeColumn("qOpt");
+ design.removeColumn("bezOpt");
+ design.removeColumn("durOpt");
+ // }
+ }
+ }
+
+ reporter.exportPDF(out);
+ }
+ catch (final JRException je) {
+ getLog().warn("Error generating PDF Report!", je);
+ }
+
+ }
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Mon Jun 25 19:21:11 2018 +0200
@@ -14,19 +14,23 @@
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.ChartArtifact;
import org.dive4elements.river.artifacts.D4EArtifact;
-import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult;
+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.sinfo.common.FloodDurationProcessor;
import org.dive4elements.river.artifacts.states.DefaultState;
-/** State in which a waterlevel has been calculated. */
+/**
+ * Last state of the S-Info flood duration workflow that calculates and outputs the result
+ */
public class FloodDurationState extends DefaultState {
/// ** The log that is used in this state. */
- // private static Logger log = Logger.getLogger(FlowDepthState.class);
+ // private static Logger log = Logger.getLogger(FloodDurationState.class);
private static final long serialVersionUID = 1L;
@@ -44,7 +48,6 @@
facets.add(new EmptyFacet());
return null;
}
-
return compute((SINFOArtifact) artifact, context, hash, facets, old);
}
@@ -71,32 +74,21 @@
return res;
final FloodDurationCalculationResults results = (FloodDurationCalculationResults) res.getData();
+ final FloodDurationCalculationResult result = results.getResult();
+ if (result != null) {
+ // add themes for chart
+ final int index = 0;
- /* add themes for chart, for each result */
- final List<AbstractCalculationExportableResult<FloodDurationCalculationResults>> resultList = results.getResults();
- for (int index = 0; index < resultList.size(); index++) {
+ facets.add(FloodDurationProcessor.createFloodDurationFacet(context, hash, this.id, result, index));
+ facets.add(FloodDurationProcessor.createMainValueDurationFacet(context, hash, this.id, result, index));
- final AbstractCalculationExportableResult<FloodDurationCalculationResults> result = resultList.get(0);
-
- /* filtered (zoom dependent mean) flow depth TODO: */
- // facets.add(FloodDurationProcessor.createFlowDepthFilteredFacet(context, hash, this.id, result, index));
- // facets.add(FloodDurationProcessor.createFlowDepthRawFacet(context, hash, this.id, result, index));
-
+ facets.add(new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id));
+ facets.add(new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id));
}
- 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));
- // }
+ final Calculation report = res.getReport();
+ if (report.hasProblems())
+ facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
return res;
}
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/RiversideRadioChoice.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/RiversideRadioChoice.java Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/RiversideRadioChoice.java Mon Jun 25 19:21:11 2018 +0200
@@ -12,25 +12,63 @@
import java.util.List;
import org.dive4elements.river.artifacts.states.RadioSelect;
+import org.dive4elements.river.model.Attribute.AttributeKey;
/**
* @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
*/
public class RiversideRadioChoice extends RadioSelect {
+
private static final long serialVersionUID = 1L;
+ /***** TYPES *****/
+
+ public enum RiversideChoiceKey {
+ NONE("", AttributeKey.NONE), //
+ LEFT("state.sinfo.riverside.left", AttributeKey.LEFT), //
+ RIGHT("state.sinfo.riverside.right", AttributeKey.RIGHT), //
+ BOTH("state.sinfo.riverside.both", AttributeKey.UNKNOWN);
+
+ private final String key;
+ private final AttributeKey attributeKey;
+
+ RiversideChoiceKey(final String key, final AttributeKey attributeKey) {
+ this.key = key;
+ this.attributeKey = attributeKey;
+ }
+
+ public static RiversideChoiceKey fromKey(final String key) {
+ for (final RiversideChoiceKey v : values()) {
+ if (key.equalsIgnoreCase(v.key))
+ return v;
+ }
+ return NONE;
+ }
+
+ public String getKey() {
+ return this.key;
+ }
+
+ public AttributeKey getAttributeKey() {
+ return this.attributeKey;
+ }
+ }
+
+ /***** CONSTRUCTORS *****/
+
public RiversideRadioChoice() {
super();
}
+ /***** METHODS *****/
+
@Override
protected List<String> makeEntries() {
final List<String> entries = new ArrayList<>();
- entries.add("state.sinfo.riverside.left");
- entries.add("state.sinfo.riverside.right");
- entries.add("state.sinfo.riverside.both");
+ entries.add(RiversideChoiceKey.LEFT.getKey());
+ entries.add(RiversideChoiceKey.RIGHT.getKey());
+ entries.add(RiversideChoiceKey.BOTH.getKey());
return entries;
-
}
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/resources/messages.properties
--- a/artifacts/src/main/resources/messages.properties Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/resources/messages.properties Mon Jun 25 19:21:11 2018 +0200
@@ -922,11 +922,11 @@
sinfo.export.flow_depth.csv.header.location = Lage
sinfo.export.flood_duration.csv.header.riverside = Uferseite
sinfo.export.flood_duration.csv.header.infrastructure.height = H\u00f6he der Infrastruktur
-sinfo.export.flood_duration.csv.header.inundation_duration = \u00dcberflutungsdauer [d/a]
-sinfo.export.flood_duration.csv.header.inundation_duration_q = \u00dcberflutungsdauerabfluss Q[m\u00b3/s]
+sinfo.export.flood_duration.csv.header.duration = \u00dcberflutungsdauer [d/a]
+sinfo.export.flood_duration.csv.header.discharge = \u00dcberflutungsdauerabfluss Q
sinfo.export.flood_duration.csv.header.infrastructure_type = Infrastrukturtyp
-sinfo.export.flood_duration.pdf.header.inundation_duration = \u00dcberflu-tungs-dauer [d/a]
-sinfo.export.flood_duration.pdf.header.inundation_duration_q = \u00dcberflu-tungs-dauer-abfluss Q[m\u00b3/s]
+sinfo.export.flood_duration.pdf.header.duration = \u00dcber-flutungs-dauer [d/a]
+sinfo.export.flood_duration.pdf.header.discharge = \u00dcber-flutungs-dauer-abfluss Q [m\u00b3/s]
sinfo.export.flood_duration.pdf.header.infrastructure_type = Infra-struktur-typ
sinfo.export.flood_duration.pdf.header.infrastructure.height = H\u00f6he der Infra-struktur
@@ -1113,7 +1113,7 @@
sinfo.export.csv.header.collision.count = Anzahl der Grundber\u00fchrungen
collision.count.title = Grundber\u00fchrungen {0}
chart.collision_count.section.yaxis.label = H\u00e4ufigkeit
-sinfo.export.csv.header.collision.gaugew = W am Pegel
+sinfo.export.csv.header.collision.gaugew = Pegelstand
collision.gaugew.title = W am Pegel {0}
sinfo.export.csv.header.discharge.zone = Abflusszustand
@@ -1123,6 +1123,17 @@
sinfo.chart.collision.section.title = Grundber\u00fchrungen
+sinfo.chart.flood_duration.section.title = \u00dcberflutungsdauer Infrastrukturen BWaStr
+sinfo.chart.flood_duration.section.yaxis.label = \u00dcberflutungsdauer [d/a]
+sinfo_facet_flood_duration = \u00dcberflutungsdauern
+sinfo_facet_flood_duration.description = \u00dcberflutungsdauern ({0})
+gauge_duration.missing = Keine Dauerzahlen vorhanden am Pegel {0}
+gauge_discharge_table.missing = No discharge table available for gauge {0}
+gauge_main_values.missing = No named main values available for gauge {0}
+wq_base_data.missing = No base waterlevel/discharge available
+mainvalue.duration = \u00dcberflutungsdauer
+mainvalue.duration.description = \u00dcberflutungsdauer ({0})
+
bundu_bezugswst = Bezugswasserst\u00e4nde
bundu_analysis = Fixinganalysis
bundu_vollmer = relocated Waterlevel Calculation
diff -r 34dc0163ad2d -r 1614cb14308f artifacts/src/main/resources/messages_de.properties
--- a/artifacts/src/main/resources/messages_de.properties Mon Jun 25 17:58:11 2018 +0200
+++ b/artifacts/src/main/resources/messages_de.properties Mon Jun 25 19:21:11 2018 +0200
@@ -922,11 +922,11 @@
sinfo.export.flow_depth.csv.header.location = Lage
sinfo.export.flood_duration.csv.header.riverside = Uferseite
sinfo.export.flood_duration.csv.header.infrastructure.height = H\u00f6he der Infrastruktur
-sinfo.export.flood_duration.csv.header.inundation_duration = \u00dcberflutungsdauer [d/a]
-sinfo.export.flood_duration.csv.header.inundation_duration_q = \u00dcberflutungsdauerabfluss Q[m\u00b3/s]
+sinfo.export.flood_duration.csv.header.duration = \u00dcberflutungsdauer [d/a]
+sinfo.export.flood_duration.csv.header.discharge = \u00dcberflutungsdauerabfluss Q
sinfo.export.flood_duration.csv.header.infrastructure_type = Infrastrukturtyp
-sinfo.export.flood_duration.pdf.header.inundation_duration = \u00dcberflu-tungs-dauer [d/a]
-sinfo.export.flood_duration.pdf.header.inundation_duration_q = \u00dcberflu-tungs-dauer-abfluss Q[m\u00b3/s]
+sinfo.export.flood_duration.pdf.header.duration = \u00dcber-flutungs-dauer [d/a]
+sinfo.export.flood_duration.pdf.header.discharge = \u00dcber-flutungs-dauer-abfluss Q [m\u00b3/s]
sinfo.export.flood_duration.pdf.header.infrastructure_type = Infra-struktur-typ
sinfo.export.flood_duration.pdf.header.infrastructure.height = H\u00f6he der Infra-struktur
@@ -1113,7 +1113,7 @@
sinfo.export.csv.header.collision.count = Anzahl der Grundber\u00fchrungen
collision.count.title = Grundber\u00fchrungen {0}
chart.collision_count.section.yaxis.label = H\u00e4ufigkeit
-sinfo.export.csv.header.collision.gaugew = Pegelstand [cm]
+sinfo.export.csv.header.collision.gaugew = Pegelstand
collision.gaugew.title = W am Pegel {0}
sinfo.export.csv.header.discharge.zone = Abflusszustand
@@ -1123,6 +1123,17 @@
sinfo.chart.collision.section.title = Grundber\u00fchrungen
+sinfo.chart.flood_duration.section.title = \u00dcberflutungsdauer Infrastrukturen BWaStr
+sinfo.chart.flood_duration.section.yaxis.label = \u00dcberflutungsdauer [d/a]
+sinfo_facet_flood_duration = \u00dcberflutungsdauern
+sinfo_facet_flood_duration.description = \u00dcberflutungsdauern ({0})
+gauge_duration.missing = Dauerzahlen fehlen am Pegel {0}
+gauge_discharge_table.missing = Abflusstafel fehlt am Pegel {0}
+gauge_main_values.missing = Hauptwerte fehlen am Pegel {0}
+wq_base_data.missing = W/Q-Daten fehlen oder sind ung\00fcltig
+mainvalue.duration = \u00dcberflutungsdauer
+mainvalue.duration.description = \u00dcberflutungsdauer ({0})
+
bundu_bezugswst = Bezugswasserst\u00e4nde
bundu_analysis = Fixierungsanalyse
bundu_vollmer = ausgelagerte Wasserspiegellage
diff -r 34dc0163ad2d -r 1614cb14308f backend/src/main/java/org/dive4elements/river/model/Annotation.java
--- a/backend/src/main/java/org/dive4elements/river/model/Annotation.java Mon Jun 25 17:58:11 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/model/Annotation.java Mon Jun 25 19:21:11 2018 +0200
@@ -10,15 +10,18 @@
import java.io.Serializable;
+import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Column;
-import javax.persistence.SequenceGenerator;
-import javax.persistence.GenerationType;
-import javax.persistence.OneToOne;
-import javax.persistence.JoinColumn;
+import javax.persistence.Transient;
+
+import org.dive4elements.river.model.Attribute.AttributeKey;
@Entity
@Table(name = "annotations")
@@ -36,12 +39,12 @@
}
public Annotation(
- Range range,
- Attribute attribute,
- Position position,
- Edge edge,
- AnnotationType type
- ) {
+ final Range range,
+ final Attribute attribute,
+ final Position position,
+ final Edge edge,
+ final AnnotationType type
+ ) {
this.range = range;
this.attribute = attribute;
this.position = position;
@@ -51,68 +54,73 @@
@Id
@SequenceGenerator(
- name = "SEQUENCE_ANNOTATIONS_ID_SEQ",
- sequenceName = "ANNOTATIONS_ID_SEQ",
- allocationSize = 1)
+ name = "SEQUENCE_ANNOTATIONS_ID_SEQ",
+ sequenceName = "ANNOTATIONS_ID_SEQ",
+ allocationSize = 1)
@GeneratedValue(
- strategy = GenerationType.SEQUENCE,
- generator = "SEQUENCE_ANNOTATIONS_ID_SEQ")
+ strategy = GenerationType.SEQUENCE,
+ generator = "SEQUENCE_ANNOTATIONS_ID_SEQ")
@Column(name = "id")
public Integer getId() {
- return id;
+ return this.id;
}
- public void setId(Integer id) {
+ public void setId(final Integer id) {
this.id = id;
}
@OneToOne
@JoinColumn(name = "range_id")
public Range getRange() {
- return range;
+ return this.range;
}
- public void setRange(Range range) {
+ public void setRange(final Range range) {
this.range = range;
}
@OneToOne
@JoinColumn(name = "attribute_id")
public Attribute getAttribute() {
- return attribute;
+ return this.attribute;
}
- public void setAttribute(Attribute attribute) {
+ public void setAttribute(final Attribute attribute) {
this.attribute = attribute;
}
+ @Transient
+ public AttributeKey getAttributeKey() {
+ return this.getAttribute().getKey();
+ }
+
@OneToOne
@JoinColumn(name = "position_id")
public Position getPosition() {
- return position;
+ return this.position;
}
- public void setPosition(Position position) {
+ public void setPosition(final Position position) {
this.position = position;
}
@OneToOne
@JoinColumn(name = "edge_id")
public Edge getEdge() {
- return edge;
+ return this.edge;
}
- public void setEdge(Edge edge) {
+ public void setEdge(final Edge edge) {
this.edge = edge;
}
@OneToOne
@JoinColumn(name = "type_id")
public AnnotationType getType() {
- return type;
+ return this.type;
}
- public void setType(AnnotationType type) {
+ public void setType(final AnnotationType type) {
this.type = type;
}
}
diff -r 34dc0163ad2d -r 1614cb14308f backend/src/main/java/org/dive4elements/river/model/Attribute.java
--- a/backend/src/main/java/org/dive4elements/river/model/Attribute.java Mon Jun 25 17:58:11 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/model/Attribute.java Mon Jun 25 19:21:11 2018 +0200
@@ -9,20 +9,124 @@
package org.dive4elements.river.model;
import java.io.Serializable;
+import java.util.List;
+import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Column;
-import javax.persistence.SequenceGenerator;
-import javax.persistence.GenerationType;
+import javax.persistence.Transient;
+
+import org.dive4elements.river.backend.SessionHolder;
+import org.hibernate.Query;
+import org.hibernate.Session;
@Entity
@Table(name = "attributes")
public class Attribute
implements Serializable
{
+
+ /***** TYPES *****/
+
+ /**
+ * River attribute (river side or range type)
+ *
+ */
+ public enum AttributeKey {
+ NONE(""), STRECKE(">>>>>>>>>>>>>>>"), LEFT("links"), RIGHT("rechts"), UNKNOWN("?");
+
+ private final String name;
+ private int id;
+ private boolean ready;
+
+ AttributeKey(final String name) {
+ this.name = name;
+ this.id = 0;
+ this.ready = false;
+ }
+
+ /**
+ * Type name in the database
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * Type id in the database
+ */
+ public int getId() {
+ initFromDatabase();
+ return this.id;
+ }
+
+ /**
+ * Set the type id
+ */
+ public void setId(final int id) {
+ this.id = id;
+ }
+
+ protected boolean getReady() {
+ return this.ready;
+ }
+
+ protected void setReady(final boolean ready) {
+ this.ready = ready;
+ }
+
+ /**
+ * Main value type key for a database name value
+ */
+ public static AttributeKey forDbName(final String dbname) {
+ initFromDatabase();
+ for (final AttributeKey k : AttributeKey.values()) {
+ if (k.getName().equalsIgnoreCase(dbname))
+ return k;
+ }
+ return UNKNOWN;
+ }
+
+ /**
+ * Main value type key for a database id value
+ */
+ public static AttributeKey forDbId(final int dbid) {
+ initFromDatabase();
+ for (final AttributeKey k : AttributeKey.values()) {
+ if (k.getId() == dbid)
+ return k;
+ }
+ return UNKNOWN;
+ }
+
+ /**
+ * Initially queries the database ids
+ */
+ private static void initFromDatabase() {
+ if (STRECKE.getReady())
+ return;
+ // Avoid recursion
+ for (final AttributeKey k : AttributeKey.values())
+ k.setReady(true);
+ // Select database ids
+ final Session session = SessionHolder.HOLDER.get();
+ final Query query = session.createQuery("FROM Attribute");
+ final List<Attribute> rows = query.list();
+ if (!rows.isEmpty()) {
+ for (int i = 0; i <= rows.size() - 1; i++) {
+ if (forDbName(rows.get(i).getValue()) != UNKNOWN)
+ forDbName(rows.get(i).getValue()).setId(rows.get(i).getId());
+ }
+ }
+ }
+ }
+
+ /***** FIELDS *****/
+
private Integer id;
private String value;
@@ -30,34 +134,43 @@
public Attribute() {
}
- public Attribute(String value) {
+ /***** CONSTRUCTORS *****/
+
+ public Attribute(final String value) {
this.value = value;
}
+ /***** METHODS *****/
+
@Id
@SequenceGenerator(
- name = "SEQUENCE_ATTRIBUTES_ID_SEQ",
- sequenceName = "ATTRIBUTES_ID_SEQ",
- allocationSize = 1)
+ name = "SEQUENCE_ATTRIBUTES_ID_SEQ",
+ sequenceName = "ATTRIBUTES_ID_SEQ",
+ allocationSize = 1)
@GeneratedValue(
- strategy = GenerationType.SEQUENCE,
- generator = "SEQUENCE_ATTRIBUTES_ID_SEQ")
+ strategy = GenerationType.SEQUENCE,
+ generator = "SEQUENCE_ATTRIBUTES_ID_SEQ")
@Column(name = "id")
public Integer getId() {
- return id;
+ return this.id;
}
- public void setId(Integer id) {
+ public void setId(final Integer id) {
this.id = id;
}
@Column(name = "value")
public String getValue() {
- return value;
+ return this.value;
}
- public void setValue(String value) {
+ public void setValue(final String value) {
this.value = value;
}
+
+ @Transient
+ public AttributeKey getKey() {
+ return AttributeKey.forDbId(this.getId());
+ }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 34dc0163ad2d -r 1614cb14308f backend/src/main/java/org/dive4elements/river/model/MainValue.java
--- a/backend/src/main/java/org/dive4elements/river/model/MainValue.java Mon Jun 25 17:58:11 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/model/MainValue.java Mon Jun 25 19:21:11 2018 +0200
@@ -128,5 +128,19 @@
query.setParameter("typeid", typekey.getId());
return query.list();
}
+
+ /**
+ * Selects from the database the discharge-duration main values of a gauge sorted by duration
+ */
+ public static List<MainValue> getDurationDischargesOfGauge(final Gauge gauge) {
+ final Session session = SessionHolder.HOLDER.get();
+ final Query query = session.createQuery("SELECT mv"
+ + " FROM MainValue AS mv JOIN mv.mainValue AS nmv"
+ + " WHERE mv.gauge.id=:gaugeid AND nmv.type.id=:typeid"
+ + " ORDER BY CAST(nmv.name AS int)");
+ query.setParameter("gaugeid", gauge.getId());
+ query.setParameter("typeid", MainValueTypeKey.DURATION.getId());
+ return query.list();
+ }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 34dc0163ad2d -r 1614cb14308f backend/src/main/java/org/dive4elements/river/model/sinfo/Infrastructure.java
--- a/backend/src/main/java/org/dive4elements/river/model/sinfo/Infrastructure.java Mon Jun 25 17:58:11 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/model/sinfo/Infrastructure.java Mon Jun 25 19:21:11 2018 +0200
@@ -199,4 +199,18 @@
query.setParameter("id", id);
return (Infrastructure) query.list().get(0);
}
+
+ /**
+ * Get first data series of a river
+ */
+ public static Infrastructure getSeries(final River river) {
+ final Session session = SessionHolder.HOLDER.get();
+ final Query query = session.createQuery("FROM Infrastructure WHERE (river=:river)");
+ query.setParameter("river", river);
+ final List rows = query.list();
+ if (!rows.isEmpty())
+ return (Infrastructure) rows.get(0);
+ else
+ return null;
+ }
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f backend/src/main/java/org/dive4elements/river/model/sinfo/InfrastructureValue.java
--- a/backend/src/main/java/org/dive4elements/river/model/sinfo/InfrastructureValue.java Mon Jun 25 17:58:11 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/model/sinfo/InfrastructureValue.java Mon Jun 25 19:21:11 2018 +0200
@@ -22,9 +22,12 @@
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
+import javax.persistence.Transient;
import org.dive4elements.river.backend.SessionHolder;
import org.dive4elements.river.model.Attribute;
+import org.dive4elements.river.model.Attribute.AttributeKey;
+import org.dive4elements.river.model.River;
import org.hibernate.Query;
import org.hibernate.Session;
@@ -117,6 +120,11 @@
this.attribute = attribute;
}
+ @Transient
+ public AttributeKey getAttributeKey() {
+ return this.getAttribute().getKey();
+ }
+
@Column(name = "height")
public Double getHeight() {
return this.height;
@@ -127,7 +135,7 @@
}
/**
- * Selects the infrastructure values of a data series in a km range from the database
+ * Selects from the database the infrastructure values of a data series in a km range
*/
public static List<InfrastructureValue> getValues(final Infrastructure parent, final double kmLo, final double kmHi) {
final Session session = SessionHolder.HOLDER.get();
@@ -138,4 +146,25 @@
query.setParameter("kmHi", new Double(kmHi));
return query.list();
}
+
+ /**
+ * Selects from the database the infrastructure values of a km range of a river and a river side
+ */
+ public static List<InfrastructureValue> getValues(final River river, final double kmLo, final double kmHi, final AttributeKey riverside) {
+ final Session session = SessionHolder.HOLDER.get();
+ String riversideClause = "";
+ if ((riverside == AttributeKey.LEFT) || (riverside == AttributeKey.RIGHT))
+ riversideClause = " AND (v.attribute.id=:attr_id)";
+ final Query query = session.createQuery("FROM InfrastructureValue v"
+ + " WHERE (v.infrastructure.river=:river)"
+ + " AND (v.station BETWEEN :kmLo - 0.0001 AND :kmHi + 0.0001)"
+ + riversideClause
+ + " ORDER BY v.station, v.attribute.id");
+ query.setParameter("river", river);
+ query.setParameter("kmLo", new Double(kmLo));
+ query.setParameter("kmHi", new Double(kmHi));
+ if (!riversideClause.isEmpty())
+ query.setParameter("attr_id", riverside.getId());
+ return query.list();
+ }
}
diff -r 34dc0163ad2d -r 1614cb14308f gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Mon Jun 25 17:58:11 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Mon Jun 25 19:21:11 2018 +0200
@@ -1536,4 +1536,6 @@
String export_csv_title();
String waterlevel_ground_state();
+
+ String sinfo_flood_duration();
}
\ No newline at end of file
diff -r 34dc0163ad2d -r 1614cb14308f gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Mon Jun 25 17:58:11 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Mon Jun 25 19:21:11 2018 +0200
@@ -809,6 +809,8 @@
sinfo_collisions = Grundber\u00fchrungen
sinfo_collision = Grundber\u00fchrungen
+sinfo_flood_duration = \u00dcberflutungsdauer Infrastruktur BWaStr
+
uinfo = U-INFO
uinfo_inundation_duration_export = \u00dcberflutungsdauern Export
uinfo_salix_line_export = Salix-Linie Export
diff -r 34dc0163ad2d -r 1614cb14308f gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Mon Jun 25 17:58:11 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Mon Jun 25 19:21:11 2018 +0200
@@ -809,6 +809,8 @@
sinfo_collisions = Grundber\u00fchrungen
sinfo_collision = Grundber\u00fchrungen
+sinfo_flood_duration = \u00dcberflutungsdauer Infrastruktur BWaStr
+
uinfo = U-INFO
uinfo_inundation_duration_export = \u00dcberflutungsdauern Export
uinfo_salix_line_export = Salix-Linie Export
More information about the Dive4Elements-commits
mailing list