# HG changeset patch # User gernotbelger # Date 1521220118 -3600 # Node ID 322b0e6298ea376ec3938ae14d7f9cf66e053d19 # Parent b0aeed4c97c18d024a74276b069a09b719511955 Work on SINFO FlowDepth-Development diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/doc/conf/artifacts/sinfo.xml --- a/artifacts/doc/conf/artifacts/sinfo.xml Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/doc/conf/artifacts/sinfo.xml Fri Mar 16 18:08:38 2018 +0100 @@ -130,6 +130,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/doc/conf/generators/generators.xml --- a/artifacts/doc/conf/generators/generators.xml Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/doc/conf/generators/generators.xml Fri Mar 16 18:08:38 2018 +0100 @@ -64,6 +64,8 @@ + + diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/SInfoI18NStrings.java Fri Mar 16 18:08:38 2018 +0100 @@ -68,6 +68,18 @@ String CSV_TKHKIND_HEADER = "sinfo.export.tkh.csv.header.tkhkind"; + String CSV_FLOWDEPTH_DEVELOPMENT_HEADER = "sinfo.export.csv.header.flowdepth.development"; + + String CSV_FLOWDEPTH_DEVELOPMENT_PER_YEAR_HEADER = "sinfo.export.csv.header.flowdepth.development.per.year"; + + String CSV_WATERLEVEL_DIFFERENCE_HEADER = "sinfo.export.csv.header.waterlevel.difference"; + + String CSV_MEAN_BED_HEIGHT_DIFFERENCE_HEADER = "sinfo.export.csv.header.mean_bed_height.difference"; + + String CSV_FLOWDEPTH_CURRENT_HEADER = "sinfo.export.csv.header.flowdepth.current"; + + String CSV_FLOWDEPTH_HISTORICAL_HEADER = "sinfo.export.csv.header.flowdepth.historical"; + String CSV_META_HEADER_WATERLEVEL = "sinfo.export.flow_depth.csv.meta.header.waterlevel"; String CSV_META_HEADER_WATERLEVEL_NAME = "sinfo.export.flow_depth.csv.meta.header.waterlevel.name"; @@ -92,5 +104,7 @@ String UNIT_CM = "cm"; + String UNIT_CM_A = "cm/a"; + String UNIT_CUBIC_M = "m³/s"; } \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/DatacagePairSelectState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/DatacagePairSelectState.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,118 @@ +/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde + * Software engineering by Intevation GmbH + * + * 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.log4j.Logger; +import org.dive4elements.artifactdatabase.ProtocolUtils; +import org.dive4elements.artifactdatabase.state.Facet; +import org.dive4elements.artifacts.Artifact; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.artifacts.common.utils.XMLUtils.ElementCreator; +import org.dive4elements.river.artifacts.D4EArtifact; +import org.dive4elements.river.artifacts.model.FacetTypes; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.states.DefaultState; +import org.dive4elements.river.artifacts.states.WaterlevelPairSelectState; +import org.w3c.dom.Element; + +/** + * Copy of {@link WaterlevelPairSelectState}. We must copy instead of crate an abstraction, else we break the + * serialization of {@link WaterlevelPairSelectState}. + * State in which the user selects 1 to n pairs of Waterlevels and alikes. + */ +public abstract class DatacagePairSelectState extends DefaultState implements FacetTypes { + + private static final long serialVersionUID = 1L; + + /** The log that is used in this state. */ + private static Logger log = Logger.getLogger(DatacagePairSelectState.class); + + private final String dataId; + + private final String uiProvider; + + /** + * Name of the state data this state is responsible for. + */ + public DatacagePairSelectState(final String uiProvider, final String dataId) { + this.uiProvider = uiProvider; + this.dataId = dataId; + } + + /** Specify to display a datacage_twin_panel. */ + @Override + protected final String getUIProvider() { + return this.uiProvider; + } + + /** + * Overridden to do nothing. + */ + @Override + public final Object computeAdvance(final D4EArtifact artifact, final String hash, final CallContext context, final List facets, final Object old) { + // Get data and do stuff, do not calculate + return ""; + } + + /** + * Create elements for document (prepopulated with data, if any). + * + * @param artifact + * D4EArtifact to get data from. + * @param name + * DataName, expceted to be dataId given in constructor. + */ + @Override + protected final Element[] createItems(final ElementCreator cr, final Artifact artifact, final String name, final CallContext context) { + log.debug("createItems: " + name); + + if (name.equals(this.dataId)) { + final Element item = ProtocolUtils.createArtNode(cr, "item", null, null); + final Element label = ProtocolUtils.createArtNode(cr, "label", null, null); + final Element value = ProtocolUtils.createArtNode(cr, "value", null, null); + + final D4EArtifact flys = (D4EArtifact) artifact; + + final String s = flys.getDataAsString(name); + value.setTextContent(s); + item.appendChild(label); + item.appendChild(value); + return new Element[] { item }; + } + + return new Element[] {}; + } + + /** + * Creats the data element used for the static part of DESCRIBE document. + */ + @Override + protected final Element createStaticData(final D4EArtifact flys, final ElementCreator creator, final CallContext cc, final String name, final String value, + final String type) { + final Element dataElement = creator.create("data"); + creator.addAttr(dataElement, "name", name, true); + creator.addAttr(dataElement, "type", type, true); + + final Element itemElement = creator.create("item"); + creator.addAttr(itemElement, "value", value, true); + + final String[] labels = WaterlevelPairSelectState.getLabels(cc, value); + final Object[] obj = new Object[] { labels[0] }; + + // TODO own i18n + final String attrValue = Resources.getMsg(cc.getMeta(), "wsp.selected.string", "wsp.selected.string", obj); + + creator.addAttr(itemElement, "label", attrValue, true); + dataElement.appendChild(itemElement); + + return dataElement; + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/SInfoResultType.java Fri Mar 16 18:08:38 2018 +0100 @@ -280,6 +280,78 @@ protected NumberFormat createFormatter(final CallContext context) { return Formatter.getFlowDepth(context); } + }, + flowdepthDevelopment(SInfoI18NStrings.UNIT_CM, SInfoI18NStrings.CSV_FLOWDEPTH_DEVELOPMENT_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getTkh(context); + } + }, + flowdepthDevelopmentPerYear(SInfoI18NStrings.UNIT_CM_A, SInfoI18NStrings.CSV_FLOWDEPTH_DEVELOPMENT_PER_YEAR_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getFlowDepthDevelopmentPerYear(context); + } + }, + waterlevelDifference(SInfoI18NStrings.UNIT_CM, SInfoI18NStrings.CSV_WATERLEVEL_DIFFERENCE_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getTkh(context); + } + }, + bedHeightDifference(SInfoI18NStrings.UNIT_CM, SInfoI18NStrings.CSV_MEAN_BED_HEIGHT_DIFFERENCE_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getTkh(context); + } + }, + flowdepthCurrent(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTH_CURRENT_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getFlowDepth(context); + } + }, + flowdepthHistorical(SInfoI18NStrings.UNIT_M, SInfoI18NStrings.CSV_FLOWDEPTH_HISTORICAL_HEADER) { + @Override + public String exportValue(final CallContext context, final Object value) { + final double doubleValue = asDouble(value); + return exportDoubleValue(context, doubleValue); + } + + @Override + protected NumberFormat createFormatter(final CallContext context) { + return Formatter.getFlowDepth(context); + } }; /* Cache for formatters because Formatter will always create new formats (which is very expensive) */ diff -r b0aeed4c97c1 -r 322b0e6298ea 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 Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Fri Mar 16 18:08:38 2018 +0100 @@ -100,7 +100,7 @@ final String soundingLabel = bedHeight.getInfo().getDescription(); final String label = String.format("%s - %s", wspLabel, soundingLabel); - FlowDepthUtils.checkYearDifference(label, waterlevel, bedHeight.getInfo().getYear(), problems); + FlowDepthUtils.checkYearDifference(label, waterlevel.getYear(), bedHeight.getInfo().getYear(), problems); checkWaterlevelDiscretisation(wstKms, calcRange, problems); // TODO: prüfen, ob sohlhöhen die calcRange abdecken/überschneiden diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthPairSelectState.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthPairSelectState.java Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthPairSelectState.java Fri Mar 16 18:08:38 2018 +0100 @@ -9,7 +9,7 @@ */ package org.dive4elements.river.artifacts.sinfo.flowdepth; -import org.dive4elements.river.artifacts.states.WaterlevelPairSelectState; +import org.dive4elements.river.artifacts.sinfo.common.DatacagePairSelectState; /** * @author Gernot Belger @@ -17,13 +17,11 @@ */ // FIXME: very ugly; but probably we will break the serialization of WaterlevelPairSelectState if we introduce an // abstraction -public final class FlowDepthPairSelectState extends WaterlevelPairSelectState { +public final class FlowDepthPairSelectState extends DatacagePairSelectState { private static final long serialVersionUID = 1L; - /** Specify to display a datacage_twin_panel. */ - @Override - protected String getUIProvider() { - return "sinfo_flowdepth_twin_panel"; + public FlowDepthPairSelectState() { + super("sinfo_flowdepth_twin_panel", "diffids"); } } \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthUtils.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthUtils.java Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthUtils.java Fri Mar 16 18:08:38 2018 +0100 @@ -10,7 +10,6 @@ package org.dive4elements.river.artifacts.sinfo.flowdepth; import org.dive4elements.river.artifacts.model.Calculation; -import org.dive4elements.river.artifacts.states.WaterlevelData; /** * @author Gernot Belger @@ -30,9 +29,8 @@ * 1918 ≤ X < 1958 ± 12 * X < 1918 ± 25 */ - public static void checkYearDifference(final String label, final WaterlevelData waterlevel, final int soundingYear, final Calculation problems) { + public static void checkYearDifference(final String label, final int wstYear, final int soundingYear, final Calculation problems) { - final int wstYear = waterlevel.getYear(); if (wstYear < 0) return; diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentAccess.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentAccess.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,67 @@ +/* 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.flowdepthdev; + +import java.util.List; + +import org.apache.commons.lang.math.DoubleRange; +import org.dive4elements.river.artifacts.access.RangeAccess; +import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; +import org.dive4elements.river.artifacts.sinfo.SinfoCalcMode; +import org.dive4elements.river.artifacts.sinfo.flowdepth.WstSoundingIdPair; + +/** + * Access to the flow depth calculation type specific SInfo artifact data. + * REMARK: this class is NOT intended to be hold in the results (or anywhere else), in order to avoid a permanent + * reference to the artifact instance. + * Hence we do NOT cache any data. + * + * @author Gernot Belger + */ +final class FlowDepthDevelopmentAccess extends RangeAccess { + + static final String FIELD_DIFFID_CURRENT = "diffid_current"; + static final String FIELD_DIFFID_HIST = "diffid_historical"; + + public FlowDepthDevelopmentAccess(final SINFOArtifact artifact) { + super(artifact); + + /* assert calculation mode */ + final SinfoCalcMode calculationMode = artifact.getCalculationMode(); + assert (calculationMode == SinfoCalcMode.sinfo_calc_flow_depth_minmax); + } + + public DoubleRange getRange() { + final double from = getFrom(); + final double to = getTo(); + return new DoubleRange(from, to); + } + + public WstSoundingIdPair getCurrentPair() { + return getPair(FIELD_DIFFID_CURRENT); + } + + public WstSoundingIdPair getHistoricalPair() { + return getPair(FIELD_DIFFID_HIST); + } + + private WstSoundingIdPair getPair(final String field) { + final String diffids = getString(field); + + /* fetch the raw configured pairs */ + final List diffPairs = WstSoundingIdPair.parsePairs(diffids); + + if (diffPairs.size() != 1) + return null; + + return diffPairs.get(0); + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,197 @@ +/** 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.flowdepthdev; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.commons.lang.math.DoubleRange; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.model.Calculation; +import org.dive4elements.river.artifacts.model.CalculationResult; +import org.dive4elements.river.artifacts.model.WKms; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; +import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; +import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthUtils; +import org.dive4elements.river.artifacts.sinfo.flowdepth.WstSoundingIdPair; +import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder; +import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; +import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; +import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; +import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; +import org.dive4elements.river.artifacts.states.WaterlevelData; +import org.dive4elements.river.artifacts.states.WaterlevelFetcher; +import org.dive4elements.river.model.River; + +/** + * @author Gernot Belger + */ +final class FlowDepthDevelopmentCalculation { + + private final CallContext context; + + public FlowDepthDevelopmentCalculation(final CallContext context) { + this.context = context; + } + + public CalculationResult calculate(final SINFOArtifact sinfo) { + + final String user = CalculationUtils.findArtifactUser(this.context, sinfo); + + /* access input data */ + final FlowDepthDevelopmentAccess access = new FlowDepthDevelopmentAccess(sinfo); + final River river = access.getRiver(); + final RiverInfo riverInfo = new RiverInfo(river); + + final WstSoundingIdPair currentPair = access.getCurrentPair(); + final WstSoundingIdPair histPair = access.getHistoricalPair(); + + final DoubleRange calcRange = access.getRange(); + + /* calculate results for each diff pair */ + final Calculation problems = new Calculation(); + + final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange); + + final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); + + final FlowDepthDevelopmentCalculationResults results = new FlowDepthDevelopmentCalculationResults(calcModeLabel, user, riverInfo, calcRange); + + final FlowDepthDevelopmentCalculationResult result = calculateResult(calcRange, currentPair, histPair, problems, infoProvider); + if (result != null) + results.addResult(result); + + return new CalculationResult(results, problems); + } + + private FlowDepthDevelopmentCalculationResult calculateResult(final DoubleRange calcRange, final WstSoundingIdPair currentPair, + final WstSoundingIdPair histPair, final Calculation problems, final RiverInfoProvider infoProvider) { + + /* access real input data from database */ + final WaterlevelData currentWaterlevel = loadWaterlevel(currentPair, problems); + if (currentWaterlevel == null) + return null; + + final WaterlevelData historicalWaterlevel = loadWaterlevel(histPair, problems); + if (historicalWaterlevel == null) + return null; + + final BedHeightsFinder currentSounding = loadBedHeight(currentPair, calcRange, problems); + if (currentSounding == null) + return null; + + final BedHeightsFinder historicalSounding = loadBedHeight(histPair, calcRange, problems); + if (historicalSounding == null) + return null; + + // FIXME: check current/hist wst have same discharge... + + final BedHeightInfo currentSoundingInfo = currentSounding.getInfo(); + final BedHeightInfo historicalSoundingInfo = historicalSounding.getInfo(); + + // final String label = createLabel(waterlevel, minBedHeight, maxBedHeight); + + // final WKms wstKms = waterlevel.getWkms(); + final int currentWstYear = currentWaterlevel.getYear(); + final int historicalWstYear = historicalWaterlevel.getYear(); + final int currentSoundingYear = currentSoundingInfo.getYear(); + final int historicalSoundingYear = historicalSoundingInfo.getYear(); + + // FIXME: distinguish error messages + FlowDepthUtils.checkYearDifference("", currentWstYear, currentSoundingYear, problems); + FlowDepthUtils.checkYearDifference("", historicalWstYear, historicalSoundingYear, problems); + + // checkWaterlevelDiscretisation(wstKms, calcRange, problems); + // TODO: prüfen, ob sohlhöhen die calcRange abdecken/überschneiden + + /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */ + final RiverInfoProvider currentRiverInfoProvider = infoProvider.forWaterlevel(currentWaterlevel); + final RiverInfoProvider histRiverInfoProvider = infoProvider.forWaterlevel(historicalWaterlevel); + + final WstInfo currentWstInfo = new WstInfo(currentWaterlevel.getName(), currentWstYear, currentRiverInfoProvider.getReferenceGauge()); + final WstInfo historicalWstInfo = new WstInfo(historicalWaterlevel.getName(), historicalWstYear, histRiverInfoProvider.getReferenceGauge()); + + final WKms currentWkms = currentWaterlevel.getWkms(); + final WaterlevelValuesFinder currentWstProvider = WaterlevelValuesFinder.fromKms(currentWkms); + // final DischargeValuesFinder currentDischargeProvider = DischargeValuesFinder.fromKms(currentWkms); + + final WKms historicalWkms = historicalWaterlevel.getWkms(); + final WaterlevelValuesFinder historicalWstProvider = WaterlevelValuesFinder.fromKms(historicalWkms); + // final DischargeValuesFinder historicalDischargeProvider = DischargeValuesFinder.fromKms(historicalWkms); + + final int currentMeanYear = (currentWstYear + currentSoundingYear) / 2; + final int historcialMeanYear = (historicalWstYear + historicalSoundingYear) / 2; + + // final String waterlevelLabel = waterlevel.getName(); + // final String soundingLabel = buildSoundingLabel(minBedHeight, maxBedHeight); + + final double diffYear = currentMeanYear - historcialMeanYear; + + /* real calculation loop */ + final Collection rows = new ArrayList<>(); + + // FIXME: determine what is the spatial discretisation that we will use... + final double[] allKms = currentWkms.allKms().toNativeArray(); + for (final double station : allKms) { + if (calcRange.containsDouble(station)) { + + final double currentWst = currentWstProvider.getWaterlevel(station); + // final double currentDischarge = currentDischargeProvider.getDischarge(station); + final double currentBedHeight = currentSounding.getMeanBedHeight(station); + + final double historicalWst = historicalWstProvider.getWaterlevel(station); + // final double historicalDischarge = historicalDischargeProvider.getDischarge(station); + final double historicalBedHeight = historicalSounding.getMeanBedHeight(station); + + final double diffWst = (currentWst - historicalWst) * 100; + final double diffBedHeight = (currentBedHeight - historicalBedHeight) * 100; + + final double flowDepthDevelopment = diffWst - diffBedHeight; + + final double flowDepthDevelopmentPerYear = flowDepthDevelopment / diffYear; + + final double currentFlowDepth = currentWst - currentBedHeight; + final double historicalFlowDepth = historicalWst - historicalBedHeight; + + // REMARK: access the location once only during calculation + final String location = currentRiverInfoProvider.getLocation(station); + + final SInfoResultRow row = SInfoResultRow.create().// + putValue(SInfoResultType.station, station). // + putValue(SInfoResultType.flowdepthDevelopment, flowDepthDevelopment). // + putValue(SInfoResultType.flowdepthDevelopmentPerYear, flowDepthDevelopmentPerYear). // + putValue(SInfoResultType.waterlevelDifference, diffWst). // + putValue(SInfoResultType.bedHeightDifference, diffBedHeight). // + putValue(SInfoResultType.flowdepthCurrent, currentFlowDepth). // + putValue(SInfoResultType.flowdepthHistorical, historicalFlowDepth). // + putValue(SInfoResultType.location, location); + rows.add(row); + } + } + + return new FlowDepthDevelopmentCalculationResult("", currentWstInfo, historicalWstInfo, currentSoundingInfo, historicalSoundingInfo, + rows); + } + + /* REMARK: fetch ALL wst kms, because we need to determine the original reference gauge */ + private WaterlevelData loadWaterlevel(final WstSoundingIdPair pair, final Calculation problems) { + final String wstId = pair.getWstId(); + return new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN, problems); + } + + private BedHeightsFinder loadBedHeight(final WstSoundingIdPair pair, final DoubleRange calcRange, final Calculation problems) { + final String soundingId = pair.getSoundingId(); + return BedHeightsFinder.forId(this.context, soundingId, calcRange, problems); + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculationResult.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculationResult.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,63 @@ +/* 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.flowdepthdev; + +import java.util.Collection; + +import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResult; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; + +/** + * Contains the results of a {@link FlowDepthCalculation}. + * + * @author Gernot Belger + */ +final class FlowDepthDevelopmentCalculationResult extends AbstractSInfoCalculationResult { + + private static final long serialVersionUID = 1L; + + private final BedHeightInfo currentSounding; + + private final BedHeightInfo historicalSounding; + + private final WstInfo historicalWst; + + private final WstInfo currentWst; + + public FlowDepthDevelopmentCalculationResult(final String label, final WstInfo currentWst, final WstInfo historicalWst, final BedHeightInfo currentSounding, + final BedHeightInfo historicalSounding, final Collection rows) { + // FIXME: bad abstraction if we give null here... + super(label, null, rows); + + this.currentWst = currentWst; + this.historicalWst = historicalWst; + + this.currentSounding = currentSounding; + this.historicalSounding = historicalSounding; + } + + public WstInfo getCurrentWst() { + return this.currentWst; + } + + public WstInfo getHistoricalWst() { + return this.historicalWst; + } + + public BedHeightInfo getCurrentSounding() { + return this.currentSounding; + } + + public BedHeightInfo getHistoricalSounding() { + return this.historicalSounding; + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculationResults.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculationResults.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,26 @@ +/** 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.flowdepthdev; + +import org.apache.commons.lang.math.DoubleRange; +import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoCalculationResults; +import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; + +/** + * @author Gernot Belger + */ +final class FlowDepthDevelopmentCalculationResults extends AbstractSInfoCalculationResults { + + private static final long serialVersionUID = 1L; + + public FlowDepthDevelopmentCalculationResults(final String calcModeLabel, final String user, final RiverInfo river, final DoubleRange calcRange) { + super(calcModeLabel, user, river, calcRange); + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentExporter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentExporter.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,161 @@ +/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde + * Software engineering by Intevation GmbH + * + * 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.flowdepthdev; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.log4j.Logger; +import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoExporter; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; +import org.dive4elements.river.artifacts.sinfo.util.MetaAndTableJRDataSource; +import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; + +import au.com.bytecode.opencsv.CSVWriter; + +/** + * Generates different output formats (csv, pdf) of data that resulted from a flow depths computation. + * + * @author Ingo Weinzierl + * @author Gernot Belger + */ +// REMARK: must be public because its registered in generators.xml +public class FlowDepthDevelopmentExporter extends AbstractSInfoExporter { + + /** The log used in this exporter. */ + private static Logger log = Logger.getLogger(FlowDepthDevelopmentExporter.class); + + private static final String JASPER_FILE = "/jasper/sinfo.flowdepthminmax.jasper"; + + @Override + protected Logger getLog() { + return log; + } + + @Override + protected void writeCSVResultMetadata(final CSVWriter writer, final FlowDepthDevelopmentCalculationResults results, + final FlowDepthDevelopmentCalculationResult result) { + + // FIXME: distinguish header labels + writeCSVSoundingMetadata(writer, result.getCurrentSounding()); + writeCSVWaterlevelMetadata(writer, result.getCurrentWst()); + + // FIXME: distinguish header labels + writeCSVSoundingMetadata(writer, result.getHistoricalSounding()); + writeCSVWaterlevelMetadata(writer, result.getHistoricalWst()); + } + + @Override + protected void writeCSVGlobalMetadata(final CSVWriter writer, final FlowDepthDevelopmentCalculationResults results) { + + super.writeCSVGlobalMetadataDefaults(writer, results); + + writer.writeNext(new String[] { "" }); + } + + /** + * Write the header, with different headings depending on whether at a + * gauge or at a location. + * + * @param river + * @param useTkh + */ + @Override + protected void writeCSVHeader(final CSVWriter writer, final FlowDepthDevelopmentCalculationResults results, final RiverInfo river) { + log.info("FlowDepthExporter.writeCSVHeader"); + + final Collection header = new ArrayList<>(11); + + header.add(msg(SInfoResultType.station.getCsvHeader())); + header.add(msgUnit(SInfoResultType.flowdepthDevelopment.getCsvHeader(), SInfoResultType.flowdepthDevelopment.getUnit())); + header.add(msgUnit(SInfoResultType.flowdepthDevelopmentPerYear.getCsvHeader(), SInfoResultType.flowdepthDevelopmentPerYear.getUnit())); + + // FIXME: add data-labels in header + header.add(msgUnit(SInfoResultType.waterlevelDifference.getCsvHeader(), SInfoResultType.waterlevelDifference.getUnit())); + header.add(msgUnit(SInfoResultType.bedHeightDifference.getCsvHeader(), SInfoResultType.bedHeightDifference.getUnit())); + + header.add(msgUnit(SInfoResultType.flowdepthCurrent.getCsvHeader(), SInfoResultType.flowdepthCurrent.getUnit())); + header.add(msgUnit(SInfoResultType.flowdepthHistorical.getCsvHeader(), SInfoResultType.flowdepthHistorical.getUnit())); + + header.add(msg(SInfoResultType.location.getCsvHeader())); + + writer.writeNext(header.toArray(new String[header.size()])); + } + + @Override + protected String[] formatCSVRow(final FlowDepthDevelopmentCalculationResults results, final FlowDepthDevelopmentCalculationResult result, + final SInfoResultRow row) { + return formatRow(result, row); + } + + /** + * Format a row of a flow depth result into an array of string, both used by csv and pdf + * + * @param result + * + * @param useTkh + */ + private String[] formatRow(final FlowDepthDevelopmentCalculationResult result, final SInfoResultRow row) { + + final Collection lines = new ArrayList<>(10); + + lines.add(row.exportValue(this.context, SInfoResultType.station)); + + // FIXME + + // REMARK: null check as pdf will call this with null and in that case we show all columns (to avoid multiple jasper + // FIXME: does not work like this: we may have several pairs of min/max; so we need to look at all of them? + // templates) + // if (result == null || result.getMinSounding() != null) + lines.add(row.exportValue(this.context, SInfoResultType.flowdepthmin)); + // if (result == null || result.getMaxSounding() != null) + lines.add(row.exportValue(this.context, SInfoResultType.flowdepthmax)); + + lines.add(row.exportValue(this.context, SInfoResultType.waterlevel)); + lines.add(row.exportValue(this.context, SInfoResultType.discharge)); + lines.add(row.exportValue(this.context, SInfoResultType.waterlevelLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.gaugeLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.meanBedHeight)); + lines.add(row.exportValue(this.context, SInfoResultType.soundingLabel)); + lines.add(row.exportValue(this.context, SInfoResultType.location)); + + return lines.toArray(new String[lines.size()]); + } + + @Override + protected final String getJasperFile() { + return JASPER_FILE; + } + + @Override + protected final void addJRMetaData(final MetaAndTableJRDataSource source, final FlowDepthDevelopmentCalculationResults results) { + + /* general metadata */ + super.addJRMetaDataDefaults(source, results); + + /* column headings */ + // FIXME + source.addMetaData("station_header", SInfoResultType.station.getPdfHeader(this.context.getMeta())); + source.addMetaData("flowdepthmin_header", SInfoResultType.flowdepthmin.getPdfHeader(this.context.getMeta())); + source.addMetaData("flowdepthmax_header", SInfoResultType.flowdepthmax.getPdfHeader(this.context.getMeta())); + source.addMetaData("waterlevel_header", SInfoResultType.waterlevel.getPdfHeader(this.context.getMeta())); + source.addMetaData("discharge_header", SInfoResultType.discharge.getPdfHeader(this.context.getMeta())); + source.addMetaData("waterlevel_name_header", SInfoResultType.waterlevelLabel.getPdfHeader(this.context.getMeta())); + source.addMetaData("gauge_header", SInfoResultType.gaugeLabel.getPdfHeader(this.context.getMeta())); + source.addMetaData("bedheight_header", SInfoResultType.meanBedHeight.getPdfHeader(this.context.getMeta())); + source.addMetaData("sounding_name_header", SInfoResultType.soundingLabel.getPdfHeader(this.context.getMeta())); + source.addMetaData("location_header", SInfoResultType.location.getPdfHeader(this.context.getMeta())); + } + + @Override + protected String[] formatPDFRow(final FlowDepthDevelopmentCalculationResults results, final SInfoResultRow row) { + return formatRow(null, row); + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentState.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,113 @@ +/** 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.flowdepthdev; + +import java.util.List; + +import org.dive4elements.artifactdatabase.state.Facet; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.ChartArtifact; +import org.dive4elements.river.artifacts.D4EArtifact; +import org.dive4elements.river.artifacts.model.CalculationResult; +import org.dive4elements.river.artifacts.model.EmptyFacet; +import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; +import org.dive4elements.river.artifacts.states.DefaultState; + +/** + * @author Gernot Belger + */ +public class FlowDepthDevelopmentState extends DefaultState { + + private static final long serialVersionUID = 1L; + + /** + * From this state can only be continued trivially. + */ + @Override + protected String getUIProvider() { + return "continue"; + } + + @Override + public Object computeFeed(final D4EArtifact artifact, final String hash, final CallContext context, final List facets, final Object old) { + // FIXME: why is this necessary? + if (artifact instanceof ChartArtifact) { + facets.add(new EmptyFacet()); + return null; + } + + return compute((SINFOArtifact) artifact, context, hash, facets, old); + } + + @Override + public Object computeAdvance(final D4EArtifact artifact, final String hash, final CallContext context, final List facets, final Object old) { + if (artifact instanceof ChartArtifact) { + facets.add(new EmptyFacet()); + return null; + } + return compute((SINFOArtifact) artifact, context, hash, facets, old); + } + + /** + * Compute result or returned object from cache, create facets. + * + * @param old + * Object that was cached. + */ + private Object compute(final SINFOArtifact sinfo, final CallContext context, final String hash, final List facets, final Object old) { + + final CalculationResult res = doCompute(sinfo, context, old); + + if (facets == null) + return res; + + // final FlowDepthCalculationResults results = (FlowDepthCalculationResults) res.getData(); + // + // /* add themes for chart, for each result */ + // final List resultList = results.getResults(); + // for (int index = 0; index < resultList.size(); index++) { + // + // final FlowDepthCalculationResult result = resultList.get(index); + // + // /* filtered (zoom dependent mean) flow depth */ + // facets.add(FlowDepthProcessor.createFlowDepthFacet(context, hash, this.id, result, index)); + // + // if (results.isUseTkh()) { + // /* filtered (zoom dependent mean) flow depth including tkh */ + // facets.add(FlowDepthProcessor.createFlowDepthTkhFacet(context, hash, this.id, result, index)); + // + // facets.add(TkhProcessor.createTkhFacet(context, hash, this.id, result, index)); + // } + // } + // + // if (!resultList.isEmpty()) { + // 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); + // + // facets.add(csv); + // facets.add(pdf); + // } + // + // final Calculation report = res.getReport(); + // + // if (report.hasProblems()) { + // facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id)); + // } + + return res; + } + + private CalculationResult doCompute(final SINFOArtifact sinfo, final CallContext context, final Object old) { + if (old instanceof CalculationResult) + return (CalculationResult) old; + + return new FlowDepthDevelopmentCalculation(context).calculate(sinfo); + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/WaterlevelSoundingCurrentPairSelectState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/WaterlevelSoundingCurrentPairSelectState.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,27 @@ +/** 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.flowdepthdev; + +import org.dive4elements.river.artifacts.sinfo.common.DatacagePairSelectState; + +/** + * @author Gernot Belger + * + */ +// FIXME: very ugly; but probably we will break the serialization of WaterlevelPairSelectState if we introduce an +// abstraction +public final class WaterlevelSoundingCurrentPairSelectState extends DatacagePairSelectState { + + private static final long serialVersionUID = 1L; + + public WaterlevelSoundingCurrentPairSelectState() { + super("sinfo_flowdepth_twin_panel", FlowDepthDevelopmentAccess.FIELD_DIFFID_CURRENT); + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/WaterlevelSoundingHistoricalPairSelectState.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/WaterlevelSoundingHistoricalPairSelectState.java Fri Mar 16 18:08:38 2018 +0100 @@ -0,0 +1,27 @@ +/** 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.flowdepthdev; + +import org.dive4elements.river.artifacts.sinfo.common.DatacagePairSelectState; + +/** + * @author Gernot Belger + * + */ +// FIXME: very ugly; but probably we will break the serialization of WaterlevelPairSelectState if we introduce an +// abstraction +public final class WaterlevelSoundingHistoricalPairSelectState extends DatacagePairSelectState { + + private static final long serialVersionUID = 1L; + + public WaterlevelSoundingHistoricalPairSelectState() { + super("sinfo_flowdepth_twin_panel", FlowDepthDevelopmentAccess.FIELD_DIFFID_HIST); + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea 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 Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java Fri Mar 16 18:08:38 2018 +0100 @@ -105,7 +105,7 @@ final WKms wstKms = waterlevel.getWkms(); final int soundingYear = checkSoundingYear(minBedHeight, maxBedHeight, problems); - FlowDepthUtils.checkYearDifference(label, waterlevel, soundingYear, problems); + FlowDepthUtils.checkYearDifference(label, waterlevel.getYear(), soundingYear, problems); // FIXME // checkWaterlevelDiscretisation(wstKms, calcRange, problems); // TODO: prüfen, ob sohlhöhen die calcRange abdecken/überschneiden diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java --- a/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java Fri Mar 16 18:08:38 2018 +0100 @@ -9,9 +9,9 @@ package org.dive4elements.river.utils; import java.text.DateFormat; +import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; -import java.text.DecimalFormat; import java.util.Locale; import org.dive4elements.artifacts.CallContext; @@ -111,9 +111,9 @@ * @return A NumberFormat. Use #format(NUMBER) to get String representation * of NUMBER. */ - public static NumberFormat getFormatter(CallMeta m, int min, int max){ - Locale locale = Resources.getLocale(m); - NumberFormat nf = NumberFormat.getInstance(locale); + public static NumberFormat getFormatter(final CallMeta m, final int min, final int max){ + final Locale locale = Resources.getLocale(m); + final NumberFormat nf = NumberFormat.getInstance(locale); nf.setMaximumFractionDigits(max); nf.setMinimumFractionDigits(min); @@ -121,7 +121,7 @@ return nf; } - public static NumberFormat getFormatter(CallContext c, int min, int max){ + public static NumberFormat getFormatter(final CallContext c, final int min, final int max){ return getFormatter(c.getMeta(), min, max); } @@ -133,18 +133,18 @@ * * @return a number formatter. */ - public static NumberFormat getRawFormatter(CallContext c) { - Locale locale = Resources.getLocale(c.getMeta()); + public static NumberFormat getRawFormatter(final CallContext c) { + final Locale locale = Resources.getLocale(c.getMeta()); return NumberFormat.getInstance(locale); } /** * Returns a formatter in engineering notation. */ - public static NumberFormat getEngFormatter(CallContext c) { - NumberFormat nf = getRawFormatter(c); + public static NumberFormat getEngFormatter(final CallContext c) { + final NumberFormat nf = getRawFormatter(c); if (nf instanceof DecimalFormat) { - DecimalFormat df = (DecimalFormat)nf; + final DecimalFormat df = (DecimalFormat)nf; df.applyPattern("##0.#####E0"); } return nf; @@ -154,13 +154,13 @@ * Returns a number formatter that uses an exponent after max digits. */ public static NumberFormat getScientificFormater( - CallContext c, - int min, - int max - ) { - NumberFormat nf = getRawFormatter(c); + final CallContext c, + final int min, + final int max + ) { + final NumberFormat nf = getRawFormatter(c); if (nf instanceof DecimalFormat) { - DecimalFormat df = (DecimalFormat)nf; + final DecimalFormat df = (DecimalFormat)nf; df.applyPattern("0.0E0"); df.setMaximumFractionDigits(max); df.setMinimumFractionDigits(min); @@ -172,8 +172,8 @@ /** * Returns a date formatter with SHORT style. */ - public static DateFormat getShortDateFormat(CallContext cc) { - Locale locale = Resources.getLocale(cc.getMeta()); + public static DateFormat getShortDateFormat(final CallContext cc) { + final Locale locale = Resources.getLocale(cc.getMeta()); return DateFormat.getDateInstance(DateFormat.SHORT, locale); } @@ -181,8 +181,8 @@ /** * Returns a date formatter with MEDIUM style. */ - public static DateFormat getMediumDateFormat(CallContext cc) { - Locale locale = Resources.getLocale(cc.getMeta()); + public static DateFormat getMediumDateFormat(final CallContext cc) { + final Locale locale = Resources.getLocale(cc.getMeta()); return DateFormat.getDateInstance(DateFormat.MEDIUM, locale); } @@ -192,7 +192,7 @@ * * @return the number formatter for kilometer values. */ - public static NumberFormat getWaterlevelKM(CallContext context) { + public static NumberFormat getWaterlevelKM(final CallContext context) { return getFormatter( context, WATERLEVEL_KM_MIN_DIGITS, @@ -205,14 +205,14 @@ * * @return the number formatter for csv data from diagra. */ - public static NumberFormat getCSVFormatter(CallContext context) { + public static NumberFormat getCSVFormatter(final CallContext context) { return getFormatter( context, CSV_DIAGRAM_DATA_MIN_DIGITS, CSV_DIAGRAM_DATA_MAX_DIGITS); } - public static NumberFormat getWaterlevelW(CallMeta meta) { + public static NumberFormat getWaterlevelW(final CallMeta meta) { return getFormatter( meta, WATERLEVEL_W_MIN_DIGITS, @@ -225,7 +225,7 @@ * * @return the number formatter for W values. */ - public static NumberFormat getWaterlevelW(CallContext context) { + public static NumberFormat getWaterlevelW(final CallContext context) { return getFormatter( context, WATERLEVEL_W_MIN_DIGITS, @@ -238,7 +238,7 @@ * * @return the number formatter for Q values. */ - public static NumberFormat getWaterlevelQ(CallContext context) { + public static NumberFormat getWaterlevelQ(final CallContext context) { return getFormatter( context, WATERLEVEL_Q_MIN_DIGITS, @@ -246,7 +246,7 @@ } - public static NumberFormat getWaterlevelQ(CallMeta meta) { + public static NumberFormat getWaterlevelQ(final CallMeta meta) { return getFormatter( meta, WATERLEVEL_Q_MIN_DIGITS, @@ -259,7 +259,7 @@ * * @return the number formatter for W values. */ - public static NumberFormat getComputedDischargeW(CallContext context) { + public static NumberFormat getComputedDischargeW(final CallContext context) { return getFormatter( context, COMPUTED_DISCHARGE_W_MIN_DIGITS, @@ -273,7 +273,7 @@ * * @return the number formatter for Q values. */ - public static NumberFormat getComputedDischargeQ(CallContext context) { + public static NumberFormat getComputedDischargeQ(final CallContext context) { return getFormatter( context, COMPUTED_DISCHARGE_Q_MIN_DIGITS, @@ -287,7 +287,7 @@ * * @return the number formatter for W values. */ - public static NumberFormat getHistoricalDischargeW(CallContext context) { + public static NumberFormat getHistoricalDischargeW(final CallContext context) { return getFormatter( context, HISTORICAL_DISCHARGE_W_MIN_DIGITS, @@ -301,7 +301,7 @@ * * @return the number formatter for Q values. */ - public static NumberFormat getHistoricalDischargeQ(CallContext context) { + public static NumberFormat getHistoricalDischargeQ(final CallContext context) { return getFormatter( context, HISTORICAL_DISCHARGE_Q_MIN_DIGITS, @@ -314,7 +314,7 @@ * * @return the number formatter for W values. */ - public static NumberFormat getDurationW(CallContext context) { + public static NumberFormat getDurationW(final CallContext context) { return getFormatter( context, DURATION_W_MIN_DIGITS, @@ -327,7 +327,7 @@ * * @return the number formatter for W values. */ - public static NumberFormat getDurationQ(CallContext context) { + public static NumberFormat getDurationQ(final CallContext context) { return getFormatter( context, DURATION_Q_MIN_DIGITS, @@ -340,14 +340,14 @@ * * @return the number formatter for W values. */ - public static NumberFormat getDurationD(CallContext context) { + public static NumberFormat getDurationD(final CallContext context) { return getFormatter( context, DURATION_D_MIN_DIGITS, DURATION_D_MAX_DIGITS); } - public static NumberFormat getCalculationKm(CallMeta meta) { + public static NumberFormat getCalculationKm(final CallMeta meta) { return getFormatter( meta, CALCULATION_REPORT_KM_MIN_DIGITS, @@ -355,7 +355,7 @@ } - public static NumberFormat getFlowVelocityKM(CallContext context) { + public static NumberFormat getFlowVelocityKM(final CallContext context) { return getFormatter( context, FLOW_VELOCITY_KM_MIN_DIGITS, @@ -363,7 +363,7 @@ } - public static NumberFormat getFlowVelocityValues(CallContext context) { + public static NumberFormat getFlowVelocityValues(final CallContext context) { return getFormatter( context, FLOW_VELOCITY_VALUES_MIN_DIGITS, @@ -371,7 +371,7 @@ } - public static NumberFormat getFlowVelocityQ(CallContext context) { + public static NumberFormat getFlowVelocityQ(final CallContext context) { return getFormatter( context, FLOW_VELOCITY_Q_MIN_DIGITS, @@ -379,7 +379,7 @@ } - public static NumberFormat getMiddleBedHeightKM(CallContext context) { + public static NumberFormat getMiddleBedHeightKM(final CallContext context) { return getFormatter( context, MIDDLE_BED_HEIGHT_KM_MIN_DIGITS, @@ -387,7 +387,7 @@ } - public static NumberFormat getMiddleBedHeightHeight(CallContext context) { + public static NumberFormat getMiddleBedHeightHeight(final CallContext context) { return getFormatter( context, MIDDLE_BED_HEIGHT_HEIGHT_MIN_DIGITS, @@ -395,7 +395,7 @@ } - public static NumberFormat getMiddleBedHeightUncert(CallContext context) { + public static NumberFormat getMiddleBedHeightUncert(final CallContext context) { return getFormatter( context, MIDDLE_BED_HEIGHT_UNCERT_MIN_DIGITS, @@ -403,7 +403,7 @@ } - public static NumberFormat getMiddleBedHeightDataGap(CallContext context) { + public static NumberFormat getMiddleBedHeightDataGap(final CallContext context) { return getFormatter( context, MIDDLE_BED_HEIGHT_DATAGAP_MIN_DIGITS, @@ -412,8 +412,8 @@ public static NumberFormat getMiddleBedHeightSounding( - CallContext context - ) { + final CallContext context + ) { return getFormatter( context, MIDDLE_BED_HEIGHT_SOUNDING_WIDTH_MIN_DIGITS, @@ -421,63 +421,63 @@ } - public static NumberFormat getFixDeltaWKM(CallContext context) { + public static NumberFormat getFixDeltaWKM(final CallContext context) { return getFormatter( context, FIX_DELTA_W_KM_MIN_DIGITS, FIX_DELTA_W_KM_MAX_DIGITS); } - public static NumberFormat getFixDeltaWDeltaW(CallContext context) { - return getFormatter( - context, - FIX_DELTA_W_DELTA_W_MIN_DIGITS, - FIX_DELTA_W_DELTA_W_MAX_DIGITS); - } - - public static NumberFormat getFixDeltaWQ(CallContext context) { - return getFormatter( - context, - FIX_DELTA_W_DELTA_Q_MIN_DIGITS, - FIX_DELTA_W_DELTA_Q_MAX_DIGITS); - } - - public static NumberFormat getFixDeltaWW(CallContext context) { + public static NumberFormat getFixDeltaWDeltaW(final CallContext context) { return getFormatter( context, FIX_DELTA_W_DELTA_W_MIN_DIGITS, FIX_DELTA_W_DELTA_W_MAX_DIGITS); } - public static NumberFormat getVariance(CallContext context) { + public static NumberFormat getFixDeltaWQ(final CallContext context) { + return getFormatter( + context, + FIX_DELTA_W_DELTA_Q_MIN_DIGITS, + FIX_DELTA_W_DELTA_Q_MAX_DIGITS); + } + + public static NumberFormat getFixDeltaWW(final CallContext context) { + return getFormatter( + context, + FIX_DELTA_W_DELTA_W_MIN_DIGITS, + FIX_DELTA_W_DELTA_W_MAX_DIGITS); + } + + public static NumberFormat getVariance(final CallContext context) { return getFormatter( context, VARIANCE_MIN_DIGITS, VARIANCE_MAX_DIGITS); } - public static NumberFormat getSQRelationA(CallContext context) { + public static NumberFormat getSQRelationA(final CallContext context) { return getScientificFormater( context, SQ_RELATION_A_MIN_DIGITS, SQ_RELATION_A_MAX_DIGITS); } - public static NumberFormat getSQRelationB(CallContext context) { + public static NumberFormat getSQRelationB(final CallContext context) { return getFormatter( context, SQ_RELATION_B_MIN_DIGITS, SQ_RELATION_B_MAX_DIGITS); } - public static NumberFormat getSQRelationKM(CallContext context) { + public static NumberFormat getSQRelationKM(final CallContext context) { return getFormatter( context, SQ_RELATION_KM_MIN_DIGITS, SQ_RELATION_KM_MAX_DIGITS); } - public static NumberFormat getMeterFormat(CallContext context) { + public static NumberFormat getMeterFormat(final CallContext context) { return getFormatter( context, 0, @@ -485,32 +485,35 @@ } - public static DateFormat getDateFormatter(CallMeta m, String pattern) { - Locale locale = Resources.getLocale(m); + public static DateFormat getDateFormatter(final CallMeta m, final String pattern) { + final Locale locale = Resources.getLocale(m); return new SimpleDateFormat(pattern, locale); } - public static NumberFormat getMeanBedHeight(CallContext context) { + public static NumberFormat getMeanBedHeight(final CallContext context) { return Formatter.getFormatter(context, 2, 2); } - public static NumberFormat getTkh(CallContext context) { + public static NumberFormat getTkh(final CallContext context) { return Formatter.getFormatter(context, 1, 1); } - public static NumberFormat getFlowDepth(CallContext context) { + public static NumberFormat getFlowDepth(final CallContext context) { return Formatter.getFormatter(context, 2, 2); } - public static NumberFormat getW(CallContext context) { + public static NumberFormat getW(final CallContext context) { return Formatter.getFormatter(context, 2, 2); } /** * Another waterlevel formatter with fixed digits (always 2) */ - public static NumberFormat getWaterlevelW2(CallMeta meta) { + public static NumberFormat getWaterlevelW2(final CallMeta meta) { return getFormatter( meta, 2, 2); } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : + + public static NumberFormat getFlowDepthDevelopmentPerYear(final CallContext context) { + return getFormatter(context.getMeta(), 2, 2); + } +} \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/resources/messages.properties --- a/artifacts/src/main/resources/messages.properties Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/resources/messages.properties Fri Mar 16 18:08:38 2018 +0100 @@ -821,6 +821,12 @@ useTransportBodies.active = Activ useTransportBodies.inactive = Inactiv +state.sinfo.flowdepthdevlopment_current_select = Aktuelles Differenzenpaar +help.state.sinfo.flowdepthdevlopment_current_select = ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.flowdepthdevlopment_current_select + +state.sinfo.flowdepthdevlopment_historical_select = Historisches Differenzenpaar +help.state.sinfo.flowdepthdevlopment_historical_select = ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.flowdepthdevlopment_historical_select + sinfo.export.flow_depth.csv.meta.header.result = ## {0} - {1} - {2} sinfo.export.flow_depth.csv.meta.header.result.label = Calculation Output sinfo.export.flow_depth.csv.meta.version = # {0}: {1} diff -r b0aeed4c97c1 -r 322b0e6298ea artifacts/src/main/resources/messages_de.properties --- a/artifacts/src/main/resources/messages_de.properties Thu Mar 15 17:22:28 2018 +0100 +++ b/artifacts/src/main/resources/messages_de.properties Fri Mar 16 18:08:38 2018 +0100 @@ -821,6 +821,12 @@ useTransportBodies.active = Aktiv useTransportBodies.inactive = Inaktiv +state.sinfo.flowdepthdevlopment_current_select = Aktuelles Differenzenpaar +help.state.sinfo.flowdepthdevlopment_current_select = ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.flowdepthdevlopment_current_select + +state.sinfo.flowdepthdevlopment_historical_select = Historisches Differenzenpaar +help.state.sinfo.flowdepthdevlopment_historical_select = ${help.url}/OnlineHilfe/SINFO#help.state.sinfo.flowdepthdevlopment_historical_select + sinfo.export.flow_depth.csv.meta.header.result = ## {0} - {1} - {2} sinfo.export.flow_depth.csv.meta.header.result.label = Ergebnisausgabe sinfo.export.flow_depth.csv.meta.version = # {0}: {1} diff -r b0aeed4c97c1 -r 322b0e6298ea 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 Thu Mar 15 17:22:28 2018 +0100 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Fri Mar 16 18:08:38 2018 +0100 @@ -1457,5 +1457,7 @@ String sinfo_d50s(); String sinfo_flowdepthminmax_export(); + + String sinfo_flowdepthdevelopment_export(); } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea 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 Thu Mar 15 17:22:28 2018 +0100 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Fri Mar 16 18:08:38 2018 +0100 @@ -774,4 +774,5 @@ sinfo_bedqualities = Sohlbeschaffenheit sinfo_d50s = Korndurchmesser -sinfo_flowdepthminmax_export = min/max Flie\u00dftiefen Export \ No newline at end of file +sinfo_flowdepthminmax_export = min/max Flie\u00dftiefen Export +sinfo_flowdepthdevelopment_export = Flie\u00dftiefenentwicklung Export \ No newline at end of file diff -r b0aeed4c97c1 -r 322b0e6298ea 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 Thu Mar 15 17:22:28 2018 +0100 +++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Fri Mar 16 18:08:38 2018 +0100 @@ -775,4 +775,5 @@ sinfo_bedqualities = Sohlbeschaffenheit sinfo_d50s = Korndurchmesser -sinfo_flowdepthminmax_export = min/max Flie\u00dftiefen Export \ No newline at end of file +sinfo_flowdepthminmax_export = min/max Flie\u00dftiefen Export +sinfo_flowdepthdevelopment_export = Flie\u00dftiefenentwicklung Export \ No newline at end of file