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 :

http://dive4elements.wald.intevation.org