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);

http://dive4elements.wald.intevation.org