Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/SoilKindKmValueFinder.java @ 8964:45f1ad66560e
Code cleanup concerning calculations: improved error handling; improved interpolation; bed heights are now always used for spatial discretisation
author | gernotbelger |
---|---|
date | Thu, 29 Mar 2018 15:48:17 +0200 |
parents | 1a8f19f3b776 |
children | b194fa64506a |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/SoilKindKmValueFinder.java Wed Mar 28 17:04:20 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/SoilKindKmValueFinder.java Thu Mar 29 15:48:17 2018 +0200 @@ -16,14 +16,13 @@ import java.util.TreeMap; import org.apache.commons.lang.math.DoubleRange; -import org.apache.commons.math.ArgumentOutsideDomainException; +import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.backend.SessionHolder; import org.dive4elements.river.model.River; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.type.StandardBasicTypes; - /** * @author Matthias Schäfer */ @@ -38,21 +37,17 @@ */ private static final String SQL_BED_MOBILITY = "SELECT bmv.station, bmv.moving" + " FROM bed_mobility bm INNER JOIN bed_mobility_values bmv ON bm.id = bmv.bed_mobility_id" - + " WHERE (bm.river_id=:river_id) AND (bmv.station BETWEEN (:fromkm-0.0001) AND (:tokm+0.0001))" - + " ORDER BY bmv.station ASC"; + + " WHERE (bm.river_id=:river_id) AND (bmv.station BETWEEN (:fromkm-0.0001) AND (:tokm+0.0001))" + " ORDER BY bmv.station ASC"; - private final NavigableMap<Double, SoilKind> kmMobility; + private final NavigableMap<Double, SoilKind> kmMobility = new TreeMap<>(); + private Calculation problems; /***** CONSTRUCTORS *****/ - private SoilKindKmValueFinder() { - /* only instantiate me via static constructor */ - this.kmMobility = null; - } + private SoilKindKmValueFinder(final Calculation problems, final List<Object[]> queryRows) { + this.problems = problems; - private SoilKindKmValueFinder(final List<Object[]> queryRows) { - this.kmMobility = new TreeMap<>(); for (int i = 0; i <= queryRows.size() - 1; i++) { this.kmMobility.put(Double.valueOf((double) queryRows.get(i)[0]), (((int) queryRows.get(i)[1]) == 1) ? SoilKind.mobil : SoilKind.starr); } @@ -65,18 +60,19 @@ * * @return Whether the load has been successful */ - public static SoilKindKmValueFinder loadValues(final River river, final DoubleRange kmRange) { + public static SoilKindKmValueFinder loadValues(final Calculation problems, final River river, final DoubleRange kmRange) { final Session session = SessionHolder.HOLDER.get(); - final SQLQuery sqlQuery = session.createSQLQuery(SQL_BED_MOBILITY).addScalar("station", StandardBasicTypes.DOUBLE) - .addScalar("moving", StandardBasicTypes.INTEGER); + final SQLQuery sqlQuery = session.createSQLQuery(SQL_BED_MOBILITY).addScalar("station", StandardBasicTypes.DOUBLE).addScalar("moving", + StandardBasicTypes.INTEGER); sqlQuery.setInteger("river_id", river.getId().intValue()); sqlQuery.setDouble("fromkm", kmRange.getMinimumDouble()); sqlQuery.setDouble("tokm", kmRange.getMaximumDouble()); final List<Object[]> rows = sqlQuery.list(); if (rows.size() >= 1) - return new SoilKindKmValueFinder(rows); - else - return null; + return new SoilKindKmValueFinder(problems, rows); + + problems.addProblem("soilkindkmvaluefinder.empty"); + return null; } /***** METHODS *****/ @@ -84,26 +80,41 @@ /** * Searches a km with its soil kind */ - public SoilKind findSoilKind(final double km) throws ArgumentOutsideDomainException { - if ((this.kmMobility == null) || this.kmMobility.isEmpty()) - throw new ArgumentOutsideDomainException(km, Double.NaN, Double.NaN); - else if (this.kmMobility.containsKey(Double.valueOf(km))) + public SoilKind findSoilKind(final double km) { + + if (this.kmMobility.containsKey(Double.valueOf(km))) return this.kmMobility.get(Double.valueOf(km)); - else { - // FIXME: Assert minimum distance between neighbouring stations and candidate km? - final Entry<Double, SoilKind> streamUp = this.kmMobility.floorEntry(Double.valueOf(km)); - if (streamUp == null) - throw new ArgumentOutsideDomainException(km, Double.NaN, Double.NaN); - else { - // Return the soil kind of the neighbouring station with the shorter distance to the candidate. - final Entry<Double, SoilKind> streamDown = this.kmMobility.ceilingEntry(Double.valueOf(km)); - if (streamDown == null) - return streamUp.getValue(); - else if ((streamUp.getKey().doubleValue() + streamDown.getKey().doubleValue()) / 2 <= km) - return streamUp.getValue(); - else - return streamDown.getValue(); - } + + final Entry<Double, SoilKind> streamUp = this.kmMobility.floorEntry(Double.valueOf(km)); + if (streamUp == null) + { + reportProblem(km); + return null; } + + // FIXME: Assert minimum distance between neighbouring stations and candidate km? + + // Return the soil kind of the neighbouring station with the shorter distance to the candidate. + final Entry<Double, SoilKind> streamDown = this.kmMobility.ceilingEntry(Double.valueOf(km)); + if (streamDown == null) + return streamUp.getValue(); + + final double streamUpValue = streamUp.getKey().doubleValue(); + final double streamDownValue = streamDown.getKey().doubleValue(); + + if ((streamUpValue + streamDownValue) / 2 <= km) + return streamUp.getValue(); + + return streamDown.getValue(); + } + + private void reportProblem(final double km) { + if (this.problems == null) + return; + + this.problems.addProblem(km, "soilkindkmvaluefinder.missing"); + + // report problem only once + this.problems = null; } } \ No newline at end of file