[PATCH] work on uinfo-inundation_duration states

Wald Commits scm-commit at wald.intevation.org
Tue May 8 15:21:41 CEST 2018


# HG changeset patch
# User gernotbelger
# Date 1525785683 -7200
# Node ID b6919e3c2d869fb45dc426cebe4ea0c23a12a9db
# Parent  5198066492a93e646cded2e9adfef466bb8c13f8
work on uinfo-inundation_duration states

diff -r 5198066492a9 -r b6919e3c2d86 artifacts/doc/conf/artifacts/sinfo.xml
--- a/artifacts/doc/conf/artifacts/sinfo.xml	Mon May 07 17:25:53 2018 +0200
+++ b/artifacts/doc/conf/artifacts/sinfo.xml	Tue May 08 15:21:23 2018 +0200
@@ -254,7 +254,7 @@
       <data name="years" type="String" />
     </state>
 
-    <state id="state.sinfo.load.epoch" description="state.sinfo.load.epoch" state="org.dive4elements.river.artifacts.states.minfo.SedimentLoadEpochSelect" helpText="help.state.sinfo.load.epoch">
+    <state id="state.sinfo.load.epoch" description="state.sinfo.load.epoch" state="org.dive4elements.river.artifacts.sinfo.collision.LoadEpochSelect" helpText="help.state.sinfo.load.epoch">
       <data name="epochs" type="String" />
     </state>
 
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/doc/conf/artifacts/uinfo.xml
--- a/artifacts/doc/conf/artifacts/uinfo.xml	Mon May 07 17:25:53 2018 +0200
+++ b/artifacts/doc/conf/artifacts/uinfo.xml	Tue May 08 15:21:23 2018 +0200
@@ -70,7 +70,6 @@
       <data name="ld_to_part" type="Double" />
     </state>
 
-
     <transition transition="org.dive4elements.river.artifacts.transitions.DefaultTransition">
       <from state="state.uinfo.distance_only_part" />
       <to state="state.uinfo.salix_line" />
@@ -78,6 +77,9 @@
     </transition>
 
 
+
+
+
     <state id="state.uinfo.salix_line" description="state.uinfo.salix_line" state="org.dive4elements.river.artifacts.uinfo.salix.SalixLineState" helpText="help.state.uinfo.salix_line">
       <outputmodes>
 
@@ -97,55 +99,101 @@
         </outputmode>
       </outputmodes>
     </state>
- 
 
- 
 
+    <!-- Calculation Mode: Inundation Duration -->
 
-
-
-    <!-- Calculation Mode: Vegetation Zones -->
     <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
       <from state="state.uinfo.calculation_mode" />
-      <to state="state.uinfo.vegetation_zones" />
-      <condition data="calculation_mode" value="uinfo_vegetation_zones" operator="equal" />
-
+      <to state="state.uinfo.distance_only" />
+      <condition data="calculation_mode" value="uinfo_inundation_duration" operator="equal" />
     </transition>
 
-    <state id="state.uinfo.vegetation_zones" description="state.uinfo.vegetation_zones" state="org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZonesState" helpText="help.state.uinfo.vegetation_zones">
-      <outputmodes>
+    <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+      <from state="state.uinfo.distance_only" />
+      <to state="state.uinfo.year_epoch" />
+      <condition data="calculation_mode" value="uinfo_inundation_duration" operator="equal" />
+    </transition>
 
-        <!-- FIXME: i01n name in FLYSConstants -->
-        <outputmode name="uinfo_vegetation_zones_export" description="output.uinfo_vegetation_zones_export" mime-type="text/plain" type="export">
-          <facets>
-            <facet name="csv" description="facet.uinfo_vegetation_zones_export.csv" />
-            <facet name="pdf" description="facet.uinfo_vegetation_zones_export.pdf" />
-          </facets>
-        </outputmode>
 
-        <!-- FIXME: i01n name in FLYSConstants -->
-        <outputmode name="uinfo_vegetation_zones_report" description="output.uinfo_vegetation_zones_report" mime-type="text/xml" type="report">
-          <facets>
-            <facet name="report" description="facet.uinfo_vegetation_zones_report" />
-          </facets>
-        </outputmode>
-      </outputmodes>
+    <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+      <from state="state.uinfo.year_epoch" />
+      <to state="state.uinfo.load.year" />
+      <condition data="ye_select" value="state.uinfo.year" operator="equal" />
+    </transition>
+
+    <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+      <from state="state.uinfo.year_epoch" />
+      <to state="state.uinfo.load.epoch" />
+      <condition data="ye_select" value="state.uinfo.epoch" operator="equal" />
+    </transition>
+
+
+    <state id="state.uinfo.year_epoch" description="state.uinfo.year_epoch" state="org.dive4elements.river.artifacts.uinfo.inundationduration.YearChoice" helpText="help.state.uinfo.year">
+      <data name="ye_select" type="String" />
     </state>
 
 
+    <state id="state.uinfo.load.year" description="state.uinfo.load.year" state="org.dive4elements.river.artifacts.uinfo.inundationduration.LoadYearSelect" helpText="help.state.uinfo.load.year">
+      <data name="years" type="String" />
+    </state>
 
+    <state id="state.uinfo.load.epoch" description="state.uinfo.load.epoch" state="org.dive4elements.river.artifacts.uinfo.inundationduration.LoadEpochSelect" helpText="help.state.uinfo.load.epoch">
+      <data name="epochs" type="String" />
+    </state>
 
 
-
-
-    <!-- Calculation Mode: Inundation Duration -->
     <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
-      <from state="state.uinfo.calculation_mode" />
-      <to state="state.uinfo.inundation_duration" />
+      <from state="state.uinfo.load.epoch" />
+      <to state="state.uinfo.inundation.use_scenario" />
       <condition data="calculation_mode" value="uinfo_inundation_duration" operator="equal" />
-
     </transition>
 
+    <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+      <from state="state.uinfo.load.year" />
+      <to state="state.uinfo.inundation.use_scenario" />
+      <condition data="calculation_mode" value="uinfo_inundation_duration" operator="equal" />
+    </transition>
+
+    <!-- Doppelter State, andere ID, damit keine Mehrfach-Condition benötigt wird -->
+    <state id="state.uinfo.inundation.use_scenario" description="state.uinfo.inundation.use_scenario" state="org.dive4elements.river.artifacts.uinfo.salix.UseScenarioChoice" helpText="help.state.uinfo.use_scenario">
+      <data name="use_scenario" type="Boolean" />
+    </state>
+
+
+    <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+      <from state="state.uinfo.inundation.use_scenario" />
+      <to state="state.uinfo.inundation.scenario" />
+      <condition data="use_scenario" value="true" operator="equal" />
+    </transition>
+
+    <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+      <from state="state.uinfo.inundation.use_scenario" />
+      <to state="state.uinfo.inundation.vegetation" />
+      <condition data="use_scenario" value="false" operator="equal" />
+    </transition>
+
+    <state id="state.uinfo.inundation.scenario" description="state.uinfo.inundation.scenario" state="org.dive4elements.river.artifacts.uinfo.inundationduration.LoadScenarioSelect" helpText="help.state.uinfo.use_scenario">
+      <data name="years" type="String" /> <!-- mittelwasserlage in cm! -->
+    </state>
+
+    <state id="state.uinfo.inundation.vegetation" description="state.uinfo.inundation.vegetation" state="org.dive4elements.river.artifacts.uinfo.salix.UseScenarioChoice" helpText="help.state.uinfo.use_scenario">
+      <data name="vegetation" type="Boolean" />
+    </state>
+
+    <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+      <from state="state.uinfo.inundation.scenario" />
+      <to state="state.uinfo.inundation.vegetation" />
+     <condition data="calculation_mode" value="uinfo_inundation_duration" operator="equal" />
+    </transition>
+
+
+    <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+      <from state="state.uinfo.inundation.vegetation" />
+      <to state="state.uinfo.inundation_duration" />
+     <condition data="calculation_mode" value="uinfo_inundation_duration" operator="equal" />
+    </transition>
+    
     <state id="state.uinfo.inundation_duration" description="state.uinfo.inundation_duration" state="org.dive4elements.river.artifacts.uinfo.inundationduration.InundationDurationState" helpText="help.state.uinfo.inundation_duration">
       <outputmodes>
 
@@ -167,4 +215,52 @@
     </state>
 
   </states>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  <!-- Calculation Mode: Vegetation Zones -->
+  <transition transition="org.dive4elements.river.artifacts.transitions.ValueCompareTransition">
+    <from state="state.uinfo.calculation_mode" />
+    <to state="state.uinfo.vegetation_zones" />
+    <condition data="calculation_mode" value="uinfo_vegetation_zones" operator="equal" />
+
+  </transition>
+
+  <state id="state.uinfo.vegetation_zones" description="state.uinfo.vegetation_zones" state="org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZonesState" helpText="help.state.uinfo.vegetation_zones">
+    <outputmodes>
+
+      <!-- FIXME: i01n name in FLYSConstants -->
+      <outputmode name="uinfo_vegetation_zones_export" description="output.uinfo_vegetation_zones_export" mime-type="text/plain" type="export">
+        <facets>
+          <facet name="csv" description="facet.uinfo_vegetation_zones_export.csv" />
+          <facet name="pdf" description="facet.uinfo_vegetation_zones_export.pdf" />
+        </facets>
+      </outputmode>
+
+      <!-- FIXME: i01n name in FLYSConstants -->
+      <outputmode name="uinfo_vegetation_zones_report" description="output.uinfo_vegetation_zones_report" mime-type="text/xml" type="report">
+        <facets>
+          <facet name="report" description="facet.uinfo_vegetation_zones_report" />
+        </facets>
+      </outputmode>
+    </outputmodes>
+  </state>
+
+
 </artifact>
