mschaefer@8898: /* Copyright (C) 2017 by Bundesanstalt für Gewässerkunde mschaefer@8898: * Software engineering by mschaefer@8898: * Björnsen Beratende Ingenieure GmbH mschaefer@8898: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt mschaefer@8898: * mschaefer@8898: * This file is Free Software under the GNU AGPL (>=v3) mschaefer@8898: * and comes with ABSOLUTELY NO WARRANTY! Check out the mschaefer@8898: * documentation coming with Dive4Elements River for details. mschaefer@8898: */ mschaefer@8898: gernotbelger@8915: package org.dive4elements.river.artifacts.sinfo.tkhcalculation; mschaefer@8898: mschaefer@8898: import java.util.ArrayList; mschaefer@8898: import java.util.List; mschaefer@8898: mschaefer@8898: import org.apache.commons.lang.math.DoubleRange; mschaefer@8898: import org.apache.commons.math.ArgumentOutsideDomainException; mschaefer@8898: import org.dive4elements.river.model.River; mschaefer@8898: mschaefer@8898: import gnu.trove.TDoubleArrayList; mschaefer@8898: mschaefer@8898: /** gernotbelger@8915: * @author Matthias Schäfer mschaefer@8898: */ gernotbelger@8915: final class SoilKindKmValueFinder { gernotbelger@8915: // /** gernotbelger@8915: // * Private log to use here. gernotbelger@8915: // */ gernotbelger@8915: // private static Logger log = Logger.getLogger(SoilKindKmValueFinder.class); gernotbelger@8915: gernotbelger@8915: private final TDoubleArrayList kms = new TDoubleArrayList(); gernotbelger@8915: gernotbelger@8915: private final List values = new ArrayList<>(); gernotbelger@8915: mschaefer@8898: /** gernotbelger@8915: * Loads the range of the river's kms with their soil kind. gernotbelger@8915: * gernotbelger@8915: * @return Whether the load has been successful mschaefer@8898: */ gernotbelger@8915: public static SoilKindKmValueFinder loadValues(final River river, final DoubleRange kmRange) { mschaefer@8898: gernotbelger@8915: final SoilKindKmValueFinder instance = new SoilKindKmValueFinder(); gernotbelger@8915: gernotbelger@8915: // FIXME Echte Daten aus der Datenbank abfragen gernotbelger@8915: instance.addKmKind(0, SoilKind.starr); gernotbelger@8915: instance.addKmKind(15.7, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(15.8, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(15.9, SoilKind.starr); gernotbelger@8915: instance.addKmKind(108.7, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(108.8, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(108.9, SoilKind.starr); gernotbelger@8915: instance.addKmKind(119.1, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(119.4, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(119.5, SoilKind.starr); gernotbelger@8915: instance.addKmKind(128.3, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(128.9, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(129, SoilKind.starr); gernotbelger@8915: instance.addKmKind(133.1, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(135.9, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(136, SoilKind.starr); gernotbelger@8915: instance.addKmKind(136.5, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(139.9, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(140, SoilKind.starr); gernotbelger@8915: instance.addKmKind(140.5, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(165, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(165.1, SoilKind.starr); gernotbelger@8915: instance.addKmKind(165.9, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(180.8, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(180.9, SoilKind.starr); gernotbelger@8915: instance.addKmKind(182, SoilKind.mobil); gernotbelger@8915: instance.addKmKind(221.3, SoilKind.mobil); gernotbelger@8915: gernotbelger@8915: return instance; gernotbelger@8915: } gernotbelger@8915: gernotbelger@8915: private SoilKindKmValueFinder() { gernotbelger@8915: /* only instantiate me via static constructor */ gernotbelger@8915: } gernotbelger@8915: mschaefer@8898: /***** METHODS *****/ gernotbelger@8915: mschaefer@8898: /** mschaefer@8898: * Searches a km with its soil kind mschaefer@8898: */ gernotbelger@8915: public SoilKind findSoilKind(final double km) throws ArgumentOutsideDomainException { gernotbelger@8915: if ((this.kms == null) || (this.kms.size() == 0)) mschaefer@8898: throw new ArgumentOutsideDomainException(km, Double.NaN, Double.NaN); gernotbelger@8915: gernotbelger@8915: // TODO: Voraussetzung für die binäre suche ist, dass nach km sortiert ist. gernotbelger@8915: // In diesem Fall könnte man ggf. auch gleich eine bessere Datenklasse benutzen, z.B. eine TreeMap gernotbelger@8915: // (also station -> art), und deren funktionen zum finden verwenden: gernotbelger@8915: // final double station = 0.0; gernotbelger@8915: // final NavigableMap data = new TreeMap<>(); gernotbelger@8915: // data.ceilingEntry(station); gernotbelger@8915: // data.floorEntry(station); gernotbelger@8915: gernotbelger@8915: int i = this.kms.binarySearch(km); mschaefer@8898: if (i >= 0) { mschaefer@8898: // Exact km match gernotbelger@8915: return this.values.get(i); gernotbelger@8915: } else { mschaefer@8898: // Out of range or within km interval mschaefer@8898: if (i < 0) mschaefer@8898: i = -i - 1; gernotbelger@8915: if ((i <= 0) || (i >= this.kms.size())) mschaefer@8898: throw new ArgumentOutsideDomainException(km, Double.NaN, Double.NaN); gernotbelger@8915: if (km <= ((this.kms.get(i - 1) + this.kms.get(i)) / 2)) gernotbelger@8915: return this.values.get(i - 1); mschaefer@8898: else gernotbelger@8915: return this.values.get(i); mschaefer@8898: } mschaefer@8898: } mschaefer@8898: gernotbelger@8915: private void addKmKind(final double km, final SoilKind kind) { gernotbelger@8915: this.kms.add(km); gernotbelger@8915: this.values.add(kind); mschaefer@8898: } gernotbelger@8915: }