view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FacetCalculator.java @ 9614:d889ffe2fb05

Nachtrag Pos. 20: rename type/part to group/type, group added in Infrastructure class
author mschaefer
date Wed, 09 Oct 2019 19:17:06 +0200
parents f8308db94634
children
line wrap: on
line source
/** 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.flood_duration;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.common.GeneralResultType;
import org.dive4elements.river.artifacts.common.ResultRow;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
import org.dive4elements.river.jfree.StickyAxisAnnotation;
import org.dive4elements.river.jfree.StickyAxisAnnotation.SimpleAxis;
import org.dive4elements.river.model.Attribute.AttributeKey;

/**
 * @author Domenico Nardi Tironi
 *
 */
public class FacetCalculator {

    private static final double DELTA_KM = 0.0001;

    private final CallContext m_context;

    public FacetCalculator(final CallContext context) {
        this.m_context = context;
    }

    /**
     * Calculates the data for the W main value lines in the duration curve chart
     */
    public List<StickyAxisAnnotation> calcMainValueWAnnotations(final Calculation problems, final double station, final FloodDurationCalculationResult result) {

        final List<ResultRow> stationRows = searchStation(station, result.getAllRows(), AttributeKey.NONE);
        if (stationRows.isEmpty())
            return Collections.emptyList();

        final List<StickyAxisAnnotation> annotations = new ArrayList<>();
        final ResultRow row = stationRows.get(0);
        final List<DurationWaterlevel> wqds = (List<DurationWaterlevel>) row.getValue(SInfoResultType.customMultiRowColWaterlevel);
        for (final DurationWaterlevel wqd : wqds) {
            final String label = !wqd.getBezeichnung().startsWith("W=") ? "W(" + wqd.getBezeichnung() + ")" : wqd.getBezeichnung();
            final StickyAxisAnnotation annotation = new StickyAxisAnnotation(label, (float) wqd.getWaterlevel(), SimpleAxis.Y_AXIS,
                    FloodDurationCurveGenerator.YAXIS.W.idx);
            annotation.setHitPoint((float) wqd.getFloodDurDaysPerYear());
            annotations.add(annotation);
        }
        return annotations;
    }

    /**
     * Calculates the data for the Q main value lines in the duration curve chart
     *
     * @param infrastructure
     */
    public List<StickyAxisAnnotation> calcMainValueQAnnotations(final Calculation problems, final double station, final FloodDurationCalculationResult result) {

        final List<ResultRow> stationRows = searchStation(station, result.getAllRows(), AttributeKey.NONE);
        if (stationRows.isEmpty())
            return Collections.emptyList();

        final ResultRow row = stationRows.get(0);
        final List<StickyAxisAnnotation> annotations = new ArrayList<>();
        final List<DurationWaterlevel> wqds = (List<DurationWaterlevel>) row.getValue(SInfoResultType.customMultiRowColWaterlevel);
        for (final DurationWaterlevel wqd : wqds) {
            final String label = wqd.getBezeichnung().startsWith("W=") ? "Q(" + wqd.getBezeichnung() + ")" : wqd.getBezeichnung();
            final StickyAxisAnnotation annotation = new StickyAxisAnnotation(label, (float) wqd.getDischarge(), SimpleAxis.Y_AXIS,
                    FloodDurationCurveGenerator.YAXIS.Q.idx);
            annotation.setHitPoint((float) wqd.getFloodDurDaysPerYear());
            annotations.add(annotation);
        }
        return annotations;
    }

    /**
     * Find and return the W or Q annotation(s) of a station and a riverside in a previously calculated result
     *
     * @param key
     */
    public List<StickyAxisAnnotation> calcInfrastructureAnnotations(final Calculation problems, final double station, final boolean isW,
            final FloodDurationCalculationResult result, final AttributeKey riverside) {

        final List<ResultRow> stationRows = searchStation(station, result.getAllRows(), riverside);
        if (stationRows.isEmpty())
            return Collections.emptyList();

        // Same way as in MainValueWFacet and ..QFacet
        final List<StickyAxisAnnotation> annotations = new ArrayList<>();
        for (final ResultRow row : stationRows) {
            if (isW)
                annotations.add(calcInfrastructureWAnnotation(row));
            else
                annotations.add(calcInfrastructureQAnnotation(row));
        }
        return annotations;
    }

