gernotbelger@9145: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@9145: * Software engineering by gernotbelger@9145: * Björnsen Beratende Ingenieure GmbH gernotbelger@9145: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@9145: * gernotbelger@9145: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@9145: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@9145: * documentation coming with Dive4Elements River for details. gernotbelger@9145: */ gernotbelger@9145: package org.dive4elements.river.artifacts.sinfo.flood_duration; gernotbelger@9145: gernotbelger@9145: import java.util.ArrayList; gernotbelger@9145: import java.util.Collection; mschaefer@9176: import java.util.HashMap; mschaefer@9176: import java.util.Map; gernotbelger@9145: gernotbelger@9145: import org.apache.commons.lang.math.DoubleRange; gernotbelger@9150: import org.dive4elements.artifacts.CallContext; gernotbelger@9145: import org.dive4elements.river.artifacts.common.GeneralResultType; gernotbelger@9145: import org.dive4elements.river.artifacts.common.ResultRow; gernotbelger@9150: import org.dive4elements.river.artifacts.model.Calculation; mschaefer@9176: import org.dive4elements.river.artifacts.sinfo.common.GaugeDurationValuesFinder; gernotbelger@9145: import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; gernotbelger@9145: import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; mschaefer@9176: import org.dive4elements.river.artifacts.sinfo.common.WQBaseTableFinder; mschaefer@9176: import org.dive4elements.river.artifacts.sinfo.flood_duration.RiversideRadioChoice.RiversideChoiceKey; gernotbelger@9150: import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; mschaefer@9176: import org.dive4elements.river.model.Attribute.AttributeKey; mschaefer@9176: import org.dive4elements.river.model.Gauge; mschaefer@9176: import org.dive4elements.river.model.sinfo.InfrastructureValue; gernotbelger@9145: gernotbelger@9145: /** mschaefer@9176: * Calculation of the result rows of the flood duration of the infrastructures in a river km range mschaefer@9176: * and selected main value durations mschaefer@9176: * mschaefer@9176: * @author Matthias Schäfer gernotbelger@9145: */ gernotbelger@9145: final class FloodDurationCalculator { gernotbelger@9145: gernotbelger@9145: private final Collection rows = new ArrayList<>(); gernotbelger@9145: gernotbelger@9145: private final RiverInfoProvider riverInfoProvider; gernotbelger@9145: gernotbelger@9150: private final CallContext context; gernotbelger@9145: mschaefer@9176: gernotbelger@9150: public FloodDurationCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) { gernotbelger@9150: this.context = context; gernotbelger@9145: this.riverInfoProvider = riverInfoProvider; gernotbelger@9145: } gernotbelger@9145: mschaefer@9176: /** mschaefer@9176: * Calculate the result rows mschaefer@9176: * mschaefer@9176: * @return a result collection with one result mschaefer@9176: */ mschaefer@9176: public FloodDurationCalculationResults execute(final Calculation problems, final String label, final String calcModeLabel, mschaefer@9176: final DoubleRange calcRange, final RiversideChoiceKey riverside, final String user) { gernotbelger@9145: mschaefer@9176: final WQBaseTableFinder wqFinder = WQBaseTableFinder.loadValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(), mschaefer@9176: calcRange.getMaximumDouble(), problems); mschaefer@9176: final Map durFinders = new HashMap<>(); mschaefer@9176: for (final Gauge gauge : this.riverInfoProvider.getRiver().determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble())) { mschaefer@9176: durFinders.put(gauge, GaugeDurationValuesFinder.loadValues(gauge, problems)); mschaefer@9176: } mschaefer@9176: final AttributeKey bankKey = riverside.getAttributeKey(); mschaefer@9176: for (final InfrastructureValue infrastructure : InfrastructureValue.getValues(this.riverInfoProvider.getRiver(), calcRange.getMinimumDouble(), mschaefer@9176: calcRange.getMaximumDouble(), bankKey)) { mschaefer@9176: calculateResultRow(infrastructure, wqFinder, durFinders); mschaefer@9176: } gernotbelger@9150: mschaefer@9176: final FloodDurationCalculationResult result = new FloodDurationCalculationResult(label, this.rows); gernotbelger@9150: gernotbelger@9150: final RiverInfo riverInfo = new RiverInfo(this.riverInfoProvider.getRiver()); gernotbelger@9150: mschaefer@9176: final FloodDurationCalculationResults results = new FloodDurationCalculationResults(calcModeLabel, user, riverInfo, calcRange); gernotbelger@9150: results.addResult(result, problems); gernotbelger@9150: return results; gernotbelger@9145: } gernotbelger@9145: mschaefer@9176: /** mschaefer@9176: * Calculate the result row for one infrastructure mschaefer@9176: */ mschaefer@9176: private void calculateResultRow(final InfrastructureValue infrastructure, final WQBaseTableFinder wqFinder, mschaefer@9176: final Map durFinders) { gernotbelger@9145: gernotbelger@9145: final ResultRow row = ResultRow.create(); gernotbelger@9145: mschaefer@9176: final Gauge gauge = this.riverInfoProvider.getGauge(infrastructure.getStation(), true); mschaefer@9176: final double q = wqFinder.getDischarge(infrastructure.getStation(), infrastructure.getHeight()); mschaefer@9176: final double qOut = Double.isInfinite(q) ? Double.NaN : q; gernotbelger@9145: // REMARK: access the location once only during calculation mschaefer@9176: final String location = this.riverInfoProvider.getLocation(infrastructure.getStation()); mschaefer@9176: row.putValue(GeneralResultType.station, infrastructure.getStation()); mschaefer@9176: row.putValue(SInfoResultType.riverside, infrastructure.getAttributeKey().getName()); // TODO i18n mschaefer@9176: row.putValue(SInfoResultType.floodDuration, 365 - durFinders.get(gauge).getDuration(q)); mschaefer@9176: row.putValue(SInfoResultType.floodDischarge, qOut); mschaefer@9176: row.putValue(SInfoResultType.infrastructureHeight, infrastructure.getHeight()); mschaefer@9176: row.putValue(SInfoResultType.infrastructuretype, infrastructure.getInfrastructure().getType().getName()); gernotbelger@9145: mschaefer@9176: // TODO Berechne W, Überflutungsdauer, Q und Bezeichnung von bis zu drei WSPL mschaefer@9176: // row.putValue(SInfoResultType.customMultiRowColWaterlevel, rowWsps); gernotbelger@9145: mschaefer@9176: row.putValue(SInfoResultType.gaugeLabel, gauge.getName()); mschaefer@9176: row.putValue(SInfoResultType.location, location); gernotbelger@9145: gernotbelger@9145: this.rows.add(row); gernotbelger@9145: } gernotbelger@9145: }