diff artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java @ 9499:853f2dafc16e

VegetationZones in CrossSectionsDiagram
author gernotbelger
date Thu, 27 Sep 2018 18:06:26 +0200
parents e44c1a8b0c54
children 76c0665888a3
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java	Wed Sep 26 15:48:05 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java	Thu Sep 27 18:06:26 2018 +0200
@@ -12,9 +12,7 @@
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Map.Entry;
 import java.util.NavigableMap;
 
@@ -24,18 +22,13 @@
 import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.model.Calculation;
-import org.dive4elements.river.artifacts.model.WstValueTable;
-import org.dive4elements.river.artifacts.model.WstValueTable.QPosition;
-import org.dive4elements.river.artifacts.model.WstValueTableFactory;
-import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
+import org.dive4elements.river.artifacts.model.river.MainWstValuesCalculator;
+import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper;
 import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
 import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType;
 import org.dive4elements.river.artifacts.uinfo.salix.SalixLineAccess.ScenarioType;
 import org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZoneServerClientXChange;
-import org.dive4elements.river.model.Gauge;
-import org.dive4elements.river.model.MainValue;
-import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
 import org.dive4elements.river.utils.Formatter;
 
 /**
@@ -45,31 +38,21 @@
  */
 final class SalixLineCalculator {
 
+    private static final String MAIN_VALUE_MNQ = "mnq";
+
+    private static final String MAIN_VALUE_MQ = "mq";
+
+    private static final String MAIN_VALUE_MHQ = "mhq";
+
+    private static final String MAIN_VALUE_HQ5 = "hq5";
+
     private static final BigDecimal SALIX_DISTANCE = new BigDecimal("2.31");
     private final List<ResultRow> rows = new ArrayList<>();
 
     private final RiverInfoProvider riverInfoProvider;
 
-    private final Map<Gauge, QPosition> gaugeMwPos;
-    private final Map<Gauge, QPosition> gaugeMnwPos;
-    private final Map<Gauge, QPosition> gaugeMhwPos;
-    private final Map<Gauge, QPosition> gaugeHw5Pos;
-    private QPosition refGaugeMwPos;
-    private QPosition refGaugeMnwPos;
-    private QPosition refGaugeMhwPos;
-    private QPosition refGaugeHw5Pos;
-    private Gauge firstGauge;
-
-    private Calculation problems;
-
-    private WstValueTable wst;
-
     public SalixLineCalculator(final RiverInfoProvider riverInfoProvider) {
         this.riverInfoProvider = riverInfoProvider;
-        this.gaugeMwPos = new HashMap<>();
-        this.gaugeMnwPos = new HashMap<>();
-        this.gaugeMhwPos = new HashMap<>();
-        this.gaugeHw5Pos = new HashMap<>();
     }
 
     /**
@@ -79,16 +62,13 @@
             final ScenarioType scenarioType, final String[] scenarioLabels, final String rangeString, final String additionalString,
             final SalixLineCalculationResults results) {
 
-        this.problems = problems;
-        this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver());
-
-        fetchGaugeMainValuePositions();
+        final MainWstValuesCalculator mainWstValues = fetchGaugeMainValuePositions2(problems);
 
         final WINFOArtifact winfo = new WinfoArtifactWrapper(uinfo);
         winfo.addStringData("ld_mode", "distance");
         winfo.addStringData("ld_step", "100");
         for (final double station : new ComputationRangeAccess(winfo).getKms()) {
-            this.rows.add(createRow(station, rangeScenarios));
+            this.rows.add(createRow(mainWstValues, station, rangeScenarios));
         }
         if (scenarioType == ScenarioType.REGIONAL)
             results.addResult(new SalixLineCalculationRegionalResult("Salix-regional", scenarioLabels, rangeString, additionalString, this.rows), problems);
@@ -100,54 +80,28 @@
             results.addResult(new SalixLineCalculationResult("Salix-simple", this.rows), problems);
     }
 
-    /**
-     * Fetch MQ, MNQ and MHQ of all gauges and determine the wst QPosition for each one
-     */
-    private void fetchGaugeMainValuePositions() {
-        this.gaugeMwPos.clear();
-        this.gaugeMnwPos.clear();
-        this.gaugeMhwPos.clear();
-        this.gaugeHw5Pos.clear();
+    private MainWstValuesCalculator fetchGaugeMainValuePositions2(final Calculation problems) {
+        final MainWstValuesCalculator mainWstValues = MainWstValuesCalculator.forRiverInfo(this.riverInfoProvider, MAIN_VALUE_MQ, MAIN_VALUE_MNQ,
+                MAIN_VALUE_MHQ, MAIN_VALUE_HQ5);
 
-        this.firstGauge = null;
-        for (final Gauge gauge : this.riverInfoProvider.getGauges()) {
-            this.gaugeMwPos.put(gauge, null);
-            this.gaugeMnwPos.put(gauge, null);
-            this.gaugeMhwPos.put(gauge, null);
-            this.gaugeHw5Pos.put(gauge, null);
-            final double gaugeKm = gauge.getStation().doubleValue();
-            for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q)) {
-                if (mv.getMainValue().getName().equalsIgnoreCase("mq"))
-                    this.gaugeMwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
-                else if (mv.getMainValue().getName().equalsIgnoreCase("mnq"))
-                    this.gaugeMnwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
-                else if (mv.getMainValue().getName().equalsIgnoreCase("mhq"))
-                    this.gaugeMhwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
-                else if (mv.getMainValue().getName().equalsIgnoreCase("hq5"))
-                    this.gaugeHw5Pos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue()));
-            }
-            if (this.firstGauge == null) {
-                this.refGaugeMwPos = this.gaugeMwPos.get(gauge);
-                this.refGaugeMnwPos = this.gaugeMnwPos.get(gauge);
-                this.refGaugeMhwPos = this.gaugeMhwPos.get(gauge);
-                this.refGaugeHw5Pos = this.gaugeHw5Pos.get(gauge);
-                this.firstGauge = gauge;
-            }
+        if (!mainWstValues.hasPosition(MAIN_VALUE_MQ))
+            problems.addProblem("uinfo_salix_calc.warning.missing_mq");
+        else {
+            if (!mainWstValues.hasPosition(MAIN_VALUE_MHQ))
+                problems.addProblem("uinfo_salix_calc.warning.missing_mhq");
+            if (!mainWstValues.hasPosition(MAIN_VALUE_MNQ))
+                problems.addProblem("uinfo_salix_calc.warning.missing_mnq");
         }
