Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java @ 8882:f762fadc5313
Further work on SINFO-FlowDepth
author | gernotbelger |
---|---|
date | Fri, 09 Feb 2018 16:11:47 +0100 |
parents | 64ca63f79f6f |
children | a536e1aacf0f |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Fri Feb 09 16:11:34 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Fri Feb 09 16:11:47 2018 +0100 @@ -23,7 +23,8 @@ import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthAccess.DifferencesPair; -import org.dive4elements.river.artifacts.states.WDifferencesState; +import org.dive4elements.river.artifacts.states.WaterlevelData; +import org.dive4elements.river.artifacts.states.WaterlevelFetcher; import org.dive4elements.river.model.BedHeight; import org.dive4elements.river.model.Gauge; import org.dive4elements.river.model.River; @@ -36,7 +37,7 @@ private final CallContext context; - public FlowDepthCalculation( final CallContext context ) { + public FlowDepthCalculation(final CallContext context) { this.context = context; } @@ -66,81 +67,86 @@ final List<Gauge> gauges = river.determineGauges(from, to); final GaugeIndex gaugeIndex = new GaugeIndex(gauges); - final String calcModeLabel = Resources.getMsg(this.context.getMeta(),sinfo.getCalculationMode().name() ); + final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); - final FlowDepthCalculationResults results = new FlowDepthCalculationResults(calcModeLabel, user, river, from, to, useTkh); + final FlowDepthCalculationResults results = new FlowDepthCalculationResults(calcModeLabel, user, river, from, + to, useTkh); for (final DifferencesPair diffPair : diffPairs) { - final FlowDepthCalculationResult result = calculateResult( river, from, to, diffPair, problems, gaugeIndex ); - if( result != null ) + final FlowDepthCalculationResult result = calculateResult(river, from, to, diffPair, problems, gaugeIndex); + if (result != null) results.addResult(result); } - return new CalculationResult(results,problems); + return new CalculationResult(results, problems); } - private FlowDepthCalculationResult calculateResult(final River river, final double from, final double to, final DifferencesPair diffPair, final Calculation problems, final GaugeIndex gaugeIndex) { + private FlowDepthCalculationResult calculateResult(final River river, final double from, final double to, + final DifferencesPair diffPair, final Calculation problems, final GaugeIndex gaugeIndex) { /* access real input data from database */ final String soundingId = diffPair.getSoundingId(); final String wstId = diffPair.getWstId(); - final BedHeight bedHeight = loadBedHeight( soundingId, from, to ); - if( bedHeight == null ) - { - final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", soundingId); + final BedHeight bedHeight = loadBedHeight(soundingId, from, to); + if (bedHeight == null) { + final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", + soundingId); problems.addProblem(message); return null; } - final WKms wstKms = new WDifferencesState().getWKms(wstId, this.context, from, to); - if( wstKms == null ) - { - final String message = Resources.format(this.context.getMeta(), "Failed to access waterlevel with id '{0}'", wstId); + /* 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); return null; } + final WKms wstKms = waterlevel.getWkms(); + + checkWaterlevelDiscretisation(wstKms, problems); // FIXME: woher bekommen? final int wspYear = 0; - // FIXME: angeblich metadatum bestimmter wsps? - // Könnte 'source' an 'wst_columns' sein - final String wspSource = "FIXME"; - // FIXME: Umsetzung IDENTISCH zu allen möglichen Arten wie ein WSPL berechnet wird.... - final String wspGauge = "FIXME"; + + /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */ + final String notinrange = Resources.getMsg(this.context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, + CSV_NOT_IN_GAUGE_RANGE); + + final Gauge refGauge = waterlevel.findReferenceGauge(river); + final String refGaugeName = refGauge == null ? notinrange : refGauge.getName(); final String wspLabel = wstKms.getName(); final String soundingLabel = bedHeight.getDescription(); final String label = String.format("%s - %s", wspLabel, soundingLabel); final BedHeightInfo sounding = BedHeightInfo.from(bedHeight); - final WstInfo wstInfo = new WstInfo(wspLabel, wspYear, wspSource, wspGauge); + final WstInfo wstInfo = new WstInfo(wspLabel, wspYear, refGaugeName); final FlowDepthCalculationResult resultData = new FlowDepthCalculationResult(label, wstInfo, sounding); - final String notinrange = Resources.getMsg(this.context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE); - - // TODO: prüfe diskretisierung wsp --> > 1000m --> Fehlermeldung - // TODO: Berechnung der Transportkörperhöhen - // - woher kommen die zusätzlichen eingangsdaten? sind das fixe daten pro gewässer? --> falls ja, warum nicht einmal berechnen und in db ablegen? + // - woher kommen die zusätzlichen eingangsdaten? sind das fixe daten pro gewässer? --> falls ja, warum nicht + // einmal berechnen und in db ablegen? // Benötigte Daten // - Abfluss / Station - // - kein Abfluss --> Fehler - if( !(wstKms instanceof QKms)) - { - final String message = Resources.format(this.context.getMeta(), "{0}: keine Abflussdaten vorhanden, Transportkörperhöhenberechnung nicht möglich", label); + // - kein Abfluss --> Fehler + if (!(wstKms instanceof QKms)) { + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", + null, label); problems.addProblem(message); // TODO: keine Berechnung TKH } // - Sohlbeschaffenheit (D50 Korndurchmesser aus Seddb) - // - Abhängig von Peiljahr - // - kein D50 vorhanden --> Fehler + // - Abhängig von Peiljahr + // - kein D50 vorhanden --> Fehler // - Art der Gewässersohle (starr/mobil) - final String bedHeightLabel = bedHeight.getDescription(); final String wstLabel = wstKms.getName(); @@ -164,36 +170,74 @@ final String location = LocationProvider.getLocation(river.getName(), km); // REMARK: access the gauge once only during calculation - // FIXME: copy specific handling from original wst - final Gauge gauge = gaugeIndex.findGauge(km); + final Gauge gauge = findGauge(waterlevel, refGauge, gaugeIndex, km); + final String gaugeLabel = gauge == null ? notinrange : gauge.getName(); - resultData.addRow( km, flowDepth, flowDepthTkh, tkh, wst, discharge, wstLabel, gaugeLabel, meanBedHeight, bedHeightLabel, location ); + resultData.addRow(km, flowDepth, flowDepthTkh, tkh, wst, discharge, wstLabel, gaugeLabel, meanBedHeight, + bedHeightLabel, location); } return resultData; } + private Gauge findGauge(final WaterlevelData waterlevel, final Gauge refGauge, final GaugeIndex gaugeIndex, + final double km) { + + // REMARK: using same logic as in WaterlevelExporter here + + final boolean showAllGauges = waterlevel.isShowAllGauges(); + + if (showAllGauges) + return gaugeIndex.findGauge(km); + + if (refGauge.getRange().contains(km)) + return refGauge; + + return null; + } + + /* Checks if the discretisation of the waterlevel exceeds 1000m */ + private void checkWaterlevelDiscretisation(final WKms wstKms, final Calculation problems) { + final int size = wstKms.size(); + for (int i = 0; i < size - 2; i++) { + final double kmPrev = wstKms.getKm(i); + final double kmNext = wstKms.getKm(i + 1); + + if (Math.abs(kmPrev - kmNext) > 1) { + final String label = wstKms.getName(); + + final String message = Resources.getMsg(this.context.getMeta(), + "sinfo_calc_flow_depth.warning.waterlevel_discretisation", null, label); + problems.addProblem(kmPrev, message); + } + } + } + private BedHeight loadBedHeight(final String soundingId, final double from, final double to) { // FIXME: absolutely unbelievable.... - // The way how bed-heights (and other data too) is accessed is different for nearly ever calculation-type throughout flys. + // The way how bed-heights (and other data too) is accessed is different for nearly ever 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 + // 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"); - // FIXME: this only works with type 'single'; unclear on how to distinguish from epoch data (or whatever the other type means) + // FIXME: 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"); // FIXME: BedDifferences uses this, but we also need the metadata of the BedHeight - // FIXME: second absolutely awful thing: BedHeight is a hibernate binding class, accessing the database via hibernate stuff + // FIXME: 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 BedHeightFactory.getHeight(bedheightType, bedheightId, from, to); return BedHeight.getBedHeightById(bedheightId); }