Mercurial > dive4elements > river
changeset 8940:82998242ba84
Preparing for additional outputs of SINFO-Tkh
line wrap: on
line diff
--- a/artifacts/doc/conf/artifacts/sinfo.xml Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/doc/conf/artifacts/sinfo.xml Tue Mar 06 18:51:18 2018 +0100 @@ -125,8 +125,10 @@ <!-- REMARK: id's that ends with 'filtered' are handled differently ' --> <!-- FIXME: should be filtered according to spec --> <facet name="sinfo_flow_depth.tkh" description="Facet for tkh"/> + <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/> - <facet name="longitudinal_section.annotations" description="facet.longitudinal_section.annotations"/> + <facet name="sinfo_flow_depth.filtered" description="Facet for mean flow depth, filtered by current zoom state"/> + <!-- FIXME: more themes --> </facets> </outputmode>
--- a/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/doc/conf/generators/longitudinal-diagram-defaults.xml Tue Mar 06 18:51:18 2018 +0100 @@ -45,8 +45,8 @@ <processor class="org.dive4elements.river.exports.process.BedHeightProcessor" axis="W"/> <!-- S-INFO --> - <processor class="org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthProcessor" axis="flowdepthAxis"/> + <processor class="org.dive4elements.river.artifacts.sinfo.common.FlowDepthProcessor" axis="flowdepthAxis"/> <processor class="org.dive4elements.river.artifacts.sinfo.common.TkhProcessor" axis="tkhAxis"/> - + <chartextender class="org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthChartExtender" /> </longitudinal-defaults> \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResult.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResult.java Tue Mar 06 18:51:18 2018 +0100 @@ -62,6 +62,32 @@ return Collections.unmodifiableCollection(this.rows); } + public double[][] getFlowDepthPoints() { + + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + + for (final ROW row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getFlowDepth()); + } + + 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 ROW row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getFlowDepthWithTkh()); + } + + return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; + } + public final double[][] getTkhUpPoints() { final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); @@ -90,6 +116,45 @@ return adjustTkhVisualization(xPoints, yPoints, kinds); } + public double[][] getVelocityPoints() { + + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + + for (final ROW row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getVelocity()); + } + + return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; + } + + public double[][] getD50Points() { + + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + + for (final ROW row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getD50()); + } + + return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; + } + + public double[][] getTauPoints() { + + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + + for (final ROW row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getTau()); + } + + return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; + } + /** * the up and down points must be further adjusted for visualization, see Mail Hr. Reiß * basically we need to introduce extra points when the kind changes, so we get vertical lines in that case
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoLineProcessor.java Tue Mar 06 18:51:18 2018 +0100 @@ -0,0 +1,99 @@ +/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ + +package org.dive4elements.river.artifacts.sinfo.common; + +import java.util.Map; +import java.util.Set; + +import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; +import org.dive4elements.artifacts.Artifact; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.D4EArtifact; +import org.dive4elements.river.artifacts.access.RiverAccess; +import org.dive4elements.river.artifacts.context.RiverContext; +import org.dive4elements.river.artifacts.math.MovingAverage; +import org.dive4elements.river.artifacts.model.ZoomScale; +import org.dive4elements.river.exports.DiagramGenerator; +import org.dive4elements.river.exports.StyledSeriesBuilder; +import org.dive4elements.river.jfree.StyledXYSeries; +import org.dive4elements.river.themes.ThemeDocument; + +abstract class AbstractSInfoLineProcessor extends AbstractSInfoProcessor { + + public AbstractSInfoLineProcessor(final String i18nAxisLabel, final Set<String> handledFacetType) { + super(i18nAxisLabel, handledFacetType); + } + + @Override + protected final String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) { + + final CallContext context = generator.getCallContext(); + final Map<String, String> metaData = bundle.getFacet().getMetaData(); + + final Artifact artifact = bundle.getArtifact(); + + final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme); + series.putMetaData(metaData, artifact, context); + + final String facetName = bundle.getFacetName(); + final AbstractSInfoCalculationResult<?> data = (AbstractSInfoCalculationResult<?>) bundle.getData(context); + if (data == null) { + // Check has been here before so we keep it for security reasons + // this should never happen though. + throw new IllegalStateException("Data is null for facet: " + facetName); + } + + final double[][] points = generatePoints(context, artifact, data, facetName); + + StyledSeriesBuilder.addPoints(series, points, true); + generator.addAxisSeries(series, getAxisName(), visible); + + return metaData.get("Y"); + } + + private Double findRadius(final CallContext context, final Artifact artifact) { + final Double start = (Double) context.getContextValue("startkm"); + final Double end = (Double) context.getContextValue("endkm"); + + if (start == null || end == null) + return null; + + final RiverContext fc = (RiverContext) context.globalContext(); + final ZoomScale scales = (ZoomScale) fc.get("zoomscale"); + final RiverAccess access = new RiverAccess((D4EArtifact) artifact); + final String river = access.getRiverName(); + + return scales.getRadius(river, start, end); + } + + private double[][] generatePoints(final CallContext context, final Artifact artifact, final AbstractSInfoCalculationResult<?> data, + final String facetName) { + + final double[][] points = doGetPoints(data, facetName); + if( facetName.endsWith(".filtered")) + { + final Double radius = findRadius(context, artifact); + return movingAverage(radius, points); + } + + return points; + } + + protected abstract double[][] doGetPoints(AbstractSInfoCalculationResult<?> data, String facetName); + + private double[][] movingAverage(final Double radius, final double[][] points) { + + if (radius == null) + return points; + + return MovingAverage.weighted(points, radius); + } +} \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoResultRow.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoResultRow.java Tue Mar 06 18:51:18 2018 +0100 @@ -77,6 +77,26 @@ return this.tkh.getMeanBedHeight(); } + public final double getFlowDepth() { + return this.tkh.getFlowDepth(); + } + + public double getFlowDepthWithTkh() { + return this.tkh.getFlowDepthTkh(); + } + + public double getVelocity() { + return this.tkh.getVelocity(); + } + + public double getD50() { + return this.tkh.getD50(); + } + + public double getTau() { + return this.tkh.getTau(); + } + public final String getLocation() { return this.location; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/D50Processor.java Tue Mar 06 18:51:18 2018 +0100 @@ -0,0 +1,60 @@ +/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ + +package org.dive4elements.river.artifacts.sinfo.common; + +import java.util.HashSet; +import java.util.Set; + +import org.dive4elements.artifactdatabase.state.Facet; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; + +public final class D50Processor extends AbstractSInfoLineProcessor { + + // FIXME: translate! + private static final String I18N_AXIS_LABEL = "sinfo.chart.d50.section.yaxis.label"; + + private static final String SINFO_CHART_D50_YAXIS_LABEL = "sinfo.chart.d50.yaxis.label"; + + // FIXME: check: filtered or not? + private static final String FACET_TKH_D50_FILTERED = "sinfo_tkh_d50.filtered"; + + private static final String I18N_FACET_TKH_D50_FILTERED_DESCRIPTION = "sinfo.facet.tkh_d50.filtered.description"; + + private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>(); + + static { + HANDLED_FACET_TYPES.add(FACET_TKH_D50_FILTERED); + } + + public D50Processor() { + super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES); + } + + @Override + protected double[][] doGetPoints(final AbstractSInfoCalculationResult<?> data, final String facetName) { + + if (FACET_TKH_D50_FILTERED.contentEquals(facetName)) + return data.getD50Points(); + + final String error = String.format("Unknown facet name: %s", facetName); + throw new UnsupportedOperationException(error); + } + + public static Facet createD50Facet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult<?> result, + final int index) { + final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_D50_FILTERED_DESCRIPTION, + I18N_FACET_TKH_D50_FILTERED_DESCRIPTION, result.getLabel()); + return new SInfoResultFacet(index, D50Processor.FACET_TKH_D50_FILTERED, facetFlowDepthFilteredDescription, SINFO_CHART_D50_YAXIS_LABEL, + ComputeType.ADVANCE, id, hash); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/FlowDepthProcessor.java Tue Mar 06 18:51:18 2018 +0100 @@ -0,0 +1,77 @@ +/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ + +package org.dive4elements.river.artifacts.sinfo.common; + +import java.util.HashSet; +import java.util.Set; + +import org.dive4elements.artifactdatabase.state.Facet; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; + +public final class FlowDepthProcessor extends AbstractSInfoLineProcessor { + + private static final String I18N_AXIS_LABEL = "sinfo.chart.flow_depth.section.yaxis.label"; + + private static final String SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL = "sinfo.chart.flow_depth.yaxis.label"; + + /* 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 + public static final String FACET_FLOW_DEPTH_FILTERED = "sinfo_flow_depth.filtered"; + + private static final String I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION = "sinfo.facet.flow_depth.filtered.description"; + + private static final String FACET_FLOW_DEPTH_TKH_FILTERED = "sinfo_flow_depth.tkh.filtered"; + + private static final String I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION = "sinfo.facet.flow_depth.tkh.filtered.description"; + + private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>(); + + static { + HANDLED_FACET_TYPES.add(FACET_FLOW_DEPTH_FILTERED); + HANDLED_FACET_TYPES.add(FACET_FLOW_DEPTH_TKH_FILTERED); + } + + public FlowDepthProcessor() { + super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES); + } + + @Override + protected double[][] doGetPoints(final AbstractSInfoCalculationResult<?> data, final String facetName) { + + if (FACET_FLOW_DEPTH_FILTERED.contentEquals(facetName)) + return data.getFlowDepthPoints(); + + if (FACET_FLOW_DEPTH_TKH_FILTERED.contentEquals(facetName)) + return data.getFlowDepthTkhPoints(); + + final String error = String.format("Unknown facet name: %s", facetName); + throw new UnsupportedOperationException(error); + } + + public static Facet createFlowDepthFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult<?> result, + final int index) { + final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, + I18N_FACET_FLOW_DEPTH_FILTERED_DESCRIPTION, result.getLabel()); + return new SInfoResultFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED, facetFlowDepthFilteredDescription, SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, + ComputeType.ADVANCE, id, hash); + } + + public static Facet createFlowDepthTkhFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult<?> result, + final int index) { + final String facetFlowDepthTkhFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION, + I18N_FACET_FLOW_DEPTH_TKH_FILTERED_DESCRIPTION, result.getLabel()); + return new SInfoResultFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_TKH_FILTERED, facetFlowDepthTkhFilteredDescription, + SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, id, hash); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TauProcessor.java Tue Mar 06 18:51:18 2018 +0100 @@ -0,0 +1,60 @@ +/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ + +package org.dive4elements.river.artifacts.sinfo.common; + +import java.util.HashSet; +import java.util.Set; + +import org.dive4elements.artifactdatabase.state.Facet; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; + +public final class TauProcessor extends AbstractSInfoLineProcessor { + + // FIXME: translate! + private static final String I18N_AXIS_LABEL = "sinfo.chart.tau.section.yaxis.label"; + + private static final String SINFO_CHART_TAU_YAXIS_LABEL = "sinfo.chart.tau.yaxis.label"; + + // FIXME: check: filtered or not? + private static final String FACET_TKH_TAU_FILTERED = "sinfo_tkh_tau.filtered"; + + private static final String I18N_FACET_TKH_TAU_FILTERED_DESCRIPTION = "sinfo.facet.tkh_tau.filtered.description"; + + private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>(); + + static { + HANDLED_FACET_TYPES.add(FACET_TKH_TAU_FILTERED); + } + + public TauProcessor() { + super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES); + } + + @Override + protected double[][] doGetPoints(final AbstractSInfoCalculationResult<?> data, final String facetName) { + + if (FACET_TKH_TAU_FILTERED.contentEquals(facetName)) + return data.getTauPoints(); + + final String error = String.format("Unknown facet name: %s", facetName); + throw new UnsupportedOperationException(error); + } + + public static Facet createD50Facet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult<?> result, + final int index) { + final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_TAU_FILTERED_DESCRIPTION, + I18N_FACET_TKH_TAU_FILTERED_DESCRIPTION, result.getLabel()); + return new SInfoResultFacet(index, TauProcessor.FACET_TKH_TAU_FILTERED, facetFlowDepthFilteredDescription, SINFO_CHART_TAU_YAXIS_LABEL, + ComputeType.ADVANCE, id, hash); + } +} \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/TkhProcessor.java Tue Mar 06 18:51:18 2018 +0100 @@ -26,11 +26,13 @@ public final class TkhProcessor extends AbstractSInfoProcessor { - public static String FACET_TKH = "sinfo_flow_depth.tkh"; + private static String FACET_TKH = "sinfo_flow_depth.tkh"; - public static final String I18N_FACET_TKH_DESCRIPTION = "sinfo.facet.tkh.description"; + private static final String I18N_AXIS_LABEL = "sinfo.chart.tkh.section.yaxis.label"; - public static final String SINFO_CHART_TKX_YAXIS_LABEL = "sinfo.chart.tkh.yaxis.label"; + private static final String I18N_FACET_TKH_DESCRIPTION = "sinfo.facet.tkh.description"; + + private static final String SINFO_CHART_TKX_YAXIS_LABEL = "sinfo.chart.tkh.yaxis.label"; private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>(); @@ -38,8 +40,6 @@ 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); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/VelocityProcessor.java Tue Mar 06 18:51:18 2018 +0100 @@ -0,0 +1,60 @@ +/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde + * Software engineering by + * Björnsen Beratende Ingenieure GmbH + * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt + * + * This file is Free Software under the GNU AGPL (>=v3) + * and comes with ABSOLUTELY NO WARRANTY! Check out the + * documentation coming with Dive4Elements River for details. + */ + +package org.dive4elements.river.artifacts.sinfo.common; + +import java.util.HashSet; +import java.util.Set; + +import org.dive4elements.artifactdatabase.state.Facet; +import org.dive4elements.artifacts.CallContext; +import org.dive4elements.river.artifacts.resources.Resources; +import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; + +public final class VelocityProcessor extends AbstractSInfoLineProcessor { + + // FIXME: translate! + private static final String I18N_AXIS_LABEL = "sinfo.chart.velocity.section.yaxis.label"; + + private static final String SINFO_CHART_VELOCITY_YAXIS_LABEL = "sinfo.chart.velocity.yaxis.label"; + + // FIXME: check: filtered or not? + private static final String FACET_TKH_VELOCITY_FILTERED = "sinfo_tkh_velocity.filtered"; + + private static final String I18N_FACET_TKH_VELOCITY_FILTERED_DESCRIPTION = "sinfo.facet.tkh_velocity.filtered.description"; + + private static final Set<String> HANDLED_FACET_TYPES = new HashSet<>(); + + static { + HANDLED_FACET_TYPES.add(FACET_TKH_VELOCITY_FILTERED); + } + + public VelocityProcessor() { + super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES); + } + + @Override + protected double[][] doGetPoints(final AbstractSInfoCalculationResult<?> data, final String facetName) { + + if (FACET_TKH_VELOCITY_FILTERED.contentEquals(facetName)) + return data.getVelocityPoints(); + + final String error = String.format("Unknown facet name: %s", facetName); + throw new UnsupportedOperationException(error); + } + + public static Facet createVelocityFacet(final CallContext context, final String hash, final String id, final AbstractSInfoCalculationResult<?> result, + final int index) { + final String facetFlowDepthFilteredDescription = Resources.getMsg(context.getMeta(), I18N_FACET_TKH_VELOCITY_FILTERED_DESCRIPTION, + I18N_FACET_TKH_VELOCITY_FILTERED_DESCRIPTION, result.getLabel()); + return new SInfoResultFacet(index, VelocityProcessor.FACET_TKH_VELOCITY_FILTERED, facetFlowDepthFilteredDescription, SINFO_CHART_VELOCITY_YAXIS_LABEL, + ComputeType.ADVANCE, id, hash); + } +} \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculationResult.java Tue Mar 06 18:51:18 2018 +0100 @@ -15,8 +15,6 @@ import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; import org.dive4elements.river.artifacts.sinfo.util.WstInfo; -import gnu.trove.TDoubleArrayList; - /** * Contains the results of a {@link FlowDepthCalculation}. * @@ -38,34 +36,4 @@ public BedHeightInfo getSounding() { return this.sounding; } - - public double[][] getFlowDepthPoints() { - - final Collection<FlowDepthRow> rows = getRows(); - - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - - for (final FlowDepthRow row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getFlowDepth()); - } - - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } - - public double[][] getFlowDepthTkhPoints() { - - final Collection<FlowDepthRow> rows = getRows(); - - final TDoubleArrayList xPoints = new TDoubleArrayList(rows.size()); - final TDoubleArrayList yPoints = new TDoubleArrayList(rows.size()); - - for (final FlowDepthRow row : rows) { - xPoints.add(row.getStation()); - yPoints.add(row.getFlowDepthWithTkh()); - } - - return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; - } } \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java Tue Mar 06 18:51:18 2018 +0100 @@ -18,7 +18,6 @@ import org.dive4elements.river.artifacts.model.WKms; import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder; -import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh; import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; @@ -80,18 +79,13 @@ final Tkh tkh = calculateTkh(station, wst); - final double meanBedHeight = tkh.getMeanBedHeight(); - - final double flowDepth = wst - meanBedHeight; - final double flowDepthTkh = calculateFlowDepthTkh(tkh, wst, meanBedHeight); - // REMARK: access the location once only during calculation final String location = this.riverInfoProvider.getLocation(station); // REMARK: access the gauge once only during calculation final String gaugeLabel = this.riverInfoProvider.findGauge(station); - this.rows.add(new FlowDepthRow(flowDepth, flowDepthTkh, tkh, this.wstLabel, gaugeLabel, this.bedHeightLabel, location)); + this.rows.add(new FlowDepthRow(tkh, this.wstLabel, gaugeLabel, this.bedHeightLabel, location)); } catch (final FunctionEvaluationException e) { /* should only happen if out of range */ @@ -104,26 +98,10 @@ if (this.tkhCalculator == null) { final double discharge = this.dischargeProvider.getDischarge(station); final double meanBedHeight = this.bedHeight.getMeanBedHeight(station); - return new Tkh(station, wst, meanBedHeight, discharge); + final double flowDepth = wst - meanBedHeight; + return new Tkh(station, wst, meanBedHeight, flowDepth, discharge); } return this.tkhCalculator.getTkh(station, wst); } - - private double calculateFlowDepthTkh(final Tkh tkh, final double wst, final double meanBedHeight) { - final double tkhValue = tkh.getTkh(); - final SoilKind tkhKind = tkh.getKind(); - - if (Double.isNaN(tkhValue) || tkhKind == null) - return Double.NaN; - - switch (tkhKind) { - case starr: - return wst - (meanBedHeight + tkhValue / 100); - - case mobil: - default: - return wst - (meanBedHeight + tkhValue / 200); - } - } } \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthProcessor.java Tue Mar 06 17:14:56 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde - * Software engineering by - * Björnsen Beratende Ingenieure GmbH - * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt - * - * This file is Free Software under the GNU AGPL (>=v3) - * and comes with ABSOLUTELY NO WARRANTY! Check out the - * documentation coming with Dive4Elements River for details. - */ - -package org.dive4elements.river.artifacts.sinfo.flowdepth; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; -import org.dive4elements.artifacts.Artifact; -import org.dive4elements.artifacts.CallContext; -import org.dive4elements.river.artifacts.D4EArtifact; -import org.dive4elements.river.artifacts.access.RiverAccess; -import org.dive4elements.river.artifacts.context.RiverContext; -import org.dive4elements.river.artifacts.math.MovingAverage; -import org.dive4elements.river.artifacts.model.ZoomScale; -import org.dive4elements.river.artifacts.sinfo.common.AbstractSInfoProcessor; -import org.dive4elements.river.exports.DiagramGenerator; -import org.dive4elements.river.exports.StyledSeriesBuilder; -import org.dive4elements.river.jfree.StyledXYSeries; -import org.dive4elements.river.themes.ThemeDocument; - -public final class FlowDepthProcessor extends AbstractSInfoProcessor { - - /* 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"; - - static String FACET_FLOW_DEPTH_TKH_FILTERED = "sinfo_flow_depth.tkh.filtered"; - - private static final Set<String> 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"; - - public FlowDepthProcessor() { - super(I18N_AXIS_LABEL, HANDLED_FACET_TYPES); - } - - @Override - protected final String generateSeries(final DiagramGenerator generator, final ArtifactAndFacet bundle, final ThemeDocument theme, final boolean visible) { - - final CallContext context = generator.getCallContext(); - final Map<String, String> metaData = bundle.getFacet().getMetaData(); - - final Artifact artifact = bundle.getArtifact(); - - final StyledXYSeries series = new StyledXYSeries(bundle.getFacetDescription(), theme); - series.putMetaData(metaData, artifact, context); - - 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. - throw new IllegalStateException("Data is null for facet: " + facetName); - } - - final Double radius = findRadius(context, artifact); - - final double[][] points = generatePoints(radius, data, facetName); - - StyledSeriesBuilder.addPoints(series, points, true); - generator.addAxisSeries(series, getAxisName(), visible); - - return metaData.get("Y"); - } - - private Double findRadius(final CallContext context, final Artifact artifact) { - final Double start = (Double) context.getContextValue("startkm"); - final Double end = (Double) context.getContextValue("endkm"); - - if (start == null || end == null) - return null; - - final RiverContext fc = (RiverContext) context.globalContext(); - final ZoomScale scales = (ZoomScale) fc.get("zoomscale"); - final RiverAccess access = new RiverAccess((D4EArtifact) artifact); - final String river = access.getRiverName(); - - return scales.getRadius(river, start, end); - } - - private double[][] generatePoints(final Double radius, final FlowDepthCalculationResult data, final String facetName) { - - if (FACET_FLOW_DEPTH_FILTERED.contentEquals(facetName)) - return movingAverage(radius, data.getFlowDepthPoints()); - - if (FACET_FLOW_DEPTH_TKH_FILTERED.contentEquals(facetName)) - return movingAverage(radius, data.getFlowDepthTkhPoints()); - - final String error = String.format("Unknown facet name: %s", facetName); - throw new UnsupportedOperationException(error); - } - - private double[][] movingAverage(final Double radius, final double[][] points) { - - if (radius == null) - return points; - - return MovingAverage.weighted(points, radius); - } -} \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthRow.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthRow.java Tue Mar 06 18:51:18 2018 +0100 @@ -20,30 +20,16 @@ final class FlowDepthRow extends AbstractSInfoResultRow { private static final long serialVersionUID = 1L; - private final double flowDepth; - - private final double flowDepthWithTkh; - private final String soundingLabel; - public FlowDepthRow(final double flowDepth, final double flowDepthWithTkh, final Tkh tkh, final String waterlevelLabel, + public FlowDepthRow(final Tkh tkh, final String waterlevelLabel, final String gauge, final String soundingLabel, final String location) { super(tkh, waterlevelLabel, gauge, location); - this.flowDepth = flowDepth; - this.flowDepthWithTkh = flowDepthWithTkh; this.soundingLabel = soundingLabel; } - public double getFlowDepth() { - return this.flowDepth; - } - - public double getFlowDepthWithTkh() { - return this.flowDepthWithTkh; - } - public String getSoundageLabel() { return this.soundingLabel; }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthState.java Tue Mar 06 18:51:18 2018 +0100 @@ -20,9 +20,8 @@ import org.dive4elements.river.artifacts.model.EmptyFacet; import org.dive4elements.river.artifacts.model.FacetTypes; import org.dive4elements.river.artifacts.model.ReportFacet; -import org.dive4elements.river.artifacts.resources.Resources; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; -import org.dive4elements.river.artifacts.sinfo.common.SInfoResultFacet; +import org.dive4elements.river.artifacts.sinfo.common.FlowDepthProcessor; import org.dive4elements.river.artifacts.sinfo.common.TkhProcessor; import org.dive4elements.river.artifacts.states.DefaultState; @@ -34,13 +33,6 @@ private static final long serialVersionUID = 1L; - 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 SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL = "sinfo.chart.flow_depth.yaxis.label"; - /** * From this state can only be continued trivially. */ @@ -91,17 +83,11 @@ 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 SInfoResultFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED, facetFlowDepthFilteredDescription, - SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, this.id, hash)); + facets.add(FlowDepthProcessor.createFlowDepthFacet(context, hash, this.id, result, index)); 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 SInfoResultFacet(index, FlowDepthProcessor.FACET_FLOW_DEPTH_TKH_FILTERED, facetFlowDepthTkhFilteredDescription, - SINFO_CHART_FLOW_DEPTH_YAXIS_LABEL, ComputeType.ADVANCE, this.id, hash)); + facets.add(FlowDepthProcessor.createFlowDepthTkhFacet(context, hash, this.id, result, index)); facets.add(TkhProcessor.createTkhFacet(context, hash, this.id, result, index)); }
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/Tkh.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/Tkh.java Tue Mar 06 18:51:18 2018 +0100 @@ -26,6 +26,10 @@ private final double meanBedHeight; + private final double flowDepth; + + private final double flowDepthTkh; + private final double discharge; private final SoilKind kind; @@ -36,20 +40,35 @@ private final double tkhDown; - public Tkh(final double km, final double wst, final double meanBedHeight, final double discharge) { - this(km, wst, meanBedHeight, discharge, null, Double.NaN, Double.NaN, Double.NaN); + private final double velocity; + + private final double d50; + + private final double tau; + + public Tkh(final double km, final double wst, final double meanBedHeight, final double flowDepth, final double discharge) { + this(km, wst, meanBedHeight, flowDepth, discharge, null); } - public Tkh(final double km, final double wst, final double meanBedHeight, final double discharge, final SoilKind kind, final double tkh, final double tkhUp, - final double tkhDown) { + public Tkh(final double km, final double wst, final double meanBedHeight, final double flowDepth, final double discharge, final SoilKind kind) { + this(km, wst, meanBedHeight, flowDepth, Double.NaN, discharge, kind, Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN, Double.NaN); + } + + public Tkh(final double km, final double wst, final double meanBedHeight, final double flowDepth, final double flowDepthTkh, final double discharge, + final SoilKind kind, final double tkh, final double tkhUp, final double tkhDown, final double velocity, final double d50, final double tau) { this.km = km; this.wst = wst; this.meanBedHeight = meanBedHeight; + this.flowDepth = flowDepth; + this.flowDepthTkh = flowDepthTkh; this.discharge = discharge; this.kind = kind; this.tkh = tkh; this.tkhUp = tkhUp; this.tkhDown = tkhDown; + this.velocity = velocity; + this.d50 = d50; + this.tau = tau; } public double getStation() { @@ -83,4 +102,24 @@ public double getMeanBedHeight() { return this.meanBedHeight; } + + public double getFlowDepth() { + return this.flowDepth; + } + + public double getFlowDepthTkh() { + return this.flowDepthTkh; + } + + public double getVelocity() { + return this.velocity; + } + + public double getD50() { + return this.d50; + } + + public double getTau() { + return this.tau; + } } \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java Tue Mar 06 18:51:18 2018 +0100 @@ -140,6 +140,8 @@ final double meanBedHeight = this.bedHeightsProvider.getMeanBedHeight(km); + final double flowDepth = wst - meanBedHeight; + final double discharge = getDischarge(km); if (Double.isNaN(discharge)) { @@ -150,22 +152,25 @@ // TODO: nochmal gemeinsam überlegen welche probleme wir loggen, an dieser stelle müsste man ggf. die station // mitausgeben - return new Tkh(km, wst, meanBedHeight, Double.NaN, kind, Double.NaN, Double.NaN, Double.NaN); + return new Tkh(km, wst, meanBedHeight, flowDepth, Double.NaN, kind); } final double d50 = getBedMeasurement(km); if (Double.isNaN(d50)) - return new Tkh(km, wst, meanBedHeight, discharge, kind, Double.NaN, Double.NaN, Double.NaN); + return new Tkh(km, wst, meanBedHeight, flowDepth, discharge, kind); if (!this.flowVelocitiesFinder.findKmQValues(km, discharge)) { // TODO: ggf. station in Fehlermeldung? final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingVelocity", null, this.problemLabel); this.problems.addProblem(km, message); // FIXME: cumulate problems to one message? - return new Tkh(km, wst, meanBedHeight, discharge, kind, Double.NaN, Double.NaN, Double.NaN); + return new Tkh(km, wst, meanBedHeight, flowDepth, discharge, kind); } - final double tkh = calculateTkh(wst - meanBedHeight, this.flowVelocitiesFinder.getFindVmainFound(), d50, this.flowVelocitiesFinder.getFindTauFound()); + final double velocity = this.flowVelocitiesFinder.getFindVmainFound(); + final double tau = this.flowVelocitiesFinder.getFindTauFound(); + + final double tkh = calculateTkh(wst - meanBedHeight, velocity, d50, tau); double tkhUp; double tkhDown; switch (kind) { @@ -181,7 +186,9 @@ break; } - return new Tkh(km, wst, meanBedHeight, discharge, kind, tkh, tkhUp, tkhDown); + final double flowDepthTkh = calculateFlowDepthTkh(tkhUp, kind, wst, meanBedHeight); + + return new Tkh(km, wst, meanBedHeight, flowDepth, flowDepthTkh, discharge, kind, tkh, tkhUp, tkhDown, velocity, d50, tau); } /** @@ -217,4 +224,19 @@ return tkh; } + + private double calculateFlowDepthTkh(final double tkhValue, final SoilKind tkhKind, final double wst, final double meanBedHeight) { + + if (Double.isNaN(tkhValue) || tkhKind == null) + return Double.NaN; + + switch (tkhKind) { + case starr: + return wst - (meanBedHeight + tkhValue / 100); + + case mobil: + default: + return wst - (meanBedHeight + tkhValue / 200); + } + } } \ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhState.java Tue Mar 06 17:14:56 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhState.java Tue Mar 06 18:51:18 2018 +0100 @@ -11,6 +11,8 @@ import java.util.List; import org.dive4elements.artifactdatabase.state.Facet; +import org.dive4elements.artifactdatabase.state.FacetActivity; +import org.dive4elements.artifacts.Artifact; import org.dive4elements.artifacts.CallContext; import org.dive4elements.river.artifacts.ChartArtifact; import org.dive4elements.river.artifacts.D4EArtifact; @@ -21,6 +23,7 @@ import org.dive4elements.river.artifacts.model.FacetTypes; import org.dive4elements.river.artifacts.model.ReportFacet; import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; +import org.dive4elements.river.artifacts.sinfo.common.FlowDepthProcessor; import org.dive4elements.river.artifacts.sinfo.common.TkhProcessor; import org.dive4elements.river.artifacts.states.DefaultState; @@ -32,6 +35,25 @@ private static final long serialVersionUID = 1L; + static { + // Active/deactivate facets. + // BEWARE: we can only define one activity for "sinfo", so this is not the right place.... + FacetActivity.Registry.getInstance().register("sinfo", new FacetActivity() { + @Override + public Boolean isInitialActive(final Artifact artifact, final Facet facet, final String output) { + + /* only */ + if ("sinfo_tkk".equals(output)) { + final String name = facet.getName(); + if (FlowDepthProcessor.FACET_FLOW_DEPTH_FILTERED.equals(name)) + return Boolean.FALSE; + } + + return null; + } + }); + } + /** * From this state can only be continued trivially. */ @@ -82,6 +104,9 @@ final TkhCalculationResult result = resultList.get(index); facets.add(TkhProcessor.createTkhFacet(context, hash, this.id, result, index)); + + // FIXME: should only be optionally visible + facets.add(FlowDepthProcessor.createFlowDepthTkhFacet(context, hash, this.id, result, index)); } if (!resultList.isEmpty()) {