Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java @ 8946:5d5d482da3e9
Implementing SINFO - FlowDepthMinMax calculation
author | gernotbelger |
---|---|
date | Tue, 13 Mar 2018 18:49:33 +0100 |
parents | d9dbf0b74bc2 |
children | 322b0e6298ea |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Tue Mar 13 09:55:53 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Tue Mar 13 18:49:33 2018 +0100 @@ -13,16 +13,15 @@ import org.apache.commons.lang.math.DoubleRange; import org.dive4elements.artifacts.CallContext; -import org.dive4elements.river.artifacts.BedHeightsArtifact; import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.model.CalculationResult; import org.dive4elements.river.artifacts.model.WKms; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; -import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthAccess.DifferencesPair; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; +import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder; import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; @@ -30,7 +29,6 @@ import org.dive4elements.river.artifacts.states.WaterlevelData; import org.dive4elements.river.artifacts.states.WaterlevelFetcher; import org.dive4elements.river.model.River; -import org.dive4elements.river.utils.RiverUtils; class FlowDepthCalculation { @@ -51,7 +49,7 @@ final River river = access.getRiver(); final RiverInfo riverInfo = new RiverInfo(river); - final Collection<DifferencesPair> diffPairs = access.getDifferencePairs(); + final Collection<WstSoundingIdPair> diffPairs = access.getDifferencePairs(); final DoubleRange calcRange = access.getRange(); @@ -66,7 +64,7 @@ final FlowDepthCalculationResults results = new FlowDepthCalculationResults(calcModeLabel, user, riverInfo, calcRange, useTkh); - for (final DifferencesPair diffPair : diffPairs) { + for (final WstSoundingIdPair diffPair : diffPairs) { final FlowDepthCalculationResult result = calculateResult(calcRange, diffPair, problems, infoProvider, useTkh); if (result != null) results.addResult(result); @@ -80,34 +78,29 @@ * * @param infoProvider */ - private FlowDepthCalculationResult calculateResult(final DoubleRange calcRange, final DifferencesPair diffPair, - final Calculation problems, final RiverInfoProvider infoProvider, final boolean useTkh) { + private FlowDepthCalculationResult calculateResult(final DoubleRange calcRange, final WstSoundingIdPair diffPair, final Calculation problems, + final RiverInfoProvider infoProvider, final boolean useTkh) { /* access real input data from database */ final String soundingId = diffPair.getSoundingId(); final String wstId = diffPair.getWstId(); - final BedHeightsFinder bedHeight = loadBedHeight(soundingId, calcRange); - if (bedHeight == null) { - final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", soundingId); - problems.addProblem(message); + final BedHeightsFinder bedHeight = BedHeightsFinder.forId(this.context, soundingId, calcRange, problems); + if (bedHeight == null) return null; - } /* REMARK: fetch ALL wst kms, because we want to determine the original reference gauge */ - final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN); - if (waterlevel == null) { - final String message = Resources.format(this.context.getMeta(), "Failed to access waterlevel with id '{0}'", wstId); - problems.addProblem(message); + final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN, problems); + if (waterlevel == null) return null; - } + final WKms wstKms = waterlevel.getWkms(); final String wspLabel = wstKms.getName(); final String soundingLabel = bedHeight.getInfo().getDescription(); final String label = String.format("%s - %s", wspLabel, soundingLabel); - checkYearDifference(label, waterlevel, bedHeight.getInfo().getYear(), problems); + FlowDepthUtils.checkYearDifference(label, waterlevel, bedHeight.getInfo().getYear(), problems); checkWaterlevelDiscretisation(wstKms, calcRange, problems); // TODO: prüfen, ob sohlhöhen die calcRange abdecken/überschneiden @@ -117,61 +110,19 @@ final int wspYear = waterlevel.getYear(); final WstInfo wstInfo = new WstInfo(wspLabel, wspYear, riverInfoProvider.getReferenceGauge()); + final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(wstKms); final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wstKms); final River river = riverInfoProvider.getRiver(); - final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(useTkh, this.context, problems, label, river, calcRange, dischargeProvider, + final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(useTkh, this.context, problems, label, river, calcRange, waterlevelProvider, + dischargeProvider, bedHeight); - final FlowDepthCalculator calculator = new FlowDepthCalculator(riverInfoProvider, wstKms, dischargeProvider, bedHeight, tkhCalculator); + final FlowDepthCalculator calculator = new FlowDepthCalculator(riverInfoProvider, wspLabel, bedHeight, tkhCalculator); return calculator.execute(label, wstInfo, calcRange); } - - /** - * Checks the year difference between waterlevels and sounding, and issues a warning if too big. - * - * Zeitraum Zeitliche Differenz [a] - * X ≥ 1998 ± 3 - * 1958 ≤ X < 1998 ± 6 - * 1918 ≤ X < 1958 ± 12 - * X < 1918 ± 25 - */ - private void checkYearDifference(final String label, final WaterlevelData waterlevel, final Integer soundingYear, final Calculation problems) { - if (soundingYear == null) - return; - - final int wstYear = waterlevel.getYear(); - if (wstYear < 0) - return; - - final int maxDifference = getMaxDifferenceYears(soundingYear); - - final int difference = Math.abs(soundingYear - wstYear); - if (difference > maxDifference) { - final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.year_difference", null, label, wstYear, - soundingYear); - problems.addProblem(message); - } - } - - private int getMaxDifferenceYears(final int year) { - - if (year < 1918) - return 25; - - if (1918 <= year && year < 1958) - return 12; - - if (1958 <= year && year < 1998) - return 6; - - /* >= 1998 */ - return 3; - } - /* Checks if the discretisation of the waterlevel exceeds 1000m */ - private void checkWaterlevelDiscretisation(final WKms wstKms, final DoubleRange calcRange, final Calculation problems) { final int size = wstKms.size(); @@ -190,37 +141,4 @@ } } } - - private BedHeightsFinder loadBedHeight(final String soundingId, final DoubleRange calcRange) { - - // REMARK: absolutely unbelievable.... - // The way how bed-heights (and other data too) is accessed is different for nearly every calculation-type - // throughout flys. - // The knowledge on how to parse the datacage-ids is spread through the complete code-base... - - // We use here the way on how bed-heights are accessed by the BedDifferenceAccess/BedDifferenceCalculation, but - // this is plain random - final String[] parts = soundingId.split(";"); - - final BedHeightsArtifact artifact = (BedHeightsArtifact) RiverUtils.getArtifact(parts[0], this.context); - - final Integer bedheightId = artifact.getDataAsInteger("height_id"); - if (bedheightId == null) { - // FIXME: error message! - return null; - } - - // REMARK: this only works with type 'single'; unclear on how to distinguish from epoch data (or whatever the - // other type means) - // Luckily, the requirement is to only access 'single' data here. - // final String bedheightType = artifact.getDataAsString("type"); - - // REMARK: BedDifferences uses this, but we also need the metadata of the BedHeight - // REMARK: second absolutely awful thing: BedHeight is a hibernate binding class, accessing the database via - // hibernate stuff - // BedHeightFactory uses its own (direct) way of accessing the data, with its own implemented data classes. - // return BedHeightFactory.getHeight(bedheightType, bedheightId, from, to); - - return BedHeightsFinder.forId(bedheightId, calcRange); - } } \ No newline at end of file