changeset 8996:fb9430250899

Work on uinfo
author gernotbelger
date Thu, 12 Apr 2018 19:13:39 +0200
parents 8c3e5682cb60
children d5802f22e4f5
files artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhExporter.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/CalculationSelectUinfo.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/UINFOArtifact.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/UinfoCalcMode.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/commons/AbstractUInfoExporter.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/commons/UInfoResultType.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculationResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculationResults.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationExporter.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationState.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResults.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineExporter.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineState.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCalculationResult.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCalculationResults.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesExporter.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesState.java artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java artifacts/src/main/resources/messages.properties artifacts/src/main/resources/messages_de.properties
diffstat 26 files changed, 1690 insertions(+), 244 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java	Thu Apr 12 19:11:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java	Thu Apr 12 19:13:39 2018 +0200
@@ -22,6 +22,7 @@
 import org.apache.commons.lang.math.NumberRange;
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.artifacts.WINFOArtifact;
+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.CalculationResult;
@@ -29,7 +30,6 @@
 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.SInfoResultRow;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator;
@@ -151,7 +151,7 @@
             return null;
         }
 
-        final Collection<SInfoResultRow> rows = new ArrayList<>();
+        final Collection<ResultRow> rows = new ArrayList<>();
 
         for (final Double stationDbl : allStations) {
 
@@ -162,7 +162,7 @@
             if (tkhCalculator == null)
                 continue;
 
-            final SInfoResultRow row = SInfoResultRow.create();
+            final ResultRow row = ResultRow.create();
 
             row.putValue(SInfoResultType.waterlevelLabel, descBuilder.getDesc(wkms));
             row.putValue(SInfoResultType.gaugeLabel, riverInfoProvider.findGauge(station));
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResult.java	Thu Apr 12 19:11:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculationResult.java	Thu Apr 12 19:13:39 2018 +0200
@@ -11,8 +11,8 @@
 
 import java.util.Collection;
 
+import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.sinfo.common.AbstractTkhCalculationResult;
-import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow;
 import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
 
 /**
@@ -24,7 +24,7 @@
 
     private static final long serialVersionUID = 1L;
 
-    public TkhCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection<SInfoResultRow> rows) {
+    public TkhCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection<ResultRow> rows) {
         super(label, wst, hasTkh, rows);
     }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhExporter.java	Thu Apr 12 19:11:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhExporter.java	Thu Apr 12 19:13:39 2018 +0200
@@ -12,8 +12,9 @@
 import java.util.Collection;
 
 import org.apache.log4j.Logger;
+import org.dive4elements.river.artifacts.common.GeneralResultType;
+import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter;
-import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
@@ -29,10 +30,6 @@
 // REMARK: must be public because its registered in generators.xml
 public class TkhExporter extends AbstractSInfoExporter<TkhCalculationResult, TkhCalculationResults> {
 
-    private static enum ExportMode {
-        pdf, csv
-    }
-
     /** The log used in this exporter. */
     private static Logger log = Logger.getLogger(TkhExporter.class);
 
@@ -67,7 +64,7 @@
 
         final Collection<String> header = new ArrayList<>(11);
 
-        header.add(msg(SInfoResultType.station.getCsvHeader()));
+        header.add(msg(GeneralResultType.station.getCsvHeader()));
         header.add(msgUnit(SInfoResultType.tkh.getCsvHeader(), SInfoResultType.tkh.getUnit()));
         header.add(msg(SInfoResultType.soilkind.getCsvHeader()));
         header.add(msgUnit(SInfoResultType.meanBedHeight.getCsvHeader(), river.getWstUnit()));
@@ -96,11 +93,6 @@
         // "# Q (m³/s): " (nur bei Eingabe des Durchflusses)
     }
 
-    @Override
-    protected String[] formatCSVRow(final TkhCalculationResults results, final TkhCalculationResult result, final SInfoResultRow row) {
-        return formatRow(results, row, ExportMode.csv);
-    }
-
     /**
      * Format a row of a flow depth result into an array of string, both used by csv and pdf
      *
@@ -108,11 +100,12 @@
      *
      * @param useTkh
      */
