Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java @ 9620:26e113e8224f
Nachtrag Pos. 20: flood duration calculation for multiple infrastructure groups/types,
local class FloodDurationCalculationResult.Infrastructure renamed and extracted into own class
author | mschaefer |
---|---|
date | Thu, 10 Oct 2019 17:11:54 +0200 |
parents | d889ffe2fb05 |
children | 07f02019065e |
comparison
equal
deleted
inserted
replaced
9619:63bbd5e45839 | 9620:26e113e8224f |
---|---|
31 import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; | 31 import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; |
32 import org.dive4elements.river.artifacts.model.WstValueTableFactory; | 32 import org.dive4elements.river.artifacts.model.WstValueTableFactory; |
33 import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; | 33 import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; |
34 import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder; | 34 import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder; |
35 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; | 35 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; |
36 import org.dive4elements.river.artifacts.sinfo.flood_duration.FloodDurationCalculationResult.Infrastructure; | |
37 import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey; | |
38 import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; | 36 import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; |
39 import org.dive4elements.river.model.Attribute.AttributeKey; | 37 import org.dive4elements.river.model.Attribute.AttributeKey; |
40 import org.dive4elements.river.model.Gauge; | 38 import org.dive4elements.river.model.Gauge; |
41 import org.dive4elements.river.model.sinfo.InfrastructureValue; | 39 import org.dive4elements.river.model.sinfo.InfrastructureValue; |
42 | 40 |
52 | 50 |
53 private final List<ResultRow> rows = new ArrayList<>(); | 51 private final List<ResultRow> rows = new ArrayList<>(); |
54 | 52 |
55 private final RiverInfoProvider riverInfoProvider; | 53 private final RiverInfoProvider riverInfoProvider; |
56 private RiverInfoProvider riverInfoProvider2; | 54 private RiverInfoProvider riverInfoProvider2; |
55 private final Map<Double, List<InfrastructureValue>> stationInfras; | |
57 | 56 |
58 private final CallContext context; | 57 private final CallContext context; |
59 | 58 |
60 public FloodDurationCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) { | 59 public FloodDurationCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) { |
61 this.context = context; | 60 this.context = context; |
62 this.riverInfoProvider = riverInfoProvider; | 61 this.riverInfoProvider = riverInfoProvider; |
63 this.riverInfoProvider2 = null; | 62 this.riverInfoProvider2 = null; |
63 this.stationInfras = new HashMap<>(); | |
64 } | 64 } |
65 | 65 |
66 /** | 66 /** |
67 * Calculate the infrastructures flood duration result rows | 67 * Calculate the infrastructures flood duration result rows |
68 */ | 68 */ |
69 public void execute(final Calculation problems, final String label, final DoubleRange calcRange, final RiversideChoiceKey riverside, | 69 public void execute(final Calculation problems, final String label, final DoubleRange calcRange, final AttributeKey riverside, |
70 final Set<Infrastructure> infrastruktureKey, final boolean withWspl, final WINFOArtifact winfo, final FloodDurationCalculationResults results) { | 70 final Set<String> infrastructureChoices, final boolean withWspl, final WINFOArtifact winfo, final FloodDurationCalculationResults results) { |
71 | |
72 // FIXME Schäfer: | |
73 // filter by infrastructureKey | |
74 // FIXME: Tironi: api gscheit benennen; | |
75 // Lösung finden für: Infrastructure enthält riverside, wird hier aber nicht benötigt (weil schon im choice) | |
76 | 71 |
77 // Find all gauges of the calc range, and create the duration finders | 72 // Find all gauges of the calc range, and create the duration finders |
78 final Map<Gauge, GaugeDurationValuesFinder> durFinders = new HashMap<>(); | 73 final Map<Gauge, GaugeDurationValuesFinder> durFinders = new HashMap<>(); |
79 for (final Gauge gauge : this.riverInfoProvider.getGauges()) { | 74 for (final Gauge gauge : this.riverInfoProvider.getGauges()) { |
80 durFinders.put(gauge, GaugeDurationValuesFinder.loadValues(gauge, problems)); | 75 durFinders.put(gauge, GaugeDurationValuesFinder.loadValues(gauge, problems)); |
81 } | 76 } |
82 | 77 |
83 // Find all infrastructures within the calc range | 78 // Find all infrastructures within the calc range |
84 final AttributeKey bankKey = riverside.getAttributeKey(); | |
85 final List<InfrastructureValue> infras = InfrastructureValue.getValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(), | 79 final List<InfrastructureValue> infras = InfrastructureValue.getValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(), |
86 calcRange.getMaximumDouble(), bankKey); | 80 calcRange.getMaximumDouble(), riverside, infrastructureChoices); |
87 | 81 |
88 // Merge all stations (range/step, borders of gauge ranges, infrastructures) | 82 // Merge all stations (range/step, borders of gauge ranges, infrastructures) |
89 final Map<Double, InfrastructureValue> allStations = new HashMap<>(); | 83 // final Map<Double, InfrastructureValue> allStations = new HashMap<>(); |
90 final Map<Double, InfrastructureValue> secondBank = new HashMap<>(); // any second infrastructure in case of both-banks-option | 84 this.stationInfras.clear(); |
91 addRangeStations(allStations, winfo); | 85 // final Map<Double, InfrastructureValue> secondBank = new HashMap<>(); // any second infrastructure in case of |
92 addGaugeLimits(allStations, durFinders.keySet(), calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); | 86 // both-banks-option |
93 addInfrastructures(allStations, secondBank, infras); | 87 addRangeStations(winfo); |
94 final double[] stationsSorted = sortStations(allStations.keySet()); | 88 addGaugeLimits(durFinders.keySet(), calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); |
89 addInfrastructures(infras); | |
90 final double[] stationsSorted = sortStations(this.stationInfras.keySet()); | |
95 | 91 |
96 // Calculate W and Q for all stations and the selected discharge states/waterlevels | 92 // Calculate W and Q for all stations and the selected discharge states/waterlevels |
97 final WQKms[] wqkmsArray = calculateWsts(winfo, withWspl, stationsSorted, problems); | 93 final WQKms[] wqkmsArray = calculateWsts(winfo, withWspl, stationsSorted, problems); |
98 // final WaterlevelData waterlevel = new WaterlevelData(wqkmsArray[0], -1, false, true); | 94 // final WaterlevelData waterlevel = new WaterlevelData(wqkmsArray[0], -1, false, true); |
99 // this.riverInfoProvider2 = this.riverInfoProvider.forWaterlevel(waterlevel); | 95 // this.riverInfoProvider2 = this.riverInfoProvider.forWaterlevel(waterlevel); |
109 | 105 |
110 // Load base wst table (river).wst | 106 // Load base wst table (river).wst |
111 // (should be in cache since already used in calculateWaterlevels (winfo.computeWaterlevelData) | 107 // (should be in cache since already used in calculateWaterlevels (winfo.computeWaterlevelData) |
112 final WstValueTable wst = WstValueTableFactory.getTable(this.riverInfoProvider2.getRiver()); | 108 final WstValueTable wst = WstValueTableFactory.getTable(this.riverInfoProvider2.getRiver()); |
113 | 109 |
114 final Set<FloodDurationCalculationResult.Infrastructure> infrastructures = new HashSet<>(); | 110 final Set<FloodDurationInfrastructureChoice> infrastructures = new HashSet<>(); |
115 | 111 |
116 // Create the result rows, and calculate and add the flood durations etc. | 112 // Create the result rows, and calculate and add the flood durations etc. |
117 for (int i = 0; i <= stationsSorted.length - 1; i++) { | 113 for (int i = 0; i <= stationsSorted.length - 1; i++) { |
118 final Gauge gauge = this.riverInfoProvider2.getGauge(stationsSorted[i], true); | 114 final Gauge gauge = this.riverInfoProvider2.getGauge(stationsSorted[i], true); |
119 final ResultRow row = createRow(stationsSorted[i], wqkmsArray, gaugeWstDurations.get(gauge), i); | 115 if (this.stationInfras.containsKey(stationsSorted[i])) { |
120 if (allStations.containsKey(stationsSorted[i]) && (allStations.get(stationsSorted[i]) != null)) | 116 for (final InfrastructureValue infra : this.stationInfras.get(stationsSorted[i])) { |
121 calculateInfrastructure(row, gauge, allStations.get(stationsSorted[i]), wst, durFinders, infrastructures); | 117 final ResultRow row = createRow(stationsSorted[i], wqkmsArray, gaugeWstDurations.get(gauge), i); |
122 | 118 calculateInfrastructure(row, gauge, infra, wst, durFinders, infrastructures); |
123 this.rows.add(row); | 119 this.rows.add(row); |
124 if (secondBank.containsKey(stationsSorted[i])) { | 120 } |
125 final ResultRow row2 = ResultRow.create(row); | |
126 calculateInfrastructure(row2, gauge, secondBank.get(stationsSorted[i]), wst, durFinders, infrastructures); | |
127 this.rows.add(row2); | |
128 } | 121 } |
129 | |
130 } | 122 } |
131 | 123 |
132 // Get the labels of the selected waterlevels | 124 // Get the labels of the selected waterlevels |
133 final String[] wstLabels = new String[wqkmsArray.length]; | 125 final String[] wstLabels = new String[wqkmsArray.length]; |
134 for (int i = 0; i <= wqkmsArray.length - 1; i++) | 126 for (int i = 0; i <= wqkmsArray.length - 1; i++) |
156 } | 148 } |
157 | 149 |
158 /** | 150 /** |
159 * Adds to a stations map all stations corresponding to the active range and step | 151 * Adds to a stations map all stations corresponding to the active range and step |
160 */ | 152 */ |
161 private void addRangeStations(final Map<Double, InfrastructureValue> allStations, final WINFOArtifact winfo) { | 153 private void addRangeStations(final WINFOArtifact winfo) { |
162 for (final double station : new ComputationRangeAccess(winfo).getKms()) | 154 for (final double station : new ComputationRangeAccess(winfo).getKms()) |
163 allStations.put(Double.valueOf(station), null); | 155 this.stationInfras.put(Double.valueOf(station), new ArrayList<InfrastructureValue>()); |
164 } | 156 } |
165 | 157 |
166 /** | 158 /** |
167 * Adds to a stations map all range limits of the gauges within the calc range | 159 * Adds to a stations map all range limits of the gauges within the calc range |
168 */ | 160 */ |
169 private void addGaugeLimits(final Map<Double, InfrastructureValue> allStations, final Set<Gauge> gauges, final double fromKm, final double toKm) { | 161 private void addGaugeLimits(final Set<Gauge> gauges, final double fromKm, final double toKm) { |
170 for (final Gauge gauge : gauges) { | 162 for (final Gauge gauge : gauges) { |
171 final Double kmA = Double.valueOf(gauge.getRange().getA().doubleValue()); | 163 final Double kmA = Double.valueOf(gauge.getRange().getA().doubleValue()); |
172 final Double kmB = Double.valueOf(gauge.getRange().getB().doubleValue()); | 164 final Double kmB = Double.valueOf(gauge.getRange().getB().doubleValue()); |
173 if (kmA > fromKm - 0.0001) | 165 if (kmA > fromKm - 0.0001) |
174 allStations.put(kmA, null); | 166 this.stationInfras.put(kmA, new ArrayList<InfrastructureValue>()); |
175 if (kmB < toKm + 0.0001) | 167 if (kmB < toKm + 0.0001) |
176 allStations.put(kmB, null); | 168 this.stationInfras.put(kmB, new ArrayList<InfrastructureValue>()); |
177 } | 169 } |
178 } | 170 } |
179 | 171 |
180 /** | 172 /** |
181 * Adds to a stations map all (first) infrastructures of a station, and the second, if any, to another map | 173 * Adds all infrastructures of a station to the station map |
182 */ | 174 */ |
183 private void addInfrastructures(final Map<Double, InfrastructureValue> allStations, final Map<Double, InfrastructureValue> secondBank, | 175 private void addInfrastructures(final List<InfrastructureValue> infrastructures) { |
184 final List<InfrastructureValue> infrastructures) { | |
185 for (final InfrastructureValue infrastructure : infrastructures) { | 176 for (final InfrastructureValue infrastructure : infrastructures) { |
186 final Double station = infrastructure.getStation(); | 177 final Double station = infrastructure.getStation(); |
187 if (!allStations.containsKey(station) || !(allStations.get(station) instanceof InfrastructureValue)) | 178 if (this.stationInfras.containsKey(station)) |
188 allStations.put(station, infrastructure); | 179 this.stationInfras.get(station).add(infrastructure); |
189 else | |
190 secondBank.put(station, infrastructure); | |
191 } | 180 } |
192 } | 181 } |
193 | 182 |
194 /** | 183 /** |
195 * Returns a double array with a sorted stations set | 184 * Returns a double array with a sorted stations set |
310 | 299 |
311 /** | 300 /** |
312 * Calculate the result row fields for one infrastructure | 301 * Calculate the result row fields for one infrastructure |
313 */ | 302 */ |
314 private void calculateInfrastructure(final ResultRow row, final Gauge gauge, final InfrastructureValue infrastructure, final WstValueTable wst, | 303 private void calculateInfrastructure(final ResultRow row, final Gauge gauge, final InfrastructureValue infrastructure, final WstValueTable wst, |
315 final Map<Gauge, GaugeDurationValuesFinder> durFinders, final Set<Infrastructure> infrastructures) { | 304 final Map<Gauge, GaugeDurationValuesFinder> durFinders, final Set<FloodDurationInfrastructureChoice> infrastructures) { |
316 | 305 |
317 // Interpolate the infrastructure height in the wst table to get the corresponding Q | 306 // Interpolate the infrastructure height in the wst table to get the corresponding Q |
318 final Calculation problems = new Calculation(); | 307 final Calculation problems = new Calculation(); |
319 final double[] qs = wst.findQsForW(infrastructure.getStation().doubleValue(), infrastructure.getHeight().doubleValue(), problems); | 308 final double[] qs = wst.findQsForW(infrastructure.getStation().doubleValue(), infrastructure.getHeight().doubleValue(), problems); |
320 // TODO Fehlerbehandlung (kein Q gefunden) | 309 // TODO Fehlerbehandlung (kein Q gefunden) |
326 row.putValue(SInfoResultType.infrastructuregroup, infrastructure.getInfrastructure().getGroup().getName()); | 315 row.putValue(SInfoResultType.infrastructuregroup, infrastructure.getInfrastructure().getGroup().getName()); |
327 row.putValue(SInfoResultType.infrastructuretype, infrastructure.getInfrastructure().getType().getName()); | 316 row.putValue(SInfoResultType.infrastructuretype, infrastructure.getInfrastructure().getType().getName()); |
328 | 317 |
329 // Determine the relative column position of the Q of the infrastructure height | 318 // Determine the relative column position of the Q of the infrastructure height |
330 final QPosition qPos = wst.getQPosition(infrastructure.getStation().doubleValue(), q); | 319 final QPosition qPos = wst.getQPosition(infrastructure.getStation().doubleValue(), q); |
331 if (qPos == null) | 320 if (qPos != null) { |
332 return; | 321 // Get the Q for the found column position for the station of the gauge |
333 // Get the Q for the found column position for the station of the gauge | 322 final double qGauge = wst.getQ(qPos, gauge.getStation().doubleValue()); |
334 final double qGauge = wst.getQ(qPos, gauge.getStation().doubleValue()); | 323 // Interpolate the Q-D-table of the gauge |
335 // Interpolate the Q-D-table of the gauge | 324 final double dur = underflowDaysToOverflowDays(durFinders.get(gauge).getDuration(qGauge)); |
336 final double dur = underflowDaysToOverflowDays(durFinders.get(gauge).getDuration(qGauge)); | 325 // Set D in the result row |
337 // Set D in the result row | 326 row.putValue(SInfoResultType.floodDuration, dur); |
338 row.putValue(SInfoResultType.floodDuration, dur); | 327 } |
339 | 328 final FloodDurationInfrastructureChoice groupType = new FloodDurationInfrastructureChoice(row); |
340 final FloodDurationCalculationResult.Infrastructure groupType = new FloodDurationCalculationResult.Infrastructure(row); | |
341 infrastructures.add(groupType); | 329 infrastructures.add(groupType); |
342 } | 330 } |
343 | 331 |
344 /** | 332 /** |
345 * Translates underflow duration into overflow duration | 333 * Translates underflow duration into overflow duration |