view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/SoilKindKmValueFinder.java @ 9016:6e5ff436febe

Added datacage select and chart display for TKH series loaded from database
author mschaefer
date Mon, 23 Apr 2018 15:18:48 +0200
parents b194fa64506a
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.tkhcalculation;

import java.util.List;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;

import org.apache.commons.lang.math.DoubleRange;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.backend.SessionHolder;
import org.dive4elements.river.model.River;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.type.StandardBasicTypes;

/**
 * @author Matthias Schäfer
 */
public final class SoilKindKmValueFinder {

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

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

    /**
     * Query selecting the bed mobility attribute for a range of stations of a river
     */
    private static final String SQL_BED_MOBILITY = "SELECT bmv.station, bmv.moving"
            + " FROM bed_mobility bm INNER JOIN bed_mobility_values bmv ON bm.id = bmv.bed_mobility_id"
            + " WHERE (bm.river_id=:river_id) AND (bmv.station BETWEEN (:fromkm-0.0001) AND (:tokm+0.0001))" + " ORDER BY bmv.station ASC";

    private final NavigableMap<Double, SoilKind> kmMobility = new TreeMap<>();

    private Calculation problems;

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

    private SoilKindKmValueFinder(final Calculation problems, final List<Object[]> queryRows) {
        this.problems = problems;

        for (int i = 0; i <= queryRows.size() - 1; i++) {
            this.kmMobility.put(Double.valueOf((double) queryRows.get(i)[0]), (((int) queryRows.get(i)[1]) == 1) ? SoilKind.mobil : SoilKind.starr);
        }
    }

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

    /**
     * Loads the range of the river's kms with their soil kind.
     *
     * @return Whether the load has been successful
     */
    public static SoilKindKmValueFinder loadValues(final Calculation problems, final River river, final DoubleRange kmRange) {
        final Session session = SessionHolder.HOLDER.get();
        final SQLQuery sqlQuery = session.createSQLQuery(SQL_BED_MOBILITY).addScalar("station", StandardBasicTypes.DOUBLE).addScalar("moving",
                StandardBasicTypes.INTEGER);
        sqlQuery.setInteger("river_id", river.getId().intValue());
        sqlQuery.setDouble("fromkm", kmRange.getMinimumDouble());
        sqlQuery.setDouble("tokm", kmRange.getMaximumDouble());
        final List<Object[]> rows = sqlQuery.list();
        if (rows.size() >= 1)
            return new SoilKindKmValueFinder(problems, rows);

        problems.addProblem("soilkindkmvaluefinder.empty");
        return null;
    }

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

    /**
     * Searches a km with its soil kind
     */
    public SoilKind findSoilKind(final double km) {

        if (this.kmMobility.containsKey(Double.valueOf(km)))
            return this.kmMobility.get(Double.valueOf(km));

        final Entry<Double, SoilKind> streamUp = this.kmMobility.floorEntry(Double.valueOf(km));
        if (streamUp == null) {
            reportProblem(km);
            return null;
        }

        // Return the soil kind of the neighbouring station with the shorter distance to the candidate.
        final Entry<Double, SoilKind> streamDown = this.kmMobility.ceilingEntry(Double.valueOf(km));
        if (streamDown == null)
            return streamUp.getValue();

        final double streamUpValue = streamUp.getKey().doubleValue();
        final double streamDownValue = streamDown.getKey().doubleValue();

        if ((streamUpValue + streamDownValue) / 2 <= km)
            return streamUp.getValue();

        return streamDown.getValue();
    }

    private void reportProblem(final double km) {
        if (this.problems == null)
            return;

        this.problems.addProblem(km, "soilkindkmvaluefinder.missing");

        // report problem only once
        this.problems = null;
    }
}

http://dive4elements.wald.intevation.org