view artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java @ 9444:ecadc9ed0ba0

Added heights and depths of cross section fields in the bundu bzws calculation and longitudinal section charts
author mschaefer
date Tue, 21 Aug 2018 13:41:18 +0200
parents d2f5375ede26
children e60584f2a531
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.bundu.bezugswst;

import java.util.ArrayList;
import java.util.List;

import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.access.FixRealizingAccess;
import org.dive4elements.river.artifacts.bundu.BUNDUArtifact;
import org.dive4elements.river.artifacts.bundu.BunduResultType;
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.Calculation.Problem;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.WQKms;
import org.dive4elements.river.artifacts.model.fixings.FixRealizingCalculation;
import org.dive4elements.river.artifacts.model.fixings.FixRealizingResult;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper;
import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
import org.dive4elements.river.exports.WaterlevelDescriptionBuilder;
import org.dive4elements.river.model.BedHeightValueType;
import org.dive4elements.river.model.River;
import org.dive4elements.river.utils.Formatter;

class BezugswstCalculation {

    // private static Logger log = Logger.getLogger(BezugswstCalculation.class);

    private final CallContext context;


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


    /**
     * Calculates the result rows of a bundu bzws workflow
     */
    public CalculationResult calculate(final BUNDUArtifact bunduartifact) {

        // Get input data
        final String user = CalculationUtils.findArtifactUser(this.context, bunduartifact);
        final BunduAccess access = new BunduAccess(bunduartifact);
        final River river = access.getRiver();
        final RiverInfo riverInfo = new RiverInfo(river);
        final String calcModeLabel = Resources.getMsg(this.context.getMeta(), "bundu_bezugswst");
        final boolean preprocessing = access.getPreprocessing();
        final int startYear = access.getStartYear();
        final int endYear = access.getBezugsJahr();
        final Integer ud = access.getUd();
        final Double missingVolFrom = access.getMissingVolFrom();
        final Double missingVolTo = access.getMissingVolTo();

        final BezugswstCalculationResults results = new BezugswstCalculationResults(calcModeLabel, user, riverInfo, access.getRange());

        final Calculation problems = new Calculation();

        // Calculate the wspl for the selected river range as in fixa awspl
        bunduartifact.addStringData("wq_isq", "true"); // macht doch Sinn hier, sorry!
        final WinfoArtifactWrapper winfo = new WinfoArtifactWrapper(bunduartifact);
        final RiverInfoProvider riverInfoProvider = RiverInfoProvider.forRange(this.context, river, access.getRange(), true);
        final FixRealizingResult fixResult = calculateWspl(bunduartifact, problems);
        if (fixResult == null)
            return new CalculationResult(results, problems);

        final WQKms wqkms = fixResult.getWQKms()[0];
        final WstInfo wstInfo = new WstInfo(wqkms.getName(), 0, riverInfoProvider.getReferenceGauge(), true);

        // Fetch the bed heights of the selected sounding
        final int bedHeightId = access.getBedHeightID();
        final BedHeightsFinder bedHeightsFinder = BedHeightsFinder.forId(problems, bedHeightId, access.getRange());
        if (bedHeightsFinder == null)
            return new CalculationResult(results, problems);

        // Fetch the river channel data
        final ChannelFinder channelFinder = ChannelFinder.loadValues(problems, river, access.getBezugsJahr());
        if (channelFinder == null)
            return new CalculationResult(results, problems);

        // Calculate the result rows
        final List<ResultRow> rows = new ArrayList<>();
        for (int i = 0; i <= wqkms.size() - 1; i++) {
            rows.add(createRow(wqkms.getKm(i), wqkms.getW(i), wqkms.getQ(i), bedHeightsFinder, channelFinder, riverInfoProvider, wstInfo));
        }

        // Add the result to the results collection
        final WaterlevelDescriptionBuilder descBuilder = new WaterlevelDescriptionBuilder(winfo, this.context);
        final String qtext = descBuilder.getMetadataQ();
        final BezugswstMainCalculationResult result = new BezugswstMainCalculationResult("bundu-bzws", rows, bedHeightsFinder.getInfo(), wstInfo,
                access.getFunction(), preprocessing, startYear, endYear, ud, qtext, wqkms, missingVolFrom, missingVolTo);
        results.addResult(result, problems);

        // // missing volume calculation
        // if (access.getMissingVolFrom() != null) {
        // /// FIRST RESULT
        // final List<ResultRow> listResult1 = new ArrayList<>();
        // final ResultRow rowResult1 = ResultRow.create();
        // rowResult1.putValue(BunduResultType.bezugswst, 45.15);
        // rowResult1.putValue(GeneralResultType.dischargeQwithUnit, 890);
        // rowResult1.putValue(GeneralResultType.waterlevelLabel, "GLQ");
        // rowResult1.putValue(GeneralResultType.gaugeLabel, "Bonn");
        //
        // rowResult1.putValue(BunduResultType.sounding, "NIEDERRHEIN_QP-2002");
        // rowResult1.putValue(BunduResultType.channelLowerEdge, 42.65);
        // rowResult1.putValue(BunduResultType.channelMinDepth, 2.5);
        // rowResult1.putValue(BunduResultType.hasMissingDepth, Resources.getMsg(meta, "true"));
        // rowResult1.putValue(BunduResultType.missVolume, 2250);
        // rowResult1.putValue(BunduResultType.missMass, 3897);
        // rowResult1.putValue(BunduResultType.excavationVolume, 2475);
        // rowResult1.putValue(BunduResultType.excavationCosts, 999.99);
        // rowResult1.putValue(BunduResultType.channelWidth, 150);
        // rowResult1.putValue(BunduResultType.density, 1732);
        //
        // rowResult1.putValue(GeneralResultType.location, "Spitzenlage");
        // listResult1.add(rowResult1);
        //
        // final BezugswstMissVolCalculationResult1 r1 = new BezugswstMissVolCalculationResult1(
        // Resources.getMsg(meta, "bundu.export.csv.title.bezugswst.result1"), listResult1);
        // results.addResult(r1, null);
        //
        // // SECOND RESULT
        // final List<ResultRow> listResult2 = new ArrayList<>();
        // final ResultRow rowResult2 = ResultRow.create();
        //
        // rowResult2.putValue(GeneralResultType.station, 890);
        // final List<String> fieldValues = new ArrayList<>();
        // fieldValues.add("444 [m³] / 765 [t]");
        // fieldValues.add("4.444 [m³] / 1.765 [t]");
        // fieldValues.add("444 [m³] / 765 [t]");
        // fieldValues.add("");
        // fieldValues.add("");
        // fieldValues.add("");
        // fieldValues.add("");
        // fieldValues.add("");
        // fieldValues.add("");
        // fieldValues.add("444 [m³] / 765 [t]");
        // rowResult2.putValue(BunduResultType.fields, fieldValues);
        // rowResult2.putValue(BunduResultType.meanBedheight, "9.444 [m³] / 8.765 [t]");
        //
        // listResult2.add(rowResult2);
        //
        // final BezugswstMissVolCalculationResult2 r2 = new BezugswstMissVolCalculationResult2(
        // Resources.getMsg(meta, "bundu.export.csv.title.bezugswst.result2"), listResult2);
        // results.addResult(r2, null);
        //
        // // Third RESULT
        // final List<ResultRow> listResult3 = new ArrayList<>();
        // final ResultRow rowResult3 = ResultRow.create();
        //
        // rowResult3.putValue(BunduResultType.stationForMiss, "650 - 651");
        // rowResult3.putValue(BunduResultType.missVolume, 52950);
        // rowResult3.putValue(BunduResultType.missMass, 91491);
        //
        // listResult3.add(rowResult3);
        //
        // final BezugswstMissVolCalculationResult3 r3 = new BezugswstMissVolCalculationResult3(
        // Resources.getMsg(meta, "bundu.export.csv.title.bezugswst.result3"), listResult3);
        // results.addResult(r3, null);
        //
        // }

        return new CalculationResult(results, problems);
    }

