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

http://dive4elements.wald.intevation.org