Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java @ 9295:385b52ccde23
Work on U-Info salix line calculation and chart (no scenario case)
author | mschaefer |
---|---|
date | Tue, 24 Jul 2018 18:51:47 +0200 |
parents | |
children | 9a9f076d5716 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java Tue Jul 24 18:51:47 2018 +0200 @@ -0,0 +1,153 @@ +/** 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.HashMap; +import java.util.List; +import java.util.Map; + +import org.dive4elements.artifacts.CallContext; +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.WstValueTable; +import org.dive4elements.river.artifacts.model.WstValueTable.QPosition; +import org.dive4elements.river.artifacts.model.WstValueTableFactory; +import org.dive4elements.river.artifacts.sinfo.common.GaugeDischargeValuesFinder; +import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; +import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; +import org.dive4elements.river.artifacts.sinfo.tkhstate.WinfoArtifactWrapper; +import org.dive4elements.river.artifacts.uinfo.UINFOArtifact; +import org.dive4elements.river.artifacts.uinfo.commons.UInfoResultType; +import org.dive4elements.river.model.Gauge; +import org.dive4elements.river.model.MainValue; +import org.dive4elements.river.model.MainValueType.MainValueTypeKey; + +/** + * Calculation of the result rows of the u-info salix line calc mode + * + * @author Matthias Schäfer + */ +public class SalixLineCalculator { + + private final List<ResultRow> rows = new ArrayList<>(); + + private final RiverInfoProvider riverInfoProvider; + + private final CallContext context; + + private final Map<Gauge, QPosition> gaugeMwPos; + private final Map<Gauge, QPosition> gaugeMnwPos; + private final Map<Gauge, QPosition> gaugeMhwPos; + + private Calculation problems; + + private WstValueTable wst; + + public SalixLineCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) { + this.context = context; + this.riverInfoProvider = riverInfoProvider; + this.gaugeMwPos = new HashMap<>(); + this.gaugeMnwPos = new HashMap<>(); + this.gaugeMhwPos = new HashMap<>(); + } + + + /** + * Calculate the salix line result rows + */ + public void execute(final Calculation problems, final UINFOArtifact uinfo, final SalixLineCalculationResults results) { + + this.problems = problems; + this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver()); + + fetchGaugeMainValuePositions(); + + final WINFOArtifact winfo = new WinfoArtifactWrapper(uinfo); + winfo.addStringData("ld_mode", "distance"); + winfo.addStringData("ld_step", "100"); + for (final double station : new ComputationRangeAccess(winfo).getKms()) { + this.rows.add(createRow(station)); + } + results.addResult(new SalixLineCalculationNoScenarioResult("Salix", null, this.rows), problems); + } + + /** + * Fetch MW, MNW and MHW of all gauges and determine the wst QPosition for each one + */ + private void fetchGaugeMainValuePositions() { + this.gaugeMwPos.clear(); + this.gaugeMnwPos.clear(); + this.gaugeMhwPos.clear(); + for (final Gauge gauge : this.riverInfoProvider.getGauges()) { + this.gaugeMwPos.put(gauge, null); + this.gaugeMnwPos.put(gauge, null); + this.gaugeMhwPos.put(gauge, null); + final GaugeDischargeValuesFinder finder = GaugeDischargeValuesFinder.loadValues(gauge, this.problems); + if (finder == null) + continue; + final double gaugeKm = gauge.getStation().doubleValue(); + for (final MainValue mv : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.W)) { + if (mv.getMainValue().getName().equalsIgnoreCase("mw")) + this.gaugeMwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue()))); + else if (mv.getMainValue().getName().equalsIgnoreCase("mnw")) + this.gaugeMnwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue()))); + else if (mv.getMainValue().getName().equalsIgnoreCase("mhw")) + this.gaugeMhwPos.put(gauge, this.wst.getQPosition(gaugeKm, finder.getDischarge(mv.getValue().doubleValue()))); + } + } + } + + /** + * Create a result row for a station and its gauge, and add w-q-values as selected + */ + private ResultRow createRow(final double station) { + + final ResultRow row = ResultRow.create(); + final Gauge gauge = this.riverInfoProvider.getGauge(station, true); + row.putValue(GeneralResultType.station, station); + 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)); + row.putValue(SInfoResultType.waterlevel, mnw); + row.putValue(SInfoResultType.waterlevel1, mw); + row.putValue(SInfoResultType.waterlevel2, mhw); + row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw)); + row.putValue(UInfoResultType.salix_delta_mw, calcMwmnw(mw, mnw)); + return row; + } + + /** + * Interpolates the W for a station with a fixed (virtual) wst column position + */ + private double interpolateW(final double station, final QPosition qPosition) { + if (qPosition != null) + return this.wst.interpolateW(station, qPosition, this.problems); + else + return Double.NaN; + } + + /** + * Calculates the salix value + */ + private double calcSalix(final double mhw, final double mw) { + return mhw - 2.31 - mw; + } + + /** + * Calculates the inverse MW-MNW difference + */ + private double calcMwmnw(final double mw, final double mnw) { + return mnw - mw; + } +}