Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/utils/FLYSUtils.java @ 3468:f37e7e8907cb
merged flys-artifacts/2.8.1
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:39 +0200 |
parents | f903f1e5aed6 |
children | 8490faba00e7 |
comparison
equal
deleted
inserted
replaced
3387:5ffad8bde8ad | 3468:f37e7e8907cb |
---|---|
1 package de.intevation.flys.utils; | |
2 | |
3 import org.apache.log4j.Logger; | |
4 | |
5 import java.text.NumberFormat; | |
6 import java.util.HashMap; | |
7 import java.util.List; | |
8 import java.util.Map; | |
9 import java.util.regex.Matcher; | |
10 import java.util.regex.Pattern; | |
11 | |
12 import javax.xml.xpath.XPathConstants; | |
13 | |
14 import org.w3c.dom.Document; | |
15 | |
16 import org.hibernate.SessionFactory; | |
17 import org.hibernate.impl.SessionFactoryImpl; | |
18 | |
19 import gnu.trove.TDoubleArrayList; | |
20 import gnu.trove.TIntArrayList; | |
21 import gnu.trove.TLongArrayList; | |
22 | |
23 import de.intevation.artifacts.Artifact; | |
24 import de.intevation.artifacts.CallContext; | |
25 | |
26 import de.intevation.artifacts.common.utils.Config; | |
27 import de.intevation.artifacts.common.utils.XMLUtils; | |
28 | |
29 import de.intevation.flys.backend.SessionFactoryProvider; | |
30 | |
31 import de.intevation.flys.artifacts.context.FLYSContext; | |
32 import de.intevation.flys.artifacts.FLYSArtifact; | |
33 import de.intevation.flys.artifacts.WINFOArtifact; | |
34 import de.intevation.flys.artifacts.StaticWKmsArtifact; | |
35 import de.intevation.flys.artifacts.model.RiverFactory; | |
36 import de.intevation.flys.artifacts.model.LocationProvider; | |
37 import de.intevation.flys.artifacts.model.WQ; | |
38 import de.intevation.flys.artifacts.model.WKms; | |
39 import de.intevation.flys.artifacts.model.WQKms; | |
40 | |
41 import de.intevation.artifactdatabase.state.State; | |
42 import de.intevation.flys.artifacts.states.WaterlevelSelectState; | |
43 import de.intevation.flys.artifacts.states.WDifferencesState; | |
44 import de.intevation.flys.model.Gauge; | |
45 import de.intevation.flys.model.MainValue; | |
46 import de.intevation.flys.model.River; | |
47 | |
48 | |
49 /** static helper methods to e.g. access FLYSArtifacts data. */ | |
50 public class FLYSUtils { | |
51 | |
52 /** The logger that is used in this utility. */ | |
53 private static Logger logger = Logger.getLogger(FLYSUtils.class); | |
54 | |
55 public static enum KM_MODE { RANGE, LOCATIONS, NONE }; | |
56 | |
57 /** | |
58 * An enum that represents the 5 possible WQ modes in FLYS. The 5 values are | |
59 * <i>QFREE</i> <i>QGAUGE</i> <i>WGAUGE</i> <i>WFREE</i> and <i>NONE</i>. | |
60 */ | |
61 public static enum WQ_MODE { QFREE, QGAUGE, WFREE, WGAUGE, NONE }; | |
62 | |
63 /** | |
64 * An enum that represents the 4 possible WQ input modes in FLYS. The 4 | |
65 * values are | |
66 * <i>ADAPTED</i> <i>SINGLE</i> <i>RANGE</i> and <i>NONE</i>. | |
67 */ | |
68 public static enum WQ_INPUT { ADAPTED, SINGLE, RANGE, NONE }; | |
69 | |
70 public static final Pattern NUMBERS_PATTERN = | |
71 Pattern.compile("\\D*(\\d++.\\d*)\\D*"); | |
72 | |
73 public static final String XPATH_RIVER_PROJECTION = | |
74 "/artifact-database/floodmap/river[@name=$name]/srid/@value"; | |
75 | |
76 public static final String XPATH_SHAPEFILE_DIR = | |
77 "/artifact-database/floodmap/shapefile-path/@value"; | |
78 | |
79 public static final String XPATH_VELOCITY_LOGFILE = | |
80 "/artifact-database/floodmap/velocity/logfile/@path"; | |
81 | |
82 public static final String XPATH_MAPSERVER_URL = | |
83 "/artifact-database/floodmap/mapserver/server/@path"; | |
84 | |
85 public static final String XPATH_MAPFILE_PATH = | |
86 "/artifact-database/floodmap/mapserver/mapfile/@path"; | |
87 | |
88 public static final String XPATH_MAPFILE_TEMPLATE = | |
89 "/artifact-database/floodmap/mapserver/map-template/@path"; | |
90 | |
91 public static final String XPATH_MAPSERVER_TEMPLATE_PATH = | |
92 "/artifact-database/floodmap/mapserver/templates/@path"; | |
93 | |
94 | |
95 private FLYSUtils() { | |
96 } | |
97 | |
98 | |
99 /** | |
100 * Pulls Artifact with given UUID fromm database. | |
101 * @return FLYSArtifact with given UUID or null (in case of errors). | |
102 */ | |
103 public static FLYSArtifact getArtifact(String uuid, CallContext context) { | |
104 try { | |
105 Artifact artifact = context.getDatabase().getRawArtifact(uuid); | |
106 | |
107 if (artifact == null) { | |
108 logger.error("Artifact '" + uuid + "' does not exist."); | |
109 return null; | |
110 } | |
111 | |
112 if (!(artifact instanceof FLYSArtifact)) { | |
113 logger.error("Artifact '" +uuid+ "' is no valid FLYSArtifact."); | |
114 return null; | |
115 } | |
116 | |
117 return (FLYSArtifact) artifact; | |
118 } | |
119 // TODO: catch more selective | |
120 catch (Exception e) { | |
121 logger.error("Cannot get FLYSArtifact " + uuid | |
122 + " from database (" + e.getMessage() + ")."); | |
123 return null; | |
124 } | |
125 } | |
126 | |
127 | |
128 /** | |
129 * Returns the FLYSContext from context object. | |
130 * | |
131 * @param context The CallContext or the FLYSContext. | |
132 * | |
133 * @return the FLYSContext. | |
134 */ | |
135 public static FLYSContext getFlysContext(Object context) { | |
136 return context instanceof FLYSContext | |
137 ? (FLYSContext) context | |
138 : (FLYSContext) ((CallContext) context).globalContext(); | |
139 } | |
140 | |
141 | |
142 /** | |
143 * Convinience function to retrieve an XPath as string with replaced config | |
144 * directory. | |
145 * | |
146 * @param xpath The XPath expression. | |
147 * | |
148 * @return a string with replaced config directory. | |
149 */ | |
150 public static String getXPathString(String xpath) { | |
151 String tmp = Config.getStringXPath(xpath); | |
152 tmp = Config.replaceConfigDir(tmp); | |
153 | |
154 return tmp; | |
155 } | |
156 | |
157 | |
158 public static boolean isUsingOracle() { | |
159 SessionFactory sf = SessionFactoryProvider.getSessionFactory(); | |
160 | |
161 String d = SessionFactoryProvider.getDriver((SessionFactoryImpl) sf); | |
162 | |
163 return d != null ? d.indexOf("Oracle") >= 0 : false; | |
164 } | |
165 | |
166 | |
167 /** | |
168 * This method returns an WQ_MODE enum which is based on the parameters | |
169 * stored in <i>flys</i> Artifact. If there is no <i>wq_isq</i> parameter | |
170 * existing, WQ_MODE.NONE is returned. | |
171 * | |
172 * @param flys The FLYSArtifact that stores wq mode relevant parameters. | |
173 * | |
174 * @return an enum WQ_MODE. | |
175 */ | |
176 public static WQ_MODE getWQMode(FLYSArtifact flys) { | |
177 if (flys == null) { | |
178 return WQ_MODE.NONE; | |
179 } | |
180 | |
181 String values = flys.getDataAsString("wq_values"); | |
182 Boolean isQ = flys.getDataAsBoolean("wq_isq"); | |
183 | |
184 if (values != null) { | |
185 return isQ ? WQ_MODE.QGAUGE : WQ_MODE.WGAUGE; | |
186 } | |
187 | |
188 Boolean isFree = flys.getDataAsBoolean("wq_isfree"); | |
189 | |
190 if (isQ) { | |
191 return isFree ? WQ_MODE.QFREE : WQ_MODE.QGAUGE; | |
192 } | |
193 else if (!isQ) { | |
194 return isFree ? WQ_MODE.WFREE : WQ_MODE.WGAUGE; | |
195 } | |
196 else { | |
197 return WQ_MODE.NONE; | |
198 } | |
199 } | |
200 | |
201 | |
202 public static WQ_INPUT getWQInputMode(FLYSArtifact flys) { | |
203 if (flys == null) { | |
204 return WQ_INPUT.NONE; | |
205 } | |
206 | |
207 Boolean selection = flys.getDataAsBoolean("wq_isrange"); | |
208 String adapted = flys.getDataAsString("wq_values"); | |
209 | |
210 if(adapted != null && adapted.length() > 0) { | |
211 return WQ_INPUT.ADAPTED; | |
212 } | |
213 | |
214 if (selection != null && selection) { | |
215 return WQ_INPUT.RANGE; | |
216 } | |
217 else { | |
218 return WQ_INPUT.SINGLE; | |
219 } | |
220 } | |
221 | |
222 public static KM_MODE getKmRangeMode(FLYSArtifact flys) { | |
223 String mode = flys.getDataAsString("ld_mode"); | |
224 | |
225 if (mode == null || mode.length() == 0) { | |
226 return KM_MODE.NONE; | |
227 } | |
228 else if (mode.equals("distance")) { | |
229 return KM_MODE.RANGE; | |
230 } | |
231 else if (mode.equals("locations")) { | |
232 return KM_MODE.LOCATIONS; | |
233 } | |
234 else { | |
235 return KM_MODE.NONE; | |
236 } | |
237 } | |
238 | |
239 /** | |
240 * Get min and max kilometer, independent of parametization | |
241 * (ld_from/to vs ld_locations). | |
242 */ | |
243 public static double[] getKmRange(FLYSArtifact flys) { | |
244 switch (getKmRangeMode(flys)) { | |
245 case RANGE: { | |
246 return getKmFromTo(flys); | |
247 } | |
248 | |
249 case LOCATIONS: { | |
250 double[] locs = getLocations(flys); | |
251 return new double[] { locs[0], locs[locs.length-1] }; | |
252 } | |
253 | |
254 case NONE: { | |
255 double[] locs = getLocations(flys); | |
256 if (locs != null) { | |
257 return new double[] { locs[0], locs[locs.length-1] }; | |
258 } | |
259 else { | |
260 return getKmFromTo(flys); | |
261 } | |
262 } | |
263 } | |
264 | |
265 return new double[] { Double.NaN, Double.NaN }; | |
266 } | |
267 | |
268 | |
269 /** | |
270 * Get bounds for river of artifact. | |
271 * @param flysArtifact artifact which has a "river" data. | |
272 * @return double array. min is at[0], max at[1]. null if given artifact is null | |
273 */ | |
274 public static double[] getRiverMinMax(FLYSArtifact flysArtifact) { | |
275 if (flysArtifact == null) { | |
276 return null; | |
277 } | |
278 | |
279 String riverName = flysArtifact.getDataAsString("river"); | |
280 | |
281 if (riverName == null) { | |
282 riverName = ""; | |
283 } | |
284 | |
285 logger.debug("Search for the min/max distances of '" + riverName + "'"); | |
286 | |
287 River river = RiverFactory.getRiver(riverName); | |
288 | |
289 return river != null | |
290 ? river.determineMinMaxDistance() | |
291 : null; | |
292 } | |
293 | |
294 | |
295 public static double[] getKmFromTo(FLYSArtifact flys) { | |
296 String strFrom = flys.getDataAsString("ld_from"); | |
297 String strTo = flys.getDataAsString("ld_to"); | |
298 | |
299 if (strFrom == null) { | |
300 strFrom = flys.getDataAsString("from"); | |
301 } | |
302 | |
303 if (strTo == null) { | |
304 strTo = flys.getDataAsString("to"); | |
305 } | |
306 | |
307 if (strFrom == null || strTo == null) { | |
308 return null; | |
309 } | |
310 | |
311 try { | |
312 return new double[] { | |
313 Double.parseDouble(strFrom), | |
314 Double.parseDouble(strTo) }; | |
315 } | |
316 catch (NumberFormatException nfe) { | |
317 return null; | |
318 } | |
319 } | |
320 | |
321 | |
322 /** | |
323 * Return sorted array of locations at which stuff was calculated | |
324 * (from ld_locations data), null if not parameterized this way. | |
325 */ | |
326 public static double[] getLocations(FLYSArtifact flys) { | |
327 String locationStr = flys.getDataAsString("ld_locations"); | |
328 | |
329 if (locationStr == null || locationStr.length() == 0) { | |
330 if (flys instanceof WINFOArtifact) { | |
331 WINFOArtifact winfo = (WINFOArtifact) flys; | |
332 if (winfo.getReferenceStartKm() != null) { | |
333 return new double[] | |
334 { | |
335 winfo.getReferenceStartKm().doubleValue(), | |
336 winfo.getReferenceEndKms()[0] | |
337 }; | |
338 } | |
339 } | |
340 return null; | |
341 } | |
342 | |
343 String[] tmp = locationStr.split(" "); | |
344 TDoubleArrayList locations = new TDoubleArrayList(); | |
345 | |
346 for (String l: tmp) { | |
347 try { | |
348 locations.add(Double.parseDouble(l)); | |
349 } | |
350 catch (NumberFormatException nfe) { | |
351 } | |
352 } | |
353 | |
354 locations.sort(); | |
355 | |
356 return locations.toNativeArray(); | |
357 } | |
358 | |
359 | |
360 /** | |
361 * Returns the Qs for a given FLYSArtifact. This method currently accepts | |
362 * only instances of WINFOArtifact. | |
363 * | |
364 * @param flys A FLYSArtifact. | |
365 * | |
366 * @return the Qs. | |
367 */ | |
368 public static double[] getQs(FLYSArtifact flys) { | |
369 // XXX this is not nice! | |
370 if (flys instanceof WINFOArtifact) { | |
371 return ((WINFOArtifact) flys).getQs(); | |
372 } | |
373 | |
374 logger.warn("This method currently supports WINFOArtifact only!"); | |
375 | |
376 return null; | |
377 } | |
378 | |
379 | |
380 /** | |
381 * Returns the Ws for a given FLYSArtifact. This method currently accepts | |
382 * only instances of WINFOArtifact. | |
383 * | |
384 * @param flys A FLYSArtifact. | |
385 * | |
386 * @return the Ws. | |
387 */ | |
388 public static double[] getWs(FLYSArtifact flys) { | |
389 // XXX this is not nice! | |
390 if (flys instanceof WINFOArtifact) { | |
391 return ((WINFOArtifact) flys).getWs(); | |
392 } | |
393 | |
394 logger.warn("This method currently supports WINFOArtifact only!"); | |
395 | |
396 return null; | |
397 } | |
398 | |
399 | |
400 /** | |
401 * Returns the selected River object based on the 'river' data that might | |
402 * have been inserted by the user. | |
403 * | |
404 * @return the selected River or null if no river has been chosen yet. | |
405 */ | |
406 public static River getRiver(FLYSArtifact flys) { | |
407 String sRiver = getRivername(flys); | |
408 | |
409 return (sRiver != null) | |
410 ? RiverFactory.getRiver(sRiver) | |
411 : null; | |
412 } | |
413 | |
414 | |
415 /** | |
416 * Returns the name of the river specified in the given <i>flys</i> | |
417 * Artifact. | |
418 * | |
419 * @param flys The FLYSArtifact that stores a river relevant information. | |
420 * | |
421 * @return the name of the specified river or null. | |
422 */ | |
423 public static String getRivername(FLYSArtifact flys) { | |
424 return flys != null ? flys.getDataAsString("river") : null; | |
425 } | |
426 | |
427 | |
428 /** | |
429 * Extracts the SRID defined in the global configuration for the river | |
430 * specified in <i>artifact</i>. | |
431 * | |
432 * @param artifact The FLYSArtifact that stores the name of the river. | |
433 * | |
434 * @return the SRID as string (e.g. "31466"). | |
435 */ | |
436 public static String getRiverSrid(FLYSArtifact artifact) { | |
437 String river = artifact.getDataAsString("river"); | |
438 | |
439 if (river == null || river.length() == 0) { | |
440 return null; | |
441 } | |
442 | |
443 return getRiverSrid(river); | |
444 } | |
445 | |
446 | |
447 public static String getRiverSrid(String rivername) { | |
448 Map<String, String> variables = new HashMap<String, String>(1); | |
449 variables.put("name", rivername); | |
450 | |
451 Document cfg = Config.getConfig(); | |
452 | |
453 return (String) XMLUtils.xpath( | |
454 cfg, | |
455 XPATH_RIVER_PROJECTION, | |
456 XPathConstants.STRING, | |
457 null, | |
458 variables); | |
459 } | |
460 | |
461 | |
462 /** | |
463 * Return the (first) Gauge corresponding to the given location(s) of | |
464 * the artifact. | |
465 * @param flys the artifact in question. | |
466 * @return (First) gauge of locations of river of artifact. | |
467 */ | |
468 public static Gauge getGauge(FLYSArtifact flys) { | |
469 River river = getRiver(flys); | |
470 | |
471 if (river == null) { | |
472 logger.debug("no river found"); | |
473 return null; | |
474 } | |
475 | |
476 double[] dist = getKmRange(flys); | |
477 | |
478 if (dist == null) { | |
479 logger.debug("no range found"); | |
480 return null; | |
481 } | |
482 | |
483 if (logger.isDebugEnabled()) { | |
484 logger.debug("Determine gauge for:"); | |
485 logger.debug("... river: " + river.getName()); | |
486 logger.debug("... distance: " + dist[0] + " - " + dist[1]); | |
487 } | |
488 | |
489 Gauge gauge = river.determineGauge(dist[0], dist[1]); | |
490 | |
491 String name = gauge != null ? gauge.getName() : "'n/a"; | |
492 logger.debug("Found gauge: " + name); | |
493 | |
494 return gauge; | |
495 } | |
496 | |
497 | |
498 public static String getGaugename(FLYSArtifact flys) { | |
499 Gauge gauge = getGauge(flys); | |
500 | |
501 return gauge != null ? gauge.getName() : null; | |
502 } | |
503 | |
504 | |
505 public static Gauge getReferenceGauge(FLYSArtifact flys) { | |
506 Long officialNumber = flys.getDataAsLong("reference_gauge"); | |
507 | |
508 return officialNumber != null | |
509 ? Gauge.getGaugeByOfficialNumber(officialNumber) | |
510 : null; | |
511 } | |
512 | |
513 | |
514 public static String getReferenceGaugeName(FLYSArtifact flys) { | |
515 Gauge refGauge = getReferenceGauge(flys); | |
516 | |
517 return refGauge != null | |
518 ? refGauge.getName() | |
519 : "-- not found --"; | |
520 } | |
521 | |
522 | |
523 public static Double getValueFromWQ(WQ wq) { | |
524 if (wq == null) { | |
525 return null; | |
526 } | |
527 | |
528 Matcher m = NUMBERS_PATTERN.matcher(wq.getName()); | |
529 | |
530 if (m.matches()) { | |
531 logger.debug("Found a number."); | |
532 | |
533 String raw = m.group(1); | |
534 | |
535 try { | |
536 return Double.valueOf(raw); | |
537 } | |
538 catch (NumberFormatException nfe) { | |
539 } | |
540 } | |
541 | |
542 return null; | |
543 } | |
544 | |
545 | |
546 public static String createWspWTitle( | |
547 WINFOArtifact winfo, | |
548 CallContext cc, | |
549 String name | |
550 ) { | |
551 String[] parts = name.split("="); | |
552 | |
553 NumberFormat nf = Formatter.getWaterlevelW(cc); | |
554 | |
555 String namedMainValue = null; | |
556 | |
557 boolean isQ = winfo.isQ(); | |
558 boolean isFree = winfo.isFreeQ(); | |
559 | |
560 double v; | |
561 | |
562 try { | |
563 v = Double.valueOf(parts[1]); | |
564 | |
565 namedMainValue = getNamedMainValue(winfo.getGauge(), v); | |
566 } | |
567 catch (NumberFormatException nfe) { | |
568 logger.warn("Cannot parse Double of: '" + parts[1] + "'"); | |
569 return name; | |
570 } | |
571 | |
572 String prefix = null; | |
573 | |
574 if (isQ && !isFree && namedMainValue != null) { | |
575 return "W (" + namedMainValue + ")"; | |
576 } | |
577 | |
578 if (isQ) { | |
579 prefix = "Q="; | |
580 } | |
581 | |
582 return prefix == null | |
583 ? "W(" + nf.format(v) + ")" | |
584 : "W(" + prefix + nf.format(v) + ")"; | |
585 } | |
586 | |
587 | |
588 public static String createWspQTitle( | |
589 WINFOArtifact winfo, | |
590 CallContext cc, | |
591 String name | |
592 ) { | |
593 String[] parts = name.split("="); | |
594 | |
595 NumberFormat nf = Formatter.getWaterlevelQ(cc); | |
596 | |
597 String namedMainValue = null; | |
598 | |
599 boolean isQ = winfo.isQ(); | |
600 boolean isFree = winfo.isFreeQ(); | |
601 | |
602 double v; | |
603 | |
604 try { | |
605 v = Double.valueOf(parts[1]); | |
606 | |
607 namedMainValue = getNamedMainValue(winfo.getGauge(), v); | |
608 } | |
609 catch (NumberFormatException nfe) { | |
610 logger.warn("Cannot parse Double of: '" + parts[1] + "'"); | |
611 return name; | |
612 } | |
613 | |
614 String prefix = null; | |
615 | |
616 if (isQ && !isFree && namedMainValue != null) { | |
617 return namedMainValue; | |
618 } | |
619 | |
620 if (!isQ) { | |
621 prefix = "W="; | |
622 } | |
623 | |
624 return prefix == null | |
625 ? "Q(" + nf.format(v) + ")" | |
626 : "Q(" + prefix + nf.format(v) + ")"; | |
627 } | |
628 | |
629 | |
630 /** | |
631 * Returns the named main value if a Q was selected and if this Q fits to a | |
632 * named main value. Otherwise, this function returns null. | |
633 * | |
634 * @param winfo The WINFO Artifact. | |
635 * @param value The Q (or W) value. | |
636 * | |
637 * @return a named main value or null. | |
638 */ | |
639 public static String getNamedMainValue(WINFOArtifact winfo, double value) { | |
640 WQ_MODE wqmode = getWQMode(winfo); | |
641 | |
642 if (wqmode != WQ_MODE.QGAUGE) { | |
643 return null; | |
644 } | |
645 else { | |
646 return getNamedMainValue(winfo.getGauge(), value); | |
647 } | |
648 } | |
649 | |
650 | |
651 public static String getNamedMainValue(Gauge gauge, double value) { | |
652 List<MainValue> mainValues = gauge.getMainValues(); | |
653 logger.debug("Search named main value for: " + value); | |
654 | |
655 for (MainValue mv: mainValues) { | |
656 if (mv.getValue().doubleValue() == value) { | |
657 logger.debug("Found named main value: " + mv.getMainValue().getName()); | |
658 return mv.getMainValue().getName(); | |
659 } | |
660 } | |
661 | |
662 logger.debug("Did not find a named main value for: " + value); | |
663 return null; | |
664 } | |
665 | |
666 | |
667 /** | |
668 * | |
669 * @param nmv A string that represents a named main value. | |
670 * | |
671 * @throws NullPointerException if nmv is null. | |
672 */ | |
673 public static String stripNamedMainValue(String nmv) { | |
674 int startIndex = nmv.indexOf("("); | |
675 int endIndex = nmv.indexOf(")"); | |
676 | |
677 if (startIndex > 0 && endIndex > 0 && startIndex < endIndex) { | |
678 return nmv.substring(0, startIndex); | |
679 } | |
680 | |
681 return nmv; | |
682 } | |
683 | |
684 | |
685 /** | |
686 * Returns the URL of user mapfile for the owner of Artifact | |
687 * <i>artifactId</i>. | |
688 * | |
689 * @param artifactId The UUID of an artifact. | |
690 * | |
691 * @return the URL of the user wms. | |
692 */ | |
693 public static String getUserWMSUrl(String artifactId) { | |
694 String url = getXPathString(XPATH_MAPSERVER_URL); | |
695 url = url.endsWith("/") ? url + "user-wms" : url + "/" + "user-wms"; | |
696 | |
697 return url; | |
698 } | |
699 | |
700 | |
701 /** | |
702 * This method returns the description for a given <i>km</i> for a specific | |
703 * river. The river is provided by the FLYSArtifact <i>flys</i>. | |
704 * | |
705 * @param flys The FLYSArtifact that provides a river. | |
706 * @param km The kilometer. | |
707 * | |
708 * @return the description for <i>km</i> or an empty string if no | |
709 * description was found. | |
710 */ | |
711 public static String getLocationDescription(FLYSArtifact flys, double km) { | |
712 String river = getRivername(flys); | |
713 | |
714 if (river == null) { | |
715 return ""; | |
716 } | |
717 | |
718 return LocationProvider.getLocation(river, km); | |
719 } | |
720 | |
721 | |
722 /** | |
723 * This method returns the differences for a w-differences calculation. | |
724 * | |
725 * @param winfo The WINFOArtifact. | |
726 * @param context The context. | |
727 * | |
728 * @return The differences as string separated by semicolon and linebreak. | |
729 */ | |
730 public static String getWDifferences( | |
731 WINFOArtifact winfo, | |
732 CallContext context) | |
733 { | |
734 State state = winfo.getCurrentState(context); | |
735 if(state instanceof WDifferencesState) { | |
736 String diffids = winfo.getDataAsString("diffids"); | |
737 String datas[] = diffids.split("#"); | |
738 | |
739 // Validate the Data-Strings. | |
740 for (String s: datas) { | |
741 if (!WaterlevelSelectState.isValueValid(winfo.getDataAsString("diffids"))) { | |
742 return ""; | |
743 } | |
744 } | |
745 | |
746 if (datas.length < 2) { | |
747 return ""; | |
748 } | |
749 | |
750 String diffs = ""; | |
751 for(int i = 0; i < datas.length; i+=2) { | |
752 // e.g.: | |
753 // 42537f1e-3522-42ef-8968-635b03d8e9c6;longitudinal_section.w;1 | |
754 WKms minuendWKms = getWKms(StringUtil.unbracket(datas[i+0]), | |
755 context); | |
756 WKms subtrahendWKms = getWKms(StringUtil.unbracket(datas[i+1]), | |
757 context); | |
758 if (minuendWKms != null && subtrahendWKms != null) { | |
759 diffs += StringUtil.wWrap(minuendWKms.getName()) | |
760 + " - " + StringUtil.wWrap(subtrahendWKms.getName()); | |
761 } | |
762 diffs += ";\n"; | |
763 } | |
764 return diffs; | |
765 } | |
766 else { | |
767 logger.warn("Not a valid state for differences."); | |
768 return ""; | |
769 } | |
770 } | |
771 | |
772 | |
773 protected static WKms getWKms(String mingle, CallContext context) { | |
774 String[] def = mingle.split(";"); | |
775 String uuid = def[0]; | |
776 String name = def[1]; | |
777 int idx = Integer.parseInt(def[2]); | |
778 | |
779 if (name.startsWith("staticwkms")) { | |
780 StaticWKmsArtifact staticWKms = | |
781 (StaticWKmsArtifact) FLYSUtils.getArtifact( | |
782 uuid, | |
783 context); | |
784 WKms wkms = staticWKms.getWKms(idx); | |
785 if (wkms == null) | |
786 logger.error("No WKms from artifact."); | |
787 return wkms; | |
788 } | |
789 | |
790 WINFOArtifact flys = (WINFOArtifact) FLYSUtils.getArtifact( | |
791 uuid, | |
792 context); | |
793 | |
794 if (flys == null) { | |
795 logger.warn("One of the artifacts (1) for diff calculation could not be loaded"); | |
796 return null; | |
797 } | |
798 else{ | |
799 WQKms[] wqkms = (WQKms[]) flys.getWaterlevelData(). | |
800 getData(); | |
801 if (wqkms == null) | |
802 logger.warn("not waterlevels in artifact"); | |
803 else if (wqkms.length < idx) | |
804 logger.warn("not enough waterlevels in artifact"); | |
805 return wqkms[idx]; | |
806 } | |
807 } | |
808 | |
809 | |
810 /** | |
811 * This method transform a string into an int array. Therefore, the string | |
812 * <i>raw</i> must consist of int values separated by a <i>';'</i>. | |
813 * | |
814 * @param raw The raw integer array as string separated by a ';'. | |
815 * | |
816 * @return an array of int values. | |
817 */ | |
818 public static int[] intArrayFromString(String raw) { | |
819 String[] splitted = raw != null ? raw.split(";") : null; | |
820 | |
821 if (splitted == null || splitted.length == 0) { | |
822 logger.warn("No integer values found in '" + raw + "'"); | |
823 return new int[0]; | |
824 } | |
825 | |
826 TIntArrayList integers = new TIntArrayList(splitted.length); | |
827 | |
828 for (String value: splitted) { | |
829 try { | |
830 integers.add(Integer.parseInt(value)); | |
831 } | |
832 catch (NumberFormatException nfe) { | |
833 logger.warn("Parsing integer failed: " + nfe); | |
834 } | |
835 } | |
836 | |
837 return integers.toNativeArray(); | |
838 } | |
839 | |
840 | |
841 /** | |
842 * This method transform a string into a long array. Therefore, the string | |
843 * <i>raw</i> must consist of int values separated by a <i>';'</i>. | |
844 * | |
845 * @param raw The raw long array as string separated by a ';'. | |
846 * | |
847 * @return an array of int values. | |
848 */ | |
849 public static long[] longArrayFromString(String raw) { | |
850 String[] splitted = raw != null ? raw.split(";") : null; | |
851 | |
852 if (splitted == null || splitted.length == 0) { | |
853 logger.warn("No long values found in '" + raw + "'"); | |
854 return new long[0]; | |
855 } | |
856 | |
857 TLongArrayList longs = new TLongArrayList(splitted.length); | |
858 | |
859 for (String value: splitted) { | |
860 try { | |
861 longs.add(Long.valueOf(value)); | |
862 } | |
863 catch (NumberFormatException nfe) { | |
864 logger.warn("Parsing long failed: " + nfe); | |
865 } | |
866 } | |
867 | |
868 return longs.toNativeArray(); | |
869 } | |
870 | |
871 | |
872 /** | |
873 * This method transform a string into an double array. Therefore, the | |
874 * string <i>raw</i> must consist of double values separated by a | |
875 * <i>';'</i>. | |
876 * | |
877 * @param raw The raw double array as string separated by a ';'. | |
878 * | |
879 * @return an array of double values. | |
880 */ | |
881 public static double[] doubleArrayFromString(String raw) { | |
882 String[] splitted = raw != null ? raw.split(";") : null; | |
883 | |
884 if (splitted == null || splitted.length == 0) { | |
885 logger.warn("No double values found in '" + raw + "'"); | |
886 return new double[0]; | |
887 } | |
888 | |
889 TDoubleArrayList doubles = new TDoubleArrayList(splitted.length); | |
890 | |
891 for (String value: splitted) { | |
892 try { | |
893 doubles.add(Double.valueOf(value)); | |
894 } | |
895 catch (NumberFormatException nfe) { | |
896 logger.warn("Parsing double failed: " + nfe); | |
897 } | |
898 } | |
899 | |
900 return doubles.toNativeArray(); | |
901 } | |
902 | |
903 | |
904 /** | |
905 * Returns the gauges that match the selected kilometer range. | |
906 * | |
907 * @param flys the flys artifact. | |
908 * | |
909 * @return the gauges based on the selected kilometer range (null if | |
910 * none/no range set). | |
911 */ | |
912 public static List<Gauge> getGauges(FLYSArtifact flys) { | |
913 | |
914 River river = getRiver(flys); | |
915 if (river == null) { | |
916 logger.debug("getGauges: no river!"); | |
917 return null; | |
918 } | |
919 | |
920 double [] dist = getKmRange(flys); | |
921 if (dist == null) { | |
922 logger.debug("getGauges: no dist!"); | |
923 return null; | |
924 } | |
925 logger.debug("getGauges: " + dist[0] + " - " + dist[1]); | |
926 | |
927 return river.determineGauges(dist[0], dist[1]); | |
928 } | |
929 } | |
930 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |