mschaefer@9432: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@9313: * Software engineering by gernotbelger@9313: * Björnsen Beratende Ingenieure GmbH gernotbelger@9313: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@9313: * gernotbelger@9313: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@9313: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@9313: * documentation coming with Dive4Elements River for details. gernotbelger@9313: */ mschaefer@9432: gernotbelger@9313: package org.dive4elements.river.artifacts.bundu.bezugswst; gernotbelger@9313: gernotbelger@9313: import java.util.ArrayList; gernotbelger@9313: import java.util.List; gernotbelger@9313: gernotbelger@9313: import org.dive4elements.artifacts.CallContext; mschaefer@9432: import org.dive4elements.river.artifacts.access.FixRealizingAccess; gernotbelger@9313: import org.dive4elements.river.artifacts.bundu.BUNDUArtifact; gernotbelger@9318: import org.dive4elements.river.artifacts.bundu.BunduResultType; gernotbelger@9313: import org.dive4elements.river.artifacts.common.GeneralResultType; gernotbelger@9313: import org.dive4elements.river.artifacts.common.ResultRow; mschaefer@9432: import org.dive4elements.river.artifacts.model.Calculation; mschaefer@9432: import org.dive4elements.river.artifacts.model.Calculation.Problem; gernotbelger@9313: import org.dive4elements.river.artifacts.model.CalculationResult; mschaefer@9432: import org.dive4elements.river.artifacts.model.WQKms; mschaefer@9432: import org.dive4elements.river.artifacts.model.fixings.FixRealizingCalculation; mschaefer@9432: import org.dive4elements.river.artifacts.model.fixings.FixRealizingResult; gernotbelger@9313: import org.dive4elements.river.artifacts.resources.Resources; mschaefer@9432: import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; mschaefer@9432: import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; mschaefer@9432: import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; mschaefer@9432: import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; gernotbelger@9313: import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; gernotbelger@9313: import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; gernotbelger@9323: import org.dive4elements.river.artifacts.sinfo.util.WstInfo; mschaefer@9432: import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; gernotbelger@9313: import org.dive4elements.river.model.River; mschaefer@9432: import org.dive4elements.river.utils.Formatter; gernotbelger@9313: gernotbelger@9313: class BezugswstCalculation { gernotbelger@9313: mschaefer@9432: // private static Logger log = Logger.getLogger(BezugswstCalculation.class); gernotbelger@9313: gernotbelger@9313: private final CallContext context; gernotbelger@9313: gernotbelger@9313: public BezugswstCalculation(final CallContext context) { gernotbelger@9313: this.context = context; gernotbelger@9313: } gernotbelger@9313: mschaefer@9432: /** mschaefer@9432: * Calculates the result rows of a bundu bzws workflow mschaefer@9432: */ gernotbelger@9313: public CalculationResult calculate(final BUNDUArtifact bunduartifact) { gernotbelger@9313: mschaefer@9432: // Get input data gernotbelger@9313: final String user = CalculationUtils.findArtifactUser(this.context, bunduartifact); gernotbelger@9313: final BunduAccess access = new BunduAccess(bunduartifact); gernotbelger@9313: final River river = access.getRiver(); gernotbelger@9313: final RiverInfo riverInfo = new RiverInfo(river); mschaefer@9432: final String calcModeLabel = Resources.getMsg(this.context.getMeta(), "bundu_bezugswst"); mschaefer@9432: final boolean preprocessing = access.getPreprocessing(); gernotbelger@9323: final int startYear = access.getStartYear(); gernotbelger@9323: final int endYear = access.getBezugsJahr(); gernotbelger@9323: final Integer ud = access.getUd(); gernotbelger@9323: final Double missingVolFrom = access.getMissingVolFrom(); gernotbelger@9323: final Double missingVolTo = access.getMissingVolTo(); gernotbelger@9330: mschaefer@9432: final BezugswstCalculationResults results = new BezugswstCalculationResults(calcModeLabel, user, riverInfo, access.getRange()); gernotbelger@9330: mschaefer@9432: final Calculation problems = new Calculation(); gernotbelger@9331: mschaefer@9432: // Calculate the wspl for the selected river range as in fixa awspl mschaefer@9432: bunduartifact.addStringData("wq_isq", "true"); mschaefer@9432: final WinfoArtifactWrapper winfo = new WinfoArtifactWrapper(bunduartifact); mschaefer@9432: final RiverInfoProvider riverInfoProvider = RiverInfoProvider.forRange(this.context, river, access.getRange(), true); mschaefer@9432: final WQKms wqkms = calculateWspl(bunduartifact, problems); mschaefer@9432: if (wqkms == null) mschaefer@9432: return new CalculationResult(results, problems); mschaefer@9432: final WstInfo wstInfo = new WstInfo(wqkms.getName(), 0, riverInfoProvider.getReferenceGauge(), true); gernotbelger@9331: mschaefer@9432: // Fetch the bed heights of the selected sounding mschaefer@9432: final int bedHeightId = access.getBedHeightID(); mschaefer@9432: final BedHeightsFinder bedHeightsFinder = BedHeightsFinder.forId(problems, bedHeightId, access.getRange()); mschaefer@9432: if (bedHeightsFinder == null) mschaefer@9432: return new CalculationResult(results, problems); gernotbelger@9332: mschaefer@9432: // Fetch the river channel data mschaefer@9432: final ChannelFinder channelFinder = ChannelFinder.loadValues(problems, river, access.getBezugsJahr()); mschaefer@9432: if (channelFinder == null) mschaefer@9432: return new CalculationResult(results, problems); gernotbelger@9332: mschaefer@9432: // Calculate the result rows mschaefer@9432: final List rows = new ArrayList<>(); mschaefer@9432: for (int i = 0; i <= wqkms.size() - 1; i++) { mschaefer@9432: rows.add(createRow(wqkms.getKm(i), wqkms.getW(i), wqkms.getQ(i), bedHeightsFinder, channelFinder, riverInfoProvider, wstInfo)); gernotbelger@9330: } gernotbelger@9330: mschaefer@9432: // Add the result to the results collection mschaefer@9432: final WaterlevelDescriptionBuilder descBuilder = new WaterlevelDescriptionBuilder(winfo, this.context); mschaefer@9432: final String qtext = descBuilder.getMetadataQ(); mschaefer@9432: final BezugswstMainCalculationResult result = new BezugswstMainCalculationResult("bundu-bzws", rows, bedHeightsFinder.getInfo(), mschaefer@9432: wstInfo, access.getFunction(), preprocessing, startYear, endYear, ud, qtext, missingVolFrom, missingVolTo); mschaefer@9432: results.addResult(result, problems); mschaefer@9432: mschaefer@9432: // // missing volume calculation mschaefer@9432: // if (access.getMissingVolFrom() != null) { mschaefer@9432: // /// FIRST RESULT mschaefer@9432: // final List listResult1 = new ArrayList<>(); mschaefer@9432: // final ResultRow rowResult1 = ResultRow.create(); mschaefer@9432: // rowResult1.putValue(BunduResultType.bezugswst, 45.15); mschaefer@9432: // rowResult1.putValue(GeneralResultType.dischargeQwithUnit, 890); mschaefer@9432: // rowResult1.putValue(GeneralResultType.waterlevelLabel, "GLQ"); mschaefer@9432: // rowResult1.putValue(GeneralResultType.gaugeLabel, "Bonn"); mschaefer@9432: // mschaefer@9432: // rowResult1.putValue(BunduResultType.sounding, "NIEDERRHEIN_QP-2002"); mschaefer@9432: // rowResult1.putValue(BunduResultType.channelLowerEdge, 42.65); mschaefer@9432: // rowResult1.putValue(BunduResultType.channelMinDepth, 2.5); mschaefer@9432: // rowResult1.putValue(BunduResultType.hasMissingDepth, Resources.getMsg(meta, "true")); mschaefer@9432: // rowResult1.putValue(BunduResultType.missVolume, 2250); mschaefer@9432: // rowResult1.putValue(BunduResultType.missMass, 3897); mschaefer@9432: // rowResult1.putValue(BunduResultType.excavationVolume, 2475); mschaefer@9432: // rowResult1.putValue(BunduResultType.excavationCosts, 999.99); mschaefer@9432: // rowResult1.putValue(BunduResultType.channelWidth, 150); mschaefer@9432: // rowResult1.putValue(BunduResultType.density, 1732); mschaefer@9432: // mschaefer@9432: // rowResult1.putValue(GeneralResultType.location, "Spitzenlage"); mschaefer@9432: // listResult1.add(rowResult1); mschaefer@9432: // mschaefer@9432: // final BezugswstMissVolCalculationResult1 r1 = new BezugswstMissVolCalculationResult1( mschaefer@9432: // Resources.getMsg(meta, "bundu.export.csv.title.bezugswst.result1"), listResult1); mschaefer@9432: // results.addResult(r1, null); mschaefer@9432: // mschaefer@9432: // // SECOND RESULT mschaefer@9432: // final List listResult2 = new ArrayList<>(); mschaefer@9432: // final ResultRow rowResult2 = ResultRow.create(); mschaefer@9432: // mschaefer@9432: // rowResult2.putValue(GeneralResultType.station, 890); mschaefer@9432: // final List fieldValues = new ArrayList<>(); mschaefer@9432: // fieldValues.add("444 [m³] / 765 [t]"); mschaefer@9432: // fieldValues.add("4.444 [m³] / 1.765 [t]"); mschaefer@9432: // fieldValues.add("444 [m³] / 765 [t]"); mschaefer@9432: // fieldValues.add(""); mschaefer@9432: // fieldValues.add(""); mschaefer@9432: // fieldValues.add(""); mschaefer@9432: // fieldValues.add(""); mschaefer@9432: // fieldValues.add(""); mschaefer@9432: // fieldValues.add(""); mschaefer@9432: // fieldValues.add("444 [m³] / 765 [t]"); mschaefer@9432: // rowResult2.putValue(BunduResultType.fields, fieldValues); mschaefer@9432: // rowResult2.putValue(BunduResultType.meanBedheight, "9.444 [m³] / 8.765 [t]"); mschaefer@9432: // mschaefer@9432: // listResult2.add(rowResult2); mschaefer@9432: // mschaefer@9432: // final BezugswstMissVolCalculationResult2 r2 = new BezugswstMissVolCalculationResult2( mschaefer@9432: // Resources.getMsg(meta, "bundu.export.csv.title.bezugswst.result2"), listResult2); mschaefer@9432: // results.addResult(r2, null); mschaefer@9432: // mschaefer@9432: // // Third RESULT mschaefer@9432: // final List listResult3 = new ArrayList<>(); mschaefer@9432: // final ResultRow rowResult3 = ResultRow.create(); mschaefer@9432: // mschaefer@9432: // rowResult3.putValue(BunduResultType.stationForMiss, "650 - 651"); mschaefer@9432: // rowResult3.putValue(BunduResultType.missVolume, 52950); mschaefer@9432: // rowResult3.putValue(BunduResultType.missMass, 91491); mschaefer@9432: // mschaefer@9432: // listResult3.add(rowResult3); mschaefer@9432: // mschaefer@9432: // final BezugswstMissVolCalculationResult3 r3 = new BezugswstMissVolCalculationResult3( mschaefer@9432: // Resources.getMsg(meta, "bundu.export.csv.title.bezugswst.result3"), listResult3); mschaefer@9432: // results.addResult(r3, null); mschaefer@9432: // mschaefer@9432: // } mschaefer@9432: mschaefer@9432: return new CalculationResult(results, problems); gernotbelger@9313: } gernotbelger@9313: gernotbelger@9313: /** mschaefer@9432: * Calculates a w-q-longitudinal section for a river range and Q specified in an artifact gernotbelger@9313: */ mschaefer@9432: private WQKms calculateWspl(final BUNDUArtifact bundu, final Calculation problems) { gernotbelger@9313: mschaefer@9432: final FixRealizingAccess access = new FixRealizingAccess(bundu); mschaefer@9432: final FixRealizingCalculation calc = new FixRealizingCalculation(access); mschaefer@9432: mschaefer@9432: final CalculationResult res = calc.calculate(); mschaefer@9432: mschaefer@9432: final FixRealizingResult fixRes = (FixRealizingResult) res.getData(); mschaefer@9432: final WQKms[] wqkms = (fixRes != null) ? fixRes.getWQKms() : new WQKms[0]; mschaefer@9432: mschaefer@9432: final List problems2 = res.getReport().getProblems(); mschaefer@9432: if (problems2 != null) { mschaefer@9432: for (final Problem problem : problems2) { mschaefer@9432: problems.addProblem(problem); mschaefer@9432: } mschaefer@9432: } mschaefer@9432: if (wqkms.length >= 1) mschaefer@9432: return wqkms[0]; mschaefer@9432: return null; mschaefer@9432: } mschaefer@9432: mschaefer@9432: /** mschaefer@9432: * Create a result row for a station mschaefer@9432: */ mschaefer@9432: private ResultRow createRow(final double station, final double w, final double q, final BedHeightsFinder bedHeightsFinder, mschaefer@9432: final ChannelFinder channelFinder, final RiverInfoProvider riverInfoProv, final WstInfo wstInfo) { mschaefer@9432: mschaefer@9432: final ResultRow row = ResultRow.create(); mschaefer@9432: row.putValue(GeneralResultType.station, station); mschaefer@9432: row.putValue(BunduResultType.bezugswst, w); mschaefer@9432: row.putValue(GeneralResultType.dischargeQwithUnit, q); mschaefer@9432: row.putValue(GeneralResultType.waterlevelLabel, wstInfo.getLabel()); mschaefer@9432: row.putValue(GeneralResultType.gaugeLabel, riverInfoProv.findGauge(station)); mschaefer@9432: row.putValue(GeneralResultType.location, riverInfoProv.getLocation(station)); mschaefer@9432: final double msh = bedHeightsFinder.getMeanBedHeight(station); mschaefer@9432: row.putValue(SInfoResultType.meanBedHeight, msh); mschaefer@9432: if (!Double.isNaN(w) && !Double.isNaN(msh)) mschaefer@9432: row.putValue(SInfoResultType.flowdepth, Formatter.roundFlowDepth(w).subtract(Formatter.roundFlowDepth(msh)).doubleValue()); mschaefer@9432: else mschaefer@9432: row.putValue(SInfoResultType.flowdepth, Double.NaN); mschaefer@9432: final double channelDepth = channelFinder.getDepth(station); mschaefer@9432: row.putValue(BunduResultType.channelDepth, channelDepth); mschaefer@9432: if (!Double.isNaN(w) && !Double.isNaN(channelDepth)) mschaefer@9432: row.putValue(BunduResultType.channelLowerEdge, Formatter.roundFlowDepth(w).subtract(Formatter.roundFlowDepth(channelDepth)).doubleValue()); mschaefer@9432: else mschaefer@9432: row.putValue(BunduResultType.channelLowerEdge, Double.NaN); mschaefer@9432: return row; mschaefer@9432: } gernotbelger@9313: }