Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java @ 395:aae8f327425e
'berechnete Abflusskurve': generate ws from qs
flys-artifacts/trunk@1822 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 04 May 2011 13:51:25 +0000 |
parents | 5f55047a17e8 |
children | c6b7ca0febcb |
comparison
equal
deleted
inserted
replaced
394:b9175ddea49b | 395:aae8f327425e |
---|---|
44 public static final String SQL_POS_WQ = | 44 public static final String SQL_POS_WQ = |
45 "SELECT position, w, q, column_pos" + | 45 "SELECT position, w, q, column_pos" + |
46 " FROM wst_value_table" + | 46 " FROM wst_value_table" + |
47 " WHERE wst_id = :wst_id"; | 47 " WHERE wst_id = :wst_id"; |
48 | 48 |
49 public static final double DEFAULT_STEP_WIDTH = 0.01; | 49 public static final int DEFAULT_Q_STEPS = 500; |
50 | 50 |
51 public static class Column | 51 public static class Column |
52 implements Serializable | 52 implements Serializable |
53 { | 53 { |
54 protected String name; | 54 protected String name; |
210 return new double [][] { | 210 return new double [][] { |
211 (double [])ws.clone(), | 211 (double [])ws.clone(), |
212 (double [])qs.clone() }; | 212 (double [])qs.clone() }; |
213 } | 213 } |
214 | 214 |
215 public double [][] interpolateWQ(Row other, double km, double stepWidth) { | 215 public double [][] interpolateWQ(Row other, double km, int steps) { |
216 | 216 |
217 int W1 = ascendingWs(); | 217 int W = Math.min(ws.length, other.ws.length); |
218 int W2 = other.ascendingWs(); | |
219 | |
220 int W = Math.min(W1, W2); | |
221 | 218 |
222 if (W < 1) { | 219 if (W < 1) { |
223 return new double[2][0]; | 220 return new double[2][0]; |
224 } | 221 } |
225 | 222 |
226 double factor = factor(km, this.km, other.km); | 223 double factor = factor(km, this.km, other.km); |
227 | 224 |
228 double minW = weight(factor, ws[0], other.ws[0]); | 225 double [] splineQ = new double[W]; |
229 double maxW = weight(factor, ws[W-1], other.ws[W-1]); | 226 double [] splineW = new double[W]; |
230 | 227 |
231 if (minW > maxW) { | 228 double minQ = Double.MAX_VALUE; |
232 double t = minW; | 229 double maxQ = -Double.MAX_VALUE; |
233 minW = maxW; | |
234 maxW = t; | |
235 } | |
236 double [] x = new double[W]; | |
237 double [] y = new double[W]; | |
238 | 230 |
239 for (int i = 0; i < W; ++i) { | 231 for (int i = 0; i < W; ++i) { |
240 x[i] = weight(factor, ws[i], other.ws[i]); | 232 double wws = weight(factor, ws[i], other.ws[i]); |
241 y[i] = weight(factor, qs[i], other.qs[i]); | 233 double wqs = weight(factor, qs[i], other.qs[i]); |
242 } | 234 splineW[i] = wws; |
235 splineQ[i] = wqs; | |
236 if (wqs < minQ) minQ = wqs; | |
237 if (wqs > maxQ) maxQ = wqs; | |
238 } | |
239 | |
240 double stepWidth = (maxQ - minQ)/steps; | |
243 | 241 |
244 SplineInterpolator interpolator = new SplineInterpolator(); | 242 SplineInterpolator interpolator = new SplineInterpolator(); |
245 PolynomialSplineFunction spline = interpolator.interpolate(x, y); | 243 PolynomialSplineFunction spline = |
246 | 244 interpolator.interpolate(splineQ, splineW); |
247 double [] outWs = | 245 |
248 new double[(int)Math.ceil((maxW - minW)/stepWidth)]; | 246 double [] outWs = new double[steps]; |
249 double [] outQs = | 247 double [] outQs = new double[steps]; |
250 new double[outWs.length]; | |
251 | 248 |
252 try { | 249 try { |
253 double w = minW; | 250 double q = minQ; |
254 for (int i = 0; i < outWs.length; ++i, w += stepWidth) { | 251 for (int i = 0; i < outWs.length; ++i, q += stepWidth) { |
255 outQs[i] = spline.value(outWs[i] = w); | 252 outWs[i] = spline.value(outQs[i] = q); |
256 } | 253 } |
257 } | 254 } |
258 catch (ArgumentOutsideDomainException aode) { | 255 catch (ArgumentOutsideDomainException aode) { |
259 log.error("Spline interpolation failed.", aode); | 256 log.error("Spline interpolation failed.", aode); |
260 } | 257 } |
261 | 258 |
262 return new double [][] { outWs, outQs }; | 259 return new double [][] { outWs, outQs }; |
263 | 260 } |
264 } | 261 |
265 | 262 public double [][] interpolateWQ(int steps) { |
266 public double [][] interpolateWQ(double stepWidth) { | 263 |
267 int W = ascendingWs(); // ignore back jumps | 264 int W = ws.length; |
268 | 265 |
269 if (W < 1) { | 266 if (W < 1) { |
270 return new double[2][0]; | 267 return new double[2][0]; |
271 } | 268 } |
272 | 269 |
273 double [] x = new double[W]; | 270 double [] splineW = new double[W]; |
274 double [] y = new double[W]; | 271 double [] splineQ = new double[W]; |
272 | |
273 double minQ = Double.MAX_VALUE; | |
274 double maxQ = -Double.MAX_VALUE; | |
275 | 275 |
276 for (int i = 0; i < W; ++i) { | 276 for (int i = 0; i < W; ++i) { |
277 x[i] = ws[i]; | 277 splineW[i] = ws[i]; |
278 y[i] = qs[i]; | 278 splineQ[i] = qs[i]; |
279 } | 279 if (qs[i] < minQ) minQ = qs[i]; |
280 if (qs[i] > maxQ) maxQ = qs[i]; | |
281 } | |
282 | |
283 double stepWidth = (maxQ - minQ)/steps; | |
280 | 284 |
281 SplineInterpolator interpolator = new SplineInterpolator(); | 285 SplineInterpolator interpolator = new SplineInterpolator(); |
282 | 286 |
283 PolynomialSplineFunction spline = interpolator.interpolate(x, y); | 287 PolynomialSplineFunction spline = |
284 | 288 interpolator.interpolate(splineQ, splineW); |
285 double minW = ws[0]; | 289 |
286 double maxW = ws[W-1]; | 290 double [] outWs = new double[steps]; |
287 | 291 double [] outQs = new double[steps]; |
288 double [] outWs = | |
289 new double[(int)Math.ceil((maxW - minW)/stepWidth)]; | |
290 double [] outQs = | |
291 new double[outWs.length]; | |
292 | 292 |
293 try { | 293 try { |
294 double w = minW; | 294 double q = minQ; |
295 for (int i = 0; i < outWs.length; ++i, w += stepWidth) { | 295 for (int i = 0; i < outWs.length; ++i, q += stepWidth) { |
296 outQs[i] = spline.value(outWs[i] = w); | 296 outWs[i] = spline.value(outQs[i] = q); |
297 } | 297 } |
298 } | 298 } |
299 catch (ArgumentOutsideDomainException aode) { | 299 catch (ArgumentOutsideDomainException aode) { |
300 log.error("Spline interpolation failed.", aode); | 300 log.error("Spline interpolation failed.", aode); |
301 } | 301 } |
380 return ws; | 380 return ws; |
381 } | 381 } |
382 | 382 |
383 | 383 |
384 public double [][] interpolateWQ(double km) { | 384 public double [][] interpolateWQ(double km) { |
385 return interpolateWQ(km, DEFAULT_STEP_WIDTH, true); | 385 return interpolateWQ(km, DEFAULT_Q_STEPS); |
386 } | 386 } |
387 | 387 |
388 public double [][] interpolateWQ( | 388 public double [][] interpolateWQ(double km, int steps) { |
389 double km, | 389 |
390 double stepWidth, | |
391 boolean checkAscending | |
392 ) { | |
393 int rowIndex = Collections.binarySearch(rows, new Row(km)); | 390 int rowIndex = Collections.binarySearch(rows, new Row(km)); |
394 | 391 |
395 if (rowIndex >= 0) { // direct row match | 392 if (rowIndex >= 0) { // direct row match |
396 Row row = rows.get(rowIndex); | 393 Row row = rows.get(rowIndex); |
397 return checkAscending | 394 return row.interpolateWQ(steps); |
398 ? row.interpolateWQ(stepWidth) | |
399 : row.cloneWQs(); | |
400 } | 395 } |
401 | 396 |
402 rowIndex = -rowIndex -1; | 397 rowIndex = -rowIndex -1; |
403 | 398 |
404 if (rowIndex < 1 || rowIndex >= rows.size()) { | 399 if (rowIndex < 1 || rowIndex >= rows.size()) { |
407 } | 402 } |
408 | 403 |
409 Row r1 = rows.get(rowIndex-1); | 404 Row r1 = rows.get(rowIndex-1); |
410 Row r2 = rows.get(rowIndex); | 405 Row r2 = rows.get(rowIndex); |
411 | 406 |
412 return checkAscending | 407 return r1.interpolateWQ(r2, km, steps); |
413 ? r1.interpolateWQ(r2, km, stepWidth) | |
414 : r1.weightWQs(r2, km); | |
415 } | 408 } |
416 | 409 |
417 public static WstValueTable getTable(River river) { | 410 public static WstValueTable getTable(River river) { |
418 return getTable(river, 0); | 411 return getTable(river, 0); |
419 } | 412 } |