# HG changeset patch # User mschaefer # Date 1531499885 -7200 # Node ID ef7b65576d4b61e5108aeb27a5c732ec7d2506eb # Parent 6c24c857ccf95c2633fd5caf914a1accf7b3ba4b Added W and Q main values to S-Info flood duration curve chart diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResults.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResults.java Fri Jul 13 12:04:21 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculationResults.java Fri Jul 13 18:38:05 2018 +0200 @@ -13,6 +13,7 @@ import org.dive4elements.river.artifacts.common.AbstractCalculationResults; import org.dive4elements.river.artifacts.model.CalculationResult; import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; +import org.dive4elements.river.jfree.RiverAnnotation; /** * @author Gernot Belger @@ -34,4 +35,24 @@ public void setDurationCurve(final CalculationResult durationCurve) { this.durationCurve = durationCurve; } + + private RiverAnnotation mainValueWAnnotation; + + public RiverAnnotation getMainValueWAnnotation() { + return this.mainValueWAnnotation; + } + + public void setMainValueWAnnotation(final RiverAnnotation mainValueAnnotation) { + this.mainValueWAnnotation = mainValueAnnotation; + } + + private RiverAnnotation mainValueQAnnotation; + + public RiverAnnotation getMainValueQAnnotation() { + return this.mainValueQAnnotation; + } + + public void setMainValueQAnnotation(final RiverAnnotation mainValueAnnotation) { + this.mainValueQAnnotation = mainValueAnnotation; + } } \ No newline at end of file diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Fri Jul 13 12:04:21 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCalculator.java Fri Jul 13 18:38:05 2018 +0200 @@ -33,6 +33,9 @@ import org.dive4elements.river.artifacts.sinfo.common.WQBaseTableFinder; import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey; import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; +import org.dive4elements.river.jfree.RiverAnnotation; +import org.dive4elements.river.jfree.StickyAxisAnnotation; +import org.dive4elements.river.jfree.StickyAxisAnnotation.SimpleAxis; import org.dive4elements.river.model.Attribute.AttributeKey; import org.dive4elements.river.model.Gauge; import org.dive4elements.river.model.sinfo.InfrastructureValue; @@ -116,11 +119,17 @@ } results.addResult(new FloodDurationCalculationResult(label, mainValueLabels, this.rows), problems); calcWQDays(problems, stationsSorted[0], AttributeKey.LEFT, winfo, results); + calcMainValueAnnotations(label, problems, 0, AttributeKey.LEFT, wqkmsArray, mainValueLabels, results); + // TODO Infrastrukturhoehe } - public void calcWQDays(final Calculation problems, final double station, final AttributeKey riverside, final WINFOArtifact winfo, + /** + * Calculate duration curve for a station and add to result collection + */ + private void calcWQDays(final Calculation problems, final double station, final AttributeKey riverside, final WINFOArtifact winfo, final FloodDurationCalculationResults results) { + // Same processing as in W-Info DurationCurveState winfo.addStringData("ld_locations", Double.toString(station)); final CalculationResult res = winfo.getDurationCurveData(); final WQDay underflow = (WQDay) res.getData(); @@ -134,12 +143,51 @@ qs[j] = underflow.getQ(i); } res.setData(new WQDay(days, ws, qs)); - // TODO Infrastrukturhoehe - // TODO WSPL/Hauptwerte results.setDurationCurve(res); } /** + * Calculate the data for the W and Q main value lines in the duration curve chart and add to result collection + */ + private void calcMainValueAnnotations(final String label, final Calculation problems, final int stationIndex, final AttributeKey riverside, + final WQKms[] wqkmsArray, final String[] mainValueLabels, final FloodDurationCalculationResults results) { + + // Same way as in MainValueWFacet and ..QFacet + final List ws = new ArrayList<>(); + final List qs = new ArrayList<>(); + for (int i = 0; i <= wqkmsArray.length - 1; i++) { + final StickyAxisAnnotation qAnnotation = new StickyAxisAnnotation(mainValueLabels[i], (float) wqkmsArray[i].getQ(stationIndex), SimpleAxis.Y_AXIS, + FloodDurationCurveGenerator.YAXIS.Q.idx); + qs.add(qAnnotation); + setHitPoint((WQDay) results.getDurationCurve().getData(), qAnnotation); + final StickyAxisAnnotation wAnnotation = new StickyAxisAnnotation(mainValueLabels[i], (float) wqkmsArray[i].getW(stationIndex), SimpleAxis.Y_AXIS, + FloodDurationCurveGenerator.YAXIS.W.idx); + ws.add(wAnnotation); + setHitPoint((WQDay) results.getDurationCurve().getData(), wAnnotation); + } + // TODO RiverAnnotation ersetzen weil das eine NotSerializableException erzeugt + results.setMainValueQAnnotation(new RiverAnnotation(label, qs)); + results.setMainValueWAnnotation(new RiverAnnotation(label, ws)); + } + + /** + * Set the hit-point in Q where a line drawn from the axis would hit the + * curve in WQDay (if hit). + * Employ linear interpolation. + */ + private static void setHitPoint(final WQDay wqday, final StickyAxisAnnotation annotation) { + + final float q = annotation.getPos(); + final Double day = wqday.interpolateDayByQ(q); + if (day != null) { + annotation.setHitPoint(day.floatValue()); + } + // else if (log.isDebugEnabled()) { + // log.debug("StickyAnnotation does not hit wqday curve: " + q); + // } + } + + /** * Adds to a stations map all stations corresponding to the active range and step */ private void addRangeStations(final Map allStations, final WINFOArtifact winfo) { diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveFacet.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveFacet.java Fri Jul 13 12:04:21 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveFacet.java Fri Jul 13 18:38:05 2018 +0200 @@ -8,8 +8,8 @@ package org.dive4elements.river.artifacts.sinfo.flood_duration; -import java.util.ArrayList; -import java.util.List; +//import java.util.ArrayList; +//import java.util.List; import org.apache.log4j.Logger; import org.dive4elements.artifactdatabase.state.DefaultFacet; @@ -18,7 +18,7 @@ import org.dive4elements.artifacts.CallContext; import org.dive4elements.river.artifacts.D4EArtifact; import org.dive4elements.river.artifacts.model.CalculationResult; -import org.dive4elements.river.artifacts.model.WQDay; +//import org.dive4elements.river.artifacts.model.WQDay; import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; @@ -29,11 +29,11 @@ private static Logger log = Logger.getLogger(FloodDurationCurveFacet.class); - /** Blackboard data provider key for durationcurve (wqday) data. */ - public static String BB_DURATIONCURVE = "durationcurve"; - - /** Blackboard data provider key for km of durationcurve. */ - public static String BB_DURATIONCURVE_KM = "durationcurve.km"; + // /** Blackboard data provider key for durationcurve (wqday) data. */ + // public static String BB_DURATIONCURVE = "durationcurve"; + // + // /** Blackboard data provider key for km of durationcurve. */ + // public static String BB_DURATIONCURVE_KM = "durationcurve.km"; public FloodDurationCurveFacet() { } @@ -61,52 +61,52 @@ // return getTestData(); } - private WQDay getTestData() { - final int[] days = new int[366]; - final double[] ws = new double[366]; - final double[] qs = new double[366]; - for (int i = 0; i <= 365; i++) { - days[i] = i; - final double x = (i - 182.5) / 182.5; - ws[i] = 102.0 - (Math.pow(x, 5) + x); - qs[i] = 1600.0 - 800 * (Math.pow(x, 9) + x); - } - return new WQDay(days, ws, qs); - } - - - @Override - public List getStaticDataProviderKeys(final Artifact art) { - final List list = new ArrayList(); - list.add(BB_DURATIONCURVE); - list.add(BB_DURATIONCURVE_KM); - return list; - } + // private WQDay getTestData() { + // final int[] days = new int[366]; + // final double[] ws = new double[366]; + // final double[] qs = new double[366]; + // for (int i = 0; i <= 365; i++) { + // days[i] = i; + // final double x = (i - 182.5) / 182.5; + // ws[i] = 102.0 - (Math.pow(x, 5) + x); + // qs[i] = 1600.0 - 800 * (Math.pow(x, 9) + x); + // } + // return new WQDay(days, ws, qs); + // } - /** - * Can provide whatever getData returns and additionally the location. - * @param key will respond on BB_DURATIONCURVE +KM - * @param param ignored - * @param context ignored - * @return whatever getData delivers or location. - */ - @Override - public Object provideBlackboardData(final Artifact artifact, - final Object key, - final Object param, - final CallContext context - ) { - if (key.equals(BB_DURATIONCURVE)) { - return getData(artifact, context); - } - else if (key.equals(BB_DURATIONCURVE_KM)) { - return ((D4EArtifact)artifact).getDataAsString("ld_locations"); - } - else { - return null; - } - } + // @Override + // public List getStaticDataProviderKeys(final Artifact art) { + // final List list = new ArrayList(); + // list.add(BB_DURATIONCURVE); + // list.add(BB_DURATIONCURVE_KM); + // return list; + // } + + + // /** + // * Can provide whatever getData returns and additionally the location. + // * @param key will respond on BB_DURATIONCURVE +KM + // * @param param ignored + // * @param context ignored + // * @return whatever getData delivers or location. + // */ + // @Override + // public Object provideBlackboardData(final Artifact artifact, + // final Object key, + // final Object param, + // final CallContext context + // ) { + // if (key.equals(BB_DURATIONCURVE)) { + // return getData(artifact, context); + // } + // else if (key.equals(BB_DURATIONCURVE_KM)) { + // return ((D4EArtifact)artifact).getDataAsString("ld_locations"); + // } + // else { + // return null; + // } + // } /** Create a deep copy. */ diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveGenerator.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveGenerator.java Fri Jul 13 12:04:21 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveGenerator.java Fri Jul 13 18:38:05 2018 +0200 @@ -130,7 +130,7 @@ final boolean zoomin = super.zoom(plot, axis, bounds, x); if (!zoomin) axis.setLowerBound(0d); - // axis.setUpperBound(364); + axis.setUpperBound(364); return zoomin; } diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveProcessor.java Fri Jul 13 12:04:21 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveProcessor.java Fri Jul 13 18:38:05 2018 +0200 @@ -35,11 +35,17 @@ private static final String FACET_FLOOD_DURATION_Q = "duration_curve.q"; + private static final String FACET_FLOOD_DURATION_MAINVALUES_W = "mainvalues.w"; + + private static final String FACET_FLOOD_DURATION_MAINVALUES_Q = "mainvalues.q"; + private static final Set HANDLED_FACET_TYPES = new HashSet<>(); static { HANDLED_FACET_TYPES.add(FACET_FLOOD_DURATION_W); HANDLED_FACET_TYPES.add(FACET_FLOOD_DURATION_Q); + HANDLED_FACET_TYPES.add(FACET_FLOOD_DURATION_MAINVALUES_W); + HANDLED_FACET_TYPES.add(FACET_FLOOD_DURATION_MAINVALUES_Q); } public static Facet createFloodDurationWCurveFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result, @@ -54,6 +60,18 @@ return new FloodDurationCurveFacet(FACET_FLOOD_DURATION_Q, description); } + public static Facet createMainValuesWFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result, + final int facetIndex, final int resultIndex, final String description) { + + return new FloodDurationMainValuesWFacet(FACET_FLOOD_DURATION_MAINVALUES_W, description); + } + + public static Facet createMainValuesQFacet(final CallContext context, final String hash, final String id, final AbstractCalculationResult result, + final int facetIndex, final int resultIndex, final String description) { + + return new FloodDurationMainValuesQFacet(FACET_FLOOD_DURATION_MAINVALUES_Q, description); + } + /** * Processes data to generate a chart. */ diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationMainValuesQFacet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationMainValuesQFacet.java Fri Jul 13 18:38:05 2018 +0200 @@ -0,0 +1,91 @@ +/* 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.flood_duration; + +import org.apache.log4j.Logger; +import org.dive4elements.artifactdatabase.state.DefaultFacet; +import org.dive4elements.artifacts.Artifact; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.D4EArtifact; +import org.dive4elements.river.artifacts.model.CalculationResult; +import org.dive4elements.river.artifacts.model.WQDay; +import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; +import org.dive4elements.river.jfree.StickyAxisAnnotation; + + +/** + * Facet to show Main Q Values. + */ +public class FloodDurationMainValuesQFacet extends DefaultFacet { + + /** Own log. */ + private static Logger log = Logger.getLogger(FloodDurationMainValuesQFacet.class); + + /** Trivial Constructor. */ + public FloodDurationMainValuesQFacet(final String name, final String description) { + this.description = description; + this.name = name; + this.index = 0; + } + + /** + * Set the hit-point in Q where a line drawn from the axis would hit the + * curve in WQDay (if hit). + * Employ linear interpolation. + */ + protected static void setHitPoint(final WQDay wqday, final StickyAxisAnnotation annotation) { + + final float q = annotation.getPos(); + final Double day = wqday.interpolateDayByQ(q); + + if (day != null) { + annotation.setHitPoint(day.floatValue()); + } + else if (log.isDebugEnabled()) { + log.debug("StickyAnnotation does not hit wqday curve: " + q); + } + } + + + /** + * Returns the data this facet requires. + * + * @param artifact the owner artifact. + * @param context the CallContext (can be used to find out if in + * navigable fixation-setting, or durationcurve). + * + * @return the data. + */ + @Override + public Object getData(final Artifact artifact, final CallContext context) { + + log.debug("Get data for flood duration main value Q data"); + + final D4EArtifact flys = (D4EArtifact) artifact; + + final CalculationResult res = (CalculationResult) flys.compute(context, ComputeType.ADVANCE, false); + + final FloodDurationCalculationResults data = (FloodDurationCalculationResults) res.getData(); + + return data.getMainValueQAnnotation(); + } + + + /** + * Create a deep copy of this Facet. + * @return a deep copy. + */ + @Override + public FloodDurationMainValuesQFacet deepCopy() { + final FloodDurationMainValuesQFacet copy = new FloodDurationMainValuesQFacet(this.name, this.description); + copy.set(this); + return copy; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationMainValuesWFacet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationMainValuesWFacet.java Fri Jul 13 18:38:05 2018 +0200 @@ -0,0 +1,92 @@ +/* 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.flood_duration; + +import org.apache.log4j.Logger; +import org.dive4elements.artifactdatabase.state.DefaultFacet; +import org.dive4elements.artifacts.Artifact; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.D4EArtifact; +import org.dive4elements.river.artifacts.model.CalculationResult; +import org.dive4elements.river.artifacts.model.WQDay; +import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; +import org.dive4elements.river.jfree.StickyAxisAnnotation; + +/** + * Facet to show Main W Values. + */ +public class FloodDurationMainValuesWFacet extends DefaultFacet { + + /** Own log. */ + private static Logger log = Logger.getLogger(FloodDurationMainValuesWFacet.class); + + /** Trivial Constructor. */ + public FloodDurationMainValuesWFacet(final String name, final String description) { + this.description = description; + this.name = name; + this.index = 0; + } + + + /** + * Set the hit-point in W where a line drawn from the axis would hit the + * curve in WQDay (if hit). + * Employ linear interpolation. + */ + protected static void setHitPoint(final WQDay wqday, final StickyAxisAnnotation annotation) { + + final float w = annotation.getPos(); + + final Double day = wqday.interpolateDayByW(w); + + if (day != null) { + annotation.setHitPoint(day.floatValue()); + } + else if (log.isDebugEnabled()) { + log.debug("StickyAnnotation does not hit wqday curve: " + w); + } + } + + + /** + * Returns the data this facet provides. + * + * @param artifact the owner artifact. + * @param context the CallContext (can be used to find out if in + * navigable fixation-setting, or durationcurve). + * + * @return the data. + */ + @Override + public Object getData(final Artifact artifact, final CallContext context) { + + log.debug("Get data for flood duration main value W data"); + + final D4EArtifact flys = (D4EArtifact) artifact; + + final CalculationResult res = (CalculationResult) flys.compute(context, ComputeType.ADVANCE, false); + + final FloodDurationCalculationResults data = (FloodDurationCalculationResults) res.getData(); + + return data.getMainValueWAnnotation(); + } + + + /** + * Create a deep copy of this Facet. + * @return a deep copy. + */ + @Override + public FloodDurationMainValuesWFacet deepCopy() { + final FloodDurationMainValuesWFacet copy = new FloodDurationMainValuesWFacet(this.name, this.description); + copy.set(this); + return copy; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Fri Jul 13 12:04:21 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationState.java Fri Jul 13 18:38:05 2018 +0200 @@ -109,6 +109,12 @@ final String nameQ = Resources.getMsg(context.getMeta(), "sinfo.chart.flood_duration.curve.q"); facets.add(FloodDurationCurveProcessor.createFloodDurationWCurveFacet(context, hash, this.id, result, 0, resultIndex, nameW)); facets.add(FloodDurationCurveProcessor.createFloodDurationQCurveFacet(context, hash, this.id, result, 1, resultIndex, nameQ)); + if (waterlevelCount >= 1) { + facets.add(FloodDurationCurveProcessor.createMainValuesWFacet(context, hash, this.id, result, 0, resultIndex, + Resources.getMsg(context.getMeta(), "sinfo.chart.flood_duration.curve.mainw"))); + facets.add(FloodDurationCurveProcessor.createMainValuesQFacet(context, hash, this.id, result, 1, resultIndex, + Resources.getMsg(context.getMeta(), "sinfo.chart.flood_duration.curve.mainq"))); + } facets.add(new DataFacet(FacetTypes.CSV, "CSV data", ComputeType.ADVANCE, hash, this.id)); facets.add(new DataFacet(FacetTypes.PDF, "PDF data", ComputeType.ADVANCE, hash, this.id)); diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/resources/messages.properties --- a/artifacts/src/main/resources/messages.properties Fri Jul 13 12:04:21 2018 +0200 +++ b/artifacts/src/main/resources/messages.properties Fri Jul 13 18:38:05 2018 +0200 @@ -1157,6 +1157,8 @@ sinfo.chart.flood_duration.curve.xaxis.label = \u00dcberflutungsdauer [d/a] sinfo.chart.flood_duration.curve.w = Wasserstandsdauerlinie sinfo.chart.flood_duration.curve.q = Abflussdauerlinie +sinfo.chart.flood_duration.curve.mainw = W (ausgew\u00e4hlte WSPL) +sinfo.chart.flood_duration.curve.mainq = Q (ausgew\u00e4hlte WSPL) bundu_bezugswst = Bezugswasserst\u00e4nde bundu_analysis = Fixinganalysis diff -r 6c24c857ccf9 -r ef7b65576d4b artifacts/src/main/resources/messages_de.properties --- a/artifacts/src/main/resources/messages_de.properties Fri Jul 13 12:04:21 2018 +0200 +++ b/artifacts/src/main/resources/messages_de.properties Fri Jul 13 18:38:05 2018 +0200 @@ -1157,6 +1157,8 @@ sinfo.chart.flood_duration.curve.xaxis.label = \u00dcberflutungsdauer [d/a] sinfo.chart.flood_duration.curve.w = Wasserstandsdauerlinie sinfo.chart.flood_duration.curve.q = Abflussdauerlinie +sinfo.chart.flood_duration.curve.mainw = W (ausgew\u00e4hlte WSPL) +sinfo.chart.flood_duration.curve.mainq = Q (ausgew\u00e4hlte WSPL) bundu_bezugswst = Bezugswasserst\u00e4nde bundu_analysis = Fixierungsanalyse