view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/RiverInfoProvider.java @ 9018:aab0c2730a25

Restriction for not-null reference gauge added
author mschaefer
date Mon, 23 Apr 2018 15:22:36 +0200
parents d9dbf0b74bc2
children 4a41b7fba4da
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.sinfo.common;

import java.util.List;

import org.apache.commons.lang.math.DoubleRange;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.LocationProvider;
import org.dive4elements.river.artifacts.model.WKms;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.artifacts.states.WaterlevelData;
import org.dive4elements.river.model.Gauge;
import org.dive4elements.river.model.River;
import org.dive4elements.river.utils.GaugeIndex;

/**
 * @author Gernot Belger
 *
 */
public final class RiverInfoProvider {

    private static final String CSV_NOT_IN_GAUGE_RANGE = "export.waterlevel.csv.not.in.gauge.range";

    private final River river;
    private final GaugeIndex gaugeIndex;
    private final Gauge refGauge;
    private final boolean showAllGauges;
    private final String notinrange;

    public static RiverInfoProvider forRange(final CallContext context, final River river, final DoubleRange calcRange) {

        final List<Gauge> gauges = river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble());
        final GaugeIndex gaugeIndex = new GaugeIndex(gauges);

        final String notinrange = Resources.getMsg(context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE);

        return new RiverInfoProvider(notinrange, river, false, gaugeIndex, null);
    }

    private RiverInfoProvider(final String notinrange, final River river, final boolean showAllGauges, final GaugeIndex gaugeIndex, final Gauge refGauge) {
        this.notinrange = notinrange;
        this.river = river;
        this.showAllGauges = showAllGauges;
        this.gaugeIndex = gaugeIndex;
        this.refGauge = refGauge;
    }

    public RiverInfoProvider forWaterlevel(final WaterlevelData waterlevel) {
        final WKms wstKms = waterlevel.getWkms();
        final Gauge waterlevelRefGauge = findReferenceGauge(wstKms);
        final boolean waterlevelShowAllGauges = waterlevel.isShowAllGauges();

        return new RiverInfoProvider(this.notinrange, this.river, waterlevelShowAllGauges, this.gaugeIndex, waterlevelRefGauge);
    }

    /**
     * Re-determines the reference gauge, in the same way as the WaterlevelArtifact would do it
     */
    private Gauge findReferenceGauge(final WKms wkms) {

        final double[] wstFromTo = findWstFromTo(wkms);
        return this.river.determineRefGauge(wstFromTo, true);
    }

    private static double[] findWstFromTo(final WKms wkms) {

        final double from = wkms.getKm(0);
        final double to = wkms.getKm(wkms.size() - 1);

        final boolean waterIncreasing = wkms.guessWaterIncreasing();
        if (waterIncreasing)
            return new double[] { to, from };

        return new double[] { from, to };
    }

    public String getLocation(final double km) {
        return LocationProvider.getLocation(this.river.getName(), km);
    }

    public String findGauge(final double km) {
        // REMARK: access the gauge once only during calculation
        final Gauge gauge = getGauge(km);

        return gauge == null ? this.notinrange : gauge.getName();
    }

    private Gauge getGauge(final double km) {

        // REMARK: using same logic as in WaterlevelExporter here

        if (this.showAllGauges)
            return this.gaugeIndex.findGauge(km);

        if ((this.refGauge != null) && this.refGauge.getRange().contains(km))
            return this.refGauge;

        return null;
    }

    public String getReferenceGauge() {
        return this.refGauge == null ? this.notinrange : this.refGauge.getName();
    }

    public River getRiver() {
        return this.river;
    }
}

http://dive4elements.wald.intevation.org