[PATCH 3 of 6] Added the S-Info collision calculation and chart output

Wald Commits scm-commit at wald.intevation.org
Tue Jun 19 14:25:10 CEST 2018


# HG changeset patch
# User mschaefer
# Date 1529410772 -7200
# Node ID f9bb5d0a6ff3cb890aab35e6a940ed57f4ee436c
# Parent  568961ff709aa4603e60956565d1ffee9b1cbb33
Added the S-Info collision calculation and chart output

diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractResultType.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractResultType.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractResultType.java	Tue Jun 19 14:19:32 2018 +0200
@@ -9,7 +9,9 @@
  */
 package org.dive4elements.river.artifacts.common;
 
+import java.text.DateFormat;
 import java.text.NumberFormat;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
@@ -84,6 +86,12 @@
         return this.formatters.get(locale);
     }
 
+    protected final String exportDateValue(final CallContext context, final Date value) {
+        final Locale locale = Resources.getLocale(context.getMeta());
+        final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
+        return df.format(value);
+    }
+
     protected abstract NumberFormat createFormatter(CallContext context);
 
     @Override
@@ -95,10 +103,12 @@
         return Resources.getMsg(meta, this.csvHeader, this.csvHeader);
     }
 
+    @Override
     public final String getPdfHeader(final CallMeta meta) {
         return Resources.getMsg(meta, this.pdfHeader, this.pdfHeader);
     }
 
+    @Override
     public final String getUnit() {
         return this.unit;
     }
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/common/GeneralResultType.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/GeneralResultType.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/GeneralResultType.java	Tue Jun 19 14:19:32 2018 +0200
@@ -10,6 +10,7 @@
 package org.dive4elements.river.artifacts.common;
 
 import java.text.NumberFormat;
+import java.util.Date;
 
 import org.dive4elements.artifacts.CallContext;
 import org.dive4elements.river.utils.Formatter;
@@ -35,6 +36,18 @@
         }
     };
 
+    public static final GeneralResultType date = new GeneralResultType(I18NStrings.UNIT_NONE, I18NStrings.CSV_META_DATE) {
+        @Override
+        public String exportValue(final CallContext context, final Object value) {
+            return exportDateValue(context, (Date) value);
+        }
+
+        @Override
+        protected NumberFormat createFormatter(final CallContext context) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
     private GeneralResultType(final String unit, final String csvHeader) {
 
         super(unit, csvHeader, csvHeader);
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/common/I18NStrings.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/I18NStrings.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/I18NStrings.java	Tue Jun 19 14:19:32 2018 +0200
@@ -47,6 +47,8 @@
 
     String CSV_META_HEIGHT_UNIT_RIVER = "sinfo.export.flow_depth.csv.meta.height_unit.river"; // move to child?
 
+    String CSV_META_DATE = "sinfo.export.csv.meta.date";
+
     /// sonstiges:
 
     // Einheiten:
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionArtifact.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionArtifact.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionArtifact.java	Tue Jun 19 14:19:32 2018 +0200
@@ -36,6 +36,8 @@
  */
 public class CollisionArtifact extends AbstractStaticStateArtifact implements FacetTypes {
 
+    private static final long serialVersionUID = 1L;
+
     /** The log for this class. */
     private static Logger log = Logger.getLogger(CollisionArtifact.class);
 
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcDetailResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcDetailResult.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcDetailResult.java	Tue Jun 19 14:19:32 2018 +0200
@@ -17,6 +17,7 @@
 import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
 import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
 
 /**
@@ -45,18 +46,14 @@
     @Override
     public void writeCSVHeader(final ExportContextCSV exportContextCSV, final CollisionCalculationResults results, final RiverInfo river) {
 
-        // FIXME wrong columns:
-        final Collection<String> header = new ArrayList<>(99);
+        final Collection<String> header = new ArrayList<>(6);
 
         header.add(exportContextCSV.formatCsvHeader(GeneralResultType.station));
-        //
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.riverside));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.inundationduration));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.inundationdurationq));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.infrastructureHeight));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.infrastructuretype));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.gaugeLabel));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.location));
+        header.add(exportContextCSV.formatCsvHeader(GeneralResultType.date));
+        header.add(exportContextCSV.formatCsvHeader(SInfoResultType.collisionGaugeW));
+        header.add(exportContextCSV.formatCsvHeader(SInfoResultType.gaugeLabel));
+        header.add(exportContextCSV.formatCsvHeader(SInfoResultType.discharge));
+        header.add(exportContextCSV.formatCsvHeader(SInfoResultType.dischargeZone));
 
         exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
     }
@@ -68,22 +65,24 @@
 
     @Override
     protected String[] formatPDFRow(final ExportContextCSV exportContextCSV, final CollisionCalculationResults results, final ResultRow row) {
+        /*
+         * final Collection<String> lines = new ArrayList<>(6);
+         * lines.add(exportContextCSV.formatRowValue(row, GeneralResultType.station));
+         * return lines.toArray(new String[lines.size()]);
+         */
         return formatRow(exportContextCSV, results, row);
     }
 
     private String[] formatRow(final ExportContextCSV exportContextCSV, final CollisionCalculationResults results, final ResultRow row) {
 
-        final Collection<String> lines = new ArrayList<>(11);
+        final Collection<String> lines = new ArrayList<>(6);
 
-        // FIXME wrong columns:
         lines.add(exportContextCSV.formatRowValue(row, GeneralResultType.station));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.tkh));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.soilkind));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.meanBedHeight));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.waterlevel));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.discharge));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.gaugeLabel));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.location));
