Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.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 | 9c02733a1b3c |
children | 5d5d482da3e9 |
comparison
equal
deleted
inserted
replaced
8941:a9950a3a71e5 | 8942:11bf13cf0463 |
---|---|
9 */ | 9 */ |
10 package org.dive4elements.river.artifacts.sinfo.tkhstate; | 10 package org.dive4elements.river.artifacts.sinfo.tkhstate; |
11 | 11 |
12 import java.util.ArrayList; | 12 import java.util.ArrayList; |
13 import java.util.Collection; | 13 import java.util.Collection; |
14 import java.util.HashMap; | |
14 import java.util.List; | 15 import java.util.List; |
16 import java.util.Map; | |
17 import java.util.Map.Entry; | |
18 import java.util.Set; | |
15 | 19 |
16 import org.apache.commons.lang.math.DoubleRange; | 20 import org.apache.commons.lang.math.DoubleRange; |
21 import org.apache.commons.lang.math.NumberRange; | |
17 import org.dive4elements.artifacts.CallContext; | 22 import org.dive4elements.artifacts.CallContext; |
18 import org.dive4elements.river.artifacts.WINFOArtifact; | 23 import org.dive4elements.river.artifacts.WINFOArtifact; |
19 import org.dive4elements.river.artifacts.model.Calculation; | 24 import org.dive4elements.river.artifacts.model.Calculation; |
20 import org.dive4elements.river.artifacts.model.Calculation.Problem; | 25 import org.dive4elements.river.artifacts.model.Calculation.Problem; |
21 import org.dive4elements.river.artifacts.model.CalculationResult; | 26 import org.dive4elements.river.artifacts.model.CalculationResult; |
24 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; | 29 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; |
25 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; | 30 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; |
26 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder; | 31 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder; |
27 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh; | 32 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.Tkh; |
28 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; | 33 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator; |
34 import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; | |
29 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; | 35 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; |
30 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; | 36 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo; |
31 import org.dive4elements.river.artifacts.sinfo.util.WstInfo; | 37 import org.dive4elements.river.artifacts.sinfo.util.WstInfo; |
32 import org.dive4elements.river.artifacts.states.WaterlevelData; | 38 import org.dive4elements.river.artifacts.states.WaterlevelData; |
33 import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; | 39 import org.dive4elements.river.exports.WaterlevelDescriptionBuilder; |
40 import org.dive4elements.river.model.BedHeight; | |
34 import org.dive4elements.river.model.River; | 41 import org.dive4elements.river.model.River; |
35 | 42 |
36 /** | 43 /** |
37 * @author Gernot Belger | 44 * @author Gernot Belger |
38 */ | 45 */ |
53 final DoubleRange calcRange = access.getRange(); | 60 final DoubleRange calcRange = access.getRange(); |
54 | 61 |
55 final Calculation problems = new Calculation(); | 62 final Calculation problems = new Calculation(); |
56 | 63 |
57 /* find relevant bed-heights */ | 64 /* find relevant bed-heights */ |
58 final Collection<BedHeightsFinder> bedHeights = BedHeightsFinder.createTkhBedHeights(river, problems, calcRange); | 65 final List<BedHeight> defaultBedHeights = new DefaultBedHeights(river).getBedHeights(problems); |
66 final Collection<BedHeightsFinder> bedHeights = BedHeightsFinder.createTkhBedHeights(calcRange, defaultBedHeights); | |
59 | 67 |
60 /* misuse winfo-artifact to calculate waterlevels in the same way */ | 68 /* misuse winfo-artifact to calculate waterlevels in the same way */ |
61 final WINFOArtifact winfo = new WinfoArtifactWrapper(sinfo); | 69 final WINFOArtifact winfo = new WinfoArtifactWrapper(sinfo); |
62 | 70 |
63 /* calculate waterlevels */ | 71 /* calculate waterlevels */ |
116 // FIXME: check with winfo how the name is generated | 124 // FIXME: check with winfo how the name is generated |
117 final String wstLabel = waterlevel.getName(); | 125 final String wstLabel = waterlevel.getName(); |
118 | 126 |
119 final WstInfo wstInfo = new WstInfo(wstLabel, wspYear, riverInfoProvider.getReferenceGauge()); | 127 final WstInfo wstInfo = new WstInfo(wstLabel, wspYear, riverInfoProvider.getReferenceGauge()); |
120 | 128 |
129 /* build tkh calculators per bedheight */ | |
130 final Map<NumberRange, TkhCalculator> calculatorsByRanges = buildCalculators(calcRange, wkms, bedHeights, problems, riverInfoProvider, wstLabel); | |
131 if (calculatorsByRanges.isEmpty()) { | |
132 /* there should already be some problems, so just abort */ | |
133 return null; | |
134 } | |
135 | |
121 final Collection<TkhResultRow> rows = new ArrayList<>(); | 136 final Collection<TkhResultRow> rows = new ArrayList<>(); |
122 | 137 |
123 /* | 138 /* using wst-kms as basis, because we know that they are generated wst's with a fixed km-step */ |
124 * for each separate bed height dataset we do the calculation and put everything into one result, bed heights must not | 139 // FIXME: das führt dazu, das aktuell die Sohlhöhen beliebig linear interpolierrt werden. ist das immer richtig? z.b. |
125 * overlap accordingly | 140 // bei großen abständen? |
126 */ | 141 |
142 final int size = wkms.size(); | |
143 for (int i = 0; i < size; i++) { | |
144 | |
145 final double station = wkms.getKm(i); | |
146 final double wst = wkms.getW(i); | |
147 | |
148 /* find the right calculator (i.e. bedheigh) depending on station, there should only be one maximal */ | |
149 final TkhCalculator tkhCalculator = findCalculator(calculatorsByRanges, station); | |
150 if (tkhCalculator == null) | |
151 continue; | |
152 | |
153 final Tkh tkh = tkhCalculator.getTkh(station, wst); | |
154 | |
155 final String description = descBuilder.getDesc(wkms); | |
156 final String gaugeLabel = riverInfoProvider.findGauge(station); | |
157 final String location = riverInfoProvider.getLocation(station); | |
158 | |
159 rows.add(new TkhResultRow(tkh, description, gaugeLabel, location)); | |
160 } | |
161 | |
162 return new TkhCalculationResult(wstLabel, wstInfo, true, rows); | |
163 } | |
164 | |
165 private TkhCalculator findCalculator(final Map<NumberRange, TkhCalculator> calculators, final double station) { | |
166 | |
167 // REMAKR: linear search at this point, put we expect the number of bed heights to be very small (1-2 items) | |
168 final Set<Entry<NumberRange, TkhCalculator>> x = calculators.entrySet(); | |
169 for (final Entry<NumberRange, TkhCalculator> entry : x) { | |
170 final NumberRange range = entry.getKey(); | |
171 // FIXME: check if we need comparison with a tolerance | |
172 if (range.containsDouble(station)) | |
173 return entry.getValue(); | |
174 } | |
175 | |
176 return null; | |
177 } | |
178 | |
179 private Map<NumberRange, TkhCalculator> buildCalculators(final DoubleRange calcRange, final WQKms wkms, final Collection<BedHeightsFinder> bedHeights, | |
180 final Calculation problems, final RiverInfoProvider riverInfoProvider, final String wstLabel) { | |
181 final Map<NumberRange, TkhCalculator> calculatorByRanges = new HashMap<>(); | |
127 for (final BedHeightsFinder bedHeightsProvider : bedHeights) { | 182 for (final BedHeightsFinder bedHeightsProvider : bedHeights) { |
183 | |
184 final BedHeightInfo info = bedHeightsProvider.getInfo(); | |
185 | |
186 final NumberRange range = new NumberRange(info.getFrom(), info.getTo()); | |
128 | 187 |
129 final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wkms); | 188 final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wkms); |
130 | 189 |
131 /* initialize tkh calculator */ | 190 /* initialize tkh calculator */ |
132 final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(true, this.context, problems, wstLabel, riverInfoProvider.getRiver(), | 191 final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(true, this.context, problems, wstLabel, riverInfoProvider.getRiver(), |
133 calcRange, | 192 calcRange, dischargeProvider, bedHeightsProvider); |
134 dischargeProvider, bedHeightsProvider); | 193 |
135 if (tkhCalculator == null) { | 194 if (tkhCalculator != null) { |
136 /* just abort, problems have already been updated by buildTkhCalculator() */ | 195 /* just ignore null ones, problems have already been updated by buildTkhCalculator() */ |
137 return null; | 196 calculatorByRanges.put(range, tkhCalculator); |
138 } | 197 } |
139 | 198 } |
140 /* using wst-kms as basis, because we know that they are generated wst's with a fixed km-step */ | 199 |
141 | 200 return calculatorByRanges; |
142 // FIXME: das führt dazu, das aktuell die Sohlhöhen beliebig linear interpolierrt werden. ist das immer richtig? z.b. | |
143 // bei großen abständen? | |
144 | |
145 final int size = wkms.size(); | |
146 for (int i = 0; i < size; i++) { | |
147 | |
148 final double station = wkms.getKm(i); | |
149 final double wst = wkms.getW(i); | |
150 | |
151 final Tkh tkh = tkhCalculator.getTkh(station, wst); | |
152 | |
153 final String description = descBuilder.getDesc(wkms); | |
154 final String gaugeLabel = riverInfoProvider.findGauge(station); | |
155 final String location = riverInfoProvider.getLocation(station); | |
156 | |
157 rows.add(new TkhResultRow(tkh, description, gaugeLabel, location)); | |
158 } | |
159 } | |
160 | |
161 return new TkhCalculationResult(wstLabel, wstInfo, true, rows); | |
162 } | 201 } |
163 } | 202 } |