    /**
     * Calculates the Q annotation lines of an infrastructure
     */
    private StickyAxisAnnotation calcInfrastructureQAnnotation(final ResultRow row) {
        final String label = Resources.getMsg(this.m_context.getMeta(), "sinfo.chart.flood_duration.curve.infrastructure",
                "sinfo.chart.flood_duration.curve.infrastructure", getInfrastructureLabel(row));
        final StickyAxisAnnotation annotation = new StickyAxisAnnotation(label, (float) row.getDoubleValue(SInfoResultType.floodDischarge), SimpleAxis.Y_AXIS,
                FloodDurationCurveGenerator.YAXIS.Q.idx);
        annotation.setHitPoint((float) row.getDoubleValue(SInfoResultType.floodDuration));
        return annotation;
    }

    /**
     * Calculates the W annotation lines of an infrastructure
     */
    private StickyAxisAnnotation calcInfrastructureWAnnotation(final ResultRow row) {
        final String label = Resources.getMsg(this.m_context.getMeta(), "sinfo.chart.flood_duration.curve.infrastructure",
                "sinfo.chart.flood_duration.curve.infrastructure", getInfrastructureLabel(row));
        final StickyAxisAnnotation annotation = new StickyAxisAnnotation(label, (float) row.getDoubleValue(SInfoResultType.infrastructureHeight),
                SimpleAxis.Y_AXIS, FloodDurationCurveGenerator.YAXIS.W.idx);
        annotation.setHitPoint((float) row.getDoubleValue(SInfoResultType.floodDuration));
        return annotation;
    }

    /**
     * Builds the label of the type and bank location of the infrastructure of a result row
     */
    private String getInfrastructureLabel(final ResultRow row) {
        return SInfoResultType.getInfrastructureLabel(this.m_context, (String) row.getValue(SInfoResultType.infrastructuregroup),
                (String) row.getValue(SInfoResultType.infrastructuretype), (AttributeKey) row.getValue(SInfoResultType.riverside));
    }

    /**
     * Searches the one or two rows of a station in a result rows collection
     *
     * @param m_riverside
     */
    private List<ResultRow> searchStation(final double station, final Collection<ResultRow> rows, final AttributeKey riverside) {

        final double searchStation = findSearchStation(rows, station, riverside);
        if (Double.isNaN(searchStation))
            return Collections.emptyList();

        final List<ResultRow> found = new ArrayList<>();

        for (final ResultRow row : rows) { // rows are not sorted
            final String riversideStr = String.valueOf(row.getValue(SInfoResultType.riverside));
            if (riversideStr.equals("null"))
                continue;

            if (Math.abs(row.getDoubleValue(GeneralResultType.station) - station) > DELTA_KM)
                continue;

            if (riverside.equals(AttributeKey.NONE) || riverside.equals(AttributeKey.valueOf(String.valueOf(row.getValue(SInfoResultType.riverside)))))
                found.add(row);
        }
        return found;
    }

    @Deprecated
    private double findSearchStation(final Collection<ResultRow> rows, final double station, final AttributeKey riverside) {

        if (!Double.isNaN(station))
            return station;

        for (final ResultRow row : rows) {
            final String riversideStr = String.valueOf(row.getValue(SInfoResultType.riverside));
            if (riversideStr.equals("null"))
                continue;

            if (riverside.equals(AttributeKey.NONE) || riverside.equals(AttributeKey.valueOf(riversideStr)))
                return row.getDoubleValue(GeneralResultType.station);
        }

        return Double.NaN;
    }
}

http://dive4elements.wald.intevation.org