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 }

http://dive4elements.wald.intevation.org