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.util.ArrayList; 032import java.util.Calendar; 033import java.util.Collection; 034import java.util.Date; 035import java.util.GregorianCalendar; 036import java.util.HashMap; 037import java.util.Hashtable; 038import java.util.Iterator; 039import java.util.List; 040import java.util.Map; 041 042import org.slf4j.Logger; 043import org.slf4j.LoggerFactory; 044import ucar.unidata.data.DataSourceDescriptor; 045import ucar.unidata.data.DataUtil; 046import ucar.unidata.util.DateUtil; 047import ucar.unidata.util.IOUtil; 048import ucar.unidata.util.StringUtil; 049import ucar.visad.Util; 050import visad.CommonUnit; 051import visad.DateTime; 052import visad.Real; 053import visad.RealType; 054import visad.VisADException; 055import visad.georef.EarthLocation; 056import visad.georef.EarthLocationLite; 057 058/** 059 * Created by IntelliJ IDEA. User: yuanho Date: May 8, 2009 Time: 10:02:15 AM To 060 * change this template use File | Settings | File Templates. 061 */ 062public class Diamond7StormDataSource extends StormDataSource { 063 064 private static final Logger logger = 065 LoggerFactory.getLogger(Diamond7StormDataSource.class); 066 067 /** 068 * _more_ 069 * 070 * @return _more_ 071 */ 072 073 public String getId() { 074 return "stiDiamond"; 075 } 076 077 /** _more_ */ 078 public static StormParam PARAM_MAXWINDSPEED; 079 080 /** _more_ */ 081 public static StormParam PARAM_RADIUSMODERATEGALE; 082 083 /** _more_ */ 084 public static StormParam PARAM_RADIUSWHOLEGALE; 085 086 /** _more_ */ 087 public static StormParam PARAM_DISTANCE_ERROR; 088 089 /** _more_ */ 090 public static StormParam PARAM_PROBABILITY100RADIUS; 091 092 /** _more_ */ 093 public static StormParam PARAM_PROBABILITYRADIUS; 094 095 /** _more_ */ 096 public static StormParam PARAM_MOVEDIRECTION; 097 098 /** _more_ */ 099 public static StormParam PARAM_MOVESPEED; 100 101 /** _more_ */ 102 private static float MISSING = 9999.0f; 103 104 /** _more_ */ 105 private String fileName; 106 107 /** the stormInfo and track */ 108 private List<StormInfo> stormInfos; 109 110 /** the stormInfo and track */ 111 private List<StormTrack> stormTracks; 112 113 private HashMap<String, Way> stormWays; 114 115 /** 116 * constructor of sti storm data source 117 * 118 * 119 * 120 * @param descriptor 121 * _more_ 122 * @param fileName 123 * _more_ 124 * @param properties 125 * _more_ 126 * @throws Exception 127 * _more_ 128 */ 129 130 public Diamond7StormDataSource(DataSourceDescriptor descriptor, 131 String fileName, Hashtable properties) throws Exception { 132 super(descriptor, fileName, "Diamond7 Storm Data", properties); 133 if ((fileName == null) || (fileName.trim().length() == 0) 134 || fileName.trim().equalsIgnoreCase("default")) { 135 System.err.println("No input file"); 136 ; 137 } 138 139 this.fileName = fileName; 140 141 } 142 143 /** 144 * _more_ 145 * 146 * @return _more_ 147 */ 148 public boolean isEditable() { 149 return true; 150 } 151 152 static { 153 try { 154 // TODO: Make sure these are the right units 155 PARAM_MINPRESSURE = new StormParam(makeRealType("minpressure", 156 "Min_Pressure", DataUtil.parseUnit("mb"))); 157 PARAM_MAXWINDSPEED = new StormParam(makeRealType("maxwindspeed", 158 "Max_Windspeed", Util.parseUnit("m/s"))); 159 PARAM_RADIUSMODERATEGALE = new StormParam(makeRealType( 160 "radiusmoderategale", "Radius_of_Beaufort_Scale7", DataUtil 161 .parseUnit("km"))); 162 PARAM_RADIUSWHOLEGALE = new StormParam(makeRealType( 163 "radiuswholegale", "Radius_of_Beaufort_Scale10", DataUtil 164 .parseUnit("km"))); 165 PARAM_MOVEDIRECTION = new StormParam(makeRealType("movedirection", 166 "Storm_Direction", CommonUnit.degree)); 167 PARAM_MOVESPEED = new StormParam(makeRealType("movespeed", 168 "Storm_Speed", Util.parseUnit("m/s"))); 169 } catch (Exception exc) { 170 logger.error("Error creating storm params", exc); 171 } 172 } 173 174 /** 175 * _more_ 176 * 177 * @throws VisADException 178 * _more_ 179 */ 180 protected void initParams() throws VisADException { 181 super.initParams(); 182 183 obsParams = new StormParam[] { PARAM_MAXWINDSPEED, PARAM_MINPRESSURE, 184 PARAM_RADIUSMODERATEGALE, PARAM_RADIUSWHOLEGALE, 185 PARAM_MOVESPEED, PARAM_MOVEDIRECTION }; 186 187 forecastParams = new StormParam[] { PARAM_MAXWINDSPEED, 188 PARAM_MINPRESSURE, PARAM_RADIUSMODERATEGALE, 189 PARAM_RADIUSWHOLEGALE, PARAM_MOVESPEED, PARAM_MOVEDIRECTION }; 190 } 191 192 /** 193 * _more_ 194 * 195 * 196 * @throws Exception 197 * _more_ 198 */ 199 public Diamond7StormDataSource() throws Exception { 200 } 201 202 /** 203 * _more_ 204 */ 205 protected void initializeStormData() { 206 207 try { 208 stormInfos = new ArrayList<StormInfo>(); 209 stormTracks = new ArrayList<StormTrack>(); 210 stormWays = new HashMap<String, Way>(); 211 String s = IOUtil.readContents(fileName); 212 /* 213 * 214 * diamond 7 0807 Tropical Cyclone Track Name 0807 japn 15 08 06 15 215 * 8 0 123.7 18.1 18.0 996.0 NaN NaN NaN NaN 08 06 15 14 6 124.4 216 * 18.8 19.0 995.0 NaN NaN NaN NaN year mon day time forecasttime 217 * lon lat speed pressure wind-circle-radii radii2 movspd movdir 218 */ 219 int lcn = 0; 220 String sid = null; 221 String sway = null; 222 boolean nextTrack = false; 223 Way trackWay = null; 224 StormInfo sInfo = null; 225 List<StormTrackPoint> pts = null; 226 List<StormTrackPoint> obsPts = new ArrayList(); 227 StormTrack sTrack = null; 228 List<String> lines = StringUtil.split(s, "\n", true, true); 229 int currentIndex = 0; 230 String headerLine1 = lines.get(currentIndex++); 231 double minTime = Double.MAX_VALUE; 232 DateTime minDate = null; 233 234 while (currentIndex < lines.size()) { 235 236 String headerLine2 = lines.get(currentIndex++); 237 List<String> toks = StringUtil.split(headerLine2, " ", true, 238 true); 239 sid = toks.get(1); 240 sway = toks.get(2); 241 int numberPts = Integer.parseInt(toks.get(3)); 242 trackWay = new Way(sway); 243 stormWays.put(sway, trackWay); 244 if (trackWay.isObservation()) 245 hasObservation = true; 246 if (sInfo == null) { 247 sInfo = new StormInfo(sid, new DateTime(new Date())); 248 stormInfos.add(sInfo); 249 } 250 251 pts = new ArrayList(); 252 /* */ 253 int endPtsIndex = currentIndex + numberPts; 254 255 // System.out.println("endPtsIndex "+ endPtsIndex); 256 while (currentIndex < endPtsIndex) { 257 258 // System.out.println("currentIndex "+ currentIndex); 259 String line = lines.get(currentIndex++); 260 toks = StringUtil.split(line, " ", true, true); 261 String year = toks.get(0); 262 String mon = toks.get(1); 263 String day = toks.get(2); 264 String hr = toks.get(3); 265 String fhr = toks.get(4); 266 String lon = toks.get(5); 267 String lat = toks.get(6); 268 String maxwindsp = toks.get(7); 269 String minpress = toks.get(8); 270 String radiusmgale = toks.get(9); 271 String radiuswgale = toks.get(10); 272 String mspd = toks.get(11); 273 String mdir = toks.get(12); 274 int yy = Integer.parseInt(year); 275 if (yy < 20) 276 yy = 2000 + yy; 277 else if (yy > 50 && yy < 99) 278 yy = 1900 + yy; 279 DateTime dtt = getDateTime(yy, Integer.parseInt(mon), 280 Integer.parseInt(day), Integer.parseInt(hr)); 281 double latitude = Double.parseDouble(lat); 282 double longitude = Double.parseDouble(lon); 283 Real altReal = new Real(RealType.Altitude, 0); 284 int fhour = Integer.parseInt(fhr); 285 286 EarthLocation elt = new EarthLocationLite(new Real( 287 RealType.Latitude, latitude), new Real( 288 RealType.Longitude, longitude), altReal); 289 List<Real> attributes = new ArrayList<Real>(); 290 291 double windspeed = getDouble(maxwindsp); 292 double pressure = getDouble(minpress); 293 attributes.add(PARAM_MINPRESSURE.getReal(pressure)); 294 attributes.add(PARAM_MAXWINDSPEED.getReal(windspeed)); 295 attributes.add(PARAM_RADIUSMODERATEGALE 296 .getReal(getDouble(radiusmgale))); 297 attributes.add(PARAM_RADIUSWHOLEGALE 298 .getReal(getDouble(radiuswgale))); 299 attributes 300 .add(PARAM_MOVEDIRECTION.getReal(getDouble(mdir))); 301 attributes.add(PARAM_MOVESPEED.getReal(getDouble(mspd))); 302 303 StormTrackPoint stp = new StormTrackPoint(elt, dtt, fhour, 304 attributes); 305 306 // System.out.println("fhour "+ fhour); 307 if (fhour == 0 && !trackWay.isObservation()) { 308 obsPts.add(stp); 309 } 310 if (fhour == 0 && pts.size() > 0 311 && !trackWay.isObservation()) { 312 // System.out.println("fhours "+ pts.size()); 313 DateTime trackStartTime = pts.get(0).getTime(); 314 if (trackStartTime.getValue() < minTime) { 315 minTime = trackStartTime.getValue(); 316 minDate = trackStartTime; 317 } 318 sTrack = new StormTrack(sInfo, trackWay, pts, 319 forecastParams); 320 stormTracks.add(sTrack); 321 pts = new ArrayList(); 322 } 323 pts.add(stp); 324 } 325 if (trackWay.isObservation()) { 326 DateTime trackStartTime = pts.get(0).getTime(); 327 if (trackStartTime.getValue() < minTime) { 328 minTime = trackStartTime.getValue(); 329 minDate = trackStartTime; 330 } 331 sTrack = new StormTrack(sInfo, trackWay, pts, obsParams); 332 stormTracks.add(sTrack); 333 pts = new ArrayList(); 334 } 335 if (pts.size() > 0 && !trackWay.isObservation()) { 336 DateTime trackStartTime = pts.get(0).getTime(); 337 if (trackStartTime.getValue() < minTime) { 338 minTime = trackStartTime.getValue(); 339 minDate = trackStartTime; 340 } 341 sTrack = new StormTrack(sInfo, trackWay, pts, 342 forecastParams); 343 stormTracks.add(sTrack); 344 pts = new ArrayList(); 345 } 346 347 } 348 /* last track */ 349 if (sInfo != null && minDate != null) { 350 sInfo.setStartTime(minDate); 351 } 352 /* obs */ 353 if (!hasObservation && obsPts.size() > 0) { 354 sTrack = new StormTrack(sInfo, DEFAULT_OBSERVATION_WAY, obsPts, 355 obsParams); 356 stormTracks.add(sTrack); 357 stormWays.put("Observation", DEFAULT_OBSERVATION_WAY); 358 } 359 360 } catch (Exception exc) { 361 logException("Error initializing ATCF data", exc); 362 } finally { 363 decrOutstandingGetDataCalls(); 364 } 365 366 } 367 368 /** 369 * _more_ 370 * 371 * @param dstring 372 * _more_ 373 * 374 * @return _more_ 375 */ 376 public double getDouble(String dstring) { 377 if (dstring.equalsIgnoreCase("NaN") || dstring.equalsIgnoreCase("9999")) { 378 return Double.NaN; 379 } else { 380 return Double.parseDouble(dstring); 381 } 382 } 383 384 /** 385 * _more_ 386 * 387 * @return _more_ 388 */ 389 public List<StormInfo> getStormInfos() { 390 List<StormInfo> sInfos = new ArrayList(); 391 sInfos.addAll(stormInfos); 392 return sInfos; 393 } 394 395 /** 396 * _more_ 397 * 398 * @param stormInfo 399 * _more_ 400 * @param waysToUse 401 * _more_ 402 * @param observationWay 403 * _more_ 404 * 405 * @return _more_ 406 * 407 * @throws Exception 408 * _more_ 409 */ 410 411 /** _more_ */ 412 private static final Way DEFAULT_OBSERVATION_WAY = new Way("Observation"); 413 private boolean hasObservation = false; 414 415 /** 416 * _more_ 417 * 418 * @param stormInfo 419 * _more_ 420 * @param waysToUse 421 * _more_ 422 * @param observationWay 423 * _more_ 424 * 425 * @return _more_ 426 * 427 * @throws Exception 428 * _more_ 429 */ 430 public StormTrackCollection getTrackCollectionInner(StormInfo stormInfo, 431 Hashtable<String, Boolean> waysToUse, Way observationWay) 432 throws Exception { 433 434 if (observationWay == null) { 435 observationWay = DEFAULT_OBSERVATION_WAY; 436 } 437 438 // long t1 = System.currentTimeMillis(); 439 StormTrackCollection trackCollection = new StormTrackCollection(); 440 // initializeStormData(); 441 List<Way> forecastWays = getForecastWays(stormInfo); 442 443 for (Way forecastWay : forecastWays) { 444 if ((waysToUse != null) && (waysToUse.size() > 0) 445 && (waysToUse.get(forecastWay.getId()) == null)) { 446 continue; 447 } 448 List forecastTracks = getForecastTracks(stormInfo, forecastWay); 449 if (forecastTracks.size() > 0) { 450 trackCollection.addTrackList(forecastTracks); 451 } 452 } 453 StormTrack obsTrack = getObservationTrack(stormInfo, observationWay); 454 // (Way) forecastWays.get(0)); 455 if (obsTrack != null) { 456 List<StormTrack> tracks = trackCollection.getTracks(); 457 // for (StormTrack stk : tracks) { 458 // addDistanceError(obsTrack, stk); 459 // } 460 // long t2 = System.currentTimeMillis(); 461 // System.err.println("time:" + (t2 - t1)); 462 trackCollection.addTrack(obsTrack); 463 } 464 return trackCollection; 465 } 466 467 /** 468 * _more_ 469 * 470 * 471 * 472 * @param stormInfo 473 * _more_ 474 * @param forecastWay 475 * _more_ 476 * 477 * @return _more_ 478 * @throws Exception 479 * _more_ 480 */ 481 private List<StormTrack> getForecastTracks(StormInfo stormInfo, 482 Way forecastWay) throws Exception { 483 484 List<StormTrack> tracks = new ArrayList<StormTrack>(); 485 List<DateTime> startDates = getForecastTrackStartDates(stormInfo, 486 forecastWay); 487 488 int nstarts = startDates.size(); 489 for (int i = 0; i < nstarts; i++) { 490 DateTime dt = (DateTime) startDates.get(i); 491 StormTrack tk = getForecastTrack(stormInfo, dt, forecastWay); 492 if (tk != null) { 493 int pn = tk.getTrackPoints().size(); 494 // Why > 1??? 495 if (pn > 1) { 496 tracks.add(tk); 497 } 498 } 499 } 500 return tracks; 501 502 } 503 504 /** 505 * If d is a missing value return NaN. Else return d 506 * 507 * @param d 508 * is checked if not missing return same value 509 * @param name 510 * _more_ 511 * 512 * @return _more_ 513 */ 514 515 public double getValue(double d, String name) { 516 if ((d == 9999) || (d == 999)) { 517 return Double.NaN; 518 } 519 520 if (name.equalsIgnoreCase(PARAM_MAXWINDSPEED.getName())) { 521 if ((d < 0) || (d > 60)) { 522 return Double.NaN; 523 } 524 } else if (name.equalsIgnoreCase(PARAM_MINPRESSURE.getName())) { 525 if ((d < 800) || (d > 1050)) { 526 return Double.NaN; 527 } 528 } else if (name.equalsIgnoreCase(PARAM_RADIUSMODERATEGALE.getName())) { 529 if ((d < 0) || (d > 900)) { 530 return Double.NaN; 531 } 532 } else if (name.equalsIgnoreCase(PARAM_RADIUSWHOLEGALE.getName())) { 533 if ((d < 0) || (d > 500)) { 534 return Double.NaN; 535 } 536 } else if (name.equalsIgnoreCase(PARAM_MOVESPEED.getName())) { 537 if ((d < 0) || (d > 55)) { 538 return Double.NaN; 539 } 540 } else if (name.equalsIgnoreCase(PARAM_MOVEDIRECTION.getName())) { 541 if ((d < 0) || (d > 360)) { 542 return Double.NaN; 543 } 544 } 545 546 return d; 547 } 548 549 /** 550 * _more_ 551 * 552 * @param d 553 * _more_ 554 * 555 * @return _more_ 556 */ 557 public double getLatLonValue(double d) { 558 if ((d == 9999) || (d == 999)) { 559 return Double.NaN; 560 } 561 return d; 562 } 563 564 /** 565 * _more_ 566 * 567 * 568 * 569 * @param stormInfo 570 * _more_ 571 * @param sTime 572 * _more_ 573 * @param forecastWay 574 * _more_ 575 * 576 * @return _more_ 577 * @throws Exception 578 * _more_ 579 */ 580 private StormTrack getForecastTrack(StormInfo stormInfo, DateTime sTime, 581 Way forecastWay) throws Exception { 582 583 StormTrack track = null; 584 585 Iterator iter = stormTracks.iterator(); 586 String sid = stormInfo.getStormId(); 587 String sway = forecastWay.getId(); 588 while (iter.hasNext()) { 589 track = (StormTrack) iter.next(); 590 String away = track.getWay().getId(); 591 String id = track.getStormInfo().getStormId(); 592 DateTime dt = track.getStartTime(); 593 if (id.equalsIgnoreCase(sid) && (dt == sTime) 594 && sway.equalsIgnoreCase(away)) { 595 return track; 596 } 597 598 } 599 return null; 600 } 601 602 /** 603 * _more_ 604 * 605 * @param year 606 * _more_ 607 * @param month 608 * _more_ 609 * @param day 610 * _more_ 611 * @param hour 612 * _more_ 613 * 614 * @return _more_ 615 * 616 * @throws Exception 617 * _more_ 618 */ 619 private DateTime getDateTime(int year, int month, int day, int hour) 620 throws Exception { 621 GregorianCalendar convertCal = new GregorianCalendar( 622 DateUtil.TIMEZONE_GMT); 623 convertCal.clear(); 624 convertCal.set(Calendar.YEAR, year); 625 // The MONTH is 0 based. The incoming month is 1 based 626 convertCal.set(Calendar.MONTH, month - 1); 627 convertCal.set(Calendar.DAY_OF_MONTH, day); 628 convertCal.set(Calendar.HOUR_OF_DAY, hour); 629 return new DateTime(convertCal.getTime()); 630 } 631 632 /** 633 * _more_ 634 * 635 * 636 * 637 * @param stormInfo 638 * _more_ 639 * @param way 640 * _more_ 641 * 642 * @return _more_ 643 * @throws Exception 644 * _more_ 645 */ 646 protected List<DateTime> getForecastTrackStartDates(StormInfo stormInfo, 647 Way way) throws Exception { 648 649 Iterator iter = stormTracks.iterator(); 650 List<DateTime> startDates = new ArrayList<DateTime>(); 651 while (iter.hasNext()) { 652 StormTrack track = (StormTrack) iter.next(); 653 if (!track.getWay().isObservation()) { 654 DateTime dt = track.getStartTime(); 655 startDates.add(dt); 656 } 657 } 658 return startDates; 659 } 660 661 /** 662 * _more_ 663 * 664 * @param stormInfo 665 * _more_ 666 * @param observationWay 667 * _more_ 668 * 669 * @return _more_ 670 * 671 * @throws Exception 672 * _more_ 673 */ 674 protected StormTrack getObservationTrack(StormInfo stormInfo, 675 Way observationWay) throws Exception { 676 addWay(observationWay); 677 // first get the obs from one specific way 678 List<StormTrackPoint> obsTrackPoints = getObservationTrackPoints( 679 stormInfo, observationWay); 680 681 if ((obsTrackPoints == null) || (obsTrackPoints.size() == 0)) { 682 return null; 683 } 684 685 return new StormTrack(stormInfo, addWay(Way.OBSERVATION), 686 obsTrackPoints, obsParams); 687 } 688 689 /** 690 * _more_ 691 * 692 * @return _more_ 693 */ 694 public boolean getIsObservationWayChangeable() { 695 return true; 696 } 697 698 /** 699 * _more_ 700 * 701 * 702 * 703 * @param stormInfo 704 * _more_ 705 * @param wy 706 * _more_ 707 * 708 * @return _more_ 709 * @throws Exception 710 * _more_ 711 */ 712 protected List<StormTrackPoint> getObservationTrackPoints( 713 StormInfo stormInfo, Way wy) throws Exception { 714 715 Iterator iter = stormTracks.iterator(); 716 String sway = wy.getId(); 717 String sid = stormInfo.getStormId(); 718 719 while (iter.hasNext()) { 720 StormTrack strack = (StormTrack) iter.next(); 721 String away = strack.getWay().getId(); 722 String aid = strack.getStormInfo().getStormId(); 723 if (away.equalsIgnoreCase(sway) && aid.equalsIgnoreCase(sid)) { 724 return strack.getTrackPoints(); 725 } 726 727 } 728 729 return null; 730 } 731 732 /** 733 * _more_ 734 * 735 * @param stormInfo 736 * _more_ 737 * @param wy 738 * _more_ 739 * @param before 740 * _more_ 741 * @param after 742 * _more_ 743 * @param pts 744 * _more_ 745 * 746 * @return _more_ 747 * 748 * @throws Exception 749 * _more_ 750 */ 751 protected List<StormTrackPoint> getObservationTrack(StormInfo stormInfo, 752 Way wy, DateTime before, DateTime after, List pts) throws Exception { 753 754 return null; 755 } 756 757 /** 758 * _more_ 759 * 760 * @param times 761 * _more_ 762 * 763 * @return _more_ 764 */ 765 protected DateTime getStartTime(List times) { 766 int size = times.size(); 767 DateTime dt = (DateTime) times.get(0); 768 int idx = 0; 769 double value = dt.getValue(); 770 for (int i = 1; i < size; i++) { 771 dt = (DateTime) times.get(i); 772 double dtValue = dt.getValue(); 773 if (dtValue < value) { 774 value = dtValue; 775 idx = i; 776 } 777 } 778 return (DateTime) times.get(idx); 779 } 780 781 /** 782 * _more_ 783 * 784 * @param sid 785 * _more_ 786 * 787 * @return _more_ 788 * 789 * @throws Exception 790 * _more_ 791 */ 792 protected DateTime getStormStartTime(String sid) throws Exception { 793 794 Iterator iter = stormTracks.iterator(); 795 796 while (iter.hasNext()) { 797 StormTrack strack = (StormTrack) iter.next(); 798 String aid = strack.getStormInfo().getStormId(); 799 if (aid.equalsIgnoreCase(sid)) { 800 return strack.getStartTime(); 801 } 802 } 803 return null; 804 } 805 806 /** 807 * _more_ 808 * 809 * 810 * 811 * @param stormInfo 812 * _more_ 813 * 814 * @return _more_ 815 * @throws Exception 816 * _more_ 817 */ 818 protected List<Way> getForecastWays(StormInfo stormInfo) throws Exception { 819 820 List<Way> ways = new ArrayList(); 821 822 Collection wc = stormWays.values(); 823 Iterator iter = wc.iterator(); 824 825 while (iter.hasNext()) { 826 Way way = (Way) iter.next(); 827 if (!way.isObservation()) 828 ways.add(way); 829 } 830 831 // System.err.println ("ways:" + forecastWays); 832 return ways; 833 834 } 835 836 /** 837 * _more_ 838 * 839 * @param args 840 * _more_ 841 * 842 * @throws Exception 843 * _more_ 844 */ 845 public static void main(String[] args) throws Exception { 846 String sid = "0623"; 847 STIStormDataSource s = null; 848 try { 849 s = new STIStormDataSource(); 850 } catch (Exception exc) { 851 logger.error("Problem creating new STIStormDataSource", exc); 852 } 853 s.initAfter(); 854 List sInfoList = s.getStormInfos(); 855 StormInfo sInfo = (StormInfo) sInfoList.get(0); 856 sInfo = s.getStormInfo(sid); 857 String sd = sInfo.getStormId(); 858 StormTrackCollection cls = s.getTrackCollection(sInfo, null, null); 859 StormTrack obsTrack = cls.getObsTrack(); 860 List trackPointList = obsTrack.getTrackPoints(); 861 List trackPointTime = obsTrack.getTrackTimes(); 862 List ways = cls.getWayList(); 863 Map mp = cls.getWayToStartDatesHashMap(); 864 Map mp1 = cls.getWayToTracksHashMap(); 865 866 System.err.println("test:"); 867 868 } 869 870}