001 /*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2013
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 *
010 * All Rights Reserved
011 *
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.
014 *
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 *
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023 * GNU Lesser Public License for more details.
024 *
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program. If not, see http://www.gnu.org/licenses.
027 */
028
029 package edu.wisc.ssec.mcidasv.data.cyclone;
030
031 import java.io.File;
032 import java.sql.Connection;
033 import java.sql.DriverManager;
034 import java.sql.ResultSet;
035 import java.sql.SQLException;
036 import java.sql.Statement;
037 import java.util.ArrayList;
038 import java.util.Calendar;
039 import java.util.GregorianCalendar;
040 import java.util.HashMap;
041 import java.util.Hashtable;
042 import java.util.List;
043 import java.util.Map;
044
045 import ucar.unidata.data.BadDataException;
046 import ucar.unidata.data.DataSourceDescriptor;
047 import ucar.unidata.data.DataUtil;
048 import ucar.unidata.sql.SqlUtil;
049 import ucar.unidata.util.DateUtil;
050 import ucar.unidata.util.IOUtil;
051 import ucar.unidata.util.Misc;
052 import ucar.visad.Util;
053 import visad.CommonUnit;
054 import visad.DateTime;
055 import visad.Real;
056 import visad.RealType;
057 import visad.VisADException;
058 import visad.georef.EarthLocation;
059 import visad.georef.EarthLocationLite;
060
061 /**
062 * Created by IntelliJ IDEA. User: yuanho Date: Apr 9, 2008 Time: 4:58:27 PM To
063 * change this template use File | Settings | File Templates.
064 */
065 public class STIStormDataSource extends StormDataSource {
066
067 /** _more_ */
068 private static final Way DEFAULT_OBSERVATION_WAY = new Way("babj");
069
070 /* Use this for mysql: */
071
072 /** _more_ */
073 private static final String DEFAULT_URL = "jdbc:mysql://localhost:3306/typhoon?zeroDateTimeBehavior=convertToNull&user=yuanho&password=password";
074
075 // private static final String DEFAULT_URL =
076 // "jdbc:mysql://localhost:3306/typhoon?zeroDateTimeBehavior=convertToNull&user=yuanho&password=password";
077
078 /** _more_ */
079 private static final String DEFAULT_DERBY_URL = "jdbc:derby:test;create=true";
080
081 /** _more_ */
082 private static final String COL_DERBY_HOUR = "hh";
083
084 /** _more_ */
085 private static final String COL_DERBY_YEAR = "yyyy";
086
087 /**
088 * _more_
089 *
090 * @return _more_
091 */
092 private boolean useDerby() {
093 if ((dbUrl != null) && (dbUrl.indexOf("derby") >= 0)) {
094 return true;
095 }
096 return false;
097 }
098
099 /**
100 * _more_
101 *
102 * @return _more_
103 */
104 public String getId() {
105 return "sti";
106 }
107
108 /**
109 * _more_
110 *
111 * @return _more_
112 */
113 private String getColHour() {
114 if (useDerby()) {
115 return COL_DERBY_HOUR;
116 }
117 return COL_TYPHOON_HOUR;
118 }
119
120 /**
121 * _more_
122 *
123 * @return _more_
124 */
125 private String getColYear() {
126 if (useDerby()) {
127 return COL_DERBY_YEAR;
128 }
129 return COL_TYPHOON_YEAR;
130 }
131
132 /** _more_ */
133 public static StormParam PARAM_MAXWINDSPEED;
134
135 /** _more_ */
136 public static StormParam PARAM_RADIUSMODERATEGALE;
137
138 /** _more_ */
139 public static StormParam PARAM_RADIUSWHOLEGALE;
140
141 /** _more_ */
142 public static StormParam PARAM_PROBABILITY10RADIUS;
143
144 /** _more_ */
145 public static StormParam PARAM_PROBABILITY20RADIUS;
146
147 /** _more_ */
148 public static StormParam PARAM_PROBABILITY30RADIUS;
149
150 /** _more_ */
151 public static StormParam PARAM_PROBABILITY40RADIUS;
152
153 /** _more_ */
154 public static StormParam PARAM_PROBABILITY50RADIUS;
155
156 /** _more_ */
157 public static StormParam PARAM_PROBABILITY60RADIUS;
158
159 /** _more_ */
160 public static StormParam PARAM_PROBABILITY70RADIUS;
161
162 /** _more_ */
163 public static StormParam PARAM_PROBABILITY80RADIUS;
164
165 /** _more_ */
166 public static StormParam PARAM_PROBABILITY90RADIUS;
167
168 /** _more_ */
169 public static StormParam PARAM_DISTANCE_ERROR;
170
171 /** _more_ */
172 public static StormParam PARAM_PROBABILITY100RADIUS;
173
174 /** _more_ */
175 public static StormParam PARAM_PROBABILITYRADIUS;
176
177 /** _more_ */
178 public static StormParam PARAM_MOVEDIRECTION;
179
180 /** _more_ */
181 public static StormParam PARAM_MOVESPEED;
182
183 /** _more_ */
184 private static float MISSING = 9999.0f;
185
186 /** _more_ */
187 private static final String ZEROHOUR = "0";
188
189 /** _more_ */
190 private static final String TABLE_TRACK = "typhoon";
191
192 /** _more_ */
193 private static final String COL_TYPHOON_YEAR = "year";
194
195 /** _more_ */
196 private static final String COL_TYPHOON_HOUR = "hour";
197 /**/
198
199 /** _more_ */
200 private static final String COL_TYPHOON_STORMID = "nno";
201
202 /** _more_ */
203 private static final String COL_TYPHOON_TIME = "time";
204
205 /** _more_ */
206 private static final String COL_TYPHOON_LATITUDE = "lat";
207
208 /** _more_ */
209 private static final String COL_TYPHOON_LONGITUDE = "lon";
210
211 /** _more_ */
212 private static final String COL_TYPHOON_MONTH = "mon";
213
214 /** _more_ */
215 private static final String COL_TYPHOON_DAY = "day";
216
217 /** _more_ */
218 private static final String COL_TYPHOON_FHOUR = "fhour";
219
220 /** _more_ */
221 private static final String COL_TYPHOON_WAY = "way";
222
223 /** _more_ */
224 private static final String COL_TYPHOON_PRESSURE = "pressure";
225
226 /** _more_ */
227 private static final String COL_TYPHOON_WINDSPEED = "wind";
228
229 /** _more_ */
230 private static final String COL_TYPHOON_RADIUSMG = "xx1";
231
232 /** _more_ */
233 private static final String COL_TYPHOON_RADIUSWG = "xx2";
234
235 /** _more_ */
236 private static final String COL_TYPHOON_MOVEDIR = "xx3";
237
238 /** _more_ */
239 private static final String COL_TYPHOON_MOVESPEED = "xx4";
240
241 /** _more_ */
242 private static final String TABLE_PROBILITY = "probility";
243
244 /** _more_ */
245 private static final String COL_PROBILITY_WAYNAME = "wayname";
246
247 /** _more_ */
248 private static final String COL_PROBILITY_FHOUR = "fhour";
249
250 /** _more_ */
251 private static final String COL_PROBILITY_P10 = "p10";
252
253 /** _more_ */
254 private static final String COL_PROBILITY_P20 = "p20";
255
256 /** _more_ */
257 private static final String COL_PROBILITY_P30 = "p30";
258
259 /** _more_ */
260 private static final String COL_PROBILITY_P40 = "p40";
261
262 /** _more_ */
263 private static final String COL_PROBILITY_P50 = "p50";
264
265 /** _more_ */
266 private static final String COL_PROBILITY_P60 = "p60";
267
268 /** _more_ */
269 private static final String COL_PROBILITY_P70 = "p70";
270
271 /** _more_ */
272 private static final String COL_PROBILITY_P80 = "p80";
273
274 /** _more_ */
275 private static final String COL_PROBILITY_P90 = "p90";
276
277 /** _more_ */
278 private static final String COL_PROBILITY_P100 = "p100";
279
280 /** _more_ */
281 private static final String COL_DISTANCE_ERROR = "error";
282
283 /** _more_ */
284 private static final String COL_PROBILITY_REMARK = "remark";
285
286 /** _more_ */
287 private String dbUrl;
288
289 /** the db connection */
290 private Connection connection;
291
292 /** _more_ */
293 private String fromDate = "-1 year";
294
295 /** _more_ */
296 private String toDate = "now";
297
298 /** the stormInfo and track */
299 private List<StormInfo> stormInfos;
300
301 /** _more_ */
302 private HashMap<String, float[]> wayfhourToRadius;
303
304 /**
305 * constructor of sti storm data source
306 *
307 *
308 * @throws Exception
309 * _more_
310 */
311
312 public STIStormDataSource() throws Exception {
313 }
314
315 /**
316 * _more_
317 *
318 * @return _more_
319 */
320 public boolean isEditable() {
321 return true;
322 }
323
324 static {
325 try {
326 // TODO: Make sure these are the right units
327 PARAM_MAXWINDSPEED = new StormParam(makeRealType("maxwindspeed",
328 "Max_Windspeed", Util.parseUnit("m/s")));
329 PARAM_RADIUSMODERATEGALE = new StormParam(makeRealType(
330 "radiusmoderategale", "Radius_of_Beaufort_Scale7", DataUtil
331 .parseUnit("km")));
332 PARAM_RADIUSWHOLEGALE = new StormParam(makeRealType(
333 "radiuswholegale", "Radius_of_Beaufort_Scale10", DataUtil
334 .parseUnit("km")));
335 PARAM_MOVEDIRECTION = new StormParam(makeRealType("movedirection",
336 "Storm_Direction", CommonUnit.degree));
337 PARAM_MOVESPEED = new StormParam(makeRealType("movespeed",
338 "Storm_Speed", Util.parseUnit("m/s")));
339
340 PARAM_PROBABILITY10RADIUS = new StormParam(makeRealType(
341 "probabilityradius10", "Probability_10%_Radius", DataUtil
342 .parseUnit("km")), true, false, false);
343 PARAM_PROBABILITY20RADIUS = new StormParam(makeRealType(
344 "probabilityradius20", "Probability_20%_Radius", DataUtil
345 .parseUnit("km")), true, false, false);
346 PARAM_PROBABILITY30RADIUS = new StormParam(makeRealType(
347 "probabilityradius30", "Probability_30%_Radius", DataUtil
348 .parseUnit("km")), true, false, false);
349 PARAM_PROBABILITY40RADIUS = new StormParam(makeRealType(
350 "probabilityradius40", "Probability_40%_Radius", DataUtil
351 .parseUnit("km")), true, false, false);
352 PARAM_PROBABILITY50RADIUS = new StormParam(makeRealType(
353 "probabilityradius50", "Probability_50%_Radius", DataUtil
354 .parseUnit("km")), true, false, false);
355 PARAM_PROBABILITY60RADIUS = new StormParam(makeRealType(
356 "probabilityradius60", "Probability_60%_Radius", DataUtil
357 .parseUnit("km")), true, false, false);
358 PARAM_PROBABILITY70RADIUS = new StormParam(makeRealType(
359 "probabilityradius70", "Probability_70%_Radius", DataUtil
360 .parseUnit("km")), true, false, false);
361 PARAM_PROBABILITY80RADIUS = new StormParam(makeRealType(
362 "probabilityradius80", "Probability_80%_Radius", DataUtil
363 .parseUnit("km")), true, false, false);
364 PARAM_PROBABILITY90RADIUS = new StormParam(makeRealType(
365 "probabilityradius90", "Probability_90%_Radius", DataUtil
366 .parseUnit("km")), true, false, false);
367 PARAM_PROBABILITY100RADIUS = new StormParam(makeRealType(
368 "probabilityradius100", "Probability_100%_Radius", DataUtil
369 .parseUnit("km")), true, false, false);
370 PARAM_DISTANCE_ERROR = new StormParam(makeRealType(
371 "meanDistanceError", "Mean_Distance_Error", DataUtil
372 .parseUnit("km")), true, false, false);
373 } catch (Exception exc) {
374 System.err.println("Error creating storm params:" + exc);
375 exc.printStackTrace();
376
377 }
378 }
379
380 /**
381 * _more_
382 *
383 * @throws VisADException
384 * _more_
385 */
386 protected void initParams() throws VisADException {
387 super.initParams();
388
389 obsParams = new StormParam[] { PARAM_MAXWINDSPEED, PARAM_MINPRESSURE,
390 PARAM_RADIUSMODERATEGALE, PARAM_RADIUSWHOLEGALE,
391 PARAM_MOVEDIRECTION, PARAM_MOVESPEED };
392
393 forecastParams = new StormParam[] {
394 PARAM_MAXWINDSPEED,
395 PARAM_MINPRESSURE,
396 PARAM_RADIUSMODERATEGALE,
397 PARAM_RADIUSWHOLEGALE,
398 PARAM_MOVEDIRECTION,
399 PARAM_MOVESPEED, // PARAM_DISTANCEERROR,
400 PARAM_PROBABILITY10RADIUS, PARAM_PROBABILITY20RADIUS,
401 PARAM_PROBABILITY30RADIUS, PARAM_PROBABILITY40RADIUS,
402 PARAM_PROBABILITY50RADIUS, PARAM_PROBABILITY60RADIUS,
403 PARAM_PROBABILITY70RADIUS, PARAM_PROBABILITY80RADIUS,
404 PARAM_PROBABILITY90RADIUS, PARAM_PROBABILITY100RADIUS,
405 PARAM_DISTANCE_ERROR };
406 }
407
408 /**
409 * _more_
410 *
411 * @param descriptor
412 * _more_
413 * @param url
414 * _more_
415 * @param properties
416 * _more_
417 *
418 * @throws Exception
419 * _more_
420 */
421 public STIStormDataSource(DataSourceDescriptor descriptor, String url,
422 Hashtable properties) throws Exception {
423 super(descriptor, "STI Storm Data", "STI Storm Data", properties);
424 if ((url != null) && url.trim().equals("test")) {
425 url = DEFAULT_DERBY_URL;
426 }
427 if ((url == null) || url.trim().equalsIgnoreCase("default")
428 || (url.trim().length() == 0)) {
429 url = (useDerby() ? DEFAULT_DERBY_URL : DEFAULT_URL);
430 }
431 dbUrl = url;
432 }
433
434 /**
435 * _more_
436 */
437 protected void initializeStormData() {
438 try {
439 initParams();
440 File userDir = getDataContext().getIdv().getObjectStore()
441 .getUserDirectory();
442 String derbyDir = IOUtil.joinDir(userDir, "derbydb");
443 IOUtil.makeDirRecursive(new File(derbyDir));
444 System.setProperty("derby.system.home", derbyDir);
445
446 Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
447 Class.forName("com.mysql.jdbc.Driver");
448 if (!initConnection()) {
449 setInError(true, true,
450 "Unable to initialize database connection:" + dbUrl);
451 } else {
452 stormInfos = getAllStormInfos();
453 }
454 } catch (Exception exc) {
455 logException("Error initializing STI database: " + dbUrl, exc);
456 }
457 }
458
459 /**
460 * _more_
461 *
462 * @return _more_
463 */
464 public List<StormInfo> getStormInfos() {
465 List<StormInfo> sInfos = new ArrayList();
466 sInfos.addAll(stormInfos);
467 return sInfos;
468 }
469
470 /**
471 * _more_
472 *
473 * @param stormInfo
474 * _more_
475 * @param waysToUse
476 * _more_
477 * @param observationWay
478 * _more_
479 *
480 * @return _more_
481 *
482 * @throws Exception
483 * _more_
484 */
485
486 public StormTrackCollection getTrackCollectionInner(StormInfo stormInfo,
487 Hashtable<String, Boolean> waysToUse, Way observationWay)
488 throws Exception {
489 if (observationWay == null) {
490 observationWay = DEFAULT_OBSERVATION_WAY;
491 }
492
493 long t1 = System.currentTimeMillis();
494 StormTrackCollection trackCollection = new StormTrackCollection();
495 List<Way> forecastWays = getForecastWays(stormInfo);
496
497 getWayProbabilityRadius();
498 for (Way forecastWay : forecastWays) {
499 if ((waysToUse != null) && (waysToUse.size() > 0)
500 && (waysToUse.get(forecastWay.getId()) == null)) {
501 continue;
502 }
503 List forecastTracks = getForecastTracks(stormInfo, forecastWay);
504 if (forecastTracks.size() > 0) {
505 trackCollection.addTrackList(forecastTracks);
506 }
507 }
508 StormTrack obsTrack = getObservationTrack(stormInfo, observationWay);
509 // (Way) forecastWays.get(0));
510 if (obsTrack != null) {
511 List<StormTrack> tracks = trackCollection.getTracks();
512 // for (StormTrack stk : tracks) {
513 // addDistanceError(obsTrack, stk);
514 // }
515 long t2 = System.currentTimeMillis();
516 // System.err.println("time:" + (t2 - t1));
517 trackCollection.addTrack(obsTrack);
518 }
519 return trackCollection;
520 }
521
522 /**
523 * _more_
524 *
525 *
526 *
527 * @param stormInfo
528 * _more_
529 * @param forecastWay
530 * _more_
531 *
532 * @return _more_
533 * @throws Exception
534 * _more_
535 */
536 private List<StormTrack> getForecastTracks(StormInfo stormInfo,
537 Way forecastWay) throws Exception {
538
539 List<StormTrack> tracks = new ArrayList<StormTrack>();
540 List<DateTime> startDates = getForecastTrackStartDates(stormInfo,
541 forecastWay);
542
543 int nstarts = startDates.size();
544 for (int i = 0; i < nstarts; i++) {
545 DateTime dt = (DateTime) startDates.get(i);
546 StormTrack tk = getForecastTrack(stormInfo, dt, forecastWay);
547 if (tk != null) {
548 int pn = tk.getTrackPoints().size();
549 // Why > 1???
550 if (pn > 1) {
551 tracks.add(tk);
552 }
553 }
554 }
555 return tracks;
556
557 }
558
559 /**
560 * If d is a missing value return NaN. Else return d
561 *
562 * @param d
563 * is checked if not missing return same value
564 * @param name
565 * _more_
566 *
567 * @return _more_
568 */
569
570 public double getValue(double d, String name) {
571 if ((d == 9999) || (d == 999)) {
572 return Double.NaN;
573 }
574
575 if (name.equalsIgnoreCase(PARAM_MAXWINDSPEED.getName())) {
576 if ((d < 0) || (d > 60)) {
577 return Double.NaN;
578 }
579 } else if (name.equalsIgnoreCase(PARAM_MINPRESSURE.getName())) {
580 if ((d < 800) || (d > 1050)) {
581 return Double.NaN;
582 }
583 } else if (name.equalsIgnoreCase(PARAM_RADIUSMODERATEGALE.getName())) {
584 if ((d < 0) || (d > 900)) {
585 return Double.NaN;
586 }
587 } else if (name.equalsIgnoreCase(PARAM_RADIUSWHOLEGALE.getName())) {
588 if ((d < 0) || (d > 500)) {
589 return Double.NaN;
590 }
591 } else if (name.equalsIgnoreCase(PARAM_MOVESPEED.getName())) {
592 if ((d < 0) || (d > 55)) {
593 return Double.NaN;
594 }
595 } else if (name.equalsIgnoreCase(PARAM_MOVEDIRECTION.getName())) {
596 if ((d < 0) || (d > 360)) {
597 return Double.NaN;
598 }
599 }
600
601 return d;
602 }
603
604 /**
605 * _more_
606 *
607 * @param d
608 * _more_
609 *
610 * @return _more_
611 */
612 public double getLatLonValue(double d) {
613 if ((d == 9999) || (d == 999)) {
614 return Double.NaN;
615 }
616 return d;
617 }
618
619 /**
620 * _more_
621 *
622 *
623 *
624 * @param stormInfo
625 * _more_
626 * @param sTime
627 * _more_
628 * @param forecastWay
629 * _more_
630 *
631 * @return _more_
632 * @throws Exception
633 * _more_
634 */
635 private StormTrack getForecastTrack(StormInfo stormInfo, DateTime sTime,
636 Way forecastWay) throws Exception {
637
638 // if(true) return getForecastTrackX(stormInfo, sTime, forecastWay);
639 String columns = SqlUtil.comma(new String[] { getColYear(),
640 COL_TYPHOON_MONTH, COL_TYPHOON_DAY, getColHour(),
641 COL_TYPHOON_FHOUR, COL_TYPHOON_LATITUDE, COL_TYPHOON_LONGITUDE,
642 COL_TYPHOON_WINDSPEED, COL_TYPHOON_PRESSURE,
643 COL_TYPHOON_RADIUSMG, COL_TYPHOON_RADIUSWG,
644 COL_TYPHOON_MOVEDIR, COL_TYPHOON_MOVESPEED });
645
646 List whereList = new ArrayList();
647 whereList.add(SqlUtil.eq(COL_TYPHOON_STORMID, SqlUtil.quote(stormInfo
648 .getStormId())));
649 whereList.add(SqlUtil.eq(COL_TYPHOON_WAY, SqlUtil.quote(forecastWay
650 .getId())));
651
652 addDateSelection(sTime, whereList);
653
654 String query = SqlUtil.makeSelect(columns, Misc.newList(TABLE_TRACK),
655 SqlUtil.makeAnd(whereList));
656 query = query
657 + " order by "
658 + SqlUtil.comma(new String[] { getColYear(), COL_TYPHOON_MONTH,
659 COL_TYPHOON_DAY, getColHour(), COL_TYPHOON_FHOUR });
660 // System.err.println (query);
661 Statement statement = evaluate(query);
662 SqlUtil.Iterator iter = SqlUtil.getIterator(statement);
663 ResultSet results;
664 double radius = 0;
665 List<StormTrackPoint> pts = new ArrayList();
666
667 Real altReal = new Real(RealType.Altitude, 0);
668 while ((results = iter.getNext()) != null) {
669 // System.err.println ("row " + cnt);
670 List<Real> attrs = new ArrayList<Real>();
671 int col = 1;
672 int year = results.getInt(col++);
673 int month = results.getInt(col++);
674 int day = results.getInt(col++);
675 int hour = results.getInt(col++);
676 int fhour = results.getInt(col++);
677
678 double latitude = getLatLonValue(results.getDouble(col++));
679 if ((latitude > 90) || (latitude < -90)) {
680 continue;
681 }
682 double longitude = getLatLonValue(results.getDouble(col++));
683 if ((longitude > 360) || (longitude < -180)) {
684 continue;
685 }
686 attrs.add(PARAM_MAXWINDSPEED.getReal(getValue(results
687 .getDouble(col++), PARAM_MAXWINDSPEED.getName())));
688 attrs.add(PARAM_MINPRESSURE.getReal(getValue(results
689 .getDouble(col++), PARAM_MINPRESSURE.getName())));
690 attrs.add(PARAM_RADIUSMODERATEGALE.getReal(getValue(results
691 .getDouble(col++), PARAM_RADIUSMODERATEGALE.getName())));
692 attrs.add(PARAM_RADIUSWHOLEGALE.getReal(getValue(results
693 .getDouble(col++), PARAM_RADIUSWHOLEGALE.getName())));
694 attrs.add(PARAM_MOVEDIRECTION.getReal(getValue(results
695 .getDouble(col++), PARAM_MOVEDIRECTION.getName())));
696 attrs.add(PARAM_MOVESPEED.getReal(getValue(
697 results.getDouble(col++), PARAM_MOVESPEED.getName())));
698 float[] radiuses = getProbabilityRadius(forecastWay, fhour);
699 DateTime dttm = getDateTime(year, month, day, hour + fhour);
700 EarthLocation elt = new EarthLocationLite(new Real(
701 RealType.Latitude, latitude), new Real(RealType.Longitude,
702 longitude), altReal);
703 if (true) { // radiuses != null) {
704 // radius = fhour * 50.0f / 24.0f;
705 addProbabilityRadiusAttrs(attrs, radiuses);
706 }
707 StormTrackPoint stp = new StormTrackPoint(elt, dttm, fhour, attrs);
708 if (!elt.isMissing()) {
709 pts.add(stp);
710 }
711 }
712
713 if (pts.size() == 0) {
714 // We should never be here
715 System.err.println("found no track data time=" + sTime
716 + " from query:" + SqlUtil.makeAnd(whereList));
717 }
718 if (pts.size() > 0) {
719 return new StormTrack(stormInfo, forecastWay, pts, forecastParams);
720 } else {
721 return null;
722 }
723
724 }
725
726 /**
727 * _more_
728 *
729 * @param way
730 * _more_
731 * @param forecastHour
732 * _more_
733 *
734 * @return _more_
735 */
736 private float[] getProbabilityRadius(Way way, int forecastHour) {
737 String key = way.getId().toUpperCase() + forecastHour;
738 // System.out.println("get:" + key + " "
739 // +(wayfhourToRadius.get(key)!=null));
740 return wayfhourToRadius.get(key);
741 }
742
743 /**
744 * _more_
745 *
746 * @param way
747 * _more_
748 * @param forecastHour
749 * _more_
750 * @param radiuses
751 * _more_
752 */
753 private void putProbabilityRadius(Way way, int forecastHour,
754 float[] radiuses) {
755 String key = way.getId().toUpperCase() + forecastHour;
756 // System.out.println("put:" + key);
757 wayfhourToRadius.put(key, radiuses);
758 }
759
760 /**
761 * _more_
762 *
763 * @param attrs
764 * _more_
765 * @param radiuses
766 * _more_
767 *
768 * @throws Exception
769 * _more_
770 */
771 private void addProbabilityRadiusAttrs(List<Real> attrs, float[] radiuses)
772 throws Exception {
773 if (radiuses != null) {
774 attrs.add(PARAM_PROBABILITY10RADIUS.getReal(radiuses[0]));
775 attrs.add(PARAM_PROBABILITY20RADIUS.getReal(radiuses[1]));
776 attrs.add(PARAM_PROBABILITY30RADIUS.getReal(radiuses[2]));
777 attrs.add(PARAM_PROBABILITY40RADIUS.getReal(radiuses[3]));
778 attrs.add(PARAM_PROBABILITY50RADIUS.getReal(radiuses[4]));
779 attrs.add(PARAM_PROBABILITY60RADIUS.getReal(radiuses[5]));
780 attrs.add(PARAM_PROBABILITY70RADIUS.getReal(radiuses[6]));
781 attrs.add(PARAM_PROBABILITY80RADIUS.getReal(radiuses[7]));
782 attrs.add(PARAM_PROBABILITY90RADIUS.getReal(radiuses[8]));
783 attrs.add(PARAM_PROBABILITY100RADIUS.getReal(radiuses[9]));
784 attrs.add(PARAM_DISTANCE_ERROR
785 .getReal(getLatLonValue(radiuses[10])));
786 } else {
787 attrs.add(PARAM_PROBABILITY10RADIUS.getReal(Float.NaN));
788 attrs.add(PARAM_PROBABILITY20RADIUS.getReal(Float.NaN));
789 attrs.add(PARAM_PROBABILITY30RADIUS.getReal(Float.NaN));
790 attrs.add(PARAM_PROBABILITY40RADIUS.getReal(Float.NaN));
791 attrs.add(PARAM_PROBABILITY50RADIUS.getReal(Float.NaN));
792 attrs.add(PARAM_PROBABILITY60RADIUS.getReal(Float.NaN));
793 attrs.add(PARAM_PROBABILITY70RADIUS.getReal(Float.NaN));
794 attrs.add(PARAM_PROBABILITY80RADIUS.getReal(Float.NaN));
795 attrs.add(PARAM_PROBABILITY90RADIUS.getReal(Float.NaN));
796 attrs.add(PARAM_PROBABILITY100RADIUS.getReal(Float.NaN));
797 attrs.add(PARAM_DISTANCE_ERROR.getReal(Float.NaN));
798
799 }
800 }
801
802 /**
803 * _more_
804 *
805 * @param sTime
806 * _more_
807 * @param whereList
808 * _more_
809 *
810 * @throws VisADException
811 * _more_
812 */
813 private void addDateSelection(DateTime sTime, List whereList)
814 throws VisADException {
815 GregorianCalendar cal = new GregorianCalendar(DateUtil.TIMEZONE_GMT);
816 cal.setTime(ucar.visad.Util.makeDate(sTime));
817 int yy = cal.get(Calendar.YEAR);
818 // The MONTH is 0 based. The db month is 1 based
819 int mm = cal.get(Calendar.MONTH) + 1;
820 int dd = cal.get(Calendar.DAY_OF_MONTH);
821 int hh = cal.get(Calendar.HOUR_OF_DAY);
822 whereList.add(SqlUtil.eq(getColYear(), Integer.toString(yy)));
823 whereList.add(SqlUtil.eq(COL_TYPHOON_MONTH, Integer.toString(mm)));
824 whereList.add(SqlUtil.eq(COL_TYPHOON_DAY, Integer.toString(dd)));
825 whereList.add(SqlUtil.eq(getColHour(), Integer.toString(hh)));
826 }
827
828 /**
829 * _more_
830 *
831 * @param year
832 * _more_
833 * @param month
834 * _more_
835 * @param day
836 * _more_
837 * @param hour
838 * _more_
839 *
840 * @return _more_
841 *
842 * @throws Exception
843 * _more_
844 */
845 private DateTime getDateTime(int year, int month, int day, int hour)
846 throws Exception {
847 GregorianCalendar convertCal = new GregorianCalendar(
848 DateUtil.TIMEZONE_GMT);
849 convertCal.clear();
850 convertCal.set(Calendar.YEAR, year);
851 // The MONTH is 0 based. The incoming month is 1 based
852 convertCal.set(Calendar.MONTH, month - 1);
853 convertCal.set(Calendar.DAY_OF_MONTH, day);
854 convertCal.set(Calendar.HOUR_OF_DAY, hour);
855 return new DateTime(convertCal.getTime());
856 }
857
858 /**
859 * _more_
860 *
861 *
862 *
863 * @param stormInfo
864 * _more_
865 * @param way
866 * _more_
867 *
868 * @return _more_
869 * @throws Exception
870 * _more_
871 */
872 protected List<DateTime> getForecastTrackStartDates(StormInfo stormInfo,
873 Way way) throws Exception {
874
875 String columns = SqlUtil.comma(new String[] { getColYear(),
876 COL_TYPHOON_MONTH, COL_TYPHOON_DAY, getColHour() });
877
878 List whereList = new ArrayList();
879 whereList.add(SqlUtil.eq(COL_TYPHOON_STORMID, SqlUtil.quote(stormInfo
880 .getStormId())));
881 whereList.add(SqlUtil.eq(COL_TYPHOON_FHOUR, ZEROHOUR));
882 whereList.add(SqlUtil.eq(COL_TYPHOON_WAY, SqlUtil.quote(way.getId())));
883
884 String query = SqlUtil.makeSelect(columns, Misc.newList(TABLE_TRACK),
885 SqlUtil.makeAnd(whereList));
886 query = query
887 + " order by "
888 + SqlUtil.comma(new String[] { getColYear(), COL_TYPHOON_MONTH,
889 COL_TYPHOON_DAY, getColHour() });
890 // System.err.println (query);
891 Statement statement = evaluate(query);
892 SqlUtil.Iterator iter = SqlUtil.getIterator(statement);
893 ResultSet results;
894 List<DateTime> startDates = new ArrayList<DateTime>();
895 while ((results = iter.getNext()) != null) {
896 int col = 1;
897 int year = results.getInt(col++);
898 int month = results.getInt(col++);
899 int day = results.getInt(col++);
900 int hour = results.getInt(col++);
901 startDates.add(getDateTime(year, month, day, hour));
902 }
903 return startDates;
904 }
905
906 /**
907 * _more_
908 *
909 *
910 * @throws Exception
911 * _more_
912 */
913 protected void getWayProbabilityRadius() throws Exception {
914
915 String columns = SqlUtil.comma(new String[] { COL_PROBILITY_WAYNAME,
916 COL_PROBILITY_FHOUR, COL_PROBILITY_P10, COL_PROBILITY_P20,
917 COL_PROBILITY_P30, COL_PROBILITY_P40, COL_PROBILITY_P50,
918 COL_PROBILITY_P60, COL_PROBILITY_P70, COL_PROBILITY_P80,
919 COL_PROBILITY_P90, COL_PROBILITY_P100, COL_DISTANCE_ERROR });
920
921 List whereList = new ArrayList();
922
923 String query = SqlUtil.makeSelect(columns, Misc
924 .newList(TABLE_PROBILITY), SqlUtil.makeAnd(whereList));
925 Statement statement = evaluate(query);
926 SqlUtil.Iterator iter = SqlUtil.getIterator(statement);
927 ResultSet results;
928 wayfhourToRadius = new HashMap();
929 while ((results = iter.getNext()) != null) {
930 float[] wp = new float[11];
931 int col = 1;
932 String wayName = results.getString(col++);
933 int fhour = results.getInt(col++);
934 wp[0] = results.getFloat(col++);
935 wp[1] = results.getFloat(col++);
936 wp[2] = results.getFloat(col++);
937 wp[3] = results.getFloat(col++);
938 wp[4] = results.getFloat(col++);
939 wp[5] = results.getFloat(col++);
940 wp[6] = results.getFloat(col++);
941 wp[7] = results.getFloat(col++);
942 wp[8] = results.getFloat(col++);
943 wp[9] = results.getFloat(col++);
944 wp[10] = results.getFloat(col++);
945 putProbabilityRadius(new Way(wayName), fhour, wp);
946 }
947 }
948
949 /**
950 * _more_
951 *
952 * @param stormInfo
953 * _more_
954 * @param observationWay
955 * _more_
956 *
957 * @return _more_
958 *
959 * @throws Exception
960 * _more_
961 */
962 protected StormTrack getObservationTrack(StormInfo stormInfo,
963 Way observationWay) throws Exception {
964 addWay(observationWay);
965 // first get the obs from one specific way
966 List<StormTrackPoint> obsTrackPoints = getObservationTrackPoints(
967 stormInfo, observationWay);
968
969 if (obsTrackPoints.size() == 0) {
970 return null;
971 }
972
973 return new StormTrack(stormInfo, addWay(Way.OBSERVATION),
974 obsTrackPoints, obsParams);
975 }
976
977 /**
978 * _more_
979 *
980 * @return _more_
981 */
982 public boolean getIsObservationWayChangeable() {
983 return true;
984 }
985
986 /**
987 * _more_
988 *
989 * @return _more_
990 */
991 public Way getDefaultObservationWay() {
992 return DEFAULT_OBSERVATION_WAY;
993 }
994
995 /**
996 * _more_
997 *
998 *
999 *
1000 * @param stormInfo
1001 * _more_
1002 * @param wy
1003 * _more_
1004 *
1005 * @return _more_
1006 * @throws Exception
1007 * _more_
1008 */
1009 protected List<StormTrackPoint> getObservationTrackPoints(
1010 StormInfo stormInfo, Way wy) throws Exception {
1011 String columns = SqlUtil.comma(new String[] { getColYear(),
1012 COL_TYPHOON_MONTH, COL_TYPHOON_DAY, getColHour(),
1013 COL_TYPHOON_LATITUDE, COL_TYPHOON_LONGITUDE,
1014 COL_TYPHOON_WINDSPEED, COL_TYPHOON_PRESSURE,
1015 COL_TYPHOON_RADIUSMG, COL_TYPHOON_RADIUSWG,
1016 COL_TYPHOON_MOVEDIR, COL_TYPHOON_MOVESPEED, COL_TYPHOON_WAY });
1017
1018 List whereList = new ArrayList();
1019
1020 whereList.add(SqlUtil.eq(COL_TYPHOON_STORMID, SqlUtil.quote(stormInfo
1021 .getStormId())));
1022 whereList.add(SqlUtil.eq(COL_TYPHOON_FHOUR, ZEROHOUR));
1023 whereList.add(SqlUtil.eq(COL_TYPHOON_WAY, SqlUtil.quote(wy.getId())));
1024
1025 String query = SqlUtil.makeSelect(columns, Misc.newList(TABLE_TRACK),
1026 SqlUtil.makeAnd(whereList));
1027 query = query
1028 + " order by "
1029 + SqlUtil.comma(new String[] { getColYear(), COL_TYPHOON_MONTH,
1030 COL_TYPHOON_DAY, getColHour() });
1031 // System.err.println (query);
1032 Statement statement = evaluate(query);
1033 SqlUtil.Iterator iter = SqlUtil.getIterator(statement);
1034 ResultSet results;
1035
1036 List<StormTrackPoint> obsPts = new ArrayList();
1037 // Hashtable seenDate = new Hashtable();
1038 Real altReal = new Real(RealType.Altitude, 0);
1039
1040 while ((results = iter.getNext()) != null) {
1041 List<Real> attrs = new ArrayList();
1042 int col = 1;
1043 int year = results.getInt(col++);
1044 int month = results.getInt(col++);
1045 int day = results.getInt(col++);
1046 int hour = results.getInt(col++);
1047 double latitude = getLatLonValue(results.getDouble(col++));
1048 if ((latitude > 90) || (latitude < -90)) {
1049 continue;
1050 }
1051 double longitude = getLatLonValue(results.getDouble(col++));
1052 if ((longitude > 360) || (longitude < -180)) {
1053 continue;
1054 }
1055 attrs.add(PARAM_MAXWINDSPEED.getReal(getValue(results
1056 .getDouble(col++), PARAM_MAXWINDSPEED.getName())));
1057 attrs.add(PARAM_MINPRESSURE.getReal(getValue(results
1058 .getDouble(col++), PARAM_MINPRESSURE.getName())));
1059 attrs.add(PARAM_RADIUSMODERATEGALE.getReal(getValue(results
1060 .getDouble(col++), PARAM_RADIUSMODERATEGALE.getName())));
1061 attrs.add(PARAM_RADIUSWHOLEGALE.getReal(getValue(results
1062 .getDouble(col++), PARAM_RADIUSWHOLEGALE.getName())));
1063 attrs.add(PARAM_MOVEDIRECTION.getReal(getValue(results
1064 .getDouble(col++), PARAM_MOVEDIRECTION.getName())));
1065 attrs.add(PARAM_MOVESPEED.getReal(getValue(
1066 results.getDouble(col++), PARAM_MOVESPEED.getName())));
1067
1068 EarthLocation elt = new EarthLocationLite(new Real(
1069 RealType.Latitude, latitude), new Real(RealType.Longitude,
1070 longitude), altReal);
1071
1072 DateTime date = getDateTime(year, month, day, hour);
1073 String key = "" + latitude + " " + longitude;
1074 // if(seenDate.get(date)!=null) {
1075 // if(!seenDate.get(date).equals(key)) {
1076 // System.err.println ("seen: " + date + " " + seenDate.get(date) +
1077 // " != " + key);
1078 // }
1079 // continue;
1080 // }
1081 // seenDate.put(date,date);
1082 // seenDate.put(date,key);
1083 StormTrackPoint stp = new StormTrackPoint(elt, date, 0, attrs);
1084 obsPts.add(stp);
1085 }
1086
1087 return obsPts;
1088 }
1089
1090 /**
1091 * _more_
1092 *
1093 * @param stormInfo
1094 * _more_
1095 * @param wy
1096 * _more_
1097 * @param before
1098 * _more_
1099 * @param after
1100 * _more_
1101 * @param pts
1102 * _more_
1103 *
1104 * @return _more_
1105 *
1106 * @throws Exception
1107 * _more_
1108 */
1109 protected List<StormTrackPoint> getObservationTrack(StormInfo stormInfo,
1110 Way wy, DateTime before, DateTime after, List pts) throws Exception {
1111
1112 String columns = SqlUtil.comma(new String[] { getColYear(),
1113 COL_TYPHOON_MONTH, COL_TYPHOON_DAY, getColHour(),
1114 COL_TYPHOON_LATITUDE, COL_TYPHOON_LONGITUDE,
1115 COL_TYPHOON_WINDSPEED, COL_TYPHOON_PRESSURE,
1116 COL_TYPHOON_RADIUSMG, COL_TYPHOON_RADIUSWG,
1117 COL_TYPHOON_MOVEDIR, COL_TYPHOON_MOVESPEED, COL_TYPHOON_WAY });
1118
1119 List whereList = new ArrayList();
1120
1121 whereList.add(SqlUtil.eq(COL_TYPHOON_STORMID, SqlUtil.quote(stormInfo
1122 .getStormId())));
1123 whereList.add(SqlUtil.eq(COL_TYPHOON_FHOUR, ZEROHOUR));
1124 whereList.add(SqlUtil.eq(COL_TYPHOON_WAY, SqlUtil.quote(wy.getId())));
1125
1126 String query = SqlUtil.makeSelect(columns, Misc.newList(TABLE_TRACK),
1127 SqlUtil.makeAnd(whereList));
1128 query = query
1129 + " order by "
1130 + SqlUtil.comma(new String[] { getColYear(), COL_TYPHOON_MONTH,
1131 COL_TYPHOON_DAY, getColHour() });
1132 // System.err.println (query);
1133 Statement statement = evaluate(query);
1134 SqlUtil.Iterator iter = SqlUtil.getIterator(statement);
1135 ResultSet results;
1136
1137 List<StormTrackPoint> obsPts = new ArrayList();
1138 List<StormTrackPoint> obsPts1 = new ArrayList();
1139 List<StormTrackPoint> obsPts2 = new ArrayList();
1140 Real altReal = new Real(RealType.Altitude, 0);
1141
1142 while ((results = iter.getNext()) != null) {
1143 List<Real> attrs = new ArrayList();
1144 int col = 1;
1145 int year = results.getInt(col++);
1146 int month = results.getInt(col++);
1147 int day = results.getInt(col++);
1148 int hour = results.getInt(col++);
1149 double latitude = getLatLonValue(results.getDouble(col++));
1150 if ((latitude > 90) || (latitude < -90)) {
1151 continue;
1152 }
1153 double longitude = getLatLonValue(results.getDouble(col++));
1154 if ((longitude > 360) || (longitude < -180)) {
1155 continue;
1156 }
1157
1158 attrs.add(PARAM_MAXWINDSPEED.getReal(getValue(results
1159 .getDouble(col++), PARAM_MAXWINDSPEED.getName())));
1160 attrs.add(PARAM_MINPRESSURE.getReal(getValue(results
1161 .getDouble(col++), PARAM_MINPRESSURE.getName())));
1162 attrs.add(PARAM_RADIUSMODERATEGALE.getReal(getValue(results
1163 .getDouble(col++), PARAM_RADIUSMODERATEGALE.getName())));
1164 attrs.add(PARAM_RADIUSWHOLEGALE.getReal(getValue(results
1165 .getDouble(col++), PARAM_RADIUSWHOLEGALE.getName())));
1166 attrs.add(PARAM_MOVEDIRECTION.getReal(getValue(results
1167 .getDouble(col++), PARAM_MOVEDIRECTION.getName())));
1168 attrs.add(PARAM_MOVESPEED.getReal(getValue(
1169 results.getDouble(col++), PARAM_MOVESPEED.getName())));
1170
1171 EarthLocation elt = new EarthLocationLite(new Real(
1172 RealType.Latitude, latitude), new Real(RealType.Longitude,
1173 longitude), altReal);
1174
1175 DateTime date = getDateTime(year, month, day, hour);
1176
1177 if (date.getValue() < before.getValue()) {
1178 StormTrackPoint stp = new StormTrackPoint(elt, date, 0, attrs);
1179 obsPts1.add(stp);
1180 }
1181
1182 if (date.getValue() > after.getValue()) {
1183 StormTrackPoint stp = new StormTrackPoint(elt, date, 0, attrs);
1184 obsPts2.add(stp);
1185 }
1186
1187 }
1188
1189 if (obsPts1.size() > 0) {
1190 obsPts.addAll(obsPts1);
1191 }
1192
1193 obsPts.addAll(pts);
1194
1195 if (obsPts2.size() > 0) {
1196 obsPts.addAll(obsPts2);
1197 }
1198
1199 return obsPts;
1200
1201 }
1202
1203 /**
1204 * _more_
1205 *
1206 * @param times
1207 * _more_
1208 *
1209 * @return _more_
1210 */
1211 protected DateTime getStartTime(List times) {
1212 int size = times.size();
1213 DateTime dt = (DateTime) times.get(0);
1214 int idx = 0;
1215 double value = dt.getValue();
1216 for (int i = 1; i < size; i++) {
1217 dt = (DateTime) times.get(i);
1218 double dtValue = dt.getValue();
1219 if (dtValue < value) {
1220 value = dtValue;
1221 idx = i;
1222 }
1223 }
1224 return (DateTime) times.get(idx);
1225 }
1226
1227 /**
1228 * _more_
1229 *
1230 *
1231 *
1232 * @return _more_
1233 * @throws Exception
1234 * _more_
1235 */
1236 private List<StormInfo> getAllStormInfos() throws Exception {
1237 String columns = SqlUtil.distinct(COL_TYPHOON_STORMID);
1238 String query = SqlUtil.makeSelect(columns, Misc.newList(TABLE_TRACK));
1239 // System.err.println (query);
1240 // System.err.println(query);
1241 SqlUtil.Iterator iter = SqlUtil.getIterator(evaluate(query));
1242 ResultSet results;
1243 List<StormInfo> stormInfos = new ArrayList<StormInfo>();
1244 while ((results = iter.getNext()) != null) {
1245 String id = results.getString(1);
1246 DateTime startTime = getStormStartTime(id);
1247 // System.err.println(id + " " + startTime);
1248 StormInfo sinfo = new StormInfo(id, startTime);
1249 stormInfos.add(sinfo);
1250 }
1251 return stormInfos;
1252 }
1253
1254 /**
1255 * _more_
1256 *
1257 * @param id
1258 * _more_
1259 *
1260 * @return _more_
1261 *
1262 * @throws Exception
1263 * _more_
1264 */
1265 protected DateTime getStormStartTime(String id) throws Exception {
1266 String columns = SqlUtil.comma(new String[] { getColYear(),
1267 COL_TYPHOON_MONTH, COL_TYPHOON_DAY, getColHour() });
1268
1269 List whereList = new ArrayList();
1270 whereList.add(SqlUtil.eq(COL_TYPHOON_STORMID, SqlUtil.quote(id)));
1271 whereList.add(SqlUtil.eq(COL_TYPHOON_FHOUR, ZEROHOUR));
1272 String query = SqlUtil.makeSelect(columns, Misc.newList(TABLE_TRACK),
1273 SqlUtil.makeAnd(whereList));
1274 query = query + " order by " + columns;
1275 // System.err.println (query);
1276 Statement statement = evaluate(query);
1277 SqlUtil.Iterator iter = SqlUtil.getIterator(statement);
1278 ResultSet results;
1279 while ((results = iter.getNext()) != null) {
1280 int col = 1;
1281 int year = results.getInt(col++);
1282 int month = results.getInt(col++);
1283 int day = results.getInt(col++);
1284 int hour = results.getInt(col++);
1285 statement.close();
1286 // Just get the first one since we sorted the results with the order
1287 // by
1288 return getDateTime(year, month, day, hour);
1289 }
1290 return null;
1291 }
1292
1293 /**
1294 * _more_
1295 *
1296 *
1297 *
1298 * @param stormInfo
1299 * _more_
1300 *
1301 * @return _more_
1302 * @throws Exception
1303 * _more_
1304 */
1305 protected List<Way> getForecastWays(StormInfo stormInfo) throws Exception {
1306
1307 String columns = SqlUtil.distinct(COL_TYPHOON_WAY);
1308
1309 List whereList = new ArrayList();
1310 whereList.add(SqlUtil.eq(COL_TYPHOON_STORMID, SqlUtil.quote(stormInfo
1311 .getStormId())));
1312 String query = SqlUtil.makeSelect(columns, Misc.newList(TABLE_TRACK),
1313 SqlUtil.makeAnd(whereList));
1314 // System.err.println (query);
1315 Statement statement = evaluate(query);
1316 SqlUtil.Iterator iter = SqlUtil.getIterator(statement);
1317 ResultSet results;
1318
1319 List<Way> forecastWays = new ArrayList<Way>();
1320
1321 // TODO: How do we handle no data???
1322 while ((results = iter.getNext()) != null) {
1323 Way way = new Way(results.getString(1));
1324 addWay(way);
1325 forecastWays.add(way);
1326 }
1327
1328 // System.err.println ("ways:" + forecastWays);
1329 return forecastWays;
1330
1331 }
1332
1333 /**
1334 * _more_
1335 *
1336 * @param sql
1337 * _more_
1338 *
1339 * @return _more_
1340 *
1341 * @throws SQLException
1342 * _more_
1343 */
1344 private Statement evaluate(String sql) throws SQLException {
1345 Statement stmt = getConnection().createStatement();
1346 stmt.execute(sql);
1347 return stmt;
1348 }
1349
1350 /**
1351 * _more_
1352 *
1353 * @return _more_
1354 */
1355 public Connection getConnection() {
1356 if (connection != null) {
1357 return connection;
1358 }
1359 // String url = getFilePath();
1360 // Just hard code the jdbc url
1361 String url = dbUrl;
1362 // We don't need to do this for derby.
1363 /*
1364 * if ((getUserName() == null) || (getUserName().trim().length() == 0))
1365 * { if (url.indexOf("?") >= 0) { int idx = url.indexOf("?");
1366 * List<String> args = (List<String>) StringUtil.split(url.substring(idx
1367 * + 1), "&", true, true); url = url.substring(0, idx); for (String tok
1368 * : args) { List<String> subtoks = (List<String>) StringUtil.split(tok,
1369 * "=", true, true); if (subtoks.size() != 2) { continue; } String name
1370 * = subtoks.get(0); String value = subtoks.get(1); if
1371 * (name.equals("user")) { setUserName(value); } else if
1372 * (name.equals("password")) { setPassword(value); } } } }
1373 */
1374
1375 int cnt = 0;
1376 while (true) {
1377 String userName = getUserName();
1378 String password = getPassword();
1379 if (userName == null) {
1380 userName = "";
1381 }
1382 if (password == null) {
1383 password = "";
1384 }
1385 // userName = "jeff";
1386 // password = "mypassword";
1387 try {
1388 // System.err.println(url);
1389 if (useDerby()) {
1390 connection = DriverManager.getConnection(url);
1391 } else {
1392 if ((url.indexOf("user") > 0)
1393 && (url.indexOf("password") > 0)) {
1394 connection = DriverManager.getConnection(url);
1395 } else {
1396 connection = DriverManager.getConnection(url, userName,
1397 password);
1398 }
1399 }
1400
1401 return connection;
1402 } catch (Exception sqe) {
1403 // System.out.println(sqe);
1404 String msg = sqe.toString();
1405 if ((msg.indexOf("Access denied") >= 0)
1406 || (msg.indexOf("role \"" + userName
1407 + "\" does not exist") >= 0)
1408 || (msg.indexOf("user name specified") >= 0)) {
1409 String label;
1410 if (cnt == 0) {
1411 label = "<html>The database requires a login.<br>Please enter a user name and password:</html>";
1412 } else {
1413 label = "<html>Incorrect username/password. Please try again.</html>";
1414 }
1415 if (!showPasswordDialog("Database Login", label)) {
1416 return null;
1417 }
1418 cnt++;
1419 continue;
1420 }
1421 throw new BadDataException("Unable to connect to database", sqe);
1422 }
1423 }
1424 }
1425
1426 /**
1427 * _more_
1428 *
1429 * @return _more_
1430 *
1431 * @throws Exception
1432 * _more_
1433 */
1434 private boolean initConnection() throws Exception {
1435 if (getConnection() == null) {
1436 return false;
1437 }
1438
1439 try {
1440 // Create the dummy database
1441 Connection connection = getConnection();
1442 Statement stmt = connection.createStatement();
1443 // Drop the table - ignore any errors
1444 // SqlUtil.loadSql("drop table " + TABLE_TRACK, stmt, false);
1445
1446 if (useDerby()) {
1447 // Load in the test data
1448 try {
1449 stmt.execute("select count(*) from typhoon");
1450 System.err.println("Derby DB OK");
1451 } catch (Exception exc) {
1452 System.err.println("exc;" + exc);
1453 System.err.println("Creating test database");
1454 String initSql = IOUtil.readContents(
1455 "/ucar/unidata/data/storm/testdb.sql", getClass());
1456
1457 connection.setAutoCommit(false);
1458 SqlUtil.loadSql(initSql, stmt, false);
1459 connection.commit();
1460 connection.setAutoCommit(true);
1461 }
1462 }
1463 } catch (Exception exc) {
1464 exc.printStackTrace();
1465 return false;
1466 }
1467 return true;
1468 }
1469
1470 /**
1471 * _more_
1472 *
1473 * @param args
1474 * _more_
1475 *
1476 * @throws Exception
1477 * _more_
1478 */
1479 public static void main(String[] args) throws Exception {
1480 String sid = "0623";
1481 STIStormDataSource s = null;
1482 try {
1483 s = new STIStormDataSource();
1484 } catch (Exception exc) {
1485 System.err.println("err:" + exc);
1486 exc.printStackTrace();
1487 }
1488 s.initAfter();
1489 List sInfoList = s.getStormInfos();
1490 StormInfo sInfo = (StormInfo) sInfoList.get(0);
1491 sInfo = s.getStormInfo(sid);
1492 String sd = sInfo.getStormId();
1493 StormTrackCollection cls = s.getTrackCollection(sInfo, null, null);
1494 StormTrack obsTrack = cls.getObsTrack();
1495 List trackPointList = obsTrack.getTrackPoints();
1496 List trackPointTime = obsTrack.getTrackTimes();
1497 List ways = cls.getWayList();
1498 Map mp = cls.getWayToStartDatesHashMap();
1499 Map mp1 = cls.getWayToTracksHashMap();
1500
1501 System.err.println("test:");
1502
1503 }
1504
1505 /**
1506 * Set the DbUrl property.
1507 *
1508 * @param value
1509 * The new value for DbUrl
1510 */
1511 public void setDbUrl(String value) {
1512 dbUrl = value;
1513 }
1514
1515 /**
1516 * Get the DbUrl property.
1517 *
1518 * @return The DbUrl
1519 */
1520 public String getDbUrl() {
1521 return dbUrl;
1522 }
1523
1524 }