# HG changeset patch # User gernotbelger # Date 1518530003 -3600 # Node ID 7a8c127068340b73d2b8572bda7c5684c3bc6975 # Parent a536e1aacf0f6e2823561b4b705ecb211eada515 Work on SINFO-FlowDepth diff -r a536e1aacf0f -r 7a8c12706834 artifacts/doc/conf/artifacts/sinfo.xml --- a/artifacts/doc/conf/artifacts/sinfo.xml Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/doc/conf/artifacts/sinfo.xml Tue Feb 13 14:53:23 2018 +0100 @@ -60,6 +60,9 @@ + + + + \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/doc/conf/themes.xml --- a/artifacts/doc/conf/themes.xml Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/doc/conf/themes.xml Tue Feb 13 14:53:23 2018 +0100 @@ -407,5 +407,7 @@ + + \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/doc/conf/themes/default.xml --- a/artifacts/doc/conf/themes/default.xml Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/doc/conf/themes/default.xml Tue Feb 13 14:53:23 2018 +0100 @@ -2883,5 +2883,22 @@ default="0, 0, 255" /> - + + + + + + + + + + + + + + + + diff -r a536e1aacf0f -r 7a8c12706834 artifacts/doc/conf/themes/second.xml --- a/artifacts/doc/conf/themes/second.xml Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/doc/conf/themes/second.xml Tue Feb 13 14:53:23 2018 +0100 @@ -2880,4 +2880,22 @@ default="0, 0, 255" /> + + + + + + + + + + + + + + + + \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/AbstractSInfoProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/AbstractSInfoProcessor.java Tue Feb 13 14:53:23 2018 +0100 @@ -0,0 +1,98 @@ +/* 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.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.exports.DiagramGenerator; +import org.dive4elements.river.exports.StyledSeriesBuilder; +import org.dive4elements.river.exports.process.DefaultProcessor; +import org.dive4elements.river.jfree.StyledXYSeries; +import org.dive4elements.river.themes.ThemeDocument; + +/** + * Abstraction for some processor implementation within S-INFO. Probably this abstraction could also be used for other + * cases as well. + * + * @author Gernot Belger + * + */ +abstract class AbstractSInfoProcessor extends DefaultProcessor { + + private final static Logger log = Logger.getLogger(AbstractSInfoProcessor.class); + + private String yAxisLabel; + + private final Set handled_facet_types; + + private final String i18n_axis_label; + + public AbstractSInfoProcessor(final String i18n_axis_label, final Set handled_facet_types) { + this.i18n_axis_label = i18n_axis_label; + this.handled_facet_types = handled_facet_types; + } + + @Override + public final void doOut(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) { + + final CallContext context = generator.getCallContext(); + final Map metaData = bundle.getFacet().getMetaData(); + + final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme); + series.putMetaData(metaData, bundle.getArtifact(), context); + + this.yAxisLabel = metaData.get("Y"); + + final String facetName = bundle.getFacetName(); + final FlowDepthCalculationResult data = (FlowDepthCalculationResult) bundle.getData(context); + if (data == null) { + // Check has been here before so we keep it for security reasons + // this should never happen though. + log.error("Data is null for facet: " + facetName); + return; + } + + final double[][] points = generatePoints(data, facetName); + + StyledSeriesBuilder.addPoints(series, points, true); + generator.addAxisSeries(series, this.axisName, visible); + } + + /** + * Override to implement, call super as last line for default case. + */ + protected double[][] generatePoints(@SuppressWarnings("unused") final FlowDepthCalculationResult data, final String facetName) { + final String error = String.format("Unknown facet name: %s", facetName); + log.error(error); + throw new UnsupportedOperationException(error); + } + + @Override + public final boolean canHandle(final String facettype) { + return this.handled_facet_types.contains(facettype); + } + + @Override + public final String getAxisLabel(final DiagramGenerator generator) { + if (this.yAxisLabel != null && !this.yAxisLabel.isEmpty()) { + // REMARK/UNINTENDED: yAxisLabel may also be a resolved message (side-effect of StyledXYSeries#putMetadata), + // and cannot be resolved, so we need to give the resolved value as default + // FIXME: In other implementations (i.e. FlowVelocityProcessor), an explicit (German) default label is given here, + // probably the English version will also show German (CHECK) + return generator.msg(this.yAxisLabel, this.yAxisLabel); + } + return generator.msg(this.i18n_axis_label, "MISSING"); + } +} \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 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 Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedHeightInfo.java Tue Feb 13 14:53:23 2018 +0100 @@ -9,6 +9,8 @@ */ package org.dive4elements.river.artifacts.sinfo.flowdepth; +import java.io.Serializable; + import org.dive4elements.river.model.BedHeight; /** @@ -16,7 +18,9 @@ * * @author Gernot Belger */ -final class BedHeightInfo { +final class BedHeightInfo implements Serializable { + + private static final long serialVersionUID = 1L; private final Integer year; diff -r a536e1aacf0f -r 7a8c12706834 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 Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Tue Feb 13 14:53:23 2018 +0100 @@ -75,8 +75,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, river, from, to, useTkh); for (final DifferencesPair diffPair : diffPairs) { final FlowDepthCalculationResult result = calculateResult(river, from, to, diffPair, problems, gaugeIndex); @@ -87,8 +86,8 @@ return new CalculationResult(results, problems); } - private FlowDepthCalculationResult calculateResult(final River river, final double from, final double to, - final DifferencesPair diffPair, final Calculation problems, final GaugeIndex gaugeIndex) { + private FlowDepthCalculationResult calculateResult(final River river, final double from, final double to, final DifferencesPair diffPair, + final Calculation problems, final GaugeIndex gaugeIndex) { /* access real input data from database */ final String soundingId = diffPair.getSoundingId(); @@ -96,18 +95,15 @@ final BedHeight bedHeight = loadBedHeight(soundingId, from, to); if (bedHeight == null) { - final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", - soundingId); + final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", soundingId); problems.addProblem(message); return null; } /* REMARK: fetch ALL wst kms, because we want to determine the original reference gauge */ - final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, - Double.NaN); + final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN); if (waterlevel == null) { - final String message = Resources.format(this.context.getMeta(), "Failed to access waterlevel with id '{0}'", - wstId); + final String message = Resources.format(this.context.getMeta(), "Failed to access waterlevel with id '{0}'", wstId); problems.addProblem(message); return null; } @@ -121,8 +117,7 @@ checkWaterlevelDiscretisation(wstKms, problems); /* 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); + final String notinrange = Resources.getMsg(this.context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE); final Gauge refGauge = waterlevel.findReferenceGauge(river); final String refGaugeName = refGauge == null ? notinrange : refGauge.getName(); @@ -136,23 +131,23 @@ // FIXME: nur prüfen/beschaffen wenn TKH Berechnung aktiv /* Abflusswerte vorhanden? */ if (!(wstKms instanceof QKms)) { - final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", - null, label); + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, label); problems.addProblem(message); // TODO: keine Berechnung TKH } + // FIXME // - Sohlbeschaffenheit (D50 Korndurchmesser aus Seddb) // - Abhängig von Peiljahr // - kein D50 vorhanden --> Fehler + // FIXME // - Art der Gewässersohle (starr/mobil) final String bedHeightLabel = bedHeight.getDescription(); final String wstLabel = wstKms.getName(); - final UnivariateRealFunction wstInterpolator = DoubleUtil.getLinearInterpolator(wstKms.allKms(), - wstKms.allWs()); + final UnivariateRealFunction wstInterpolator = DoubleUtil.getLinearInterpolator(wstKms.allKms(), wstKms.allWs()); // FIXME: sort by station first, but in what direction? final List values = bedHeight.getValues(); @@ -195,8 +190,7 @@ final String gaugeLabel = gauge == null ? notinrange : gauge.getName(); - resultData.addRow(km, flowDepth, flowDepthTkh, tkh, wst, discharge, wstLabel, gaugeLabel, meanBedHeight, - bedHeightLabel, location); + resultData.addRow(km, flowDepth, flowDepthTkh, tkh, wst, discharge, wstLabel, gaugeLabel, meanBedHeight, bedHeightLabel, location); } catch (final FunctionEvaluationException e) { /* should only happen if out of range */ @@ -218,8 +212,7 @@ * 1918 ≤ X < 1958 ± 12 * X < 1918 ± 25 */ - private void checkYearDifference(final String label, final WaterlevelData waterlevel, final BedHeight sounding, - final Calculation problems) { + private void checkYearDifference(final String label, final WaterlevelData waterlevel, final BedHeight sounding, final Calculation problems) { final Integer soundingYear = sounding.getYear(); if (soundingYear == null) @@ -233,8 +226,7 @@ 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, difference); problems.addProblem(message); } } @@ -254,8 +246,7 @@ return 3; } - private Gauge findGauge(final WaterlevelData waterlevel, final Gauge refGauge, final GaugeIndex gaugeIndex, - final double km) { + private Gauge findGauge(final WaterlevelData waterlevel, final Gauge refGauge, final GaugeIndex gaugeIndex, final double km) { // REMARK: using same logic as in WaterlevelExporter here @@ -271,6 +262,7 @@ } /* 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) { final int size = wstKms.size(); for (int i = 0; i < size - 2; i++) { @@ -280,8 +272,7 @@ 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); + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.waterlevel_discretisation", null, label); problems.addProblem(kmPrev, message); } } @@ -314,4 +305,4 @@ return BedHeight.getBedHeightById(bedheightId); } -} +} \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 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 Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Tue Feb 13 14:53:23 2018 +0100 @@ -72,4 +72,29 @@ return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; } + + public double[][] getFlowDepthTkhPoints() { + + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + + for (final FlowDepthRow row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getFlowDepthWithTkh()); + } + + return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; + } + + public double[][] getTkhPoints() { + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + + for (final FlowDepthRow row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getTkh()); + } + + return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; + } } \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 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 Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResults.java Tue Feb 13 14:53:23 2018 +0100 @@ -9,6 +9,7 @@ */ package org.dive4elements.river.artifacts.sinfo.flowdepth; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -18,7 +19,9 @@ /** * @author Gernot Belger */ -public final class FlowDepthCalculationResults { +public final class FlowDepthCalculationResults implements Serializable { + private static final long serialVersionUID = 1L; + private final List results = new ArrayList<>(); private final River river; diff -r a536e1aacf0f -r 7a8c12706834 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 Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthExporter.java Tue Feb 13 14:53:23 2018 +0100 @@ -100,7 +100,6 @@ private static final String CSV_META_HEADER_WATERLEVEL_NAME = "sinfo.export.flow_depth.csv.meta.header.waterlevel.name"; - private static final String CSV_META_HEADER_WATERLEVEL_GAUGE = "sinfo.export.flow_depth.csv.meta.header.waterlevel.gauge"; private static final String CSV_META_HEADER_WATERLEVEL_YEAR = "sinfo.export.flow_depth.csv.meta.header.waterlevel.year"; @@ -163,8 +162,7 @@ } } - private void writeCSVFlowDepthResult(final CSVWriter writer, final FlowDepthCalculationResult result, - final boolean useTkh) { + private void writeCSVFlowDepthResult(final CSVWriter writer, final FlowDepthCalculationResult result, final boolean useTkh) { /* first some specific metadata */ final BedHeightInfo sounding = result.getSounding(); @@ -184,8 +182,7 @@ // "# Höhensystem: " writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL, sounding.getCurElevationModelUnit()); // "# ursprüngliches Höhensystem: " - writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL_ORIGINAL, - sounding.getOldElevationModelUnit()); + writeCSVMetaEntry(writer, CSV_META_HEADER_SOUNDING_ELEVATIOIN_MODEL_ORIGINAL, sounding.getOldElevationModelUnit()); // "##METADATEN WASSERSPIEGELLAGE" writeCSVMetaEntry(writer, CSV_META_HEADER_WATERLEVEL); @@ -208,8 +205,7 @@ final String calcModeLabel = results.getCalcModeLabel(); final River river = results.getRiver(); - writeCSVMetaEntry(writer, CSV_META_HEADER_RESULT, msg(CSV_META_HEADER_RESULT_LABEL), river.getName(), - calcModeLabel); + writeCSVMetaEntry(writer, CSV_META_HEADER_RESULT, msg(CSV_META_HEADER_RESULT_LABEL), river.getName(), calcModeLabel); // "# FLYS-Version: " writeCSVMetaEntry(writer, CSV_META_VERSION, msg(CSV_META_VERSION_LABEL), FLYS.VERSION); @@ -302,10 +298,9 @@ // Q [m³/s] final double discharge = row.getDischarge(); - if( Double.isNaN(discharge)) + if (Double.isNaN(discharge)) lines.add(StringUtils.EMPTY); - else - { + else { final double roundedDischarge = RiverUtils.roundQ(discharge); lines.add(getQFormatter().format(roundedDischarge)); } @@ -402,8 +397,7 @@ 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 String rangeValue = String.format("%s - %s", getKmFormatter().format(results.getFrom()), getKmFormatter().format(results.getTo())); source.addMetaData("range_label", msg(CSV_META_RANGE_LABEL)); source.addMetaData("range", rangeValue); @@ -422,8 +416,7 @@ source.addMetaData("location_header", msg(CSV_LOCATION_HEADER)); } - private void addJRTableData(final MetaAndTableJRDataSource source, final FlowDepthCalculationResult result, - final boolean useTkh) { + private void addJRTableData(final MetaAndTableJRDataSource source, final FlowDepthCalculationResult result, final boolean useTkh) { final Collection rows = result.getRows(); diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthFacet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthFacet.java Tue Feb 13 14:53:23 2018 +0100 @@ -0,0 +1,93 @@ +/* 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.flowdepth; + +import org.apache.log4j.Logger; +import org.dive4elements.artifactdatabase.state.Facet; +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.DataFacet; +import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; + +/** + * Facet of a FlowDepth curve. + */ +public class FlowDepthFacet extends DataFacet { + + private static final long serialVersionUID = 1L; + + private static Logger log = Logger.getLogger(FlowDepthFacet.class); + + public FlowDepthFacet() { + // required for clone operation deepCopy() + } + + public FlowDepthFacet(final int idx, final String name, final String description, final String yAxisLabelKey, final ComputeType type, final String stateId, + final String hash) { + super(idx, name, description, type, hash, stateId); + this.metaData.put("X", "sinfo.chart.flow_depth.xaxis.label"); + this.metaData.put("Y", yAxisLabelKey); + } + + @Override + public Object getData(final Artifact artifact, final CallContext context) { + log.debug("Get data for flow velocity at index: " + this.index); + + final D4EArtifact flys = (D4EArtifact) artifact; + + final CalculationResult res = (CalculationResult) flys.compute(context, this.hash, this.stateId, this.type, false); + + final FlowDepthCalculationResults data = (FlowDepthCalculationResults) res.getData(); + + final FlowDepthCalculationResult result = data.getResults().get(this.index); + + // FIXME: variable mean computation depending on current scale + + // Double start = (Double)context.getContextValue("startkm"); + // Double end = (Double)context.getContextValue("endkm"); + // if(start != null && end != null) { + // RiverContext fc = (RiverContext)context.globalContext(); + // ZoomScale scales = (ZoomScale)fc.get("zoomscale"); + // RiverAccess access = new RiverAccess((D4EArtifact)artifact); + // String river = access.getRiverName(); + // + // double radius = scales.getRadius(river, start, end); + // FlowVelocityData oldData = data[index]; + // FlowVelocityData newData = new FlowVelocityData(); + // double[][] q = oldData.getQPoints(); + // double[][] totalV = MovingAverage.weighted(oldData.getTotalChannelPoints(), radius); + // double[][] mainV = MovingAverage.weighted(oldData.getMainChannelPoints(), radius); + // double[][] tau = MovingAverage.weighted(oldData.getTauPoints(), radius); + // for(int j = 0; j < q[0].length; j++) { + // newData.addKM(q[0][j]); + // newData.addQ(q[1][j]); + // newData.addTauMain(tau[1][j]); + // newData.addVMain(mainV[1][j]); + // newData.addVTotal(totalV[1][j]); + // } + // return newData; + // } + + return result; + } + + /** Copy deeply. */ + @Override + public Facet deepCopy() { + final FlowDepthFacet copy = new FlowDepthFacet(); + // FIXME: why does DataFacet does not override set? Bad access to variables of parent! + copy.set(this); + copy.type = this.type; + copy.hash = this.hash; + copy.stateId = this.stateId; + return copy; + } +} \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthFilterFacet.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthFilterFacet.java Fri Feb 09 18:07:22 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* 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.flowdepth; - -import org.apache.log4j.Logger; -import org.dive4elements.artifactdatabase.state.Facet; -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.DataFacet; -import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; - -/** - * Facet of a FlowDepth curve. - */ -public class FlowDepthFilterFacet extends DataFacet { - - private static Logger log = Logger.getLogger(FlowDepthFilterFacet.class); - - public FlowDepthFilterFacet() { - // required for clone operation deepCopy() - } - - public FlowDepthFilterFacet( - int idx, - String name, - String description, - ComputeType type, - String stateId, - String hash - ) { - super(idx, name, description, type, hash, stateId); - this.metaData.put("X", "sinfo.chart.flow_depth.xaxis.label"); - this.metaData.put("Y", "sinfo.chart.flow_depth.yaxis.label"); - } - - @Override - public Object getData(Artifact artifact, CallContext context) { - log.debug("Get data for flow velocity at index: " + index); - - final D4EArtifact flys = (D4EArtifact) artifact; - - final CalculationResult res = (CalculationResult) - flys.compute(context, hash, stateId, type, false); - - final FlowDepthCalculationResults data = (FlowDepthCalculationResults) res.getData(); - - final FlowDepthCalculationResult result = data.getResults().get(index); - - // FIXME: variable mean computation depending on current scale -// Double start = (Double)context.getContextValue("startkm"); -// Double end = (Double)context.getContextValue("endkm"); -// if(start != null && end != null) { -// RiverContext fc = (RiverContext)context.globalContext(); -// ZoomScale scales = (ZoomScale)fc.get("zoomscale"); -// RiverAccess access = new RiverAccess((D4EArtifact)artifact); -// String river = access.getRiverName(); -// -// double radius = scales.getRadius(river, start, end); -// FlowVelocityData oldData = data[index]; -// FlowVelocityData newData = new FlowVelocityData(); -// double[][] q = oldData.getQPoints(); -// double[][] totalV = MovingAverage.weighted(oldData.getTotalChannelPoints(), radius); -// double[][] mainV = MovingAverage.weighted(oldData.getMainChannelPoints(), radius); -// double[][] tau = MovingAverage.weighted(oldData.getTauPoints(), radius); -// for(int j = 0; j < q[0].length; j++) { -// newData.addKM(q[0][j]); -// newData.addQ(q[1][j]); -// newData.addTauMain(tau[1][j]); -// newData.addVMain(mainV[1][j]); -// newData.addVTotal(totalV[1][j]); -// } -// return newData; -// } - - return result; - } - - - /** Copy deeply. */ - @Override - public Facet deepCopy() { - FlowDepthFilterFacet copy = new FlowDepthFilterFacet(); - // FIXME: why does DataFacet does not override set? Bad access to variables of parent! - copy.set(this); - copy.type = type; - copy.hash = hash; - copy.stateId = stateId; - return copy; - } -} \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java Tue Feb 13 14:53:23 2018 +0100 @@ -1,6 +1,6 @@ /* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde - * Software engineering by - * Björnsen Beratende Ingenieure GmbH + * 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) @@ -10,96 +10,41 @@ package org.dive4elements.river.artifacts.sinfo.flowdepth; -import java.util.Map; +import java.util.HashSet; +import java.util.Set; -import org.apache.log4j.Logger; -import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; -import org.dive4elements.artifacts.CallContext; -import org.dive4elements.river.exports.DiagramGenerator; -import org.dive4elements.river.exports.StyledSeriesBuilder; -import org.dive4elements.river.exports.process.DefaultProcessor; -import org.dive4elements.river.jfree.StyledXYSeries; -import org.dive4elements.river.themes.ThemeDocument; +public final class FlowDepthProcessor extends AbstractSInfoProcessor { -public final class FlowDepthProcessor extends DefaultProcessor { - - /* Theme name, usually defined in 'FacetTypes', but that is soooo bad dependencies... */ + /* Theme name, usually defined in 'FacetTypes', but that is soooo bad dependencies... */ + // REMARK: these mustend with 'filtered' so extra handling happens in chart: point are always recalculated, because data + // changes depending on zoom state static String FACET_FLOW_DEPTH_FILTERED = "sinfo_flow_depth.filtered"; - private final static Logger log = Logger.getLogger(FlowDepthProcessor.class); + static String FACET_FLOW_DEPTH_TKH_FILTERED = "sinfo_flow_depth.tkh.filtered"; + + private static final Set HANDLED_FACET_TYPES = new HashSet<>(); + + static { + HANDLED_FACET_TYPES.add(FACET_FLOW_DEPTH_FILTERED); + HANDLED_FACET_TYPES.add(FACET_FLOW_DEPTH_TKH_FILTERED); + } private static final String I18N_AXIS_LABEL = "sinfo.chart.flow_depth.section.yaxis.label"; - private String yAxisLabel; - - @Override - public void doOut( - final DiagramGenerator generator, - final ArtifactAndFacet bundle, - final ThemeDocument theme, - final boolean visible) { - - final CallContext context = generator.getCallContext(); - final Map metaData = bundle.getFacet().getMetaData(); - - final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme); - series.putMetaData(metaData, bundle.getArtifact(), context); - yAxisLabel = metaData.get("Y"); - - final String facetName = bundle.getFacetName(); - final FlowDepthCalculationResult data = (FlowDepthCalculationResult) bundle.getData(context); - if (data == null) { - // Check has been here before so we keep it for security reasons - // this should never happen though. - log.error("Data is null for facet: " + facetName); - return; - } - - final double [][] points = generatePoints(data); - - StyledSeriesBuilder.addPoints(series, points, true); - generator.addAxisSeries(series, axisName, visible); + public FlowDepthProcessor() { + super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES); } - private static double[][] generatePoints(final FlowDepthCalculationResult data) { - - // FIXME - return data.getFlowDepthPoints(); + // FIXME: do filtering + @Override + protected double[][] generatePoints(final FlowDepthCalculationResult data, final String facetName) { -// if (facetName.equals(FacetTypes.FLOW_VELOCITY_TOTALCHANNEL) || -// facetName.equals(FacetTypes.FLOW_VELOCITY_TOTALCHANNEL_FILTERED)) { -// FlowVelocityData fData = (FlowVelocityData) data; -// points = fData.getTotalChannelPoints(); -// } else if (facetName.equals(FacetTypes.FLOW_VELOCITY_MAINCHANNEL) || -// facetName.equals(FacetTypes.FLOW_VELOCITY_MAINCHANNEL_FILTERED)) { -// FlowVelocityData fData = (FlowVelocityData) data; -// points = fData.getMainChannelPoints(); // I hate facets! -// } else if (facetName.equals(FacetTypes.FLOW_VELOCITY_MEASUREMENT)) { -// FastFlowVelocityMeasurementValue fData = -// (FastFlowVelocityMeasurementValue) data; -// points = new double[][] {{fData.getStation()},{fData.getV()}}; -// } else { -// log.error("Unknown facet name: " + facetName); -// return; -// } - } + if (FACET_FLOW_DEPTH_FILTERED.contentEquals(facetName)) + return data.getFlowDepthPoints(); - @Override - public boolean canHandle(String facettype) { - return FACET_FLOW_DEPTH_FILTERED.equals(facettype); - } + if (FACET_FLOW_DEPTH_TKH_FILTERED.contentEquals(facetName)) + return data.getFlowDepthTkhPoints(); - @Override - public String getAxisLabel(DiagramGenerator generator) { - if (yAxisLabel != null && !yAxisLabel.isEmpty()) { - // REMARK/UNINTENDED: yAxisLabel may also be a resolved message (side-effect of StyledXYSeries#putMetadata), - // and cannot be resolved, so we need to give the resolved value as default - // In other implementations (i.e. FlowVelocityProcessor), an explicit (German) default label is given here, probably - // the English version will also show German (CHECK) - return generator.msg(yAxisLabel, yAxisLabel); - } - return generator.msg( - I18N_AXIS_LABEL, - "MISSING"); + return super.generatePoints(data, facetName); } } \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java Tue Feb 13 14:53:23 2018 +0100 @@ -25,9 +25,8 @@ import org.dive4elements.river.artifacts.states.DefaultState; /** State in which a waterlevel has been calculated. */ -public class FlowDepthState -extends DefaultState -{ +public class FlowDepthState extends DefaultState { + /// ** The log that is used in this state. */ // private static Logger log = Logger.getLogger(FlowDepthState.class); @@ -35,6 +34,14 @@ private static final String I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION = "sinfo.facet.flow_depth.filtered.description"; + private static final String I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION = "sinfo.facet.flow_depth.tkh.filtered.description"; + + private static final String I18N_FACET_TKH_DESCRIPTION = "sinfo.facet.tkh.description"; + + private static final String SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL = "sinfo.chart.flow_depth.yaxis.label"; + + private static final String SINFO_CHART_TKX_YAXIS_LABEL = "sinfo.chart.tkh.yaxis.label"; + /** * From this state can only be continued trivially. */ @@ -44,13 +51,7 @@ } @Override - public Object computeFeed( - final D4EArtifact artifact, - final String hash, - final CallContext context, - final List facets, - final Object old - ) { + 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()); @@ -61,13 +62,7 @@ } @Override - public Object computeAdvance( - final D4EArtifact artifact, - final String hash, - final CallContext context, - final List facets, - final Object old - ) { + 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; @@ -77,15 +72,11 @@ /** * Compute result or returned object from cache, create facets. - * @param old Object that was cached. + * + * @param old + * Object that was cached. */ - private Object compute( - final SINFOArtifact sinfo, - final CallContext context, - final String hash, - final List facets, - final Object old - ) { + private Object compute(final SINFOArtifact sinfo, final CallContext context, final String hash, final List facets, final Object old) { final CalculationResult res; if (old instanceof CalculationResult) @@ -97,7 +88,7 @@ return res; } - final FlowDepthCalculationResults results = (FlowDepthCalculationResults) res.getData(); + final FlowDepthCalculationResults results = (FlowDepthCalculationResults) res.getData(); /* add themes for chart, for each result */ final List resultList = results.getResults(); @@ -106,24 +97,36 @@ final FlowDepthCalculationResult result = resultList.get(index); /* filtered (zoom dependent mean) flow depth */ - final String facetFlowDepthFilteredDescription = Resources.getMsg( context.getMeta(), I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, result.getLabel() ); - facets.add(new FlowDepthFilterFacet( - index, - FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED, - facetFlowDepthFilteredDescription, - ComputeType.ADVANCE, - this.id, - hash - )); + final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, + I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, result.getLabel()); + facets.add(new FlowDepthFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED, facetFlowDepthFilteredDescription, + SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, this.id, hash)); - // FIXME: add other themes + if (results.isUseTkh()) { + /* filtered (zoom dependent mean) flow depth including tkh */ + final String facetFlowDepthTkhFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION, + I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION, result.getLabel()); + facets.add(new FlowDepthFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_TKH_FILTERED, facetFlowDepthTkhFilteredDescription, + SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, this.id, hash)); + + // FIXME: add other themes + // - Streckenfavoriten + + // FIXME: + // - Gemittelte Linie der Fließtiefe mitsamt TKH + // - Transportkörperhöhen (oben/unten/schraffur) + final String facetTkhDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_DESCRIPTION, I18N_FACET_TKH_DESCRIPTION, + result.getLabel()); + facets.add(new FlowDepthFacet(index, TkhProcessor.FACET_TKH, facetTkhDescription, SINFO_CHART_TKX_YAXIS_LABEL, ComputeType.ADVANCE, this.id, + hash)); + } + + // FIXME: Datenkorbkonfiguration } - 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); + 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); diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/TkhProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/TkhProcessor.java Tue Feb 13 14:53:23 2018 +0100 @@ -0,0 +1,39 @@ +/* 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.util.HashSet; +import java.util.Set; + +public final class TkhProcessor extends AbstractSInfoProcessor { + + static String FACET_TKH = "sinfo_flow_depth.tkh"; + + private static final Set HANDLED_FACET_TYPES = new HashSet<>(); + + static { + HANDLED_FACET_TYPES.add(FACET_TKH); + } + + private static final String I18N_AXIS_LABEL = "sinfo.chart.tkh.section.yaxis.label"; + + public TkhProcessor() { + super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES); + } + + @Override + protected double[][] generatePoints(final FlowDepthCalculationResult data, final String facetName) { + if (FACET_TKH.contentEquals(facetName)) + return data.getTkhPoints(); + + return super.generatePoints(data, facetName); + } +} \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 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 Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/WstInfo.java Tue Feb 13 14:53:23 2018 +0100 @@ -9,13 +9,19 @@ */ package org.dive4elements.river.artifacts.sinfo.flowdepth; +import java.io.Serializable; + /** * @author Gernot Belger */ -final class WstInfo { +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) { diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/resources/messages.properties --- a/artifacts/src/main/resources/messages.properties Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/resources/messages.properties Tue Feb 13 14:53:23 2018 +0100 @@ -845,5 +845,9 @@ 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.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.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] +sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/resources/messages_de.properties --- a/artifacts/src/main/resources/messages_de.properties Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/resources/messages_de.properties Tue Feb 13 14:53:23 2018 +0100 @@ -852,5 +852,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=Flow Depth h [m] -sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0}) \ No newline at end of file +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.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] +sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/resources/messages_de_DE.properties --- a/artifacts/src/main/resources/messages_de_DE.properties Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/resources/messages_de_DE.properties Tue Feb 13 14:53:23 2018 +0100 @@ -846,5 +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=Flow Depth h [m] -sinfo.facet.flow_depth.filtered.description = Flie\u00dftiefe ({0}) \ No newline at end of file +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.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] +sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] \ No newline at end of file diff -r a536e1aacf0f -r 7a8c12706834 artifacts/src/main/resources/messages_en.properties --- a/artifacts/src/main/resources/messages_en.properties Fri Feb 09 18:07:22 2018 +0100 +++ b/artifacts/src/main/resources/messages_en.properties Tue Feb 13 14:53:23 2018 +0100 @@ -846,4 +846,9 @@ 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}) \ No newline at end of file +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.tkh.section.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] +sinfo.chart.tkh.yaxis.label = Transportk\u00f6rperh\u00f6hen [cm] \ No newline at end of file