comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java @ 8884:7a8c12706834

Work on SINFO-FlowDepth
author gernotbelger
date Tue, 13 Feb 2018 14:53:23 +0100
parents a536e1aacf0f
children cc86b0f9b3c3
comparison
equal deleted inserted replaced
8883:a536e1aacf0f 8884:7a8c12706834
73 final List<Gauge> gauges = river.determineGauges(from, to); 73 final List<Gauge> gauges = river.determineGauges(from, to);
74 final GaugeIndex gaugeIndex = new GaugeIndex(gauges); 74 final GaugeIndex gaugeIndex = new GaugeIndex(gauges);
75 75
76 final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); 76 final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name());
77 77
78 final FlowDepthCalculationResults results = new FlowDepthCalculationResults(calcModeLabel, user, river, from, 78 final FlowDepthCalculationResults results = new FlowDepthCalculationResults(calcModeLabel, user, river, from, to, useTkh);
79 to, useTkh);
80 79
81 for (final DifferencesPair diffPair : diffPairs) { 80 for (final DifferencesPair diffPair : diffPairs) {
82 final FlowDepthCalculationResult result = calculateResult(river, from, to, diffPair, problems, gaugeIndex); 81 final FlowDepthCalculationResult result = calculateResult(river, from, to, diffPair, problems, gaugeIndex);
83 if (result != null) 82 if (result != null)
84 results.addResult(result); 83 results.addResult(result);
85 } 84 }
86 85
87 return new CalculationResult(results, problems); 86 return new CalculationResult(results, problems);
88 } 87 }
89 88
90 private FlowDepthCalculationResult calculateResult(final River river, final double from, final double to, 89 private FlowDepthCalculationResult calculateResult(final River river, final double from, final double to, final DifferencesPair diffPair,
91 final DifferencesPair diffPair, final Calculation problems, final GaugeIndex gaugeIndex) { 90 final Calculation problems, final GaugeIndex gaugeIndex) {
92 91
93 /* access real input data from database */ 92 /* access real input data from database */
94 final String soundingId = diffPair.getSoundingId(); 93 final String soundingId = diffPair.getSoundingId();
95 final String wstId = diffPair.getWstId(); 94 final String wstId = diffPair.getWstId();
96 95
97 final BedHeight bedHeight = loadBedHeight(soundingId, from, to); 96 final BedHeight bedHeight = loadBedHeight(soundingId, from, to);
98 if (bedHeight == null) { 97 if (bedHeight == null) {
99 final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", 98 final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", soundingId);
100 soundingId);
101 problems.addProblem(message); 99 problems.addProblem(message);
102 return null; 100 return null;
103 } 101 }
104 102
105 /* REMARK: fetch ALL wst kms, because we want to determine the original reference gauge */ 103 /* REMARK: fetch ALL wst kms, because we want to determine the original reference gauge */
106 final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, 104 final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN);
107 Double.NaN);
108 if (waterlevel == null) { 105 if (waterlevel == null) {
109 final String message = Resources.format(this.context.getMeta(), "Failed to access waterlevel with id '{0}'", 106 final String message = Resources.format(this.context.getMeta(), "Failed to access waterlevel with id '{0}'", wstId);
110 wstId);
111 problems.addProblem(message); 107 problems.addProblem(message);
112 return null; 108 return null;
113 } 109 }
114 final WKms wstKms = waterlevel.getWkms(); 110 final WKms wstKms = waterlevel.getWkms();
115 111
119 115
120 checkYearDifference(label, waterlevel, bedHeight, problems); 116 checkYearDifference(label, waterlevel, bedHeight, problems);
121 checkWaterlevelDiscretisation(wstKms, problems); 117 checkWaterlevelDiscretisation(wstKms, problems);
122 118
123 /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */ 119 /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */
124 final String notinrange = Resources.getMsg(this.context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, 120 final String notinrange = Resources.getMsg(this.context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE);
125 CSV_NOT_IN_GAUGE_RANGE);
126 121
127 final Gauge refGauge = waterlevel.findReferenceGauge(river); 122 final Gauge refGauge = waterlevel.findReferenceGauge(river);
128 final String refGaugeName = refGauge == null ? notinrange : refGauge.getName(); 123 final String refGaugeName = refGauge == null ? notinrange : refGauge.getName();
129 124
130 final BedHeightInfo sounding = BedHeightInfo.from(bedHeight); 125 final BedHeightInfo sounding = BedHeightInfo.from(bedHeight);
134 final FlowDepthCalculationResult resultData = new FlowDepthCalculationResult(label, wstInfo, sounding); 129 final FlowDepthCalculationResult resultData = new FlowDepthCalculationResult(label, wstInfo, sounding);
135 130
136 // FIXME: nur prüfen/beschaffen wenn TKH Berechnung aktiv 131 // FIXME: nur prüfen/beschaffen wenn TKH Berechnung aktiv
137 /* Abflusswerte vorhanden? */ 132 /* Abflusswerte vorhanden? */
138 if (!(wstKms instanceof QKms)) { 133 if (!(wstKms instanceof QKms)) {
139 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", 134 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, label);
140 null, label);
141 problems.addProblem(message); 135 problems.addProblem(message);
142 // TODO: keine Berechnung TKH 136 // TODO: keine Berechnung TKH
143 } 137 }
144 138
139 // FIXME
145 // - Sohlbeschaffenheit (D50 Korndurchmesser aus Seddb) 140 // - Sohlbeschaffenheit (D50 Korndurchmesser aus Seddb)
146 // - Abhängig von Peiljahr 141 // - Abhängig von Peiljahr
147 // - kein D50 vorhanden --> Fehler 142 // - kein D50 vorhanden --> Fehler
148 143
144 // FIXME
149 // - Art der Gewässersohle (starr/mobil) 145 // - Art der Gewässersohle (starr/mobil)
150 146
151 final String bedHeightLabel = bedHeight.getDescription(); 147 final String bedHeightLabel = bedHeight.getDescription();
152 final String wstLabel = wstKms.getName(); 148 final String wstLabel = wstKms.getName();
153 149
154 final UnivariateRealFunction wstInterpolator = DoubleUtil.getLinearInterpolator(wstKms.allKms(), 150 final UnivariateRealFunction wstInterpolator = DoubleUtil.getLinearInterpolator(wstKms.allKms(), wstKms.allWs());
155 wstKms.allWs());
156 151
157 // FIXME: sort by station first, but in what direction? 152 // FIXME: sort by station first, but in what direction?
158 final List<BedHeightValue> values = bedHeight.getValues(); 153 final List<BedHeightValue> values = bedHeight.getValues();
159 154
160 final List<BedHeightValue> sortedValues = new ArrayList<>(values); 155 final List<BedHeightValue> sortedValues = new ArrayList<>(values);
193 // REMARK: access the gauge once only during calculation 188 // REMARK: access the gauge once only during calculation
194 final Gauge gauge = findGauge(waterlevel, refGauge, gaugeIndex, km); 189 final Gauge gauge = findGauge(waterlevel, refGauge, gaugeIndex, km);
195 190
196 final String gaugeLabel = gauge == null ? notinrange : gauge.getName(); 191 final String gaugeLabel = gauge == null ? notinrange : gauge.getName();
197 192
198 resultData.addRow(km, flowDepth, flowDepthTkh, tkh, wst, discharge, wstLabel, gaugeLabel, meanBedHeight, 193 resultData.addRow(km, flowDepth, flowDepthTkh, tkh, wst, discharge, wstLabel, gaugeLabel, meanBedHeight, bedHeightLabel, location);
199 bedHeightLabel, location);
200 } 194 }
201 catch (final FunctionEvaluationException e) { 195 catch (final FunctionEvaluationException e) {
202 /* should only happen if out of range */ 196 /* should only happen if out of range */
203 e.printStackTrace(); 197 e.printStackTrace();
204 /* simply ignore */ 198 /* simply ignore */
216 * X ≥ 1998 ± 3 210 * X ≥ 1998 ± 3
217 * 1958 ≤ X < 1998 ± 6 211 * 1958 ≤ X < 1998 ± 6
218 * 1918 ≤ X < 1958 ± 12 212 * 1918 ≤ X < 1958 ± 12
219 * X < 1918 ± 25 213 * X < 1918 ± 25
220 */ 214 */
221 private void checkYearDifference(final String label, final WaterlevelData waterlevel, final BedHeight sounding, 215 private void checkYearDifference(final String label, final WaterlevelData waterlevel, final BedHeight sounding, final Calculation problems) {
222 final Calculation problems) {
223 216
224 final Integer soundingYear = sounding.getYear(); 217 final Integer soundingYear = sounding.getYear();
225 if (soundingYear == null) 218 if (soundingYear == null)
226 return; 219 return;
227 220
231 224
232 final int maxDifference = getMaxDifferenceYears(soundingYear); 225 final int maxDifference = getMaxDifferenceYears(soundingYear);
233 226
234 final int difference = Math.abs(soundingYear - wstYear); 227 final int difference = Math.abs(soundingYear - wstYear);
235 if (difference > maxDifference) { 228 if (difference > maxDifference) {
236 final String message = Resources.getMsg(this.context.getMeta(), 229 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.year_difference", null, label, difference);
237 "sinfo_calc_flow_depth.warning.year_difference", null, label, difference);
238 problems.addProblem(message); 230 problems.addProblem(message);
239 } 231 }
240 } 232 }
241 233
242 private int getMaxDifferenceYears(final int year) { 234 private int getMaxDifferenceYears(final int year) {
252 244
253 /* >= 1998 */ 245 /* >= 1998 */
254 return 3; 246 return 3;
255 } 247 }
256 248
257 private Gauge findGauge(final WaterlevelData waterlevel, final Gauge refGauge, final GaugeIndex gaugeIndex, 249 private Gauge findGauge(final WaterlevelData waterlevel, final Gauge refGauge, final GaugeIndex gaugeIndex, final double km) {
258 final double km) {
259 250
260 // REMARK: using same logic as in WaterlevelExporter here 251 // REMARK: using same logic as in WaterlevelExporter here
261 252
262 final boolean showAllGauges = waterlevel.isShowAllGauges(); 253 final boolean showAllGauges = waterlevel.isShowAllGauges();
263 254
269 260
270 return null; 261 return null;
271 } 262 }
272 263
273 /* Checks if the discretisation of the waterlevel exceeds 1000m */ 264 /* Checks if the discretisation of the waterlevel exceeds 1000m */
265 // FIXME: vermutlich sollten wir diesen check auf den gültigkeitsbereich einschränken
274 private void checkWaterlevelDiscretisation(final WKms wstKms, final Calculation problems) { 266 private void checkWaterlevelDiscretisation(final WKms wstKms, final Calculation problems) {
275 final int size = wstKms.size(); 267 final int size = wstKms.size();
276 for (int i = 0; i < size - 2; i++) { 268 for (int i = 0; i < size - 2; i++) {
277 final double kmPrev = wstKms.getKm(i); 269 final double kmPrev = wstKms.getKm(i);
278 final double kmNext = wstKms.getKm(i + 1); 270 final double kmNext = wstKms.getKm(i + 1);
279 271
280 if (Math.abs(kmPrev - kmNext) > 1) { 272 if (Math.abs(kmPrev - kmNext) > 1) {
281 final String label = wstKms.getName(); 273 final String label = wstKms.getName();
282 274
283 final String message = Resources.getMsg(this.context.getMeta(), 275 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.waterlevel_discretisation", null, label);
284 "sinfo_calc_flow_depth.warning.waterlevel_discretisation", null, label);
285 problems.addProblem(kmPrev, message); 276 problems.addProblem(kmPrev, message);
286 } 277 }
287 } 278 }
288 } 279 }
289 280

http://dive4elements.wald.intevation.org