-        if (this.refGaugeMwPos == null)
-            this.problems.addProblem("uinfo_salix_calc.warning.missing_mq");
-        else {
-            if (this.refGaugeMhwPos == null)
-                this.problems.addProblem("uinfo_salix_calc.warning.missing_mhq");
-            if (this.refGaugeMnwPos == null)
-                this.problems.addProblem("uinfo_salix_calc.warning.missing_mnq");
-        }
+
+        return mainWstValues;
     }
 
     /**
      * Create a result row for a station and its gauge, and add w-q-values as selected
+     *
+     * @param mainWstValues
      */
-    private ResultRow createRow(final double station, final NavigableMap<Double, List<Double>> rangeScenarios) {
+    private ResultRow createRow(final MainWstValuesCalculator mainWstValues, final double station, final NavigableMap<Double, List<Double>> rangeScenarios) {
 
         final ResultRow row = ResultRow.create();
         row.putValue(GeneralResultType.station, station);
@@ -157,10 +111,10 @@
         // final double mnw = interpolateW(station, this.gaugeMnwPos.get(gauge));
         // final double mw = interpolateW(station, this.gaugeMwPos.get(gauge));
         // final double mhw = interpolateW(station, this.gaugeMhwPos.get(gauge));
-        final double mnw = interpolateW(station, this.refGaugeMnwPos);
-        final double mw = interpolateW(station, this.refGaugeMwPos);
-        final double mhw = interpolateW(station, this.refGaugeMhwPos);
-        final double hw5 = interpolateW(station, this.refGaugeHw5Pos);
+        final double mnw = mainWstValues.interpolateW(station, MAIN_VALUE_MNQ);
+        final double mw = mainWstValues.interpolateW(station, MAIN_VALUE_MQ);
+        final double mhw = mainWstValues.interpolateW(station, MAIN_VALUE_MHQ);
+        final double hw5 = mainWstValues.interpolateW(station, MAIN_VALUE_HQ5);
         row.putValue(UInfoResultType.waterlevelMNW, mnw);
         row.putValue(UInfoResultType.waterlevelMW, mw);
         row.putValue(UInfoResultType.waterlevelMHW, mhw);
@@ -179,8 +133,7 @@
                 final double salix = calcSalix(mhw, mw, deltaw.doubleValue());
                 final double scen = calcSalix(mhw, 0.0, deltaw.doubleValue());
                 scenarios.add(new SalixScenario((int) (deltaw * 100), salix, scen));
-            }
-            else {
+            } else {
                 scenarios.add(null);
             }
         }
@@ -190,15 +143,6 @@
     }
 
     /**
-     * Interpolates the W for a station with a fixed (virtual) wst column position
-     */
-    private double interpolateW(final double station, final QPosition qPosition) {
-        if (qPosition != null)
-            return this.wst.interpolateW(station, qPosition, this.problems);
-        return Double.NaN;
-    }
-
-    /**
      * Calculates the salix value
      */
     private double calcSalix(final double mhw, final double mw, final double deltamw) {
@@ -263,6 +207,7 @@
         final ResultRow stationRow = searchStation(station, result.getRows());
         if (stationRow == null)
             return Double.NaN;
+
         // Compute height from overflow duration days
         final List<VegetationZoneServerClientXChange> vzs = VegetationZoneServerClientXChange.getStandardList(null, null); // TODO river, context
         if ((vegetationZoneType >= 1) && (vegetationZoneType <= vzs.size())) {

http://dive4elements.wald.intevation.org