Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java @ 9598:17414e70746e
Softwaretests...20181219 10.1/10.2/10.5/10.9: corrected computation of missing volume and excavation volume, date range for density queries as in Sinfo/Tkh, empty values instead of 0 if computation not possible
author | mschaefer |
---|---|
date | Tue, 05 Feb 2019 15:51:35 +0100 |
parents | c57caff9b00b |
children | 4c73fe16533d |
comparison
equal
deleted
inserted
replaced
9597:5395c6d4ca50 | 9598:17414e70746e |
---|---|
9 */ | 9 */ |
10 | 10 |
11 package org.dive4elements.river.artifacts.bundu.bezugswst; | 11 package org.dive4elements.river.artifacts.bundu.bezugswst; |
12 | 12 |
13 import java.util.ArrayList; | 13 import java.util.ArrayList; |
14 import java.util.Calendar; | |
15 import java.util.List; | 14 import java.util.List; |
16 | 15 |
17 import org.dive4elements.artifacts.CallContext; | 16 import org.dive4elements.artifacts.CallContext; |
18 import org.dive4elements.river.artifacts.access.FixRealizingAccess; | 17 import org.dive4elements.river.artifacts.access.FixRealizingAccess; |
19 import org.dive4elements.river.artifacts.bundu.BUNDUArtifact; | 18 import org.dive4elements.river.artifacts.bundu.BUNDUArtifact; |
22 import org.dive4elements.river.artifacts.common.GeneralResultType; | 21 import org.dive4elements.river.artifacts.common.GeneralResultType; |
23 import org.dive4elements.river.artifacts.common.ResultRow; | 22 import org.dive4elements.river.artifacts.common.ResultRow; |
24 import org.dive4elements.river.artifacts.model.Calculation; | 23 import org.dive4elements.river.artifacts.model.Calculation; |
25 import org.dive4elements.river.artifacts.model.Calculation.Problem; | 24 import org.dive4elements.river.artifacts.model.Calculation.Problem; |
26 import org.dive4elements.river.artifacts.model.CalculationResult; | 25 import org.dive4elements.river.artifacts.model.CalculationResult; |
26 import org.dive4elements.river.artifacts.model.DateRange; | |
27 import org.dive4elements.river.artifacts.model.WQKms; | 27 import org.dive4elements.river.artifacts.model.WQKms; |
28 import org.dive4elements.river.artifacts.model.fixings.FixRealizingCalculation; | 28 import org.dive4elements.river.artifacts.model.fixings.FixRealizingCalculation; |
29 import org.dive4elements.river.artifacts.model.fixings.FixRealizingResult; | 29 import org.dive4elements.river.artifacts.model.fixings.FixRealizingResult; |
30 import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; | 30 import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; |
31 import org.dive4elements.river.artifacts.resources.Resources; | 31 import org.dive4elements.river.artifacts.resources.Resources; |
32 import org.dive4elements.river.artifacts.services.DynamicMainValuesTimeRangeDeterminationService; | 32 import org.dive4elements.river.artifacts.services.DynamicMainValuesTimeRangeDeterminationService; |
33 import org.dive4elements.river.artifacts.services.DynamicMainValuesTimeRangeDeterminationService.GaugeInfoResult; | 33 import org.dive4elements.river.artifacts.services.DynamicMainValuesTimeRangeDeterminationService.GaugeInfoResult; |
34 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; | 34 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; |
35 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedQualityD50TimeRangeConfig; | |
35 import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; | 36 import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; |
36 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; | 37 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; |
37 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; | 38 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; |
38 import org.dive4elements.river.artifacts.sinfo.util.WstInfo; | 39 import org.dive4elements.river.artifacts.sinfo.util.WstInfo; |
39 import org.dive4elements.river.artifacts.states.WaterlevelData; | 40 import org.dive4elements.river.artifacts.states.WaterlevelData; |
53 | 54 |
54 /** | 55 /** |
55 * Excavation costs (euro) per cubic meter | 56 * Excavation costs (euro) per cubic meter |
56 */ | 57 */ |
57 private final static double EXPENSE_PER_CBM = 12.0; // REMARK Sollte von außen einstellbar sein | 58 private final static double EXPENSE_PER_CBM = 12.0; // REMARK Sollte von außen einstellbar sein |
59 | |
60 private final static double KM_TO_M = 1000.0; | |
58 | 61 |
59 private final CallContext context; | 62 private final CallContext context; |
60 | 63 |
61 private final List<ResultRow> rows; | 64 private final List<ResultRow> rows; |
62 | 65 |
114 final RiverInfoProvider riverInfoProvider2 = riverInfoProvider.forWaterlevel(waterlevel); | 117 final RiverInfoProvider riverInfoProvider2 = riverInfoProvider.forWaterlevel(waterlevel); |
115 final WstInfo wstInfo = new WstInfo(wqkms.getName(), 0, riverInfoProvider2.getReferenceGauge(), true); | 118 final WstInfo wstInfo = new WstInfo(wqkms.getName(), 0, riverInfoProvider2.getReferenceGauge(), true); |
116 | 119 |
117 // Fetch the bed levels of the selected sounding | 120 // Fetch the bed levels of the selected sounding |
118 final Integer bedHeightId = access.getBedHeightID(); | 121 final Integer bedHeightId = access.getBedHeightID(); |
119 final BedHeightsFinder bedHeightsFinder = (bedHeightId != null) ? BedHeightsFinder.forId(problems, bedHeightId, access.getRange()) | 122 final BedHeightsFinder bedHeightsFinder = (bedHeightId != null) ? BedHeightsFinder.forId(problems, bedHeightId, access.getRange(), false) |
120 : BedHeightsFinder.NullFinder(); | 123 : BedHeightsFinder.NullFinder(); |
121 | 124 |
122 // Fetch the river channel data | 125 // Fetch the river channel data |
123 final ChannelFinder channelFinder = ChannelFinder.loadValues(problems, river, access.getBezugsJahr()); | 126 final ChannelFinder channelFinder = ChannelFinder.loadValues(problems, river, access.getBezugsJahr()); |
124 if (channelFinder == null) | 127 if (channelFinder == null) |
133 if (access.isCalculateMissingVolume()) { | 136 if (access.isCalculateMissingVolume()) { |
134 if ((bedHeightsFinder == null) || bedHeightsFinder.isNull()) | 137 if ((bedHeightsFinder == null) || bedHeightsFinder.isNull()) |
135 return new CalculationResult(results, problems); | 138 return new CalculationResult(results, problems); |
136 computeMissingVolumes(problems); | 139 computeMissingVolumes(problems); |
137 final BedQualityCalculator bqCalculator = computeDensities(problems, bunduartifact, access, river); | 140 final BedQualityCalculator bqCalculator = computeDensities(problems, bunduartifact, access, river); |
138 computeMissingMasses(problems, bqCalculator); | 141 if (bqCalculator != null) |
142 computeMissingMasses(problems, bqCalculator); | |
139 } | 143 } |
140 | 144 |
141 // Add the result to the results collection | 145 // Add the result to the results collection |
142 final WaterlevelDescriptionBuilder descBuilder = new WaterlevelDescriptionBuilder(winfo, this.context); | 146 final WaterlevelDescriptionBuilder descBuilder = new WaterlevelDescriptionBuilder(winfo, this.context); |
143 final String qtext = descBuilder.getMetadataQ(); | 147 final String qtext = descBuilder.getMetadataQ(); |
223 channelHeight = Double.NaN; | 227 channelHeight = Double.NaN; |
224 row.putValue(BunduResultType.channelLowerEdge, channelHeight); | 228 row.putValue(BunduResultType.channelLowerEdge, channelHeight); |
225 final double channelWidth = channelFinder.getWidth(station); | 229 final double channelWidth = channelFinder.getWidth(station); |
226 row.putValue(BunduResultType.channelWidth, channelWidth); | 230 row.putValue(BunduResultType.channelWidth, channelWidth); |
227 if (!Double.isNaN(channelHeight)) { | 231 if (!Double.isNaN(channelHeight)) { |
228 if (msh > channelHeight + 0.001) | 232 if (Double.isNaN(msh)) |
233 row.putValue(BunduResultType.missDepthMeanBed, Double.NaN); | |
234 else if (msh > channelHeight + 0.001) | |
229 row.putValue(BunduResultType.missDepthMeanBed, msh - channelHeight); | 235 row.putValue(BunduResultType.missDepthMeanBed, msh - channelHeight); |
230 else | 236 else |
231 row.putValue(BunduResultType.missDepthMeanBed, 0.0); | 237 row.putValue(BunduResultType.missDepthMeanBed, 0.0); |
232 } | 238 } |
233 | 239 |
240 int missFieldCnt = 0; | 246 int missFieldCnt = 0; |
241 for (int i = BedHeightValueType.FIELD_FIRST_INDEX; i <= BedHeightValueType.FIELD_LAST_INDEX; i++) { | 247 for (int i = BedHeightValueType.FIELD_FIRST_INDEX; i <= BedHeightValueType.FIELD_LAST_INDEX; i++) { |
242 final double h = bedHeightsFinder.getFieldHeight(station, i); | 248 final double h = bedHeightsFinder.getFieldHeight(station, i); |
243 fieldHeights.add(Double.valueOf(h)); | 249 fieldHeights.add(Double.valueOf(h)); |
244 fieldDepths.add(Double.valueOf(w - h)); | 250 fieldDepths.add(Double.valueOf(w - h)); |
245 if (h > channelHeight + 0.001) { | 251 if (Double.isNaN(h)) { |
252 fieldMissDepths.add(Double.NaN); | |
253 fieldMissWidths.add(Double.NaN); | |
254 } | |
255 else if (h > channelHeight + 0.001) { | |
246 missFieldCnt++; | 256 missFieldCnt++; |
247 fieldMissDepths.add(Double.valueOf(h - channelHeight)); | 257 fieldMissDepths.add(Double.valueOf(h - channelHeight)); |
248 fieldMissWidths.add(Double.valueOf(channelWidth / BedHeightValueType.FIELD_LAST_INDEX)); | 258 fieldMissWidths.add(Double.valueOf(channelWidth / BedHeightValueType.FIELD_LAST_INDEX)); |
249 } else { | 259 } else { |
250 fieldMissDepths.add(Double.valueOf(0.0)); | 260 fieldMissDepths.add(Double.valueOf(0.0)); |
251 fieldMissWidths.add(Double.valueOf(0.0)); | 261 fieldMissWidths.add(Double.valueOf(0.0)); |
252 } | 262 } |
253 fieldNulls.add(Double.NaN); | 263 fieldNulls.add(Double.NaN); |
254 } | 264 } |
255 if (isKmInMissingVolumeRange(station)) { | 265 if (!Double.isNaN(msh) && isKmInMissingVolumeRange(station)) { |
256 row.putValue(BunduResultType.missDepthFields, fieldMissDepths); | 266 row.putValue(BunduResultType.missDepthFields, fieldMissDepths); |
257 row.putValue(BunduResultType.missWidthFields, fieldMissWidths); | 267 row.putValue(BunduResultType.missWidthFields, fieldMissWidths); |
258 row.putValue(BunduResultType.hasMissingDepth, (missFieldCnt >= 1)); | 268 row.putValue(BunduResultType.hasMissingDepth, (missFieldCnt >= 1)); |
259 } else { | 269 } else { |
260 row.putValue(BunduResultType.missDepthFields, fieldNulls); | 270 row.putValue(BunduResultType.missDepthFields, fieldNulls); |
301 km = this.rows.get(i).getDoubleValue(GeneralResultType.station); | 311 km = this.rows.get(i).getDoubleValue(GeneralResultType.station); |
302 if (!isKmInMissingVolumeRange(km)) | 312 if (!isKmInMissingVolumeRange(km)) |
303 break; | 313 break; |
304 if (km > this.missKmTo.doubleValue() - 0.0001) | 314 if (km > this.missKmTo.doubleValue() - 0.0001) |
305 last = i; | 315 last = i; |
316 if (this.rows.get(i).getValue(BunduResultType.hasMissingDepth) == null) | |
317 continue; | |
318 final double chDepth = this.rows.get(i).getDoubleValue(BunduResultType.channelDepth) + EXCAVATION_DEPTH; | |
306 final List<Double> areas = new ArrayList<>(); | 319 final List<Double> areas = new ArrayList<>(); |
307 final List<Double> volumes = new ArrayList<>(); | 320 final List<Double> volumes = new ArrayList<>(); |
308 double vTotal = 0.0; | 321 double vTotal = 0.0; |
309 double vExcav = 0.0; | 322 double vExcav = 0.0; |
310 for (int j = BedHeightValueType.FIELD_FIRST_INDEX; j <= BedHeightValueType.FIELD_LAST_INDEX; j++) { | 323 for (int j = BedHeightValueType.FIELD_FIRST_INDEX; j <= BedHeightValueType.FIELD_LAST_INDEX; j++) { |
311 if (getFieldValue(i, BunduResultType.missDepthFields, j) > 0.0001) { | 324 if (getFieldValue(i, BunduResultType.missDepthFields, j) > 0.0001) { |
312 computeMissingVolume(volumes, areas, i, first, last, j); | 325 computeMissingVolume(volumes, areas, i, first, last, j, ActualMissingHeightComputer.Instance); |
313 vTotal += volumes.get(j - 1); | 326 vTotal += volumes.get(j - 1); |
314 vExcav += volumes.get(j - 1) + areas.get(j - 1) * EXCAVATION_DEPTH; | |
315 } else { | 327 } else { |
316 volumes.add(Double.valueOf(0.0)); | 328 volumes.add(Double.valueOf(0.0)); |
317 areas.add(Double.valueOf(0.0)); | 329 areas.add(Double.valueOf(0.0)); |
330 } | |
331 if (chDepth - getFieldValue(i, BunduResultType.depthFields, j) > 0.0001) { | |
332 vExcav += computeMissingVolume(null, null, i, first, last, j, ExcavationMissingAreaComputer.Instance); | |
318 } | 333 } |
319 } | 334 } |
320 final double[] meanBedVolumeArea = computeMeanBedMissingAreaAndVolume(i, first, last); | 335 final double[] meanBedVolumeArea = computeMeanBedMissingAreaAndVolume(i, first, last); |
321 this.rows.get(i).putValue(BunduResultType.missVolumeMeanBed, meanBedVolumeArea[0]); | 336 this.rows.get(i).putValue(BunduResultType.missVolumeMeanBed, meanBedVolumeArea[0]); |
322 this.rows.get(i).putValue(BunduResultType.missAreaMeanBed, meanBedVolumeArea[1]); | 337 this.rows.get(i).putValue(BunduResultType.missAreaMeanBed, meanBedVolumeArea[1]); |
329 } | 344 } |
330 | 345 |
331 /** | 346 /** |
332 * Computes the missing volume of a field of a km row | 347 * Computes the missing volume of a field of a km row |
333 */ | 348 */ |
334 private void computeMissingVolume(final List<Double> volumes, final List<Double> areas, final int current, final int first, final int last, | 349 private double computeMissingVolume(final List<Double> volumes, final List<Double> areas, final int current, final int first, final int last, |
335 final int field) { | 350 final int field, final MissingHeightComputer heightcomputer) { |
336 | 351 |
337 final double areaCurr = missingArea(current, first, last, field); | 352 final double dhCurr = heightcomputer.missingHeight(this.rows.get(current), current, first, last, field); |
338 final double areaPrev = missingArea(current - 1, first, last, field); | 353 final double dhPrev = heightcomputer.missingHeight(this.rows.get(current - 1), current - 1, first, last, field); |
339 final double areaNext = missingArea(current + 1, first, last, field); | 354 final double dhNext = heightcomputer.missingHeight(this.rows.get(current + 1), current + 1, first, last, field); |
340 final double kmCurr = missingKm(current); | 355 final double kmCurr = missingKm(current); |
341 final double kmPrev = missingKm(current - 1); | 356 final double kmPrev = missingKm(current - 1); |
342 final double kmNext = missingKm(current + 1); | 357 final double kmNext = missingKm(current + 1); |
343 final double area1 = Double.isNaN(kmPrev) ? 0.0 : 0.5 * (areaCurr + areaPrev); | 358 final double width = getFieldValue(current, BunduResultType.missWidthFields, field); |
344 final double area2 = Double.isNaN(kmNext) ? 0.0 : 0.5 * (areaCurr + areaNext); | 359 final double area1 = Double.isNaN(kmPrev) ? 0.0 : (0.25 * dhPrev + 0.75 * dhCurr) * width; |
345 final double volume = Double.valueOf((Math.abs(kmCurr - kmPrev) * 500 * area1) + (Math.abs(kmNext - kmCurr) * 500 * area2)); | 360 final double area2 = Double.isNaN(kmNext) ? 0.0 : (0.75 * dhCurr + 0.25 * dhNext) * width; |
346 volumes.add(volume); | 361 final double volume = Double.valueOf((Math.abs(kmCurr - kmPrev) * KM_TO_M / 2 * area1) + (Math.abs(kmNext - kmCurr) * KM_TO_M / 2 * area2)); |
347 if (!Double.isNaN(volume)) | 362 if (volumes != null) |
348 areas.add(Double.valueOf(area1 + area2)); | 363 volumes.add(volume); |
349 else | 364 if (areas != null) { |
350 areas.add(Double.NaN); | 365 if (!Double.isNaN(volume)) |
351 } | 366 areas.add(Double.valueOf(area1 + area2)); |
352 | 367 else |
353 /** | 368 areas.add(Double.NaN); |
354 * Gets the missing area of a field and a row if in range, otherwise 0.0 | 369 } |
355 */ | 370 return volume; |
356 private double missingArea(final int rowIndex, final int first, final int last, final int fieldIndex) { | 371 } |
357 if ((first <= rowIndex) && (rowIndex <= last)) | 372 |
358 return getFieldValue(rowIndex, BunduResultType.missDepthFields, fieldIndex) * getFieldValue(rowIndex, BunduResultType.missWidthFields, fieldIndex); | 373 /** |
359 else | 374 * Interface for the function that computes the missing height of a field |
360 return 0.0; | 375 */ |
376 private interface MissingHeightComputer { | |
377 /** | |
378 * Gets the missing area of a field and a row if in range, otherwise 0.0 | |
379 */ | |
380 double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex); | |
381 } | |
382 | |
383 /** | |
384 * Computation of the actual missing height of a field | |
385 */ | |
386 private static class ActualMissingHeightComputer implements MissingHeightComputer { | |
387 public static MissingHeightComputer Instance = new ActualMissingHeightComputer(); | |
388 | |
389 /** | |
390 * Gets the missing height of a field and a row if in range, otherwise 0.0 | |
391 */ | |
392 @SuppressWarnings("unchecked") | |
393 @Override | |
394 public double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex) { | |
395 if ((first <= rowIndex) && (rowIndex <= last)) { | |
396 return ((List<Double>) row.getValue(BunduResultType.missDepthFields)).get(fieldIndex - 1).doubleValue(); | |
397 } | |
398 else | |
399 return 0.0; | |
400 } | |
401 } | |
402 | |
403 /** | |
404 * Computation of the excavation height of a field | |
405 */ | |
406 private static class ExcavationMissingAreaComputer implements MissingHeightComputer { | |
407 public static MissingHeightComputer Instance = new ExcavationMissingAreaComputer(); | |
408 | |
409 /** | |
410 * Gets the excavation height of a field and a row if in range, otherwise 0.0 | |
411 */ | |
412 @SuppressWarnings("unchecked") | |
413 @Override | |
414 public double missingHeight(final ResultRow row, final int rowIndex, final int first, final int last, final int fieldIndex) { | |
415 if ((first <= rowIndex) && (rowIndex <= last)) { | |
416 final double channeldepth = row.getDoubleValue(BunduResultType.channelDepth) + EXCAVATION_DEPTH; | |
417 final double fielddepth = ((List<Double>) row.getValue(BunduResultType.depthFields)).get(fieldIndex - 1).doubleValue(); | |
418 return (channeldepth - fielddepth); | |
419 } | |
420 else | |
421 return 0.0; | |
422 } | |
361 } | 423 } |
362 | 424 |
363 /** | 425 /** |
364 * Computes the missing area and volume of the mean bed level of a km row | 426 * Computes the missing area and volume of the mean bed level of a km row |
365 */ | 427 */ |
366 private double[] computeMeanBedMissingAreaAndVolume(final int current, final int first, final int last) { | 428 private double[] computeMeanBedMissingAreaAndVolume(final int current, final int first, final int last) { |
367 | 429 |
368 final double areaCurr = meanBedMissingArea(current, first, last); | 430 final double dhCurr = meanBedMissingHeight(current, first, last); |
369 if (areaCurr < 0.0001) | 431 if (dhCurr < 0.0001) |
370 return new double[] { 0.0, 0.0 }; | 432 return new double[] { 0.0, 0.0 }; |
371 final double areaPrev = meanBedMissingArea(current - 1, first, last); | 433 final double dhPrev = meanBedMissingHeight(current - 1, first, last); |
372 final double areaNext = meanBedMissingArea(current + 1, first, last); | 434 final double dhNext = meanBedMissingHeight(current + 1, first, last); |
373 final double kmCurr = missingKm(current); | 435 final double kmCurr = missingKm(current); |
374 final double kmPrev = missingKm(current - 1); | 436 final double kmPrev = missingKm(current - 1); |
375 final double kmNext = missingKm(current + 1); | 437 final double kmNext = missingKm(current + 1); |
376 final double area1 = Double.isNaN(kmPrev) ? 0.0 : 0.5 * (areaCurr + areaPrev); | 438 final double width = this.rows.get(current).getDoubleValue(BunduResultType.channelWidth); |
377 final double area2 = Double.isNaN(kmNext) ? 0.0 : 0.5 * (areaCurr + areaNext); | 439 final double area1 = Double.isNaN(kmPrev) ? 0.0 : (0.25 * dhPrev + 0.75 * dhCurr) * width; |
378 final double volume = Double.valueOf((Math.abs(kmCurr - kmPrev) * 500 * area1) + (Math.abs(kmNext - kmCurr) * 500 * area2)); | 440 final double area2 = Double.isNaN(kmNext) ? 0.0 : (0.75 * dhCurr + 0.25 * dhNext) * width; |
441 final double volume = Double.valueOf((Math.abs(kmCurr - kmPrev) * KM_TO_M / 2 * area1) + (Math.abs(kmNext - kmCurr) * KM_TO_M / 2 * area2)); | |
379 final double area = Double.isNaN(volume) ? Double.NaN : Double.valueOf(area1 + area2); | 442 final double area = Double.isNaN(volume) ? Double.NaN : Double.valueOf(area1 + area2); |
380 return new double[] { volume, area }; | 443 return new double[] { volume, area }; |
381 } | 444 } |
382 | 445 |
383 /** | 446 /** |
384 * Gets the missing area of the mean bed level and a row if in range, otherwise 0.0 | 447 * Gets the missing height of the mean bed level and a row if in range, otherwise 0.0 |
385 */ | 448 */ |
386 private double meanBedMissingArea(final int rowIndex, final int first, final int last) { | 449 private double meanBedMissingHeight(final int rowIndex, final int first, final int last) { |
387 if ((first <= rowIndex) && (rowIndex <= last)) { | 450 if ((first <= rowIndex) && (rowIndex <= last)) { |
388 final double dh = this.rows.get(rowIndex).getDoubleValue(BunduResultType.channelDepth) | 451 final double dh = this.rows.get(rowIndex).getDoubleValue(BunduResultType.channelDepth) |
389 - this.rows.get(rowIndex).getDoubleValue(BunduResultType.flowdepthMeanBed); | 452 - this.rows.get(rowIndex).getDoubleValue(BunduResultType.flowdepthMeanBed); |
390 if (dh > 0.0) | 453 if (dh > 0.0) |
391 return dh * this.rows.get(rowIndex).getDoubleValue(BunduResultType.channelWidth); | 454 return dh; |
392 return 0.0; | 455 return 0.0; |
393 } | 456 } |
394 return 0.0; | 457 return 0.0; |
395 } | 458 } |
396 | 459 |
397 /** | 460 /** |
398 * Gets the km of a row if within range, otherwise NaN | 461 * Gets the km of a row if within range, otherwise NaN |
399 */ | 462 */ |
400 private double missingKm(final int rowIndex) { | 463 private double missingKm(final int rowIndex) { |
401 if ((0 <= rowIndex) && (rowIndex <= this.rows.size() - 1)) | 464 if ((0 <= rowIndex) && (rowIndex <= this.rows.size() - 1) && (this.rows.get(rowIndex).getValue(BunduResultType.hasMissingDepth) != null)) |
402 return this.rows.get(rowIndex).getDoubleValue(GeneralResultType.station); | 465 return this.rows.get(rowIndex).getDoubleValue(GeneralResultType.station); |
403 return Double.NaN; | 466 return Double.NaN; |
404 } | 467 } |
405 | 468 |
406 /** | 469 /** |
410 private BedQualityCalculator computeDensities(final Calculation problems, final BUNDUArtifact bunduartifact, final BunduAccess access, final River river) { | 473 private BedQualityCalculator computeDensities(final Calculation problems, final BUNDUArtifact bunduartifact, final BunduAccess access, final River river) { |
411 final BedQualityCalculator bqCalculator = new BedQualityCalculator(this.context, bunduartifact); | 474 final BedQualityCalculator bqCalculator = new BedQualityCalculator(this.context, bunduartifact); |
412 // REMARK 10km tolerance at start and end to enable interpolation there | 475 // REMARK 10km tolerance at start and end to enable interpolation there |
413 final double[] kms = DoubleUtil.explode(access.getMissingVolFrom().doubleValue() - 10.0, access.getMissingVolTo().doubleValue() + 10.0, | 476 final double[] kms = DoubleUtil.explode(access.getMissingVolFrom().doubleValue() - 10.0, access.getMissingVolTo().doubleValue() + 10.0, |
414 access.getStep().doubleValue() / 1000); | 477 access.getStep().doubleValue() / 1000); |
415 final Calendar endDay = Calendar.getInstance(); | 478 final DateRange dateRange = BedQualityD50TimeRangeConfig.getDefaults(river, access.getBezugsJahr().intValue(), problems); |
416 endDay.set(access.getBezugsJahr().intValue(), 11, 31); | 479 if (dateRange == null) |
417 final Calendar startDay = Calendar.getInstance(); | 480 return null; |
418 // TODO Spezialregelung für den Rhein (bis 1999, 2000 bis 2009, ab 2010) | 481 bqCalculator.execute(problems, river, kms, dateRange.getFrom(), dateRange.getTo()); |
419 startDay.set(endDay.get(Calendar.YEAR) - 20, 0, 1); | |
420 bqCalculator.execute(problems, river, kms, startDay.getTime(), endDay.getTime()); | |
421 return bqCalculator; | 482 return bqCalculator; |
422 } | 483 } |
423 | 484 |
424 /** | 485 /** |
425 * Computes the missing masses | 486 * Computes the missing masses |
431 if ((volumes == null) || Double.isNaN(volumes.get(0))) | 492 if ((volumes == null) || Double.isNaN(volumes.get(0))) |
432 continue; | 493 continue; |
433 final double density = getDensity(row.getDoubleValue(GeneralResultType.station), densityFinder); | 494 final double density = getDensity(row.getDoubleValue(GeneralResultType.station), densityFinder); |
434 final List<Double> masses = new ArrayList<>(); | 495 final List<Double> masses = new ArrayList<>(); |
435 double kmTotal = 0.0; | 496 double kmTotal = 0.0; |
497 int mcnt = 0; | |
436 for (int j = BedHeightValueType.FIELD_FIRST_INDEX; j <= BedHeightValueType.FIELD_LAST_INDEX; j++) { | 498 for (int j = BedHeightValueType.FIELD_FIRST_INDEX; j <= BedHeightValueType.FIELD_LAST_INDEX; j++) { |
437 final double m = volumes.get(j - 1) * density; | 499 final double m = volumes.get(j - 1) * density; |
438 masses.add(m); | 500 masses.add(m); |
439 if (!Double.isNaN(m)) | 501 if (!Double.isNaN(m)) { |
440 kmTotal += m; | 502 kmTotal += m; |
441 } | 503 mcnt += 1; |
504 } | |
505 } | |
506 if (mcnt == 0) | |
507 kmTotal = Double.NaN; | |
442 row.putValue(BunduResultType.density, density); | 508 row.putValue(BunduResultType.density, density); |
443 row.putValue(BunduResultType.missMassFields, masses); | 509 row.putValue(BunduResultType.missMassFields, masses); |
444 row.putValue(BunduResultType.missMassTotal, kmTotal); | 510 row.putValue(BunduResultType.missMassTotal, kmTotal); |
445 row.putValue(BunduResultType.missMassMeanBed, row.getDoubleValue(BunduResultType.missVolumeMeanBed) * density); | 511 row.putValue(BunduResultType.missMassMeanBed, row.getDoubleValue(BunduResultType.missVolumeMeanBed) * density); |
446 } | 512 } |
467 // Search start km | 533 // Search start km |
468 double vTotal = 0.0; | 534 double vTotal = 0.0; |
469 double mTotal = 0.0; | 535 double mTotal = 0.0; |
470 double eTotal = 0.0; | 536 double eTotal = 0.0; |
471 double cTotal = 0.0; | 537 double cTotal = 0.0; |
538 int vcnt = 0; | |
539 int mcnt = 0; | |
540 int ecnt = 0; | |
472 for (final ResultRow row : this.rows) { | 541 for (final ResultRow row : this.rows) { |
473 final double volume = row.getDoubleValue(BunduResultType.missVolumeTotal); | 542 final double volume = row.getDoubleValue(BunduResultType.missVolumeTotal); |
474 final double mass = row.getDoubleValue(BunduResultType.missMassTotal); | 543 final double mass = row.getDoubleValue(BunduResultType.missMassTotal); |
544 if (!Double.isNaN(volume)) { | |
545 vTotal += volume; | |
546 vcnt++; | |
547 if (!Double.isNaN(mass)) { | |
548 mTotal += mass; | |
549 mcnt++; | |
550 } | |
551 } | |
475 final double excavation = row.getDoubleValue(BunduResultType.excavationVolume); | 552 final double excavation = row.getDoubleValue(BunduResultType.excavationVolume); |
476 final double costs = row.getDoubleValue(BunduResultType.excavationCosts); | 553 final double costs = row.getDoubleValue(BunduResultType.excavationCosts); |
477 if (!Double.isNaN(volume) && !Double.isNaN(mass)) { | 554 if (!Double.isNaN(excavation)) { |
478 vTotal += volume; | |
479 mTotal += mass; | |
480 eTotal += excavation; | 555 eTotal += excavation; |
481 cTotal += costs; | 556 cTotal += costs; |
482 } | 557 ecnt++; |
558 } | |
559 } | |
560 if (vcnt == 0) | |
561 vTotal = Double.NaN; | |
562 if (mcnt == 0) | |
563 mTotal = Double.NaN; | |
564 if (ecnt == 0) { | |
565 eTotal = Double.NaN; | |
566 cTotal = Double.NaN; | |
483 } | 567 } |
484 final ResultRow sumRow = ResultRow.create(); | 568 final ResultRow sumRow = ResultRow.create(); |
485 sumRow.putValue(BunduResultType.missStationRangeFrom, Double.valueOf(this.missKmFrom)); | 569 sumRow.putValue(BunduResultType.missStationRangeFrom, Double.valueOf(this.missKmFrom)); |
486 sumRow.putValue(BunduResultType.missStationRangeTo, Double.valueOf(this.missKmTo)); | 570 sumRow.putValue(BunduResultType.missStationRangeTo, Double.valueOf(this.missKmTo)); |
487 sumRow.putValue(BunduResultType.missVolumeTotal, vTotal); | 571 sumRow.putValue(BunduResultType.missVolumeTotal, vTotal); |