comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java @ 9229:0dcd1cd41915

Different themes/facets for left bank and right bank infrastructures in S-Info flood durations, some fixmes done
author mschaefer
date Thu, 05 Jul 2018 16:49:42 +0200
parents 0fc9c82e744e
children d47f6641f597
comparison
equal deleted inserted replaced
9228:dba14da43f23 9229:0dcd1cd41915
25 import org.dive4elements.river.artifacts.model.Calculation; 25 import org.dive4elements.river.artifacts.model.Calculation;
26 import org.dive4elements.river.artifacts.model.Calculation.Problem; 26 import org.dive4elements.river.artifacts.model.Calculation.Problem;
27 import org.dive4elements.river.artifacts.model.CalculationResult; 27 import org.dive4elements.river.artifacts.model.CalculationResult;
28 import org.dive4elements.river.artifacts.model.WQKms; 28 import org.dive4elements.river.artifacts.model.WQKms;
29 import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder; 29 import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder;
30 import org.dive4elements.river.artifacts.sinfo.common.GaugeMainValueFinder;
31 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; 30 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
32 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; 31 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
33 import org.dive4elements.river.artifacts.sinfo.common.WQBaseTableFinder; 32 import org.dive4elements.river.artifacts.sinfo.common.WQBaseTableFinder;
34 import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey; 33 import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey;
35 import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; 34 import org.dive4elements.river.exports.WaterlevelDescriptionBuilder;
36 import org.dive4elements.river.model.Attribute.AttributeKey; 35 import org.dive4elements.river.model.Attribute.AttributeKey;
37 import org.dive4elements.river.model.Gauge; 36 import org.dive4elements.river.model.Gauge;
38 import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
39 import org.dive4elements.river.model.sinfo.InfrastructureValue; 37 import org.dive4elements.river.model.sinfo.InfrastructureValue;
40 38
41 import gnu.trove.TDoubleArrayList; 39 import gnu.trove.TDoubleArrayList;
42 40
43 /** 41 /**
80 calcRange.getMaximumDouble(), bankKey); 78 calcRange.getMaximumDouble(), bankKey);
81 79
82 // Merge all stations (range/step, borders of gauge ranges, infrastructures) 80 // Merge all stations (range/step, borders of gauge ranges, infrastructures)
83 final Map<Double, InfrastructureValue> allStations = new HashMap<>(); 81 final Map<Double, InfrastructureValue> allStations = new HashMap<>();
84 final Map<Double, InfrastructureValue> secondBank = new HashMap<>(); // any second infrastructure in case of both-banks-option 82 final Map<Double, InfrastructureValue> secondBank = new HashMap<>(); // any second infrastructure in case of both-banks-option
85 // FIXME: check, do we really need all stations? compare with tkh...
86 addRangeStations(allStations, winfo); 83 addRangeStations(allStations, winfo);
87 addGaugeLimits(allStations, durFinders.keySet(), calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); 84 addGaugeLimits(allStations, durFinders.keySet(), calcRange.getMinimumDouble(), calcRange.getMaximumDouble());
88 addInfrastructures(allStations, secondBank, infras); 85 addInfrastructures(allStations, secondBank, infras);
89 final double[] stationsSorted = sortStations(allStations.keySet()); 86 final double[] stationsSorted = sortStations(allStations.keySet());
90 87
91 // Calculate W and Q for all stations and the selected discharge states 88 // Calculate W and Q for all stations and the selected discharge states
89 // TODO Laut Herrn Reiß: Q und D jeweils konstant für jedes Pegel-Intervall, Q-Änderungen (Zuflüsse etc.) aus .wst
90 // ignorieren
92 final WQKms[] wqkmsArray = calculateWaterlevels(winfo, stationsSorted, problems); 91 final WQKms[] wqkmsArray = calculateWaterlevels(winfo, stationsSorted, problems);
93 92
94 // Determine discharge state labels of the main values 93 // Determine discharge state labels of the main values
95 final String[] mainValueLabels = findMainValueLabels(wqkmsArray, winfo.getQs(), firstGauge, problems); 94 final WaterlevelDescriptionBuilder wdescBuilder = new WaterlevelDescriptionBuilder(winfo, this.context);
95 final String[] mainValueLabels = findMainValueLabels(wqkmsArray, winfo.getQs(), wdescBuilder, problems);
96 96
97 // Create a finder for Q in the {river}.wst km-w-q table 97 // Create a finder for Q in the {river}.wst km-w-q table
98 final WQBaseTableFinder wqFinder = WQBaseTableFinder.loadValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(), 98 final WQBaseTableFinder wqFinder = WQBaseTableFinder.loadValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(),
99 calcRange.getMaximumDouble(), problems); 99 calcRange.getMaximumDouble(), problems);
100 100
101 final WaterlevelDescriptionBuilder descBuilder = new WaterlevelDescriptionBuilder(winfo, this.context); 101 final WaterlevelDescriptionBuilder descBuilder = new WaterlevelDescriptionBuilder(winfo, this.context);
102 102
103 // Calculate the durations and create the result rows 103 // Calculate the durations and create the result rows
104 for (int i = 0; i <= stationsSorted.length - 1; i++) { 104 for (int i = 0; i <= stationsSorted.length - 1; i++) {
105 final Gauge gauge = this.riverInfoProvider.getGauge(stationsSorted[i], true); 105 final Gauge gauge = this.riverInfoProvider.getGauge(stationsSorted[i], true);
106 final ResultRow row = createRow(descBuilder, stationsSorted[i], gauge, wqkmsArray, durFinders.get(gauge), i); 106 final ResultRow row = createRow(descBuilder, stationsSorted[i], gauge, firstGauge, wqkmsArray, durFinders.get(gauge), i);
107 if (allStations.containsKey(stationsSorted[i]) && (allStations.get(stationsSorted[i]) != null)) 107 if (allStations.containsKey(stationsSorted[i]) && (allStations.get(stationsSorted[i]) != null))
108 calculateInfrastructure(row, gauge, allStations.get(stationsSorted[i]), wqFinder, durFinders); 108 calculateInfrastructure(row, gauge, allStations.get(stationsSorted[i]), wqFinder, durFinders);
109 this.rows.add(row); 109 this.rows.add(row);
110 if (secondBank.containsKey(stationsSorted[i])) { 110 if (secondBank.containsKey(stationsSorted[i])) {
111 final ResultRow row2 = ResultRow.create(row); 111 final ResultRow row2 = ResultRow.create(row);
169 */ 169 */
170 private WQKms[] calculateWaterlevels(final WINFOArtifact winfo, final double[] stations, final Calculation problems) { 170 private WQKms[] calculateWaterlevels(final WINFOArtifact winfo, final double[] stations, final Calculation problems) {
171 // REMARK aus TkhCalculation - move to WinfoArtifactWrapper? 171 // REMARK aus TkhCalculation - move to WinfoArtifactWrapper?
172 // TODO das ist ziemlich langsam - durch den WQBaseTableFinder ersetzen? (vorher W-Optionen in Q umrechnen) 172 // TODO das ist ziemlich langsam - durch den WQBaseTableFinder ersetzen? (vorher W-Optionen in Q umrechnen)
173 // (So funktioniert computeWaterlevelData wohl: 173 // (So funktioniert computeWaterlevelData wohl:
174 // Es sucht die Spalte(n) zum Bezugspegel-Q in der W-Q-Tabelle ({river}.wst in Wst etc.) 174 // Es sucht die Spalte(n) zum Bezugspegel-Q in der W-Q-Tabelle ({river}.wst in Wst etc.),
175 // und interpoliert für diese horizontale Tabellenposition jeweils die vertikale Tabellenposition der station; 175 // interpoliert die horizontale Tabellenposition (Q) und dann die vertikale Tabellenposition der station;
176 // das ergibt das W einer station für einen Abflusszustand; 176 // das ergibt das W einer station für einen Abflusszustand;
177 // bei Vorgabe eines Pegel-W wird vorher anhand der W-Q-Tabelle des Pegels ({gauge}.at in DischargeTable) das Q 177 // bei Vorgabe eines Pegel-W wird vorher anhand der W-Q-Tabelle des Pegels ({gauge}.at in DischargeTable) das Q
178 // interpoliert; 178 // interpoliert;
179 // bei Vorgabe eines W auf freier Strecke wird wohl vorher noch die .wst-Interpolation eingesetzt. 179 // bei Vorgabe eines W auf freier Strecke wird wohl vorher noch die .wst-Interpolation eingesetzt, um das Q zu bekommen.
180
180 final CalculationResult waterlevelData = winfo.computeWaterlevelData(stations); 181 final CalculationResult waterlevelData = winfo.computeWaterlevelData(stations);
181 182
182 /* copy all problems */ 183 /* copy all problems */
183 final Calculation winfoProblems = waterlevelData.getReport(); 184 final Calculation winfoProblems = waterlevelData.getReport();
184 final List<Problem> problems2 = winfoProblems.getProblems(); 185 final List<Problem> problems2 = winfoProblems.getProblems();
189 } 190 }
190 return (WQKms[]) waterlevelData.getData(); 191 return (WQKms[]) waterlevelData.getData();
191 } 192 }
192 193
193 /** 194 /**
194 * Determines the discharge state labels for the selected Q or W values 195 * Determines the waterlevel/discharge state labels for the selected Q or W values
195 */ 196 */
196 // FIXME: use WaterlevelDescriptionBuilder instead! 197 private String[] findMainValueLabels(final WQKms[] wqkmsArray, final double[] qs, final WaterlevelDescriptionBuilder descBuilder,
197 private String[] findMainValueLabels(final WQKms[] wqkmsArray, final double[] qs, final Gauge gauge, final Calculation problems) { 198 final Calculation problems) {
198 199
199 final String[] mainValueLabels = new String[wqkmsArray.length]; 200 final String[] mainValueLabels = new String[wqkmsArray.length];
200 if (wqkmsArray.length >= 1) { 201 for (int i = 0; i <= wqkmsArray.length - 1; i++)
201 202 mainValueLabels[i] = descBuilder.getDesc(wqkmsArray[i]);
202 // FIXME
203 // WaterlevelDescriptionBuilder builder = new WaterlevelDescriptionBuilder(artifact, context);
204
205 // Labels like Q=123 or W=123
206 for (int i = 0; i <= wqkmsArray.length - 1; i++) {
207 // FIXME
208 // String label = builder.getDesc(wqkmsArray[i]);
209
210 mainValueLabels[i] = wqkmsArray[i].getName();
211 }
212 // Replace labels for named main Q values
213 final GaugeMainValueFinder zoneFinder = GaugeMainValueFinder.loadValues(MainValueTypeKey.Q, gauge, problems);
214 if ((zoneFinder != null) && (qs != null)) {
215 for (int i = 0; i <= qs.length - 1; i++)
216 mainValueLabels[i] = zoneFinder.findExactZoneName(qs[i], mainValueLabels[i]);
217 }
218 }
219 return mainValueLabels; 203 return mainValueLabels;
220 } 204 }
221 205
222 /** 206 /**
223 * Create a result row for a station and its gauge, and add w-q-values as selected 207 * Create a result row for a station and its gauge, and add w-q-values as selected
224 * 208 *
225 * @param descBuilder 209 * @param descBuilder
226 */ 210 */
227 private ResultRow createRow(final WaterlevelDescriptionBuilder descBuilder, final Double station, final Gauge gauge, final WQKms[] wqkmsArray, 211 private ResultRow createRow(final WaterlevelDescriptionBuilder descBuilder, final Double station, final Gauge gauge, final Gauge firstGauge,
228 final GaugeDurationValuesFinder durationFinder, final int kmIndex) { 212 final WQKms[] wqkmsArray, final GaugeDurationValuesFinder durationFinder, final int kmIndex) {
229 213
230 final ResultRow row = ResultRow.create(); 214 final ResultRow row = ResultRow.create();
231 row.putValue(GeneralResultType.station, station); 215 row.putValue(GeneralResultType.station, station);
232 row.putValue(SInfoResultType.infrastructuretype, null); // is replaced later for an infrastructure 216 row.putValue(SInfoResultType.infrastructuretype, null); // is replaced later for an infrastructure
233 row.putValue(SInfoResultType.floodDuration, Double.NaN); // is replaced later for an infrastructure 217 row.putValue(SInfoResultType.floodDuration, Double.NaN); // is replaced later for an infrastructure
234 218
235 // row.putValue(SInfoResultType.gaugeLabel, gauge.getName()); 219 final String gaugeLabel = this.riverInfoProvider.findGauge(station, (gauge == firstGauge));
236 final String gaugeLabel = this.riverInfoProvider.findGauge(station);
237 row.putValue(SInfoResultType.gaugeLabel, gaugeLabel); 220 row.putValue(SInfoResultType.gaugeLabel, gaugeLabel);
238 221
239 final String location = this.riverInfoProvider.getLocation(station); 222 final String location = this.riverInfoProvider.getLocation(station);
240 row.putValue(SInfoResultType.location, location); 223 row.putValue(SInfoResultType.location, location);
241 224
263 final Map<Gauge, GaugeDurationValuesFinder> durFinders) { 246 final Map<Gauge, GaugeDurationValuesFinder> durFinders) {
264 247
265 final double q = wqFinder.getDischarge(infrastructure.getStation(), infrastructure.getHeight()); 248 final double q = wqFinder.getDischarge(infrastructure.getStation(), infrastructure.getHeight());
266 final double qOut = Double.isInfinite(q) ? Double.NaN : q; 249 final double qOut = Double.isInfinite(q) ? Double.NaN : q;
267 final double dur = underflowDaysToOverflowDays(durFinders.get(gauge).getDuration(q)); 250 final double dur = underflowDaysToOverflowDays(durFinders.get(gauge).getDuration(q));
268 row.putValue(SInfoResultType.riverside, infrastructure.getAttributeKey().getName()); // TODO i18n 251 row.putValue(SInfoResultType.riverside, infrastructure.getAttributeKey());
269 row.putValue(SInfoResultType.floodDuration, dur); 252 row.putValue(SInfoResultType.floodDuration, dur);
270 row.putValue(SInfoResultType.floodDischarge, qOut); 253 row.putValue(SInfoResultType.floodDischarge, qOut);
271 row.putValue(SInfoResultType.infrastructureHeight, infrastructure.getHeight()); 254 row.putValue(SInfoResultType.infrastructureHeight, infrastructure.getHeight());
272 row.putValue(SInfoResultType.infrastructuretype, infrastructure.getInfrastructure().getType().getName()); 255 row.putValue(SInfoResultType.infrastructuretype, infrastructure.getInfrastructure().getType().getName());
273 } 256 }

http://dive4elements.wald.intevation.org