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 }