+        lines.add(exportContextCSV.formatRowValue(row, GeneralResultType.date));
+        lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.collisionGaugeW));
+        lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.gaugeLabel));
+        lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.discharge));
+        lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.dischargeZone));
 
         return lines.toArray(new String[lines.size()]);
     }
@@ -97,13 +96,11 @@
     protected void addJRTableHeader(final ExportContextCSV exportContextCSV, final MetaAndTableJRDataSource source, final CollisionCalculationResults results) {
 
         /* column headings */
-        // FIXME wrong columns:
         exportContextCSV.addJRMetadata(source, "station_header", GeneralResultType.station);
-        // exportContext.addJRMetadata(source, "station_header", GeneralResultType.station);
-        // exportContext.addJRMetadata(source, "tkh_header", SInfoResultType.tkh);
-        // exportContext.addJRMetadata(source, "tkhkind_header", SInfoResultType.soilkind);
-        // exportContext.addJRMetadata(source, "bedheight_header", SInfoResultType.meanBedHeight);
-        // exportContext.addJRMetadata(source, "waterlevel_header", SInfoResultType.waterlevel);
-        // exportContext.addJRMetadata(source, "discharge_header", SInfoResultType.discharge);
+        exportContextCSV.addJRMetadata(source, "date_header", GeneralResultType.date);
+        exportContextCSV.addJRMetadata(source, "gaugew_header", SInfoResultType.collisionGaugeW);
+        exportContextCSV.addJRMetadata(source, "gaugelabel_header", SInfoResultType.gaugeLabel);
+        exportContextCSV.addJRMetadata(source, "discharge_header", SInfoResultType.discharge);
+        exportContextCSV.addJRMetadata(source, "dischargezone_header", SInfoResultType.dischargeZone);
     }
 }
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcFacet.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcFacet.java	Tue Jun 19 14:19:32 2018 +0200
@@ -0,0 +1,65 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.collision;
+
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.D4EArtifact;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.DataFacet;
+import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
+
+/**
+ * Facet for calculated river bed collision counts
+ *
+ * @author Matthias Schäfer
+ */
+public class CollisionCalcFacet extends DataFacet {
+
+    private static final long serialVersionUID = 1;
+
+    public CollisionCalcFacet() {
+        // required for clone operation deepCopy()
+    }
+
+    public CollisionCalcFacet(final int idx, final String name, final String description, final String yAxisLabelKey, final ComputeType type,
+            final String stateId, final String hash) {
+        super(idx, name, description, type, hash, stateId);
+        this.metaData.put("X", "sinfo.chart.km.xaxis.label");
+        this.metaData.put("Y", yAxisLabelKey);
+    }
+
+    @Override
+    public Object getData(final Artifact artifact, final CallContext context) {
+
+        final D4EArtifact flys = (D4EArtifact) artifact;
+
+        final CalculationResult res = (CalculationResult) flys.compute(context, this.hash, this.stateId, this.type, false);
+
+        final CollisionCalculationResults data = (CollisionCalculationResults) res.getData();
+
+        return data.getResults().get(this.index);
+    }
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        // FIXME: why not simply use the full constructor instead?
+        final CollisionCalcFacet copy = new CollisionCalcFacet();
+        // FIXME: why does DataFacet does not override set? Bad access to variables of parent!
+        copy.set(this);
+        copy.type = this.type;
+        copy.hash = this.hash;
+        copy.stateId = this.stateId;
+        return copy;
+    }
+}
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcOverviewResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcOverviewResult.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalcOverviewResult.java	Tue Jun 19 14:19:32 2018 +0200
@@ -17,14 +17,15 @@
 import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
 import org.dive4elements.river.artifacts.common.ResultRow;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
 
 /**
- * Contains the results of a {@link FloodDurationCalculation}.
+ * Contains the results of a {@link CollisionCalculation}.
  *
  * @author Gernot Belger
  */
-final class CollisionCalcOverviewResult extends AbstractCalculationExportableResult<CollisionCalculationResults> {
+final public class CollisionCalcOverviewResult extends AbstractCalculationExportableResult<CollisionCalculationResults> {
 
     private static final long serialVersionUID = 1L;
 
@@ -44,18 +45,11 @@
     @Override
     public void writeCSVHeader(final ExportContextCSV exportContextCSV, final CollisionCalculationResults results, final RiverInfo river) {
 
-        // FIXME wrong columns:
-        final Collection<String> header = new ArrayList<>(99);
+        final Collection<String> header = new ArrayList<>(3);
 
         header.add(exportContextCSV.formatCsvHeader(GeneralResultType.station));
-        //
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.riverside));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.inundationduration));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.inundationdurationq));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.infrastructureHeight));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.infrastructuretype));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.gaugeLabel));
-        // header.add(exportContext.formatCsvHeader(SInfoResultType.location));
+        header.add(exportContextCSV.formatCsvHeader(SInfoResultType.years));
+        header.add(exportContextCSV.formatCsvHeader(SInfoResultType.collisionCount));
 
         exportContextCSV.writeCSVLine(header.toArray(new String[header.size()]));
     }
@@ -67,22 +61,21 @@
 
     @Override
     protected String[] formatPDFRow(final ExportContextCSV exportContextCSV, final CollisionCalculationResults results, final ResultRow row) {
-        return formatRow(exportContextCSV, results, row);
+        final Collection<String> lines = new ArrayList<>(3);
+
+        lines.add(exportContextCSV.formatRowValue(row, GeneralResultType.station));
+
+        return lines.toArray(new String[lines.size()]);
+        // return formatRow(exportContextCSV, results, row);
     }
 
     private String[] formatRow(final ExportContextCSV exportContextCSV, final CollisionCalculationResults results, final ResultRow row) {
 
-        final Collection<String> lines = new ArrayList<>(11);
+        final Collection<String> lines = new ArrayList<>(3);
 
-        // FIXME wrong columns:
         lines.add(exportContextCSV.formatRowValue(row, GeneralResultType.station));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.tkh));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.soilkind));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.meanBedHeight));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.waterlevel));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.discharge));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.gaugeLabel));
