[PATCH 1 of 2] VegetationZones in CrossSectionsDiagram

Wald Commits scm-commit at wald.intevation.org
Thu Sep 27 18:08:24 CEST 2018


# HG changeset patch
# User gernotbelger
# Date 1538064386 -7200
# Node ID 853f2dafc16e0e0c1640a6d761d78f5bcc9957f5
# Parent  d8e753d0fdb9e773d02f10af2a8e5f2dab8e3580
VegetationZones in CrossSectionsDiagram

diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/artifacts/uinfo.xml
--- a/artifacts/doc/conf/artifacts/uinfo.xml	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/doc/conf/artifacts/uinfo.xml	Thu Sep 27 18:06:26 2018 +0200
@@ -306,7 +306,6 @@
           </facets>
         </outputmode>
 
-        <!-- FIXME: i01n name in FLYSConstants -->
         <outputmode name="uinfo_inundation_duration_export" description="output.uinfo_inundation_duration_export" mime-type="text/plain" type="export">
           <facets>
             <facet name="wms_url" description="XXXXXXXXXX _ no entry in generators necessary either" />
@@ -348,8 +347,6 @@
 
     <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" />
@@ -357,7 +354,12 @@
           </facets>
         </outputmode>
 
-        <!-- FIXME: i01n name in FLYSConstants -->
+        <outputmode name="uinfo_vegetation_zones_invisible" description="uinfo_vegetation_zones_invisible" mime-type="text/plain" type="invisible">
+          <facets>
+            <facet name="uinfo_facet_vegetation_zones_cross_section" description="uinfo_facet_vegetation_zones_cross_section.description" />
+          </facets>
+        </outputmode>
+        
         <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" />
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/meta-data.xml
--- a/artifacts/doc/conf/meta-data.xml	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/doc/conf/meta-data.xml	Thu Sep 27 18:06:26 2018 +0200
@@ -256,6 +256,7 @@
                     <dc:call-macro name="cross_sections" />
                     <dc:call-macro name="basedata_5_flood-protections" />
                     <dc:call-macro name="hyks" />
+                    <dc:call-macro name="predefined_vegetation_zones_cs" />
                   </dc:when>
                   <dc:comment> Duration curve </dc:comment>
                   <dc:when test="$out = 'duration_curve'">
@@ -492,8 +493,8 @@
                     </dc:when>
                     <dc:comment> Cross sections </dc:comment>
                     <dc:when test="$out = 'cross_section'">
-                      <dc:call-macro name="waterlevels" />
-                    </dc:when>
+                      <dc:call-macro name="cross_section_user_content" />
+                    </dc:when>                    
                     <dc:comment> Duration curve </dc:comment>
                     <dc:when test="$out = 'duration_curve'">
                       <dc:call-macro name="duration-curve" />
@@ -512,7 +513,6 @@
 
                     <dc:when test="$out = 'sinfo_flowdepth_waterlevels'">
                       <dc:call-macro name="longitudinal-section-fix-vollmer_w" />
-                      <!-- TODO: 'Frühere Berechnungen//Bezugswasserstände' -->
                     </dc:when>
                   </dc:choose>
                 </dc:iterate>
@@ -614,6 +614,11 @@
         </dc:if>
       </dc:filter>
     </dc:macro>
+    
+    <dc:macro name="cross_section_user_content">
+      <dc:call-macro name="waterlevels" />                    
+      <dc:call-macro name="vegetationzones" />
+    </dc:macro>
 
     <dc:macro name="waterlevels">
       <dc:filter expr="$out_name = 'cross_section'">
@@ -639,6 +644,8 @@
       </dc:filter>
     </dc:macro>
 
+
+
     <dc:macro name="collection-group">
       <dc:group expr="concat($river, ' ', dc:date-format('dd.MM.yyyy - H:mm:ss', $a_creation), ' ', $collection_name)">
         <dc:macro-body />
@@ -1324,6 +1331,15 @@
       </hyks>
     </dc:macro>
 
+ <!-- Default Vegetation Zones -->
+    <dc:macro name="predefined_vegetation_zones_cs">
+      <U-INFO>
+        <vegetation_zones> 
+          <dc:variable name="vegzonedata" expr="dc:defaultvegetationzone($river)"></dc:variable>
+            <defaultVegetationZone factory="dummy" target_out="{$out}" data="{$vegzonedata}"/>         
+        </vegetation_zones>
+      </U-INFO>
+    </dc:macro>
 
     <!-- wst-data -->
 
@@ -3297,6 +3313,7 @@
         </dc:comment>
         <dc:statement>
           SELECT c.name AS collection_name,
+          c.gid AS collection_gid,
           ma.id AS a_id,
           ma.state AS a_state,
           ma.gid AS a_gid,
@@ -3757,31 +3774,34 @@
 
     <!-- Vegetation zones, edited by the user -->
     <dc:macro name="vegetationzones">
-      <dc:filter expr="$a_state = 'state.uinfo.vegetation_zones' and $facet_name = 'csv'"> <!-- we misuse the csv-facet -->
+      <dc:filter expr="$a_state = 'state.uinfo.vegetation_zones' and $facet_name = 'uinfo_facet_vegetation_zones_cross_section'"> <!--'uinfo_facet_vegetation_zones_cross_section'" >  and $facet_name = 'csv'"> we misuse the csv-facet -->
         <dc:if test="dc:has-result()">
-          <dc:for-each>
-            <dc:variable name="vegzonedata" expr="dc:data_from_artifact($a_gid,'vegzones')" />
-            <dc:variable name="vegzonedatalabel" expr="dc:get('ld_from'))" />
-            <dc:variable name="label_temp" type="string" expr="dc:coalesce($collection_name, dc:toString($a_gid))" />
-            <dc:variable name="fromkm" type="number" expr="dc:fromValue(dc:get('ld_mode'),
-                             dc:get('ld_locations'), dc:get('ld_from'))" />
-            <dc:variable name="tokm" type="number" expr="dc:fromValue(dc:get('ld_mode'),
-                               dc:get('ld_locations'), dc:get('ld_to'))" />
-            <dc:element name="${facet_name}">
-              <dc:attribute name="factory" value="dummy" />
-              <dc:attribute name="target_out" value="${out}" />
-              <dc:attribute name="description" value="${label_temp}" />
-              <!-- veg zones string as attribute -->
-              <dc:attribute name="data" value="${vegzonedata}" />
-              <dc:attribute name="from_km" value="${fromkm}" />
-              <dc:attribute name="to_km" value="${tokm}" />
-            </dc:element>
-          </dc:for-each>
+          <vegetation_zones>
+            <dc:for-each>
+              <dc:variable name="vegzonedata" expr="dc:data_from_artifact($a_gid,'vegzones')" />
+              <dc:variable name="vegzonedatalabel" expr="dc:get('ld_from')" />
+              <dc:variable name="label_temp" type="string" expr="dc:coalesce($collection_name, dc:toString($collection_gid))" />
+              <dc:variable name="fromkm" type="number" expr="dc:fromValue(dc:get('ld_mode'), dc:get('ld_locations'), dc:get('ld_from'))" />
+              <dc:variable name="tokm" type="number" expr="dc:fromValue(dc:get('ld_mode'), dc:get('ld_locations'), dc:get('ld_to'))" />
+
+              <dc:element name="${facet_name}">
+                <dc:attribute name="factory" value="uinfo" />
+                <dc:attribute name="target_out" value="${out}" />
+                <dc:attribute name="description" value="${label_temp}" />
+                <dc:attribute name="artifact-id" value="${a_gid}" />
+                <dc:attribute name="out" value="${out_name}" />
+                <dc:attribute name="ids" value="${facet_num}" />
+                <!-- veg zones string as attribute -->
+                <dc:attribute name="data" value="${vegzonedata}" />
+                <dc:attribute name="from_km" value="${fromkm}" />
+                <dc:attribute name="to_km" value="${tokm}" /> 
+              </dc:element>
+            </dc:for-each>
+          </vegetation_zones>
         </dc:if>
       </dc:filter>
     </dc:macro>
 
