gernotbelger@8942: /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde gernotbelger@8942: * Software engineering by gernotbelger@8942: * Björnsen Beratende Ingenieure GmbH gernotbelger@8942: * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt gernotbelger@8942: * gernotbelger@8942: * This file is Free Software under the GNU AGPL (>=v3) gernotbelger@8942: * and comes with ABSOLUTELY NO WARRANTY! Check out the gernotbelger@8942: * documentation coming with Dive4Elements River for details. gernotbelger@8942: */ gernotbelger@8942: package org.dive4elements.river.artifacts.sinfo.tkhstate; gernotbelger@8942: gernotbelger@8942: import java.util.ArrayList; gernotbelger@8942: import java.util.Collection; gernotbelger@8942: import java.util.Collections; gernotbelger@8942: import java.util.List; gernotbelger@8942: gernotbelger@8942: import org.apache.commons.lang.math.NumberRange; gernotbelger@8942: import org.dive4elements.river.artifacts.model.Calculation; gernotbelger@9211: import org.dive4elements.river.artifacts.sinfo.tkhstate.DefaultBedHeightsConfig.DefaultBedHeight; gernotbelger@8942: import org.dive4elements.river.model.BedHeight; gernotbelger@8942: import org.dive4elements.river.model.Range; gernotbelger@8942: import org.dive4elements.river.model.River; gernotbelger@8942: gernotbelger@8942: /** d@9706: * This class knows how to find the default bed levels defined for tkh and other d@9706: * calculations gernotbelger@8942: * gernotbelger@8942: * @author Gernot Belger gernotbelger@8942: */ mschaefer@9394: public final class DefaultBedHeights { gernotbelger@9211: d@9706: private final River river; gernotbelger@8942: d@9706: public DefaultBedHeights(final River river) { d@9706: this.river = river; d@9706: } gernotbelger@9211: d@9706: public List getBedHeights(final Calculation problems) { d@9706: final Collection defaults = DefaultBedHeightsConfig.getDefaults(this.river, problems); d@9706: // check ob jede default-range irgendeine andere überlappt gernotbelger@8942: d@9706: for (DefaultBedHeight check : defaults) { d@9706: double end = check.endKm > check.startKm ? check.endKm : check.startKm; d@9706: double start = check.startKm < check.endKm ? check.startKm : check.endKm; gernotbelger@8942: d@9706: for (DefaultBedHeight checkInner : defaults) { d@9706: if (!checkInner.description.equals(check.description) d@9706: && (checkInner.startKm < end && checkInner.endKm > start)) d@9706: problems.addProblem("sinfo.bedheightsfinder.overlappingrange", check.description); d@9706: } d@9706: } gernotbelger@8942: d@9706: final List defaultBedHeights = loadBedHeightsByName(this.river, defaults, problems); d@9706: if (defaultBedHeights.isEmpty()) { d@9706: problems.addProblem("sinfo.bedheightsfinder.nobedheightsforriver", this.river.getName()); d@9706: return Collections.emptyList(); d@9706: } gernotbelger@8942: d@9706: /* d@9706: * check for overlapping ranges, N2-search, but we expect only have small d@9706: * numbers of bed levels d@9706: */ d@9706: final List result = new ArrayList<>(defaultBedHeights.size()); d@9706: d@9706: for (int i = 0; i < defaultBedHeights.size(); i++) { d@9706: d@9706: final BedHeight bedHeight = defaultBedHeights.get(i); d@9706: d@9706: DefaultBedHeight configuredBH = getConfiguredBedheightByDescription(problems, defaults, d@9706: bedHeight.getDescription()); d@9706: d@9706: final double startKm = configuredBH.startKm < configuredBH.endKm ? configuredBH.startKm d@9706: : configuredBH.endKm; d@9706: final double endKm = configuredBH.endKm > configuredBH.startKm ? configuredBH.endKm : configuredBH.startKm; d@9706: // final NumberRange bedRange = new NumberRange(range.getA(), range.getB()); d@9706: d@9706: // FIXME: optional: deckt die echte Range (Datenbank) die d@9706: // konfigurierte Range ab? d@9706: d@9706: // copy bedheight and restrict to configured ranges d@9706: BedHeight rangedBedheight = BedHeight.copyPojoFrom(bedHeight, startKm, endKm); d@9706: result.add(rangedBedheight); d@9706: } d@9706: d@9706: final List validBedHeights = new ArrayList<>(defaultBedHeights.size()); d@9706: d@9706: // REMARK: check for bad ranges because db schema allow for incomplete ranges, d@9706: // and ignore if this is the case d@9706: for (final BedHeight bedHeight : defaultBedHeights) { d@9706: d@9706: final Range range = bedHeight.getRange(); d@9706: d@9706: if (range.getA() == null || range.getB() == null) d@9706: problems.addProblem("sinfo.bedheightsfinder.badrange", bedHeight.getDescription()); d@9706: else d@9706: validBedHeights.add(bedHeight); d@9706: } d@9706: d@9706: return result; d@9706: } d@9706: d@9706: private DefaultBedHeight getConfiguredBedheightByDescription(Calculation problems, d@9706: Collection defaults, String description) { d@9706: for (DefaultBedHeight bh : defaults) { d@9706: if (bh.description.equals(description)) d@9706: return bh; d@9706: } d@9706: problems.addProblem("could not find the configured bedheight, which is not possible", description); d@9706: return null; d@9706: } d@9706: d@9706: private static List loadBedHeightsByName(final River river, final Collection defaults, d@9706: final Calculation problems) { d@9706: d@9706: final List bedHeights = new ArrayList<>(defaults.size()); d@9706: d@9706: for (final DefaultBedHeight heightDefault : defaults) { d@9706: d@9706: final String description = heightDefault.description; d@9706: try { d@9706: d@9706: final BedHeight bedHeight = BedHeight.getBedHeightByDescription(river, description, d@9706: heightDefault.startKm, heightDefault.endKm); d@9706: if (bedHeight == null) d@9706: problems.addProblem("sinfo.bedheightsfinder.missingdescription", river.getName(), description); d@9706: else d@9706: bedHeights.add(bedHeight); d@9706: } catch (final Exception e) { d@9706: e.printStackTrace(); d@9706: problems.addProblem("sinfo.bedheightsfinder.missingdescription", river.getName(), description); d@9706: } d@9706: } d@9706: d@9706: return bedHeights; d@9706: } d@9706: d@9706: /* d@9706: * this check is replaced by configRangeCheck private static boolean d@9706: * overlapsRange(final NumberRange bedRange, final List result, final d@9706: * int startIndex) { d@9706: * d@9706: * for (int i = startIndex; i < result.size(); i++) { d@9706: * d@9706: * final BedHeight compareBed = result.get(i); final Range range = d@9706: * compareBed.getRange(); final NumberRange compareRange = new d@9706: * NumberRange(range.getA(), range.getB()); d@9706: * d@9706: * if (compareRange.overlapsRange(bedRange)) return true; } d@9706: * d@9706: * return false; } d@9706: */ gernotbelger@8942: }