Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/SoilKindKmValueFinder.java @ 8952:1a8f19f3b776
Connection to new database table bed_mobility implemented
author | mschaefer |
---|---|
date | Mon, 19 Mar 2018 09:12:17 +0100 |
parents | d9dbf0b74bc2 |
children | 45f1ad66560e |
comparison
equal
deleted
inserted
replaced
8951:322b0e6298ea | 8952:1a8f19f3b776 |
---|---|
8 * documentation coming with Dive4Elements River for details. | 8 * documentation coming with Dive4Elements River for details. |
9 */ | 9 */ |
10 | 10 |
11 package org.dive4elements.river.artifacts.sinfo.tkhcalculation; | 11 package org.dive4elements.river.artifacts.sinfo.tkhcalculation; |
12 | 12 |
13 import java.util.ArrayList; | |
14 import java.util.List; | 13 import java.util.List; |
14 import java.util.Map.Entry; | |
15 import java.util.NavigableMap; | |
16 import java.util.TreeMap; | |
15 | 17 |
16 import org.apache.commons.lang.math.DoubleRange; | 18 import org.apache.commons.lang.math.DoubleRange; |
17 import org.apache.commons.math.ArgumentOutsideDomainException; | 19 import org.apache.commons.math.ArgumentOutsideDomainException; |
20 import org.dive4elements.river.backend.SessionHolder; | |
18 import org.dive4elements.river.model.River; | 21 import org.dive4elements.river.model.River; |
22 import org.hibernate.SQLQuery; | |
23 import org.hibernate.Session; | |
24 import org.hibernate.type.StandardBasicTypes; | |
19 | 25 |
20 import gnu.trove.TDoubleArrayList; | |
21 | 26 |
22 /** | 27 /** |
23 * @author Matthias Schäfer | 28 * @author Matthias Schäfer |
24 */ | 29 */ |
25 final class SoilKindKmValueFinder { | 30 final class SoilKindKmValueFinder { |
26 // /** | 31 |
27 // * Private log to use here. | 32 /***** FIELDS *****/ |
28 // */ | 33 |
29 // private static Logger log = Logger.getLogger(SoilKindKmValueFinder.class); | 34 // private static Logger log = Logger.getLogger(SoilKindKmValueFinder.class); |
30 | 35 |
31 private final TDoubleArrayList kms = new TDoubleArrayList(); | 36 /** |
37 * Query selecting the bed mobility attribute for a range of stations of a river | |
38 */ | |
39 private static final String SQL_BED_MOBILITY = "SELECT bmv.station, bmv.moving" | |
40 + " FROM bed_mobility bm INNER JOIN bed_mobility_values bmv ON bm.id = bmv.bed_mobility_id" | |
41 + " WHERE (bm.river_id=:river_id) AND (bmv.station BETWEEN (:fromkm-0.0001) AND (:tokm+0.0001))" | |
42 + " ORDER BY bmv.station ASC"; | |
32 | 43 |
33 private final List<SoilKind> values = new ArrayList<>(); | 44 private final NavigableMap<Double, SoilKind> kmMobility; |
45 | |
46 | |
47 /***** CONSTRUCTORS *****/ | |
48 | |
49 private SoilKindKmValueFinder() { | |
50 /* only instantiate me via static constructor */ | |
51 this.kmMobility = null; | |
52 } | |
53 | |
54 private SoilKindKmValueFinder(final List<Object[]> queryRows) { | |
55 this.kmMobility = new TreeMap<>(); | |
56 for (int i = 0; i <= queryRows.size() - 1; i++) { | |
57 this.kmMobility.put(Double.valueOf((double) queryRows.get(i)[0]), (((int) queryRows.get(i)[1]) == 1) ? SoilKind.mobil : SoilKind.starr); | |
58 } | |
59 } | |
60 | |
61 /***** METHODS *****/ | |
34 | 62 |
35 /** | 63 /** |
36 * Loads the range of the river's kms with their soil kind. | 64 * Loads the range of the river's kms with their soil kind. |
37 * | 65 * |
38 * @return Whether the load has been successful | 66 * @return Whether the load has been successful |
39 */ | 67 */ |
40 public static SoilKindKmValueFinder loadValues(final River river, final DoubleRange kmRange) { | 68 public static SoilKindKmValueFinder loadValues(final River river, final DoubleRange kmRange) { |
41 | 69 final Session session = SessionHolder.HOLDER.get(); |
42 final SoilKindKmValueFinder instance = new SoilKindKmValueFinder(); | 70 final SQLQuery sqlQuery = session.createSQLQuery(SQL_BED_MOBILITY).addScalar("station", StandardBasicTypes.DOUBLE) |
43 | 71 .addScalar("moving", StandardBasicTypes.INTEGER); |
44 // FIXME Echte Daten aus der Datenbank abfragen | 72 sqlQuery.setInteger("river_id", river.getId().intValue()); |
45 instance.addKmKind(0, SoilKind.starr); | 73 sqlQuery.setDouble("fromkm", kmRange.getMinimumDouble()); |
46 instance.addKmKind(15.7, SoilKind.mobil); | 74 sqlQuery.setDouble("tokm", kmRange.getMaximumDouble()); |
47 instance.addKmKind(15.8, SoilKind.mobil); | 75 final List<Object[]> rows = sqlQuery.list(); |
48 instance.addKmKind(15.9, SoilKind.starr); | 76 if (rows.size() >= 1) |
49 instance.addKmKind(108.7, SoilKind.mobil); | 77 return new SoilKindKmValueFinder(rows); |
50 instance.addKmKind(108.8, SoilKind.mobil); | 78 else |
51 instance.addKmKind(108.9, SoilKind.starr); | 79 return null; |
52 instance.addKmKind(119.1, SoilKind.mobil); | |
53 instance.addKmKind(119.4, SoilKind.mobil); | |
54 instance.addKmKind(119.5, SoilKind.starr); | |
55 instance.addKmKind(128.3, SoilKind.mobil); | |
56 instance.addKmKind(128.9, SoilKind.mobil); | |
57 instance.addKmKind(129, SoilKind.starr); | |
58 instance.addKmKind(133.1, SoilKind.mobil); | |
59 instance.addKmKind(135.9, SoilKind.mobil); | |
60 instance.addKmKind(136, SoilKind.starr); | |
61 instance.addKmKind(136.5, SoilKind.mobil); | |
62 instance.addKmKind(139.9, SoilKind.mobil); | |
63 instance.addKmKind(140, SoilKind.starr); | |
64 instance.addKmKind(140.5, SoilKind.mobil); | |
65 instance.addKmKind(165, SoilKind.mobil); | |
66 instance.addKmKind(165.1, SoilKind.starr); | |
67 instance.addKmKind(165.9, SoilKind.mobil); | |
68 instance.addKmKind(180.8, SoilKind.mobil); | |
69 instance.addKmKind(180.9, SoilKind.starr); | |
70 instance.addKmKind(182, SoilKind.mobil); | |
71 instance.addKmKind(221.3, SoilKind.mobil); | |
72 | |
73 return instance; | |
74 } | |
75 | |
76 private SoilKindKmValueFinder() { | |
77 /* only instantiate me via static constructor */ | |
78 } | 80 } |
79 | 81 |
80 /***** METHODS *****/ | 82 /***** METHODS *****/ |
81 | 83 |
82 /** | 84 /** |
83 * Searches a km with its soil kind | 85 * Searches a km with its soil kind |
84 */ | 86 */ |
85 public SoilKind findSoilKind(final double km) throws ArgumentOutsideDomainException { | 87 public SoilKind findSoilKind(final double km) throws ArgumentOutsideDomainException { |
86 if ((this.kms == null) || (this.kms.size() == 0)) | 88 if ((this.kmMobility == null) || this.kmMobility.isEmpty()) |
87 throw new ArgumentOutsideDomainException(km, Double.NaN, Double.NaN); | 89 throw new ArgumentOutsideDomainException(km, Double.NaN, Double.NaN); |
88 | 90 else if (this.kmMobility.containsKey(Double.valueOf(km))) |
89 // TODO: Voraussetzung für die binäre suche ist, dass nach km sortiert ist. | 91 return this.kmMobility.get(Double.valueOf(km)); |
90 // In diesem Fall könnte man ggf. auch gleich eine bessere Datenklasse benutzen, z.B. eine TreeMap<Double, SoilKind> | 92 else { |
91 // (also station -> art), und deren funktionen zum finden verwenden: | 93 // FIXME: Assert minimum distance between neighbouring stations and candidate km? |
92 // final double station = 0.0; | 94 final Entry<Double, SoilKind> streamUp = this.kmMobility.floorEntry(Double.valueOf(km)); |
93 // final NavigableMap<Double, SoilKind> data = new TreeMap<>(); | 95 if (streamUp == null) |
94 // data.ceilingEntry(station); | |
95 // data.floorEntry(station); | |
96 | |
97 int i = this.kms.binarySearch(km); | |
98 if (i >= 0) { | |
99 // Exact km match | |
100 return this.values.get(i); | |
101 } else { | |
102 // Out of range or within km interval | |
103 if (i < 0) | |
104 i = -i - 1; | |
105 if ((i <= 0) || (i >= this.kms.size())) | |
106 throw new ArgumentOutsideDomainException(km, Double.NaN, Double.NaN); | 96 throw new ArgumentOutsideDomainException(km, Double.NaN, Double.NaN); |
107 if (km <= ((this.kms.get(i - 1) + this.kms.get(i)) / 2)) | 97 else { |
108 return this.values.get(i - 1); | 98 // Return the soil kind of the neighbouring station with the shorter distance to the candidate. |
109 else | 99 final Entry<Double, SoilKind> streamDown = this.kmMobility.ceilingEntry(Double.valueOf(km)); |
110 return this.values.get(i); | 100 if (streamDown == null) |
101 return streamUp.getValue(); | |
102 else if ((streamUp.getKey().doubleValue() + streamDown.getKey().doubleValue()) / 2 <= km) | |
103 return streamUp.getValue(); | |
104 else | |
105 return streamDown.getValue(); | |
106 } | |
111 } | 107 } |
112 } | 108 } |
113 | |
114 private void addKmKind(final double km, final SoilKind kind) { | |
115 this.kms.add(km); | |
116 this.values.add(kind); | |
117 } | |
118 } | 109 } |