Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResult.java @ 8915:d9dbf0b74bc2
Refaktoring of flow depth calculation, extracting tkh part. First implementation of tkh calculation.
author | gernotbelger |
---|---|
date | Wed, 28 Feb 2018 17:27:15 +0100 |
parents | |
children | 82998242ba84 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/AbstractSInfoCalculationResult.java Wed Feb 28 17:27:15 2018 +0100 @@ -0,0 +1,134 @@ +/** 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.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind; +import org.dive4elements.river.artifacts.sinfo.util.WstInfo; + +import gnu.trove.TDoubleArrayList; + +/** + * @author Gernot Belger + */ +public abstract class AbstractSInfoCalculationResult<ROW extends AbstractSInfoResultRow> implements Serializable { + + private static final long serialVersionUID = 1L; + + private final Collection<ROW> rows; + + private final String label; + + private final boolean hasTkh; + + private final WstInfo wst; + + public AbstractSInfoCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection<ROW> rows) { + this.label = label; + this.wst = wst; + this.hasTkh = hasTkh; + this.rows = new ArrayList<>(rows); + } + + public final String getLabel() { + return this.label; + } + + public final boolean hasTkh() { + return this.hasTkh; + } + + public final WstInfo getWst() { + return this.wst; + } + + public final void addRow(final ROW resultRow) { + this.rows.add(resultRow); + } + + public final Collection<ROW> getRows() { + return Collections.unmodifiableCollection(this.rows); + } + + public final double[][] getTkhUpPoints() { + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + final List<SoilKind> kinds = new ArrayList<>(this.rows.size()); + + for (final ROW row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getTkhUp()); + kinds.add(row.getTkhKind()); + } + + return adjustTkhVisualization(xPoints, yPoints, kinds); + } + + public final double[][] getTkhDownPoints() { + final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); + final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); + final List<SoilKind> kinds = new ArrayList<>(this.rows.size()); + + for (final ROW row : this.rows) { + xPoints.add(row.getStation()); + yPoints.add(row.getTkhDown()); + kinds.add(row.getTkhKind()); + } + + return adjustTkhVisualization(xPoints, yPoints, kinds); + } + + /** + * 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 + */ + private double[][] adjustTkhVisualization(final TDoubleArrayList xPoints, final TDoubleArrayList yPoints, final List<SoilKind> kinds) { + + final TDoubleArrayList adjustedX = new TDoubleArrayList(xPoints.size()); + final TDoubleArrayList adjustedY = new TDoubleArrayList(yPoints.size()); + + adjustedX.add(xPoints.get(0)); + adjustedY.add(yPoints.get(0)); + + for (int i = 1; i < xPoints.size(); i++) { + + final SoilKind kind1 = kinds.get(i - 1); + final SoilKind kind2 = kinds.get(i); + + if (kind1 != kind2) { + /* introduce two extra points in order to create a vertical line in the middle of the two adjacent points */ + final double x1 = xPoints.get(i - 1); + final double y1 = yPoints.get(i - 1); + final double x2 = xPoints.get(i); + final double y2 = yPoints.get(i); + + final double middleX = (x1 + x2) / 2; + + // REMARK: we can't produce a 100% vertical line, as the area-renderer will not work correctly + adjustedX.add(middleX - 0.0001); + adjustedY.add(y1); + + adjustedX.add(middleX + 0.0001); + adjustedY.add(y2); + } + + /* always add the real point now */ + adjustedX.add(xPoints.get(i)); + adjustedY.add(yPoints.get(i)); + } + + return new double[][] { adjustedX.toNativeArray(), adjustedY.toNativeArray() }; + } +} \ No newline at end of file