Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java @ 9514:ee6508687e3f
Added default vegetation zones tzo iota result map.
author | gernotbelger |
---|---|
date | Mon, 01 Oct 2018 13:03:42 +0200 |
parents | 8b7bf26b8782 |
children | 7c8d62867876 |
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.uinfo.salix; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; import java.util.NavigableMap; import org.dive4elements.river.artifacts.WINFOArtifact; import org.dive4elements.river.artifacts.access.ComputationRangeAccess; 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.model.river.MainWstValuesCalculator; import org.dive4elements.river.artifacts.model.river.RiverInfoProvider; import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; import org.dive4elements.river.artifacts.uinfo.UINFOArtifact; import org.dive4elements.river.artifacts.uinfo.common.UInfoResultType; import org.dive4elements.river.artifacts.uinfo.salix.SalixLineAccess.ScenarioType; /** * Calculation of the result rows of the u-info salix line calc mode * * @author Matthias Schäfer */ final class SalixLineCalculator { private static final String MAIN_VALUE_MNQ = "MNQ"; private static final String MAIN_VALUE_MQ = "MQ"; private static final String MAIN_VALUE_MHQ = "MHQ"; private static final String MAIN_VALUE_HQ5 = "HQ5"; private static final double SALIX_DISTANCE = 2.31; private final RiverInfoProvider riverInfoProvider; public SalixLineCalculator(final RiverInfoProvider riverInfoProvider) { this.riverInfoProvider = riverInfoProvider; } /** * Calculate the salix line result rows */ public void execute(final Calculation problems, final UINFOArtifact uinfo, final NavigableMap<Double, List<Double>> rangeScenarios, final ScenarioType scenarioType, final String[] scenarioLabels, final String rangeString, final String additionalString, final SalixLineCalculationResults results) { final MainWstValuesCalculator mainWstValues = fetchGaugeMainValuePositions2(problems); final WINFOArtifact winfo = new WinfoArtifactWrapper(uinfo); winfo.addStringData("ld_mode", "distance"); winfo.addStringData("ld_step", "100"); final List<ResultRow> rows = new ArrayList<>(); for (final double station : new ComputationRangeAccess(winfo).getKms()) rows.add(createRow(mainWstValues, station, rangeScenarios)); final SalixLineCalculationResult result = createResult(scenarioType, scenarioLabels, rangeString, additionalString, rows); results.addResult(result, problems); } private SalixLineCalculationResult createResult(final ScenarioType scenarioType, final String[] scenarioLabels, final String rangeString, final String additionalString, final List<ResultRow> rows) { switch (scenarioType) { case REGIONAL: return new SalixLineCalculationRegionalResult("Salix-regional", scenarioLabels, rangeString, additionalString, rows); case SUPRAREGIONAL: return new SalixLineCalculationSupraRegionalResult("Salix-supra", scenarioLabels, rangeString, additionalString, rows); case HISTORICAL: return new SalixLineCalculationHistoricalResult("Salix-hist", scenarioLabels, rangeString, additionalString, rows); default: return new SalixLineCalculationResult("Salix-simple", rows); } } private MainWstValuesCalculator fetchGaugeMainValuePositions2(final Calculation problems) { final MainWstValuesCalculator mainWstValues = MainWstValuesCalculator.forRiverInfo(this.riverInfoProvider, MAIN_VALUE_MQ, MAIN_VALUE_MNQ, MAIN_VALUE_MHQ, MAIN_VALUE_HQ5); if (!mainWstValues.hasPosition(MAIN_VALUE_MQ)) problems.addProblem("uinfo_salix_calc.warning.missing_mq"); else { if (!mainWstValues.hasPosition(MAIN_VALUE_MHQ)) problems.addProblem("uinfo_salix_calc.warning.missing_mhq"); if (!mainWstValues.hasPosition(MAIN_VALUE_MNQ)) problems.addProblem("uinfo_salix_calc.warning.missing_mnq"); } return mainWstValues; } /** * Create a result row for a station and its gauge, and add w-q-values as selected */ private ResultRow createRow(final MainWstValuesCalculator mainWstValues, final double station, final NavigableMap<Double, List<Double>> rangeScenarios) { final ResultRow row = ResultRow.create(); row.putValue(GeneralResultType.station, station); // Find station's gauge (obsolete version which calculates gauge-wise) // final Gauge gauge = this.riverInfoProvider.getGauge(station, true); // Interpolate mnw, mw, and mhw // final double mnw = interpolateW(station, this.gaugeMnwPos.get(gauge)); // final double mw = interpolateW(station, this.gaugeMwPos.get(gauge)); // final double mhw = interpolateW(station, this.gaugeMhwPos.get(gauge)); final double mnw = mainWstValues.interpolateW(station, MAIN_VALUE_MNQ); final double mw = mainWstValues.interpolateW(station, MAIN_VALUE_MQ); final double mhw = mainWstValues.interpolateW(station, MAIN_VALUE_MHQ); final double hw5 = mainWstValues.interpolateW(station, MAIN_VALUE_HQ5); row.putValue(UInfoResultType.waterlevelMNW, mnw); row.putValue(UInfoResultType.waterlevelMW, mw); row.putValue(UInfoResultType.waterlevelMHW, mhw); row.putValue(UInfoResultType.waterlevelMH5, hw5); // Calc salix-line and mw-mnw row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw, 0.0)); row.putValue(UInfoResultType.salix_mw_mnw, calcMwmnw(mw, mnw)); final double salixw = mhw - SALIX_DISTANCE; row.putValue(UInfoResultType.salixw, salixw); // Calc scenario values (always all scenario types set, Result variant extracts the fields needed) final List<SalixScenario> scenarios = new ArrayList<>(); final List<Double> deltaws = getDeltaWs(station, rangeScenarios); for (final Double deltaw : deltaws) { if (deltaw != null) { final double salix = calcSalix(mhw, mw, deltaw.doubleValue()); final double scen = calcSalix(mhw, 0.0, deltaw.doubleValue()); scenarios.add(new SalixScenario(deltaw * 100, salix, scen)); } else { scenarios.add(null); } } row.putValue(UInfoResultType.customMultiRowColSalixScenarios, scenarios); row.putValue(GeneralResultType.gaugeLabel, this.riverInfoProvider.findGauge(station)); return row; } /** * Calculates the salix value */ private double calcSalix(final double mhw, final double mw, final double deltamw) { if (Double.isNaN(mw) || Double.isInfinite(mw) || Double.isNaN(mhw) || Double.isInfinite(mhw)) return mhw - mw; // preserving NaN or Infinity return mhw - SALIX_DISTANCE - mw - deltamw; } /** * Calculates the inverse MW-MNW difference */ private double calcMwmnw(final double mw, final double mnw) { if (Double.isNaN(mw) || Double.isInfinite(mw) || Double.isNaN(mnw) || Double.isInfinite(mnw)) return mnw - mw; // preserving NaN or Inifinity return mnw - mw; } /** * Gets the station-specific list of delta-ws of the active scenario, at least with one null item in any case */ private List<Double> getDeltaWs(final double station, final NavigableMap<Double, List<Double>> rangeScenarios) { final Entry<Double, List<Double>> stationScenarios = rangeScenarios.floorEntry(station); if (stationScenarios != null) { return stationScenarios.getValue(); } final List<Double> noScen = new ArrayList<>(); noScen.add(null); return noScen; } }