# HG changeset patch # User mschaefer # Date 1519305079 -3600 # Node ID d32c22fc686ceb307d6641333346b92bd1819d01 # Parent 3dd0c77a4b27bc752fc37d12464d5c6dfc351052# Parent 863f2850dbcf3bfafa13c8304a08659539576d70 Merge diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/doc/conf/artifacts/sinfo.xml --- a/artifacts/doc/conf/artifacts/sinfo.xml Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/doc/conf/artifacts/sinfo.xml Thu Feb 22 14:11:19 2018 +0100 @@ -56,7 +56,7 @@ - + @@ -64,22 +64,7 @@ - diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml --- a/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml Thu Feb 22 14:11:19 2018 +0100 @@ -14,7 +14,7 @@ - + @@ -45,6 +45,8 @@ - + + + \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/doc/conf/meta-data.xml --- a/artifacts/doc/conf/meta-data.xml Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/doc/conf/meta-data.xml Thu Feb 22 14:11:19 2018 +0100 @@ -117,6 +117,10 @@ + + + + @@ -255,6 +259,12 @@ + + + + + + diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedHeightInfo.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedHeightInfo.java Thu Feb 22 12:07:16 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +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.flowdepth; - -import java.io.Serializable; - -import org.dive4elements.river.model.BedHeight; - -/** - * Basic infos about a {@link BedHeight}. - * - * @author Gernot Belger - */ -final class BedHeightInfo implements Serializable { - - private static final long serialVersionUID = 1L; - - private final Integer year; - - private final String description; - - private final String type; - - private final String evaluationBy; - - private final String locationSystem; - - private final String curElevationModelUnit; - - private final String oldElevationModelUnit; - - - public static BedHeightInfo from(final BedHeight bedHeight) { - return new BedHeightInfo(bedHeight); - } - - private BedHeightInfo(final BedHeight bedHeight) { - this.year = bedHeight.getYear(); - this.description = bedHeight.getDescription(); - this.type = bedHeight.getType().getName(); - this.evaluationBy = bedHeight.getEvaluationBy(); - this.locationSystem = bedHeight.getLocationSystem().getName(); - this.curElevationModelUnit = bedHeight.getCurElevationModel().getUnit().getName(); - this.oldElevationModelUnit = bedHeight.getCurElevationModel().getUnit().getName(); - } - - public Integer getYear() { - return this.year; - } - - public String getDescription() { - return this.description; - } - - public String getType() { - return this.type; - } - - public String getEvaluationBy() { - return this.evaluationBy; - } - - public String getLocationSystem() { - return this.locationSystem; - } - - public String getCurElevationModelUnit() { - return this.curElevationModelUnit; - } - - public String getOldElevationModelUnit() { - return this.oldElevationModelUnit; - } -} diff -r 3dd0c77a4b27 -r d32c22fc686c 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 Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Thu Feb 22 14:11:19 2018 +0100 @@ -32,6 +32,9 @@ 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.sinfo.util.BedHeightInfo; +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.artifacts.states.WaterlevelFetcher; import org.dive4elements.river.model.BedHeight; @@ -68,6 +71,7 @@ /* access input data */ final FlowDepthAccess access = new FlowDepthAccess(sinfo); final River river = access.getRiver(); + final RiverInfo riverInfo = new RiverInfo(river); final Collection diffPairs = access.getDifferencePairs(); @@ -85,7 +89,7 @@ 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, riverInfo, calcRange, useTkh); for (final DifferencesPair diffPair : diffPairs) { final FlowDepthCalculationResult result = calculateResult(river, calcRange, diffPair, problems, gaugeIndex, useTkh); @@ -107,6 +111,7 @@ final String wstId = diffPair.getWstId(); final BedHeight bedHeight = loadBedHeight(soundingId); + final BedHeight bedHeight = loadBedHeight(soundingId); if (bedHeight == null) { final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", soundingId); problems.addProblem(message); @@ -127,7 +132,8 @@ final String label = String.format("%s - %s", wspLabel, soundingLabel); checkYearDifference(label, waterlevel, bedHeight, problems); - checkWaterlevelDiscretisation(wstKms, problems); + checkWaterlevelDiscretisation(wstKms, calcRange, problems); + // TODO: prüfen, ob sohlhöen die calcRange abdecken/überschneiden /* 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); @@ -202,7 +208,9 @@ if (!calcRange.containsDouble(km)) continue; - + if (!calcRange.containsDouble(km)) + continue; + try { // FIXME: check out of range final double wst = wstInterpolator.value(km); @@ -287,7 +295,6 @@ break; } - // REMARK: access the location once only during calculation final String location = LocationProvider.getLocation(river.getName(), km); @@ -356,7 +363,8 @@ 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, difference); + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.year_difference", null, label, wstYear, + soundingYear); problems.addProblem(message); } } @@ -392,18 +400,22 @@ } /* Checks if the discretisation of the waterlevel exceeds 1000m */ - // FIXME: vermutlich sollten wir diesen check auf den gültigkeitsbereich einschränken - private void checkWaterlevelDiscretisation(final WKms wstKms, final Calculation problems) { + + private void checkWaterlevelDiscretisation(final WKms wstKms, final DoubleRange calcRange, 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(); + /* only check if we are within the calculation range */ + if (calcRange.overlapsRange(new DoubleRange(kmPrev, kmNext))) { + 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); + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.waterlevel_discretisation", null, label); + problems.addProblem(kmPrev, message); + } } } } diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Thu Feb 22 14:11:19 2018 +0100 @@ -15,6 +15,9 @@ import java.util.Collections; import java.util.List; +import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; + import gnu.trove.TDoubleArrayList; /** diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java Thu Feb 22 14:11:19 2018 +0100 @@ -14,7 +14,8 @@ import java.util.Collections; import java.util.List; -import org.dive4elements.river.model.River; +import org.apache.commons.lang.math.DoubleRange; +import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; /** * @author Gernot Belger @@ -24,25 +25,22 @@ private final List results = new ArrayList<>(); - private final River river; - - private final double from; - - private final double to; - - private final boolean useTkh; - private final String calcModeLabel; private final String user; - public FlowDepthCalculationResults(final String calcModeLabel, final String user, final River river, - final double from, final double to, final boolean useTkh) { + private final RiverInfo river; + + private final boolean useTkh; + + private final DoubleRange calcRange; + + public FlowDepthCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange, + final boolean useTkh) { this.calcModeLabel = calcModeLabel; this.user = user; this.river = river; - this.from = from; - this.to = to; + this.calcRange = calcRange; this.useTkh = useTkh; } @@ -54,16 +52,12 @@ return this.user; } - public River getRiver() { + public RiverInfo getRiver() { return this.river; } - public double getFrom() { - return this.from; - } - - public double getTo() { - return this.to; + public DoubleRange getCalcRange() { + return this.calcRange; } public boolean isUseTkh() { @@ -77,4 +71,4 @@ public List getResults() { return Collections.unmodifiableList(this.results); } -} +} \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthChartExtender.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthChartExtender.java Thu Feb 22 14:11:19 2018 +0100 @@ -0,0 +1,59 @@ +/** 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.flowdepth; + +import java.awt.BasicStroke; +import java.awt.Stroke; + +import org.dive4elements.river.exports.ChartExtender; +import org.dive4elements.river.exports.DiagramGenerator; +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.plot.XYPlot; + +/** + * @author Gernot Belger + */ +public class FlowDepthChartExtender implements ChartExtender { + /** + * Synchronizes the location of '0' on the flow-depth-axis with the tkh-axis, by extending the lower bound of the + * flow-depth-axis. + */ + @Override + public void afterAutoZoom(final DiagramGenerator generator) { + final ValueAxis axis1 = generator.getAxis("flowdepthAxis"); + final ValueAxis axis2 = generator.getAxis("tkhAxis"); + if (axis1 == null || axis2 == null) + return; + + final double axis2lb = axis2.getLowerBound(); + final double axis1ub = axis1.getUpperBound(); + final double axis2ub = axis2.getUpperBound(); + + final double ratio = axis2lb / (axis2ub - axis2lb); + final double axis1lbNew = axis1ub / (1 / ratio + 1); + + axis1.setLowerBound(axis1lbNew); + } + + @Override + public void afterGenerateChart(final DiagramGenerator generator, final XYPlot plot) { + + final ValueAxis tkhAxis = generator.getAxis("tkhAxis"); + if (tkhAxis != null) { + /* show baseline if tkhAxis is present */ + + // TODO: it would probably better to configure this via the ChartSettings, but currently no chart settings are loaded, + // so it is unclear if that feature still works. + final Stroke baselineStroke = new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); + plot.setRangeZeroBaselineStroke(baselineStroke); + plot.setRangeZeroBaselineVisible(true); + } + } +} \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java Thu Feb 22 14:11:19 2018 +0100 @@ -10,6 +10,7 @@ import java.io.OutputStream; import java.text.DateFormat; +import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -18,16 +19,18 @@ import java.util.Map; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.math.DoubleRange; import org.apache.log4j.Logger; import org.dive4elements.artifacts.CallMeta; import org.dive4elements.artifacts.common.utils.Config; import org.dive4elements.river.FLYS; import org.dive4elements.river.artifacts.model.CalculationResult; import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource; +import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; import org.dive4elements.river.exports.AbstractExporter; -import org.dive4elements.river.model.River; -import org.dive4elements.river.model.Unit; import org.dive4elements.river.utils.RiverUtils; import au.com.bytecode.opencsv.CSVWriter; @@ -151,7 +154,7 @@ final FlowDepthCalculationResults results = this.data; final boolean useTkh = results.isUseTkh(); - final River river = results.getRiver(); + final RiverInfo river = results.getRiver(); /* write as csv */ writeCSVMeta(writer, results); @@ -204,7 +207,7 @@ log.info("FlowDepthExporter.writeCSVMeta"); final String calcModeLabel = results.getCalcModeLabel(); - final River river = results.getRiver(); + final RiverInfo river = results.getRiver(); writeCSVMetaEntry(writer, CSV_META_HEADER_RESULT, msg(CSV_META_HEADER_RESULT_LABEL), river.getName(), calcModeLabel); // "# FLYS-Version: " @@ -222,12 +225,12 @@ writeCSVMetaEntry(writer, CSV_META_RIVER, msg(CSV_META_RIVER_LABEL), river.getName()); // "# Höhensystem des Flusses: " - final Unit wstUnit = river.getWstUnit(); - writeCSVMetaEntry(writer, CSV_META_HEIGHT_UNIT_RIVER, wstUnit.getName()); + writeCSVMetaEntry(writer, CSV_META_HEIGHT_UNIT_RIVER, river.getWstUnit()); // "# Ort/Bereich (km): " - writeCSVMetaEntry(writer, CSV_META_RANGE, msg(CSV_META_RANGE_LABEL), getKmFormatter().format(results.getFrom()), - getKmFormatter().format(results.getTo())); + final DoubleRange calcRange = results.getCalcRange(); + writeCSVMetaEntry(writer, CSV_META_RANGE, msg(CSV_META_RANGE_LABEL), getKmFormatter().format(calcRange.getMinimumDouble()), + getKmFormatter().format(calcRange.getMaximumDouble())); writer.writeNext(new String[] { "" }); } @@ -246,7 +249,7 @@ * @param river * @param useTkh */ - private void writeCSVHeader(final CSVWriter writer, final River river, final boolean useTkh) { + private void writeCSVHeader(final CSVWriter writer, final RiverInfo river, final boolean useTkh) { log.info("FlowDepthExporter.writeCSVHeader"); final Collection header = new ArrayList<>(11); @@ -258,12 +261,11 @@ header.add(msgUnit(CSV_TKH_HEADER, UNIT_CM)); } - final String wstUnitName = river.getWstUnit().getName(); - header.add(msgUnit(CSV_WATERLEVEL_HEADER, wstUnitName)); + header.add(msgUnit(CSV_WATERLEVEL_HEADER, river.getWstUnit())); header.add(msgUnit(CSV_DISCHARGE_HEADER, UNIT_CUBIC_M)); header.add(msg(CSV_LABEL_HEADER)); header.add(msg(CSV_GAUGE_HEADER)); - header.add(msgUnit(CSV_MEAN_BED_HEIGHT_HEADER, wstUnitName)); + header.add(msgUnit(CSV_MEAN_BED_HEIGHT_HEADER, river.getWstUnit())); header.add(msg(CSV_SOUNDING_HEADER)); header.add(msg(CSV_LOCATION_HEADER)); @@ -376,8 +378,8 @@ private void addJRMetaData(final MetaAndTableJRDataSource source, final FlowDepthCalculationResults results) { - final River river = results.getRiver(); - final String wstUnitName = river.getWstUnit().getName(); + final RiverInfo river = results.getRiver(); + final String wstUnitName = river.getWstUnit(); /* general metadata */ source.addMetaData("header", msg(CSV_META_HEADER_RESULT_LABEL)); @@ -397,7 +399,9 @@ source.addMetaData("river_label", msg(CSV_META_RIVER_LABEL)); source.addMetaData("river", river.getName()); - final String rangeValue = String.format("%s - %s", getKmFormatter().format(results.getFrom()), getKmFormatter().format(results.getTo())); + final DoubleRange calcRange = results.getCalcRange(); + final NumberFormat kmFormatter = getKmFormatter(); + final String rangeValue = String.format("%s - %s", kmFormatter.format(calcRange.getMinimumDouble()), kmFormatter.format(calcRange.getMaximumDouble())); source.addMetaData("range_label", msg(CSV_META_RANGE_LABEL)); source.addMetaData("range", rangeValue); diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/WstInfo.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/WstInfo.java Thu Feb 22 12:07:16 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +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.flowdepth; - -import java.io.Serializable; - -/** - * @author Gernot Belger - */ -final class WstInfo implements Serializable { - - private static final long serialVersionUID = 1L; - - private final String label; - - private final int year; - - private final String gauge; - - public WstInfo(final String label, final int year, final String gauge) { - this.label = label; - this.year = year; - this.gauge = gauge; - } - - public String getLabel() { - return this.label; - } - - public int getYear() { - return this.year; - } - - public String getGauge() { - return this.gauge; - } -} \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/BedHeightInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/BedHeightInfo.java Thu Feb 22 14:11:19 2018 +0100 @@ -0,0 +1,81 @@ +/** 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.util; + +import java.io.Serializable; + +import org.dive4elements.river.model.BedHeight; + +/** + * Basic infos about a {@link BedHeight}. + * + * @author Gernot Belger + */ +public final class BedHeightInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + private final Integer year; + + private final String description; + + private final String type; + + private final String evaluationBy; + + private final String locationSystem; + + private final String curElevationModelUnit; + + private final String oldElevationModelUnit; + + + public static BedHeightInfo from(final BedHeight bedHeight) { + return new BedHeightInfo(bedHeight); + } + + private BedHeightInfo(final BedHeight bedHeight) { + this.year = bedHeight.getYear(); + this.description = bedHeight.getDescription(); + this.type = bedHeight.getType().getName(); + this.evaluationBy = bedHeight.getEvaluationBy(); + this.locationSystem = bedHeight.getLocationSystem().getName(); + this.curElevationModelUnit = bedHeight.getCurElevationModel().getUnit().getName(); + this.oldElevationModelUnit = bedHeight.getCurElevationModel().getUnit().getName(); + } + + public Integer getYear() { + return this.year; + } + + public String getDescription() { + return this.description; + } + + public String getType() { + return this.type; + } + + public String getEvaluationBy() { + return this.evaluationBy; + } + + public String getLocationSystem() { + return this.locationSystem; + } + + public String getCurElevationModelUnit() { + return this.curElevationModelUnit; + } + + public String getOldElevationModelUnit() { + return this.oldElevationModelUnit; + } +} diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/RiverInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/RiverInfo.java Thu Feb 22 14:11:19 2018 +0100 @@ -0,0 +1,41 @@ +/** 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.util; + +import java.io.Serializable; + +import org.dive4elements.river.model.River; + +/** + * Contains similar data as {@link River}, but is used in instead to avoid keeping database objects. + * + * @author Gernot Belger + */ +public class RiverInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String name; + + private final String wstUnit; + + public RiverInfo(final River river) { + this.name = river.getName(); + this.wstUnit = river.getWstUnit().getName(); + } + + public String getName() { + return this.name; + } + + public String getWstUnit() { + return this.wstUnit; + } +} \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/WstInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/util/WstInfo.java Thu Feb 22 14:11:19 2018 +0100 @@ -0,0 +1,44 @@ +/** 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.util; + +import java.io.Serializable; + +/** + * @author Gernot Belger + */ +public final class WstInfo implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String label; + + private final int year; + + private final String gauge; + + public WstInfo(final String label, final int year, final String gauge) { + this.label = label; + this.year = year; + this.gauge = gauge; + } + + public String getLabel() { + return this.label; + } + + public int getYear() { + return this.year; + } + + public String getGauge() { + return this.gauge; + } +} \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/exports/ChartExtender.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartExtender.java Thu Feb 22 14:11:19 2018 +0100 @@ -0,0 +1,34 @@ +/** 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.exports; + +import org.jfree.chart.plot.XYPlot; + +/** + * Implementors of this class can be used to tweak some very application specific behaviour within the charts.
+ * Implementations should not have a state, because they are instantiated only once. + * + * @author Gernot Belger + */ +public interface ChartExtender { + + /** + * Called after {@link DiagramGenerator#autoZoom(org.jfree.chart.plot.XYPlot)} was called, allows to tweak auto zoom + * behavior. + */ + void afterAutoZoom(DiagramGenerator generator); + + /** + * Called after the complete chart is generated. + * + * @param plot + */ + void afterGenerateChart(DiagramGenerator generator, XYPlot plot); +} \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java Thu Feb 22 14:11:19 2018 +0100 @@ -22,6 +22,7 @@ import java.io.OutputStream; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -139,6 +140,8 @@ protected String outName; + private Map axisNameToAxis = new HashMap<>(); + /** * Default constructor that initializes internal data structures. */ @@ -1479,8 +1482,7 @@ String axisName = axisIndexToName(index); - IdentifiableNumberAxis axis = new IdentifiableNumberAxis( - axisName, getYAxisLabel(axisName)); + IdentifiableNumberAxis axis = new IdentifiableNumberAxis(axisName, getYAxisLabel(axisName)); axis.setAutoRangeIncludesZero(false); axis.setLabelFont(labelFont); @@ -1489,6 +1491,9 @@ axis.setLowerMargin(0); axis.setUpperMargin(0); + /* remember axis for lookup */ + axisNameToAxis.put( axisName, axis ); + return axis; } @@ -1599,4 +1604,8 @@ public CallContext getCallContext() { return context; } -} + + public final IdentifiableNumberAxis getAxis(final String axisName) { + return axisNameToAxis.get(axisName); + } +} \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/exports/DiagramAttributes.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/DiagramAttributes.java Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/DiagramAttributes.java Thu Feb 22 14:11:19 2018 +0100 @@ -9,6 +9,8 @@ package org.dive4elements.river.exports; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import org.w3c.dom.Element; @@ -82,6 +84,10 @@ public List getProcessors() { return processors; } + + public Collection getExtenders() { + return DiagramAttributes.this.getExtenders(); + } public Title getTitle() { return DiagramAttributes.this.getTitle(); @@ -345,6 +351,7 @@ private List axesAttrs; private List axesProcessors; + private List extenders = new ArrayList<>(); private Title title; private Title subtitle; @@ -363,6 +370,7 @@ parseTitle(config); parseSubtitle(config); parseDomainAxis(config); + parseExtenders(config); return this; } @@ -459,6 +467,10 @@ public List getAxesProcessors() { return axesProcessors; } + + public Collection getExtenders() { + return Collections.unmodifiableCollection(extenders); + } public Title getTitle() { return title; @@ -493,6 +505,33 @@ } } } + + private void parseExtenders(final Element config) { + final NodeList processorNodes = config.getElementsByTagName("chartextender"); + + for (int i = 0, N = processorNodes.getLength(); i < N; ++i) { + final Element extenderElement = (Element)processorNodes.item(i); + final String className = extenderElement.getAttribute("class").trim(); + if (className.isEmpty() ) { + log.error("chartextender missing 'class' attribute"); + continue; + } + + try { + final Class protoclass = Class.forName(className); + if( !ChartExtender.class.isAssignableFrom(protoclass) ) { + log.error(String.format( "Chart extender must implement interface ChartExtender: %s", className) ); + continue; + } + + final ChartExtender extender = (ChartExtender) protoclass.newInstance(); + extenders.add(extender); + } + catch (ClassNotFoundException | InstantiationException | IllegalAccessException cnfe) { + log.error(String.format( "Failed to load or create chartextender class: %s", className ), cnfe); + } + } + } private void parseTitle(Element config) { title = extractTitle(config, "title"); diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java --- a/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java Thu Feb 22 14:11:19 2018 +0100 @@ -14,6 +14,7 @@ import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -238,6 +239,12 @@ aggregateLegendEntries(plot); + /* allow extenders to do some work */ + final Collection extenders = this.diagramAttributes.getExtenders(); + for (final ChartExtender extender : extenders) { + extender.afterGenerateChart(this, plot); + } + return chart; } @@ -390,12 +397,19 @@ isLog().evaluate((D4EArtifact)getMaster(), context); if (logarithmic) { - return new LogarithmicAxis(label); + final LogarithmicAxis axis = new LogarithmicAxis(label); + // REMARK: we overwrite the default values to 0.0, because in earlier version margins were never applied. + axis.setLowerMargin(0); + axis.setUpperMargin(0); + return axis; } final NumberAxis axis = new NumberAxis(label); // REMARK: we overwrite the default values to 0.0, because in earlier version margins were never applied. axis.setLowerMargin(0); axis.setUpperMargin(0); + // REMARK: we overwrite the default values to 0.0, because in earlier version margins were never applied. + axis.setLowerMargin(0); + axis.setUpperMargin(0); return axis; } @@ -739,9 +753,14 @@ log.debug("Prepare zoom settings for y axis at index: " + i); zoom(plot, yaxis, getYBounds(Integer.valueOf(i)), yrange); } + + /* allow chart extenders to tweak zoom behaviour */ + final Collection extenders = this.diagramAttributes.getExtenders(); + for (final ChartExtender extender : extenders) { + extender.afterAutoZoom(this); + } } - protected Range getDomainAxisRange() { String[] ranges = getDomainAxisRangeFromRequest(); diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/resources/messages.properties --- a/artifacts/src/main/resources/messages.properties Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/resources/messages.properties Thu Feb 22 14:11:19 2018 +0100 @@ -772,7 +772,7 @@ sinfo_calc_flow_depth=Flie\u00dftiefen sinfo_calc_flow_depth.warning.missingQ = {0}: keine Abflussdaten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth.warning.waterlevel_discretisation = Wasserspiegel {0}: r\u00e4umliche Aufl\u00f6sung betr\u00e4gt mehr als 1000m -sinfo_calc_flow_depth.warning.year_difference = {0}: Zeitliche Abweichung betr\u00e4gt {1} Jahre. Dies kann zu unplausiblen Ergebnissen f\u00fchren +sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. sinfo_calc_flow_depth.warning.missingSoilKind = {0}: no soil kind available sinfo_calc_flow_depth.warning.missingD50 = {0}: no d50 available @@ -846,10 +846,10 @@ sinfo.chart.flow_depth.xaxis.label = {0}-km sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m] -sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe h [m] -sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0}) -sinfo.facet.flow_depth.tkh.filtered.description = Flie\u00dftiefe mit TKH ({0}) - -sinfo.facet.tkh.description = Transportk\u00f6rperh\u00f6hen ({0}) +sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe [m] +sinfo.facet.flow_depth.filtered.description = h ({0}) +sinfo.facet.flow_depth.tkh.filtered.description = h + \u0394d ({0}) + sinfo.chart.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] -sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] \ No newline at end of file +sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] +sinfo.facet.tkh.description = \u0394d ({0}) \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/resources/messages_de.properties --- a/artifacts/src/main/resources/messages_de.properties Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/resources/messages_de.properties Thu Feb 22 14:11:19 2018 +0100 @@ -778,7 +778,7 @@ sinfo_calc_flow_depth=Flie\u00dftiefen sinfo_calc_flow_depth.warning.missingQ = {0}: keine Abflussdaten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth.warning.waterlevel_discretisation = Wasserspiegel {0}: r\u00e4umliche Aufl\u00f6sung betr\u00e4gt mehr als 1000m -sinfo_calc_flow_depth.warning.year_difference = {0}: Zeitliche Abweichung betr\u00e4gt {1} Jahre. Dies kann zu unplausiblen Ergebnissen f\u00fchren +sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. sinfo_calc_flow_depth.warning.missingSoilKind = {0}: keine Sohlart vorhanden sinfo_calc_flow_depth.warning.missingD50 = {0}: kein D50 vorhanden @@ -854,10 +854,10 @@ sinfo.chart.flow_depth.xaxis.label = {0}-km sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m] -sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe h [m] -sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0}) -sinfo.facet.flow_depth.tkh.filtered.description = Flie\u00dftiefe mit TKH ({0}) - -sinfo.facet.tkh.description = Transportk\u00f6rperh\u00f6hen ({0}) +sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe [m] +sinfo.facet.flow_depth.filtered.description = h ({0}) +sinfo.facet.flow_depth.tkh.filtered.description = h + \u0394d ({0}) + sinfo.chart.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] -sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] \ No newline at end of file +sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] +sinfo.facet.tkh.description = \u0394d ({0}) \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/resources/messages_de_DE.properties --- a/artifacts/src/main/resources/messages_de_DE.properties Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/resources/messages_de_DE.properties Thu Feb 22 14:11:19 2018 +0100 @@ -774,7 +774,9 @@ sinfo_calc_flow_depth=Flie\u00dftiefen sinfo_calc_flow_depth.warning.missingQ = {0}: keine Abflussdaten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth.warning.waterlevel_discretisation = Wasserspiegel {0}: r\u00e4umliche Aufl\u00f6sung betr\u00e4gt mehr als 1000m -sinfo_calc_flow_depth.warning.year_difference = {0}: Zeitliche Abweichung betr\u00e4gt {1} Jahre. Dies kann zu unplausiblen Ergebnissen f\u00fchren +sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. + +Zeitliche Abweichung betr\u00e4gt {1} Jahre. Dies kann zu unplausiblen Ergebnissen f\u00fchren sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe @@ -846,10 +848,10 @@ sinfo.chart.flow_depth.xaxis.label = {0}-km sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m] -sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe h [m] -sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0}) -sinfo.facet.flow_depth.tkh.filtered.description = Flie\u00dftiefe mit TKH ({0}) - -sinfo.facet.tkh.description = Transportk\u00f6rperh\u00f6hen ({0}) +sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe [m] +sinfo.facet.flow_depth.filtered.description = h ({0}) +sinfo.facet.flow_depth.tkh.filtered.description = h + \u0394d ({0}) + sinfo.chart.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] -sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] \ No newline at end of file +sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] +sinfo.facet.tkh.description = \u0394d ({0}) \ No newline at end of file diff -r 3dd0c77a4b27 -r d32c22fc686c artifacts/src/main/resources/messages_en.properties --- a/artifacts/src/main/resources/messages_en.properties Thu Feb 22 12:07:16 2018 +0100 +++ b/artifacts/src/main/resources/messages_en.properties Thu Feb 22 14:11:19 2018 +0100 @@ -773,7 +773,7 @@ sinfo_calc_flow_depth=Flie\u00dftiefen sinfo_calc_flow_depth.warning.missingQ = {0}: keine Abflussdaten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth.warning.waterlevel_discretisation = Wasserspiegel {0}: r\u00e4umliche Aufl\u00f6sung betr\u00e4gt mehr als 1000m -sinfo_calc_flow_depth.warning.year_difference = {0}: Zeitliche Abweichung betr\u00e4gt {1} Jahre. Dies kann zu unplausiblen Ergebnissen f\u00fchren +sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe @@ -845,10 +845,10 @@ sinfo.chart.flow_depth.xaxis.label = {0}-km sinfo.chart.flow_depth.yaxis.label = Flie\u00dftiefe [m] -sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe h [m] -sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0}) -sinfo.facet.flow_depth.tkh.filtered.description = Flie\u00dftiefe mit TKH ({0}) - -sinfo.facet.tkh.description = Transportk\u00f6rperh\u00f6hen ({0}) +sinfo.chart.flow_depth.section.yaxis.label=Flie\u00dftiefe [m] +sinfo.facet.flow_depth.filtered.description = h ({0}) +sinfo.facet.flow_depth.tkh.filtered.description = h + \u0394d ({0}) + sinfo.chart.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] -sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] \ No newline at end of file +sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] +sinfo.facet.tkh.description = \u0394d ({0}) \ No newline at end of file