-        // lines.add(exportContext.formatRowValue(row, SInfoResultType.location));
+        lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.years));
+        lines.add(exportContextCSV.formatRowValue(row, SInfoResultType.collisionCount));
 
         return lines.toArray(new String[lines.size()]);
     }
@@ -96,13 +89,8 @@
     protected void addJRTableHeader(final ExportContextCSV exportContextCSV, final MetaAndTableJRDataSource source, final CollisionCalculationResults results) {
 
         /* column headings */
-        // FIXME wrong columns:
         exportContextCSV.addJRMetadata(source, "station_header", GeneralResultType.station);
-        // exportContext.addJRMetadata(source, "station_header", GeneralResultType.station);
-        // exportContext.addJRMetadata(source, "tkh_header", SInfoResultType.tkh);
-        // exportContext.addJRMetadata(source, "tkhkind_header", SInfoResultType.soilkind);
-        // exportContext.addJRMetadata(source, "bedheight_header", SInfoResultType.meanBedHeight);
-        // exportContext.addJRMetadata(source, "waterlevel_header", SInfoResultType.waterlevel);
-        // exportContext.addJRMetadata(source, "discharge_header", SInfoResultType.discharge);
+        // exportContextCSV.addJRMetadata(source, "years_header", SInfoResultType.years);
+        // exportContextCSV.addJRMetadata(source, "collisioncount_header", SInfoResultType.collisionCount);
     }
 }
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java	Tue Jun 19 14:19:32 2018 +0200
@@ -11,6 +11,8 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.commons.lang.math.DoubleRange;
 import org.dive4elements.artifacts.CallContext;
@@ -18,12 +20,18 @@
 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.model.DateRange;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
+import org.dive4elements.river.backend.utils.DateUtil;
+import org.dive4elements.river.model.Gauge;
 import org.dive4elements.river.model.River;
+import org.dive4elements.river.model.sinfo.CollisionAggregateValue;
+import org.dive4elements.river.model.sinfo.CollisionValue;
 
 class CollisionCalculation {
 
@@ -39,46 +47,89 @@
 
         final String user = CalculationUtils.findArtifactUser(this.context, sinfo);
 
-        /* access input data */
+        // access input data
         final CollisionAccess access = new CollisionAccess(sinfo);
         final River river = access.getRiver();
         final RiverInfo riverInfo = new RiverInfo(river);
 
         final DoubleRange calcRange = access.getRange();
 
-        /* calculate results for each diff pair */
+        // calculate results for each year or epoch
         final Calculation problems = new Calculation();
 
-        final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange);
-
         final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name());
 
-        final int[] years = access.getYears();
-        final int[][] epochs = access.getEpochs();
+        final CollisionCalculationResults results = new CollisionCalculationResults(calcModeLabel, user, riverInfo, calcRange, access.getYearsHeader());
 
         final Collection<ResultRow> overViewRows = new ArrayList<>();
+
+        if (access.getYears() != null) {
+            for (final int year : access.getYears())
+                calculateOverview(overViewRows, river, access.getLowerKm(), access.getUpperKm(), year, year, false);
+        }
+        else {
+            for (final DateRange dr : access.getEpochs())
+                calculateOverview(overViewRows, river, access.getLowerKm(), access.getUpperKm(), dr.getFromYear(), dr.getToYear(), true);
+        }
+        final CollisionCalcOverviewResult overviewResult = new CollisionCalcOverviewResult(access.getYearsHeader(), overViewRows);
+        results.addResult(overviewResult, problems);
+
+        // create q-for-w-finders for all gauges of the calculation km range
+        final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange);
+        final Map<Gauge, GaugeDischargeValuesFinder> qFinders = new HashMap<>();
+        final Map<Gauge, GaugeDischargeZoneFinder> zoneFinders = new HashMap<>();
+        for (final Gauge gauge : river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble())) {
+            qFinders.put(gauge, GaugeDischargeValuesFinder.loadValues(gauge, problems));
+            zoneFinders.put(gauge, GaugeDischargeZoneFinder.loadValues(gauge, problems));
+        }
         final Collection<ResultRow> detailsRows = new ArrayList<>();
 
