gernotbelger@8915: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@8915: * Software engineering by gernotbelger@8915: * Björnsen Beratende Ingenieure GmbH gernotbelger@8915: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@8915: * gernotbelger@8915: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@8915: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@8915: * documentation coming with Dive4Elements River for details. gernotbelger@8915: */ gernotbelger@8915: package org.dive4elements.river.artifacts.sinfo.common; gernotbelger@8915: gernotbelger@8915: import java.util.List; gernotbelger@8915: gernotbelger@8915: import org.apache.commons.lang.math.DoubleRange; gernotbelger@8915: import org.dive4elements.artifacts.CallContext; gernotbelger@8915: import org.dive4elements.river.artifacts.model.LocationProvider; gernotbelger@8915: import org.dive4elements.river.artifacts.model.WKms; gernotbelger@8915: import org.dive4elements.river.artifacts.resources.Resources; gernotbelger@8915: import org.dive4elements.river.artifacts.states.WaterlevelData; gernotbelger@8915: import org.dive4elements.river.model.Gauge; gernotbelger@8915: import org.dive4elements.river.model.River; gernotbelger@8915: import org.dive4elements.river.utils.GaugeIndex; gernotbelger@8915: gernotbelger@8915: /** gernotbelger@8915: * @author Gernot Belger gernotbelger@8915: * gernotbelger@8915: */ gernotbelger@8915: public final class RiverInfoProvider { gernotbelger@8915: gernotbelger@8915: private static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range"; gernotbelger@8915: gernotbelger@8915: private final River river; gernotbelger@8915: private final GaugeIndex gaugeIndex; gernotbelger@8915: private final Gauge refGauge; gernotbelger@8915: private final boolean showAllGauges; gernotbelger@8915: private final String notinrange; gernotbelger@8915: gernotbelger@8915: public static RiverInfoProvider forRange(final CallContext context, final River river, final DoubleRange calcRange) { gernotbelger@8915: gernotbelger@8915: final List gauges = river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble()); gernotbelger@8915: final GaugeIndex gaugeIndex = new GaugeIndex(gauges); gernotbelger@8915: gernotbelger@8915: final String notinrange = Resources.getMsg(context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE); gernotbelger@8915: gernotbelger@8915: return new RiverInfoProvider(notinrange, river, false, gaugeIndex, null); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: private RiverInfoProvider(final String notinrange, final River river, final boolean showAllGauges, final GaugeIndex gaugeIndex, final Gauge refGauge) { gernotbelger@8915: this.notinrange = notinrange; gernotbelger@8915: this.river = river; gernotbelger@8915: this.showAllGauges = showAllGauges; gernotbelger@8915: this.gaugeIndex = gaugeIndex; gernotbelger@8915: this.refGauge = refGauge; gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public RiverInfoProvider forWaterlevel(final WaterlevelData waterlevel) { gernotbelger@8915: final WKms wstKms = waterlevel.getWkms(); gernotbelger@8915: final Gauge waterlevelRefGauge = findReferenceGauge(wstKms); gernotbelger@8915: final boolean waterlevelShowAllGauges = waterlevel.isShowAllGauges(); gernotbelger@8915: gernotbelger@8915: return new RiverInfoProvider(this.notinrange, this.river, waterlevelShowAllGauges, this.gaugeIndex, waterlevelRefGauge); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: /** gernotbelger@8915: * Re-determines the reference gauge, in the same way as the WaterlevelArtifact would do it gernotbelger@8915: */ gernotbelger@8915: private Gauge findReferenceGauge(final WKms wkms) { gernotbelger@8915: gernotbelger@8915: final double[] wstFromTo = findWstFromTo(wkms); gernotbelger@8915: return this.river.determineRefGauge(wstFromTo, true); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: private static double[] findWstFromTo(final WKms wkms) { gernotbelger@8915: gernotbelger@8915: final double from = wkms.getKm(0); gernotbelger@8915: final double to = wkms.getKm(wkms.size() - 1); gernotbelger@8915: gernotbelger@8915: final boolean waterIncreasing = wkms.guessWaterIncreasing(); gernotbelger@8915: if (waterIncreasing) gernotbelger@8915: return new double[] { to, from }; gernotbelger@8915: gernotbelger@8915: return new double[] { from, to }; gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public String getLocation(final double km) { gernotbelger@8915: return LocationProvider.getLocation(this.river.getName(), km); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public String findGauge(final double km) { gernotbelger@8915: // REMARK: access the gauge once only during calculation gernotbelger@8915: final Gauge gauge = getGauge(km); gernotbelger@8915: gernotbelger@8915: return gauge == null ? this.notinrange : gauge.getName(); gernotbelger@8915: } gernotbelger@8915: mschaefer@9229: public String findGauge(final double km, final boolean allGauges) { mschaefer@9229: // REMARK: access the gauge once only during calculation mschaefer@9229: final Gauge gauge = getGauge(km, allGauges); mschaefer@9229: mschaefer@9229: return gauge == null ? this.notinrange : gauge.getName(); mschaefer@9229: } mschaefer@9229: gernotbelger@8915: private Gauge getGauge(final double km) { gernotbelger@8915: gernotbelger@8915: // REMARK: using same logic as in WaterlevelExporter here gernotbelger@8915: mschaefer@9158: return getGauge(km, this.showAllGauges); mschaefer@9158: } mschaefer@9158: mschaefer@9158: public Gauge getGauge(final double km, final boolean allGauges) { mschaefer@9158: if (allGauges) gernotbelger@8915: return this.gaugeIndex.findGauge(km); gernotbelger@8915: mschaefer@9018: if ((this.refGauge != null) && this.refGauge.getRange().contains(km)) gernotbelger@8915: return this.refGauge; gernotbelger@8915: gernotbelger@8915: return null; gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public String getReferenceGauge() { gernotbelger@8915: return this.refGauge == null ? this.notinrange : this.refGauge.getName(); gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: public River getRiver() { gernotbelger@8915: return this.river; gernotbelger@8915: } gernotbelger@8915: }