view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeMainValueNameFinder.java @ 9195:a4121ec450d6

'ca.'-issue ExportContextCSV+PDF separated uinfo.inundationduration url export
author gernotbelger
date Fri, 29 Jun 2018 14:52:54 +0200
parents 1614cb14308f
children
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.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;

import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.model.Gauge;
import org.dive4elements.river.model.MainValue;
import org.dive4elements.river.model.MainValueType.MainValueTypeKey;

/**
 * Loading and search the main values of a gauge to find and build a name
 *
 * @author Matthias Schäfer
 *
 */
public final class GaugeMainValueNameFinder {

    /***** FIELDS *****/

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

    private final Gauge gauge;

    private Calculation problems;

    private final NavigableMap<Double, MainValue> mainValues;

    private final String approxPrefix = "\u2248";// "ca.";

    /***** CONSTRUCTORS *****/

    private GaugeMainValueNameFinder(final MainValueTypeKey type, final Gauge gauge, final Calculation problems) {
        this.gauge = gauge;
        this.problems = problems;
        this.mainValues = new TreeMap<>();
        for (final MainValue mainValue : MainValue.getValuesOfGaugeAndType(gauge, type))
            this.mainValues.put(Double.valueOf(mainValue.getValue().doubleValue()), mainValue);
        if (this.mainValues.isEmpty() && (this.problems != null)) {
            this.problems.addProblem("gauge_main_values.missing", gauge.getName());
            // Report only once
            this.problems = null;
        }
    }

    /***** METHODS *****/

    /**
     * Loads the the main values table of a type and a gauge (GAUGE.glt)
     *
     * @return The main values finder of a type and a gauge, or null
     */
    public static GaugeMainValueNameFinder loadValues(final MainValueTypeKey type, final Gauge gauge, final Calculation problems) {
        return new GaugeMainValueNameFinder(type, gauge, problems);
    }

    /**
     * If this provider may return valid data at all.
     */
    public boolean isValid() {
        return (this.mainValues != null);
    }

    /**
     * Main value zone for a value.
     */
    public String getZoneName(final double value) {
        if (!this.isValid())
            return "";
        if (Double.isNaN(value))
            return "";

        // Exact match
        if (this.mainValues.containsKey(Double.valueOf(value)))
            return this.mainValues.get(Double.valueOf(value)).getMainValue().getName();

        // Clearly below or just (max. 10%) below lowest named value
        final Entry<Double, MainValue> lowerZone = this.mainValues.floorEntry(Double.valueOf(value));
        if (lowerZone == null) {
            if (value >= this.mainValues.firstKey().doubleValue() * 0.9)
                return this.approxPrefix + this.mainValues.firstEntry().getValue().getMainValue().getName();
            else
                return "<" + this.mainValues.firstEntry().getValue().getMainValue().getName();
        }

        // Clearly above or just (max. 10%) above highest named value
        final Entry<Double, MainValue> higherZone = this.mainValues.ceilingEntry(Double.valueOf(value));
        if (higherZone == null) {
            if (value <= this.mainValues.lastKey().doubleValue() * 1.1)
                return this.approxPrefix + this.mainValues.lastEntry().getValue().getMainValue().getName();
            else
                return ">" + this.mainValues.lastEntry().getValue().getMainValue().getName();
        }

        // Near (10%) one of the borders of a zone interval, or clearly within a zone
        if (value <= lowerZone.getKey().doubleValue() * 1.1)
            return this.approxPrefix + lowerZone.getValue().getMainValue().getName();
        else if (value >= higherZone.getKey().doubleValue() * 0.9)
            return this.approxPrefix + higherZone.getValue().getMainValue().getName();
        else
            return lowerZone.getValue().getMainValue().getName() + "-" + higherZone.getValue().getMainValue().getName();
    }
}

http://dive4elements.wald.intevation.org