-        // TODO: calculate
-
-        final CollisionCalculationResults results = new CollisionCalculationResults(calcModeLabel, user, riverInfo, calcRange);
-
-        final ResultRow row = ResultRow.create().putValue(GeneralResultType.station, 8888.888);
-        final ResultRow row2 = ResultRow.create().putValue(GeneralResultType.station, 777.888);
-
-        for (int i = 0; i < 300; i++) {
-            overViewRows.add(row);
-            overViewRows.add(row2);
+        // calculate secondary results for each year or epoch
+        if (access.getYears() != null) {
+            for (final int year : access.getYears())
+                calculateDetails(detailsRows, infoProvider, access.getLowerKm(), access.getUpperKm(), year, year, qFinders, zoneFinders);
         }
-        final CollisionCalcOverviewResult overviewResult = new CollisionCalcOverviewResult("Overview", overViewRows); // TODO: get Title-Strings from messages
-        results.addResult(overviewResult, problems);
-        for (int i = 0; i < 200; i++) {
-            detailsRows.add(row);
-            detailsRows.add(row2);
+        else {
+            for (final DateRange dr : access.getEpochs())
+                calculateDetails(detailsRows, infoProvider, access.getLowerKm(), access.getUpperKm(), dr.getFromYear(), dr.getToYear(), qFinders, zoneFinders);
         }
         final CollisionCalcDetailResult detailResult = new CollisionCalcDetailResult("Details", detailsRows);
         results.addResult(detailResult, problems);
 
         return new CalculationResult(results, problems);
     }
+
+    /**
+     * Calculates the collision counts for a km range of a river and a year or year range (epoch),
+     * and adds them to a ResultRow collection
+     */
+    private void calculateOverview(final Collection<ResultRow> rows, final River river, final double fromKm, final double toKm, final int fromYear,
+            final int toYear, final boolean isEpoch) {
+        for (final CollisionAggregateValue aggregate : CollisionAggregateValue.getValuesByKm(river, fromKm, toKm, fromYear, toYear)) {
+            rows.add(ResultRow.create().putValue(GeneralResultType.station, aggregate.getStation())
+                    .putValue(SInfoResultType.years, (isEpoch? String.format("%d-%d", fromYear, toYear) : Integer.toString(fromYear)))
+                    .putValue(SInfoResultType.collisionCount, aggregate.getCount()));
+        }
+    }
+
+    /**
+     * Calculates the collision details for a km range of a river and a year or year range (epoch),
+     * and adds them to a ResultRow collection
+     */
+    private void calculateDetails(final Collection<ResultRow> rows, final RiverInfoProvider riverInfo, final double fromKm, final double toKm,
+            final int fromYear, final int toYear, final Map<Gauge, GaugeDischargeValuesFinder> qFinders,
+            final Map<Gauge, GaugeDischargeZoneFinder> zoneFinders) {
+        for (final CollisionValue collision : CollisionValue.getValues(riverInfo.getRiver(), fromKm, toKm, DateUtil.getStartDateFromYear(fromYear),
+                DateUtil.getEndDateFromYear(toYear))) {
+            final Gauge gauge = riverInfo.getGauge(collision.getStation(), true);
+            final double q = qFinders.get(gauge).getDischarge(collision.getGaugeW());
+            final double qOut = Double.isInfinite(q) ? Double.NaN : q;
+            rows.add(ResultRow.create().putValue(GeneralResultType.station, collision.getStation())
+                    .putValue(GeneralResultType.date, collision.getEventDate())
+                    .putValue(SInfoResultType.collisionGaugeW, collision.getGaugeW())
+                    .putValue(SInfoResultType.gaugeLabel, collision.getGaugeName())
+                    .putValue(SInfoResultType.discharge, qOut)
+                    .putValue(SInfoResultType.dischargeZone, zoneFinders.get(gauge).getDischargeZone(q)));
+        }
+    }
 }
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculationResults.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculationResults.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculationResults.java	Tue Jun 19 14:19:32 2018 +0200
@@ -21,8 +21,15 @@
 
     private static final long serialVersionUID = 1L;
 
-    public CollisionCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) {
+    private final String yearsHeader;
+
+    public CollisionCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange,
+            final String yearsHeader) {
         super(calcModeLabel, user, river, calcRange);
+        this.yearsHeader = yearsHeader;
+    }
 
+    public String getYearsHeader() {
+        return this.yearsHeader;
     }
 }
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionExporter.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionExporter.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionExporter.java	Tue Jun 19 14:19:32 2018 +0200
@@ -16,6 +16,7 @@
 import org.dive4elements.river.artifacts.common.ExportContextCSV;
 import org.dive4elements.river.artifacts.common.JasperReporter;
 import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource;
+import org.dive4elements.river.artifacts.sinfo.common.SInfoI18NStrings;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
 
 import au.com.bytecode.opencsv.CSVWriter;
@@ -38,6 +39,7 @@
         /* write as csv */
         exportContextCSV.writeCSVGlobalMetadataDefaults(results); // ggf auslagern innerhalb dieser Klasse
 
+        exportContextCSV.writeCSVMetaEntry(SInfoI18NStrings.CSV_META_HEADER_YEARS, results.getYearsHeader());
         // writer.writeNext(new String[] { "" }); // break line HERE to avoid redundance
 
         final RiverInfo river = results.getRiver();
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionState.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionState.java	Tue Jun 19 14:19:32 2018 +0200
@@ -15,18 +15,23 @@
 import org.dive4elements.river.artifacts.ChartArtifact;
 import org.dive4elements.river.artifacts.D4EArtifact;
 import org.dive4elements.river.artifacts.common.AbstractCalculationExportableResult;
+import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.DataFacet;
 import org.dive4elements.river.artifacts.model.EmptyFacet;
 import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.artifacts.model.ReportFacet;
 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
+import org.dive4elements.river.artifacts.sinfo.common.CollisionCalcProcessor;
 import org.dive4elements.river.artifacts.states.DefaultState;
 
-/** State in which a waterlevel has been calculated. */
+/**
+ * State in which a collision count has been calculated.
+ */
 public class CollisionState extends DefaultState {
 
     /// ** The log that is used in this state. */
-    // private static Logger log = Logger.getLogger(FlowDepthState.class);
+    // private static Logger log = Logger.getLogger(CollisionState.class);
 
     private static final long serialVersionUID = 1L;
 
@@ -44,7 +49,6 @@
             facets.add(new EmptyFacet());
             return null;
         }
-
         return compute((SINFOArtifact) artifact, context, hash, facets, old);
     }
 