-    private String[] formatRow(final TkhCalculationResults results, final SInfoResultRow row, final ExportMode mode) {
+    @Override
+    protected String[] formatRow(final TkhCalculationResults results, final ResultRow row, final ExportMode mode) {
 
         final Collection<String> lines = new ArrayList<>(11);
 
-        lines.add(row.exportValue(this.context, SInfoResultType.station));
+        lines.add(row.exportValue(this.context, GeneralResultType.station));
         lines.add(row.exportValue(this.context, SInfoResultType.tkh));
         lines.add(row.exportValue(this.context, SInfoResultType.soilkind));
         lines.add(row.exportValue(this.context, SInfoResultType.meanBedHeight));
@@ -138,19 +131,19 @@
     protected final void addJRMetaData(final MetaAndTableJRDataSource source, final TkhCalculationResults results) {
 
         /* general metadata */
-        super.addJRMetaDataDefaults(source, results);
+        super.addJRMetaData(source, results);
 
-        source.addMetaData("calculation_label",msg( "sinfo.export.flow_depth.pdf.meta.calculation.label" ));
-        source.addMetaData("calculation_name",msg( "sinfo.export.flow_depth.pdf.meta.calculation.name" ));
-        
+        source.addMetaData("calculation_label", msg("sinfo.export.flow_depth.pdf.meta.calculation.label"));
+        source.addMetaData("calculation_name", msg("sinfo.export.flow_depth.pdf.meta.calculation.name"));
+
         /* column headings */
-        source.addMetaData("station_header", SInfoResultType.station.getPdfHeader(this.context.getMeta()));
+        source.addMetaData("station_header", GeneralResultType.station.getPdfHeader(this.context.getMeta()));
         source.addMetaData("tkh_header", SInfoResultType.tkh.getPdfHeader(this.context.getMeta()));
         source.addMetaData("tkhkind_header", SInfoResultType.soilkind.getPdfHeader(this.context.getMeta()));
         source.addMetaData("bedheight_header", SInfoResultType.meanBedHeight.getPdfHeader(this.context.getMeta()));
         source.addMetaData("waterlevel_header", SInfoResultType.waterlevel.getPdfHeader(this.context.getMeta()));
         source.addMetaData("discharge_header", SInfoResultType.discharge.getPdfHeader(this.context.getMeta()));
-        	
+
         // REMARK: actually the column makes no sense if description header is null. But (software symmetry...) WINFO also
         // writes an empty column into the pdf in that case (most probably to avoid the need for two jasper templates).
         final String descriptionHeader = results.getDescriptionHeader();
@@ -162,8 +155,4 @@
         source.addMetaData("location_header", SInfoResultType.location.getPdfHeader(this.context.getMeta()));
     }
 
-    @Override
-    protected String[] formatPDFRow(final TkhCalculationResults results, final SInfoResultRow row) {
-        return formatRow(results, row, ExportMode.pdf);
-    }
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/CalculationSelectUinfo.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,61 @@
+/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.uinfo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.artifacts.CallMeta;
+import org.dive4elements.artifacts.common.utils.XMLUtils;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.states.DefaultState;
+import org.w3c.dom.Element;
+
+/**
+ * @author Gernot Belger
+ */
+public class CalculationSelectUinfo extends DefaultState {
+
+    private static final long serialVersionUID = 1L;
+
+    /** The log that is used in this class. */
+    private static Logger log = Logger.getLogger(CalculationSelectUinfo.class);
+
+    @Override
+    protected Element[] createItems(final XMLUtils.ElementCreator cr, final Artifact artifact, final String name, final CallContext context) {
+        final CallMeta meta = context.getMeta();
+
+        final Collection<Element> calcs = new ArrayList<>(UinfoCalcMode.values().length);
+
+        for (final UinfoCalcMode calcMode : UinfoCalcMode.values()) {
+            final String calc = calcMode.name();
+
+            final String label = Resources.getMsg(meta, calc, calc);
+
+            final Element element = createItem(cr, new String[] { label, calc });
+            calcs.add(element);
+        }
+
+        return calcs.toArray(new Element[calcs.size()]);
+    }
+
+    @Override
+    public boolean validate(final Artifact artifact) throws IllegalArgumentException {
+        log.debug("CalculationSelect.validate");
+
+        final UINFOArtifact sinfo = (UINFOArtifact) artifact;
+        /* throws an exception if calculation mode is invalid */
+        sinfo.getCalculationMode();
+        return true;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/UINFOArtifact.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,87 @@
+/* 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;
+
+import org.apache.commons.lang.StringUtils;
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifactdatabase.state.FacetActivity;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.river.artifacts.D4EArtifact;
+
+/**
+ * The default SINFO artifact.
+ *
+ * @author Gernot Belger
+ */
+public class UINFOArtifact extends D4EArtifact {
+
+	private static final long serialVersionUID = 1L;
+
+	/** Error message that is thrown if no mode has been chosen. */
+	private static final String ERROR_NO_CALCULATION_MODE = "error_feed_no_calculation_mode";
+
+	/**
+	 * Error message that is thrown if an invalid calculation mode has been chosen.
+	 */
+	private static final String ERROR_INVALID_CALCULATION_MODE = "error_feed_invalid_calculation_mode";
+
+	/** The name of the artifact. */
+	private static final String ARTIFACT_NAME = "uinfo";
+
+	private static final String FIELD_RIVER = "river";
+
+	private static final String FIELD_MODE = "calculation_mode";
+
+	static {
+		// Active/deactivate facets.
+		// BEWARE: we can only define one activity for "sinfo", so we use the artifact
+		// as place for this
+		FacetActivity.Registry.getInstance().register(ARTIFACT_NAME, new FacetActivity() {
+			@Override
+			public Boolean isInitialActive(final Artifact artifact, final Facet facet, final String output) {
+				return null;
+			}
+		});
+	}
+
+	/**
+	 * Default constructor, because it's serializable.
+	 */
+	public UINFOArtifact() {
+	}
+
+	/**
+	 * Returns the name of the concrete artifact.
+	 *
+	 * @return the name of the concrete artifact.
+	 */
+	@Override
+	public String getName() {
+		return ARTIFACT_NAME;
+	}
+
+	public UinfoCalcMode getCalculationMode() {
+
+		final String calc = getDataAsString(FIELD_MODE);
+		if (calc == null) {
+			throw new IllegalArgumentException(ERROR_NO_CALCULATION_MODE);
+		}
+
+		try {
+			return UinfoCalcMode.valueOf(StringUtils.trimToEmpty(calc).toLowerCase());
+		} catch (final Exception e) {
+			throw new IllegalArgumentException(ERROR_INVALID_CALCULATION_MODE, e);
+		}
+	}
+
+	public String getRiver() {
+		return getDataAsString(FIELD_RIVER);
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/UinfoCalcMode.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,17 @@
+/* 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;
+
+public enum UinfoCalcMode{
+	uinfo_salix_line,
+	uinfo_inundation_duration,
+	uinfo_vegetation_zones
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/commons/AbstractUInfoExporter.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,124 @@
+/** 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.commons;
+
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.river.FLYS;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResults;
+import org.dive4elements.river.artifacts.common.AbstractCommonExporter;
+import org.dive4elements.river.artifacts.common.I18NStrings;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+
+import au.com.bytecode.opencsv.CSVWriter;
+
+/**
+ * @author Gernot Belger
+ */
+public abstract class AbstractUInfoExporter<RESULT extends AbstractCalculationResult, RESULTS extends AbstractCalculationResults<RESULT>> extends AbstractCommonExporter<RESULT, RESULTS> {
+
+    @Override
+    protected void addJRMetaData(final MetaAndTableJRDataSource source, final RESULTS results) {
+
+        /* general metadata */
+        this.addJRMetaDataDefaults(source, results);
+
+        /* general metadata */
+        this.addJRMetaDataDefaults(source, results);
+
+        final RiverInfo river = results.getRiver();
+        final String wstUnitName = river.getWstUnit();
+
+        source.addMetaData("river_label", msg(I18NStrings.CSV_META_RIVER_LABEL));
+        source.addMetaData("river", river.getName());
+        source.addMetaData("river_unit", wstUnitName);
+
+        source.addMetaData("range_label", msg(I18NStrings.CSV_META_RANGE_LABEL));
+        final DoubleRange calcRange = results.getCalcRange();
+        final NumberFormat kmFormatter = getKmFormatter();
+        if (calcRange != null) {
+            final String rangeValue = String.format("%s - %s", kmFormatter.format(calcRange.getMinimumDouble()),
+                    kmFormatter.format(calcRange.getMaximumDouble()));
+            source.addMetaData("range", rangeValue);
+        }
+
+        /* column headings */
+        // source.addMetaData("station_header", GeneralResultType.station.getPdfHeader(this.context.getMeta())); // moved to
+        // super
+
+        // TODO: move to subs
+        // source.addMetaData("flowdepth_header", SInfoResultType.flowdepth.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("flowdepth_tkh_header", SInfoResultType.flowdepthtkh.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("tkh_header", SInfoResultType.tkh.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("waterlevel_header", SInfoResultType.waterlevel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("discharge_header", SInfoResultType.discharge.getPdfHeader(this.context.getMeta()));
+
+    }
+
+    @Override
+    protected void writeCSVGlobalMetadataDefaults(final CSVWriter writer, final RESULTS results) {
+
+        final String calcModeLabel = results.getCalcModeLabel();
+        final RiverInfo river = results.getRiver();
+        final DoubleRange calcRange = results.getCalcRange();
+
+        writeCSVMetaEntry(writer, I18NStrings.CSV_META_HEADER_RESULT, msg(I18NStrings.CSV_META_HEADER_RESULT_LABEL), river.getName(), calcModeLabel);
+
+        // "# FLYS-Version: "
+        writeCSVMetaEntry(writer, I18NStrings.CSV_META_VERSION, msg(I18NStrings.CSV_META_VERSION_LABEL), FLYS.VERSION);
+
+        // "# Bearbeiter: "
+        writeCSVMetaEntry(writer, I18NStrings.CSV_META_USER, msg(I18NStrings.CSV_META_USER_LABEL), results.getUser());
+
+        // "# Datum der Erstellung: "
+        final Locale locale = Resources.getLocale(this.context.getMeta());
+        final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+        writeCSVMetaEntry(writer, I18NStrings.CSV_META_CREATION, msg(I18NStrings.CSV_META_CREATION_LABEL), df.format(new Date()));
+
+        // "# Gewässer: "
+        writeCSVMetaEntry(writer, I18NStrings.CSV_META_RIVER, msg(I18NStrings.CSV_META_RIVER_LABEL), river.getName());
+
+        // "# Höhensystem des Flusses: "
+        writeCSVMetaEntry(writer, I18NStrings.CSV_META_HEIGHT_UNIT_RIVER, river.getWstUnit()); // move to child?
+
+        if (calcRange != null) {
+            // "# Ort/Bereich (km): "
+            writeCSVMetaEntry(writer, I18NStrings.CSV_META_RANGE, msg(I18NStrings.CSV_META_RANGE_LABEL), getKmFormatter().format(calcRange.getMinimumDouble()),
+                    getKmFormatter().format(calcRange.getMaximumDouble()));
+        }
+    }
+
+    @Override
+    protected void addJRMetaDataDefaults(final MetaAndTableJRDataSource source, final RESULTS results) {
+
+        source.addMetaData("header", msg(I18NStrings.CSV_META_HEADER_RESULT_LABEL));
+        source.addMetaData("calcMode", results.getCalcModeLabel());
+
+        source.addMetaData("version_label", msg(I18NStrings.CSV_META_VERSION_LABEL));
+        source.addMetaData("version", FLYS.VERSION);
+
+        source.addMetaData("user_label", msg(I18NStrings.CSV_META_USER_LABEL));
+        source.addMetaData("user", results.getUser());
+
+        final Locale locale = Resources.getLocale(this.context.getMeta());
+        final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+        source.addMetaData("date_label", msg(I18NStrings.CSV_META_CREATION_LABEL));
+        source.addMetaData("date", df.format(new Date()));
+
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/commons/UInfoResultType.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,86 @@
+/** 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.commons;
+
+import java.text.NumberFormat;
+
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.common.AbstractResultType;
+import org.dive4elements.river.utils.Formatter;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public abstract class UInfoResultType extends AbstractResultType {
+
+    public UInfoResultType(final String unit, final String csvHeader) {
+        super(unit, csvHeader, csvHeader);
+
+    }
+
+    @Override
+    public String exportValue(final CallContext context, final Object value) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    protected NumberFormat createFormatter(final CallContext context) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public static final UInfoResultType salixline = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.salix_line") {
+        @Override
+        public String exportValue(final CallContext context, final Object value) {
+            final double doubleValue = asDouble(value);
+            return exportDoubleValue(context, doubleValue);
+        }
+
+        @Override
+        protected NumberFormat createFormatter(final CallContext context) {
+            // REMARK: other modules use Formatter.getWaterlevelW(context) instead, but that format with a variable number of
+            // digits.
+            return Formatter.getSalixLine(context);
+        }
+    };
+
+    public static final UInfoResultType salixlinehist = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.hist") {
+        @Override
+        public String exportValue(final CallContext context, final Object value) {
+            final double doubleValue = asDouble(value);
+            return exportDoubleValue(context, doubleValue);
+        }
+
+        @Override
+        protected NumberFormat createFormatter(final CallContext context) {
+            // REMARK: other modules use Formatter.getWaterlevelW(context) instead, but that format with a variable number of
+            // digits.
+            return Formatter.getSalixLine(context);
+        }
+    };
+
+    public static final UInfoResultType salixlinescen = new UInfoResultType(null, "uinfo.export.salix_line.csv.header.scen") {
+        @Override
+        public String exportValue(final CallContext context, final Object value) {
+            final double doubleValue = asDouble(value);
+            return exportDoubleValue(context, doubleValue);
+        }
+
+        @Override
+        protected NumberFormat createFormatter(final CallContext context) {
+            // REMARK: other modules use Formatter.getWaterlevelW(context) instead, but that format with a variable number of
+            // digits.
+            return Formatter.getSalixLine(context);
+        }
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculation.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,75 @@
+/** 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.inundationduration;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.access.RiverAccess;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
+import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
+import org.dive4elements.river.model.River;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+final class InundationDurationCalculation {
+
+    private CallContext context;
+
+    public InundationDurationCalculation(CallContext context) {
+        this.context = context;
+    }
+
+    public CalculationResult calculate(UINFOArtifact uinfo) {
+        final Calculation problems = new Calculation();
+
+        final String calcModeLabel = Resources.getMsg(this.context.getMeta(), uinfo.getCalculationMode().name());
+        final String user = CalculationUtils.findArtifactUser(this.context, uinfo);
+
+        final RiverAccess access = new RiverAccess(uinfo);
+        final River river = access.getRiver();
+        DoubleRange calcRange = null;
+        final RiverInfo riverInfo = new RiverInfo(river);
+        
+        final InundationDurationCalculationResults results = new InundationDurationCalculationResults(calcModeLabel, user, riverInfo, calcRange);
+
+        final Collection<ResultRow> rows = new ArrayList<ResultRow>();
+        
+        final ResultRow row1 = ResultRow.create(). // 
+                putValue(SInfoResultType.discharge, 100). //
+        putValue(SInfoResultType.waterlevel, 2). //
+        putValue(SInfoResultType.gaugeLabel, "Torgau");
+
+        rows.add(row1);
+
+        ResultRow row2 = ResultRow.create(). // 
+                putValue(SInfoResultType.discharge, 200). //
+                putValue(SInfoResultType.waterlevel, 3). //
+                putValue(SInfoResultType.gaugeLabel, "Zollenspieker");
+
+        rows.add(row2);
+
+        final InundationDurationCalculationResult result = new InundationDurationCalculationResult("Ergebnis 1", null, rows);
+        
+        results.addResult(result, problems);
+        
+        return new CalculationResult(results, problems);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculationResult.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,29 @@
+/** 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.inundationduration;
+
+import java.util.Collection;
+
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+final class InundationDurationCalculationResult extends AbstractCalculationResult {
+
+    private static final long serialVersionUID = 1L;
+
+    public InundationDurationCalculationResult(final String label, final WstInfo wst, final Collection< ResultRow> rows) {
+        super(label,  rows);
+    }
+    
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculationResults.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,27 @@
+/** 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.inundationduration;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResults;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+final class InundationDurationCalculationResults extends AbstractCalculationResults<InundationDurationCalculationResult> {
+
+    private static final long serialVersionUID = 1L;
+
+    public InundationDurationCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) {
+        super(calcModeLabel, user, river, calcRange);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationExporter.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,138 @@
+/** 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.inundationduration;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.river.artifacts.common.GeneralResultType;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
+import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+import org.dive4elements.river.artifacts.uinfo.commons.AbstractUInfoExporter;
+
+import au.com.bytecode.opencsv.CSVWriter;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public class InundationDurationExporter extends AbstractUInfoExporter<InundationDurationCalculationResult, InundationDurationCalculationResults> {
+
+    /** The log used in this exporter. */
+    private static Logger log = Logger.getLogger(InundationDurationExporter.class);
+
+    private static final String JASPER_FILE = "/jasper/uinfo.inundationduration.jasper";
+
+    @Override
+    protected Logger getLog() {
+        return log;
+    }
+
+    @Override
+    protected void writeCSVGlobalMetadata(final CSVWriter writer, final InundationDurationCalculationResults results) {
+        log.info("SalixLineExporter.writeCSVMeta");
+
+        super.writeCSVGlobalMetadataDefaults(writer, results);
+    }
+
+    @Override
+    protected void writeCSVResultMetadata(final CSVWriter writer, final InundationDurationCalculationResults results,
+            final InundationDurationCalculationResult result) {
+
+        /*
+         * final BedHeightInfo sounding = result.getSounding();
+         * super.writeCSVSoundingMetadata(writer, sounding);
+         * final WstInfo wst = result.getWst();
+         * super.writeCSVWaterlevelMetadata(writer, wst);
+         */
+    }
+
+    /**
+     * Write the header, with different headings depending on whether at a
+     * gauge or at a location.
+     *
+     * @param river
+     * @param useTkh
+     */
+    @Override
+    protected void writeCSVHeader(final CSVWriter writer, final InundationDurationCalculationResults results, final RiverInfo river) {
+        log.info("FlowDepthExporter.writeCSVHeader");
+
+        final Collection<String> header = new ArrayList<>(11);
+
+        header.add(msg(GeneralResultType.station.getCsvHeader()));
+        header.add(msgUnit(SInfoResultType.flowdepth.getCsvHeader(), SInfoResultType.flowdepth.getUnit()));
+
+        header.add(msgUnit(SInfoResultType.waterlevel.getCsvHeader(), river.getWstUnit()));
+        header.add(msgUnit(SInfoResultType.discharge.getCsvHeader(), SInfoResultType.discharge.getUnit()));
+        header.add(msg(SInfoResultType.waterlevelLabel.getCsvHeader()));
+        header.add(msg(SInfoResultType.gaugeLabel.getCsvHeader()));
+        header.add(msgUnit(SInfoResultType.meanBedHeight.getCsvHeader(), river.getWstUnit()));
+        header.add(msg(SInfoResultType.soundingLabel.getCsvHeader()));
+        header.add(msg(SInfoResultType.location.getCsvHeader()));
+
+        writer.writeNext(header.toArray(new String[header.size()]));
+    }
+
+    /**
+     * Format a row of a flow depth result into an array of string, both used by csv and pdf
+     *
+     * @param pdf
+     *
+     * @param useTkh
+     */
+    @Override
+    protected String[] formatRow(final InundationDurationCalculationResults results, final ResultRow row, final ExportMode mode) {
+
+        final Collection<String> lines = new ArrayList<>(11);
+
+        lines.add(row.exportValue(this.context, GeneralResultType.station));
+        lines.add(row.exportValue(this.context, SInfoResultType.flowdepth));
+
+        lines.add(row.exportValue(this.context, SInfoResultType.waterlevel));
+        lines.add(row.exportValue(this.context, SInfoResultType.discharge));
+        lines.add(row.exportValue(this.context, SInfoResultType.waterlevelLabel));
+        lines.add(row.exportValue(this.context, SInfoResultType.gaugeLabel));
+        lines.add(row.exportValue(this.context, SInfoResultType.meanBedHeight));
+        lines.add(row.exportValue(this.context, SInfoResultType.soundingLabel));
+        lines.add(row.exportValue(this.context, SInfoResultType.location));
+
+        return lines.toArray(new String[lines.size()]);
+    }
+
+    @Override
+    protected final String getJasperFile() {
+        return JASPER_FILE;
+    }
+
+    @Override
+    protected final void addJRMetaData(final MetaAndTableJRDataSource source, final InundationDurationCalculationResults results) {
+
+        /* general metadata */
+        super.addJRMetaData(source, results);
+       
+        /* column headings */
+        source.addMetaData("station_header", GeneralResultType.station.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("flowdepth_header", SInfoResultType.flowdepth.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("flowdepth_tkh_header", SInfoResultType.flowdepthtkh.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("tkh_header", SInfoResultType.tkh.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("waterlevel_header", SInfoResultType.waterlevel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("discharge_header", SInfoResultType.discharge.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("waterlevel_name_header", SInfoResultType.waterlevelLabel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("gauge_header", SInfoResultType.gaugeLabel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("bedheight_header", SInfoResultType.meanBedHeight.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("sounding_name_header", SInfoResultType.soundingLabel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("location_header", SInfoResultType.location.getPdfHeader(this.context.getMeta()));
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationState.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,104 @@
+/** 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.inundationduration;
+
+import java.util.List;
+
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.ChartArtifact;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.model.EmptyFacet;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.artifacts.model.ReportFacet;
+import org.dive4elements.river.artifacts.states.DefaultState;
+import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+public class InundationDurationState extends DefaultState {
+
+    /// ** The log that is used in this state. */
+    // private static Logger log = Logger.getLogger(FlowDepthState.class);
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * From this state can only be continued trivially.
+     */
+    @Override
+    protected String getUIProvider() {
+        return "continue";
+    }
+
+    @Override
+    public Object computeFeed(final D4EArtifact artifact, final String hash, final CallContext context, final List<Facet> facets, final Object old) {
+        // FIXME: why is this necessary?
+        if (artifact instanceof ChartArtifact) {
+            facets.add(new EmptyFacet());
+            return null;
+        }
+
+        return compute((UINFOArtifact) artifact, context, hash, facets, old);
+    }
+
+    @Override
+    public Object computeAdvance(final D4EArtifact artifact, final String hash, final CallContext context, final List<Facet> facets, final Object old) {
+        if (artifact instanceof ChartArtifact) {
+            facets.add(new EmptyFacet());
+            return null;
+        }
+        return compute((UINFOArtifact) artifact, context, hash, facets, old);
+    }
+
+    /**
+     * Compute result or returned object from cache, create facets.
+     *
+     * @param old
+     *            Object that was cached.
+     */
+    private Object compute(final UINFOArtifact sinfo, final CallContext context, final String hash, final List<Facet> facets, final Object old) {
+
+        final CalculationResult res = doCompute(sinfo, context, old);
+
+        if (facets == null)
+            return res;
+
+        final InundationDurationCalculationResults results = (InundationDurationCalculationResults) res.getData();
+
+        List<InundationDurationCalculationResult> resultList = results.getResults();
+
+        if (!resultList.isEmpty()) {
+            final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id);
+            final Facet pdf = new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id);
+
+            facets.add(csv);
+            facets.add(pdf);
+        }
+
+        final Calculation report = res.getReport();
+
+        if (report.hasProblems())
+            facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
+
+        return res;
+    }
+
+    private CalculationResult doCompute(final UINFOArtifact sinfo, final CallContext context, final Object old) {
+        if (old instanceof CalculationResult)
+            return (CalculationResult) old;
+
+        return new InundationDurationCalculation(context).calculate(sinfo);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,74 @@
+/** 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.salix;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.access.RiverAccess;
+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.CalculationResult;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
+import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
+import org.dive4elements.river.model.River;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+final class SalixLineCalculation {
+
+    private final CallContext context;
+
+    public SalixLineCalculation(final CallContext context) {
+        this.context = context;
+    }
+
+    public CalculationResult calculate(final UINFOArtifact uinfo) {
+        final Calculation problems = new Calculation();
+
+        final String calcModeLabel = Resources.getMsg(this.context.getMeta(), uinfo.getCalculationMode().name());
+        final String user = CalculationUtils.findArtifactUser(this.context, uinfo);
+
+        final RiverAccess access = new RiverAccess(uinfo);
+        final River river = access.getRiver();
+        final DoubleRange calcRange = null;
+        final RiverInfo riverInfo = new RiverInfo(river);
+
+        final SalixLineCalculationResults results = new SalixLineCalculationResults(calcModeLabel, user, riverInfo, calcRange);
+
+        final Collection<ResultRow> rows = new ArrayList<>();
+
+        final ResultRow row1 = ResultRow.create(). //
+                putValue(GeneralResultType.station, 100).putValue(UInfoResultType.salixline, 28).putValue(UInfoResultType.salixlinehist, 2)
+                .putValue(UInfoResultType.salixlinescen, 82);
+        rows.add(row1);
+
+        final ResultRow row2 = ResultRow.create(). //
+                putValue(GeneralResultType.station, 200). //
+                putValue(UInfoResultType.salixline, 3). //
+                putValue(UInfoResultType.salixlinehist, 2).putValue(UInfoResultType.salixlinescen, 822);
+
+        rows.add(row2);
+
+        final SalixLineCalculationResult result = new SalixLineCalculationResult("Ergebnis 1", null, rows);
+
+        results.addResult(result, problems);
+
+        return new CalculationResult(results, problems);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,29 @@
+/** 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.salix;
+
+import java.util.Collection;
+
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+final class SalixLineCalculationResult extends AbstractCalculationResult {
+
+    private static final long serialVersionUID = 1L;
+
+    public SalixLineCalculationResult(final String label, final WstInfo wst, final Collection< ResultRow> rows) {
+        super(label,  rows);
+    }
+    
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResults.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,27 @@
+/** 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.salix;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResults;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+final class SalixLineCalculationResults extends AbstractCalculationResults<SalixLineCalculationResult> {
+
+    private static final long serialVersionUID = 1L;
+
+    public SalixLineCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) {
+        super(calcModeLabel, user, river, calcRange);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineExporter.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,182 @@
+/** 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.salix;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.river.artifacts.common.GeneralResultType;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+import org.dive4elements.river.artifacts.uinfo.commons.AbstractUInfoExporter;
+import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
+
+import au.com.bytecode.opencsv.CSVWriter;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public class SalixLineExporter extends AbstractUInfoExporter<SalixLineCalculationResult, SalixLineCalculationResults> {
+
+    /** The log used in this exporter. */
+    private static Logger log = Logger.getLogger(SalixLineExporter.class);
+
+    private static final String JASPER_FILE = "/jasper/uinfo.salixline.jasper";
+
+    @Override
+    protected Logger getLog() {
+        return log;
+    }
+
+    @Override
+    protected void writeCSVGlobalMetadata(final CSVWriter writer, final SalixLineCalculationResults results) {
+        log.info("SalixLineExporter.writeCSVMeta");
+
+        super.writeCSVGlobalMetadataDefaults(writer, results);
+
+        // Add Auswerter, Bezugspegel, Jahr/Zeitraum der Wasserspiegellage
+
+        // "# Auswerter: "
+        writeCSVMetaEntry(writer, "uinfo.export.salix_line.csv.meta.header.evaluator", "sounding.getEvaluationBy()");
+        // "# Bezugspegel: "
+        writeCSVMetaEntry(writer, "uinfo.export.salix_line.csv.meta.header.waterlevel.gauge", "wst.getGauge()");
+
+        // "# Jahr/Zeitraum der Wasserspiegellage: "
+        // final int year = wst.getYear();
+        // if (year > 0)
+        writeCSVMetaEntry(writer, "uinfo.export.salix_line.csv.meta.header.waterlevel.year", "Integer.toString(year)");
+
+    }
+
+    private void writeRegionalEffectsCSVMetadata(final CSVWriter writer) {
+        final String main = "uinfo.export.csv.meta.header.salix.regional";
+        // "##Regional wirkende Eingriffe"
+        writeCSVMetaEntry(writer, main);
+        writeRegionalCommonCSVMeta(writer);
+    }
+
+    private void writeRegionalCommonCSVMeta(final CSVWriter writer) {
+        final String main = "uinfo.export.csv.meta.header.salix";
+        // "# Szenariotyp: "
+        writeCSVMetaEntry(writer, main + ".szenariotyp");
+        // "# Teilabschnitt: "
+        writeCSVMetaEntry(writer, main + ".teilabschnitt");
+        // "# Mittelwasserspiegellagenänderung: "
+        writeCSVMetaEntry(writer, main + ".mwspiegellaenderung");
+    }
+
+    private void writeExtendedRegionalEffectsCSVMetadata(final CSVWriter writer) {
+        final String main = "uinfo.export.csv.meta.header.salix.regionalextended";
+        // "##Ãœberregional wirkende Eingriffe"
+        writeCSVMetaEntry(writer, main);
+
+        writeRegionalCommonCSVMeta(writer);
+    }
+
+    private void writeHistoricalViewCSVMetadata(final CSVWriter writer) {
+        final String main = "uinfo.export.csv.meta.header.salix.historical";
+        // "##Historische Betrachtung"
+        writeCSVMetaEntry(writer, main);
+
+        final String mainSub = "uinfo.export.csv.meta.header.salix";
+        // "# Szenariotyp: "
+        writeCSVMetaEntry(writer, mainSub + ".szenariotyp");
+        // "# Teilabschnitt: "
+        writeCSVMetaEntry(writer, mainSub + ".teilabschnitt");
+
+        // "# Art des Zeitraums: "
+        writeCSVMetaEntry(writer, main + ".zeitart");
+        // "# Historischer Zeitpunkt: "
+        writeCSVMetaEntry(writer, main + ".zeitpunkt");
+    }
+
+    @Override
+    protected void writeCSVResultMetadata(final CSVWriter writer, final SalixLineCalculationResults results, final SalixLineCalculationResult result) {
+        writeRegionalEffectsCSVMetadata(writer);
+        writer.writeNext(new String[] { "" }); // break line
+        writeExtendedRegionalEffectsCSVMetadata(writer);
+        writer.writeNext(new String[] { "" }); // break line
+        writeHistoricalViewCSVMetadata(writer);
+    }
+
+    /**
+     * Write the header, with different headings depending on whether at a
+     * gauge or at a location.
+     *
+     * @param river
+     * @param useTkh
+     */
+    @Override
+    protected void writeCSVHeader(final CSVWriter writer, final SalixLineCalculationResults results, final RiverInfo river) {
+        log.info("FlowDepthExporter.writeCSVHeader");
+
+        final Collection<String> header = new ArrayList<>(4);
+
+        header.add(msg(GeneralResultType.station.getCsvHeader()));
+        // header.add(msgUnit(SInfoResultType.flowdepth.getCsvHeader(), SInfoResultType.flowdepth.getUnit()));
+
+        header.add(msg(UInfoResultType.salixline.getCsvHeader()));
+        // wenn "historisch" gewählt wurde, nur "historisch" anzeigen; sonst für jeden scen-wert ne neue Spalte und "hist"
+        // ausblenden!...!..!!
+        header.add(msg(UInfoResultType.salixlinehist.getCsvHeader()));
+        header.add(msg(UInfoResultType.salixlinescen.getCsvHeader()));
+        writer.writeNext(header.toArray(new String[header.size()]));
+    }
+
+    /**
+     * Format a row of a flow depth result into an array of string, both used by csv and pdf
+     *
+     * @param pdf
+     *
+     * @param useTkh
+     */
+    @Override
+    protected String[] formatRow(final SalixLineCalculationResults results, final ResultRow row, final ExportMode mode) {
+
+        final Collection<String> lines = new ArrayList<>(3);
+
+        lines.add(row.exportValue(this.context, GeneralResultType.station));
+        lines.add(row.exportValue(this.context, UInfoResultType.salixline));
+
+        // wenn "historisch" gewählt wurde, nur "historisch" anzeigen; sonst für jeden scen-wert ne neue Spalte und "hist"
+        // ausblenden!...!..!!
+        lines.add(row.exportValue(this.context, UInfoResultType.salixlinehist));
+        lines.add(row.exportValue(this.context, UInfoResultType.salixlinescen));
+        return lines.toArray(new String[lines.size()]);
+    }
+
+    @Override
+    protected final String getJasperFile() {
+        return JASPER_FILE;
+    }
+
+    @Override
+    protected final void addJRMetaData(final MetaAndTableJRDataSource source, final SalixLineCalculationResults results) {
+
+        super.addJRMetaData(source, results);
+
+        /* additional column headings */
+        source.addMetaData("station_header", GeneralResultType.station.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("flowdepth_header", SInfoResultType.flowdepth.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("flowdepth_tkh_header", SInfoResultType.flowdepthtkh.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("tkh_header", SInfoResultType.tkh.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("waterlevel_header", SInfoResultType.waterlevel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("discharge_header", SInfoResultType.discharge.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("waterlevel_name_header", SInfoResultType.waterlevelLabel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("gauge_header", SInfoResultType.gaugeLabel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("bedheight_header", SInfoResultType.meanBedHeight.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("sounding_name_header", SInfoResultType.soundingLabel.getPdfHeader(this.context.getMeta()));
+        // source.addMetaData("location_header", SInfoResultType.location.getPdfHeader(this.context.getMeta()));
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineState.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,104 @@
+/** 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.salix;
+
+import java.util.List;
+
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.ChartArtifact;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.model.EmptyFacet;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.artifacts.model.ReportFacet;
+import org.dive4elements.river.artifacts.states.DefaultState;
+import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+public class SalixLineState extends DefaultState {
+
+    /// ** The log that is used in this state. */
+    // private static Logger log = Logger.getLogger(FlowDepthState.class);
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * From this state can only be continued trivially.
+     */
+    @Override
+    protected String getUIProvider() {
+        return "continue";
+    }
+
+    @Override
+    public Object computeFeed(final D4EArtifact artifact, final String hash, final CallContext context, final List<Facet> facets, final Object old) {
+        // FIXME: why is this necessary?
+        if (artifact instanceof ChartArtifact) {
+            facets.add(new EmptyFacet());
+            return null;
+        }
+
+        return compute((UINFOArtifact) artifact, context, hash, facets, old);
+    }
+
+    @Override
+    public Object computeAdvance(final D4EArtifact artifact, final String hash, final CallContext context, final List<Facet> facets, final Object old) {
+        if (artifact instanceof ChartArtifact) {
+            facets.add(new EmptyFacet());
+            return null;
+        }
+        return compute((UINFOArtifact) artifact, context, hash, facets, old);
+    }
+
+    /**
+     * Compute result or returned object from cache, create facets.
+     *
+     * @param old
+     *            Object that was cached.
+     */
+    private Object compute(final UINFOArtifact sinfo, final CallContext context, final String hash, final List<Facet> facets, final Object old) {
+
+        final CalculationResult res = doCompute(sinfo, context, old);
+
+        if (facets == null)
+            return res;
+
+        final SalixLineCalculationResults results = (SalixLineCalculationResults) res.getData();
+
+        List<SalixLineCalculationResult> resultList = results.getResults();
+
+        if (!resultList.isEmpty()) {
+            final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id);
+            final Facet pdf = new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id);
+
+            facets.add(csv);
+            facets.add(pdf);
+        }
+
+        final Calculation report = res.getReport();
+
+        if (report.hasProblems())
+            facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
+
+        return res;
+    }
+
+    private CalculationResult doCompute(final UINFOArtifact sinfo, final CallContext context, final Object old) {
+        if (old instanceof CalculationResult)
+            return (CalculationResult) old;
+
+        return new SalixLineCalculation(context).calculate(sinfo);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCalculation.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,75 @@
+/** 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.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.access.RiverAccess;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
+import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
+import org.dive4elements.river.model.River;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+final class VegetationZonesCalculation {
+
+    private CallContext context;
+
+    public VegetationZonesCalculation(CallContext context) {
+        this.context = context;
+    }
+
+    public CalculationResult calculate(UINFOArtifact uinfo) {
+        final Calculation problems = new Calculation();
+
+        final String calcModeLabel = Resources.getMsg(this.context.getMeta(), uinfo.getCalculationMode().name());
+        final String user = CalculationUtils.findArtifactUser(this.context, uinfo);
+
+        final RiverAccess access = new RiverAccess(uinfo);
+        final River river = access.getRiver();
+        DoubleRange calcRange = null;
+        final RiverInfo riverInfo = new RiverInfo(river);
+        
+        final VegetationZonesCalculationResults results = new VegetationZonesCalculationResults(calcModeLabel, user, riverInfo, calcRange);
+
+        final Collection<ResultRow> rows = new ArrayList<ResultRow>();
+        
+        final ResultRow row1 = ResultRow.create(). // 
+                putValue(SInfoResultType.discharge, 100). //
+        putValue(SInfoResultType.waterlevel, 2). //
+        putValue(SInfoResultType.gaugeLabel, "Torgau");
+
+        rows.add(row1);
+
+        ResultRow row2 = ResultRow.create(). // 
+                putValue(SInfoResultType.discharge, 200). //
+                putValue(SInfoResultType.waterlevel, 3). //
+                putValue(SInfoResultType.gaugeLabel, "Zollenspieker");
+
+        rows.add(row2);
+
+        final VegetationZonesCalculationResult result = new VegetationZonesCalculationResult("Ergebnis 1", null, rows);
+        
+        results.addResult(result, problems);
+        
+        return new CalculationResult(results, problems);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCalculationResult.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,29 @@
+/** 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.util.Collection;
+
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+final class VegetationZonesCalculationResult extends AbstractCalculationResult {
+
+    private static final long serialVersionUID = 1L;
+
+    public VegetationZonesCalculationResult(final String label, final WstInfo wst, final Collection< ResultRow> rows) {
+        super(label,  rows);
+    }
+    
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCalculationResults.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,27 @@
+/** 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 org.apache.commons.lang.math.DoubleRange;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResults;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+final class VegetationZonesCalculationResults extends AbstractCalculationResults<VegetationZonesCalculationResult> {
+
+    private static final long serialVersionUID = 1L;
+
+    public VegetationZonesCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) {
+        super(calcModeLabel, user, river, calcRange);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesExporter.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,112 @@
+/** 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.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.river.artifacts.common.GeneralResultType;
+import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
+import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+import org.dive4elements.river.artifacts.uinfo.commons.AbstractUInfoExporter;
+
+import au.com.bytecode.opencsv.CSVWriter;
+
+/**
+ * @author Domenico Nardi Tironi
+ *
+ */
+public class VegetationZonesExporter extends AbstractUInfoExporter<VegetationZonesCalculationResult, VegetationZonesCalculationResults> {
+
+    /** The log used in this exporter. */
+    private static Logger log = Logger.getLogger(VegetationZonesExporter.class);
+
+    private static final String JASPER_FILE = "/jasper/uinfo.vegetationzones.jasper";
+
+    @Override
+    protected Logger getLog() {
+        return log;
+    }
+
+    @Override
+    protected void writeCSVGlobalMetadata(final CSVWriter writer, final VegetationZonesCalculationResults results) {
+        log.info("SalixLineExporter.writeCSVMeta");
+        super.writeCSVGlobalMetadataDefaults(writer, results);
+    }
+
+    /**
+     * Write the header, with different headings depending on whether at a
+     * gauge or at a location.
+     *
+     * @param river
+     * @param useTkh
+     */
+    @Override
+    protected void writeCSVHeader(final CSVWriter writer, final VegetationZonesCalculationResults results, final RiverInfo river) {
+        log.info("FlowDepthExporter.writeCSVHeader");
+
+        final Collection<String> header = new ArrayList<>(11);
+
+        header.add(msg(GeneralResultType.station.getCsvHeader()));
+        header.add(msgUnit(SInfoResultType.flowdepth.getCsvHeader(), SInfoResultType.flowdepth.getUnit()));
+
+        header.add(msgUnit(SInfoResultType.waterlevel.getCsvHeader(), river.getWstUnit()));
+        header.add(msgUnit(SInfoResultType.discharge.getCsvHeader(), SInfoResultType.discharge.getUnit()));
+        header.add(msg(SInfoResultType.waterlevelLabel.getCsvHeader()));
+        header.add(msg(SInfoResultType.gaugeLabel.getCsvHeader()));
+        header.add(msgUnit(SInfoResultType.meanBedHeight.getCsvHeader(), river.getWstUnit()));
+        header.add(msg(SInfoResultType.soundingLabel.getCsvHeader()));
+        header.add(msg(SInfoResultType.location.getCsvHeader()));
+
+        writer.writeNext(header.toArray(new String[header.size()]));
+    }
+
+    /**
+     * Format a row of a flow depth result into an array of string, both used by csv and pdf
+     *
+     * @param pdf
+     *
+     * @param useTkh
+     */
+    @Override
+    protected String[] formatRow(final VegetationZonesCalculationResults results, final ResultRow row, final ExportMode mode) {
+
+        final Collection<String> lines = new ArrayList<>(11);
+
+        lines.add(row.exportValue(this.context, GeneralResultType.station));
+        lines.add(row.exportValue(this.context, SInfoResultType.flowdepth));
+
+        lines.add(row.exportValue(this.context, SInfoResultType.waterlevel));
+        lines.add(row.exportValue(this.context, SInfoResultType.discharge));
+        lines.add(row.exportValue(this.context, SInfoResultType.waterlevelLabel));
+        lines.add(row.exportValue(this.context, SInfoResultType.gaugeLabel));
+        lines.add(row.exportValue(this.context, SInfoResultType.meanBedHeight));
+        lines.add(row.exportValue(this.context, SInfoResultType.soundingLabel));
+        lines.add(row.exportValue(this.context, SInfoResultType.location));
+
+        return lines.toArray(new String[lines.size()]);
+    }
+
+    @Override
+    protected String getJasperFile() {
+        // TODO Auto-generated method stub
+        return JASPER_FILE;
+    }
+
+    @Override
+    protected void writeCSVResultMetadata(final CSVWriter writer, final VegetationZonesCalculationResults results,
+            final VegetationZonesCalculationResult result) {
+        // TODO Auto-generated method stub
+
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesState.java	Thu Apr 12 19:13:39 2018 +0200
@@ -0,0 +1,104 @@
+/** 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.util.List;
+
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.ChartArtifact;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.model.EmptyFacet;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.artifacts.model.ReportFacet;
+import org.dive4elements.river.artifacts.states.DefaultState;
+import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
+
+/**
+ * @author Domenico Nardi Tironi
+ */
+public class VegetationZonesState extends DefaultState {
+
+    /// ** The log that is used in this state. */
+    // private static Logger log = Logger.getLogger(FlowDepthState.class);
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * From this state can only be continued trivially.
+     */
+    @Override
+    protected String getUIProvider() {
+        return "continue";
+    }
+
+    @Override
+    public Object computeFeed(final D4EArtifact artifact, final String hash, final CallContext context, final List<Facet> facets, final Object old) {
+        // FIXME: why is this necessary?
+        if (artifact instanceof ChartArtifact) {
+            facets.add(new EmptyFacet());
+            return null;
+        }
+
+        return compute((UINFOArtifact) artifact, context, hash, facets, old);
+    }
+
+    @Override
+    public Object computeAdvance(final D4EArtifact artifact, final String hash, final CallContext context, final List<Facet> facets, final Object old) {
+        if (artifact instanceof ChartArtifact) {
+            facets.add(new EmptyFacet());
+            return null;
+        }
+        return compute((UINFOArtifact) artifact, context, hash, facets, old);
+    }
+
+    /**
+     * Compute result or returned object from cache, create facets.
+     *
+     * @param old
+     *            Object that was cached.
+     */
+    private Object compute(final UINFOArtifact sinfo, final CallContext context, final String hash, final List<Facet> facets, final Object old) {
+
+        final CalculationResult res = doCompute(sinfo, context, old);
+
+        if (facets == null)
+            return res;
+
+        final VegetationZonesCalculationResults results = (VegetationZonesCalculationResults) res.getData();
+
+        List<VegetationZonesCalculationResult> resultList = results.getResults();
+
+        if (!resultList.isEmpty()) {
+            final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id);
+            final Facet pdf = new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id);
+
+            facets.add(csv);
+            facets.add(pdf);
+        }
+
+        final Calculation report = res.getReport();
+
+        if (report.hasProblems())
+            facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
+
+        return res;
+    }
+
+    private CalculationResult doCompute(final UINFOArtifact sinfo, final CallContext context, final Object old) {
+        if (old instanceof CalculationResult)
+            return (CalculationResult) old;
+
+        return new VegetationZonesCalculation(context).calculate(sinfo);
+    }
+}
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java	Thu Apr 12 19:11:11 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java	Thu Apr 12 19:13:39 2018 +0200
@@ -18,7 +18,6 @@
 import org.dive4elements.artifacts.CallMeta;
 import org.dive4elements.river.artifacts.resources.Resources;
 
-
 /** Helper to access static i18n Formatters. */
 public final class Formatter {
 
@@ -29,18 +28,16 @@
     // WATERLEVEL FORMATTER CONSTANTS
     public static final int WATERLEVEL_KM_MIN_DIGITS = 3;
     public static final int WATERLEVEL_KM_MAX_DIGITS = 3;
-    public static final int WATERLEVEL_W_MIN_DIGITS  = 0;
-    public static final int WATERLEVEL_W_MAX_DIGITS  = 2;
-    public static final int WATERLEVEL_Q_MIN_DIGITS  = 0;
-    public static final int WATERLEVEL_Q_MAX_DIGITS  = 2;
-
+    public static final int WATERLEVEL_W_MIN_DIGITS = 0;
+    public static final int WATERLEVEL_W_MAX_DIGITS = 2;
+    public static final int WATERLEVEL_Q_MIN_DIGITS = 0;
+    public static final int WATERLEVEL_Q_MAX_DIGITS = 2;
 
     // COMPUTED DISCHARGE CURVE FORMATTER CONSTANTS
-    public static final int COMPUTED_DISCHARGE_W_MIN_DIGITS  = 2;
-    public static final int COMPUTED_DISCHARGE_W_MAX_DIGITS  = 2;
-    public static final int COMPUTED_DISCHARGE_Q_MIN_DIGITS  = 0;
-    public static final int COMPUTED_DISCHARGE_Q_MAX_DIGITS  = 2;
-
+    public static final int COMPUTED_DISCHARGE_W_MIN_DIGITS = 2;
+    public static final int COMPUTED_DISCHARGE_W_MAX_DIGITS = 2;
+    public static final int COMPUTED_DISCHARGE_Q_MIN_DIGITS = 0;
+    public static final int COMPUTED_DISCHARGE_Q_MAX_DIGITS = 2;
 
     // HISTORICAL DISCHARGE CURVE FORMATTER CONSTANTS
     public static final int HISTORICAL_DISCHARGE_W_MIN_DIGITS = 0;
@@ -48,7 +45,6 @@
     public static final int HISTORICAL_DISCHARGE_Q_MIN_DIGITS = 0;
     public static final int HISTORICAL_DISCHARGE_Q_MAX_DIGITS = 2;
 
-
     // DURATION CURVE FORMATTER CONSTANTS
     public static final int DURATION_W_MIN_DIGITS = 0;
     public static final int DURATION_W_MAX_DIGITS = 2;
@@ -57,36 +53,34 @@
     public static final int DURATION_D_MIN_DIGITS = 0;
     public static final int DURATION_D_MAX_DIGITS = 0;
 
-
     // FLOW VELOCITY FORMATTER CONSTANTS
-    public static final int FLOW_VELOCITY_KM_MIN_DIGITS     = 3;
-    public static final int FLOW_VELOCITY_KM_MAX_DIGITS     = 3;
+    public static final int FLOW_VELOCITY_KM_MIN_DIGITS = 3;
+    public static final int FLOW_VELOCITY_KM_MAX_DIGITS = 3;
     public static final int FLOW_VELOCITY_VALUES_MIN_DIGITS = 2;
     public static final int FLOW_VELOCITY_VALUES_MAX_DIGITS = 2;
-    public static final int FLOW_VELOCITY_Q_MIN_DIGITS      = 0;
-    public static final int FLOW_VELOCITY_Q_MAX_DIGITS      = 2;
-
+    public static final int FLOW_VELOCITY_Q_MIN_DIGITS = 0;
+    public static final int FLOW_VELOCITY_Q_MAX_DIGITS = 2;
 
     // MIDDLE BED HEIGHT FORMATTER CONSTANTS
-    public static final int MIDDLE_BED_HEIGHT_KM_MIN_DIGITS             = 3;
-    public static final int MIDDLE_BED_HEIGHT_KM_MAX_DIGITS             = 3;
-    public static final int MIDDLE_BED_HEIGHT_HEIGHT_MIN_DIGITS         = 3;
-    public static final int MIDDLE_BED_HEIGHT_HEIGHT_MAX_DIGITS         = 3;
-    public static final int MIDDLE_BED_HEIGHT_UNCERT_MIN_DIGITS         = 3;
-    public static final int MIDDLE_BED_HEIGHT_UNCERT_MAX_DIGITS         = 3;
-    public static final int MIDDLE_BED_HEIGHT_DATAGAP_MIN_DIGITS        = 2;
-    public static final int MIDDLE_BED_HEIGHT_DATAGAP_MAX_DIGITS        = 2;
+    public static final int MIDDLE_BED_HEIGHT_KM_MIN_DIGITS = 3;
+    public static final int MIDDLE_BED_HEIGHT_KM_MAX_DIGITS = 3;
+    public static final int MIDDLE_BED_HEIGHT_HEIGHT_MIN_DIGITS = 3;
+    public static final int MIDDLE_BED_HEIGHT_HEIGHT_MAX_DIGITS = 3;
+    public static final int MIDDLE_BED_HEIGHT_UNCERT_MIN_DIGITS = 3;
+    public static final int MIDDLE_BED_HEIGHT_UNCERT_MAX_DIGITS = 3;
+    public static final int MIDDLE_BED_HEIGHT_DATAGAP_MIN_DIGITS = 2;
+    public static final int MIDDLE_BED_HEIGHT_DATAGAP_MAX_DIGITS = 2;
     public static final int MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MIN_DIGITS = 0;
     public static final int MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MAX_DIGITS = 0;
-    public static final int MIDDLE_BED_HEIGHT_WIDTH_MIN_DIGITS          = 3;
-    public static final int MIDDLE_BED_HEIGHT_WIDTH_MAX_DIGITS          = 3;
+    public static final int MIDDLE_BED_HEIGHT_WIDTH_MIN_DIGITS = 3;
+    public static final int MIDDLE_BED_HEIGHT_WIDTH_MAX_DIGITS = 3;
 
     public static final int FIX_DELTA_W_KM_MIN_DIGITS = 3;
     public static final int FIX_DELTA_W_KM_MAX_DIGITS = 3;
     public static final int FIX_DELTA_W_DELTA_W_MIN_DIGITS = 3;
     public static final int FIX_DELTA_W_DELTA_W_MAX_DIGITS = 3;
-    public static final int FIX_DELTA_W_DELTA_Q_MIN_DIGITS  = 0;
-    public static final int FIX_DELTA_W_DELTA_Q_MAX_DIGITS  = 2;
+    public static final int FIX_DELTA_W_DELTA_Q_MIN_DIGITS = 0;
+    public static final int FIX_DELTA_W_DELTA_Q_MAX_DIGITS = 2;
 
     public static final int VARIANCE_MIN_DIGITS = 3;
     public static final int VARIANCE_MAX_DIGITS = 3;
@@ -94,26 +88,30 @@
     // SQ Relation
     public static final int SQ_RELATION_KM_MIN_DIGITS = 2;
     public static final int SQ_RELATION_KM_MAX_DIGITS = 2;
-    public static final int SQ_RELATION_A_MAX_DIGITS  = 2;
-    public static final int SQ_RELATION_A_MIN_DIGITS  = 2;
-    public static final int SQ_RELATION_B_MAX_DIGITS  = 3;
-    public static final int SQ_RELATION_B_MIN_DIGITS  = 3;
+    public static final int SQ_RELATION_A_MAX_DIGITS = 2;
+    public static final int SQ_RELATION_A_MIN_DIGITS = 2;
+    public static final int SQ_RELATION_B_MAX_DIGITS = 3;
+    public static final int SQ_RELATION_B_MIN_DIGITS = 3;
 
     // OTHER
-    public static final int CSV_DIAGRAM_DATA_MAX_DIGITS  = 3;
-    public static final int CSV_DIAGRAM_DATA_MIN_DIGITS  = 3;
+    public static final int CSV_DIAGRAM_DATA_MAX_DIGITS = 3;
+    public static final int CSV_DIAGRAM_DATA_MIN_DIGITS = 3;
 
     /**
      * Creates a localized NumberFormatter with given range of decimal digits.
-     * @param m CallMeta to find the locale.
-     * @param min minimum number of decimal ("fraction") digits.
-     * @param max maximum number of decimal ("fraction") digits.
+     * 
+     * @param m
+     *            CallMeta to find the locale.
+     * @param min
+     *            minimum number of decimal ("fraction") digits.
+     * @param max
+     *            maximum number of decimal ("fraction") digits.
      * @return A NumberFormat. Use #format(NUMBER) to get String representation
      *         of NUMBER.
      */
-    public static NumberFormat getFormatter(final CallMeta m, final int min, final int max){
-        final Locale       locale = Resources.getLocale(m);
-        final NumberFormat nf     = NumberFormat.getInstance(locale);
+    public static NumberFormat getFormatter(final CallMeta m, final int min, final int max) {
+        final Locale locale = Resources.getLocale(m);
+        final NumberFormat nf = NumberFormat.getInstance(locale);
 
         nf.setMaximumFractionDigits(max);
         nf.setMinimumFractionDigits(min);
@@ -121,15 +119,15 @@
         return nf;
     }
 
-    public static NumberFormat getFormatter(final CallContext c, final int min, final int max){
+    public static NumberFormat getFormatter(final CallContext c, final int min, final int max) {
         return getFormatter(c.getMeta(), min, max);
     }
 
-
     /**
      * Returns a number formatter with no max or min digits set.
      *
-     * @param c The CallContext.
+     * @param c
+     *            The CallContext.
      *
      * @return a number formatter.
      */
@@ -144,7 +142,7 @@
     public static NumberFormat getEngFormatter(final CallContext c) {
         final NumberFormat nf = getRawFormatter(c);
         if (nf instanceof DecimalFormat) {
-            final DecimalFormat df = (DecimalFormat)nf;
+            final DecimalFormat df = (DecimalFormat) nf;
             df.applyPattern("##0.#####E0");
         }
         return nf;
@@ -153,14 +151,10 @@
     /**
      * Returns a number formatter that uses an exponent after max digits.
      */
-    public static NumberFormat getScientificFormater(
-            final CallContext c,
-            final int min,
-            final int max
-            ) {
+    public static NumberFormat getScientificFormater(final CallContext c, final int min, final int max) {
         final NumberFormat nf = getRawFormatter(c);
         if (nf instanceof DecimalFormat) {
-            final DecimalFormat df = (DecimalFormat)nf;
+            final DecimalFormat df = (DecimalFormat) nf;
             df.applyPattern("0.0E0");
             df.setMaximumFractionDigits(max);
             df.setMinimumFractionDigits(min);
@@ -168,7 +162,6 @@
         return nf;
     }
 
-
     /**
      * Returns a date formatter with SHORT style.
      */
@@ -177,7 +170,6 @@
         return DateFormat.getDateInstance(DateFormat.SHORT, locale);
     }
 
-
     /**
      * Returns a date formatter with MEDIUM style.
      */
@@ -186,17 +178,13 @@
         return DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
     }
 
-
     /**
      * Returns the number formatter for kilometer values in waterlevel exports.
      *
      * @return the number formatter for kilometer values.
      */
     public static NumberFormat getWaterlevelKM(final CallContext context) {
-        return getFormatter(
-                context,
-                WATERLEVEL_KM_MIN_DIGITS,
-                WATERLEVEL_KM_MAX_DIGITS);
+        return getFormatter(context, WATERLEVEL_KM_MIN_DIGITS, WATERLEVEL_KM_MAX_DIGITS);
     }
 
     /**
@@ -206,51 +194,33 @@
      * @return the number formatter for csv data from diagra.
      */
     public static NumberFormat getCSVFormatter(final CallContext context) {
-        return getFormatter(
-                context,
-                CSV_DIAGRAM_DATA_MIN_DIGITS,
-                CSV_DIAGRAM_DATA_MAX_DIGITS);
+        return getFormatter(context, CSV_DIAGRAM_DATA_MIN_DIGITS, CSV_DIAGRAM_DATA_MAX_DIGITS);
     }
 
     public static NumberFormat getWaterlevelW(final CallMeta meta) {
-        return getFormatter(
-                meta,
-                WATERLEVEL_W_MIN_DIGITS,
-                WATERLEVEL_W_MAX_DIGITS);
+        return getFormatter(meta, WATERLEVEL_W_MIN_DIGITS, WATERLEVEL_W_MAX_DIGITS);
     }
 
-
     /**
      * Returns the number formatter for W values in waterlevel exports.
      *
      * @return the number formatter for W values.
      */
     public static NumberFormat getWaterlevelW(final CallContext context) {
-        return getFormatter(
-                context,
-                WATERLEVEL_W_MIN_DIGITS,
-                WATERLEVEL_W_MAX_DIGITS);
+        return getFormatter(context, WATERLEVEL_W_MIN_DIGITS, WATERLEVEL_W_MAX_DIGITS);
     }
 
-
     /**
      * Returns the number formatter for Q values in waterlevel exports.
      *
      * @return the number formatter for Q values.
      */
     public static NumberFormat getWaterlevelQ(final CallContext context) {
-        return getFormatter(
-                context,
-                WATERLEVEL_Q_MIN_DIGITS,
-                WATERLEVEL_Q_MAX_DIGITS);
+        return getFormatter(context, WATERLEVEL_Q_MIN_DIGITS, WATERLEVEL_Q_MAX_DIGITS);
     }
 
-
     public static NumberFormat getWaterlevelQ(final CallMeta meta) {
-        return getFormatter(
-                meta,
-                WATERLEVEL_Q_MIN_DIGITS,
-                WATERLEVEL_Q_MAX_DIGITS);
+        return getFormatter(meta, WATERLEVEL_Q_MIN_DIGITS, WATERLEVEL_Q_MAX_DIGITS);
     }
 
     /**
@@ -260,13 +230,9 @@
      * @return the number formatter for W values.
      */
     public static NumberFormat getComputedDischargeW(final CallContext context) {
-        return getFormatter(
-                context,
-                COMPUTED_DISCHARGE_W_MIN_DIGITS,
-                COMPUTED_DISCHARGE_W_MAX_DIGITS);
+        return getFormatter(context, COMPUTED_DISCHARGE_W_MIN_DIGITS, COMPUTED_DISCHARGE_W_MAX_DIGITS);
     }
 
-
     /**
      * Returns the number formatter for Q values in exports of computed
      * discharge curves.
@@ -274,13 +240,9 @@
      * @return the number formatter for Q values.
      */
     public static NumberFormat getComputedDischargeQ(final CallContext context) {
-        return getFormatter(
-                context,
-                COMPUTED_DISCHARGE_Q_MIN_DIGITS,
-                COMPUTED_DISCHARGE_Q_MAX_DIGITS);
+        return getFormatter(context, COMPUTED_DISCHARGE_Q_MIN_DIGITS, COMPUTED_DISCHARGE_Q_MAX_DIGITS);
     }
 
-
     /**
      * Returns the number formatter for W values in exports of historical
      * discharge curves.
@@ -288,13 +250,9 @@
      * @return the number formatter for W values.
      */
     public static NumberFormat getHistoricalDischargeW(final CallContext context) {
-        return getFormatter(
-                context,
-                HISTORICAL_DISCHARGE_W_MIN_DIGITS,
-                HISTORICAL_DISCHARGE_W_MAX_DIGITS);
+        return getFormatter(context, HISTORICAL_DISCHARGE_W_MIN_DIGITS, HISTORICAL_DISCHARGE_W_MAX_DIGITS);
     }
 
-
     /**
      * Returns the number formatter for Q values in exports of historical
      * discharge curves.
@@ -302,186 +260,106 @@
      * @return the number formatter for Q values.
      */
     public static NumberFormat getHistoricalDischargeQ(final CallContext context) {
-        return getFormatter(
-                context,
-                HISTORICAL_DISCHARGE_Q_MIN_DIGITS,
-                HISTORICAL_DISCHARGE_Q_MAX_DIGITS);
+        return getFormatter(context, HISTORICAL_DISCHARGE_Q_MIN_DIGITS, HISTORICAL_DISCHARGE_Q_MAX_DIGITS);
     }
 
-
     /**
      * Returns the number formatter for W values in duration curve exports.
      *
      * @return the number formatter for W values.
      */
     public static NumberFormat getDurationW(final CallContext context) {
-        return getFormatter(
-                context,
-                DURATION_W_MIN_DIGITS,
-                DURATION_W_MAX_DIGITS);
+        return getFormatter(context, DURATION_W_MIN_DIGITS, DURATION_W_MAX_DIGITS);
     }
 
-
     /**
      * Returns the number formatter for Q values in duration curve exports.
      *
      * @return the number formatter for W values.
      */
     public static NumberFormat getDurationQ(final CallContext context) {
-        return getFormatter(
-                context,
-                DURATION_Q_MIN_DIGITS,
-                DURATION_Q_MAX_DIGITS);
+        return getFormatter(context, DURATION_Q_MIN_DIGITS, DURATION_Q_MAX_DIGITS);
     }
 
-
     /**
      * Returns the number formatter for D values in duration curve exports.
      *
      * @return the number formatter for W values.
      */
     public static NumberFormat getDurationD(final CallContext context) {
-        return getFormatter(
-                context,
-                DURATION_D_MIN_DIGITS,
-                DURATION_D_MAX_DIGITS);
+        return getFormatter(context, DURATION_D_MIN_DIGITS, DURATION_D_MAX_DIGITS);
     }
 
     public static NumberFormat getCalculationKm(final CallMeta meta) {
-        return getFormatter(
-                meta,
-                CALCULATION_REPORT_KM_MIN_DIGITS,
-                CALCULATION_REPORT_KM_MAX_DIGITS);
-    }
-
-
-    public static NumberFormat getFlowVelocityKM(final CallContext context) {
-        return getFormatter(
-                context,
-                FLOW_VELOCITY_KM_MIN_DIGITS,
-                FLOW_VELOCITY_KM_MAX_DIGITS);
-    }
-
-
-    public static NumberFormat getFlowVelocityValues(final CallContext context) {
-        return getFormatter(
-                context,
-                FLOW_VELOCITY_VALUES_MIN_DIGITS,
-                FLOW_VELOCITY_VALUES_MAX_DIGITS);
-    }
-
-
-    public static NumberFormat getFlowVelocityQ(final CallContext context) {
-        return getFormatter(
-                context,
-                FLOW_VELOCITY_Q_MIN_DIGITS,
-                FLOW_VELOCITY_Q_MAX_DIGITS);
-    }
-
-
-    public static NumberFormat getMiddleBedHeightKM(final CallContext context) {
-        return getFormatter(
-                context,
-                MIDDLE_BED_HEIGHT_KM_MIN_DIGITS,
-                MIDDLE_BED_HEIGHT_KM_MAX_DIGITS);
+        return getFormatter(meta, CALCULATION_REPORT_KM_MIN_DIGITS, CALCULATION_REPORT_KM_MAX_DIGITS);
     }
 
-
-    public static NumberFormat getMiddleBedHeightHeight(final CallContext context) {
-        return getFormatter(
-                context,
-                MIDDLE_BED_HEIGHT_HEIGHT_MIN_DIGITS,
-                MIDDLE_BED_HEIGHT_HEIGHT_MAX_DIGITS);
+    public static NumberFormat getFlowVelocityKM(final CallContext context) {
+        return getFormatter(context, FLOW_VELOCITY_KM_MIN_DIGITS, FLOW_VELOCITY_KM_MAX_DIGITS);
     }
 
+    public static NumberFormat getFlowVelocityValues(final CallContext context) {
+        return getFormatter(context, FLOW_VELOCITY_VALUES_MIN_DIGITS, FLOW_VELOCITY_VALUES_MAX_DIGITS);
+    }
+
+    public static NumberFormat getFlowVelocityQ(final CallContext context) {
+        return getFormatter(context, FLOW_VELOCITY_Q_MIN_DIGITS, FLOW_VELOCITY_Q_MAX_DIGITS);
+    }
+
+    public static NumberFormat getMiddleBedHeightKM(final CallContext context) {
+        return getFormatter(context, MIDDLE_BED_HEIGHT_KM_MIN_DIGITS, MIDDLE_BED_HEIGHT_KM_MAX_DIGITS);
+    }
+
+    public static NumberFormat getMiddleBedHeightHeight(final CallContext context) {
+        return getFormatter(context, MIDDLE_BED_HEIGHT_HEIGHT_MIN_DIGITS, MIDDLE_BED_HEIGHT_HEIGHT_MAX_DIGITS);
+    }
 
     public static NumberFormat getMiddleBedHeightUncert(final CallContext context) {
-        return getFormatter(
-                context,
-                MIDDLE_BED_HEIGHT_UNCERT_MIN_DIGITS,
-                MIDDLE_BED_HEIGHT_UNCERT_MAX_DIGITS);
+        return getFormatter(context, MIDDLE_BED_HEIGHT_UNCERT_MIN_DIGITS, MIDDLE_BED_HEIGHT_UNCERT_MAX_DIGITS);
     }
 
-
     public static NumberFormat getMiddleBedHeightDataGap(final CallContext context) {
-        return getFormatter(
-                context,
-                MIDDLE_BED_HEIGHT_DATAGAP_MIN_DIGITS,
-                MIDDLE_BED_HEIGHT_DATAGAP_MAX_DIGITS);
+        return getFormatter(context, MIDDLE_BED_HEIGHT_DATAGAP_MIN_DIGITS, MIDDLE_BED_HEIGHT_DATAGAP_MAX_DIGITS);
     }
 
-
-    public static NumberFormat getMiddleBedHeightSounding(
-            final CallContext context
-            ) {
-        return getFormatter(
-                context,
-                MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MIN_DIGITS,
-                MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MAX_DIGITS);
+    public static NumberFormat getMiddleBedHeightSounding(final CallContext context) {
+        return getFormatter(context, MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MIN_DIGITS, MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MAX_DIGITS);
     }
 
-
     public static NumberFormat getFixDeltaWKM(final CallContext context) {
-        return getFormatter(
-                context,
-                FIX_DELTA_W_KM_MIN_DIGITS,
-                FIX_DELTA_W_KM_MAX_DIGITS);
+        return getFormatter(context, FIX_DELTA_W_KM_MIN_DIGITS, FIX_DELTA_W_KM_MAX_DIGITS);
     }
 
     public static NumberFormat getFixDeltaWDeltaW(final CallContext context) {
-        return getFormatter(
-                context,
-                FIX_DELTA_W_DELTA_W_MIN_DIGITS,
-                FIX_DELTA_W_DELTA_W_MAX_DIGITS);
+        return getFormatter(context, FIX_DELTA_W_DELTA_W_MIN_DIGITS, FIX_DELTA_W_DELTA_W_MAX_DIGITS);
     }
 
     public static NumberFormat getFixDeltaWQ(final CallContext context) {
-        return getFormatter(
-                context,
-                FIX_DELTA_W_DELTA_Q_MIN_DIGITS,
-                FIX_DELTA_W_DELTA_Q_MAX_DIGITS);
+        return getFormatter(context, FIX_DELTA_W_DELTA_Q_MIN_DIGITS, FIX_DELTA_W_DELTA_Q_MAX_DIGITS);
     }
 
     public static NumberFormat getFixDeltaWW(final CallContext context) {
-        return getFormatter(
-                context,
-                FIX_DELTA_W_DELTA_W_MIN_DIGITS,
-                FIX_DELTA_W_DELTA_W_MAX_DIGITS);
+        return getFormatter(context, FIX_DELTA_W_DELTA_W_MIN_DIGITS, FIX_DELTA_W_DELTA_W_MAX_DIGITS);
     }
 
     public static NumberFormat getVariance(final CallContext context) {
-        return getFormatter(
-                context,
-                VARIANCE_MIN_DIGITS,
-                VARIANCE_MAX_DIGITS);
+        return getFormatter(context, VARIANCE_MIN_DIGITS, VARIANCE_MAX_DIGITS);
     }
 
     public static NumberFormat getSQRelationA(final CallContext context) {
-        return getScientificFormater(
-                context,
-                SQ_RELATION_A_MIN_DIGITS,
-                SQ_RELATION_A_MAX_DIGITS);
+        return getScientificFormater(context, SQ_RELATION_A_MIN_DIGITS, SQ_RELATION_A_MAX_DIGITS);
     }
 
     public static NumberFormat getSQRelationB(final CallContext context) {
-        return getFormatter(
-                context,
-                SQ_RELATION_B_MIN_DIGITS,
-                SQ_RELATION_B_MAX_DIGITS);
+        return getFormatter(context, SQ_RELATION_B_MIN_DIGITS, SQ_RELATION_B_MAX_DIGITS);
     }
 
     public static NumberFormat getSQRelationKM(final CallContext context) {
-        return getFormatter(
-                context,
-                SQ_RELATION_KM_MIN_DIGITS,
-                SQ_RELATION_KM_MAX_DIGITS);
+        return getFormatter(context, SQ_RELATION_KM_MIN_DIGITS, SQ_RELATION_KM_MAX_DIGITS);
     }
 
     public static NumberFormat getMeterFormat(final CallContext context) {
-        return getFormatter(
-                context,
-                0,
-                2);
+        return getFormatter(context, 0, 2);
 
     }
 
@@ -510,10 +388,14 @@
      * Another waterlevel formatter with fixed digits (always 2)
      */
     public static NumberFormat getWaterlevelW2(final CallMeta meta) {
-        return getFormatter( meta, 2, 2);
+        return getFormatter(meta, 2, 2);
     }
 
     public static NumberFormat getFlowDepthDevelopmentPerYear(final CallContext context) {
         return getFormatter(context.getMeta(), 2, 2);
     }
+
+    public static NumberFormat getSalixLine(final CallContext context) {
+        return Formatter.getFormatter(context, 2, 2);
+    }
 }
\ No newline at end of file
--- a/artifacts/src/main/resources/messages.properties	Thu Apr 12 19:11:11 2018 +0200
+++ b/artifacts/src/main/resources/messages.properties	Thu Apr 12 19:13:39 2018 +0200
@@ -727,6 +727,7 @@
 
 module.winfo = W-INFO
 module.sinfo = S-INFO
+module.uinfo = U-INFO
 module.minfo = M-INFO
 module.fixanalysis = Fix Analysis
 module.new_map = New Map
@@ -982,4 +983,35 @@
 abstractsinfocalculationresults.emptyResult = {0}: result set is empty, please check the data ranges of the input 
 
 flowdepthdevelopmentcalculation.yearDifferenceCurrent = aktuelles Differenzenpaar
-flowdepthdevelopmentcalculation.yearDifferenceHistorical =  = historisches Differenzenpaar
\ No newline at end of file
+flowdepthdevelopmentcalculation.yearDifferenceHistorical =  = historisches Differenzenpaar
+
+uinfo_salix_line = Salix-Linie
+uinfo_inundation_duration = Überflutungsdauern Aue
+uinfo_vegetation_zones = Vegetationszonen
+
+state.uinfo.river = Gew\u00e4sser
+state.uinfo.calculation_mode=Berechnungsart
+
+uinfo.export.salix_line.csv.header.salix_line = Salix-Linie [m]
+uinfo.export.salix_line.csv.header.delta_mw =  (MW-MNW)x(-1) [m]
+uinfo.export.salix_line.csv.header.scen =  Salix-Linie [m] Szenario dMW={0} cm
+uinfo.export.salix_line.csv.header.hist =  Salix-Linie [m] historisch
+
+
+uinfo.export.salix_line.csv.meta.header.evaluator = # Auswerter: {0}
+uinfo.export.salix_line.csv.meta.header.waterlevel.year = # Jahr/Zeitraum der Wasserspiegellage: {0}
+uinfo.export.salix_line.csv.meta.header.waterlevel.gauge = # Bezugspegel: {0}
+
+
+uinfo.export.csv.meta.header.salix.regional = ##Regional wirkende Eingriffe 
+uinfo.export.csv.meta.header.salix.regionalextended = ##\u00dcberregional wirkende Eingriffe
+
+uinfo.export.csv.meta.header.salix.szenariotyp = # Szenariotyp
+uinfo.export.csv.meta.header.salix.teilabschnitt = # Teilabschnitt
+uinfo.export.csv.meta.header.salix.mwspiegellaenderung = # MittelwasserSpiegellagenänderung
+
+
+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
+ 
\ No newline at end of file
--- a/artifacts/src/main/resources/messages_de.properties	Thu Apr 12 19:11:11 2018 +0200
+++ b/artifacts/src/main/resources/messages_de.properties	Thu Apr 12 19:13:39 2018 +0200
@@ -727,6 +727,7 @@
 
 module.winfo = W-INFO
 module.sinfo = S-INFO
+module.uinfo = U-INFO
 module.minfo = M-INFO
 module.fixanalysis = Fixierungsanalyse
 module.new_map = Neue Karte
@@ -832,7 +833,7 @@
 state.sinfo.flowdepthdevlopment_historical_select = Historisches Differenzenpaar
 help.state.sinfo.flowdepthdevlopment_historical_select = ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.flowdepthdevlopment_historical_select
 
-sinfo.export.flow_depth.csv.meta.header.result = ## {0} - {1} - {2}
+sinfo.export.flow_depth.csv.meta.header.result = ##{0} - {1} - {2}
 sinfo.export.flow_depth.csv.meta.header.result.label = Ergebnisausgabe
 sinfo.export.flow_depth.csv.meta.version = # {0}: {1}
 sinfo.export.flow_depth.csv.meta.version.label = FLYS-Version
@@ -982,4 +983,35 @@
 abstractsinfocalculationresults.emptyResult = {0}: das Ergebnis enth\u00e4lt keine Daten, \u00fcberpr\u00fcfen Sie die Abdeckung der Eingangsdaten
 
 flowdepthdevelopmentcalculation.yearDifferenceCurrent = aktuelles Differenzenpaar
-flowdepthdevelopmentcalculation.yearDifferenceHistorical =  = historisches Differenzenpaar
\ No newline at end of file
+flowdepthdevelopmentcalculation.yearDifferenceHistorical =  = historisches Differenzenpaar
+
+uinfo_salix_line = Salix-Linie
+uinfo_inundation_duration = Überflutungsdauern Aue
+uinfo_vegetation_zones = Vegetationszonen
+
+state.uinfo.river = Gew\u00e4sser
+state.uinfo.calculation_mode=Berechnungsart
+
+uinfo.export.salix_line.csv.header.salix_line = Salix-Linie [m]
+uinfo.export.salix_line.csv.header.delta_mw =  (MW-MNW)x(-1) [m]
+uinfo.export.salix_line.csv.header.scen =  Salix-Linie [m] Szenario dMW={0} cm
+uinfo.export.salix_line.csv.header.hist =  Salix-Linie [m] historisch
+
+
+uinfo.export.salix_line.csv.meta.header.evaluator = # Auswerter: {0}
+uinfo.export.salix_line.csv.meta.header.waterlevel.year = # Jahr/Zeitraum der Wasserspiegellage: {0}
+uinfo.export.salix_line.csv.meta.header.waterlevel.gauge = # Bezugspegel: {0}
+
+
+uinfo.export.csv.meta.header.salix.regional = ##Regional wirkende Eingriffe 
+uinfo.export.csv.meta.header.salix.regionalextended = ##\u00dcberregional wirkende Eingriffe
+
+uinfo.export.csv.meta.header.salix.szenariotyp = # Szenariotyp
+uinfo.export.csv.meta.header.salix.teilabschnitt = # Teilabschnitt
+uinfo.export.csv.meta.header.salix.mwspiegellaenderung = # MittelwasserSpiegellagenänderung
+
+
+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
+ 
\ No newline at end of file

http://dive4elements.wald.intevation.org