\ No newline at end of file
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadEpochSelect.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadEpochSelect.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,28 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.collision;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.river.artifacts.states.DefaultState;
+
+public class LoadEpochSelect extends DefaultState {
+    /** The log used in this class. */
+    private static Logger log = Logger.getLogger(LoadEpochSelect.class);
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public LoadEpochSelect() {
+    }
+
+    @Override
+    protected String getUIProvider() {
+        return "sinfo.collision.load_epoch_select";
+    }
+}
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadYearSelect.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadYearSelect.java	Mon May 07 17:25:53 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/LoadYearSelect.java	Tue May 08 15:21:23 2018 +0200
@@ -28,7 +28,7 @@
     /** Year Select Widget. */
     @Override
     protected String getUIProvider() {
-        return "minfo.sedimentload_year_select";
+        return "minfo.sedimentload_year_select"; // TODO: eigenes Panel oder allgemeineren Code
     }
 
     @Override
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/LoadEpochSelect.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/LoadEpochSelect.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,28 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.uinfo.inundationduration;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.river.artifacts.states.DefaultState;
+
+public class LoadEpochSelect extends DefaultState {
+    /** The log used in this class. */
+    private static Logger log = Logger.getLogger(LoadEpochSelect.class);
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public LoadEpochSelect() {
+    }
+
+    @Override
+    protected String getUIProvider() {
+        return "uinfo.inundation_duration.load_epoch_select";
+    }
+}
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/LoadScenarioSelect.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/LoadScenarioSelect.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,46 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.uinfo.inundationduration;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.river.artifacts.states.DefaultState;
+
+/** State in which to fetch years for sedminent load calculation. */
+public class LoadScenarioSelect extends DefaultState {
+    private static final long serialVersionUID = 1L;
+    /** The log used in this class. */
+    private static Logger log = Logger.getLogger(LoadScenarioSelect.class);
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public LoadScenarioSelect() {
+    }
+
+    /** Year Select Widget. */
+    @Override
+    protected String getUIProvider() {
+        return "minfo.sedimentload_year_select"; // TODO: eigenes Panel oder allgemeineren Code und an SCENARIO AUS DB ANPASSEN!
+    }
+
+    @Override
+    public boolean validate(final Artifact artifact) throws IllegalArgumentException {
+        return true;
+        // final CollisionLoadYearEpochAccess access = new CollisionLoadYearEpochAccess((D4EArtifact) artifact);
+        //
+        // // Second year should be later than first.
+        // if (access.getYears() == null || access.getYears().length == 0)
+        // return true; // TODO: richtig in CollisionLoadYear... implementieren
+        // // throw new IllegalArgumentException("error_years_wrong");
+        //
+        // return true;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/LoadYearSelect.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/LoadYearSelect.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,46 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.uinfo.inundationduration;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.river.artifacts.states.DefaultState;
+
+/** State in which to fetch years for sedminent load calculation. */
+public class LoadYearSelect extends DefaultState {
+    private static final long serialVersionUID = 1L;
+    /** The log used in this class. */
+    private static Logger log = Logger.getLogger(LoadYearSelect.class);
+
+    /**
+     * The default constructor that initializes an empty State object.
+     */
+    public LoadYearSelect() {
+    }
+
+    /** Year Select Widget. */
+    @Override
+    protected String getUIProvider() {
+        return "uinfo.inundationduration.load_year_select";
+    }
+
+    @Override
+    public boolean validate(final Artifact artifact) throws IllegalArgumentException {
+        return true;
+        // final CollisionLoadYearEpochAccess access = new CollisionLoadYearEpochAccess((D4EArtifact) artifact);
+        //
+        // // Second year should be later than first.
+        // if (access.getYears() == null || access.getYears().length == 0)
+        // return true; // TODO: richtig in CollisionLoadYear... implementieren
+        // // throw new IllegalArgumentException("error_years_wrong");
+        //
+        // return true;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/YearChoice.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/YearChoice.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,34 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.uinfo.inundationduration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dive4elements.river.artifacts.states.RadioSelect;
+
+/**
+ * @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
+ */
+public class YearChoice extends RadioSelect {
+    private static final long serialVersionUID = 1L;
+
+    public YearChoice() {
+        super();
+    }
+
+    @Override
+    protected List<String> makeEntries() {
+        final List<String> entries = new ArrayList<>();
+        entries.add("state.uinfo.year");
+        entries.add("state.uinfo.epoch");
+        return entries;
+
+    }
+}
\ No newline at end of file
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/src/main/resources/messages.properties
--- a/artifacts/src/main/resources/messages.properties	Mon May 07 17:25:53 2018 +0200
+++ b/artifacts/src/main/resources/messages.properties	Tue May 08 15:21:23 2018 +0200
@@ -75,11 +75,18 @@
 state.minfo.t_per_a = t/a
 state.minfo.m3_per_a = m\u00b3/a
 
+state.uinfo.year_epoch = Year/Epoch
+state.uinfo.load.year= Year
+state.uinfo.load.epoch=Epoch
+state.uinfo.year=Year
+state.uinfo.epoch=Epoch
+
 state.sinfo.year_epoch = Year/Epoch
 state.sinfo.load.year= Year(s)
 state.sinfo.load.epoch=Epoch(s)
 state.sinfo.year=Year
 state.sinfo.epoch=Epoch
+
 state.sinfo.riverside.left = Linkes Ufer
 state.sinfo.riverside.right = Rechtes Ufer
 state.sinfo.riverside.both = Beide Ufer
@@ -862,7 +869,6 @@
 state.sinfo.wspl.active = Ja
 state.sinfo.wspl.inactive = Nein
 help.state.sinfo.wspl= ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.wspl
-  
 state.sinfo.grounding.year = Jahr/Zeitraum
 state.sinfo.grounding.year.option1 = Jahr
 state.sinfo.grounding.year.option1 = Zeitraum
@@ -1000,7 +1006,7 @@
 sinfo.export.csv.meta.header.sounding.current = ##METADATEN PEILUNG aktuell
 sinfo.export.csv.meta.header.sounding.historical = ##METADATEN PEILUNG historisch
 sinfo.export.csv.meta.header.waterlevel.current = ##METADATEN WASSERSPIEGELLAGE aktuell
-sinfo.export.csv.meta.header.waterlevel.historical = ##METADATEN WASSERSPIEGELLAGE historisch
+sinfo.export.csv.meta.header.waterlevel.historical = ##METADATEN WASSERSPIEGELLAGE historisch																			
 sinfo.export.csv.header.flowdepth.development = Flie\u00dftiefenentwicklung
 sinfo.export.pdf.header.flowdepth.development = Flie\u00dftiefen-entwicklung
 sinfo.export.csv.header.flowdepth.development.per.year = Flie\u00dftiefenent-wicklung pro Jahr
@@ -1019,6 +1025,9 @@
 flowdepthdevelopmentcalculation.yearDifferenceCurrent = aktuelles Differenzenpaar
 flowdepthdevelopmentcalculation.yearDifferenceHistorical =  = historisches Differenzenpaar
 
+state.uinfo.inundation.vegetation=Einteilung der Vegetationszonen und \u00dcberflutunsgdauern
+state.uinfo.inundation.use_scenario=Szenariobetrachtung
+state.uinfo.inundation.scenario = Werte f\u00fcr \u00c4nderung der Sohl- bzw. Mittelwasserlage eingeben
 state.uinfo.use_scenario=Szenariobetrachtung
 useScenario.option = Zus\u00e4tzlich Szenariobetrachtung miteinbeziehen?
 useScenario.active = Activ
@@ -1036,7 +1045,6 @@
 
 state.uinfo.distance_only = Range selection
 help.state.uinfo.distance_only = ${help.url}/OnlineHilfe/UINFO#help.state.uinfo.distance_only
-
 uinfo_salix_line = Salix-Linie
 uinfo_inundation_duration = \u00dcberflutungsdauern Aue
 uinfo_vegetation_zones = Vegetationszonen
diff -r 5198066492a9 -r b6919e3c2d86 artifacts/src/main/resources/messages_de.properties
--- a/artifacts/src/main/resources/messages_de.properties	Mon May 07 17:25:53 2018 +0200
+++ b/artifacts/src/main/resources/messages_de.properties	Tue May 08 15:21:23 2018 +0200
@@ -75,11 +75,18 @@
 state.minfo.t_per_a = t/a
 state.minfo.m3_per_a = m\u00b3/a
 
+state.uinfo.year_epoch = Jahr/Epoche
+state.uinfo.load.year= Jahr
+state.uinfo.load.epoch=Epoche
+state.uinfo.year=Jahr
+state.uinfo.epoch=Epoche
+
 state.sinfo.year_epoch = Jahr/Epoche
 state.sinfo.load.year= Jahr(e)
 state.sinfo.load.epoch=Epoche(n)
 state.sinfo.year=Jahr
 state.sinfo.epoch=Epoche
+
 state.sinfo.riverside.left = Linkes Ufer
 state.sinfo.riverside.right = Rechtes Ufer
 state.sinfo.riverside.both = Beide Ufer
@@ -861,8 +868,7 @@
 state.sinfo.wspl.option = Wasserspiegellagen zus\u00e4tzlich darstellen?
 state.sinfo.wspl.active = Ja
 state.sinfo.wspl.inactive = Nein
-help.state.sinfo.wspl= ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.wspll
-   
+help.state.sinfo.wspl= ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.wspl   
 state.sinfo.grounding.year = Jahr/Zeitraum
 state.sinfo.grounding.year.option1 = Jahr
 state.sinfo.grounding.year.option1 = Zeitraum
@@ -1002,7 +1008,7 @@
 sinfo.export.csv.meta.header.waterlevel.current = ##METADATEN WASSERSPIEGELLAGE aktuell
 sinfo.export.csv.meta.header.waterlevel.historical = ##METADATEN WASSERSPIEGELLAGE historisch
 sinfo.export.pdf.header.flowdepth.development = Flie\u00dftiefen-entwicklung
-sinfo.export.csv.header.flowdepth.development = Flie\u00dftiefenentwicklung
+sinfo.export.csv.header.flowdepth.development = Flie\u00dftiefenentwicklung																			
 sinfo.export.csv.header.flowdepth.development.per.year = Flie\u00dftiefenent-wicklung pro Jahr
 sinfo.export.csv.header.waterlevel.difference = \u0394WSPL
 sinfo.export.pdf.header.waterlevel.difference = dWSPL
@@ -1019,6 +1025,9 @@
 flowdepthdevelopmentcalculation.yearDifferenceCurrent = aktuelles Differenzenpaar
 flowdepthdevelopmentcalculation.yearDifferenceHistorical =  = historisches Differenzenpaar
 
+state.uinfo.inundation.vegetation=Einteilung der Vegetationszonen und \u00dcberflutunsgdauern
+state.uinfo.inundation.use_scenario=Szenariobetrachtung
+state.uinfo.inundation.scenario = Werte f\u00fcr \u00c4nderung der Sohl- bzw. Mittelwasserlage eingeben
 state.uinfo.use_scenario=Szenariobetrachtung
 useScenario.option = Zus\u00e4tzlich Szenariobetrachtung miteinbeziehen?
 useScenario.active = Ja
@@ -1036,7 +1045,6 @@
 
 state.uinfo.distance_only = Wahl der Berechnungsstrecke
 help.state.uinfo.distance_only = ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.distance_only
- 
 uinfo_salix_line = Salix-Linie
 uinfo_inundation_duration = \u00dcberflutungsdauern Aue
 uinfo_vegetation_zones = Vegetationszonen
@@ -1059,7 +1067,7 @@
 uinfo.export.csv.meta.header.salix.historical = ##Historische Betrachtung
 uinfo.export.csv.meta.header.salix.historical.zeitpunkt = # Historischer Zeitpunkt
 uinfo.export.csv.meta.header.salix.historical.zeitart = # Art des Zeitraums
- uinfo.export.csv.meta.header.veg.name = Vegetationszonen
+uinfo.export.csv.meta.header.veg.name = Vegetationszonen
 uinfo.export.csv.meta.header.veg.dauervon = \u00dcberflutungsdauer von [d/a]
 uinfo.export.csv.meta.header.veg.dauerbis = \u00dcberflutungsdauer bis [d/a]
 
diff -r 5198066492a9 -r b6919e3c2d86 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/RadioPanel.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/RadioPanel.java	Mon May 07 17:25:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/RadioPanel.java	Tue May 08 15:21:23 2018 +0200
@@ -8,14 +8,7 @@
 
 package org.dive4elements.river.client.client.ui;
 
-import com.google.gwt.core.client.GWT;
-
-import com.smartgwt.client.widgets.Canvas;
-import com.smartgwt.client.widgets.Label;
-import com.smartgwt.client.widgets.form.DynamicForm;
-import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
-import com.smartgwt.client.widgets.layout.HLayout;
-import com.smartgwt.client.widgets.layout.VLayout;
+import java.util.LinkedHashMap;
 
 import org.dive4elements.river.client.shared.model.Data;
 import org.dive4elements.river.client.shared.model.DataItem;
@@ -23,7 +16,13 @@
 import org.dive4elements.river.client.shared.model.DefaultData;
 import org.dive4elements.river.client.shared.model.DefaultDataItem;
 
-import java.util.LinkedHashMap;
+import com.google.gwt.core.client.GWT;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
 
 public class RadioPanel extends AbstractUIProvider {
 
@@ -33,15 +32,15 @@
     protected DynamicForm form;
 
     @Override
-    public Canvas createOld(DataList dataList) {
-        Data       data  = dataList.get(0);
-        DataItem[] items = data.getItems();
+    public Canvas createOld(final DataList dataList) {
+        final Data data = dataList.get(0);
+        final DataItem[] items = data.getItems();
 
-        HLayout layout = new HLayout();
-        Label   label  = new Label(dataList.getLabel());
-        Label   value  = new Label(items[0].getLabel());
+        final HLayout layout = new HLayout();
+        final Label label = new Label(dataList.getLabel());
+        final Label value = new Label(items[0].getLabel());
 
-        layout.setHeight(35);
+        layout.setHeight(35); // hat Einfluss auf Layout in der Übersicht (oben) nach Setzen des Wertes für den State
         layout.setWidth(400);
         label.setWidth(200);
 
@@ -53,52 +52,49 @@
     }
 
     @Override
-    public Canvas create(DataList dataList) {
-        Data       data  = dataList.get(0);
-        DataItem[] items = data.getItems();
+    public Canvas create(final DataList dataList) {
+        final Data data = dataList.get(0);
+        final DataItem[] items = data.getItems();
 
         this.dataName = data.getLabel();
 
-        VLayout layout = new VLayout();
-        Label   label  = new Label(data.getDescription());
-        RadioGroupItem rgi = new RadioGroupItem("selection");
+        final VLayout layout = new VLayout();
+        final Label label = new Label(data.getDescription());
+        final RadioGroupItem rgi = new RadioGroupItem("selection");
         rgi.setShowTitle(false);
         GWT.log("items: " + items.length);
-        LinkedHashMap<String, String> elems =
-            new LinkedHashMap<String, String>();
-        for (int i = 0; i < items.length; i++) {
-            GWT.log(items[i].getStringValue() + "; " + items[i].getLabel());
-            elems.put(items[i].getStringValue(), items[i].getLabel());
+        final LinkedHashMap<String, String> elems = new LinkedHashMap<String, String>();
+        for (final DataItem item : items) {
+            GWT.log(item.getStringValue() + "; " + item.getLabel());
+            elems.put(item.getStringValue(), item.getLabel());
         }
         rgi.setValueMap(elems);
         rgi.setDefaultValue(items[0].getStringValue());
 
-        form = new DynamicForm();
-        form.setFields(rgi);
+        this.form = new DynamicForm();
+        this.form.setFields(rgi);
         layout.setMembersMargin(10);
         layout.setHeight(35);
         label.setHeight(35);
 
         layout.addMember(label);
-        layout.addMember(form);
+        layout.addMember(this.form);
         layout.addMember(getNextButton());
         layout.setMembersMargin(10);
 
-        //initDefaultValues(dataList);
+        // initDefaultValues(dataList);
 
         return layout;
     }
 
     @Override
     protected Data[] getData() {
-        String value = form.getValueAsString("selection");
-        DataItem item = new DefaultDataItem(
-            this.dataName, this.dataName, value);
-        return new Data[] { new DefaultData(
-            this.dataName, null, null, new DataItem[]{item})};
+        final String value = this.form.getValueAsString("selection");
+        final DataItem item = new DefaultDataItem(this.dataName, this.dataName, value);
+        return new Data[] { new DefaultData(this.dataName, null, null, new DataItem[] { item }) };
     }
 
-    protected String getTitle(DataItem item) {
+    protected String getTitle(final DataItem item) {
         return item.getLabel();
     }
 }
diff -r 5198066492a9 -r b6919e3c2d86 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java	Mon May 07 17:25:53 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/UIProviderFactory.java	Tue May 08 15:21:23 2018 +0200
@@ -22,9 +22,13 @@
 import org.dive4elements.river.client.client.ui.minfo.SedLoadEpochPanel;
 import org.dive4elements.river.client.client.ui.minfo.SedLoadPeriodPanel;
 import org.dive4elements.river.client.client.ui.minfo.SedLoadSQTiPanel;
+import org.dive4elements.river.client.client.ui.sinfo.CollisionLoadEpochPanel;
 import org.dive4elements.river.client.client.ui.sinfo.FlowDepthMinMaxTwinPanel;
 import org.dive4elements.river.client.client.ui.sinfo.FlowDepthTwinPanel;
 import org.dive4elements.river.client.client.ui.sq.SQPeriodPanel;
+import org.dive4elements.river.client.client.ui.uinfo.InundationDurLoadEpochPanel;
+import org.dive4elements.river.client.client.ui.uinfo.LoadSingleEpochPanel;
+import org.dive4elements.river.client.client.ui.uinfo.LoadSingleYearPanel;
 import org.dive4elements.river.client.shared.model.User;
 
 /**
@@ -143,6 +147,14 @@
             return new SedLoadPeriodPanel();
         } else if (uiProvider.equals("minfo.sedimentload_epoch_select")) {
             return new SedLoadEpochPanel();
+        } else if (uiProvider.equals("sinfo.collision.load_epoch_select")) {
+            return new CollisionLoadEpochPanel();
+        } else if (uiProvider.equals("uinfo.inundation_duration.load_epoch_select")) {
+            return new InundationDurLoadEpochPanel();
+        } else if (uiProvider.equals("uinfo.inundationduration.load_year_select")) {
+            return new LoadSingleYearPanel();
+        } else if (uiProvider.equals("uinfo.inundationduration.load_epoch_select")) {
+            return new LoadSingleEpochPanel();
         } else if (uiProvider.equals("minfo.sedimentload_sqti_select")) {
             return new SedLoadSQTiPanel();
         } else if (uiProvider.equals("hws_datacage_panel")) {
diff -r 5198066492a9 -r b6919e3c2d86 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/CollisionLoadEpochPanel.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/sinfo/CollisionLoadEpochPanel.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,383 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.client.client.ui.sinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dive4elements.river.client.client.Config;
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.services.SedimentLoadInfoService;
+import org.dive4elements.river.client.client.services.SedimentLoadInfoServiceAsync;
+import org.dive4elements.river.client.client.ui.AbstractUIProvider;
+import org.dive4elements.river.client.shared.model.ArtifactDescription;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.DefaultData;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.SedimentLoadInfoObject;
+import org.dive4elements.river.client.shared.model.SedimentLoadInfoRecord;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Button;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.validator.IsIntegerValidator;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+public class CollisionLoadEpochPanel extends AbstractUIProvider {
+    protected SedimentLoadInfoServiceAsync sedLoadInfoService = GWT.create(SedimentLoadInfoService.class);
+
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    protected ListGrid elements;
+    private TextItem start;
+    private TextItem end;
+    private ListGrid sedLoadTable; // TODO: Datenquelle für Collision richtig wählen! Sediment komplett eliminieren
+
+    protected List<String> validYears;
+
+    public Canvas createWidget(final DataList data) {
+        final HLayout input = new HLayout();
+        final VLayout root = new VLayout();
+        final VLayout grid = new VLayout();
+        final VLayout intFields = new VLayout();
+        final Button add = new Button(this.MSG.add_date());
+        this.elements = new ListGrid();
+
+        final Label title = new Label(data.get(0).getDescription());
+        title.setHeight("25px");
+
+        final DynamicForm form = new DynamicForm();
+        form.setNumCols(4);
+        this.start = new TextItem(this.MSG.from());
+        this.start.setWidth(60);
+        this.start.setValidators(new IsIntegerValidator());
+        this.end = new TextItem(this.MSG.to());
+        this.end.setWidth(60);
+        this.end.setValidators(new IsIntegerValidator());
+        form.setFields(this.start, this.end);
+        add.addClickHandler(new ClickHandler() {
+            @Override
+            public void onClick(final ClickEvent ce) {
+                final String v1 = CollisionLoadEpochPanel.this.start.getValueAsString();
+                final String v2 = CollisionLoadEpochPanel.this.end.getValueAsString();
+                if (v1 == null || v2 == null) {
+                    return;
+                }
+                if (!isValidEpoch(v1, v2)) {
+                    return;
+                }
+                final ListGridRecord r = new ListGridRecord();
+                r.setAttribute("from", v1);
+                r.setAttribute("to", v2);
+                CollisionLoadEpochPanel.this.elements.addData(r);
+            }
+        });
+
+        final Label sel = new Label(this.MSG.select());
+        sel.setHeight(25);
+        this.elements.setWidth(185);
+        this.elements.setHeight(120);
+        this.elements.setShowHeaderContextMenu(false);
+        this.elements.setCanReorderFields(false);
+        this.elements.setCanSort(false);
+        this.elements.setCanEdit(false);
+        final ListGridField from = new ListGridField("from", this.MSG.from());
+        final ListGridField to = new ListGridField("to", this.MSG.to());
+        from.setWidth(70);
+        to.setWidth(70);
+
+        final ListGridField removeField = new ListGridField("_removeRecord", "Remove Record") {
+            {
+                setType(ListGridFieldType.ICON);
+                setIcon(GWT.getHostPageBaseURL() + CollisionLoadEpochPanel.this.MSG.removeFeature());
+                setCanEdit(false);
+                setCanFilter(false);
+                setCanSort(false);
+                setCanGroupBy(false);
+                setCanFreeze(false);
+                setWidth(25);
+            }
+        };
+
+        this.elements.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent event) {
+                // Just handle remove-clicks
+                if (!event.getField().getName().equals(removeField.getName())) {
+                    return;
+                }
+                event.getViewer().removeData(event.getRecord());
+            }
+        });
+
+        this.elements.setFields(from, to, removeField);
+
+        intFields.addMember(form);
+        intFields.addMember(add);
+        grid.addMember(sel);
+        grid.addMember(this.elements);
+        input.addMember(intFields);
+        input.addMember(grid);
+        root.addMember(title);
+        root.addMember(input);
+
+        return root;
+    }
+
+    @Override
+    public Canvas createOld(final DataList dataList) {
+        final HLayout layout = new HLayout();
+        layout.setWidth("400px");
+        final VLayout vLayout = new VLayout();
+        vLayout.setWidth(130);
+        final Label label = new Label(dataList.getLabel());
+        label.setWidth("200px");
+        label.setHeight(25);
+
+        final List<Data> items = dataList.getAll();
+        final Data str = getData(items, "epochs");
+        final DataItem[] strItems = str.getItems();
+
+        final String[] pairs = strItems[0].getLabel().split(";");
+        for (final String pair : pairs) {
+            final String[] vals = pair.split(",");
+            final Label dateLabel = new Label(vals[0] + " - " + vals[1]);
+            dateLabel.setHeight(20);
+            vLayout.addMember(dateLabel);
+        }
+        final Canvas back = getBackButton(dataList.getState());
+        layout.addMember(label);
+        layout.addMember(vLayout);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+    @Override
+    public Canvas create(final DataList data) {
+        final VLayout layout = new VLayout();
+        final Canvas helper = createHelper();
+        this.helperContainer.addMember(helper);
+
+        final Canvas submit = getNextButton();
+        final Canvas widget = createWidget(data);
+
+        layout.addMember(widget);
+        layout.addMember(submit);
+
+        fetchSedimentLoadData();
+
+        return layout;
+    }
+
+    private Canvas createHelper() {
+        this.sedLoadTable = new ListGrid();
+        this.sedLoadTable.setShowHeaderContextMenu(false);
+        this.sedLoadTable.setWidth100();
+        this.sedLoadTable.setShowRecordComponents(true);
+        this.sedLoadTable.setShowRecordComponentsByCell(true);
+        this.sedLoadTable.setHeight100();
+        this.sedLoadTable.setEmptyMessage(this.MSG.empty_table());
+        this.sedLoadTable.setCanReorderFields(false);
+
+        /* Input support pins */
+        final String baseUrl = GWT.getHostPageBaseURL();
+        final ListGridField pinFrom = new ListGridField("fromIcon", this.MESSAGES.from());
+        pinFrom.setWidth(30);
+        pinFrom.setType(ListGridFieldType.ICON);
+        pinFrom.setCellIcon(baseUrl + this.MESSAGES.markerGreen());
+
+        final ListGridField pinTo = new ListGridField("toIcon", this.MESSAGES.to());
+        pinTo.setType(ListGridFieldType.ICON);
+        pinTo.setWidth(30);
+        pinTo.setCellIcon(baseUrl + this.MESSAGES.markerRed());
+
+        pinFrom.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent e) {
+                final Record r = e.getRecord();
+                CollisionLoadEpochPanel.this.start.setValue(r.getAttribute("date"));
+            }
+        });
+
+        pinTo.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent e) {
+                final Record r = e.getRecord();
+                CollisionLoadEpochPanel.this.end.setValue(r.getAttribute("date"));
+            }
+        });
+
+        final ListGridField date = new ListGridField("date", this.MSG.year());
+        date.setType(ListGridFieldType.TEXT);
+        date.setWidth(100);
+
+        final ListGridField descr = new ListGridField("description", this.MSG.description());
+        descr.setType(ListGridFieldType.TEXT);
+        descr.setWidth("*");
+
+        this.sedLoadTable.setFields(pinFrom, pinTo, date, descr);
+        return this.sedLoadTable;
+    }
+
+    @Override
+    protected Data[] getData() {
+        final List<Data> data = new ArrayList<Data>();
+
+        final ListGridRecord[] lgr = this.elements.getRecords();
+        if (lgr.length == 0) {
+            return new Data[0];
+        }
+        String d = "";
+        for (final ListGridRecord element : lgr) {
+            final Record r = element;
+            d += r.getAttribute("from") + "," + r.getAttribute("to");
+            d += ";";
+        }
+
+        final DataItem item = new DefaultDataItem("epochs", null, d);
+        data.add(new DefaultData("epochs", null, null, new DataItem[] { item }));
+        return data.toArray(new Data[data.size()]);
+    }
+
+    protected void fetchSedimentLoadData() {
+        final Config config = Config.getInstance();
+        final String locale = config.getLocale();
+
+        final ArtifactDescription adescr = this.artifact.getArtifactDescription();
+        final DataList[] data = adescr.getOldData();
+
+        final double[] km = this.artifact.getArtifactDescription().getKMRange();
+        final String river = this.artifact.getArtifactDescription().getRiver();
+
+        String sq_ti_id = "";
+        this.validYears = new ArrayList<String>(data.length);
+        for (final DataList element : data) {
+            final Data str = getData(element.getAll(), "sq_ti_id");
+            if (str != null) {
+                final DataItem[] strItems = str.getItems();
+                sq_ti_id = strItems[0].getStringValue();
+                break;
+            }
+        }
+
+        if (sq_ti_id.isEmpty()) {
+            GWT.log("Failed to find sq time interval id in data.");
+        }
+
+        this.sedLoadInfoService.getSedimentLoadInfo(locale, river, "single", km[0], km[1], sq_ti_id, new AsyncCallback<SedimentLoadInfoObject[]>() {
+            @Override
+            public void onFailure(final Throwable caught) {
+                GWT.log("Could not recieve sediment load informations.");
+                SC.warn(CollisionLoadEpochPanel.this.MSG.getString(caught.getMessage()));
+            }
+
+            @Override
+            public void onSuccess(final SedimentLoadInfoObject[] sedLoad) {
+                final int num = sedLoad != null ? sedLoad.length : 0;
+                GWT.log("Recieved " + num + " sediment load informations.");
+
+                if (num == 0) {
+                    return;
+                }
+
+                addSedimentLoadInfo(sedLoad);
+            }
+        });
+    }
+
+    protected void addSedimentLoadInfo(final SedimentLoadInfoObject[] sedLoad) {
+        for (final SedimentLoadInfoObject sl : sedLoad) {
+            final SedimentLoadInfoRecord rec = new SedimentLoadInfoRecord(sl);
+            this.sedLoadTable.addData(rec);
+            this.validYears.add(rec.getDate());
+        }
+    }
+
+    /*
+     * Validate the epoch input. We do this here and not in an overridden
+     * validate method as we want to validate before an epoch is added
+     * to the list of epochs.
+     */
+    protected boolean isValidEpoch(final String y1, final String y2) {
+        // First check that both are integer
+        int iY1;
+        int iY2;
+        final List<String> errors = new ArrayList<String>();
+        try {
+            iY1 = Integer.parseInt(y1);
+        }
+        catch (final NumberFormatException e) {
+            errors.add(this.MESSAGES.wrongFormat() + ": " + y1);
+        }
+        try {
+            iY2 = Integer.parseInt(y2);
+        }
+        catch (final NumberFormatException e) {
+            errors.add(this.MESSAGES.wrongFormat() + ": " + y2);
+        }
+        if (!errors.isEmpty()) {
+            showErrors(errors);
+            return false;
+        }
+        boolean startIsGood = false;
+        boolean endIsGood = false;
+        for (final String validYear : this.validYears) {
+            if (startIsGood || y1.equals(validYear)) {
+                startIsGood = true;
+            }
+            if (endIsGood || y2.equals(validYear)) {
+                endIsGood = true;
+            }
+            if (startIsGood && endIsGood) {
+                break;
+            }
+            /*
+             * alternative check if data lies in between
+             * int aYear = Integer.parseInt(validYear);
+             * if (aYear >= iY1 && aYear <= iY2) {
+             * isGood = true;
+             * break;
+             * }
+             */
+        }
+        if (!startIsGood) {
+            String tmp = this.MESSAGES.no_data_for_year();
+            tmp = tmp.replace("$1", y1);
+            errors.add(tmp);
+        }
+        if (!endIsGood) {
+            String tmp = this.MESSAGES.no_data_for_year();
+            tmp = tmp.replace("$1", y2);
+            errors.add(tmp);
+        }
+        if (!errors.isEmpty()) {
+            showErrors(errors);
+            return false;
+        }
+        return true;
+    }
+}
diff -r 5198066492a9 -r b6919e3c2d86 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/InundationDurLoadEpochPanel.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/InundationDurLoadEpochPanel.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,383 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.client.client.ui.uinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dive4elements.river.client.client.Config;
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.services.SedimentLoadInfoService;
+import org.dive4elements.river.client.client.services.SedimentLoadInfoServiceAsync;
+import org.dive4elements.river.client.client.ui.AbstractUIProvider;
+import org.dive4elements.river.client.shared.model.ArtifactDescription;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.DefaultData;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.SedimentLoadInfoObject;
+import org.dive4elements.river.client.shared.model.SedimentLoadInfoRecord;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Button;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.validator.IsIntegerValidator;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+public class InundationDurLoadEpochPanel extends AbstractUIProvider {
+    protected SedimentLoadInfoServiceAsync sedLoadInfoService = GWT.create(SedimentLoadInfoService.class);
+
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    protected ListGrid elements;
+    private TextItem start;
+    private TextItem end;
+    private ListGrid sedLoadTable; // TODO: Datenquelle für Collision richtig wählen! Sediment komplett eliminieren
+
+    protected List<String> validYears;
+
+    public Canvas createWidget(final DataList data) {
+        final HLayout input = new HLayout();
+        final VLayout root = new VLayout();
+        final VLayout grid = new VLayout();
+        final VLayout intFields = new VLayout();
+        final Button add = new Button(this.MSG.add_date());
+        this.elements = new ListGrid();
+
+        final Label title = new Label(data.get(0).getDescription());
+        title.setHeight("25px");
+
+        final DynamicForm form = new DynamicForm();
+        form.setNumCols(4);
+        this.start = new TextItem(this.MSG.from());
+        this.start.setWidth(60);
+        this.start.setValidators(new IsIntegerValidator());
+        this.end = new TextItem(this.MSG.to());
+        this.end.setWidth(60);
+        this.end.setValidators(new IsIntegerValidator());
+        form.setFields(this.start, this.end);
+        add.addClickHandler(new ClickHandler() {
+            @Override
+            public void onClick(final ClickEvent ce) {
+                final String v1 = InundationDurLoadEpochPanel.this.start.getValueAsString();
+                final String v2 = InundationDurLoadEpochPanel.this.end.getValueAsString();
+                if (v1 == null || v2 == null) {
+                    return;
+                }
+                if (!isValidEpoch(v1, v2)) {
+                    return;
+                }
+                final ListGridRecord r = new ListGridRecord();
+                r.setAttribute("from", v1);
+                r.setAttribute("to", v2);
+                InundationDurLoadEpochPanel.this.elements.addData(r);
+            }
+        });
+
+        final Label sel = new Label(this.MSG.select());
+        sel.setHeight(25);
+        this.elements.setWidth(185);
+        this.elements.setHeight(120);
+        this.elements.setShowHeaderContextMenu(false);
+        this.elements.setCanReorderFields(false);
+        this.elements.setCanSort(false);
+        this.elements.setCanEdit(false);
+        final ListGridField from = new ListGridField("from", this.MSG.from());
+        final ListGridField to = new ListGridField("to", this.MSG.to());
+        from.setWidth(70);
+        to.setWidth(70);
+
+        final ListGridField removeField = new ListGridField("_removeRecord", "Remove Record") {
+            {
+                setType(ListGridFieldType.ICON);
+                setIcon(GWT.getHostPageBaseURL() + InundationDurLoadEpochPanel.this.MSG.removeFeature());
+                setCanEdit(false);
+                setCanFilter(false);
+                setCanSort(false);
+                setCanGroupBy(false);
+                setCanFreeze(false);
+                setWidth(25);
+            }
+        };
+
+        this.elements.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent event) {
+                // Just handle remove-clicks
+                if (!event.getField().getName().equals(removeField.getName())) {
+                    return;
+                }
+                event.getViewer().removeData(event.getRecord());
+            }
+        });
+
+        this.elements.setFields(from, to, removeField);
+
+        intFields.addMember(form);
+        intFields.addMember(add);
+        grid.addMember(sel);
+        grid.addMember(this.elements);
+        input.addMember(intFields);
+        input.addMember(grid);
+        root.addMember(title);
+        root.addMember(input);
+
+        return root;
+    }
+
+    @Override
+    public Canvas createOld(final DataList dataList) {
+        final HLayout layout = new HLayout();
+        layout.setWidth("400px");
+        final VLayout vLayout = new VLayout();
+        vLayout.setWidth(130);
+        final Label label = new Label(dataList.getLabel());
+        label.setWidth("200px");
+        label.setHeight(25);
+
+        final List<Data> items = dataList.getAll();
+        final Data str = getData(items, "epochs");
+        final DataItem[] strItems = str.getItems();
+
+        final String[] pairs = strItems[0].getLabel().split(";");
+        for (final String pair : pairs) {
+            final String[] vals = pair.split(",");
+            final Label dateLabel = new Label(vals[0] + " - " + vals[1]);
+            dateLabel.setHeight(20);
+            vLayout.addMember(dateLabel);
+        }
+        final Canvas back = getBackButton(dataList.getState());
+        layout.addMember(label);
+        layout.addMember(vLayout);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+    @Override
+    public Canvas create(final DataList data) {
+        final VLayout layout = new VLayout();
+        final Canvas helper = createHelper();
+        this.helperContainer.addMember(helper);
+
+        final Canvas submit = getNextButton();
+        final Canvas widget = createWidget(data);
+
+        layout.addMember(widget);
+        layout.addMember(submit);
+
+        fetchSedimentLoadData();
+
+        return layout;
+    }
+
+    private Canvas createHelper() {
+        this.sedLoadTable = new ListGrid();
+        this.sedLoadTable.setShowHeaderContextMenu(false);
+        this.sedLoadTable.setWidth100();
+        this.sedLoadTable.setShowRecordComponents(true);
+        this.sedLoadTable.setShowRecordComponentsByCell(true);
+        this.sedLoadTable.setHeight100();
+        this.sedLoadTable.setEmptyMessage(this.MSG.empty_table());
+        this.sedLoadTable.setCanReorderFields(false);
+
+        /* Input support pins */
+        final String baseUrl = GWT.getHostPageBaseURL();
+        final ListGridField pinFrom = new ListGridField("fromIcon", this.MESSAGES.from());
+        pinFrom.setWidth(30);
+        pinFrom.setType(ListGridFieldType.ICON);
+        pinFrom.setCellIcon(baseUrl + this.MESSAGES.markerGreen());
+
+        final ListGridField pinTo = new ListGridField("toIcon", this.MESSAGES.to());
+        pinTo.setType(ListGridFieldType.ICON);
+        pinTo.setWidth(30);
+        pinTo.setCellIcon(baseUrl + this.MESSAGES.markerRed());
+
+        pinFrom.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent e) {
+                final Record r = e.getRecord();
+                InundationDurLoadEpochPanel.this.start.setValue(r.getAttribute("date"));
+            }
+        });
+
+        pinTo.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent e) {
+                final Record r = e.getRecord();
+                InundationDurLoadEpochPanel.this.end.setValue(r.getAttribute("date"));
+            }
+        });
+
+        final ListGridField date = new ListGridField("date", this.MSG.year());
+        date.setType(ListGridFieldType.TEXT);
+        date.setWidth(100);
+
+        final ListGridField descr = new ListGridField("description", this.MSG.description());
+        descr.setType(ListGridFieldType.TEXT);
+        descr.setWidth("*");
+
+        this.sedLoadTable.setFields(pinFrom, pinTo, date, descr);
+        return this.sedLoadTable;
+    }
+
+    @Override
+    protected Data[] getData() {
+        final List<Data> data = new ArrayList<Data>();
+
+        final ListGridRecord[] lgr = this.elements.getRecords();
+        if (lgr.length == 0) {
+            return new Data[0];
+        }
+        String d = "";
+        for (final ListGridRecord element : lgr) {
+            final Record r = element;
+            d += r.getAttribute("from") + "," + r.getAttribute("to");
+            d += ";";
+        }
+
+        final DataItem item = new DefaultDataItem("epochs", null, d);
+        data.add(new DefaultData("epochs", null, null, new DataItem[] { item }));
+        return data.toArray(new Data[data.size()]);
+    }
+
+    protected void fetchSedimentLoadData() {
+        final Config config = Config.getInstance();
+        final String locale = config.getLocale();
+
+        final ArtifactDescription adescr = this.artifact.getArtifactDescription();
+        final DataList[] data = adescr.getOldData();
+
+        final double[] km = this.artifact.getArtifactDescription().getKMRange();
+        final String river = this.artifact.getArtifactDescription().getRiver();
+
+        String sq_ti_id = "";
+        this.validYears = new ArrayList<String>(data.length);
+        for (final DataList element : data) {
+            final Data str = getData(element.getAll(), "sq_ti_id");
+            if (str != null) {
+                final DataItem[] strItems = str.getItems();
+                sq_ti_id = strItems[0].getStringValue();
+                break;
+            }
+        }
+
+        if (sq_ti_id.isEmpty()) {
+            GWT.log("Failed to find sq time interval id in data.");
+        }
+
+        this.sedLoadInfoService.getSedimentLoadInfo(locale, river, "single", km[0], km[1], sq_ti_id, new AsyncCallback<SedimentLoadInfoObject[]>() {
+            @Override
+            public void onFailure(final Throwable caught) {
+                GWT.log("Could not recieve sediment load informations.");
+                SC.warn(InundationDurLoadEpochPanel.this.MSG.getString(caught.getMessage()));
+            }
+
+            @Override
+            public void onSuccess(final SedimentLoadInfoObject[] sedLoad) {
+                final int num = sedLoad != null ? sedLoad.length : 0;
+                GWT.log("Recieved " + num + " sediment load informations.");
+
+                if (num == 0) {
+                    return;
+                }
+
+                addSedimentLoadInfo(sedLoad);
+            }
+        });
+    }
+
+    protected void addSedimentLoadInfo(final SedimentLoadInfoObject[] sedLoad) {
+        for (final SedimentLoadInfoObject sl : sedLoad) {
+            final SedimentLoadInfoRecord rec = new SedimentLoadInfoRecord(sl);
+            this.sedLoadTable.addData(rec);
+            this.validYears.add(rec.getDate());
+        }
+    }
+
+    /*
+     * Validate the epoch input. We do this here and not in an overridden
+     * validate method as we want to validate before an epoch is added
+     * to the list of epochs.
+     */
+    protected boolean isValidEpoch(final String y1, final String y2) {
+        // First check that both are integer
+        int iY1;
+        int iY2;
+        final List<String> errors = new ArrayList<String>();
+        try {
+            iY1 = Integer.parseInt(y1);
+        }
+        catch (final NumberFormatException e) {
+            errors.add(this.MESSAGES.wrongFormat() + ": " + y1);
+        }
+        try {
+            iY2 = Integer.parseInt(y2);
+        }
+        catch (final NumberFormatException e) {
+            errors.add(this.MESSAGES.wrongFormat() + ": " + y2);
+        }
+        if (!errors.isEmpty()) {
+            showErrors(errors);
+            return false;
+        }
+        boolean startIsGood = false;
+        boolean endIsGood = false;
+        for (final String validYear : this.validYears) {
+            if (startIsGood || y1.equals(validYear)) {
+                startIsGood = true;
+            }
+            if (endIsGood || y2.equals(validYear)) {
+                endIsGood = true;
+            }
+            if (startIsGood && endIsGood) {
+                break;
+            }
+            /*
+             * alternative check if data lies in between
+             * int aYear = Integer.parseInt(validYear);
+             * if (aYear >= iY1 && aYear <= iY2) {
+             * isGood = true;
+             * break;
+             * }
+             */
+        }
+        if (!startIsGood) {
+            String tmp = this.MESSAGES.no_data_for_year();
+            tmp = tmp.replace("$1", y1);
+            errors.add(tmp);
+        }
+        if (!endIsGood) {
+            String tmp = this.MESSAGES.no_data_for_year();
+            tmp = tmp.replace("$1", y2);
+            errors.add(tmp);
+        }
+        if (!errors.isEmpty()) {
+            showErrors(errors);
+            return false;
+        }
+        return true;
+    }
+}
diff -r 5198066492a9 -r b6919e3c2d86 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/LoadSingleEpochPanel.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/LoadSingleEpochPanel.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,383 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.client.client.ui.uinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dive4elements.river.client.client.Config;
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.services.SedimentLoadInfoService;
+import org.dive4elements.river.client.client.services.SedimentLoadInfoServiceAsync;
+import org.dive4elements.river.client.client.ui.AbstractUIProvider;
+import org.dive4elements.river.client.shared.model.ArtifactDescription;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.DefaultData;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.SedimentLoadInfoObject;
+import org.dive4elements.river.client.shared.model.SedimentLoadInfoRecord;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Button;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.events.ClickEvent;
+import com.smartgwt.client.widgets.events.ClickHandler;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.validator.IsIntegerValidator;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+
+public class LoadSingleEpochPanel extends AbstractUIProvider {
+    protected SedimentLoadInfoServiceAsync sedLoadInfoService = GWT.create(SedimentLoadInfoService.class);
+
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    protected ListGrid elements;
+    private TextItem start;
+    private TextItem end;
+    private ListGrid sedLoadTable;
+
+    protected List<String> validYears;
+
+    public Canvas createWidget(final DataList data) {
+        final HLayout input = new HLayout();
+        final VLayout root = new VLayout();
+        final VLayout grid = new VLayout();
+        final VLayout intFields = new VLayout();
+        final Button add = new Button(this.MSG.add_date());
+        this.elements = new ListGrid();
+
+        final Label title = new Label(data.get(0).getDescription());
+        title.setHeight("25px");
+
+        final DynamicForm form = new DynamicForm();
+        form.setNumCols(4);
+        this.start = new TextItem(this.MSG.from());
+        this.start.setWidth(60);
+        this.start.setValidators(new IsIntegerValidator());
+        this.end = new TextItem(this.MSG.to());
+        this.end.setWidth(60);
+        this.end.setValidators(new IsIntegerValidator());
+        form.setFields(this.start, this.end);
+        add.addClickHandler(new ClickHandler() {
+            @Override
+            public void onClick(final ClickEvent ce) {
+                final String v1 = LoadSingleEpochPanel.this.start.getValueAsString();
+                final String v2 = LoadSingleEpochPanel.this.end.getValueAsString();
+                if (v1 == null || v2 == null) {
+                    return;
+                }
+                if (!isValidEpoch(v1, v2)) {
+                    return;
+                }
+                final ListGridRecord r = new ListGridRecord();
+                r.setAttribute("from", v1);
+                r.setAttribute("to", v2);
+                LoadSingleEpochPanel.this.elements.addData(r);
+            }
+        });
+
+        final Label sel = new Label(this.MSG.select());
+        sel.setHeight(25);
+        this.elements.setWidth(185);
+        this.elements.setHeight(120);
+        this.elements.setShowHeaderContextMenu(false);
+        this.elements.setCanReorderFields(false);
+        this.elements.setCanSort(false);
+        this.elements.setCanEdit(false);
+        final ListGridField from = new ListGridField("from", this.MSG.from());
+        final ListGridField to = new ListGridField("to", this.MSG.to());
+        from.setWidth(70);
+        to.setWidth(70);
+
+        final ListGridField removeField = new ListGridField("_removeRecord", "Remove Record") {
+            {
+                setType(ListGridFieldType.ICON);
+                setIcon(GWT.getHostPageBaseURL() + LoadSingleEpochPanel.this.MSG.removeFeature());
+                setCanEdit(false);
+                setCanFilter(false);
+                setCanSort(false);
+                setCanGroupBy(false);
+                setCanFreeze(false);
+                setWidth(25);
+            }
+        };
+
+        this.elements.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent event) {
+                // Just handle remove-clicks
+                if (!event.getField().getName().equals(removeField.getName())) {
+                    return;
+                }
+                event.getViewer().removeData(event.getRecord());
+            }
+        });
+
+        this.elements.setFields(from, to, removeField);
+
+        intFields.addMember(form);
+        intFields.addMember(add);
+        grid.addMember(sel);
+        grid.addMember(this.elements);
+        input.addMember(intFields);
+        input.addMember(grid);
+        root.addMember(title);
+        root.addMember(input);
+
+        return root;
+    }
+
+    @Override
+    public Canvas createOld(final DataList dataList) {
+        final HLayout layout = new HLayout();
+        layout.setWidth("400px");
+        final VLayout vLayout = new VLayout();
+        vLayout.setWidth(130);
+        final Label label = new Label(dataList.getLabel());
+        label.setWidth("200px");
+        label.setHeight(25);
+
+        final List<Data> items = dataList.getAll();
+        final Data str = getData(items, "epochs");
+        final DataItem[] strItems = str.getItems();
+
+        final String[] pairs = strItems[0].getLabel().split(";");
+        for (final String pair : pairs) {
+            final String[] vals = pair.split(",");
+            final Label dateLabel = new Label(vals[0] + " - " + vals[1]);
+            dateLabel.setHeight(20);
+            vLayout.addMember(dateLabel);
+        }
+        final Canvas back = getBackButton(dataList.getState());
+        layout.addMember(label);
+        layout.addMember(vLayout);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+    @Override
+    public Canvas create(final DataList data) {
+        final VLayout layout = new VLayout();
+        final Canvas helper = createHelper();
+        this.helperContainer.addMember(helper);
+
+        final Canvas submit = getNextButton();
+        final Canvas widget = createWidget(data);
+
+        layout.addMember(widget);
+        layout.addMember(submit);
+
+        fetchSedimentLoadData();
+
+        return layout;
+    }
+
+    private Canvas createHelper() {
+        this.sedLoadTable = new ListGrid();
+        this.sedLoadTable.setShowHeaderContextMenu(false);
+        this.sedLoadTable.setWidth100();
+        this.sedLoadTable.setShowRecordComponents(true);
+        this.sedLoadTable.setShowRecordComponentsByCell(true);
+        this.sedLoadTable.setHeight100();
+        this.sedLoadTable.setEmptyMessage(this.MSG.empty_table());
+        this.sedLoadTable.setCanReorderFields(false);
+
+        /* Input support pins */
+        final String baseUrl = GWT.getHostPageBaseURL();
+        final ListGridField pinFrom = new ListGridField("fromIcon", this.MESSAGES.from());
+        pinFrom.setWidth(30);
+        pinFrom.setType(ListGridFieldType.ICON);
+        pinFrom.setCellIcon(baseUrl + this.MESSAGES.markerGreen());
+
+        final ListGridField pinTo = new ListGridField("toIcon", this.MESSAGES.to());
+        pinTo.setType(ListGridFieldType.ICON);
+        pinTo.setWidth(30);
+        pinTo.setCellIcon(baseUrl + this.MESSAGES.markerRed());
+
+        pinFrom.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent e) {
+                final Record r = e.getRecord();
+                LoadSingleEpochPanel.this.start.setValue(r.getAttribute("date"));
+            }
+        });
+
+        pinTo.addRecordClickHandler(new RecordClickHandler() {
+            @Override
+            public void onRecordClick(final RecordClickEvent e) {
+                final Record r = e.getRecord();
+                LoadSingleEpochPanel.this.end.setValue(r.getAttribute("date"));
+            }
+        });
+
+        final ListGridField date = new ListGridField("date", this.MSG.year());
+        date.setType(ListGridFieldType.TEXT);
+        date.setWidth(100);
+
+        final ListGridField descr = new ListGridField("description", this.MSG.description());
+        descr.setType(ListGridFieldType.TEXT);
+        descr.setWidth("*");
+
+        this.sedLoadTable.setFields(pinFrom, pinTo, date, descr);
+        return this.sedLoadTable;
+    }
+
+    @Override
+    protected Data[] getData() {
+        final List<Data> data = new ArrayList<Data>();
+
+        final ListGridRecord[] lgr = this.elements.getRecords();
+        if (lgr.length == 0) {
+            return new Data[0];
+        }
+        String d = "";
+        for (final ListGridRecord element : lgr) {
+            final Record r = element;
+            d += r.getAttribute("from") + "," + r.getAttribute("to");
+            d += ";";
+        }
+
+        final DataItem item = new DefaultDataItem("epochs", null, d);
+        data.add(new DefaultData("epochs", null, null, new DataItem[] { item }));
+        return data.toArray(new Data[data.size()]);
+    }
+
+    protected void fetchSedimentLoadData() {
+        final Config config = Config.getInstance();
+        final String locale = config.getLocale();
+
+        final ArtifactDescription adescr = this.artifact.getArtifactDescription();
+        final DataList[] data = adescr.getOldData();
+
+        final double[] km = this.artifact.getArtifactDescription().getKMRange();
+        final String river = this.artifact.getArtifactDescription().getRiver();
+
+        String sq_ti_id = "";
+        this.validYears = new ArrayList<String>(data.length);
+        for (final DataList element : data) {
+            final Data str = getData(element.getAll(), "sq_ti_id");
+            if (str != null) {
+                final DataItem[] strItems = str.getItems();
+                sq_ti_id = strItems[0].getStringValue();
+                break;
+            }
+        }
+
+        if (sq_ti_id.isEmpty()) {
+            GWT.log("Failed to find sq time interval id in data.");
+        }
+
+        this.sedLoadInfoService.getSedimentLoadInfo(locale, river, "single", km[0], km[1], sq_ti_id, new AsyncCallback<SedimentLoadInfoObject[]>() {
+            @Override
+            public void onFailure(final Throwable caught) {
+                GWT.log("Could not recieve sediment load informations.");
+                SC.warn(LoadSingleEpochPanel.this.MSG.getString(caught.getMessage()));
+            }
+
+            @Override
+            public void onSuccess(final SedimentLoadInfoObject[] sedLoad) {
+                final int num = sedLoad != null ? sedLoad.length : 0;
+                GWT.log("Recieved " + num + " sediment load informations.");
+
+                if (num == 0) {
+                    return;
+                }
+
+                addSedimentLoadInfo(sedLoad);
+            }
+        });
+    }
+
+    protected void addSedimentLoadInfo(final SedimentLoadInfoObject[] sedLoad) {
+        for (final SedimentLoadInfoObject sl : sedLoad) {
+            final SedimentLoadInfoRecord rec = new SedimentLoadInfoRecord(sl);
+            this.sedLoadTable.addData(rec);
+            this.validYears.add(rec.getDate());
+        }
+    }
+
+    /*
+     * Validate the epoch input. We do this here and not in an overridden
+     * validate method as we want to validate before an epoch is added
+     * to the list of epochs.
+     */
+    protected boolean isValidEpoch(final String y1, final String y2) {
+        // First check that both are integer
+        int iY1;
+        int iY2;
+        final List<String> errors = new ArrayList<String>();
+        try {
+            iY1 = Integer.parseInt(y1);
+        }
+        catch (final NumberFormatException e) {
+            errors.add(this.MESSAGES.wrongFormat() + ": " + y1);
+        }
+        try {
+            iY2 = Integer.parseInt(y2);
+        }
+        catch (final NumberFormatException e) {
+            errors.add(this.MESSAGES.wrongFormat() + ": " + y2);
+        }
+        if (!errors.isEmpty()) {
+            showErrors(errors);
+            return false;
+        }
+        boolean startIsGood = false;
+        boolean endIsGood = false;
+        for (final String validYear : this.validYears) {
+            if (startIsGood || y1.equals(validYear)) {
+                startIsGood = true;
+            }
+            if (endIsGood || y2.equals(validYear)) {
+                endIsGood = true;
+            }
+            if (startIsGood && endIsGood) {
+                break;
+            }
+            /*
+             * alternative check if data lies in between
+             * int aYear = Integer.parseInt(validYear);
+             * if (aYear >= iY1 && aYear <= iY2) {
+             * isGood = true;
+             * break;
+             * }
+             */
+        }
+        if (!startIsGood) {
+            String tmp = this.MESSAGES.no_data_for_year();
+            tmp = tmp.replace("$1", y1);
+            errors.add(tmp);
+        }
+        if (!endIsGood) {
+            String tmp = this.MESSAGES.no_data_for_year();
+            tmp = tmp.replace("$1", y2);
+            errors.add(tmp);
+        }
+        if (!errors.isEmpty()) {
+            showErrors(errors);
+            return false;
+        }
+        return true;
+    }
+}
diff -r 5198066492a9 -r b6919e3c2d86 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/LoadSingleYearPanel.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/LoadSingleYearPanel.java	Tue May 08 15:21:23 2018 +0200
@@ -0,0 +1,296 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.client.client.ui.uinfo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.i18n.client.NumberFormat;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.Record;
+import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.util.SC;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.form.validator.IsIntegerValidator;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VLayout;
+import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
+import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
+
+import org.dive4elements.river.client.client.Config;
+import org.dive4elements.river.client.client.FLYSConstants;
+import org.dive4elements.river.client.client.services.SedimentLoadInfoService;
+import org.dive4elements.river.client.client.services.SedimentLoadInfoServiceAsync;
+import org.dive4elements.river.client.client.ui.AbstractUIProvider;
+import org.dive4elements.river.client.shared.model.ArtifactDescription;
+import org.dive4elements.river.client.shared.model.Data;
+import org.dive4elements.river.client.shared.model.DataItem;
+import org.dive4elements.river.client.shared.model.DataList;
+import org.dive4elements.river.client.shared.model.DefaultData;
+import org.dive4elements.river.client.shared.model.DefaultDataItem;
+import org.dive4elements.river.client.shared.model.SedimentLoadInfoObject;
+import org.dive4elements.river.client.shared.model.SedimentLoadInfoRecord;
+
+
+public class LoadSingleYearPanel
+extends AbstractUIProvider
+{
+    protected SedimentLoadInfoServiceAsync sedLoadInfoService =
+        GWT.create(SedimentLoadInfoService.class);
+
+    protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class);
+
+    private TextItem yearsItem;
+
+    private ListGrid sedLoadTable;
+
+    protected List<String> validYears;
+
+    public LoadSingleYearPanel () {
+    }
+
+    @Override
+    public Canvas createOld(DataList dataList) {
+        List<Data> items = dataList.getAll();
+        Data years = getData(items, "years");
+        DataItem[] yearsItems = years.getItems();
+
+        String v1 = yearsItems[0].getStringValue().replace(" ", ", ");
+
+        Label old = new Label(v1);
+        HLayout layout = new HLayout();
+        layout.setWidth("400px");
+
+        Label label = new Label(dataList.getLabel());
+        label.setWidth("200px");
+
+        Canvas back = getBackButton(dataList.getState());
+
+        layout.addMember(label);
+        layout.addMember(old);
+        layout.addMember(back);
+
+        return layout;
+    }
+
+    @Override
+    public List<String> validate() {
+        return validateYears();
+    }
+
+    @Override
+    public Canvas create(DataList data) {
+        VLayout layout = new VLayout();
+
+        Canvas helper = createHelper();
+        this.helperContainer.addMember(helper);
+
+        Canvas submit = getNextButton();
+        Canvas widget = createWidget(data);
+
+        layout.addMember(widget);
+        layout.addMember(submit);
+
+        fetchSedimentLoadData();
+
+        return layout;
+    }
+
+    private Canvas createHelper() {
+        sedLoadTable = new ListGrid();
+        sedLoadTable.setShowHeaderContextMenu(false);
+        sedLoadTable.setWidth100();
+        sedLoadTable.setShowRecordComponents(true);
+        sedLoadTable.setShowRecordComponentsByCell(true);
+        sedLoadTable.setHeight100();
+        sedLoadTable.setEmptyMessage(MSG.empty_table());
+        sedLoadTable.setCanReorderFields(false);
+
+        ListGridField date = new ListGridField("date", MSG.year());
+        date.setType(ListGridFieldType.TEXT);
+        date.setWidth(100);
+
+        ListGridField descr =
+            new ListGridField("description", MSG.description());
+        descr.setType(ListGridFieldType.TEXT);
+        descr.setWidth("*");
+
+        String baseUrl = GWT.getHostPageBaseURL();
+        ListGridField pinFrom = new ListGridField(
+            "fromIcon",  MESSAGES.selection());
+        pinFrom.setWidth (60);
+        pinFrom.setType (ListGridFieldType.ICON);
+        pinFrom.setCellIcon(baseUrl + MESSAGES.markerGreen());
+
+        pinFrom.addRecordClickHandler (new RecordClickHandler () {
+            @Override
+            public void onRecordClick (RecordClickEvent e) {
+                Record r = e.getRecord();
+                appendYear(r.getAttribute("date"));
+            }
+        });
+
+        sedLoadTable.setFields(pinFrom, date, descr);
+        return sedLoadTable;
+    }
+
+    public Canvas createWidget(DataList data) {
+        VLayout layout = new VLayout();
+
+        Label title = new Label(data.get(0).getDescription());
+        title.setHeight("25px");
+
+        DynamicForm form = new DynamicForm();
+        form.setNumCols(4);
+        yearsItem = new TextItem(MSG.years());
+        yearsItem.setValidators(new IsIntegerValidator());
+        form.setFields(yearsItem);
+
+        layout.addMember(title);
+        layout.addMember(form);
+
+        return layout;
+    }
+
+    @Override
+    protected Data[] getData() {
+        validateYears();
+        if (yearsItem != null && !yearsItem.getValueAsString().isEmpty()) {
+            List<Data> data = new ArrayList<Data>();
+
+            DataItem yearsdata = new DefaultDataItem(
+                "years", "years", yearsItem.getValueAsString().trim());
+            data.add(new DefaultData(
+                "years",
+                null,
+                null,
+                new DataItem[] { yearsdata }));
+
+            return data.toArray(new Data[data.size()]);
+        }
+        return new Data[0];
+    }
+
+    protected List<String> validateYears() {
+        List<String> errors = new ArrayList<String>();
+        NumberFormat nf     = NumberFormat.getDecimalFormat();
+
+        if (yearsItem.getValueAsString() == null ||
+                yearsItem.getValueAsString().trim().isEmpty()) {
+            errors.add(MESSAGES.empty_filter());
+            return errors;
+        }
+
+        String [] sValues = yearsItem.getValueAsString().trim().split(" ");
+        String filtered = "";
+        int goodValues = 0;
+        for (String sValue: sValues) {
+            int value;
+            try {
+                value = Integer.parseInt(sValue);
+            } catch (NumberFormatException e) {
+                errors.add(MESSAGES.wrongFormat() + ": " + sValue);
+                continue;
+            }
+            boolean isGood = false;
+            for (String validYear: validYears) {
+                /* No list contains for strings? */
+                if (sValue.equals(validYear)) {
+                    isGood = true;
+                    break;
+                }
+            }
+            if (!isGood) {
+                String tmp = MESSAGES.no_data_for_year();
+                tmp = tmp.replace("$1", sValue);
+                errors.add(tmp);
+                continue;
+            }
+            goodValues++;
+            if (goodValues > 1) {
+                filtered += " " + Integer.toString(value);
+            } else {
+                filtered = Integer.toString(value);
+            }
+        }
+
+        return errors;
+    }
+
+   protected void fetchSedimentLoadData() {
+        Config config    = Config.getInstance();
+        String locale    = config.getLocale ();
+
+        ArtifactDescription adescr = artifact.getArtifactDescription();
+        DataList[] data = adescr.getOldData();
+
+        double[] km = artifact.getArtifactDescription().getKMRange();
+        String river = artifact.getArtifactDescription().getRiver();
+
+        String sq_ti_id = "";
+        validYears = new ArrayList<String>(data.length);
+        for (int i = 0; i < data.length; i++) {
+            Data str = getData(data[i].getAll(), "sq_ti_id");
+            if (str != null) {
+                DataItem[] strItems = str.getItems();
+                sq_ti_id = strItems[0].getStringValue();
+                break;
+            }
+        }
+
+        if (sq_ti_id.isEmpty()){
+            GWT.log("Failed to find sq time interval id in data.");
+        }
+
+        sedLoadInfoService.getSedimentLoadInfo(
+            locale, river, "single", km[0], km[1], sq_ti_id,
+            new AsyncCallback<SedimentLoadInfoObject[]>() {
+                public void onFailure(Throwable caught) {
+                    GWT.log("Could not recieve sediment load informations.");
+                    SC.warn(MSG.getString(caught.getMessage()));
+                }
+
+                public void onSuccess(SedimentLoadInfoObject[] sedLoad) {
+                    int num = sedLoad != null ? sedLoad.length :0;
+                    GWT.log("Recieved " + num + " sediment load informations.");
+
+                    if (num == 0) {
+                        return;
+                    }
+
+                    addSedimentLoadInfo(sedLoad);
+                }
+            }
+        );
+    }
+
+
+    protected void addSedimentLoadInfo (SedimentLoadInfoObject[] sedLoad) {
+        for(SedimentLoadInfoObject sl: sedLoad) {
+            SedimentLoadInfoRecord rec = new SedimentLoadInfoRecord(sl);
+            sedLoadTable.addData(rec);
+            validYears.add(rec.getDate());
+        }
+    }
+
+    protected void appendYear (String year) {
+        String oldYears = yearsItem.getValueAsString();
+        if (oldYears != null && !oldYears.isEmpty()) {
+            yearsItem.setValue(oldYears.trim() + " " + year);
+        } else {
+            yearsItem.setValue(year);
+        }
+    }
+}


More information about the Dive4Elements-commits mailing list