gernotbelger@8915: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@8915: * Software engineering by gernotbelger@8915: * Björnsen Beratende Ingenieure GmbH gernotbelger@8915: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@8915: * gernotbelger@8915: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@8915: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@8915: * documentation coming with Dive4Elements River for details. gernotbelger@8915: */ gernotbelger@8915: package org.dive4elements.river.artifacts.sinfo.common; gernotbelger@8915: gernotbelger@8915: import java.io.Serializable; gernotbelger@8915: import java.util.ArrayList; gernotbelger@8915: import java.util.Collection; gernotbelger@8915: import java.util.Collections; gernotbelger@8915: import java.util.List; gernotbelger@8915: gernotbelger@8915: import org.dive4elements.river.artifacts.sinfo.tkhcalculation.SoilKind; gernotbelger@8915: import org.dive4elements.river.artifacts.sinfo.util.WstInfo; gernotbelger@8915: gernotbelger@8915: import gnu.trove.TDoubleArrayList; gernotbelger@8915: gernotbelger@8915: /** gernotbelger@8915: * @author Gernot Belger gernotbelger@8915: */ gernotbelger@8915: public abstract class AbstractSInfoCalculationResult implements Serializable { gernotbelger@8915: gernotbelger@8915: private static final long serialVersionUID = 1L; gernotbelger@8915: gernotbelger@8915: private final Collection rows; gernotbelger@8915: gernotbelger@8915: private final String label; gernotbelger@8915: gernotbelger@8915: private final boolean hasTkh; gernotbelger@8915: gernotbelger@8915: private final WstInfo wst; gernotbelger@8915: gernotbelger@8915: public AbstractSInfoCalculationResult(final String label, final WstInfo wst, final boolean hasTkh, final Collection rows) { gernotbelger@8915: this.label = label; gernotbelger@8915: this.wst = wst; gernotbelger@8915: this.hasTkh = hasTkh; gernotbelger@8915: this.rows = new ArrayList<>(rows); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public final String getLabel() { gernotbelger@8915: return this.label; gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public final boolean hasTkh() { gernotbelger@8915: return this.hasTkh; gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public final WstInfo getWst() { gernotbelger@8915: return this.wst; gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public final void addRow(final ROW resultRow) { gernotbelger@8915: this.rows.add(resultRow); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public final Collection getRows() { gernotbelger@8915: return Collections.unmodifiableCollection(this.rows); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8940: public double[][] getFlowDepthPoints() { gernotbelger@8940: gernotbelger@8940: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: gernotbelger@8940: for (final ROW row : this.rows) { gernotbelger@8940: xPoints.add(row.getStation()); gernotbelger@8940: yPoints.add(row.getFlowDepth()); gernotbelger@8940: } gernotbelger@8940: gernotbelger@8940: return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; gernotbelger@8940: } gernotbelger@8940: gernotbelger@8940: public double[][] getFlowDepthTkhPoints() { gernotbelger@8940: gernotbelger@8940: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: gernotbelger@8940: for (final ROW row : this.rows) { gernotbelger@8940: xPoints.add(row.getStation()); gernotbelger@8940: yPoints.add(row.getFlowDepthWithTkh()); gernotbelger@8940: } gernotbelger@8940: gernotbelger@8940: return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; gernotbelger@8940: } gernotbelger@8940: gernotbelger@8915: public final double[][] getTkhUpPoints() { gernotbelger@8915: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8915: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8915: final List kinds = new ArrayList<>(this.rows.size()); gernotbelger@8915: gernotbelger@8915: for (final ROW row : this.rows) { gernotbelger@8915: xPoints.add(row.getStation()); gernotbelger@8915: yPoints.add(row.getTkhUp()); gernotbelger@8915: kinds.add(row.getTkhKind()); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: return adjustTkhVisualization(xPoints, yPoints, kinds); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public final double[][] getTkhDownPoints() { gernotbelger@8915: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8915: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8915: final List kinds = new ArrayList<>(this.rows.size()); gernotbelger@8915: gernotbelger@8915: for (final ROW row : this.rows) { gernotbelger@8915: xPoints.add(row.getStation()); gernotbelger@8915: yPoints.add(row.getTkhDown()); gernotbelger@8915: kinds.add(row.getTkhKind()); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: return adjustTkhVisualization(xPoints, yPoints, kinds); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8940: public double[][] getVelocityPoints() { gernotbelger@8940: gernotbelger@8940: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: gernotbelger@8940: for (final ROW row : this.rows) { gernotbelger@8940: xPoints.add(row.getStation()); gernotbelger@8940: yPoints.add(row.getVelocity()); gernotbelger@8940: } gernotbelger@8940: gernotbelger@8940: return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; gernotbelger@8940: } gernotbelger@8940: gernotbelger@8940: public double[][] getD50Points() { gernotbelger@8940: gernotbelger@8940: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: gernotbelger@8940: for (final ROW row : this.rows) { gernotbelger@8940: xPoints.add(row.getStation()); gernotbelger@8940: yPoints.add(row.getD50()); gernotbelger@8940: } gernotbelger@8940: gernotbelger@8940: return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; gernotbelger@8940: } gernotbelger@8940: gernotbelger@8940: public double[][] getTauPoints() { gernotbelger@8940: gernotbelger@8940: final TDoubleArrayList xPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: final TDoubleArrayList yPoints = new TDoubleArrayList(this.rows.size()); gernotbelger@8940: gernotbelger@8940: for (final ROW row : this.rows) { gernotbelger@8940: xPoints.add(row.getStation()); gernotbelger@8940: yPoints.add(row.getTau()); gernotbelger@8940: } gernotbelger@8940: gernotbelger@8940: return new double[][] { xPoints.toNativeArray(), yPoints.toNativeArray() }; gernotbelger@8940: } gernotbelger@8940: gernotbelger@8915: /** gernotbelger@8915: * the up and down points must be further adjusted for visualization, see Mail Hr. Reiß gernotbelger@8915: * basically we need to introduce extra points when the kind changes, so we get vertical lines in that case gernotbelger@8915: */ gernotbelger@8915: private double[][] adjustTkhVisualization(final TDoubleArrayList xPoints, final TDoubleArrayList yPoints, final List kinds) { gernotbelger@8915: gernotbelger@8915: final TDoubleArrayList adjustedX = new TDoubleArrayList(xPoints.size()); gernotbelger@8915: final TDoubleArrayList adjustedY = new TDoubleArrayList(yPoints.size()); gernotbelger@8915: gernotbelger@8915: adjustedX.add(xPoints.get(0)); gernotbelger@8915: adjustedY.add(yPoints.get(0)); gernotbelger@8915: gernotbelger@8915: for (int i = 1; i < xPoints.size(); i++) { gernotbelger@8915: gernotbelger@8915: final SoilKind kind1 = kinds.get(i - 1); gernotbelger@8915: final SoilKind kind2 = kinds.get(i); gernotbelger@8915: gernotbelger@8915: if (kind1 != kind2) { gernotbelger@8915: /* introduce two extra points in order to create a vertical line in the middle of the two adjacent points */ gernotbelger@8915: final double x1 = xPoints.get(i - 1); gernotbelger@8915: final double y1 = yPoints.get(i - 1); gernotbelger@8915: final double x2 = xPoints.get(i); gernotbelger@8915: final double y2 = yPoints.get(i); gernotbelger@8915: gernotbelger@8915: final double middleX = (x1 + x2) / 2; gernotbelger@8915: gernotbelger@8915: // REMARK: we can't produce a 100% vertical line, as the area-renderer will not work correctly gernotbelger@8915: adjustedX.add(middleX - 0.0001); gernotbelger@8915: adjustedY.add(y1); gernotbelger@8915: gernotbelger@8915: adjustedX.add(middleX + 0.0001); gernotbelger@8915: adjustedY.add(y2); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: /* always add the real point now */ gernotbelger@8915: adjustedX.add(xPoints.get(i)); gernotbelger@8915: adjustedY.add(yPoints.get(i)); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: return new double[][] { adjustedX.toNativeArray(), adjustedY.toNativeArray() }; gernotbelger@8915: } gernotbelger@8915: }