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