comparison artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java @ 9295:385b52ccde23

Work on U-Info salix line calculation and chart (no scenario case)
author mschaefer
date Tue, 24 Jul 2018 18:51:47 +0200
parents
children 9a9f076d5716
comparison
equal deleted inserted replaced
9294:7a8b9331a946 9295:385b52ccde23
1 /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
2 * Software engineering by
3 * Björnsen Beratende Ingenieure GmbH
4 * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
5 *
6 * This file is Free Software under the GNU AGPL (>=v3)
7 * and comes with ABSOLUTELY NO WARRANTY! Check out the
8 * documentation coming with Dive4Elements River for details.
9 */
10 package org.dive4elements.river.artifacts.uinfo.salix;
11
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16
17 import org.dive4elements.artifacts.CallContext;
18 import org.dive4elements.river.artifacts.WINFOArtifact;
19 import org.dive4elements.river.artifacts.access.ComputationRangeAccess;
20 import org.dive4elements.river.artifacts.common.GeneralResultType;
21 import org.dive4elements.river.artifacts.common.ResultRow;
22 import org.dive4elements.river.artifacts.model.Calculation;
23 import org.dive4elements.river.artifacts.model.WstValueTable;
24 import org.dive4elements.river.artifacts.model.WstValueTable.QPosition;
25 import org.dive4elements.river.artifacts.model.WstValueTableFactory;
26 import org.dive4elements.river.artifacts.sinfo.common.GaugeDischargeValuesFinder;
27 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
28 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
29 import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper;
30 import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
31 import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
32 import org.dive4elements.river.model.Gauge;
33 import org.dive4elements.river.model.MainValue;
34 import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
35
36 /**
37 * Calculation of the result rows of the u-info salix line calc mode
38 *
39 * @author Matthias Schäfer
40 */
41 public class SalixLineCalculator {
42
43 private final List<ResultRow> rows = new ArrayList<>();
44
45 private final RiverInfoProvider riverInfoProvider;
46
47 private final CallContext context;
48
49 private final Map<Gauge, QPosition> gaugeMwPos;
50 private final Map<Gauge, QPosition> gaugeMnwPos;
51 private final Map<Gauge, QPosition> gaugeMhwPos;
52
53 private Calculation problems;
54
55 private WstValueTable wst;
56
57 public SalixLineCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) {
58 this.context = context;
59 this.riverInfoProvider = riverInfoProvider;
60 this.gaugeMwPos = new HashMap<>();
61 this.gaugeMnwPos = new HashMap<>();
62 this.gaugeMhwPos = new HashMap<>();
63 }
64
65
66 /**
67 * Calculate the salix line result rows
68 */
69 public void execute(final Calculation problems, final UINFOArtifact uinfo, final SalixLineCalculationResults results) {
70
71 this.problems = problems;
72 this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver());
73
74 fetchGaugeMainValuePositions();
75
76 final WINFOArtifact winfo = new WinfoArtifactWrapper(uinfo);
77 winfo.addStringData("ld_mode", "distance");
78 winfo.addStringData("ld_step", "100");
79 for (final double station : new ComputationRangeAccess(winfo).getKms()) {
80 this.rows.add(createRow(station));
81 }
82 results.addResult(new SalixLineCalculationNoScenarioResult("Salix", null, this.rows), problems);
83 }
84
85 /**
86 * Fetch MW, MNW and MHW of all gauges and determine the wst QPosition for each one
87 */
88 private void fetchGaugeMainValuePositions() {
89 this.gaugeMwPos.clear();
90 this.gaugeMnwPos.clear();
91 this.gaugeMhwPos.clear();
92 for (final Gauge gauge : this.riverInfoProvider.getGauges()) {
93 this.gaugeMwPos.put(gauge, null);
94 this.gaugeMnwPos.put(gauge, null);
95 this.gaugeMhwPos.put(gauge, null);
96 final GaugeDischargeValuesFinder finder = GaugeDischargeValuesFinder.loadValues(gauge, this.problems);
97 if (finder == null)
98 continue;
99 final double gaugeKm = gauge.getStation().doubleValue();
100 for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.W)) {
101 if (mv.getMainValue().getName().equalsIgnoreCase("mw"))
102 this.gaugeMwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue())));
103 else if (mv.getMainValue().getName().equalsIgnoreCase("mnw"))
104 this.gaugeMnwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue())));
105 else if (mv.getMainValue().getName().equalsIgnoreCase("mhw"))
106 this.gaugeMhwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue())));
107 }
108 }
109 }
110
111 /**
112 * Create a result row for a station and its gauge, and add w-q-values as selected
113 */
114 private ResultRow createRow(final double station) {
115
116 final ResultRow row = ResultRow.create();
117 final Gauge gauge = this.riverInfoProvider.getGauge(station, true);
118 row.putValue(GeneralResultType.station, station);
119 final double mnw = interpolateW(station, this.gaugeMnwPos.get(gauge));
120 final double mw = interpolateW(station, this.gaugeMwPos.get(gauge));
121 final double mhw = interpolateW(station, this.gaugeMhwPos.get(gauge));
122 row.putValue(SInfoResultType.waterlevel, mnw);
123 row.putValue(SInfoResultType.waterlevel1, mw);
124 row.putValue(SInfoResultType.waterlevel2, mhw);
125 row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw));
126 row.putValue(UInfoResultType.salix_delta_mw, calcMwmnw(mw, mnw));
127 return row;
128 }
129
130 /**
131 * Interpolates the W for a station with a fixed (virtual) wst column position
132 */
133 private double interpolateW(final double station, final QPosition qPosition) {
134 if (qPosition != null)
135 return this.wst.interpolateW(station, qPosition, this.problems);
136 else
137 return Double.NaN;
138 }
139
140 /**
141 * Calculates the salix value
142 */
143 private double calcSalix(final double mhw, final double mw) {
144 return mhw - 2.31 - mw;
145 }
146
147 /**
148 * Calculates the inverse MW-MNW difference
149 */
150 private double calcMwmnw(final double mw, final double mnw) {
151 return mnw - mw;
152 }
153 }

http://dive4elements.wald.intevation.org