# HG changeset patch # User mschaefer # Date 1538491191 -7200 # Node ID 55c187a0a31e327511442611d034f47640342421 # Parent 7c8d6286787627cc14e138d3bdcb64b7c8415752 Fixed: consistent gauge assignment with downstream gauge as reference gauge for calc range starting at a gauge range limit diff -r 7c8d62867876 -r 55c187a0a31e artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java Tue Oct 02 13:25:52 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java Tue Oct 02 16:39:51 2018 +0200 @@ -35,6 +35,7 @@ import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; +import org.dive4elements.river.artifacts.states.WaterlevelData; import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; import org.dive4elements.river.model.BedHeightValueType; import org.dive4elements.river.model.River; @@ -93,13 +94,19 @@ // Calculate the wspl for the selected river range as in fixa awspl bunduartifact.addStringData("wq_isq", "true"); final WinfoArtifactWrapper winfo = new WinfoArtifactWrapper(bunduartifact); - final RiverInfoProvider riverInfoProvider = RiverInfoProvider.forRange(this.context, river, access.getRange(), true); + final RiverInfoProvider riverInfoProvider = RiverInfoProvider.forRange(this.context, river, access.getRange()); final FixRealizingResult fixResult = calculateWspl(bunduartifact, problems); if (fixResult == null) return new CalculationResult(results, problems); final WQKms wqkms = fixResult.getWQKms()[0]; - final WstInfo wstInfo = new WstInfo(wqkms.getName(), 0, riverInfoProvider.getReferenceGauge(), true); + // We have no wst year as the wst is created by a calculation; we do not need it though + final int wspYear = -1; + // Remark: showAllGauges true for Fixierungsanalyse, false for WInfo, so true here as well + final boolean showAllGauges = true; + final WaterlevelData waterlevel = new WaterlevelData(wqkms, wspYear, showAllGauges, true); + final RiverInfoProvider riverInfoProvider2 = riverInfoProvider.forWaterlevel(waterlevel); + final WstInfo wstInfo = new WstInfo(wqkms.getName(), 0, riverInfoProvider2.getReferenceGauge(), true); // Fetch the bed heights of the selected sounding final Integer bedHeightId = access.getBedHeightID(); @@ -113,7 +120,7 @@ // Compute the result rows for (int i = 0; i <= wqkms.size() - 1; i++) { - this.rows.add(createRow(wqkms.getKm(i), wqkms.getW(i), wqkms.getQ(i), bedHeightsFinder, channelFinder, riverInfoProvider, wstInfo)); + this.rows.add(createRow(wqkms.getKm(i), wqkms.getW(i), wqkms.getQ(i), bedHeightsFinder, channelFinder, riverInfoProvider2, wstInfo)); } // Compute the missing volumes diff -r 7c8d62867876 -r 55c187a0a31e artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/RiverInfoProvider.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/RiverInfoProvider.java Tue Oct 02 13:25:52 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/RiverInfoProvider.java Tue Oct 02 16:39:51 2018 +0200 @@ -37,31 +37,16 @@ public static RiverInfoProvider forRange(final CallContext context, final River river, final DoubleRange calcRange) { - return forRange(context, river, calcRange, false); - } - - public static RiverInfoProvider forRange(final CallContext context, final River river, final DoubleRange calcRange, final boolean firstGaugeIsRefGauge) { - final List gauges; if (calcRange == null) gauges = river.getGauges(); - else { + else gauges = river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); - // If the range starts exactly at a gauge's range end, determineGauges gets this gauge as the first in list, - // but we want the list to start with the next gauge, i.e. that one that starts with the calc range, - // therefore we remove the first one - // REMARK Bei abwärts kilometriertem Fluss den letzten Gauge in der Liste prüfen (Ende)/entfernen - if ((gauges.size() >= 2) && (Math.abs(gauges.get(0).getRange().getB().doubleValue() - calcRange.getMinimumDouble()) < 0.0001)) - gauges.remove(0); - } - final GaugeIndex gaugeIndex = new GaugeIndex(gauges); final String notinrange = Resources.getMsg(context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE); - if (firstGaugeIsRefGauge && !gauges.isEmpty()) - return new RiverInfoProvider(notinrange, river, false, gaugeIndex, gauges.get(0)); return new RiverInfoProvider(notinrange, river, false, gaugeIndex, null); } @@ -73,6 +58,9 @@ this.refGauge = refGauge; } + /** + * Creates a new provider as a copy of this one, re-determining the reference gauge by a waterlevel + */ public RiverInfoProvider forWaterlevel(final WaterlevelData waterlevel) { final WKms wstKms = waterlevel.getWkms(); final Gauge waterlevelRefGauge = findReferenceGauge(wstKms); @@ -82,7 +70,15 @@ } /** - * Re-determines the reference gauge, in the same way as the WaterlevelArtifact would do it + * Create a new provider as a copy of this one, re-determining the reference gauge by the upstream side of a range + */ + public RiverInfoProvider forReferenceRange(final DoubleRange range, final boolean isShowAllGauges) { + final Gauge kmRefGauge = findReferenceGauge(range); + return new RiverInfoProvider(this.notinrange, this.river, isShowAllGauges, this.gaugeIndex, kmRefGauge); + } + + /** + * Determines the reference gauge, in the same way as the WaterlevelArtifact would do it */ private Gauge findReferenceGauge(final WKms wkms) { @@ -90,6 +86,18 @@ return this.river.determineRefGauge(wstFromTo, true); } + /** + * Determines the reference gauge for a km range of the active river + */ + private Gauge findReferenceGauge(final DoubleRange range) { + + final double from = range.getMinimumDouble(); + final double to = range.getMaximumDouble(); + final boolean waterIncreasing = this.river.getKmUp(); + final double[] wstFromTo = waterIncreasing ? new double[] { to, from } : new double[] { from, to }; + return this.river.determineRefGauge(wstFromTo, true); + } + private static double[] findWstFromTo(final WKms wkms) { final double from = wkms.getKm(0); diff -r 7c8d62867876 -r 55c187a0a31e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Tue Oct 02 13:25:52 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Tue Oct 02 16:39:51 2018 +0200 @@ -50,7 +50,7 @@ final RiverInfo riverInfo = new RiverInfo(river); final DoubleRange calcRange = access.getRange(); - final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange, true); + final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange); final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); final String label = Resources.getMsg(this.context.getMeta(), access.getRiverside().getKey()); @@ -88,7 +88,7 @@ final FloodDurationAccess access = new FloodDurationAccess(sinfo); final River river = access.getRiver(); final DoubleRange calcRange = access.getRange(); - final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange, true); + final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange); final Calculation problems = new Calculation(); diff -r 7c8d62867876 -r 55c187a0a31e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Tue Oct 02 13:25:52 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Tue Oct 02 16:39:51 2018 +0200 @@ -55,12 +55,14 @@ private final List rows = new ArrayList<>(); private final RiverInfoProvider riverInfoProvider; + private RiverInfoProvider riverInfoProvider2; private final CallContext context; public FloodDurationCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) { this.context = context; this.riverInfoProvider = riverInfoProvider; + this.riverInfoProvider2 = null; } /** @@ -71,7 +73,7 @@ // Find all gauges of the calc range, and create the duration finders final Map durFinders = new HashMap<>(); - for (final Gauge gauge : this.riverInfoProvider.getRiver().determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble())) { + for (final Gauge gauge : this.riverInfoProvider.getGauges()) { durFinders.put(gauge, GaugeDurationValuesFinder.loadValues(gauge, problems)); } @@ -90,6 +92,10 @@ // Calculate W and Q for all stations and the selected discharge states/waterlevels final WQKms[] wqkmsArray = calculateWsts(winfo, withWspl, stationsSorted, problems); + // final WaterlevelData waterlevel = new WaterlevelData(wqkmsArray[0], -1, false, true); + // this.riverInfoProvider2 = this.riverInfoProvider.forWaterlevel(waterlevel); + this.riverInfoProvider2 = this.riverInfoProvider.forReferenceRange(calcRange, false); + // this.riverInfoProvider2.cleanupGaugesAtStart(calcRange); // Determine discharge state labels of the waterlevels updateWstLabels(wqkmsArray, winfo, problems); @@ -100,11 +106,11 @@ // Load base wst table (river).wst // (should be in cache since already used in calculateWaterlevels (winfo.computeWaterlevelData) - final WstValueTable wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver()); + final WstValueTable wst = WstValueTableFactory.getTable(this.riverInfoProvider2.getRiver()); // Create the result rows, and calculate and add the flood durations etc. for (int i = 0; i <= stationsSorted.length - 1; i++) { - final Gauge gauge = this.riverInfoProvider.getGauge(stationsSorted[i], true); + final Gauge gauge = this.riverInfoProvider2.getGauge(stationsSorted[i], true); final ResultRow row = createRow(stationsSorted[i], wqkmsArray, gaugeWstDurations.get(gauge), i); if (allStations.containsKey(stationsSorted[i]) && (allStations.get(stationsSorted[i]) != null)) calculateInfrastructure(row, gauge, allStations.get(stationsSorted[i]), wst, durFinders); @@ -132,7 +138,7 @@ public WQDay calcWQDays(final Calculation problems, final double station, final WINFOArtifact winfo) { final WstValueTable wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver()); - final Gauge gauge = this.riverInfoProvider.getRiver().determineGaugeByPosition(station); + final Gauge gauge = this.riverInfoProvider.getGauge(station, true); final Object[] obj = gauge.fetchDurationCurveData(); final int[] udays = (int[]) obj[0]; final double[] qs = (double[]) obj[1]; @@ -421,10 +427,10 @@ row.putValue(SInfoResultType.infrastructuretype, null); // is replaced later for an infrastructure row.putValue(SInfoResultType.floodDuration, Double.NaN); // is replaced later for an infrastructure - final String gaugeLabel = this.riverInfoProvider.findGauge(station); + final String gaugeLabel = this.riverInfoProvider2.findGauge(station); row.putValue(GeneralResultType.gaugeLabel, gaugeLabel); - final String location = this.riverInfoProvider.getLocation(station); + final String location = this.riverInfoProvider2.getLocation(station); row.putValue(GeneralResultType.location, location); final List wsts = new ArrayList<>(wqkmsArray.length); diff -r 7c8d62867876 -r 55c187a0a31e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java Tue Oct 02 13:25:52 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java Tue Oct 02 16:39:51 2018 +0200 @@ -40,7 +40,6 @@ import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; -import org.dive4elements.river.artifacts.states.WaterlevelData; import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; import org.dive4elements.river.model.BedHeight; import org.dive4elements.river.model.River; @@ -158,9 +157,8 @@ final int wspYear = -1; // Remark: showAllGauges only true for Fixierungsanalyse, false for WInfo, so false here as well final boolean showAllGauges = false; - final WaterlevelData waterlevel = new WaterlevelData(wkms, wspYear, showAllGauges, true); - final RiverInfoProvider riverInfoProvider = riverInfo.forWaterlevel(waterlevel); + final RiverInfoProvider riverInfoProvider = riverInfo.forReferenceRange(calcRange, showAllGauges); final String waterlevelLabel = descBuilder.getDesc(wkms);