Mercurial > dive4elements > river
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 } |