# HG changeset patch # User gernotbelger # Date 1538064386 -7200 # Node ID 853f2dafc16e0e0c1640a6d761d78f5bcc9957f5 # Parent d8e753d0fdb9e773d02f10af2a8e5f2dab8e3580 VegetationZones in CrossSectionsDiagram diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/artifacts/uinfo.xml --- a/artifacts/doc/conf/artifacts/uinfo.xml Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/doc/conf/artifacts/uinfo.xml Thu Sep 27 18:06:26 2018 +0200 @@ -306,7 +306,6 @@ - @@ -348,8 +347,6 @@ - - @@ -357,7 +354,12 @@ - + + + + + + diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/meta-data.xml --- a/artifacts/doc/conf/meta-data.xml Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/doc/conf/meta-data.xml Thu Sep 27 18:06:26 2018 +0200 @@ -256,6 +256,7 @@ + Duration curve @@ -492,8 +493,8 @@ Cross sections - - + + Duration curve @@ -512,7 +513,6 @@ - @@ -614,6 +614,11 @@ + + + + + @@ -639,6 +644,8 @@ + + @@ -1324,6 +1331,15 @@ + + + + + + + + + @@ -3297,6 +3313,7 @@ SELECT c.name AS collection_name, + c.gid AS collection_gid, ma.id AS a_id, ma.state AS a_state, ma.gid AS a_gid, @@ -3757,31 +3774,34 @@ - + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - + + diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/themes/default.xml --- a/artifacts/doc/conf/themes/default.xml Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/doc/conf/themes/default.xml Thu Sep 27 18:06:26 2018 +0200 @@ -2973,8 +2973,13 @@ - - + + + + + + + diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/doc/conf/themes/second.xml --- a/artifacts/doc/conf/themes/second.xml Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/doc/conf/themes/second.xml Thu Sep 27 18:06:26 2018 +0200 @@ -2961,8 +2961,13 @@ - - + + + + + + + diff -r d8e753d0fdb9 -r 853f2dafc16e 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 Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java Thu Sep 27 18:06:26 2018 +0200 @@ -27,8 +27,8 @@ import org.dive4elements.river.artifacts.model.WQKms; import org.dive4elements.river.artifacts.model.fixings.FixRealizingCalculation; import org.dive4elements.river.artifacts.model.fixings.FixRealizingResult; +import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.resources.Resources; -import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractProcessor.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/common/AbstractProcessor.java Thu Sep 27 18:06:26 2018 +0200 @@ -30,8 +30,6 @@ import org.dive4elements.river.exports.DiagramGenerator; import org.dive4elements.river.exports.StyledSeriesBuilder; import org.dive4elements.river.exports.process.DefaultProcessor; -import org.dive4elements.river.jfree.StripedAreaDataset; -import org.dive4elements.river.jfree.StripedAreaDataset.Stripe; import org.dive4elements.river.jfree.StyledAreaSeriesCollection; import org.dive4elements.river.jfree.StyledXYSeries; import org.dive4elements.river.themes.ThemeDocument; @@ -171,19 +169,6 @@ return null; } - protected final String buildStripedAreaSeries(final Stripe[] stripes, final DiagramGenerator generator, final ArtifactAndFacet bundle, - final ThemeDocument theme, final boolean visible) { - - final StripedAreaDataset dataset = new StripedAreaDataset(theme); - - for (final Stripe stripe : stripes) - dataset.addStripe(stripe); - - generator.addAxisDataset(dataset, getAxisName(), visible); - - return null; - } - private Double findRadius(final CallContext context, final Artifact artifact) { final Double start = (Double) context.getContextValue("startkm"); final Double end = (Double) context.getContextValue("endkm"); diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DataFromArtifactXPathFunction.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DataFromArtifactXPathFunction.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DataFromArtifactXPathFunction.java Thu Sep 27 18:06:26 2018 +0200 @@ -49,7 +49,10 @@ return null; final StateData data = artifact.getData(args.get(1).toString()); - return data.getValue(); + final Object value = data.getValue(); + if (value == null) + return null; + return value; } } \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DefaultVegetationZoneXPathFunction.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DefaultVegetationZoneXPathFunction.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/datacage/templating/DefaultVegetationZoneXPathFunction.java Thu Sep 27 18:06:26 2018 +0200 @@ -47,6 +47,10 @@ if (river == null) return null; - return VegetationZoneServerClientXChange.parseListToDataString(VegetationZoneServerClientXChange.getStandardList(river, this.context)); + final String value = VegetationZoneServerClientXChange.parseListToDataString(VegetationZoneServerClientXChange.getStandardList(river, this.context)); + if (value == null) + return null; + + return value; } } \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionFacetUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionFacetUtils.java Thu Sep 27 18:06:26 2018 +0200 @@ -0,0 +1,48 @@ +/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ +package org.dive4elements.river.artifacts.model; + +import java.util.List; + +import org.apache.log4j.Logger; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.artifacts.DataProvider; +import org.dive4elements.river.model.FastCrossSectionLine; + +/** + * @author Domenico Nardi Tironi + */ +public final class CrossSectionFacetUtils { + + private static Logger log = Logger.getLogger(CrossSectionFacetUtils.class); + + private CrossSectionFacetUtils() { + throw new UnsupportedOperationException(); + } + + public static DataProvider getDataProvider(final CallContext context) { + + final List providers = context.getDataProvider(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA); + if (providers.size() < 1) { + log.warn("Could not find Cross-Section data provider."); + return null; + } + + return providers.get(0); + } + + public static FastCrossSectionLine getCrossSection(final DataProvider provider, final CallContext context) { + + if (provider == null) + return null; + + return (FastCrossSectionLine) provider.provideData(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA, null, context); + } +} \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionWaterLineFacet.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionWaterLineFacet.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/CrossSectionWaterLineFacet.java Thu Sep 27 18:06:26 2018 +0200 @@ -101,8 +101,7 @@ final double currentKm = crossSection.getKm(); final double waterLevel = lineArtifact.getWaterLevel(this.type, this.hash, this.stateId, currentKm, this.waterLineIndex, (Double) nextKm, - (Double) prevKm, - context); + (Double) prevKm, context); if (Double.isNaN(waterLevel)) return NO_LINE_DATA; diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstValueTable.java Thu Sep 27 18:06:26 2018 +0200 @@ -620,7 +620,7 @@ /** * Interpolates a W for a km using a Q column position */ - public double interpolateW(final double km, final QPosition qPosition, final Calculation errors) { + public double interpolateW(final double km, final QPosition qPosition) { int rowIndex = Collections.binarySearch(this.rows, new Row(km)); diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/MainWstValuesCalculator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/MainWstValuesCalculator.java Thu Sep 27 18:06:26 2018 +0200 @@ -0,0 +1,115 @@ +/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ +package org.dive4elements.river.artifacts.model.river; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.math.DoubleRange; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.model.WstValueTable; +import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; +import org.dive4elements.river.artifacts.model.WstValueTableFactory; +import org.dive4elements.river.model.Gauge; +import org.dive4elements.river.model.MainValue; +import org.dive4elements.river.model.MainValueType.MainValueTypeKey; +import org.dive4elements.river.model.River; + +/** + * @author Domenico Nardi Tironi + */ +public final class MainWstValuesCalculator { + + private final WstValueTable wst; + + private final Map positions; + + private static class MainValueQPosition { + + private final Map gaugePositions = new HashMap<>(); + private QPosition refGaugePositions = null; + } + + public static MainWstValuesCalculator forRiver(final CallContext context, final River river, final DoubleRange calcRange, final String... mainValueNames) { + + final RiverInfoProvider info = RiverInfoProvider.forRange(context, river, calcRange); + + return forRiverInfo(info, mainValueNames); + } + + public static MainWstValuesCalculator forRiverInfo(final RiverInfoProvider info, final String... mainValueNames) { + + final WstValueTable wst = WstValueTableFactory.getTable(info.getRiver()); + + final Map positions = calculatePositions(info, wst, mainValueNames); + + return new MainWstValuesCalculator(wst, positions); + } + + private static Map calculatePositions(final RiverInfoProvider info, final WstValueTable wst, final String[] mainValueNames) { + + boolean isFirstGauge = true; + + final Map positions = new HashMap<>(); + + for (final String mainValue : mainValueNames) + positions.put(mainValue.toUpperCase(), new MainValueQPosition()); + + for (final Gauge gauge : info.getGauges()) { + + for (final MainValueQPosition position : positions.values()) + position.gaugePositions.put(gauge, null); + + final double gaugeKm = gauge.getStation().doubleValue(); + for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q)) { + + final MainValueQPosition position = positions.get(mv.getMainValue().getName().toUpperCase()); + if (position != null) { + final QPosition qPosition = wst.getQPosition(gaugeKm, mv.getValue().doubleValue()); + position.gaugePositions.put(gauge, qPosition); + + if (isFirstGauge) + position.refGaugePositions = qPosition; + } + } + + isFirstGauge = false; + } + + return positions; + } + + private MainWstValuesCalculator(final WstValueTable wst, final Map positions) { + this.wst = wst; + this.positions = positions; + } + + public boolean hasPosition(final String mainValueName) { + + final MainValueQPosition position = this.positions.get(mainValueName); + if (position == null) + throw new IllegalArgumentException(); + + return position.refGaugePositions != null; + } + + /** + * Interpolates the W for a station with a fixed (virtual) wst column position + */ + public double interpolateW(final double station, final String mainValueName) { + + final MainValueQPosition mainValuePosition = this.positions.get(mainValueName.toUpperCase()); + + if (mainValuePosition.refGaugePositions == null) + return Double.NaN; + + return this.wst.interpolateW(station, mainValuePosition.refGaugePositions); + } +} \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/RiverInfoProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/RiverInfoProvider.java Thu Sep 27 18:06:26 2018 +0200 @@ -0,0 +1,143 @@ +/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ +package org.dive4elements.river.artifacts.model.river; + +import java.util.List; + +import org.apache.commons.lang.math.DoubleRange; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.model.LocationProvider; +import org.dive4elements.river.artifacts.model.WKms; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.states.WaterlevelData; +import org.dive4elements.river.model.Gauge; +import org.dive4elements.river.model.River; +import org.dive4elements.river.utils.GaugeIndex; + +/** + * @author Gernot Belger + * + */ +public final class RiverInfoProvider { + + private static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range"; + + private final River river; + private final GaugeIndex gaugeIndex; + private final Gauge refGauge; + private final boolean showAllGauges; + private final String notinrange; + + 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 + gauges = river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); + + 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); + } + + private RiverInfoProvider(final String notinrange, final River river, final boolean showAllGauges, final GaugeIndex gaugeIndex, final Gauge refGauge) { + this.notinrange = notinrange; + this.river = river; + this.showAllGauges = showAllGauges; + this.gaugeIndex = gaugeIndex; + this.refGauge = refGauge; + } + + public RiverInfoProvider forWaterlevel(final WaterlevelData waterlevel) { + final WKms wstKms = waterlevel.getWkms(); + final Gauge waterlevelRefGauge = findReferenceGauge(wstKms); + final boolean waterlevelShowAllGauges = waterlevel.isShowAllGauges(); + + return new RiverInfoProvider(this.notinrange, this.river, waterlevelShowAllGauges, this.gaugeIndex, waterlevelRefGauge); + } + + /** + * Re-determines the reference gauge, in the same way as the WaterlevelArtifact would do it + */ + private Gauge findReferenceGauge(final WKms wkms) { + + final double[] wstFromTo = findWstFromTo(wkms); + return this.river.determineRefGauge(wstFromTo, true); + } + + private static double[] findWstFromTo(final WKms wkms) { + + final double from = wkms.getKm(0); + final double to = wkms.getKm(wkms.size() - 1); + + final boolean waterIncreasing = wkms.guessWaterIncreasing(); + if (waterIncreasing) + return new double[] { to, from }; + + return new double[] { from, to }; + } + + public String getLocation(final double km) { + return LocationProvider.getLocation(this.river.getName(), km); + } + + public String findGauge(final double km) { + // REMARK: access the gauge once only during calculation + final Gauge gauge = getGauge(km); + + return gauge == null ? this.notinrange : gauge.getName(); + } + + private String findGauge(final double km, final boolean allGauges) { + // REMARK: access the gauge once only during calculation + final Gauge gauge = getGauge(km, allGauges); + + return gauge == null ? this.notinrange : gauge.getName(); + } + + public Gauge getGauge(final double km) { + + // REMARK: using same logic as in WaterlevelExporter here + + return getGauge(km, this.showAllGauges); + } + + public Gauge getGauge(final double km, final boolean allGauges) { + if (allGauges) + return this.gaugeIndex.findGauge(km); + + if ((this.refGauge != null) && this.refGauge.getRange().contains(km)) + return this.refGauge; + + return null; + } + + public String getReferenceGauge() { + return this.refGauge == null ? this.notinrange : this.refGauge.getName(); + } + + public River getRiver() { + return this.river; + } + + public List getGauges() { + return this.gaugeIndex.getGauges(); + } +} \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java Thu Sep 27 18:06:26 2018 +0200 @@ -24,11 +24,11 @@ import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.model.CalculationResult; import org.dive4elements.river.artifacts.model.DateRange; +import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; import org.dive4elements.river.artifacts.sinfo.common.GaugeDischargeValuesFinder; import org.dive4elements.river.artifacts.sinfo.common.GaugeMainValueFinder; -import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/RiverInfoProvider.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/RiverInfoProvider.java Wed Sep 26 15:48:05 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde - * Software engineering by - * Björnsen Beratende Ingenieure GmbH - * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt - * - * This file is Free Software under the GNU AGPL (>=v3) - * and comes with ABSOLUTELY NO WARRANTY! Check out the - * documentation coming with Dive4Elements River for details. - */ -package org.dive4elements.river.artifacts.sinfo.common; - -import java.util.List; - -import org.apache.commons.lang.math.DoubleRange; -import org.dive4elements.artifacts.CallContext; -import org.dive4elements.river.artifacts.model.LocationProvider; -import org.dive4elements.river.artifacts.model.WKms; -import org.dive4elements.river.artifacts.resources.Resources; -import org.dive4elements.river.artifacts.states.WaterlevelData; -import org.dive4elements.river.model.Gauge; -import org.dive4elements.river.model.River; -import org.dive4elements.river.utils.GaugeIndex; - -/** - * @author Gernot Belger - * - */ -public final class RiverInfoProvider { - - private static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range"; - - private final River river; - private final GaugeIndex gaugeIndex; - private final Gauge refGauge; - private final boolean showAllGauges; - private final String notinrange; - - 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 = river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); - 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); - } - - private RiverInfoProvider(final String notinrange, final River river, final boolean showAllGauges, final GaugeIndex gaugeIndex, final Gauge refGauge) { - this.notinrange = notinrange; - this.river = river; - this.showAllGauges = showAllGauges; - this.gaugeIndex = gaugeIndex; - this.refGauge = refGauge; - } - - public RiverInfoProvider forWaterlevel(final WaterlevelData waterlevel) { - final WKms wstKms = waterlevel.getWkms(); - final Gauge waterlevelRefGauge = findReferenceGauge(wstKms); - final boolean waterlevelShowAllGauges = waterlevel.isShowAllGauges(); - - return new RiverInfoProvider(this.notinrange, this.river, waterlevelShowAllGauges, this.gaugeIndex, waterlevelRefGauge); - } - - /** - * Re-determines the reference gauge, in the same way as the WaterlevelArtifact would do it - */ - private Gauge findReferenceGauge(final WKms wkms) { - - final double[] wstFromTo = findWstFromTo(wkms); - return this.river.determineRefGauge(wstFromTo, true); - } - - private static double[] findWstFromTo(final WKms wkms) { - - final double from = wkms.getKm(0); - final double to = wkms.getKm(wkms.size() - 1); - - final boolean waterIncreasing = wkms.guessWaterIncreasing(); - if (waterIncreasing) - return new double[] { to, from }; - - return new double[] { from, to }; - } - - public String getLocation(final double km) { - return LocationProvider.getLocation(this.river.getName(), km); - } - - public String findGauge(final double km) { - // REMARK: access the gauge once only during calculation - final Gauge gauge = getGauge(km); - - return gauge == null ? this.notinrange : gauge.getName(); - } - - private String findGauge(final double km, final boolean allGauges) { - // REMARK: access the gauge once only during calculation - final Gauge gauge = getGauge(km, allGauges); - - return gauge == null ? this.notinrange : gauge.getName(); - } - - public Gauge getGauge(final double km) { - - // REMARK: using same logic as in WaterlevelExporter here - - return getGauge(km, this.showAllGauges); - } - - public Gauge getGauge(final double km, final boolean allGauges) { - if (allGauges) - return this.gaugeIndex.findGauge(km); - - if ((this.refGauge != null) && this.refGauge.getRange().contains(km)) - return this.refGauge; - - return null; - } - - public String getReferenceGauge() { - return this.refGauge == null ? this.notinrange : this.refGauge.getName(); - } - - public River getRiver() { - return this.river; - } - - public List getGauges() { - return this.gaugeIndex.getGauges(); - } -} \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e 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 Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculation.java Thu Sep 27 18:06:26 2018 +0200 @@ -17,9 +17,9 @@ import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.model.CalculationResult; import org.dive4elements.river.artifacts.model.WQDay; +import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; 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.tkhstate.WinfoArtifactWrapper; import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; diff -r d8e753d0fdb9 -r 853f2dafc16e 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 Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Thu Sep 27 18:06:26 2018 +0200 @@ -30,9 +30,9 @@ import org.dive4elements.river.artifacts.model.WstValueTable; import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; import org.dive4elements.river.artifacts.model.WstValueTableFactory; +import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder; -import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey; import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; @@ -143,7 +143,7 @@ odays[j] = 365 - udays[i]; final QPosition qpos = wst.getQPosition(gauge.getStation().doubleValue(), qs[i]); if (qpos != null) { - ows[j] = wst.interpolateW(station, qpos, problems); + ows[j] = wst.interpolateW(station, qpos); oqs[j] = wst.getQ(qpos, station); } else { ows[j] = Double.NaN; diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Thu Sep 27 18:06:26 2018 +0200 @@ -16,9 +16,9 @@ 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.model.river.RiverInfoProvider; 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.tkhcalculation.DischargeValuesFinder; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder; diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java Thu Sep 27 18:06:26 2018 +0200 @@ -15,7 +15,7 @@ import org.apache.commons.lang.math.DoubleRange; import org.dive4elements.river.artifacts.common.GeneralResultType; import org.dive4elements.river.artifacts.common.ResultRow; -import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; +import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator.TkhCalculateState; diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.java Thu Sep 27 18:06:26 2018 +0200 @@ -20,9 +20,9 @@ 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.model.river.RiverInfoProvider; 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.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthUtils; import org.dive4elements.river.artifacts.sinfo.flowdepth.WstSoundingIdPair; diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java Thu Sep 27 18:06:26 2018 +0200 @@ -19,9 +19,9 @@ 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.model.river.RiverInfoProvider; 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.common.SInfoResultType; import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthUtils; import org.dive4elements.river.artifacts.sinfo.flowdepth.WstSoundingIdPair; diff -r d8e753d0fdb9 -r 853f2dafc16e 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 Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java Thu Sep 27 18:06:26 2018 +0200 @@ -27,11 +27,11 @@ import org.dive4elements.river.artifacts.common.ResultRow; import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.model.Calculation.Problem; +import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.model.CalculationResult; import org.dive4elements.river.artifacts.model.WQKms; 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.tkhcalculation.DischargeValuesFinder; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator.TkhCalculateState; diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java Thu Sep 27 18:06:26 2018 +0200 @@ -22,8 +22,8 @@ import org.dive4elements.river.artifacts.common.GeneralResultType; import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.model.CalculationResult; +import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.resources.Resources; -import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsUtils; import org.dive4elements.river.artifacts.sinfo.tkhstate.DefaultBedHeights; @@ -113,8 +113,8 @@ /** * Fills a map of delta-Ws by km-range from the regional scenario input data */ - private void fillRangeScenarios(final NavigableMap> rangeScenarios, final RangeAccess calcRange, - final double partFrom, final double partTo, final int[] deltaWs) { + private void fillRangeScenarios(final NavigableMap> rangeScenarios, final RangeAccess calcRange, final double partFrom, + final double partTo, final int[] deltaWs) { final List nulls = new ArrayList<>(); final List dwsm = new ArrayList<>(); for (int i = 0; i <= deltaWs.length - 1; i++) { @@ -145,8 +145,8 @@ /** * Fetches historical and reference bed heights and fills a map of delta-MSHs for all fetched stations in the calc range */ - private void fillRangeScenarios(final NavigableMap> rangeScenarios, final RangeAccess calcRange, - final double partFrom, final double partTo, final int historicalBedHeightId) { + private void fillRangeScenarios(final NavigableMap> rangeScenarios, final RangeAccess calcRange, final double partFrom, + final double partTo, final int historicalBedHeightId) { // Find relevant default bed-heights final River river = calcRange.getRiver(); @@ -173,8 +173,7 @@ final String msg = Resources.getMsg(this.context.getMeta(), "uinfo_salix_calc.warning.missing_bedheights"); this.problems.addProblem(station, msg); } - } - else + } else rangeScenarios.get(station).add(Double.valueOf(delta)); } rangeScenarios.put(Double.valueOf(partTo + 0.0001), nulls); @@ -270,6 +269,7 @@ return ""; } + // FIXME: check if needed /** * Fetches a iota or waterlevel height of a station from a salix calculation result */ diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculationResult.java Thu Sep 27 18:06:26 2018 +0200 @@ -22,7 +22,6 @@ import org.dive4elements.river.artifacts.common.IExportContext; import org.dive4elements.river.artifacts.common.MetaAndTableJRDataSource; import org.dive4elements.river.artifacts.common.ResultRow; -import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType; import org.dive4elements.river.artifacts.uinfo.salix.SalixLineCrossSectionIndexData.SalixWaterlevel; @@ -224,15 +223,4 @@ throw new UnsupportedOperationException(); } } - - /** - * Computes the height of a vegetation zone type for a station and a salix calculation result - */ - public double computeVegetationZoneHeight(final double station, final int vegetationZoneType, final SalixLineCalculationResult result) { - - final Calculation problems = new Calculation(); - - final SalixLineCalculator calculator = new SalixLineCalculator(null); - return calculator.computeVegetationZoneHeight(problems, station, vegetationZoneType, result); - } } \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java Thu Sep 27 18:06:26 2018 +0200 @@ -12,9 +12,7 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Map.Entry; import java.util.NavigableMap; @@ -24,18 +22,13 @@ import org.dive4elements.river.artifacts.common.GeneralResultType; import org.dive4elements.river.artifacts.common.ResultRow; import org.dive4elements.river.artifacts.model.Calculation; -import org.dive4elements.river.artifacts.model.WstValueTable; -import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; -import org.dive4elements.river.artifacts.model.WstValueTableFactory; -import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; +import org.dive4elements.river.artifacts.model.river.MainWstValuesCalculator; +import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; import org.dive4elements.river.artifacts.uinfo.UINFOArtifact; import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType; import org.dive4elements.river.artifacts.uinfo.salix.SalixLineAccess.ScenarioType; import org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZoneServerClientXChange; -import org.dive4elements.river.model.Gauge; -import org.dive4elements.river.model.MainValue; -import org.dive4elements.river.model.MainValueType.MainValueTypeKey; import org.dive4elements.river.utils.Formatter; /** @@ -45,31 +38,21 @@ */ final class SalixLineCalculator { + private static final String MAIN_VALUE_MNQ = "mnq"; + + private static final String MAIN_VALUE_MQ = "mq"; + + private static final String MAIN_VALUE_MHQ = "mhq"; + + private static final String MAIN_VALUE_HQ5 = "hq5"; + private static final BigDecimal SALIX_DISTANCE = new BigDecimal("2.31"); private final List rows = new ArrayList<>(); private final RiverInfoProvider riverInfoProvider; - private final Map gaugeMwPos; - private final Map gaugeMnwPos; - private final Map gaugeMhwPos; - private final Map gaugeHw5Pos; - private QPosition refGaugeMwPos; - private QPosition refGaugeMnwPos; - private QPosition refGaugeMhwPos; - private QPosition refGaugeHw5Pos; - private Gauge firstGauge; - - private Calculation problems; - - private WstValueTable wst; - public SalixLineCalculator(final RiverInfoProvider riverInfoProvider) { this.riverInfoProvider = riverInfoProvider; - this.gaugeMwPos = new HashMap<>(); - this.gaugeMnwPos = new HashMap<>(); - this.gaugeMhwPos = new HashMap<>(); - this.gaugeHw5Pos = new HashMap<>(); } /** @@ -79,16 +62,13 @@ final ScenarioType scenarioType, final String[] scenarioLabels, final String rangeString, final String additionalString, final SalixLineCalculationResults results) { - this.problems = problems; - this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver()); - - fetchGaugeMainValuePositions(); + final MainWstValuesCalculator mainWstValues = fetchGaugeMainValuePositions2(problems); final WINFOArtifact winfo = new WinfoArtifactWrapper(uinfo); winfo.addStringData("ld_mode", "distance"); winfo.addStringData("ld_step", "100"); for (final double station : new ComputationRangeAccess(winfo).getKms()) { - this.rows.add(createRow(station, rangeScenarios)); + this.rows.add(createRow(mainWstValues, station, rangeScenarios)); } if (scenarioType == ScenarioType.REGIONAL) results.addResult(new SalixLineCalculationRegionalResult("Salix-regional", scenarioLabels, rangeString, additionalString, this.rows), problems); @@ -100,54 +80,28 @@ results.addResult(new SalixLineCalculationResult("Salix-simple", this.rows), problems); } - /** - * Fetch MQ, MNQ and MHQ of all gauges and determine the wst QPosition for each one - */ - private void fetchGaugeMainValuePositions() { - this.gaugeMwPos.clear(); - this.gaugeMnwPos.clear(); - this.gaugeMhwPos.clear(); - this.gaugeHw5Pos.clear(); + private MainWstValuesCalculator fetchGaugeMainValuePositions2(final Calculation problems) { + final MainWstValuesCalculator mainWstValues = MainWstValuesCalculator.forRiverInfo(this.riverInfoProvider, MAIN_VALUE_MQ, MAIN_VALUE_MNQ, + MAIN_VALUE_MHQ, MAIN_VALUE_HQ5); - this.firstGauge = null; - for (final Gauge gauge : this.riverInfoProvider.getGauges()) { - this.gaugeMwPos.put(gauge, null); - this.gaugeMnwPos.put(gauge, null); - this.gaugeMhwPos.put(gauge, null); - this.gaugeHw5Pos.put(gauge, null); - final double gaugeKm = gauge.getStation().doubleValue(); - for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q)) { - if (mv.getMainValue().getName().equalsIgnoreCase("mq")) - this.gaugeMwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue())); - else if (mv.getMainValue().getName().equalsIgnoreCase("mnq")) - this.gaugeMnwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue())); - else if (mv.getMainValue().getName().equalsIgnoreCase("mhq")) - this.gaugeMhwPos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue())); - else if (mv.getMainValue().getName().equalsIgnoreCase("hq5")) - this.gaugeHw5Pos.put(gauge, this.wst.getQPosition(gaugeKm, mv.getValue().doubleValue())); - } - if (this.firstGauge == null) { - this.refGaugeMwPos = this.gaugeMwPos.get(gauge); - this.refGaugeMnwPos = this.gaugeMnwPos.get(gauge); - this.refGaugeMhwPos = this.gaugeMhwPos.get(gauge); - this.refGaugeHw5Pos = this.gaugeHw5Pos.get(gauge); - this.firstGauge = gauge; - } + if (!mainWstValues.hasPosition(MAIN_VALUE_MQ)) + problems.addProblem("uinfo_salix_calc.warning.missing_mq"); + else { + if (!mainWstValues.hasPosition(MAIN_VALUE_MHQ)) + problems.addProblem("uinfo_salix_calc.warning.missing_mhq"); + if (!mainWstValues.hasPosition(MAIN_VALUE_MNQ)) + problems.addProblem("uinfo_salix_calc.warning.missing_mnq"); } - if (this.refGaugeMwPos == null) - this.problems.addProblem("uinfo_salix_calc.warning.missing_mq"); - else { - if (this.refGaugeMhwPos == null) - this.problems.addProblem("uinfo_salix_calc.warning.missing_mhq"); - if (this.refGaugeMnwPos == null) - this.problems.addProblem("uinfo_salix_calc.warning.missing_mnq"); - } + + return mainWstValues; } /** * Create a result row for a station and its gauge, and add w-q-values as selected + * + * @param mainWstValues */ - private ResultRow createRow(final double station, final NavigableMap> rangeScenarios) { + private ResultRow createRow(final MainWstValuesCalculator mainWstValues, final double station, final NavigableMap> rangeScenarios) { final ResultRow row = ResultRow.create(); row.putValue(GeneralResultType.station, station); @@ -157,10 +111,10 @@ // final double mnw = interpolateW(station, this.gaugeMnwPos.get(gauge)); // final double mw = interpolateW(station, this.gaugeMwPos.get(gauge)); // final double mhw = interpolateW(station, this.gaugeMhwPos.get(gauge)); - final double mnw = interpolateW(station, this.refGaugeMnwPos); - final double mw = interpolateW(station, this.refGaugeMwPos); - final double mhw = interpolateW(station, this.refGaugeMhwPos); - final double hw5 = interpolateW(station, this.refGaugeHw5Pos); + final double mnw = mainWstValues.interpolateW(station, MAIN_VALUE_MNQ); + final double mw = mainWstValues.interpolateW(station, MAIN_VALUE_MQ); + final double mhw = mainWstValues.interpolateW(station, MAIN_VALUE_MHQ); + final double hw5 = mainWstValues.interpolateW(station, MAIN_VALUE_HQ5); row.putValue(UInfoResultType.waterlevelMNW, mnw); row.putValue(UInfoResultType.waterlevelMW, mw); row.putValue(UInfoResultType.waterlevelMHW, mhw); @@ -179,8 +133,7 @@ final double salix = calcSalix(mhw, mw, deltaw.doubleValue()); final double scen = calcSalix(mhw, 0.0, deltaw.doubleValue()); scenarios.add(new SalixScenario((int) (deltaw * 100), salix, scen)); - } - else { + } else { scenarios.add(null); } } @@ -190,15 +143,6 @@ } /** - * Interpolates the W for a station with a fixed (virtual) wst column position - */ - private double interpolateW(final double station, final QPosition qPosition) { - if (qPosition != null) - return this.wst.interpolateW(station, qPosition, this.problems); - return Double.NaN; - } - - /** * Calculates the salix value */ private double calcSalix(final double mhw, final double mw, final double deltamw) { @@ -263,6 +207,7 @@ final ResultRow stationRow = searchStation(station, result.getRows()); if (stationRow == null) return Double.NaN; + // Compute height from overflow duration days final List vzs = VegetationZoneServerClientXChange.getStandardList(null, null); // TODO river, context if ((vegetationZoneType >= 1) && (vegetationZoneType <= vzs.size())) { diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineProcessor.java Thu Sep 27 18:06:26 2018 +0200 @@ -26,6 +26,7 @@ import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType; import org.dive4elements.river.artifacts.uinfo.salix.SalixLineCrossSectionIndexData.SalixWaterlevel; import org.dive4elements.river.exports.DiagramGenerator; +import org.dive4elements.river.jfree.StripedAreaDataset; import org.dive4elements.river.jfree.StripedAreaDataset.Stripe; import org.dive4elements.river.themes.ThemeDocument; @@ -178,14 +179,17 @@ if (bundle.getFacetName().equals(FACET_SALIX_RANK)) { final CallMeta meta = generator.getContext().getMeta(); - final Stripe[] stripes = new Stripe[] { // - new Stripe(getSimpleMsg("uinfo_salix_rank.excellent", meta), Color.decode("#00B0F0"), -0.3, 0.3), // - new Stripe(getSimpleMsg("uinfo_salix_rank.good", meta), Color.decode("#00B050"), 0.3, 0.5), // - new Stripe(getSimpleMsg("uinfo_salix_rank.moderate", meta), Color.decode("#FFFF00"), 0.5, 1.0), // - new Stripe(getSimpleMsg("uinfo_salix_rank.bad", meta), Color.decode("#FFC000"), 1.0, 1.5), // - new Stripe(getSimpleMsg("uinfo_salix_rank.very_bad", meta), Color.decode("#FF0000"), 1.5, Double.NaN) }; - return buildStripedAreaSeries(stripes, generator, bundle, theme, visible); + final StripedAreaDataset dataset = new StripedAreaDataset(theme); + dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.excellent", meta), Color.decode("#00B0F0"), -0.3, 0.3)); + dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.good", meta), Color.decode("#00B050"), 0.3, 0.5)); + dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.moderate", meta), Color.decode("#FFFF00"), 0.5, 1.0)); + dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.bad", meta), Color.decode("#FFC000"), 1.0, 1.5)); + dataset.addStripe(new Stripe(getSimpleMsg("uinfo_salix_rank.very_bad", meta), Color.decode("#FF0000"), 1.5, Double.NaN)); + + generator.addAxisDataset(dataset, getAxisName(), visible); + + return null; } return buildSeriesForType(generator, bundle, theme, visible, doGetType(bundle.getFacetName()), GAP_DISTANCE); diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCrossSectionProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCrossSectionProcessor.java Thu Sep 27 18:06:26 2018 +0200 @@ -0,0 +1,118 @@ +/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ +package org.dive4elements.river.artifacts.uinfo.vegetationzones; + +import java.awt.Color; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; +import org.dive4elements.artifactdatabase.state.Facet; +import org.dive4elements.artifacts.Artifact; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.artifacts.DataProvider; +import org.dive4elements.river.artifacts.common.AbstractCalculationResult; +import org.dive4elements.river.artifacts.common.AbstractProcessor; +import org.dive4elements.river.artifacts.model.CrossSectionFacetUtils; +import org.dive4elements.river.artifacts.model.river.MainWstValuesCalculator; +import org.dive4elements.river.artifacts.uinfo.UINFOArtifact; +import org.dive4elements.river.exports.CrossSectionGenerator; +import org.dive4elements.river.exports.DiagramGenerator; +import org.dive4elements.river.jfree.StripedAreaDataset; +import org.dive4elements.river.jfree.StripedAreaDataset.Stripe; +import org.dive4elements.river.model.FastCrossSectionLine; +import org.dive4elements.river.model.River; +import org.dive4elements.river.themes.ThemeDocument; + +/** + * @author Domenico Nardi Tironi + * + */ +public class VegetationZonesCrossSectionProcessor extends AbstractProcessor { + + private static final String MAIN_VALUE_MQ = "mq"; + + public static final String FACET_VEGETATION_ZONES_CROSS_SECTION = "uinfo_facet_vegetation_zones_cross_section"; + + private static final String FACET_VEGETATION_ZONES_CROSS_SECTION_DESCRIPTION = "uinfo_facet_vegetation_zones_cross_section.description"; + + private static final Set HANDLED_FACET_TYPES = new HashSet<>(); + + static { + HANDLED_FACET_TYPES.add(FACET_VEGETATION_ZONES_CROSS_SECTION); + } + + public static Facet createVegetationZonesCrossSectionFacet(final CallContext context, final String hash, final String id, + final AbstractCalculationResult result, final int index) { + return AbstractProcessor.createFacet(context, hash, id, result, index, CrossSectionGenerator.I18N_XAXIS_LABEL, FACET_VEGETATION_ZONES_CROSS_SECTION, + FACET_VEGETATION_ZONES_CROSS_SECTION_DESCRIPTION); + } + + public static void generateSeries(final CrossSectionGenerator generator, final ArtifactAndFacet bundle, final CallContext context, + final ThemeDocument theme, final boolean visible) { + + final DataProvider provider = CrossSectionFacetUtils.getDataProvider(context); + final FastCrossSectionLine crossSection = CrossSectionFacetUtils.getCrossSection(provider, context); + if (crossSection == null) + return; + final double currentStation = crossSection.getKm(); + + if (bundle.getFacetName().equals(FACET_VEGETATION_ZONES_CROSS_SECTION)) { + + final StripedAreaDataset dataset = new StripedAreaDataset(theme); + + final Artifact artifact = bundle.getArtifact(); + final VegetationzonesAccess vAccess = new VegetationzonesAccess((UINFOArtifact) artifact); + final River river = vAccess.getRiver(); + final List zones = VegetationZoneServerClientXChange.parse(vAccess.getVegZones()); + + for (final VegetationZoneServerClientXChange zone : zones) { + + final double lower = uefdToHeight(context, river, currentStation, zone.getLowerFromTo()); + final double upper = uefdToHeight(context, river, currentStation, zone.getUpperFromTo()); + + final Color color = Color.decode(zone.getHexColor()); + dataset.addStripe(new Stripe(zone.getZoneName(), color, lower, upper)); + } + + generator.addAxisDataset(dataset, 0, visible); + return; + } + + throw new UnsupportedOperationException(); + } + + private static double uefdToHeight(final CallContext context, final River river, final double station, final int uefd) { + + final MainWstValuesCalculator mainWstValues = MainWstValuesCalculator.forRiver(context, river, null, MAIN_VALUE_MQ); + + final double mw = mainWstValues.interpolateW(station, MAIN_VALUE_MQ); + + // Üfd = -70,559 ∗ ln((DGM - MW) + 0,5) + 80,711 + final double f1 = -70.559; + final double f2 = -88.711; + + final double dgm = Math.exp((uefd - f2) / f1) + mw - 0.5; + return dgm; + } + + public VegetationZonesCrossSectionProcessor() { + super(CrossSectionGenerator.I18N_YAXIS_LABEL, HANDLED_FACET_TYPES); + + throw new UnsupportedOperationException(); + } + + @Override + protected String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) { + throw new UnsupportedOperationException(); + } + +} \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesState.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesState.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesState.java Thu Sep 27 18:06:26 2018 +0200 @@ -79,6 +79,9 @@ final List resultList = results.getResults(); if (!resultList.isEmpty()) { + + facets.add(VegetationZonesCrossSectionProcessor.createVegetationZonesCrossSectionFacet(context, hash, this.id, resultList.get(0), 0)); + final Facet csv = new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id); final Facet pdf = new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id); diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/AbstractChartGenerator.java Thu Sep 27 18:06:26 2018 +0200 @@ -989,7 +989,7 @@ * @param visible * Determines, if the dataset should be visible or not. */ - protected final void addAxisDataset(final XYDataset dataset, final int idx, final boolean visible) { + public final void addAxisDataset(final XYDataset dataset, final int idx, final boolean visible) { if (dataset == null || idx < 0) { return; } diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/CrossSectionGenerator.java Thu Sep 27 18:06:26 2018 +0200 @@ -25,6 +25,7 @@ import org.dive4elements.river.artifacts.model.FacetTypes; import org.dive4elements.river.artifacts.model.HYKFactory; import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZonesCrossSectionProcessor; import org.dive4elements.river.jfree.RiverAnnotation; import org.dive4elements.river.jfree.StyledXYSeries; import org.dive4elements.river.model.FastCrossSectionLine; @@ -307,6 +308,9 @@ attr, visible); } + else if (name.equals(VegetationZonesCrossSectionProcessor.FACET_VEGETATION_ZONES_CROSS_SECTION)) { + VegetationZonesCrossSectionProcessor.generateSeries(this, artifactFacet, context, attr, visible); + } else if (FacetTypes.IS.MANUALLINE(name)) { doCrossSectionWaterLineOut( artifactFacet.getData(context), diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/resources/messages.properties --- a/artifacts/src/main/resources/messages.properties Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/resources/messages.properties Thu Sep 27 18:06:26 2018 +0200 @@ -1193,6 +1193,7 @@ uinfo_facet_salix_scenario = Iota Scenario, {0} uinfo_facet_salix_scenario.filtered.description = Iota Scenario, {0} uinfo_facet_salix_scenario.raw.description = Iota Scenario, {0} (raw data) +uinfo_facet_vegetation_zones_cross_section.description = Vegetation Zones uinfo_salix_scenario_deltaw = \u0394MW={0} uinfo_salix_scenario_supraregional = supraregional uinfo_salix_scenario_historical = historical diff -r d8e753d0fdb9 -r 853f2dafc16e artifacts/src/main/resources/messages_de.properties --- a/artifacts/src/main/resources/messages_de.properties Wed Sep 26 15:48:05 2018 +0200 +++ b/artifacts/src/main/resources/messages_de.properties Thu Sep 27 18:06:26 2018 +0200 @@ -1193,6 +1193,7 @@ uinfo_facet_salix_scenario = Iota Szenario, {0} uinfo_facet_salix_scenario.filtered.description = Iota Szenario, {0} uinfo_facet_salix_scenario.raw.description = Iota Szenario, {0} (Rohdaten) +uinfo_facet_vegetation_zones_cross_section.description = Vegetationszonen uinfo_salix_scenario_deltaw = \u0394MW={0} uinfo_salix_scenario_supraregional = \u00fcberregional uinfo_salix_scenario_historical = historisch diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java --- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Wed Sep 26 15:48:05 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Thu Sep 27 18:06:26 2018 +0200 @@ -1618,4 +1618,6 @@ String no_data_for_input(); String bundu_bezugswsts(); + + String vegetation_zones(); // Order für Datenkorb } \ No newline at end of file diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties --- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Wed Sep 26 15:48:05 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Thu Sep 27 18:06:26 2018 +0200 @@ -826,11 +826,14 @@ uinfo = U-INFO uinfo_salix_dmwspl_short = \u0394MW [cm] uinfo_inundation_duration_export = Flooding Durations Export +uinfo_inundation_duration_report= Flooding Durations Report uinfo_inundation_duration_set_vegetation_zone = Set Vegetation Zone Table uinfo_salix_line_export = Iota Export uinfo_vegetation_zones_export = Vegetation Zones Export +uinfo_vegetation_zones_report = Vegetation Zones Report defaultVegetationZone = Default Vegetation Zone +vegetation_zones = Vegetation Zones uinfo_vegetation_zone_overlap = Ranges are overlapping. uinfo_vegetation_zone_has_gaps = The input (0-365) has gaps. uinfo_vegetation_zone_color = Color diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties --- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Wed Sep 26 15:48:05 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Thu Sep 27 18:06:26 2018 +0200 @@ -826,11 +826,14 @@ uinfo = U-INFO uinfo_salix_dmwspl_short = \u0394MW [cm] uinfo_inundation_duration_export = \u00dcberflutungsdauern Export +uinfo_inundation_duration_export = \u00dcberflutungsdauern Bericht uinfo_inundation_duration_set_vegetation_zone = Vegetationstabelle \u00fcbernehmen uinfo_salix_line_export = Iota Export uinfo_vegetation_zones_export = Vegetationszonen Export +uinfo_vegetation_zones_report = Vegetationszonen Bericht defaultVegetationZone = Standardvegetationszone +vegetation_zones = Vegetationszonen uinfo_vegetation_zone_overlap = Bereiche \u00fcberlappen. uinfo_vegetation_zone_has_gaps = Die Wertebelegung (0-365) weist L\u00fccken auf. uinfo_vegetation_zone_color = Farbe diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/server/CollectionHelper.java --- a/gwt-client/src/main/java/org/dive4elements/river/client/server/CollectionHelper.java Wed Sep 26 15:48:05 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/server/CollectionHelper.java Thu Sep 27 18:06:26 2018 +0200 @@ -822,35 +822,41 @@ continue; } - OutputMode outmode = null; List fs = extractFacets(tmp); - if (type.equals("export")) { - outmode = new ExportMode(name, desc, mime, fs); - } - else if (type.equals("report")) { - outmode = new ReportMode(name, desc, mime, fs); - } - else if (type.equals("chart")){ - outmode = new ChartMode(name, desc, mime, fs, type); - } - else if (type.equals("map")){ - outmode = new MapMode(name, desc, mime, fs); - } - else if (type.equals("overview")) { - outmode = new OverviewMode(name, desc, mime, fs, type); - } - else { - log.warn("Broken Output mode without type found."); - continue; - } - - modes.add(outmode); + final OutputMode outmode = createOutputMode( type, name, desc, mime, fs ); + if( outmode != null ) + modes.add(outmode); } return modes; } + private static OutputMode createOutputMode(String type, String name, String desc, String mime, List fs) { + + if (type.equals("export")) + return new ExportMode(name, desc, mime, fs); + + if (type.equals("report")) + return new ReportMode(name, desc, mime, fs); + + if (type.equals("chart")) + return new ChartMode(name, desc, mime, fs, type); + + if (type.equals("map")) + return new MapMode(name, desc, mime, fs); + + if (type.equals("overview")) + return new OverviewMode(name, desc, mime, fs, type); + + if (type.equals("invisible")) + return null; + + log.warn("Broken Output mode without type found."); + + return null; + } + /** * Create a Key/Value map for data nodes of artifact/collectionitem. diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/shared/model/DefaultCollectionItem.java --- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/DefaultCollectionItem.java Wed Sep 26 15:48:05 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/DefaultCollectionItem.java Thu Sep 27 18:06:26 2018 +0200 @@ -11,7 +11,6 @@ import java.util.List; import java.util.Map; - /** * The default implementation of a CollectionItem (artifact). * @@ -19,6 +18,8 @@ */ public class DefaultCollectionItem implements CollectionItem { + private static final long serialVersionUID = 1L; + /** The identifier that specifies the artifact related to this item. */ protected String identifier; @@ -31,52 +32,46 @@ /** The map of datanames to data values. */ protected Map data; - /** * An empty constructor. */ public DefaultCollectionItem() { } - /** * The default constructor to create a new CollectionItem related to an * artifact with output modes. * - * @param identifier The identifier of an artifact. - * @param outputModes The output modes supported by this item. + * @param identifier + * The identifier of an artifact. + * @param outputModes + * The output modes supported by this item. */ - public DefaultCollectionItem( - String identifier, - String hash, - List modes, - Map data - ) { - this.identifier = identifier; - this.hash = hash; + public DefaultCollectionItem(final String identifier, final String hash, final List modes, final Map data) { + this.identifier = identifier; + this.hash = hash; this.outputModes = modes; - this.data = data; + this.data = data; } - - + @Override public String identifier() { - return identifier; + return this.identifier; } - + @Override public String hash() { - return hash; + return this.hash; } - + @Override public List getOutputModes() { - return outputModes; + return this.outputModes; } - - public List getFacets(String outputmode) { - for (OutputMode mode: outputModes) { + @Override + public List getFacets(final String outputmode) { + for (final OutputMode mode : this.outputModes) { if (outputmode.equals(mode.getName())) { // TODO Return facets, but facets are not implemented for // OutputModes yet! @@ -86,11 +81,12 @@ return null; } - /** * Returns artifact data. + * * @return key/value data map */ + @Override public Map getData() { return this.data; } diff -r d8e753d0fdb9 -r 853f2dafc16e gwt-client/src/main/java/org/dive4elements/river/client/shared/model/VegetationZoneServerClientXChange.java --- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/VegetationZoneServerClientXChange.java Wed Sep 26 15:48:05 2018 +0200 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/VegetationZoneServerClientXChange.java Thu Sep 27 18:06:26 2018 +0200 @@ -45,14 +45,16 @@ } for (final String[] zone : results) { - final VegetationZoneServerClientXChange helper = new VegetationZoneServerClientXChange(zone[0], Integer.valueOf(zone[1]), Integer.valueOf(zone[2]), zone[3]); + final VegetationZoneServerClientXChange helper = new VegetationZoneServerClientXChange(zone[0], Integer.valueOf(zone[1]), Integer.valueOf(zone[2]), + zone[3]); resultList.add(helper); } return resultList; } - public static VegetationZoneServerClientXChange createFromTableEntry(final String zone, final String min_day_overflow, final String max_day_overflow, final String hexColor) { + public static VegetationZoneServerClientXChange createFromTableEntry(final String zone, final String min_day_overflow, final String max_day_overflow, + final String hexColor) { return new VegetationZoneServerClientXChange(zone, Integer.valueOf(min_day_overflow), Integer.valueOf(max_day_overflow), hexColor); // Error-Handling? } @@ -159,7 +161,7 @@ treeList.addAll(list); int lowerCompare = lower; for (final VegetationZoneServerClientXChange zone : treeList) { - if (zone.getLowerFromTo() > (lowerCompare + 1)) { // nicht inklusiv + if (zone.getLowerFromTo() > (lowerCompare)) { // nicht inklusiv return true; } lowerCompare = zone.getUpperFromTo(); @@ -176,12 +178,12 @@ final int upper = getUpperFromTo(); final int lower = getLowerFromTo(); - final int otherSchwerpunkt = (otherLower + otherUpper) / 2; - if ((otherUpper <= upper && otherUpper >= lower)) { + // final int otherSchwerpunkt = (otherLower + otherUpper) / 2; + if ((otherUpper <= upper && otherUpper > lower)) { return true; - } else if (otherLower >= lower && otherLower <= upper) { + } else if (otherLower >= lower && otherLower < upper) { return true; - } else if (otherSchwerpunkt >= (lower) && otherSchwerpunkt <= (upper)) { + } else if (otherLower == lower && otherUpper == upper) { return true; } return false;