@@ -71,40 +75,29 @@
             return res;
         //
         final CollisionCalculationResults results = (CollisionCalculationResults) res.getData();
-        //
-        // /* add themes for chart, for each result */
-        // final List<CollisionCalcOverviewResult> resultList = results.getResults();
-        // for (int index = 0; index < resultList.size(); index++) {
-        //
-        final AbstractCalculationExportableResult<CollisionCalculationResults> result = results.getResults().get(0);
 
-        //
-        // /* filtered (zoom dependent mean) flow depth */
-        // facets.add(FlowDepthProcessor.createFlowDepthFilteredFacet(context, hash, this.id, result, index));
-        // facets.add(FlowDepthProcessor.createFlowDepthRawFacet(context, hash, this.id, result, index));
-        //
-        // if (results.isUseTkh()) {
-        // /* filtered (zoom dependent mean) flow depth including tkh */
-        // facets.add(FlowDepthProcessor.createFlowDepthTkhFilteredFacet(context, hash, this.id, result, index));
-        // facets.add(FlowDepthProcessor.createFlowDepthTkhRawFacet(context, hash, this.id, result, index));
-        //
-        // facets.add(TkhProcessor.createTkhFacet(context, hash, this.id, result, index));
-        // }
-        // }
+        /* add themes for chart, for each result */
+        final List<AbstractCalculationExportableResult<CollisionCalculationResults>> resultList = results.getResults();
+        for (int index = 0; index < resultList.size(); index++) {
+            if (resultList.get(index) instanceof CollisionCalcOverviewResult) {
+                final CollisionCalcOverviewResult result = (CollisionCalcOverviewResult) resultList.get(index);
+                facets.add(CollisionCalcProcessor.createFacet(context, hash, this.id, result, index));
+            }
+        }
 
-        if (!result.isEmpty()) {
+        if (!resultList.isEmpty()) {
             final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id);
             final Facet pdf = new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id);
 
             facets.add(csv);
             facets.add(pdf);
         }
