view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/DefaultBedHeights.java @ 9211:aca5a7a57a3a

SINFO-TKH: definition der standard sohlhöhen jetzt mit Gültigkeitsstrecke. Definitionsdateien aufgeteilt in eine pro Gewässer.
author gernotbelger
date Tue, 03 Jul 2018 13:09:46 +0200
parents ed4b14389667
children 439699ff9b2d
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.tkhstate;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.math.NumberRange;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.sinfo.tkhstate.DefaultBedHeightsConfig.DefaultBedHeight;
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 final River river;

    public DefaultBedHeights(final River river) {
        this.river = river;
    }

    public List<BedHeight> getBedHeights(final Calculation problems) {
        final Collection<DefaultBedHeight> defaults = DefaultBedHeightsConfig.getDefaults(this.river, problems);

        final List<BedHeight> defaultBedHeights = loadBedHeightsByName(this.river, defaults, problems);
        if (defaultBedHeights.isEmpty()) {
            problems.addProblem("sinfo.bedheightsfinder.nobedheightsforriver", this.river.getName());
            return Collections.emptyList();
        }

        /* 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 = defaultBedHeights.get(i);

            final Range range = bedHeight.getRange();
            final NumberRange bedRange = new NumberRange(range.getA(), range.getB());

            if (overlapsRange(bedRange, defaultBedHeights, i + 1))
                problems.addProblem("sinfo.bedheightsfinder.overlappingrange", bedHeight.getDescription());
            else
                result.add(bedHeight);
        }

        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);
        }

        return result;
    }


    private static List<BedHeight> loadBedHeightsByName(final River river, final Collection<DefaultBedHeight> defaults, final Calculation problems) {

        final List<BedHeight> bedHeights = new ArrayList<>(defaults.size());

        for (final DefaultBedHeight heightDefault : defaults) {

            final String description = heightDefault.description;
            try {

                final BedHeight bedHeight = BedHeight.getBedHeightByDescription(river, description, heightDefault.startKm, heightDefault.endKm);
                if (bedHeight == null)
                    problems.addProblem("sinfo.bedheightsfinder.missingdescription", river.getName(), description);
                else
                    bedHeights.add(bedHeight);
            }
            catch (final Exception e) {
                e.printStackTrace();
                problems.addProblem("sinfo.bedheightsfinder.missingdescription", river.getName(), description);
            }
        }

        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;
    }
}

http://dive4elements.wald.intevation.org