    /**
     * Calculates a w-q-longitudinal section for a river range and Q specified in an artifact
     */
    private FixRealizingResult calculateWspl(final BUNDUArtifact bundu, final Calculation problems) {

        final FixRealizingAccess access = new FixRealizingAccess(bundu);
        final FixRealizingCalculation calc = new FixRealizingCalculation(access);

        final CalculationResult res = calc.calculate();

        final FixRealizingResult fixRes = (FixRealizingResult) res.getData();

        final List<Problem> problems2 = res.getReport().getProblems();
        if (problems2 != null) {
            for (final Problem problem : problems2) {
                problems.addProblem(problem);
            }
        }
        return fixRes;
    }

    /**
     * Create a result row for a station
     */
    private ResultRow createRow(final double station, final double w, final double q, final BedHeightsFinder bedHeightsFinder,
            final ChannelFinder channelFinder, final RiverInfoProvider riverInfoProv, final WstInfo wstInfo) {

        final ResultRow row = ResultRow.create();
        row.putValue(GeneralResultType.station, station);
        row.putValue(BunduResultType.bezugswst, w);
        row.putValue(GeneralResultType.dischargeQwithUnit, q);
        row.putValue(GeneralResultType.waterlevelLabel, wstInfo.getLabel());
        row.putValue(GeneralResultType.gaugeLabel, riverInfoProv.findGauge(station));
        row.putValue(GeneralResultType.location, riverInfoProv.getLocation(station));
        final double msh = bedHeightsFinder.getMeanBedHeight(station);
        row.putValue(SInfoResultType.meanBedHeight, msh);
        if (!Double.isNaN(w) && !Double.isNaN(msh))
            row.putValue(SInfoResultType.flowdepth, Formatter.roundFlowDepth(w).subtract(Formatter.roundFlowDepth(msh)).doubleValue());
        else
            row.putValue(SInfoResultType.flowdepth, Double.NaN);
        final double channelDepth = channelFinder.getDepth(station);
        row.putValue(BunduResultType.channelDepth, channelDepth);
        if (!Double.isNaN(w) && !Double.isNaN(channelDepth))
            row.putValue(BunduResultType.channelLowerEdge, Formatter.roundFlowDepth(w).subtract(Formatter.roundFlowDepth(channelDepth)).doubleValue());
        else
            row.putValue(BunduResultType.channelLowerEdge, Double.NaN);
        final List<Double> fieldHeights = new ArrayList<>();
        final List<Double> fieldDepths = new ArrayList<>();
        for (int i = BedHeightValueType.FIELD_FIRST_INDEX; i <= BedHeightValueType.FIELD_LAST_INDEX; i++) {
            final double h = bedHeightsFinder.getFieldHeight(station, i);
            fieldHeights.add(Double.valueOf(h));
            fieldDepths.add(w - h);
        }
        row.putValue(BunduResultType.bedHeightFields, fieldHeights);
        row.putValue(BunduResultType.depthFields, fieldDepths);
        return row;
    }
}

http://dive4elements.wald.intevation.org