-        //
-        // final Calculation report = res.getReport();
-        //
-        // if (report.hasProblems()) {
-        // facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
-        // }
+
+        final Calculation report = res.getReport();
+
+        if (report.hasProblems()) {
+            facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
+        }
 
         return res;
     }
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/GaugeDischargeValuesFinder.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/GaugeDischargeValuesFinder.java	Tue Jun 19 14:19:32 2018 +0200
@@ -0,0 +1,107 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo.collision;
+
+import org.apache.commons.lang.math.DoubleRange;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+import org.apache.commons.math.analysis.interpolation.LinearInterpolator;
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.model.DischargeTable;
+import org.dive4elements.river.model.DischargeTableValue;
+import org.dive4elements.river.model.Gauge;
+
+import gnu.trove.TDoubleArrayList;
+
+/**
+ * Loading and search/interpolation of a gauge's discharge table
+ *
+ * @author Matthias Schäfer
+ *
+ */
+public final class GaugeDischargeValuesFinder {
+
+    /***** FIELDS *****/
+
+    // private static Logger log = Logger.getLogger(GaugeDischargeValuesFinder.class);
+
+    private final Gauge gauge;
+
+    private final Calculation problems;
+
+    private final UnivariateRealFunction wInterpolator;
+
+    private final DoubleRange wRange;
+
+
+    /***** CONSTRUCTORS *****/
+
+    private GaugeDischargeValuesFinder(final Gauge gauge, final Calculation problems, final DischargeTable dischargeTable) {
+        this.gauge = gauge;
+        this.problems = problems;
+        final TDoubleArrayList ws = new TDoubleArrayList();
+        final TDoubleArrayList qs = new TDoubleArrayList();
+        for (final DischargeTableValue v : DischargeTable.getValuesSortedByW(dischargeTable)) {
+            ws.add(v.getW().doubleValue());
+            qs.add(v.getQ().doubleValue());
+        }
+        if (!ws.isEmpty())
+            this.wRange = new DoubleRange(ws.get(0), ws.get(ws.size() - 1));
+        else
+            this.wRange = null;
+        this.wInterpolator = new LinearInterpolator().interpolate(ws.toNativeArray(), qs.toNativeArray());
+    }
+
+
+    /***** METHODS *****/
+
+    /**
+     * Loads the the main discharge table of a gauge (GAUGE.at)
+     *
+     * @return The discharge table values finder of the gauge, or null
+     */
+    public static GaugeDischargeValuesFinder loadValues(final Gauge gauge, final Calculation problems) {
+        final DischargeTable table = DischargeTable.getGaugeMainDischargeTable(gauge);
+        if ((table == null) || (table.getDischargeTableValues().size() == 0))
+            return null;
+        else {
+            return new GaugeDischargeValuesFinder(gauge, problems, table);
+        }
+    }
+
+    /**
+     * If this provider may return valid data at all.
+     */
+    public boolean isValid() {
+        return (this.wInterpolator != null);
+    }
+
+    /**
+     * Discharge for a W
+     *
+     * @return Q, or NegInf for w less than all, or PosInf for w greater then all, or NaN in case of exception
+     */
+    public double getDischarge(final double w) {
+        try {
+            if (this.wInterpolator == null)
+                return Double.NaN;
+            else if (w < this.wRange.getMinimumDouble())
+                return Double.NEGATIVE_INFINITY;
+            else if (w > this.wRange.getMaximumDouble())
+                return Double.POSITIVE_INFINITY;
+            else
+                return this.wInterpolator.value(w);
+        }
+        catch (@SuppressWarnings("unused") final FunctionEvaluationException e) {
+            // ignore exception because this can/will happen regularly
+            return Double.NaN;
+        }
+    }
+}
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/GaugeDischargeZoneFinder.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/GaugeDischargeZoneFinder.java	Tue Jun 19 14:19:32 2018 +0200
@@ -0,0 +1,108 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.sinfo.collision;
+
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
+import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.MainValue;
+import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
+
+/**
+ * Loading and search the discharge zones of a gauge
+ *
+ * @author Matthias Schäfer
+ *
+ */
+public final class GaugeDischargeZoneFinder {
+
+    /***** FIELDS *****/
+
+    // private static Logger log = Logger.getLogger(GaugeDischargeZoneFinder.class);
+
+    private final Gauge gauge;
+
+    private final Calculation problems;
+
+    private final NavigableMap<Double, MainValue> qZones;
+
+    private final String approxPrefix = "ca."; // "\u2248" geht wohl nicht
+
+
+    /***** CONSTRUCTORS *****/
+
+    private GaugeDischargeZoneFinder(final Gauge gauge, final Calculation problems) {
+        this.gauge = gauge;
+        this.problems = problems;
+        this.qZones = new TreeMap<>();
+        for (final MainValue mainValue : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q))
+            this.qZones.put(Double.valueOf(mainValue.getValue().doubleValue()), mainValue);
+    }
+
+
+    /***** METHODS *****/
+
+    /**
+     * Loads the the main discharge table of a gauge (GAUGE.at)
+     *
+     * @return The discharge table values finder of the gauge, or null
+     */
+    public static GaugeDischargeZoneFinder loadValues(final Gauge gauge, final Calculation problems) {
+        return new GaugeDischargeZoneFinder(gauge, problems);
+    }
+
+    /**
+     * If this provider may return valid data at all.
+     */
+    public boolean isValid() {
+        return (this.qZones != null);
+    }
+
+    /**
+     * Discharge zone for a Q.
+     */
+    public String getDischargeZone(final double q) {
+        if (Double.isNaN(q))
+            return "";
+
+        // Exact match
+        if (this.qZones.containsKey(Double.valueOf(q)))
+            return this.qZones.get(Double.valueOf(q)).getMainValue().getName();
+
+        // Clearly below or just (max. 10%) below lowest named discharge
+        final Entry<Double, MainValue> lowerZone = this.qZones.floorEntry(Double.valueOf(q));
+        if (lowerZone == null) {
+            if (q >= this.qZones.firstKey().doubleValue() * 0.9)
+                return this.approxPrefix + this.qZones.firstEntry().getValue().getMainValue().getName();
+            else
+                return "<" + this.qZones.firstEntry().getValue().getMainValue().getName();
+        }
+
+        // Clearly above or just (max. 10%) above highest named discharge
+        final Entry<Double, MainValue> higherZone = this.qZones.ceilingEntry(Double.valueOf(q));
+        if (higherZone == null) {
+            if (q <= this.qZones.lastKey().doubleValue() * 1.1)
+                return this.approxPrefix + this.qZones.lastEntry().getValue().getMainValue().getName();
+            else
+                return ">" + this.qZones.lastEntry().getValue().getMainValue().getName();
+        }
+
+        // Near (10%) one of the borders of a zone interval, or clearly within a zone
+        if (q <= lowerZone.getKey().doubleValue() * 1.1)
+            return this.approxPrefix + lowerZone.getValue().getMainValue().getName();
+        else if (q >= higherZone.getKey().doubleValue() * 0.9)
+            return this.approxPrefix + higherZone.getValue().getMainValue().getName();
+        else
+            return lowerZone.getValue().getMainValue().getName() + "-" + higherZone.getValue().getMainValue().getName();
+    }
+}
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCalcProcessor.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCalcProcessor.java	Tue Jun 19 14:19:32 2018 +0200
@@ -0,0 +1,88 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ *  Björnsen Beratende Ingenieure GmbH
+ *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.common;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifactdatabase.state.Facet;
+import org.dive4elements.artifacts.Artifact;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.common.AbstractCalculationResult;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.artifacts.sinfo.collision.CollisionCalcFacet;
+import org.dive4elements.river.artifacts.sinfo.collision.CollisionCalcOverviewResult;
+import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
+import org.dive4elements.river.exports.DiagramGenerator;
+import org.dive4elements.river.exports.StyledSeriesBuilder;
+import org.dive4elements.river.jfree.StyledXYSeries;
+import org.dive4elements.river.themes.ThemeDocument;
+
+/**
+ * Processor to generate the facet and data series of calculated bed collision counts
+ *
+ * @author Matthias Schäfer
+ *
+ */
+public final class CollisionCalcProcessor extends AbstractSInfoProcessor {
+
+    public static final String FACET_COLLISION_CALC_COUNT = "sinfo_facet_collision_calc_count";
+
+    private static final String I18N_AXIS_LABEL = "chart.collision_count.section.yaxis.label";
+
+    private static final String I18N_SERIES_NAME_PATTERN = "collision.count.title";
+
+    private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>();
+
+    static {
+        HANDLED_FACET_TYPES.add(FACET_COLLISION_CALC_COUNT);
+    }
+
+    public CollisionCalcProcessor() {
+        super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES);
+    }
+
+    @Override
+    protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
+
+        final CallContext context = generator.getContext();
+        final Map<String, String> metaData = bundle.getFacet().getMetaData();
+
+        final Artifact artifact = bundle.getArtifact();
+
+        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
+        series.putMetaData(metaData, artifact, context);
+
+        final String facetName = bundle.getFacetName();
+
+        final CollisionCalcOverviewResult data = (CollisionCalcOverviewResult) bundle.getData(context);
+        if (data == null) {
+            // Check has been here before so we keep it for security reasons
+            // this should never happen though.
+            throw new IllegalStateException("Data is null for facet: " + facetName);
+        }
+
+        final double[][] points = data.getStationPoints(SInfoResultType.collisionCount);
+
+        StyledSeriesBuilder.addPoints(series, points, true);
+        generator.addAxisSeries(series, getAxisName(), visible);
+
+        return metaData.get("Y");
+    }
+
+    public static final Facet createFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result,
+            final int index) {
+        final String facetDescription = Resources.getMsg(context.getMeta(), I18N_SERIES_NAME_PATTERN, I18N_SERIES_NAME_PATTERN, result.getLabel());
+        return new CollisionCalcFacet(index, FACET_COLLISION_CALC_COUNT, facetDescription, I18N_AXIS_LABEL, ComputeType.ADVANCE, id, hash);
+    }
+}
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCountProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCountProcessor.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionCountProcessor.java	Tue Jun 19 14:19:32 2018 +0200
@@ -65,6 +65,7 @@
         series.putMetaData(metaData, artifact, context);
 
         final String facetName = bundle.getFacetName();
