view artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculation.java @ 9249:600e1ac42049

Historical Result
author gernotbelger
date Thu, 12 Jul 2018 14:15:36 +0200
parents c08d5cfa4981
children 385b52ccde23
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.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.math.DoubleRange;
import org.dive4elements.artifacts.CallContext;
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.CalculationResult;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType;
import org.dive4elements.river.model.River;

/**
 * @author Domenico Nardi Tironi
 *
 */
final class SalixLineCalculation {

    private final CallContext context;

    public SalixLineCalculation(final CallContext context) {
        this.context = context;
    }

    public CalculationResult calculate(final UINFOArtifact uinfo) {
        final Calculation problems = new Calculation();

        final String calcModeLabel = Resources.getMsg(this.context.getMeta(), uinfo.getCalculationMode().name());
        final String user = CalculationUtils.findArtifactUser(this.context, uinfo);

        final SalixLineAccess accessSalix = new SalixLineAccess(uinfo);

        final River river = accessSalix.getRiver();
        final RiverInfo riverInfo = new RiverInfo(river);

        final DoubleRange range = accessSalix.getRange();
        final boolean useScenario = accessSalix.getUseScenario();
        final String selectedScenario = accessSalix.getScenario();
        final Double fromPart = accessSalix.getFromPart();
        final Double toPart = accessSalix.getToPart();

        final boolean useSCenario = accessSalix.getUseScenario();
        final String scenario = accessSalix.getScenario();
        // calculation_mode
        // ld_from , ld_to
        // use_scenario (boolean)
        // ld_from_part; ld_to_part
        // scenario_selection (mögliche Werte:"scenarioType.option1" "scenarioType.option2" "scenarioType.option3"

        // FIXME: real calculation

        final SalixLineCalculationResults results = new SalixLineCalculationResults(calcModeLabel, user, riverInfo, range);

        final Collection<ResultRow> rows = new ArrayList<>();
        SalixLineCalculationNoScenarioResult result = null; // verzweigung etwas ungünstig. möglicherweise auch die Abstraktion. ist erstmal nur ne idee
        final ResultRow row1 = ResultRow.create(). //
                putValue(GeneralResultType.station, 100).//
                putValue(UInfoResultType.salixline, 28).//
                putValue(UInfoResultType.salix_delta_mw, 2);

        if (!useScenario) {

            rows.add(row1);
            result = new SalixLineCalculationNoScenarioResult("Ergebnis 1", null, rows);
        } else {

            if (scenario.equals("scenarioType.option1")) { // REGIONAL

                final int[] scenarios = accessSalix.getRegionalScenarioIntegers();
                final List<SalixScenario> list = new ArrayList<>();
                for (final int scen_val : scenarios) {
                    list.add(new SalixScenario(scen_val, 666.));// TODO: replace 666 by real calculated value
                }
                row1.putValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl, list);//
                rows.add(row1);
                result = new SalixLineCalculationRegionalResult("Ergebnis 1 regional test", null, rows, scenarios);

            } else if (scenario.equals("scenarioType.option2")) { // SUPRA-REGIONAL

                final String supraRegional = accessSalix.getSupraRegionalString();
                final List<SalixZone> list = SalixZone.parse(supraRegional);

                final Map<DoubleRange, SalixScenario> rangeScenarioMap = new HashMap<>();
                // make double range
                for (int i = 0; i < list.size(); i++) {
                    final SalixZone zone = list.get(i);
                    final double upper = i < list.size() - 1 ? (zone.getUpperFromTo() - 0.0001) : zone.getUpperFromTo() + 0.0001;// "halboffenes Intervall

                    final DoubleRange zonerange = new DoubleRange((double) zone.getLowerFromTo(), upper);
                    final double salixValue = 666.;// TODO: calculate the salix value
                    final SalixScenario salixscen = new SalixScenario(zone.getDwsplValue(), salixValue);

                    rangeScenarioMap.put(zonerange, salixscen);
                }

                // make calculation
                double currentKm = range.getMinimumDouble();
                final double step = 0.1; // TODO: get from global setting?
                while (currentKm < range.getMaximumDouble()) {
                    final ResultRow rowSupraRegional = ResultRow.create(). //
                            putValue(GeneralResultType.station, currentKm).//
                            putValue(UInfoResultType.salixline, 28).//
                            putValue(UInfoResultType.salix_delta_mw, 2);

                    final SalixScenario scenarioCurrentKm = findScenarioByKm(currentKm, rangeScenarioMap);

                    if (scenarioCurrentKm != null) { // should not happen, scenarioCurrentKm == null -> BUG
                        rowSupraRegional.putValue(UInfoResultType.salix_line_scenario, scenarioCurrentKm.getSalixValue());
                        rowSupraRegional.putValue(UInfoResultType.salix_line_scenario_dwspl, scenarioCurrentKm.getDwspl());
                    }
                    rows.add(rowSupraRegional);

                    currentKm = currentKm + step;
                }

                result = new SalixLineCalculationSupraRegionalResult("Ergebnis 1 supra regional test", null, rows);

            } else if (scenario.equals("scenarioType.option3")) { // HISTORICAL
                row1.putValue(UInfoResultType.salixlinehist, 66).//
                        putValue(UInfoResultType.salix_line_scenario_dwspl, 88);
                rows.add(row1);
                result = new SalixLineCalculationHistoricalResult("Ergebnis 1 historical test", null, rows);
            }
        }
        results.addResult(result, problems);
        return new CalculationResult(results, problems);
    }

    private SalixScenario findScenarioByKm(final double km, final Map<DoubleRange, SalixScenario> rangeScenarioMap) {
        final Iterator<DoubleRange> rangeIterator = rangeScenarioMap.keySet().iterator();
        while (rangeIterator.hasNext()) {
            final DoubleRange range = rangeIterator.next();
            if (range.containsDouble(km + 0.0001)) {
                return rangeScenarioMap.get(range);
            }
        }
        return null;
    }
}

http://dive4elements.wald.intevation.org