-
     <!-- U-INFO -->
     <dc:macro name="bundu_bezugswst">
       <dc:filter
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/themes.xml
--- a/artifacts/doc/conf/themes.xml	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/doc/conf/themes.xml	Thu Sep 27 18:06:26 2018 +0200
@@ -493,7 +493,8 @@
         <mapping from="uinfo_facet_salix_waterlevel_hw5_cross_section_water_line" to="UInfoSalixMH5CrossSectionWaterLine"/>
         
         <mapping from="uinfo_salix_line.manualpoints" to="ManualPoints"/>
-
+        <mapping from="uinfo_facet_vegetation_zones_cross_section" to="VegetationZonesCrossSection"/>
+        
         <mapping from="bundu_facet_channelmin" to="BunduChannel"/>
         <mapping from="bundu_facet_bedheight" to="BunduBed"/>
         <mapping from="bundu_facet_bedheight_01" to="BunduBed01"/>
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/themes/default.xml
--- a/artifacts/doc/conf/themes/default.xml	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/doc/conf/themes/default.xml	Thu Sep 27 18:06:26 2018 +0200
@@ -2973,8 +2973,13 @@
   <theme name="UInfoSalixRank">
    <fields> 
       <field name="areatransparency" type="int" default="50" display="Transparenz" /> 
-  </fields>
-  </theme>
+  </fields> 
+  </theme>
+    <theme name="VegetationZonesCrossSection">
+   <fields> 
+      <field name="areatransparency" type="int" default="50" display="Transparenz" /> 
+  </fields> 
+</theme> 
   <theme name="UInfoSalixCrossSectionWaterLine">
     <inherits>
       <inherit from="CrossSectionWaterLine"/>
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/themes/second.xml
--- a/artifacts/doc/conf/themes/second.xml	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/doc/conf/themes/second.xml	Thu Sep 27 18:06:26 2018 +0200
@@ -2961,8 +2961,13 @@
   <theme name="UInfoSalixRank">
    <fields> 
       <field name="areatransparency" type="int" default="50" display="Transparenz" /> 
-  </fields>
-  </theme>
+  </fields> 
+  </theme>
+    <theme name="VegetationZonesCrossSection">
+   <fields> 
+      <field name="areatransparency" type="int" default="50" display="Transparenz" /> 
+  </fields> 
+</theme> 
   <theme name="UInfoSalixCrossSectionWaterLine">
     <inherits>
       <inherit from="CrossSectionWaterLine"/>
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java	Thu Sep 27 18:06:26 2018 +0200
@@ -27,8 +27,8 @@
 import org.dive4elements.river.artifacts.model.WQKms;
 import org.dive4elements.river.artifacts.model.fixings.FixRealizingCalculation;
 import org.dive4elements.river.artifacts.model.fixings.FixRealizingResult;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.resources.Resources;
-import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper;
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractProcessor.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractProcessor.java	Thu Sep 27 18:06:26 2018 +0200
@@ -30,8 +30,6 @@
 import org.dive4elements.river.exports.DiagramGenerator;
 import org.dive4elements.river.exports.StyledSeriesBuilder;
 import org.dive4elements.river.exports.process.DefaultProcessor;
-import org.dive4elements.river.jfree.StripedAreaDataset;
-import org.dive4elements.river.jfree.StripedAreaDataset.Stripe;
 import org.dive4elements.river.jfree.StyledAreaSeriesCollection;
 import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.themes.ThemeDocument;
@@ -171,19 +169,6 @@
         return null;
     }
 
-    protected final String buildStripedAreaSeries(final Stripe[] stripes, final DiagramGenerator generator, final ArtifactAndFacet bundle,
-            final ThemeDocument theme, final boolean visible) {
-
-        final StripedAreaDataset dataset = new StripedAreaDataset(theme);
-
-        for (final Stripe stripe : stripes)
-            dataset.addStripe(stripe);
-
-        generator.addAxisDataset(dataset, getAxisName(), visible);
-
-        return null;
-    }
-
     private Double findRadius(final CallContext context, final Artifact artifact) {
         final Double start = (Double) context.getContextValue("startkm");
         final Double end = (Double) context.getContextValue("endkm");
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DataFromArtifactXPathFunction.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DataFromArtifactXPathFunction.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DataFromArtifactXPathFunction.java	Thu Sep 27 18:06:26 2018 +0200
@@ -49,7 +49,10 @@
             return null;
 
         final StateData data = artifact.getData(args.get(1).toString());
-        return data.getValue();
+        final Object value = data.getValue();
+        if (value == null)
+            return null;
 
+        return value;
     }
 }
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DefaultVegetationZoneXPathFunction.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DefaultVegetationZoneXPathFunction.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DefaultVegetationZoneXPathFunction.java	Thu Sep 27 18:06:26 2018 +0200
@@ -47,6 +47,10 @@
         if (river == null)
             return null;
 
-        return VegetationZoneServerClientXChange.parseListToDataString(VegetationZoneServerClientXChange.getStandardList(river, this.context));
+        final String value = VegetationZoneServerClientXChange.parseListToDataString(VegetationZoneServerClientXChange.getStandardList(river, this.context));
+        if (value == null)
+            return null;
+
+        return value;
     }
 }
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionFacetUtils.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionFacetUtils.java	Thu Sep 27 18:06:26 2018 +0200
@@ -0,0 +1,48 @@
+/** 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.model;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.artifacts.DataProvider;
+import org.dive4elements.river.model.FastCrossSectionLine;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+public final class CrossSectionFacetUtils {
+
+    private static Logger log = Logger.getLogger(CrossSectionFacetUtils.class);
+
+    private CrossSectionFacetUtils() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static DataProvider getDataProvider(final CallContext context) {
+
+        final List<DataProvider> providers = context.getDataProvider(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA);
+        if (providers.size() < 1) {
+            log.warn("Could not find Cross-Section data provider.");
+            return null;
+        }
+
+        return providers.get(0);
+    }
+
+    public static FastCrossSectionLine getCrossSection(final DataProvider provider, final CallContext context) {
+
+        if (provider == null)
+            return null;
+
+        return (FastCrossSectionLine) provider.provideData(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA, null, context);
+    }
+}
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionWaterLineFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionWaterLineFacet.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionWaterLineFacet.java	Thu Sep 27 18:06:26 2018 +0200
@@ -101,8 +101,7 @@
         final double currentKm = crossSection.getKm();
 
         final double waterLevel = lineArtifact.getWaterLevel(this.type, this.hash, this.stateId, currentKm, this.waterLineIndex, (Double) nextKm,
-                (Double) prevKm,
-                context);
+                (Double) prevKm, context);
         if (Double.isNaN(waterLevel))
             return NO_LINE_DATA;
 
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java	Thu Sep 27 18:06:26 2018 +0200
@@ -620,7 +620,7 @@
     /**
      * Interpolates a W for a km using a Q column position
      */