+
         final CollisionQueryCalculationResult data = (CollisionQueryCalculationResult) bundle.getData(context);
         if (data == null) {
             // Check has been here before so we keep it for security reasons
@@ -84,4 +85,5 @@
         return new CollisionFacet(FACET_COLLISION_COUNT,
                 Resources.getMsg(callMeta, I18N_SERIES_NAME_PATTERN, I18N_SERIES_NAME_PATTERN, seriesName), I18N_AXIS_LABEL);
     }
+
 }
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionGaugeWProcessor.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/CollisionGaugeWProcessor.java	Tue Jun 19 14:16:45 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
- * Software engineering by
- *  Björnsen Beratende Ingenieure GmbH
- *  Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
- *
- * This file is Free Software under the GNU AGPL (>=v3)
- * and comes with ABSOLUTELY NO WARRANTY! Check out the
- * documentation coming with Dive4Elements River for details.
- */
-
-package org.dive4elements.river.artifacts.sinfo.common;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
-import org.dive4elements.artifactdatabase.state.Facet;
-import org.dive4elements.artifacts.Artifact;
-import org.dive4elements.artifacts.CallContext;
-import org.dive4elements.artifacts.CallMeta;
-import org.dive4elements.river.artifacts.resources.Resources;
-import org.dive4elements.river.artifacts.sinfo.collision.CollisionFacet;
-import org.dive4elements.river.artifacts.sinfo.collision.CollisionQueryCalculationResult;
-import org.dive4elements.river.exports.DiagramGenerator;
-import org.dive4elements.river.exports.StyledSeriesBuilder;
-import org.dive4elements.river.jfree.StyledXYSeries;
-import org.dive4elements.river.themes.ThemeDocument;
-
-/**
- * Processor to generate a data series for collision gauge W data loaded from the database
- *
- * @author Matthias Schäfer
- *
- */
-public class CollisionGaugeWProcessor extends AbstractSInfoProcessor {
-
-    // private final static Logger log = Logger.getLogger(CollisionGaugeWProcessor.class);
-
-    public static final String FACET_COLLISION_GAUGEW = "sinfo_facet_collision_gaugew";
-
-    private static final String I18N_AXIS_LABEL = "chart.longitudinal.section.yaxis.label";
-
-    private static final String I18N_SERIES_NAME_PATTERN = "collision.gaugew.title";
-
-    private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>();
-
-    static {
-        HANDLED_FACET_TYPES.add(FACET_COLLISION_GAUGEW);
-    }
-
-    public CollisionGaugeWProcessor() {
-        super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES);
-    }
-
-    @Override
-    protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) {
-
-        final CallContext context = generator.getContext();
-        final Map<String, String> metaData = bundle.getFacet().getMetaData();
-
-        final Artifact artifact = bundle.getArtifact();
-
-        final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme);
-        series.putMetaData(metaData, artifact, context);
-
-        final String facetName = bundle.getFacetName();
-        final CollisionQueryCalculationResult data = (CollisionQueryCalculationResult) bundle.getData(context);
-        if (data == null) {
-            // Check has been here before so we keep it for security reasons
-            // this should never happen though.
-            throw new IllegalStateException("Data is null for facet: " + facetName);
-        }
-
-        final double[][] points = data.getStationPoints(SInfoResultType.collisionGaugeW);
-
-        StyledSeriesBuilder.addPoints(series, points, true);
-        generator.addAxisSeries(series, getAxisName(), visible);
-
-        return metaData.get("Y");
-    }
-
-    public static Facet createFacet(final CallMeta callMeta, final String seriesName) {
-        return new CollisionFacet(FACET_COLLISION_GAUGEW,
-                Resources.getMsg(callMeta, I18N_SERIES_NAME_PATTERN, I18N_SERIES_NAME_PATTERN, seriesName), I18N_AXIS_LABEL);
-    }
-}
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoI18NStrings.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoI18NStrings.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoI18NStrings.java	Tue Jun 19 14:19:32 2018 +0200
@@ -81,4 +81,9 @@
 
     String CSV_COLLISION_GAUGEW_HEADER = "sinfo.export.csv.header.collision.gaugew";
 
