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