-    public double interpolateW(final double km, final QPosition qPosition, final Calculation errors) {
+    public double interpolateW(final double km, final QPosition qPosition) {
 
         int rowIndex = Collections.binarySearch(this.rows, new Row(km));
 
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/MainWstValuesCalculator.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/MainWstValuesCalculator.java	Thu Sep 27 18:06:26 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.model.river;
+
+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.model.WstValueTable;
+import org.dive4elements.river.artifacts.model.WstValueTable.QPosition;
+import org.dive4elements.river.artifacts.model.WstValueTableFactory;
+import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.MainValue;
+import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
+import org.dive4elements.river.model.River;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+public final class MainWstValuesCalculator {
+
+    private final WstValueTable wst;
+
+    private final Map<String, MainValueQPosition> positions;
+
+    private static class MainValueQPosition {
+
+        private final Map<Gauge, QPosition> gaugePositions = new HashMap<>();
+        private QPosition refGaugePositions = null;
+    }
+
+    public static MainWstValuesCalculator forRiver(final CallContext context, final River river, final DoubleRange calcRange, final String... mainValueNames) {
+
+        final RiverInfoProvider info = RiverInfoProvider.forRange(context, river, calcRange);
+
+        return forRiverInfo(info, mainValueNames);
+    }
+
+    public static MainWstValuesCalculator forRiverInfo(final RiverInfoProvider info, final String... mainValueNames) {
+
+        final WstValueTable wst = WstValueTableFactory.getTable(info.getRiver());
+
+        final Map<String, MainValueQPosition> positions = calculatePositions(info, wst, mainValueNames);
+
+        return new MainWstValuesCalculator(wst, positions);
+    }
+
+    private static Map<String, MainValueQPosition> calculatePositions(final RiverInfoProvider info, final WstValueTable wst, final String[] mainValueNames) {
+
+        boolean isFirstGauge = true;
+
+        final Map<String, MainValueQPosition> positions = new HashMap<>();
+
+        for (final String mainValue : mainValueNames)
+            positions.put(mainValue.toUpperCase(), new MainValueQPosition());
+
+        for (final Gauge gauge : info.getGauges()) {
+
+            for (final MainValueQPosition position : positions.values())
+                position.gaugePositions.put(gauge, null);
+
+            final double gaugeKm = gauge.getStation().doubleValue();
+            for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q)) {
+
+                final MainValueQPosition position = positions.get(mv.getMainValue().getName().toUpperCase());
+                if (position != null) {
+                    final QPosition qPosition = wst.getQPosition(gaugeKm, mv.getValue().doubleValue());
+                    position.gaugePositions.put(gauge, qPosition);
+
+                    if (isFirstGauge)
+                        position.refGaugePositions = qPosition;
+                }
+            }
+
+            isFirstGauge = false;
+        }
+
+        return positions;
+    }
+
+    private MainWstValuesCalculator(final WstValueTable wst, final Map<String, MainValueQPosition> positions) {
+        this.wst = wst;
+        this.positions = positions;
+    }
+
+    public boolean hasPosition(final String mainValueName) {
+
+        final MainValueQPosition position = this.positions.get(mainValueName);
+        if (position == null)
+            throw new IllegalArgumentException();
+
+        return position.refGaugePositions != null;
+    }
+
+    /**
+     * Interpolates the W for a station with a fixed (virtual) wst column position
+     */
+    public double interpolateW(final double station, final String mainValueName) {
+
+        final MainValueQPosition mainValuePosition = this.positions.get(mainValueName.toUpperCase());
+
+        if (mainValuePosition.refGaugePositions == null)
+            return Double.NaN;
+
+        return this.wst.interpolateW(station, mainValuePosition.refGaugePositions);
+    }
+}
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/RiverInfoProvider.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/RiverInfoProvider.java	Thu Sep 27 18:06:26 2018 +0200
@@ -0,0 +1,143 @@
+/** 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.model.river;
+
+import java.util.List;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.model.LocationProvider;
+import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.states.WaterlevelData;
+import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.River;
+import org.dive4elements.river.utils.GaugeIndex;
+
+/**
+ * @author Gernot Belger
+ *
+ */
+public final class RiverInfoProvider {
+
+    private static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range";
+
+    private final River river;
+    private final GaugeIndex gaugeIndex;
+    private final Gauge refGauge;
+    private final boolean showAllGauges;
+    private final String notinrange;
+
+    public static RiverInfoProvider forRange(final CallContext context, final River river, final DoubleRange calcRange) {
+
+        return forRange(context, river, calcRange, false);
+    }
+
+    public static RiverInfoProvider forRange(final CallContext context, final River river, final DoubleRange calcRange, final boolean firstGaugeIsRefGauge) {
+
+        final List<Gauge> gauges;
+        if (calcRange == null)
+            gauges = river.getGauges();
+        else
+            gauges = river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble());
+
+        final GaugeIndex gaugeIndex = new GaugeIndex(gauges);
+
+        final String notinrange = Resources.getMsg(context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE);
+
+        if (firstGaugeIsRefGauge && !gauges.isEmpty())
+            return new RiverInfoProvider(notinrange, river, false, gaugeIndex, gauges.get(0));
+        return new RiverInfoProvider(notinrange, river, false, gaugeIndex, null);
+    }
+
+    private RiverInfoProvider(final String notinrange, final River river, final boolean showAllGauges, final GaugeIndex gaugeIndex, final Gauge refGauge) {
+        this.notinrange = notinrange;
+        this.river = river;
+        this.showAllGauges = showAllGauges;
+        this.gaugeIndex = gaugeIndex;
+        this.refGauge = refGauge;
+    }
+
+    public RiverInfoProvider forWaterlevel(final WaterlevelData waterlevel) {
+        final WKms wstKms = waterlevel.getWkms();
+        final Gauge waterlevelRefGauge = findReferenceGauge(wstKms);
+        final boolean waterlevelShowAllGauges = waterlevel.isShowAllGauges();
+
+        return new RiverInfoProvider(this.notinrange, this.river, waterlevelShowAllGauges, this.gaugeIndex, waterlevelRefGauge);
+    }
+
+    /**
+     * Re-determines the reference gauge, in the same way as the WaterlevelArtifact would do it
+     */
+    private Gauge findReferenceGauge(final WKms wkms) {
+
+        final double[] wstFromTo = findWstFromTo(wkms);
+        return this.river.determineRefGauge(wstFromTo, true);
+    }
+
+    private static double[] findWstFromTo(final WKms wkms) {
+
+        final double from = wkms.getKm(0);
+        final double to = wkms.getKm(wkms.size() - 1);
+
+        final boolean waterIncreasing = wkms.guessWaterIncreasing();
+        if (waterIncreasing)
+            return new double[] { to, from };
+
+        return new double[] { from, to };
+    }
+
+    public String getLocation(final double km) {
+        return LocationProvider.getLocation(this.river.getName(), km);
+    }
+
+    public String findGauge(final double km) {
+        // REMARK: access the gauge once only during calculation
+        final Gauge gauge = getGauge(km);
+
+        return gauge == null ? this.notinrange : gauge.getName();
+    }
+
+    private String findGauge(final double km, final boolean allGauges) {
+        // REMARK: access the gauge once only during calculation
+        final Gauge gauge = getGauge(km, allGauges);
+
+        return gauge == null ? this.notinrange : gauge.getName();
+    }
+
+    public Gauge getGauge(final double km) {
+
+        // REMARK: using same logic as in WaterlevelExporter here
+
+        return getGauge(km, this.showAllGauges);
+    }
+
+    public Gauge getGauge(final double km, final boolean allGauges) {
+        if (allGauges)
+            return this.gaugeIndex.findGauge(km);
+
+        if ((this.refGauge != null) && this.refGauge.getRange().contains(km))
+            return this.refGauge;
+
+        return null;
+    }
+
+    public String getReferenceGauge() {
+        return this.refGauge == null ? this.notinrange : this.refGauge.getName();
+    }
+
+    public River getRiver() {
+        return this.river;
+    }
+
+    public List<Gauge> getGauges() {
+        return this.gaugeIndex.getGauges();
+    }
+}
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e 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	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java	Thu Sep 27 18:06:26 2018 +0200
@@ -24,11 +24,11 @@
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.DateRange;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 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.GaugeMainValueFinder;
-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;
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/RiverInfoProvider.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/RiverInfoProvider.java	Wed Sep 26 15:48:05 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- *  Björnsen Beratende Ingenieure GmbH
- *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-package org.dive4elements.river.artifacts.sinfo.common;
-
-import java.util.List;
-
-import org.apache.commons.lang.math.DoubleRange;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.river.artifacts.model.LocationProvider;
-import org.dive4elements.river.artifacts.model.WKms;
-import org.dive4elements.river.artifacts.resources.Resources;
-import org.dive4elements.river.artifacts.states.WaterlevelData;
-import org.dive4elements.river.model.Gauge;
-import org.dive4elements.river.model.River;
-import org.dive4elements.river.utils.GaugeIndex;
-
-/**
- * @author Gernot Belger
- *
- */
-public final class RiverInfoProvider {
-
-    private static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range";
-
-    private final River river;
-    private final GaugeIndex gaugeIndex;
-    private final Gauge refGauge;
-    private final boolean showAllGauges;
-    private final String notinrange;
-
-    public static RiverInfoProvider forRange(final CallContext context, final River river, final DoubleRange calcRange) {
-
-        return forRange(context, river, calcRange, false);
-    }
-
-    public static RiverInfoProvider forRange(final CallContext context, final River river, final DoubleRange calcRange, final boolean firstGaugeIsRefGauge) {
-
-        final List<Gauge> gauges = river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble());
-        final GaugeIndex gaugeIndex = new GaugeIndex(gauges);
-
-        final String notinrange = Resources.getMsg(context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE);
-
-        if (firstGaugeIsRefGauge && !gauges.isEmpty())
-            return new RiverInfoProvider(notinrange, river, false, gaugeIndex, gauges.get(0));
-        return new RiverInfoProvider(notinrange, river, false, gaugeIndex, null);
-    }
-
-    private RiverInfoProvider(final String notinrange, final River river, final boolean showAllGauges, final GaugeIndex gaugeIndex, final Gauge refGauge) {
-        this.notinrange = notinrange;
-        this.river = river;
-        this.showAllGauges = showAllGauges;
-        this.gaugeIndex = gaugeIndex;
-        this.refGauge = refGauge;
-    }
-
-    public RiverInfoProvider forWaterlevel(final WaterlevelData waterlevel) {
-        final WKms wstKms = waterlevel.getWkms();
-        final Gauge waterlevelRefGauge = findReferenceGauge(wstKms);
-        final boolean waterlevelShowAllGauges = waterlevel.isShowAllGauges();
-
-        return new RiverInfoProvider(this.notinrange, this.river, waterlevelShowAllGauges, this.gaugeIndex, waterlevelRefGauge);
-    }
-
-    /**
-     * Re-determines the reference gauge, in the same way as the WaterlevelArtifact would do it
-     */
-    private Gauge findReferenceGauge(final WKms wkms) {
-
-        final double[] wstFromTo = findWstFromTo(wkms);
-        return this.river.determineRefGauge(wstFromTo, true);
-    }
-
-    private static double[] findWstFromTo(final WKms wkms) {
-
-        final double from = wkms.getKm(0);
-        final double to = wkms.getKm(wkms.size() - 1);
-
-        final boolean waterIncreasing = wkms.guessWaterIncreasing();
-        if (waterIncreasing)
-            return new double[] { to, from };
-
-        return new double[] { from, to };
-    }
-
-    public String getLocation(final double km) {
-        return LocationProvider.getLocation(this.river.getName(), km);
-    }
-
-    public String findGauge(final double km) {
-        // REMARK: access the gauge once only during calculation
-        final Gauge gauge = getGauge(km);
-
-        return gauge == null ? this.notinrange : gauge.getName();
-    }
-
-    private String findGauge(final double km, final boolean allGauges) {
-        // REMARK: access the gauge once only during calculation
-        final Gauge gauge = getGauge(km, allGauges);
-
-        return gauge == null ? this.notinrange : gauge.getName();
-    }
-
-    public Gauge getGauge(final double km) {
-
-        // REMARK: using same logic as in WaterlevelExporter here
-
-        return getGauge(km, this.showAllGauges);
-    }
-
-    public Gauge getGauge(final double km, final boolean allGauges) {
-        if (allGauges)
-            return this.gaugeIndex.findGauge(km);
-
-        if ((this.refGauge != null) && this.refGauge.getRange().contains(km))
-            return this.refGauge;
-
-        return null;
-    }
-
-    public String getReferenceGauge() {
-        return this.refGauge == null ? this.notinrange : this.refGauge.getName();
-    }
-
-    public River getRiver() {
-        return this.river;
-    }
-
-    public List<Gauge> getGauges() {
-        return this.gaugeIndex.getGauges();
-    }
-}
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e 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	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java	Thu Sep 27 18:06:26 2018 +0200
@@ -17,9 +17,9 @@
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.WQDay;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 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.tkhstate.WinfoArtifactWrapper;
 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