+    String CSV_META_HEADER_YEARS = "sinfo.export.csv.meta.header.years";
+
+    String CSV_YEARS_HEADER = "sinfo.export.csv.header.years";
+
+    String CSV_DISCHARGE_ZONE_HEADER = "sinfo.export.csv.header.discharge.zone";
 }
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java	Tue Jun 19 14:19:32 2018 +0200
@@ -63,12 +63,12 @@
         public String exportValue(final CallContext context, final Object value) {
             final double doubleValue = asDouble(value);
             return exportDoubleValue(context, doubleValue); // integer
-                                                            // als
-                                                            // double?
-                                                            // finde
-                                                            // gerade
-                                                            // kein
-                                                            // int-beispiel
+            // als
+            // double?
+            // finde
+            // gerade
+            // kein
+            // int-beispiel
         }
 
         @Override
@@ -85,12 +85,12 @@
         public String exportValue(final CallContext context, final Object value) {
             final double doubleValue = asDouble(value);
             return exportDoubleValue(context, doubleValue); // integer
-                                                            // als
-                                                            // double?
-                                                            // finde
-                                                            // gerade
-                                                            // kein
-                                                            // int-beispiel
+            // als
+            // double?
+            // finde
+            // gerade
+            // kein
+            // int-beispiel
         }
 
         @Override
@@ -602,4 +602,31 @@
         }
     };
 
+    public static final SInfoResultType years = new SInfoResultType(I18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_YEARS_HEADER) {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public String exportValue(final CallContext context, final Object value) {
+            return exportStringValue(value);
+        }
+
+        @Override
+        protected NumberFormat createFormatter(final CallContext context) {
+            throw new UnsupportedOperationException();
+        }
+    };
+
+    public static final SInfoResultType dischargeZone = new SInfoResultType(I18NStrings.UNIT_NONE, SInfoI18NStrings.CSV_DISCHARGE_ZONE_HEADER) {
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        public String exportValue(final CallContext context, final Object value) {
+            return exportStringValue(value);
+        }
+
+        @Override
+        protected NumberFormat createFormatter(final CallContext context) {
+            throw new UnsupportedOperationException();
+        }
+    };
 }
\ No newline at end of file
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/resources/messages.properties
--- a/artifacts/src/main/resources/messages.properties	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/resources/messages.properties	Tue Jun 19 14:19:32 2018 +0200
@@ -1110,9 +1110,16 @@
 
 sinfo.export.csv.header.collision.count = Anzahl der Grundber\u00fchrungen
 collision.count.title = Grundber\u00fchrungen {0}
-chart.collision_count.section.yaxis.label = Anzahl
+chart.collision_count.section.yaxis.label = H\u00e4ufigkeit
 sinfo.export.csv.header.collision.gaugew = W am Pegel
 collision.gaugew.title = W am Pegel {0}
+sinfo.export.csv.header.discharge.zone = Abflusszustand
+
+sinfo.export.csv.meta.header.years = # Jahr/Zeitraum: {0}
+sinfo.export.csv.header.years = Jahr/Zeitraum
+sinfo.export.csv.meta.date = Datum
+
+sinfo.chart.collision.section.title = Grundber\u00fchrungen
 
 bundu_bezugswst = Bezugswasserst\u00e4nde
 bundu_analysis = Fixinganalysis
diff -r 568961ff709a -r f9bb5d0a6ff3 artifacts/src/main/resources/messages_de.properties
--- a/artifacts/src/main/resources/messages_de.properties	Tue Jun 19 14:16:45 2018 +0200
+++ b/artifacts/src/main/resources/messages_de.properties	Tue Jun 19 14:19:32 2018 +0200
@@ -1110,9 +1110,16 @@
 
 sinfo.export.csv.header.collision.count = Anzahl der Grundber\u00fchrungen
 collision.count.title = Grundber\u00fchrungen {0}
-chart.collision_count.section.yaxis.label = Anzahl
+chart.collision_count.section.yaxis.label = H\u00e4ufigkeit
 sinfo.export.csv.header.collision.gaugew = W am Pegel
 collision.gaugew.title = W am Pegel {0}
+sinfo.export.csv.header.discharge.zone = Abflusszustand
+
+sinfo.export.csv.meta.header.years = # Jahr/Zeitraum: {0}
+sinfo.export.csv.header.years = Jahr/Zeitraum
+sinfo.export.csv.meta.date = Datum
+
+sinfo.chart.collision.section.title = Grundber\u00fchrungen
 
 bundu_bezugswst = Bezugswasserst\u00e4nde
 bundu_analysis = Fixierungsanalyse
diff -r 568961ff709a -r f9bb5d0a6ff3 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java	Tue Jun 19 14:16:45 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java	Tue Jun 19 14:19:32 2018 +0200
@@ -1505,6 +1505,8 @@
 
     String sinfo_collisions();
 
+    String sinfo_collision();
+
     String uinfo();
 
     String uinfo_salix_line_export();
diff -r 568961ff709a -r f9bb5d0a6ff3 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Tue Jun 19 14:16:45 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties	Tue Jun 19 14:19:32 2018 +0200
@@ -809,6 +809,7 @@
 sinfo_infrastructure = Infrastrukturen BWaStr
 
 sinfo_collisions = Grundber\u00fchrungen
+sinfo_collision = Grundber\u00fchrungen
 
 uinfo = U-INFO
 uinfo_inundation_duration_export = \u00dcberflutungsdauern Export
diff -r 568961ff709a -r f9bb5d0a6ff3 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Tue Jun 19 14:16:45 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties	Tue Jun 19 14:19:32 2018 +0200
@@ -809,6 +809,7 @@
 sinfo_infrastructure = Infrastrukturen BWaStr
 
 sinfo_collisions = Grundber\u00fchrungen
+sinfo_collision = Grundber\u00fchrungen
 
 uinfo = U-INFO
 uinfo_inundation_duration_export = \u00dcberflutungsdauern Export


More information about the Dive4Elements-commits mailing list