gernotbelger@8996: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@8996: * Software engineering by gernotbelger@8996: * Björnsen Beratende Ingenieure GmbH gernotbelger@8996: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@8996: * gernotbelger@8996: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@8996: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@8996: * documentation coming with Dive4Elements River for details. gernotbelger@8996: */ gernotbelger@8996: package org.dive4elements.river.artifacts.uinfo.salix; gernotbelger@8996: gernotbelger@8996: import java.util.ArrayList; gernotbelger@8996: import java.util.Collection; gernotbelger@9243: import java.util.HashMap; gernotbelger@9243: import java.util.Iterator; gernotbelger@9243: import java.util.List; gernotbelger@9243: import java.util.Map; gernotbelger@8996: gernotbelger@8996: import org.apache.commons.lang.math.DoubleRange; gernotbelger@8996: import org.dive4elements.artifacts.CallContext; gernotbelger@8996: import org.dive4elements.river.artifacts.common.GeneralResultType; gernotbelger@8996: import org.dive4elements.river.artifacts.common.ResultRow; gernotbelger@8996: import org.dive4elements.river.artifacts.model.Calculation; gernotbelger@8996: import org.dive4elements.river.artifacts.model.CalculationResult; gernotbelger@8996: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@8996: import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; gernotbelger@8996: import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; gernotbelger@8996: import org.dive4elements.river.artifacts.uinfo.UINFOArtifact; gernotbelger@8996: import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType; gernotbelger@8996: import org.dive4elements.river.model.River; gernotbelger@8996: gernotbelger@8996: /** gernotbelger@8996: * @author Domenico Nardi Tironi gernotbelger@8996: * gernotbelger@8996: */ gernotbelger@8996: final class SalixLineCalculation { gernotbelger@8996: gernotbelger@8996: private final CallContext context; gernotbelger@8996: gernotbelger@8996: public SalixLineCalculation(final CallContext context) { gernotbelger@8996: this.context = context; gernotbelger@8996: } gernotbelger@8996: gernotbelger@8996: public CalculationResult calculate(final UINFOArtifact uinfo) { gernotbelger@8996: final Calculation problems = new Calculation(); gernotbelger@8996: gernotbelger@8996: final String calcModeLabel = Resources.getMsg(this.context.getMeta(), uinfo.getCalculationMode().name()); gernotbelger@8996: final String user = CalculationUtils.findArtifactUser(this.context, uinfo); gernotbelger@8996: gernotbelger@9070: final SalixLineAccess accessSalix = new SalixLineAccess(uinfo); gernotbelger@9070: gernotbelger@9070: final River river = accessSalix.getRiver(); gernotbelger@8996: final RiverInfo riverInfo = new RiverInfo(river); gernotbelger@8996: gernotbelger@9068: final DoubleRange range = accessSalix.getRange(); gernotbelger@9068: final boolean useScenario = accessSalix.getUseScenario(); gernotbelger@9068: final String selectedScenario = accessSalix.getScenario(); gernotbelger@9222: final Double fromPart = accessSalix.getFromPart(); gernotbelger@9222: final Double toPart = accessSalix.getToPart(); gernotbelger@9243: gernotbelger@9243: final boolean useSCenario = accessSalix.getUseScenario(); gernotbelger@9243: final String scenario = accessSalix.getScenario(); gernotbelger@9068: // calculation_mode gernotbelger@9068: // ld_from , ld_to gernotbelger@9068: // use_scenario (boolean) gernotbelger@9068: // ld_from_part; ld_to_part gernotbelger@9068: // scenario_selection (mögliche Werte:"scenarioType.option1" "scenarioType.option2" "scenarioType.option3" gernotbelger@9068: gernotbelger@9070: // FIXME: real calculation gernotbelger@9070: gernotbelger@9070: final SalixLineCalculationResults results = new SalixLineCalculationResults(calcModeLabel, user, riverInfo, range); gernotbelger@8996: gernotbelger@8996: final Collection rows = new ArrayList<>(); gernotbelger@9243: SalixLineCalculationNoScenarioResult result = null; // verzweigung etwas ungünstig. möglicherweise auch die Abstraktion. ist erstmal nur ne idee gernotbelger@8996: final ResultRow row1 = ResultRow.create(). // gernotbelger@9069: putValue(GeneralResultType.station, 100).// gernotbelger@9069: putValue(UInfoResultType.salixline, 28).// gernotbelger@9243: putValue(UInfoResultType.salix_delta_mw, 2); gernotbelger@8996: gernotbelger@9243: if (!useScenario) { gernotbelger@8996: gernotbelger@9243: rows.add(row1); gernotbelger@9243: result = new SalixLineCalculationNoScenarioResult("Ergebnis 1", null, rows); gernotbelger@9243: } else { gernotbelger@8996: gernotbelger@9246: if (scenario.equals("scenarioType.option1")) { // REGIONAL gernotbelger@9243: gernotbelger@9243: final int[] scenarios = accessSalix.getRegionalScenarioIntegers(); gernotbelger@9243: final List list = new ArrayList<>(); gernotbelger@9243: for (final int scen_val : scenarios) { gernotbelger@9243: list.add(new SalixScenario(scen_val, 666.));// TODO: replace 666 by real calculated value gernotbelger@9243: } gernotbelger@9243: row1.putValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl, list);// gernotbelger@9243: rows.add(row1); gernotbelger@9243: result = new SalixLineCalculationRegionalResult("Ergebnis 1 regional test", null, rows, scenarios); gernotbelger@9246: gernotbelger@9246: } else if (scenario.equals("scenarioType.option2")) { // SUPRA-REGIONAL gernotbelger@9243: gernotbelger@9243: final String supraRegional = accessSalix.getSupraRegionalString(); gernotbelger@9243: final List list = SalixZone.parse(supraRegional); gernotbelger@9243: gernotbelger@9243: final Map rangeScenarioMap = new HashMap<>(); gernotbelger@9243: // make double range gernotbelger@9243: for (int i = 0; i < list.size(); i++) { gernotbelger@9243: final SalixZone zone = list.get(i); gernotbelger@9244: final double upper = i < list.size() - 1 ? (zone.getUpperFromTo() - 0.0001) : zone.getUpperFromTo() + 0.0001;// "halboffenes Intervall gernotbelger@9243: gernotbelger@9243: final DoubleRange zonerange = new DoubleRange((double) zone.getLowerFromTo(), upper); gernotbelger@9243: final double salixValue = 666.;// TODO: calculate the salix value gernotbelger@9243: final SalixScenario salixscen = new SalixScenario(zone.getDwsplValue(), salixValue); gernotbelger@9243: gernotbelger@9243: rangeScenarioMap.put(zonerange, salixscen); gernotbelger@9243: } gernotbelger@9243: gernotbelger@9246: // make calculation gernotbelger@9243: double currentKm = range.getMinimumDouble(); gernotbelger@9246: final double step = 0.1; // TODO: get from global setting? gernotbelger@9243: while (currentKm < range.getMaximumDouble()) { gernotbelger@9243: final ResultRow rowSupraRegional = ResultRow.create(). // gernotbelger@9243: putValue(GeneralResultType.station, currentKm).// gernotbelger@9243: putValue(UInfoResultType.salixline, 28).// gernotbelger@9243: putValue(UInfoResultType.salix_delta_mw, 2); gernotbelger@9243: gernotbelger@9243: final SalixScenario scenarioCurrentKm = findScenarioByKm(currentKm, rangeScenarioMap); gernotbelger@9243: gernotbelger@9246: if (scenarioCurrentKm != null) { // should not happen, scenarioCurrentKm == null -> BUG gernotbelger@9243: rowSupraRegional.putValue(UInfoResultType.salix_line_scenario, scenarioCurrentKm.getSalixValue()); gernotbelger@9243: rowSupraRegional.putValue(UInfoResultType.salix_line_scenario_dwspl, scenarioCurrentKm.getDwspl()); gernotbelger@9243: } gernotbelger@9243: rows.add(rowSupraRegional); gernotbelger@9243: gernotbelger@9243: currentKm = currentKm + step; gernotbelger@9243: } gernotbelger@9243: gernotbelger@9243: result = new SalixLineCalculationSupraRegionalResult("Ergebnis 1 supra regional test", null, rows); gernotbelger@9243: gernotbelger@9246: } else if (scenario.equals("scenarioType.option3")) { // HISTORICAL gernotbelger@9243: row1.putValue(UInfoResultType.salixlinehist, 2).// gernotbelger@9243: putValue(UInfoResultType.salixlinescen, 82); gernotbelger@9243: } gernotbelger@9243: } gernotbelger@8996: results.addResult(result, problems); gernotbelger@8996: return new CalculationResult(results, problems); gernotbelger@8996: } gernotbelger@9243: gernotbelger@9243: private SalixScenario findScenarioByKm(final double km, final Map rangeScenarioMap) { gernotbelger@9243: final Iterator rangeIterator = rangeScenarioMap.keySet().iterator(); gernotbelger@9243: while (rangeIterator.hasNext()) { gernotbelger@9243: final DoubleRange range = rangeIterator.next(); gernotbelger@9243: if (range.containsDouble(km + 0.0001)) { gernotbelger@9243: return rangeScenarioMap.get(range); gernotbelger@9243: } gernotbelger@9243: } gernotbelger@9243: return null; gernotbelger@9243: } gernotbelger@8996: }