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 }

http://dive4elements.wald.intevation.org