Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java @ 462:ebf049a1eb53
merged flys-artifacts/2.3.1
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:11 +0200 |
parents | af1b64ec7250 |
children | 929137ee8154 |
comparison
equal
deleted
inserted
replaced
441:c4c8137e8f0e | 462:ebf049a1eb53 |
---|---|
1 package de.intevation.flys.artifacts; | |
2 | |
3 import java.util.List; | |
4 import java.util.Vector; | |
5 import java.util.ArrayList; | |
6 | |
7 import org.w3c.dom.Document; | |
8 import org.w3c.dom.Element; | |
9 import org.w3c.dom.Node; | |
10 | |
11 import org.apache.log4j.Logger; | |
12 | |
13 import de.intevation.artifacts.ArtifactNamespaceContext; | |
14 import de.intevation.artifacts.CallContext; | |
15 | |
16 import de.intevation.artifactdatabase.ProtocolUtils; | |
17 import de.intevation.artifactdatabase.state.Output; | |
18 import de.intevation.artifactdatabase.state.State; | |
19 import de.intevation.artifactdatabase.state.StateEngine; | |
20 import de.intevation.artifactdatabase.transition.TransitionEngine; | |
21 | |
22 import de.intevation.artifacts.common.utils.XMLUtils; | |
23 | |
24 import de.intevation.flys.model.Gauge; | |
25 import de.intevation.flys.model.River; | |
26 | |
27 import de.intevation.flys.artifacts.states.DefaultState; | |
28 import de.intevation.flys.artifacts.context.FLYSContext; | |
29 import de.intevation.flys.artifacts.math.BackJumpCorrector; | |
30 import de.intevation.flys.artifacts.model.MainValuesFactory; | |
31 import de.intevation.flys.artifacts.model.WQCKms; | |
32 import de.intevation.flys.artifacts.model.WQDay; | |
33 import de.intevation.flys.artifacts.model.WQKms; | |
34 import de.intevation.flys.artifacts.model.WstValueTable; | |
35 import de.intevation.flys.artifacts.model.WstValueTable.QPosition; | |
36 import de.intevation.flys.artifacts.model.WstValueTableFactory; | |
37 | |
38 import de.intevation.flys.artifacts.math.LinearRemap; | |
39 | |
40 import gnu.trove.TDoubleArrayList; | |
41 | |
42 /** | |
43 * The default WINFO artifact. | |
44 * | |
45 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | |
46 */ | |
47 public class WINFOArtifact extends FLYSArtifact { | |
48 | |
49 /** The logger for this class */ | |
50 private static Logger logger = Logger.getLogger(WINFOArtifact.class); | |
51 | |
52 | |
53 /** The name of the artifact.*/ | |
54 public static final String ARTIFACT_NAME = "winfo"; | |
55 | |
56 /** XPath */ | |
57 public static final String XPATH_STATIC_UI ="/art:result/art:ui/art:static"; | |
58 | |
59 | |
60 /** | |
61 * The default constructor. | |
62 */ | |
63 public WINFOArtifact() { | |
64 } | |
65 | |
66 | |
67 /** | |
68 * This method returns a description of this artifact. | |
69 * | |
70 * @param data Some data. | |
71 * @param context The CallContext. | |
72 * | |
73 * @return the description of this artifact. | |
74 */ | |
75 public Document describe(Document data, CallContext context) { | |
76 logger.debug("Describe: the current state is: " + getCurrentStateId()); | |
77 | |
78 FLYSContext flysContext = null; | |
79 if (context instanceof FLYSContext) { | |
80 flysContext = (FLYSContext) context; | |
81 } | |
82 else { | |
83 flysContext = (FLYSContext) context.globalContext(); | |
84 } | |
85 | |
86 StateEngine stateEngine = (StateEngine) flysContext.get( | |
87 FLYSContext.STATE_ENGINE_KEY); | |
88 | |
89 TransitionEngine transitionEngine = (TransitionEngine) flysContext.get( | |
90 FLYSContext.TRANSITION_ENGINE_KEY); | |
91 | |
92 List<State> reachable = transitionEngine.getReachableStates( | |
93 this, getCurrentState(context), stateEngine); | |
94 | |
95 Document description = XMLUtils.newDocument(); | |
96 XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( | |
97 description, | |
98 ArtifactNamespaceContext.NAMESPACE_URI, | |
99 ArtifactNamespaceContext.NAMESPACE_PREFIX); | |
100 | |
101 Element root = ProtocolUtils.createRootNode(creator); | |
102 description.appendChild(root); | |
103 | |
104 State current = getCurrentState(context); | |
105 | |
106 ProtocolUtils.appendDescribeHeader(creator, root, identifier(), hash()); | |
107 ProtocolUtils.appendState(creator, root, current); | |
108 ProtocolUtils.appendReachableStates(creator, root, reachable); | |
109 | |
110 Element name = ProtocolUtils.createArtNode( | |
111 creator, "name", | |
112 new String[] { "value" }, | |
113 new String[] { getName() }); | |
114 | |
115 Element ui = ProtocolUtils.createArtNode( | |
116 creator, "ui", null, null); | |
117 | |
118 Element staticUI = ProtocolUtils.createArtNode( | |
119 creator, "static", null, null); | |
120 | |
121 Element outs = ProtocolUtils.createArtNode( | |
122 creator, "outputmodes", null, null); | |
123 appendOutputModes(description, outs, context, identifier()); | |
124 | |
125 appendStaticUI(description, staticUI, context, identifier()); | |
126 | |
127 Element dynamic = current.describe( | |
128 this, | |
129 description, | |
130 root, | |
131 context, | |
132 identifier()); | |
133 | |
134 if (dynamic != null) { | |
135 ui.appendChild(dynamic); | |
136 } | |
137 | |
138 ui.appendChild(staticUI); | |
139 | |
140 root.appendChild(name); | |
141 root.appendChild(ui); | |
142 root.appendChild(outs); | |
143 | |
144 return description; | |
145 } | |
146 | |
147 | |
148 /** | |
149 * Returns the name of the concrete artifact. | |
150 * | |
151 * @return the name of the concrete artifact. | |
152 */ | |
153 public String getName() { | |
154 return ARTIFACT_NAME; | |
155 } | |
156 | |
157 | |
158 protected void appendOutputModes( | |
159 Document doc, | |
160 Element outs, | |
161 CallContext context, | |
162 String uuid) | |
163 { | |
164 Vector<String> stateIds = getPreviousStateIds(); | |
165 | |
166 XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator( | |
167 doc, | |
168 ArtifactNamespaceContext.NAMESPACE_URI, | |
169 ArtifactNamespaceContext.NAMESPACE_PREFIX); | |
170 | |
171 FLYSContext flysContext = getFlysContext(context); | |
172 StateEngine engine = (StateEngine) flysContext.get( | |
173 FLYSContext.STATE_ENGINE_KEY); | |
174 | |
175 for (String stateId: stateIds) { | |
176 logger.debug("Append output modes for state: " + stateId); | |
177 State state = engine.getState(stateId); | |
178 | |
179 List<Output> list = state.getOutputs(); | |
180 if (list == null || list.size() == 0) { | |
181 continue; | |
182 } | |
183 | |
184 ProtocolUtils.appendOutputModes(creator, outs, list); | |
185 } | |
186 | |
187 try { | |
188 DefaultState cur = (DefaultState) getCurrentState(context); | |
189 if (cur.validate(this, context)) { | |
190 List<Output> list = cur.getOutputs(); | |
191 if (list != null && list.size() > 0) { | |
192 logger.debug( | |
193 "Append output modes for state: " + cur.getID()); | |
194 | |
195 ProtocolUtils.appendOutputModes(creator, outs, list); | |
196 } | |
197 } | |
198 } | |
199 catch (IllegalArgumentException iae) { | |
200 // state is not valid, so we do not append its outputs. | |
201 } | |
202 } | |
203 | |
204 | |
205 /** | |
206 * This method appends the static data - that has already been inserted by | |
207 * the user - to the static node of the DESCRIBE document. | |
208 * | |
209 * @param doc The document. | |
210 * @param ui The root node. | |
211 * @param context The CallContext. | |
212 * @param uuid The identifier of the artifact. | |
213 */ | |
214 protected void appendStaticUI( | |
215 Document doc, | |
216 Node ui, | |
217 CallContext context, | |
218 String uuid) | |
219 { | |
220 Vector<String> stateIds = getPreviousStateIds(); | |
221 | |
222 FLYSContext flysContext = getFlysContext(context); | |
223 StateEngine engine = (StateEngine) flysContext.get( | |
224 FLYSContext.STATE_ENGINE_KEY); | |
225 | |
226 for (String stateId: stateIds) { | |
227 logger.debug("Append static data for state: " + stateId); | |
228 DefaultState state = (DefaultState) engine.getState(stateId); | |
229 state = (DefaultState) fillState(state); | |
230 | |
231 ui.appendChild(state.describeStatic(doc, ui, context, uuid)); | |
232 } | |
233 } | |
234 | |
235 | |
236 // | |
237 // METHODS FOR RETRIEVING COMPUTED DATA FOR DIFFERENT CHART TYPES | |
238 // | |
239 | |
240 /** | |
241 * Returns the data that is computed by a waterlevel computation. | |
242 * | |
243 * @return an array of data triples that consist of W, Q and Kms. | |
244 */ | |
245 public WQKms[] getWaterlevelData() | |
246 throws NullPointerException | |
247 { | |
248 logger.debug("WINFOArtifact.getWaterlevelData"); | |
249 | |
250 River river = getRiver(); | |
251 if (river == null) { | |
252 throw new NullPointerException("No river selected."); | |
253 } | |
254 | |
255 double[] kms = getKms(); | |
256 if (kms == null) { | |
257 throw new NullPointerException("No Kms selected."); | |
258 } | |
259 | |
260 double[] qs = getQs(); | |
261 double[] ws = null; | |
262 boolean qSel = true; | |
263 | |
264 if (qs == null) { | |
265 logger.debug("Determine Q values based on a set of W values."); | |
266 qSel = false; | |
267 ws = getWs(); | |
268 qs = getQsForWs(ws); | |
269 } | |
270 | |
271 WstValueTable wst = WstValueTableFactory.getTable(river); | |
272 if (wst == null) { | |
273 throw new NullPointerException("No Wst found for selected river."); | |
274 } | |
275 | |
276 WQKms[] results = computeWaterlevelData(kms, qs, wst); | |
277 | |
278 // TODO Introduce a caching mechanism here! | |
279 | |
280 setWaterlevelNames(results, qSel ? qs : ws, qSel ? "Q" : "W"); | |
281 | |
282 return results; | |
283 } | |
284 | |
285 | |
286 /** | |
287 * Sets the name for waterlevels where each WQKms in <i>r</i> represents a | |
288 * column. | |
289 * | |
290 * @param r The waterlevel columns. | |
291 * @param v The input values of the computations. | |
292 * @param wq The WQ mode - can be one of "W" or "Q". | |
293 */ | |
294 public static void setWaterlevelNames(WQKms[] r, double[] v, String wq) { | |
295 for (int i = 0; i < v.length; i++) { | |
296 r[i].setName(wq + "=" + Double.toString(v[i])); | |
297 } | |
298 } | |
299 | |
300 | |
301 /** | |
302 * Computes the data of a waterlevel computation based on the interpolation | |
303 * in WstValueTable. | |
304 * | |
305 * @param kms The kilometer values. | |
306 * @param qa The discharge values. | |
307 * @param wst The WstValueTable used for the interpolation. | |
308 * | |
309 * @return an array of data triples that consist of W, Q and Kms. | |
310 */ | |
311 public static WQKms[] computeWaterlevelData( | |
312 double[] kms, | |
313 double[] qs, | |
314 WstValueTable wst) | |
315 { | |
316 logger.info("WINFOArtifact.computeWaterlevelData"); | |
317 | |
318 WQKms[] wqkms = new WQKms[qs.length]; | |
319 | |
320 ArrayList<WQKms> results = new ArrayList<WQKms>(); | |
321 | |
322 for (int i = 0; i < qs.length; i++) { | |
323 double [] oqs = new double[kms.length]; | |
324 double [] ows = new double[kms.length]; | |
325 int referenceIndex = 0; // TODO: Make depend on the flow direction | |
326 WstValueTable.QPosition qPosition = | |
327 wst.interpolate(qs[i], referenceIndex, kms, ows, oqs); | |
328 if (qPosition != null) { | |
329 results.add(new WQKms(kms, oqs, ows)); | |
330 } | |
331 else { | |
332 logger.warn("interpolation failed for q = " + qs[i]); | |
333 } | |
334 } | |
335 | |
336 return results.toArray(new WQKms[results.size()]); | |
337 } | |
338 | |
339 | |
340 /** | |
341 * Returns the data that is computed by a duration curve computation. | |
342 * | |
343 * @return the data computed by a duration curve computation. | |
344 */ | |
345 public WQDay getDurationCurveData() | |
346 throws NullPointerException | |
347 { | |
348 logger.debug("WINFOArtifact.getDurationCurveData"); | |
349 | |
350 River r = getRiver(); | |
351 | |
352 if (r == null) { | |
353 throw new NullPointerException("Cannot determine river."); | |
354 } | |
355 | |
356 Gauge g = getGauge(); | |
357 | |
358 if (g == null) { | |
359 throw new NullPointerException("Cannot determine gauge."); | |
360 } | |
361 | |
362 double[] locations = getLocations(); | |
363 | |
364 if (locations == null) { | |
365 throw new NullPointerException("Cannot determine location."); | |
366 } | |
367 | |
368 WstValueTable wst = WstValueTableFactory.getTable(r); | |
369 if (wst == null) { | |
370 throw new NullPointerException("No Wst found for selected river."); | |
371 } | |
372 | |
373 // TODO Introduce a caching mechanism here! | |
374 | |
375 return computeDurationCurveData(g, wst, locations[0]); | |
376 } | |
377 | |
378 | |
379 /** | |
380 * Computes the data used to create duration curves. | |
381 * | |
382 * @param gauge The selected gauge. | |
383 * @param location The selected location. | |
384 * | |
385 * @return the computed data. | |
386 */ | |
387 public static WQDay computeDurationCurveData( | |
388 Gauge gauge, | |
389 WstValueTable wst, | |
390 double location) | |
391 { | |
392 logger.info("WINFOArtifact.computeDurationCurveData"); | |
393 | |
394 Object[] obj = MainValuesFactory.getDurationCurveData(gauge); | |
395 | |
396 int[] days = (int[]) obj[0]; | |
397 double[] qs = (double[]) obj[1]; | |
398 | |
399 double[] interpolatedW = new double[qs.length]; | |
400 interpolatedW = wst.interpolateW(location, qs, interpolatedW); | |
401 | |
402 WQDay wqday = new WQDay(qs.length); | |
403 | |
404 for (int i = 0; i < days.length; i++) { | |
405 wqday.add(days[i], interpolatedW[i], qs[i]); | |
406 } | |
407 | |
408 return wqday; | |
409 } | |
410 | |
411 | |
412 /** | |
413 * Returns the data that is computed by a discharge curve computation. | |
414 * | |
415 * @return the data computed by a discharge curve computation. | |
416 */ | |
417 public WQKms getComputedDischargeCurveData() | |
418 throws NullPointerException | |
419 { | |
420 logger.debug("WINFOArtifact.getComputedDischargeCurveData"); | |
421 | |
422 River r = getRiver(); | |
423 | |
424 if (r == null) { | |
425 throw new NullPointerException("Cannot determine river."); | |
426 } | |
427 | |
428 double[] locations = getLocations(); | |
429 | |
430 if (locations == null) { | |
431 throw new NullPointerException("Cannot determine location."); | |
432 } | |
433 | |
434 WstValueTable wst = WstValueTableFactory.getTable(r); | |
435 if (wst == null) { | |
436 throw new NullPointerException("No Wst found for selected river."); | |
437 } | |
438 | |
439 WQKms wqkms = computeDischargeCurveData(wst, locations[0]); | |
440 | |
441 // TODO Introduce a caching mechanism here! | |
442 | |
443 setComputedDischargeCurveNames(wqkms, locations[0]); | |
444 | |
445 return wqkms; | |
446 } | |
447 | |
448 | |
449 /** | |
450 * Sets the name of the computed discharge curve data. | |
451 * | |
452 * @param wqkms The computed WQKms object. | |
453 * @param l The location used for the computation. | |
454 */ | |
455 public static void setComputedDischargeCurveNames(WQKms wqkms, double l) { | |
456 wqkms.setName(Double.toString(l)); | |
457 } | |
458 | |
459 | |
460 /** | |
461 * Computes the data used to create computed discharge curves. | |
462 * | |
463 * @param wst The WstValueTable that is used for the interpolation. | |
464 * @param location The location where the computation should be based on. | |
465 * | |
466 * @return an object that contains tuples of W/Q values at the specified | |
467 * location. | |
468 */ | |
469 public static WQKms computeDischargeCurveData( | |
470 WstValueTable wst, | |
471 double location) | |
472 { | |
473 logger.info("WINFOArtifact.computeDischargeCurveData"); | |
474 | |
475 double[][] wqs = wst.interpolateWQ(location); | |
476 | |
477 if (wqs == null) { | |
478 logger.error("Cannot compute discharge curve data."); | |
479 return null; | |
480 } | |
481 | |
482 double[] ws = wqs[0]; | |
483 double[] qs = wqs[1]; | |
484 | |
485 WQKms wqkms = new WQKms(ws.length); | |
486 | |
487 for (int i = 0; i < ws.length; i++) { | |
488 wqkms.add(ws[i], qs[i], location); | |
489 } | |
490 | |
491 return wqkms; | |
492 } | |
493 | |
494 /** | |
495 * Returns the data computed by the discharge longitudinal section | |
496 * computation. | |
497 * | |
498 * @return an array of WQKms object - one object for each given Q value. | |
499 */ | |
500 public WQKms [] getDischargeLongitudinalSectionData() { | |
501 | |
502 logger.debug("WINFOArtifact.getDischargeLongitudinalSectionData"); | |
503 | |
504 River river = getRiver(); | |
505 if (river == null) { | |
506 logger.error("No river selected."); | |
507 return new WQKms[0]; | |
508 } | |
509 | |
510 WstValueTable wst = WstValueTableFactory.getTable(river); | |
511 if (wst == null) { | |
512 logger.error("No wst found for selected river."); | |
513 return new WQKms[0]; | |
514 } | |
515 | |
516 double [][] segments = getSplittedDistance(); | |
517 | |
518 if (segments.length < 1) { | |
519 logger.warn("no segments given"); | |
520 return new WQKms[0]; | |
521 } | |
522 | |
523 if (segments.length == 1) { | |
524 // fall back to normal "Wasserstand/Wasserspiegellage" calculation | |
525 double [] qs = toQs(segments[0]); | |
526 if (qs == null) { | |
527 logger.warn("no qs given"); | |
528 return new WQKms[0]; | |
529 } | |
530 if (qs.length == 1) { | |
531 double [] kms = getKms(segments[0]); | |
532 return computeWaterlevelData(kms, qs, wst); | |
533 } | |
534 } | |
535 | |
536 // more than one segment | |
537 | |
538 double [] boundKms; | |
539 | |
540 if (segments.length == 2) { | |
541 boundKms = new double [] { segments[0][0], segments[1][1] }; | |
542 } | |
543 else { | |
544 TDoubleArrayList bounds = new TDoubleArrayList(); | |
545 | |
546 bounds.add(segments[0][0]); | |
547 | |
548 for (int i = 1; i < segments.length-1; ++i) { | |
549 double [] segment = segments[i]; | |
550 | |
551 Gauge gauge = river.determineGauge(segment[0], segment[1]); | |
552 | |
553 if (gauge == null) { | |
554 logger.warn("no gauge found between " + | |
555 segment[0] + " and " + segment[1]); | |
556 bounds.add(0.5*(segment[0] + segment[1])); | |
557 } | |
558 else { | |
559 bounds.add(gauge.getStation().doubleValue()); | |
560 } | |
561 } | |
562 | |
563 bounds.add(segments[segments.length-1][1]); | |
564 boundKms = bounds.toNativeArray(); | |
565 } | |
566 | |
567 if (logger.isDebugEnabled()) { | |
568 logger.debug("bound kms: " + joinDoubles(boundKms)); | |
569 } | |
570 | |
571 double [][] iqs = null; | |
572 | |
573 for (int i = 0; i < segments.length; ++i) { | |
574 double [] iqsi = toQs(segments[i]); | |
575 if (iqsi == null) { | |
576 logger.warn("iqsi == null"); | |
577 return new WQKms[0]; | |
578 } | |
579 | |
580 if (iqs == null) { | |
581 iqs = new double[iqsi.length][boundKms.length]; | |
582 } | |
583 else if (iqs.length != iqsi.length) { | |
584 logger.warn("iqsi.logger != iqs.length: " | |
585 + iqsi.length + " " + iqsi.length); | |
586 return new WQKms[0]; | |
587 } | |
588 | |
589 if (logger.isDebugEnabled()) { | |
590 logger.debug("segments qs[ " + i + "]: " + joinDoubles(iqsi)); | |
591 } | |
592 | |
593 for (int j = 0; j < iqs.length; ++j) { | |
594 iqs[j][i] = iqsi[j]; | |
595 } | |
596 } | |
597 | |
598 if (logger.isDebugEnabled()) { | |
599 for (int i = 0; i < iqs.length; ++i) { | |
600 logger.debug("iqs[" + i + "]: " + joinDoubles(iqs[i])); | |
601 } | |
602 } | |
603 | |
604 double [] boundWs = new double[boundKms.length]; | |
605 double [] boundQs = new double[boundKms.length]; | |
606 | |
607 double [] okms = getKms(new double [] { | |
608 boundKms[0], boundKms[boundKms.length-1] }); | |
609 | |
610 ArrayList<WQKms> results = new ArrayList<WQKms>(); | |
611 | |
612 for (int i = 0; i < iqs.length; ++i) { | |
613 double [] iqsi = iqs[i]; | |
614 | |
615 QPosition qPosition = wst.interpolate( | |
616 iqsi[0], 0, boundKms, boundWs, boundQs); | |
617 | |
618 if (qPosition == null) { | |
619 logger.warn("interpolation failed for " + iqsi[i]); | |
620 continue; | |
621 } | |
622 | |
623 LinearRemap remap = new LinearRemap(); | |
624 | |
625 for (int j = 1; j < boundKms.length; ++j) { | |
626 remap.add( | |
627 boundKms[j-1], boundKms[j], | |
628 boundQs[j-1], iqsi[j-1], | |
629 boundQs[j], iqsi[j]); | |
630 } | |
631 | |
632 double [] oqs = new double[okms.length]; | |
633 double [] ows = new double[okms.length]; | |
634 | |
635 wst.interpolate(okms, ows, oqs, qPosition, remap); | |
636 | |
637 BackJumpCorrector bjc = new BackJumpCorrector(); | |
638 if (bjc.doCorrection(okms, ows)) { | |
639 logger.debug("Discharge longitudinal section has backjumps."); | |
640 results.add(new WQCKms(okms, oqs, ows, bjc.getCorrected())); | |
641 } | |
642 else { | |
643 results.add(new WQKms(okms, oqs, ows)); | |
644 } | |
645 } | |
646 | |
647 WQKms [] wqkms = results.toArray(new WQKms[results.size()]); | |
648 | |
649 setDischargeLongitudinalSectionNames(wqkms, iqs, isQ() ? "Q" : "W"); | |
650 | |
651 return wqkms; | |
652 } | |
653 | |
654 protected static String joinDoubles(double [] x) { | |
655 if (x == null) { | |
656 return ""; | |
657 } | |
658 StringBuilder sb = new StringBuilder(); | |
659 for (int i = 0; i < x.length; ++i) { | |
660 if (i > 0) sb.append(", "); | |
661 sb.append(x[i]); | |
662 } | |
663 return sb.toString(); | |
664 } | |
665 | |
666 protected double [] toQs(double [] range) { | |
667 double [] qs = getQs(range); | |
668 if (qs == null) { | |
669 logger.debug("Determine Q values based on a set of W values."); | |
670 double [] ws = getWs(range); | |
671 qs = getQsForWs(ws); | |
672 } | |
673 return qs; | |
674 } | |
675 | |
676 | |
677 /** | |
678 * Sets the name for discharge longitudinal section curves where each WQKms | |
679 * in <i>r</i> represents a column. | |
680 */ | |
681 public static void setDischargeLongitudinalSectionNames( | |
682 WQKms [] wqkms, | |
683 double [][] iqs, | |
684 String wq | |
685 ) { | |
686 logger.debug("WINFOArtifact.setDischargeLongitudinalSectionNames"); | |
687 | |
688 // TODO: I18N | |
689 | |
690 for (int j = 0; j < wqkms.length; ++j) { | |
691 StringBuilder sb = new StringBuilder(wq) | |
692 .append(" benutzerdefiniert ("); | |
693 | |
694 double [] iqsi = iqs[j]; | |
695 for (int i = 0; i < iqsi.length; i++) { | |
696 if (i > 0) { | |
697 sb.append("; "); | |
698 } | |
699 sb.append(iqsi[i]); | |
700 } | |
701 sb.append(")"); | |
702 | |
703 wqkms[j].setName(sb.toString()); | |
704 } | |
705 } | |
706 } | |
707 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |