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