Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/DefaultBedHeights.java @ 8942:11bf13cf0463
Minor changes to tkh calculation. Loading default bed heights form config file.
author | gernotbelger |
---|---|
date | Fri, 09 Mar 2018 18:47:06 +0100 |
parents | |
children | fb976ea01463 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/DefaultBedHeights.java Fri Mar 09 18:47:06 2018 +0100 @@ -0,0 +1,146 @@ +/** 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.tkhstate; + +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.math.NumberRange; +import org.dive4elements.artifacts.common.utils.Config; +import org.dive4elements.river.artifacts.model.Calculation; +import org.dive4elements.river.model.BedHeight; +import org.dive4elements.river.model.Range; +import org.dive4elements.river.model.River; + +/** + * This class knows how to find the default bed heights defined for tkh calculation + * + * @author Gernot Belger + */ +final class DefaultBedHeights { + private static final String CONFIG_FILE = "sinfo_tkh_bedheights.properties"; + private final River river; + + public DefaultBedHeights(final River river) { + this.river = river; + } + + public List<BedHeight> getBedHeights(final Calculation problems) { + final Collection<String> bedHeightNames = loadBedHeightDefaultsForRiver(this.river, problems); + + final List<BedHeight> defaultBedHeights = loadBedHeightsByName(this.river, bedHeightNames, problems); + + final List<BedHeight> validBedHeights = new ArrayList<>(defaultBedHeights.size()); + + // REMARK: check for bad ranges because db schema allow for incomplete ranges, and ignore if this is the case + for (final BedHeight bedHeight : defaultBedHeights) { + + final Range range = bedHeight.getRange(); + + if (range.getA() == null || range.getB() == null) + problems.addProblem("sinfo.bedheightsfinder.badrange", bedHeight.getDescription()); + else + validBedHeights.add(bedHeight); + } + + /* check for overlapping ranges, N2-search, but we expect only have small numbers of bed heights */ + final List<BedHeight> result = new ArrayList<>(defaultBedHeights.size()); + + for (int i = 0; i < defaultBedHeights.size(); i++) { + final BedHeight bedHeight = validBedHeights.get(i); + + final Range range = bedHeight.getRange(); + final NumberRange bedRange = new NumberRange(range.getA(), range.getB()); + + if (overlapsRange(bedRange, validBedHeights, i + 1)) { + problems.addProblem("sinfo.bedheightsfinder.overlappingrange", bedHeight.getDescription()); + } else + result.add(bedHeight); + } + + return result; + } + + private static Collection<String> loadBedHeightDefaultsForRiver(final River river, final Calculation problems) { + final File configDir = Config.getConfigDirectory(); + final File configFile = new File(configDir, CONFIG_FILE); + + final Properties properties = new Properties(); + try (final InputStreamReader reader = new InputStreamReader(Files.newInputStream(configFile.toPath()), StandardCharsets.ISO_8859_1)) { + properties.load(reader); + + final String value = properties.getProperty(river.getName()); + final String[] split = StringUtils.split(StringUtils.trim(value), ','); + if (ArrayUtils.isEmpty(split)) { + problems.addProblem("sinfo.bedheightsfinder.configfile.missingriver", CONFIG_FILE, river.getName()); + return Collections.emptyList(); + } + + return Arrays.asList(split); + } + catch (final IOException e) { + e.printStackTrace(); + problems.addProblem("sinfo.bedheightsfinder.configfile.loaderror", CONFIG_FILE, e.getMessage()); + return Collections.emptyList(); + } + } + + private static List<BedHeight> loadBedHeightsByName(final River shouldBeRiver, final Collection<String> bedHeightNames, final Calculation problems) { + + final List<BedHeight> bedHeights = new ArrayList<>(bedHeightNames.size()); + + for (final String name : bedHeightNames) { + try { + final BedHeight bedHeight = BedHeight.getBedHeightByDescription(name); + if (bedHeight == null) + problems.addProblem("sinfo.bedheightsfinder.missingdescription", name); + else { + final River river = bedHeight.getRiver(); + if (!shouldBeRiver.getId().equals(river.getId())) + problems.addProblem("sinfo.bedheightsfinder.wrongriver", name, shouldBeRiver.getName()); + else + bedHeights.add(bedHeight); + } + } + catch (final Exception e) { + e.printStackTrace(); + problems.addProblem("sinfo.bedheightsfinder.missingdescription", name); + } + } + + return bedHeights; + } + + private static boolean overlapsRange(final NumberRange bedRange, final List<BedHeight> result, final int startIndex) { + + for (int i = startIndex; i < result.size(); i++) { + + final BedHeight compareBed = result.get(i); + final Range range = compareBed.getRange(); + final NumberRange compareRange = new NumberRange(range.getA(), range.getB()); + + if (compareRange.overlapsRange(bedRange)) + return true; + } + + return false; + } +} \ No newline at end of file