Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java @ 8993:0adc6d04de95
SInfo - FlowDepthMinMax: choosing bed heights, not bed height min and max separately
author | gernotbelger |
---|---|
date | Wed, 11 Apr 2018 14:09:13 +0200 |
parents | b194fa64506a |
children | d5802f22e4f5 |
comparison
equal
deleted
inserted
replaced
8981:2e27061d9a93 | 8993:0adc6d04de95 |
---|---|
21 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; | 21 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; |
22 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; | 22 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider; |
23 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; | 23 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; |
24 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; | 24 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; |
25 import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthUtils; | 25 import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthUtils; |
26 import org.dive4elements.river.artifacts.sinfo.flowdepthminmax.FlowDepthMinMaxAccess.MinMaxIdPair; | 26 import org.dive4elements.river.artifacts.sinfo.flowdepth.WstSoundingIdPair; |
27 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder; | 27 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder; |
28 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder; | 28 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder; |
29 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; | 29 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; |
30 import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; | 30 import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; |
31 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; | 31 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils; |
53 /* access input data */ | 53 /* access input data */ |
54 final FlowDepthMinMaxAccess access = new FlowDepthMinMaxAccess(sinfo); | 54 final FlowDepthMinMaxAccess access = new FlowDepthMinMaxAccess(sinfo); |
55 final River river = access.getRiver(); | 55 final River river = access.getRiver(); |
56 final RiverInfo riverInfo = new RiverInfo(river); | 56 final RiverInfo riverInfo = new RiverInfo(river); |
57 | 57 |
58 final Collection<MinMaxIdPair> minMaxPairs = access.getMinMaxPairs(); | 58 final Collection<WstSoundingIdPair> minMaxPairs = access.getMinMaxPairs(); |
59 | 59 |
60 final DoubleRange calcRange = access.getRange(); | 60 final DoubleRange calcRange = access.getRange(); |
61 | 61 |
62 /* calculate results for each diff pair */ | 62 /* calculate results for each diff pair */ |
63 final Calculation problems = new Calculation(); | 63 final Calculation problems = new Calculation(); |
66 | 66 |
67 final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); | 67 final String calcModeLabel = Resources.getMsg(this.context.getMeta(), sinfo.getCalculationMode().name()); |
68 | 68 |
69 final FlowDepthMinMaxCalculationResults results = new FlowDepthMinMaxCalculationResults(calcModeLabel, user, riverInfo, calcRange); | 69 final FlowDepthMinMaxCalculationResults results = new FlowDepthMinMaxCalculationResults(calcModeLabel, user, riverInfo, calcRange); |
70 | 70 |
71 for (final MinMaxIdPair minMaxPair : minMaxPairs) { | 71 for (final WstSoundingIdPair minMaxPair : minMaxPairs) { |
72 final FlowDepthMinMaxCalculationResult result = calculateResult(calcRange, minMaxPair, problems, infoProvider); | 72 final FlowDepthMinMaxCalculationResult result = calculateResult(calcRange, minMaxPair, problems, infoProvider); |
73 results.addResult(result, problems); | 73 results.addResult(result, problems); |
74 } | 74 } |
75 | 75 |
76 return new CalculationResult(results, problems); | 76 return new CalculationResult(results, problems); |
79 /** | 79 /** |
80 * Calculates one W-MSH differences pair. | 80 * Calculates one W-MSH differences pair. |
81 * | 81 * |
82 * @param infoProvider | 82 * @param infoProvider |
83 */ | 83 */ |
84 private FlowDepthMinMaxCalculationResult calculateResult(final DoubleRange calcRange, final MinMaxIdPair minMaxPair, final Calculation problems, | 84 private FlowDepthMinMaxCalculationResult calculateResult(final DoubleRange calcRange, final WstSoundingIdPair minMaxPair, final Calculation problems, |
85 final RiverInfoProvider infoProvider) { | 85 final RiverInfoProvider infoProvider) { |
86 | 86 |
87 /* access real input data from database */ | 87 /* access real input data from database */ |
88 final String wstId = minMaxPair.getWstId(); | 88 final String wstId = minMaxPair.getWstId(); |
89 | 89 |
90 // FIXME: bfg überzeugen dass man immer nur pärchen auswählen kann --> min/max id ist gleich! | 90 final String soundingId = minMaxPair.getSoundingId(); |
91 | 91 |
92 final String minSoundingId = minMaxPair.getMinSoundingId(); | 92 final BedHeightsFinder bedHeight = BedHeightsFinder.forId(this.context, soundingId, calcRange, problems); |
93 final String maxSoundingId = minMaxPair.getMaxSoundingId(); | 93 if (bedHeight == null) |
94 | |
95 final BedHeightsFinder minBedHeight = minSoundingId == null ? null : BedHeightsFinder.forId(this.context, minSoundingId, calcRange, problems); | |
96 final BedHeightsFinder maxBedHeight = maxSoundingId == null ? null : BedHeightsFinder.forId(this.context, maxSoundingId, calcRange, problems); | |
97 if (minBedHeight == null && maxBedHeight == null) | |
98 return null; | 94 return null; |
99 | 95 |
100 /* REMARK: fetch ALL wst kms, because we want to determine the original reference gauge */ | 96 /* REMARK: fetch ALL wst kms, because we want to determine the original reference gauge */ |
101 final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, calcRange, problems); | 97 final WaterlevelData waterlevel = new WaterlevelFetcher().findWaterlevel(this.context, wstId, calcRange, problems); |
102 if (waterlevel == null) | 98 if (waterlevel == null) |
103 return null; | 99 return null; |
104 | 100 |
105 final String label = createLabel(waterlevel, minBedHeight, maxBedHeight); | 101 final String label = createLabel(waterlevel, bedHeight); |
106 | 102 |
107 final WKms wstKms = waterlevel.getWkms(); | 103 final WKms wstKms = waterlevel.getWkms(); |
108 | 104 |
109 final int soundingYear = checkSoundingYear(minBedHeight, maxBedHeight, problems); | 105 final BedHeightInfo bedHeightInfo = bedHeight.getInfo(); |
106 | |
107 final int soundingYear = bedHeightInfo.getYear(); | |
110 FlowDepthUtils.checkYearDifference(label, waterlevel.getYear(), soundingYear, problems); | 108 FlowDepthUtils.checkYearDifference(label, waterlevel.getYear(), soundingYear, problems); |
111 | 109 |
112 /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */ | 110 /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */ |
113 final RiverInfoProvider riverInfoProvider = infoProvider.forWaterlevel(waterlevel); | 111 final RiverInfoProvider riverInfoProvider = infoProvider.forWaterlevel(waterlevel); |
114 | 112 |
117 | 115 |
118 final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(problems, wstKms); | 116 final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(problems, wstKms); |
119 final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wstKms); | 117 final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wstKms); |
120 | 118 |
121 final String waterlevelLabel = waterlevel.getName(); | 119 final String waterlevelLabel = waterlevel.getName(); |
122 final String soundingLabel = buildSoundingLabel(minBedHeight, maxBedHeight); | 120 final String soundingLabel = bedHeightInfo.getDescription(); |
123 | 121 |
124 /* real calculation loop */ | 122 /* real calculation loop */ |
125 final Collection<SInfoResultRow> rows = new ArrayList<>(); | 123 final Collection<SInfoResultRow> rows = new ArrayList<>(); |
126 | 124 |
127 // FIXME: we use the stations of one of the bed heights atm, because we probably will later use only data from one bed heights datasets! | 125 final Collection<Double> stations = bedHeight.getStations(); |
128 final Collection<Double> stations = minBedHeight == null ? maxBedHeight.getStations() : minBedHeight.getStations(); | |
129 for (final double station : stations) { | 126 for (final double station : stations) { |
130 if (calcRange.containsDouble(station)) { | 127 if (calcRange.containsDouble(station)) { |
131 | 128 |
132 final double wst = waterlevelProvider.getWaterlevel(station); | 129 final double wst = waterlevelProvider.getWaterlevel(station); |
133 final double discharge = dischargeProvider.getDischarge(station); | 130 final double discharge = dischargeProvider.getDischarge(station); |
134 | 131 |
135 final double minBedHeightValue = minBedHeight == null ? Double.NaN : minBedHeight.getMeanBedHeight(station); | 132 final double minBedHeightValue = bedHeight.getMinBedHeight(station); |
136 final double maxBedHeightValue = maxBedHeight == null ? Double.NaN : maxBedHeight.getMeanBedHeight(station); | 133 final double maxBedHeightValue = bedHeight.getMaxBedHeight(station); |
134 final double meanBedHeight = bedHeight.getMeanBedHeight(station); | |
137 | 135 |
138 final double minFlowDepth = wst - minBedHeightValue; | 136 final double minFlowDepth = wst - maxBedHeightValue; |
139 final double maxFlowDepth = wst - maxBedHeightValue; | 137 final double maxFlowDepth = wst - minBedHeightValue; |
140 | |
141 // FIXME: unclear what is meant here... | |
142 // FIXME: this will simply the bed height of 'the' bed height if we reduce this to simply using one sounding dataset | |
143 final double meanBedHeight = Double.NaN; | |
144 | 138 |
145 // REMARK: access the location once only during calculation | 139 // REMARK: access the location once only during calculation |
146 final String location = riverInfoProvider.getLocation(station); | 140 final String location = riverInfoProvider.getLocation(station); |
147 | 141 |
148 // REMARK: access the gauge once only during calculation | 142 // REMARK: access the gauge once only during calculation |
165 putValue(SInfoResultType.location, location); | 159 putValue(SInfoResultType.location, location); |
166 rows.add(row); | 160 rows.add(row); |
167 } | 161 } |
168 } | 162 } |
169 | 163 |
170 final BedHeightInfo minBedHeightInfo = minBedHeight == null ? null : minBedHeight.getInfo(); | 164 return new FlowDepthMinMaxCalculationResult(label, wstInfo, bedHeightInfo, rows); |
171 final BedHeightInfo maxBedHeightInfo = maxBedHeight == null ? null : maxBedHeight.getInfo(); | |
172 | |
173 return new FlowDepthMinMaxCalculationResult(label, wstInfo, minBedHeightInfo, maxBedHeightInfo, rows); | |
174 } | 165 } |
175 | 166 |
176 private String buildSoundingLabel(final BedHeightsFinder minBedHeight, final BedHeightsFinder maxBedHeight) { | 167 private String createLabel(final WaterlevelData waterlevel, final BedHeightsFinder bedHeight) { |
177 | 168 |
178 if (minBedHeight == null) | 169 return new StringBuilder(waterlevel.getName()). // |
179 return maxBedHeight.getInfo().getDescription(); | 170 append(" - "). // |
180 | 171 append(bedHeight.getInfo().getDescription()). // |
181 if (maxBedHeight == null) | 172 toString(); |
182 return minBedHeight.getInfo().getDescription(); | |
183 | |
184 return String.format("%s / %s", minBedHeight.getInfo().getDescription(), maxBedHeight.getInfo().getDescription()); | |
185 } | |
186 | |
187 private String createLabel(final WaterlevelData waterlevel, final BedHeightsFinder minBedHeight, final BedHeightsFinder maxBedHeight) { | |
188 | |
189 final StringBuilder buffer = new StringBuilder(waterlevel.getName()); | |
190 | |
191 if (minBedHeight != null) | |
192 buffer.append(" - "). // | |
193 append(minBedHeight.getInfo().getDescription()); | |
194 | |
195 if (maxBedHeight != null) | |
196 buffer.append(" - "). // | |
197 append(maxBedHeight.getInfo().getDescription()); | |
198 | |
199 return buffer.toString(); | |
200 } | |
201 | |
202 private int checkSoundingYear(final BedHeightsFinder minBedHeight, final BedHeightsFinder maxBedHeight, final Calculation problems) { | |
203 | |
204 if (maxBedHeight == null) | |
205 return minBedHeight.getInfo().getYear(); | |
206 | |
207 if (minBedHeight == null) | |
208 return maxBedHeight.getInfo().getYear(); | |
209 | |
210 final int minYear = minBedHeight.getInfo().getYear(); | |
211 final int maxYear = minBedHeight.getInfo().getYear(); | |
212 | |
213 if (minYear != maxYear) | |
214 problems.addProblem("sinfo.flowdepthminmaxcalculation.soundingyear.different"); | |
215 | |
216 return minYear; | |
217 } | 173 } |
218 } | 174 } |