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