diff -r d8e753d0fdb9 -r 853f2dafc16e 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	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java	Thu Sep 27 18:06:26 2018 +0200
@@ -30,9 +30,9 @@
 import org.dive4elements.river.artifacts.model.WstValueTable;
 import org.dive4elements.river.artifacts.model.WstValueTable.QPosition;
 import org.dive4elements.river.artifacts.model.WstValueTableFactory;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.resources.Resources;
 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.flood_duration.RiversideRadioChoice.RiversideChoiceKey;
 import org.dive4elements.river.exports.WaterlevelDescriptionBuilder;
@@ -143,7 +143,7 @@
             odays[j] = 365 - udays[i];
             final QPosition qpos = wst.getQPosition(gauge.getStation().doubleValue(), qs[i]);
             if (qpos != null) {
-                ows[j] = wst.interpolateW(station, qpos, problems);
+                ows[j] = wst.interpolateW(station, qpos);
                 oqs[j] = wst.getQ(qpos, station);
             } else {
                 ows[j] = Double.NaN;
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java	Thu Sep 27 18:06:26 2018 +0200
@@ -16,9 +16,9 @@
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 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.tkhcalculation.DischargeValuesFinder;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder;
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java	Thu Sep 27 18:06:26 2018 +0200
@@ -15,7 +15,7 @@
 import org.apache.commons.lang.math.DoubleRange;
 import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.common.ResultRow;
-import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator.TkhCalculateState;
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.java	Thu Sep 27 18:06:26 2018 +0200
@@ -20,9 +20,9 @@
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
-import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthUtils;
 import org.dive4elements.river.artifacts.sinfo.flowdepth.WstSoundingIdPair;
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java	Thu Sep 27 18:06:26 2018 +0200
@@ -19,9 +19,9 @@
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.WKms;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
-import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthUtils;
 import org.dive4elements.river.artifacts.sinfo.flowdepth.WstSoundingIdPair;
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java	Thu Sep 27 18:06:26 2018 +0200
@@ -27,11 +27,11 @@
 import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.Calculation.Problem;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.WQKms;
 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.tkhcalculation.DischargeValuesFinder;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator.TkhCalculateState;
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java	Thu Sep 27 18:06:26 2018 +0200
@@ -22,8 +22,8 @@
 import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.resources.Resources;
-import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsUtils;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.DefaultBedHeights;
@@ -113,8 +113,8 @@
     /**
      * Fills a map of delta-Ws by km-range from the regional scenario input data
      */
-    private void fillRangeScenarios(final NavigableMap<Double, List<Double>> rangeScenarios, final RangeAccess calcRange,
-            final double partFrom, final double partTo, final int[] deltaWs) {
+    private void fillRangeScenarios(final NavigableMap<Double, List<Double>> rangeScenarios, final RangeAccess calcRange, final double partFrom,
+            final double partTo, final int[] deltaWs) {
         final List<Double> nulls = new ArrayList<>();
         final List<Double> dwsm = new ArrayList<>();
         for (int i = 0; i <= deltaWs.length - 1; i++) {
@@ -145,8 +145,8 @@
     /**
      * Fetches historical and reference bed heights and fills a map of delta-MSHs for all fetched stations in the calc range
      */
-    private void fillRangeScenarios(final NavigableMap<Double, List<Double>> rangeScenarios, final RangeAccess calcRange,
-            final double partFrom, final double partTo, final int historicalBedHeightId) {
+    private void fillRangeScenarios(final NavigableMap<Double, List<Double>> rangeScenarios, final RangeAccess calcRange, final double partFrom,
+            final double partTo, final int historicalBedHeightId) {
 
         // Find relevant default bed-heights
         final River river = calcRange.getRiver();
@@ -173,8 +173,7 @@
                     final String msg = Resources.getMsg(this.context.getMeta(), "uinfo_salix_calc.warning.missing_bedheights");
                     this.problems.addProblem(station, msg);
                 }
-            }
-            else
+            } else
                 rangeScenarios.get(station).add(Double.valueOf(delta));
         }
         rangeScenarios.put(Double.valueOf(partTo + 0.0001), nulls);
@@ -270,6 +269,7 @@
         return "";
     }
 
+    // FIXME: check if needed
     /**
      * Fetches a iota or waterlevel height of a station from a salix calculation result
      */
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java	Thu Sep 27 18:06:26 2018 +0200
@@ -22,7 +22,6 @@
 import org.dive4elements.river.artifacts.common.IExportContext;
 import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
 import org.dive4elements.river.artifacts.common.ResultRow;
-import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
 import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
 import org.dive4elements.river.artifacts.uinfo.salix.SalixLineCrossSectionIndexData.SalixWaterlevel;
@@ -224,15 +223,4 @@
             throw new UnsupportedOperationException();
         }
     }
-
-    /**
-     * Computes the height of a vegetation zone type for a station and a salix calculation result
-     */
-    public double computeVegetationZoneHeight(final double station, final int vegetationZoneType, final SalixLineCalculationResult result) {
-
-        final Calculation problems = new Calculation();
-
-        final SalixLineCalculator calculator = new SalixLineCalculator(null);
-        return calculator.computeVegetationZoneHeight(problems, station, vegetationZoneType, result);
-    }
 }
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java	Thu Sep 27 18:06:26 2018 +0200
@@ -12,9 +12,7 @@
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Map.Entry;
 import java.util.NavigableMap;
 
@@ -24,18 +22,13 @@
 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.model.WstValueTable;
-import org.dive4elements.river.artifacts.model.WstValueTable.QPosition;
-import org.dive4elements.river.artifacts.model.WstValueTableFactory;
-import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
+import org.dive4elements.river.artifacts.model.river.MainWstValuesCalculator;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper;
 import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
 import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
 import org.dive4elements.river.artifacts.uinfo.salix.SalixLineAccess.ScenarioType;
 import org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZoneServerClientXChange;
-import org.dive4elements.river.model.Gauge;
-import org.dive4elements.river.model.MainValue;
-import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
 import org.dive4elements.river.utils.Formatter;
 
 /**
@@ -45,31 +38,21 @@
  */
 final class SalixLineCalculator {
 
+    private static final String MAIN_VALUE_MNQ = "mnq";
+
+    private static final String MAIN_VALUE_MQ = "mq";
+
+    private static final String MAIN_VALUE_MHQ = "mhq";
+
+    private static final String MAIN_VALUE_HQ5 = "hq5";
+
     private static final BigDecimal SALIX_DISTANCE = new BigDecimal("2.31");
     private final List<ResultRow> rows = new ArrayList<>();
 
     private final RiverInfoProvider riverInfoProvider;
 
-    private final Map<Gauge, QPosition> gaugeMwPos;
-    private final Map<Gauge, QPosition> gaugeMnwPos;
-    private final Map<Gauge, QPosition> gaugeMhwPos;
-    private final Map<Gauge, QPosition> gaugeHw5Pos;
-    private QPosition refGaugeMwPos;
-    private QPosition refGaugeMnwPos;
-    private QPosition refGaugeMhwPos;
-    private QPosition refGaugeHw5Pos;
-    private Gauge firstGauge;
-
-    private Calculation problems;
-
-    private WstValueTable wst;
-
     public SalixLineCalculator(final RiverInfoProvider riverInfoProvider) {
         this.riverInfoProvider = riverInfoProvider;
-        this.gaugeMwPos = new HashMap<>();
-        this.gaugeMnwPos = new HashMap<>();
-        this.gaugeMhwPos = new HashMap<>();
-        this.gaugeHw5Pos = new HashMap<>();
     }
 
     /**
@@ -79,16 +62,13 @@
             final ScenarioType scenarioType, final String[] scenarioLabels, final String rangeString, final String additionalString,
             final SalixLineCalculationResults results) {
 
-        this.problems = problems;
-        this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver());
-
-        fetchGaugeMainValuePositions();
+        final MainWstValuesCalculator mainWstValues = fetchGaugeMainValuePositions2(problems);
 
         final WINFOArtifact winfo = new WinfoArtifactWrapper(uinfo);
         winfo.addStringData("ld_mode", "distance");
         winfo.addStringData("ld_step", "100");
         for (final double station : new ComputationRangeAccess(winfo).getKms()) {
-            this.rows.add(createRow(station, rangeScenarios));
+            this.rows.add(createRow(mainWstValues, station, rangeScenarios));
         }
         if (scenarioType == ScenarioType.REGIONAL)
             results.addResult(new SalixLineCalculationRegionalResult("Salix-regional", scenarioLabels, rangeString, additionalString, this.rows), problems);
@@ -100,54 +80,28 @@
             results.addResult(new SalixLineCalculationResult("Salix-simple", this.rows), problems);
     }
 
-    /**
-     * Fetch MQ, MNQ and MHQ of all gauges and determine the wst QPosition for each one
-     */
-    private void fetchGaugeMainValuePositions() {
-        this.gaugeMwPos.clear();
-        this.gaugeMnwPos.clear();
-        this.gaugeMhwPos.clear();
-        this.gaugeHw5Pos.clear();
+    private MainWstValuesCalculator fetchGaugeMainValuePositions2(final Calculation problems) {
+        final MainWstValuesCalculator mainWstValues = MainWstValuesCalculator.forRiverInfo(this.riverInfoProvider, MAIN_VALUE_MQ, MAIN_VALUE_MNQ,
+                MAIN_VALUE_MHQ, MAIN_VALUE_HQ5);
 
-        this.firstGauge = null;
-        for (final Gauge gauge : this.riverInfoProvider.getGauges()) {
-            this.gaugeMwPos.put(gauge, null);
-            this.gaugeMnwPos.put(gauge, null);
-            this.gaugeMhwPos.put(gauge, null);
-            this.gaugeHw5Pos.put(gauge, null);
-            final double gaugeKm = gauge.getStation().doubleValue();
-            for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q)) {
-                if (mv.getMainValue().getName().equalsIgnoreCase("mq"))
-                    this.gaugeMwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
-                else if (mv.getMainValue().getName().equalsIgnoreCase("mnq"))
-                    this.gaugeMnwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
-                else if (mv.getMainValue().getName().equalsIgnoreCase("mhq"))
-                    this.gaugeMhwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
-                else if (mv.getMainValue().getName().equalsIgnoreCase("hq5"))
-                    this.gaugeHw5Pos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
-            }
-            if (this.firstGauge == null) {
-                this.refGaugeMwPos = this.gaugeMwPos.get(gauge);
-                this.refGaugeMnwPos = this.gaugeMnwPos.get(gauge);
-                this.refGaugeMhwPos = this.gaugeMhwPos.get(gauge);
-                this.refGaugeHw5Pos = this.gaugeHw5Pos.get(gauge);
-                this.firstGauge = gauge;
-            }
+        if (!mainWstValues.hasPosition(MAIN_VALUE_MQ))
+            problems.addProblem("uinfo_salix_calc.warning.missing_mq");
+        else {
+            if (!mainWstValues.hasPosition(MAIN_VALUE_MHQ))
+                problems.addProblem("uinfo_salix_calc.warning.missing_mhq");
+            if (!mainWstValues.hasPosition(MAIN_VALUE_MNQ))
+                problems.addProblem("uinfo_salix_calc.warning.missing_mnq");
         }
-        if (this.refGaugeMwPos == null)
-            this.problems.addProblem("uinfo_salix_calc.warning.missing_mq");
-        else {
-            if (this.refGaugeMhwPos == null)
-                this.problems.addProblem("uinfo_salix_calc.warning.missing_mhq");
-            if (this.refGaugeMnwPos == null)
-                this.problems.addProblem("uinfo_salix_calc.warning.missing_mnq");
-        }
+
+        return mainWstValues;
     }
 
     /**
      * Create a result row for a station and its gauge, and add w-q-values as selected
+     *
+     * @param mainWstValues
      */
-    private ResultRow createRow(final double station, final NavigableMap<Double, List<Double>> rangeScenarios) {
+    private ResultRow createRow(final MainWstValuesCalculator mainWstValues, final double station, final NavigableMap<Double, List<Double>> rangeScenarios) {
 
         final ResultRow row = ResultRow.create();
         row.putValue(GeneralResultType.station, station);
@@ -157,10 +111,10 @@
         // final double mnw = interpolateW(station, this.gaugeMnwPos.get(gauge));
         // final double mw = interpolateW(station, this.gaugeMwPos.get(gauge));
         // final double mhw = interpolateW(station, this.gaugeMhwPos.get(gauge));
-        final double mnw = interpolateW(station, this.refGaugeMnwPos);
-        final double mw = interpolateW(station, this.refGaugeMwPos);
-        final double mhw = interpolateW(station, this.refGaugeMhwPos);
-        final double hw5 = interpolateW(station, this.refGaugeHw5Pos);
+        final double mnw = mainWstValues.interpolateW(station, MAIN_VALUE_MNQ);
+        final double mw = mainWstValues.interpolateW(station, MAIN_VALUE_MQ);
+        final double mhw = mainWstValues.interpolateW(station, MAIN_VALUE_MHQ);
+        final double hw5 = mainWstValues.interpolateW(station, MAIN_VALUE_HQ5);
         row.putValue(UInfoResultType.waterlevelMNW, mnw);
         row.putValue(UInfoResultType.waterlevelMW, mw);
         row.putValue(UInfoResultType.waterlevelMHW, mhw);
@@ -179,8 +133,7 @@
                 final double salix = calcSalix(mhw, mw, deltaw.doubleValue());
                 final double scen = calcSalix(mhw, 0.0, deltaw.doubleValue());
                 scenarios.add(new SalixScenario((int) (deltaw * 100), salix, scen));
-            }
-            else {
+            } else {
                 scenarios.add(null);
             }
         }
@@ -190,15 +143,6 @@
     }
 
     /**
-     * Interpolates the W for a station with a fixed (virtual) wst column position
-     */
-    private double interpolateW(final double station, final QPosition qPosition) {
-        if (qPosition != null)
-            return this.wst.interpolateW(station, qPosition, this.problems);
-        return Double.NaN;
-    }
-
-    /**
      * Calculates the salix value
      */
     private double calcSalix(final double mhw, final double mw, final double deltamw) {
@@ -263,6 +207,7 @@
         final ResultRow stationRow = searchStation(station, result.getRows());
         if (stationRow == null)
             return Double.NaN;
+
         // Compute height from overflow duration days
         final List<VegetationZoneServerClientXChange> vzs = VegetationZoneServerClientXChange.getStandardList(null, null); // TODO river, context
         if ((vegetationZoneType >= 1) && (vegetationZoneType <= vzs.size())) {
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java	Thu Sep 27 18:06:26 2018 +0200
@@ -26,6 +26,7 @@
 import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
 import org.dive4elements.river.artifacts.uinfo.salix.SalixLineCrossSectionIndexData.SalixWaterlevel;
 import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.jfree.StripedAreaDataset;
 import org.dive4elements.river.jfree.StripedAreaDataset.Stripe;
 import org.dive4elements.river.themes.ThemeDocument;
 
@@ -178,14 +179,17 @@
 
         if (bundle.getFacetName().equals(FACET_SALIX_RANK)) {
             final CallMeta meta = generator.getContext().getMeta();
-            final Stripe[] stripes = new Stripe[] { //
-                    new Stripe(getSimpleMsg("uinfo_salix_rank.excellent", meta), Color.decode("#00B0F0"), -0.3, 0.3), //
-                    new Stripe(getSimpleMsg("uinfo_salix_rank.good", meta), Color.decode("#00B050"), 0.3, 0.5), //
-                    new Stripe(getSimpleMsg("uinfo_salix_rank.moderate", meta), Color.decode("#FFFF00"), 0.5, 1.0), //
-                    new Stripe(getSimpleMsg("uinfo_salix_rank.bad", meta), Color.decode("#FFC000"), 1.0, 1.5), //
-                    new Stripe(getSimpleMsg("uinfo_salix_rank.very_bad", meta), Color.decode("#FF0000"), 1.5, Double.NaN) };
 
-            return buildStripedAreaSeries(stripes, generator, bundle, theme, visible);
+            final StripedAreaDataset dataset = new StripedAreaDataset(theme);
+            dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.excellent", meta), Color.decode("#00B0F0"), -0.3, 0.3));
+            dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.good", meta), Color.decode("#00B050"), 0.3, 0.5));
+            dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.moderate", meta), Color.decode("#FFFF00"), 0.5, 1.0));
+            dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.bad", meta), Color.decode("#FFC000"), 1.0, 1.5));
+            dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.very_bad", meta), Color.decode("#FF0000"), 1.5, Double.NaN));
+
+            generator.addAxisDataset(dataset, getAxisName(), visible);
+
+            return null;
         }
 
         return buildSeriesForType(generator, bundle, theme, visible, doGetType(bundle.getFacetName()), GAP_DISTANCE);
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCrossSectionProcessor.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCrossSectionProcessor.java	Thu Sep 27 18:06:26 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.uinfo.vegetationzones;
+
+import java.awt.Color;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.artifacts.DataProvider;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.common.AbstractProcessor;
+import org.dive4elements.river.artifacts.model.CrossSectionFacetUtils;
+import org.dive4elements.river.artifacts.model.river.MainWstValuesCalculator;
+import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
+import org.dive4elements.river.exports.CrossSectionGenerator;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.jfree.StripedAreaDataset;
+import org.dive4elements.river.jfree.StripedAreaDataset.Stripe;
+import org.dive4elements.river.model.FastCrossSectionLine;
+import org.dive4elements.river.model.River;
+import org.dive4elements.river.themes.ThemeDocument;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public class VegetationZonesCrossSectionProcessor extends AbstractProcessor {
+
+    private static final String MAIN_VALUE_MQ = "mq";
+
+    public static final String FACET_VEGETATION_ZONES_CROSS_SECTION = "uinfo_facet_vegetation_zones_cross_section";
+
+    private static final String FACET_VEGETATION_ZONES_CROSS_SECTION_DESCRIPTION = "uinfo_facet_vegetation_zones_cross_section.description";
+
+    private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>();
+
+    static {
+        HANDLED_FACET_TYPES.add(FACET_VEGETATION_ZONES_CROSS_SECTION);
+    }
+
+    public static Facet createVegetationZonesCrossSectionFacet(final CallContext context, final String hash, final String id,
+            final AbstractCalculationResult result, final int index) {
+        return AbstractProcessor.createFacet(context, hash, id, result, index, CrossSectionGenerator.I18N_XAXIS_LABEL, FACET_VEGETATION_ZONES_CROSS_SECTION,
+                FACET_VEGETATION_ZONES_CROSS_SECTION_DESCRIPTION);
+    }
+
+    public static void generateSeries(final CrossSectionGenerator generator, final ArtifactAndFacet bundle, final CallContext context,
+            final ThemeDocument theme, final boolean visible) {
+
+        final DataProvider provider = CrossSectionFacetUtils.getDataProvider(context);
+        final FastCrossSectionLine crossSection = CrossSectionFacetUtils.getCrossSection(provider, context);
+        if (crossSection == null)
+            return;
+        final double currentStation = crossSection.getKm();
+
+        if (bundle.getFacetName().equals(FACET_VEGETATION_ZONES_CROSS_SECTION)) {
+
+            final StripedAreaDataset dataset = new StripedAreaDataset(theme);
+
+            final Artifact artifact = bundle.getArtifact();
+            final VegetationzonesAccess vAccess = new VegetationzonesAccess((UINFOArtifact) artifact);
+            final River river = vAccess.getRiver();
+            final List<VegetationZoneServerClientXChange> zones = VegetationZoneServerClientXChange.parse(vAccess.getVegZones());
+
+            for (final VegetationZoneServerClientXChange zone : zones) {
+
+                final double lower = uefdToHeight(context, river, currentStation, zone.getLowerFromTo());
+                final double upper = uefdToHeight(context, river, currentStation, zone.getUpperFromTo());
+
+                final Color color = Color.decode(zone.getHexColor());
+                dataset.addStripe(new Stripe(zone.getZoneName(), color, lower, upper));
+            }
+
+            generator.addAxisDataset(dataset, 0, visible);
+            return;
+        }
+
+        throw new UnsupportedOperationException();
+    }
+
+    private static double uefdToHeight(final CallContext context, final River river, final double station, final int uefd) {
+
+        final MainWstValuesCalculator mainWstValues = MainWstValuesCalculator.forRiver(context, river, null, MAIN_VALUE_MQ);
+
+        final double mw = mainWstValues.interpolateW(station, MAIN_VALUE_MQ);
+
+        // Üfd = -70,559 ∗ ln((DGM - MW) + 0,5) + 80,711
+        final double f1 = -70.559;
+        final double f2 = -88.711;
+
+        final double dgm = Math.exp((uefd - f2) / f1) + mw - 0.5;
+        return dgm;
+    }
+
+    public VegetationZonesCrossSectionProcessor() {
+        super(CrossSectionGenerator.I18N_YAXIS_LABEL, HANDLED_FACET_TYPES);
+
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
+        throw new UnsupportedOperationException();
+    }
+
+}
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesState.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesState.java	Thu Sep 27 18:06:26 2018 +0200
@@ -79,6 +79,9 @@
         final List<VegetationZonesCalculationResult> resultList = results.getResults();
 
         if (!resultList.isEmpty()) {
+
+            facets.add(VegetationZonesCrossSectionProcessor.createVegetationZonesCrossSectionFacet(context, hash, this.id, resultList.get(0), 0));
+
             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);
 
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java	Thu Sep 27 18:06:26 2018 +0200
@@ -989,7 +989,7 @@
      * @param visible
      *            Determines, if the dataset should be visible or not.
      */
-    protected final void addAxisDataset(final XYDataset dataset, final int idx, final boolean visible) {
+    public final void addAxisDataset(final XYDataset dataset, final int idx, final boolean visible) {
         if (dataset == null || idx < 0) {
             return;
         }
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java	Thu Sep 27 18:06:26 2018 +0200
@@ -25,6 +25,7 @@
 import org.dive4elements.river.artifacts.model.FacetTypes;
 import org.dive4elements.river.artifacts.model.HYKFactory;
 import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZonesCrossSectionProcessor;
 import org.dive4elements.river.jfree.RiverAnnotation;
 import org.dive4elements.river.jfree.StyledXYSeries;
 import org.dive4elements.river.model.FastCrossSectionLine;
@@ -307,6 +308,9 @@
                     attr,
                     visible);
         }
+        else if (name.equals(VegetationZonesCrossSectionProcessor.FACET_VEGETATION_ZONES_CROSS_SECTION)) {
+            VegetationZonesCrossSectionProcessor.generateSeries(this, artifactFacet, context, attr, visible);
+        }
         else if (FacetTypes.IS.MANUALLINE(name)) {
             doCrossSectionWaterLineOut(
                     artifactFacet.getData(context),
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/resources/messages.properties
--- a/artifacts/src/main/resources/messages.properties	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/resources/messages.properties	Thu Sep 27 18:06:26 2018 +0200
@@ -1193,6 +1193,7 @@
 uinfo_facet_salix_scenario = Iota Scenario, {0}
 uinfo_facet_salix_scenario.filtered.description = Iota Scenario, {0}
 uinfo_facet_salix_scenario.raw.description = Iota Scenario, {0} (raw data)
+uinfo_facet_vegetation_zones_cross_section.description = Vegetation Zones
 uinfo_salix_scenario_deltaw = \u0394MW={0}
 uinfo_salix_scenario_supraregional = supraregional
 uinfo_salix_scenario_historical = historical
diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/resources/messages_de.properties
--- a/artifacts/src/main/resources/messages_de.properties	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/resources/messages_de.properties	Thu Sep 27 18:06:26 2018 +0200
@@ -1193,6 +1193,7 @@
 uinfo_facet_salix_scenario = Iota Szenario, {0}
 uinfo_facet_salix_scenario.filtered.description = Iota Szenario, {0}
 uinfo_facet_salix_scenario.raw.description = Iota Szenario, {0} (Rohdaten)
+uinfo_facet_vegetation_zones_cross_section.description = Vegetationszonen
 uinfo_salix_scenario_deltaw = \u0394MW={0}
 uinfo_salix_scenario_supraregional = \u00fcberregional
 uinfo_salix_scenario_historical = historisch
diff -r d8e753d0fdb9 -r 853f2dafc16e 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	Wed Sep 26 15:48:05 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java	Thu Sep 27 18:06:26 2018 +0200
@@ -1618,4 +1618,6 @@
     String no_data_for_input();
 
     String bundu_bezugswsts();
+
+    String vegetation_zones(); // Order für Datenkorb
 }
\ No newline at end of file
diff -r d8e753d0fdb9 -r 853f2dafc16e 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	Wed Sep 26 15:48:05 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Thu Sep 27 18:06:26 2018 +0200
@@ -826,11 +826,14 @@
 uinfo = U-INFO
 uinfo_salix_dmwspl_short = \u0394MW [cm]
 uinfo_inundation_duration_export = Flooding Durations Export
+uinfo_inundation_duration_report= Flooding Durations Report
 uinfo_inundation_duration_set_vegetation_zone = Set Vegetation Zone Table
 uinfo_salix_line_export = Iota Export
 uinfo_vegetation_zones_export = Vegetation Zones Export
+uinfo_vegetation_zones_report = Vegetation  Zones Report
 defaultVegetationZone = Default Vegetation Zone
 
+vegetation_zones = Vegetation Zones
 uinfo_vegetation_zone_overlap = Ranges are overlapping.
 uinfo_vegetation_zone_has_gaps =  The input (0-365) has gaps.
 uinfo_vegetation_zone_color = Color
diff -r d8e753d0fdb9 -r 853f2dafc16e 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	Wed Sep 26 15:48:05 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Thu Sep 27 18:06:26 2018 +0200
@@ -826,11 +826,14 @@
 uinfo = U-INFO
 uinfo_salix_dmwspl_short = \u0394MW [cm]
 uinfo_inundation_duration_export = \u00dcberflutungsdauern Export
+uinfo_inundation_duration_export = \u00dcberflutungsdauern Bericht
 uinfo_inundation_duration_set_vegetation_zone = Vegetationstabelle \u00fcbernehmen
 uinfo_salix_line_export = Iota Export
 uinfo_vegetation_zones_export = Vegetationszonen Export
+uinfo_vegetation_zones_report = Vegetationszonen Bericht
 defaultVegetationZone = Standardvegetationszone
 
+vegetation_zones = Vegetationszonen
 uinfo_vegetation_zone_overlap = Bereiche \u00fcberlappen.
 uinfo_vegetation_zone_has_gaps = Die Wertebelegung (0-365) weist L\u00fccken auf.
 uinfo_vegetation_zone_color = Farbe
diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/server/CollectionHelper.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/server/CollectionHelper.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/CollectionHelper.java	Thu Sep 27 18:06:26 2018 +0200
@@ -822,35 +822,41 @@
                 continue;
             }
 
-            OutputMode outmode = null;
             List<Facet> fs     = extractFacets(tmp);
 
-            if (type.equals("export")) {
-                outmode = new ExportMode(name, desc, mime, fs);
-            }
-            else if (type.equals("report")) {
-                outmode = new ReportMode(name, desc, mime, fs);
-            }
-            else if (type.equals("chart")){
-                outmode = new ChartMode(name, desc, mime, fs, type);
-            }
-            else if (type.equals("map")){
-                outmode = new MapMode(name, desc, mime, fs);
-            }
-            else if (type.equals("overview")) {
-                outmode = new OverviewMode(name, desc, mime, fs, type);
-            }
-            else {
-                log.warn("Broken Output mode without type found.");
-                continue;
-            }
-
-            modes.add(outmode);
+            final OutputMode outmode = createOutputMode( type, name, desc, mime, fs );
+            if( outmode != null )
+                modes.add(outmode);
         }
 
         return modes;
     }
 
+    private static OutputMode createOutputMode(String type, String name, String desc, String mime, List<Facet> fs) {
+        
+        if (type.equals("export")) 
+            return new ExportMode(name, desc, mime, fs);
+
+        if (type.equals("report"))
+            return new ReportMode(name, desc, mime, fs);
+
+        if (type.equals("chart"))
+            return new ChartMode(name, desc, mime, fs, type);
+
+        if (type.equals("map"))
+            return new MapMode(name, desc, mime, fs);
+        
+        if (type.equals("overview")) 
+            return new OverviewMode(name, desc, mime, fs, type);
+        
+        if (type.equals("invisible")) 
+            return null;
+        
+        log.warn("Broken Output mode without type found.");
+
+        return null;
+    }
+
 
     /**
      * Create a Key/Value map for data nodes of artifact/collectionitem.
diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/shared/model/DefaultCollectionItem.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/DefaultCollectionItem.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/DefaultCollectionItem.java	Thu Sep 27 18:06:26 2018 +0200
@@ -11,7 +11,6 @@
 import java.util.List;
 import java.util.Map;
 
-
 /**
  * The default implementation of a CollectionItem (artifact).
  *
@@ -19,6 +18,8 @@
  */
 public class DefaultCollectionItem implements CollectionItem {
 
+    private static final long serialVersionUID = 1L;
+
     /** The identifier that specifies the artifact related to this item. */
     protected String identifier;
 
@@ -31,52 +32,46 @@
     /** The map of datanames to data values. */
     protected Map<String, String> data;
 
-
     /**
      * An empty constructor.
      */
     public DefaultCollectionItem() {
     }
 
-
     /**
      * The default constructor to create a new CollectionItem related to an
      * artifact with output modes.
      *
-     * @param identifier The identifier of an artifact.
-     * @param outputModes The output modes supported by this item.
+     * @param identifier
+     *            The identifier of an artifact.
+     * @param outputModes
+     *            The output modes supported by this item.
      */
-    public DefaultCollectionItem(
-        String           identifier,
-        String           hash,
-        List<OutputMode> modes,
-        Map<String,String> data
-    ) {
-        this.identifier  = identifier;
-        this.hash        = hash;
+    public DefaultCollectionItem(final String identifier, final String hash, final List<OutputMode> modes, final Map<String, String> data) {
+        this.identifier = identifier;
+        this.hash = hash;
         this.outputModes = modes;
-        this.data        = data;
+        this.data = data;
     }
 
-
-
+    @Override
     public String identifier() {
-        return identifier;
+        return this.identifier;
     }
 
-
+    @Override
     public String hash() {
-        return hash;
+        return this.hash;
     }
 
-
+    @Override
     public List<OutputMode> getOutputModes() {
-        return outputModes;
+        return this.outputModes;
     }
 
-
-    public List<Facet> getFacets(String outputmode) {
-        for (OutputMode mode: outputModes) {
+    @Override
+    public List<Facet> getFacets(final String outputmode) {
+        for (final OutputMode mode : this.outputModes) {
             if (outputmode.equals(mode.getName())) {
                 // TODO Return facets, but facets are not implemented for
                 // OutputModes yet!
@@ -86,11 +81,12 @@
         return null;
     }
 
-
     /**
      * Returns artifact data.
+     * 
      * @return key/value data map
      */
+    @Override
     public Map<String, String> getData() {
         return this.data;
     }
diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/shared/model/VegetationZoneServerClientXChange.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/VegetationZoneServerClientXChange.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/VegetationZoneServerClientXChange.java	Thu Sep 27 18:06:26 2018 +0200
@@ -45,14 +45,16 @@
         }
         for (final String[] zone : results) {
 
-            final VegetationZoneServerClientXChange helper = new VegetationZoneServerClientXChange(zone[0], Integer.valueOf(zone[1]), Integer.valueOf(zone[2]), zone[3]);
+            final VegetationZoneServerClientXChange helper = new VegetationZoneServerClientXChange(zone[0], Integer.valueOf(zone[1]), Integer.valueOf(zone[2]),
+                    zone[3]);
             resultList.add(helper);
         }
 
         return resultList;
     }
 
-    public static VegetationZoneServerClientXChange createFromTableEntry(final String zone, final String min_day_overflow, final String max_day_overflow, final String hexColor) {
+    public static VegetationZoneServerClientXChange createFromTableEntry(final String zone, final String min_day_overflow, final String max_day_overflow,
+            final String hexColor) {
         return new VegetationZoneServerClientXChange(zone, Integer.valueOf(min_day_overflow), Integer.valueOf(max_day_overflow), hexColor); // Error-Handling?
     }
 
@@ -159,7 +161,7 @@
         treeList.addAll(list);
         int lowerCompare = lower;
         for (final VegetationZoneServerClientXChange zone : treeList) {
-            if (zone.getLowerFromTo() > (lowerCompare + 1)) { // nicht inklusiv
+            if (zone.getLowerFromTo() > (lowerCompare)) { // nicht inklusiv
                 return true;
             }
             lowerCompare = zone.getUpperFromTo();
@@ -176,12 +178,12 @@
 
         final int upper = getUpperFromTo();
         final int lower = getLowerFromTo();
-        final int otherSchwerpunkt = (otherLower + otherUpper) / 2;
-        if ((otherUpper <= upper && otherUpper >= lower)) {
+        // final int otherSchwerpunkt = (otherLower + otherUpper) / 2;
+        if ((otherUpper <= upper && otherUpper > lower)) {
             return true;
-        } else if (otherLower >= lower && otherLower <= upper) {
+        } else if (otherLower >= lower && otherLower < upper) {
             return true;
-        } else if (otherSchwerpunkt >= (lower) && otherSchwerpunkt <= (upper)) {
+        } else if (otherLower == lower && otherUpper == upper) {
             return true;
         }
         return false;


More information about the Dive4Elements-commits mailing list