view artifacts/src/main/java/org/dive4elements/river/artifacts/model/river/MainWstValuesCalculator.java @ 9499:853f2dafc16e

VegetationZones in CrossSectionsDiagram
author gernotbelger
date Thu, 27 Sep 2018 18:06:26 +0200
parents
children 8b7bf26b8782
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.model.river;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.math.DoubleRange;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.WstValueTable;
import org.dive4elements.river.artifacts.model.WstValueTable.QPosition;
import org.dive4elements.river.artifacts.model.WstValueTableFactory;
import org.dive4elements.river.model.Gauge;
import org.dive4elements.river.model.MainValue;
import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
import org.dive4elements.river.model.River;

/**
 * @author Domenico Nardi Tironi
 */
public final class MainWstValuesCalculator {

    private final WstValueTable wst;

    private final Map<String, MainValueQPosition> positions;

    private static class MainValueQPosition {

        private final Map<Gauge, QPosition> gaugePositions = new HashMap<>();
        private QPosition refGaugePositions = null;
    }

    public static MainWstValuesCalculator forRiver(final CallContext context, final River river, final DoubleRange calcRange, final String... mainValueNames) {

        final RiverInfoProvider info = RiverInfoProvider.forRange(context, river, calcRange);

        return forRiverInfo(info, mainValueNames);
    }

    public static MainWstValuesCalculator forRiverInfo(final RiverInfoProvider info, final String... mainValueNames) {

        final WstValueTable wst = WstValueTableFactory.getTable(info.getRiver());

        final Map<String, MainValueQPosition> positions = calculatePositions(info, wst, mainValueNames);

        return new MainWstValuesCalculator(wst, positions);
    }

    private static Map<String, MainValueQPosition> calculatePositions(final RiverInfoProvider info, final WstValueTable wst, final String[] mainValueNames) {

        boolean isFirstGauge = true;

        final Map<String, MainValueQPosition> positions = new HashMap<>();

        for (final String mainValue : mainValueNames)
            positions.put(mainValue.toUpperCase(), new MainValueQPosition());

        for (final Gauge gauge : info.getGauges()) {

            for (final MainValueQPosition position : positions.values())
                position.gaugePositions.put(gauge, null);

            final double gaugeKm = gauge.getStation().doubleValue();
            for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q)) {

                final MainValueQPosition position = positions.get(mv.getMainValue().getName().toUpperCase());
                if (position != null) {
                    final QPosition qPosition = wst.getQPosition(gaugeKm, mv.getValue().doubleValue());
                    position.gaugePositions.put(gauge, qPosition);

                    if (isFirstGauge)
                        position.refGaugePositions = qPosition;
                }
            }

            isFirstGauge = false;
        }

        return positions;
    }

    private MainWstValuesCalculator(final WstValueTable wst, final Map<String, MainValueQPosition> positions) {
        this.wst = wst;
        this.positions = positions;
    }

    public boolean hasPosition(final String mainValueName) {

        final MainValueQPosition position = this.positions.get(mainValueName);
        if (position == null)
            throw new IllegalArgumentException();

        return position.refGaugePositions != null;
    }

    /**
     * Interpolates the W for a station with a fixed (virtual) wst column position
     */
    public double interpolateW(final double station, final String mainValueName) {

        final MainValueQPosition mainValuePosition = this.positions.get(mainValueName.toUpperCase());

        if (mainValuePosition.refGaugePositions == null)
            return Double.NaN;

        return this.wst.interpolateW(station, mainValuePosition.refGaugePositions);
    }
}

http://dive4elements.wald.intevation.org