gernotbelger@9499: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@9499: * Software engineering by gernotbelger@9499: * Björnsen Beratende Ingenieure GmbH gernotbelger@9499: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@9499: * gernotbelger@9499: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@9499: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@9499: * documentation coming with Dive4Elements River for details. gernotbelger@9499: */ gernotbelger@9499: package org.dive4elements.river.artifacts.model.river; gernotbelger@9499: gernotbelger@9499: import java.util.HashMap; gernotbelger@9499: import java.util.Map; gernotbelger@9499: gernotbelger@9499: import org.apache.commons.lang.math.DoubleRange; gernotbelger@9499: import org.dive4elements.artifacts.CallContext; gernotbelger@9499: import org.dive4elements.river.artifacts.model.WstValueTable; gernotbelger@9499: import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; gernotbelger@9499: import org.dive4elements.river.artifacts.model.WstValueTableFactory; gernotbelger@9499: import org.dive4elements.river.model.Gauge; gernotbelger@9499: import org.dive4elements.river.model.MainValue; gernotbelger@9499: import org.dive4elements.river.model.MainValueType.MainValueTypeKey; gernotbelger@9499: import org.dive4elements.river.model.River; gernotbelger@9499: gernotbelger@9499: /** gernotbelger@9499: * @author Domenico Nardi Tironi gernotbelger@9499: */ gernotbelger@9499: public final class MainWstValuesCalculator { gernotbelger@9499: gernotbelger@9499: private final WstValueTable wst; gernotbelger@9499: gernotbelger@9499: private final Map positions; gernotbelger@9499: gernotbelger@9499: private static class MainValueQPosition { gernotbelger@9499: gernotbelger@9499: private final Map gaugePositions = new HashMap<>(); gernotbelger@9499: private QPosition refGaugePositions = null; gernotbelger@9499: } gernotbelger@9499: gernotbelger@9499: public static MainWstValuesCalculator forRiver(final CallContext context, final River river, final DoubleRange calcRange, final String... mainValueNames) { gernotbelger@9499: gernotbelger@9499: final RiverInfoProvider info = RiverInfoProvider.forRange(context, river, calcRange); gernotbelger@9499: gernotbelger@9499: return forRiverInfo(info, mainValueNames); gernotbelger@9499: } gernotbelger@9499: gernotbelger@9499: public static MainWstValuesCalculator forRiverInfo(final RiverInfoProvider info, final String... mainValueNames) { gernotbelger@9499: gernotbelger@9499: final WstValueTable wst = WstValueTableFactory.getTable(info.getRiver()); gernotbelger@9499: gernotbelger@9499: final Map positions = calculatePositions(info, wst, mainValueNames); gernotbelger@9499: gernotbelger@9499: return new MainWstValuesCalculator(wst, positions); gernotbelger@9499: } gernotbelger@9499: gernotbelger@9499: private static Map calculatePositions(final RiverInfoProvider info, final WstValueTable wst, final String[] mainValueNames) { gernotbelger@9499: gernotbelger@9499: boolean isFirstGauge = true; gernotbelger@9499: gernotbelger@9499: final Map positions = new HashMap<>(); gernotbelger@9499: gernotbelger@9499: for (final String mainValue : mainValueNames) gernotbelger@9499: positions.put(mainValue.toUpperCase(), new MainValueQPosition()); gernotbelger@9499: gernotbelger@9499: for (final Gauge gauge : info.getGauges()) { gernotbelger@9499: gernotbelger@9499: for (final MainValueQPosition position : positions.values()) gernotbelger@9499: position.gaugePositions.put(gauge, null); gernotbelger@9499: gernotbelger@9499: final double gaugeKm = gauge.getStation().doubleValue(); gernotbelger@9499: for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.Q)) { gernotbelger@9499: gernotbelger@9499: final MainValueQPosition position = positions.get(mv.getMainValue().getName().toUpperCase()); gernotbelger@9499: if (position != null) { gernotbelger@9499: final QPosition qPosition = wst.getQPosition(gaugeKm, mv.getValue().doubleValue()); gernotbelger@9499: position.gaugePositions.put(gauge, qPosition); gernotbelger@9499: gernotbelger@9499: if (isFirstGauge) gernotbelger@9499: position.refGaugePositions = qPosition; gernotbelger@9499: } gernotbelger@9499: } gernotbelger@9499: gernotbelger@9499: isFirstGauge = false; gernotbelger@9499: } gernotbelger@9499: gernotbelger@9499: return positions; gernotbelger@9499: } gernotbelger@9499: gernotbelger@9499: private MainWstValuesCalculator(final WstValueTable wst, final Map positions) { gernotbelger@9499: this.wst = wst; gernotbelger@9499: this.positions = positions; gernotbelger@9499: } gernotbelger@9499: gernotbelger@9499: public boolean hasPosition(final String mainValueName) { gernotbelger@9499: gernotbelger@9499: final MainValueQPosition position = this.positions.get(mainValueName); gernotbelger@9499: if (position == null) gernotbelger@9499: throw new IllegalArgumentException(); gernotbelger@9499: gernotbelger@9499: return position.refGaugePositions != null; gernotbelger@9499: } gernotbelger@9499: gernotbelger@9499: /** gernotbelger@9499: * Interpolates the W for a station with a fixed (virtual) wst column position gernotbelger@9499: */ gernotbelger@9499: public double interpolateW(final double station, final String mainValueName) { gernotbelger@9499: gernotbelger@9499: final MainValueQPosition mainValuePosition = this.positions.get(mainValueName.toUpperCase()); gernotbelger@9499: gernotbelger@9499: if (mainValuePosition.refGaugePositions == null) gernotbelger@9499: return Double.NaN; gernotbelger@9499: gernotbelger@9499: return this.wst.interpolateW(station, mainValuePosition.refGaugePositions); gernotbelger@9499: } gernotbelger@9499: }