001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2018 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 029package edu.wisc.ssec.mcidasv.adt; 030 031import java.io.File; 032import java.io.IOException; 033import java.util.Scanner; 034 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038public class Forecasts { 039 040 private static final Logger logger = LoggerFactory.getLogger(Forecasts.class); 041 042 private static double ForecastLatitudes[] = new double[10]; 043 044 private static double ForecastLongitudes[] = new double[10]; 045 046 private static double ForecastTimes[] = new double[10]; 047 048 private static String[] MonthID_StringX = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", 049 "AUG", "SEP", "OCT", "NOV", "DEC" }; 050 051 public Forecasts() { 052 } 053 054 public static double[] ReadForecasts(String ForecastFileName, int ForecastFileType, 055 double ThresholdTime) throws IOException { 056 String delims = "[, ]+"; 057 058 double ReturnLatitudeInterpolation = -999.5; 059 double ReturnLongitudeInterpolation = -999.5; 060 double ReturnCurrentIntensity = -999.5; 061 double CurrentDayValue; 062 int ReturnFlagValue = -1; 063 String TmpStr1; 064 String TmpStr2; 065 String TmpStr3; 066 String TmpStr4; 067 String TmpStr5; 068 String TmpStr6; 069 String TmpStr7; 070 String TmpStr8; 071 String TmpStr9; 072 String TmpStr12; 073 int WindVal; 074 int YearIntVal; 075 int MonthIntVal; 076 int DayIntVal; 077 int HMSTimeIntVal; 078 int FcstTimeIntVal; 079 int JulianDayIntVal; 080 int FcstTimeIntValPrev; 081 int LocVar1, LocVar2; 082 int DayIntValXX; 083 int MonthIntValXX; 084 int YearIntValXX; 085 int JulianDayIntValXX; 086 double TimeArray[] = new double[10]; 087 double LatitudeArray[] = new double[10]; 088 double LongitudeArray[] = new double[10]; 089 double StrengthArray[] = new double[10]; 090 double TmpTimeVal2; 091 double NSFactor; 092 double WEFactor; 093 094 ReturnFlagValue = 0; 095 096 logger.debug("ReadForecasts in..."); 097 System.out.printf("Forecast File Name=%s Type=%d\n", ForecastFileName, ForecastFileType); 098 File forecastfile = new File(ForecastFileName); 099 Scanner in = new Scanner(forecastfile); 100 101 int ImageDate = Data.IRData_JulianDate; 102 int ImageTime = Data.IRData_HHMMSSTime; 103 System.out.printf("IMAGE DATE=%d TIME=%d\n", Data.IRData_JulianDate, 104 Data.IRData_HHMMSSTime); 105 /* int ImageDate = History.IRCurrentRecord.date; */ 106 /* int ImageTime = History.IRCurrentRecord.time; */ 107 double CurrentTime = Functions.calctime(ImageDate, ImageTime); 108 int XInc = 0; 109 int YInc = 0; 110 FcstTimeIntValPrev = -1; 111 112 try { 113 114 /* char aChar = ATCFStormIDString.charAt(2); */ 115 if (ForecastFileType == 0) { 116 while (in.hasNextLine()) { 117 String forecastRec = in.nextLine(); 118 String[] tokens = forecastRec.split(delims); 119 TmpStr1 = tokens[0]; 120 TmpStr2 = tokens[1]; 121 TmpStr3 = tokens[2]; 122 TmpStr4 = tokens[3]; 123 TmpStr5 = tokens[4]; 124 TmpStr6 = tokens[5]; 125 TmpStr7 = tokens[6]; 126 TmpStr8 = tokens[7]; 127 TmpStr9 = tokens[8]; 128 TmpStr12 = tokens[11]; 129 WindVal = 0; 130 if ((TmpStr12.length() > 1) && (TmpStr12.matches("\\d+"))) { 131 WindVal = Integer.parseInt(TmpStr12.substring(0, 2)); /* 132 * ( 133 * int 134 * ) 135 * aodt_atoif 136 * ( 137 * TmpStr12 138 * , 139 * 1 140 * , 141 * 2 142 * ) 143 * ; 144 */ 145 } 146 /* 147 * System.out.printf( 148 * "1=%s* 2=%s* 3=%s* 4=%s* 5=%s* 6=%s* 7=%s* 8=%s* 9=%s* 10=%s* 11=%s* 12=%s* \n" 149 * , 150 * TmpStr1,TmpStr2,TmpStr3,TmpStr4,TmpStr5,TmpStr6,TmpStr7, 151 * TmpStr8,TmpStr9,TmpStr10,TmpStr11,TmpStr12); 152 */ 153 if (WindVal == 34) { 154 YearIntVal = Integer.parseInt(TmpStr3.substring(0, 4)); /* 155 * ( 156 * int 157 * ) 158 * aodt_atoif 159 * ( 160 * TmpStr3 161 * , 162 * 1 163 * , 164 * 4 165 * ) 166 * ; 167 */ 168 MonthIntVal = Integer.parseInt(TmpStr3.substring(4, 6)); /* 169 * ( 170 * int 171 * ) 172 * aodt_atoif 173 * ( 174 * TmpStr3 175 * , 176 * 5 177 * , 178 * 6 179 * ) 180 * ; 181 */ 182 DayIntVal = Integer.parseInt(TmpStr3.substring(6, 8)); /* 183 * ( 184 * int 185 * ) 186 * aodt_atoif 187 * ( 188 * TmpStr3 189 * , 190 * 7 191 * , 192 * 8 193 * ) 194 * ; 195 */ 196 /* 197 * System.out.printf("year=%d month=%d day=%d\n",YearIntVal 198 * ,MonthIntVal,DayIntVal); 199 */ 200 HMSTimeIntVal = 10000 * Integer.parseInt(TmpStr3.substring(8, 10)); /* 201 * 10000 202 * * 203 * ( 204 * ( 205 * int 206 * ) 207 * aodt_atoif 208 * ( 209 * TmpStr3 210 * , 211 * 9 212 * , 213 * 10 214 * ) 215 * ) 216 * ; 217 */ 218 FcstTimeIntVal = 10000 * Integer.parseInt(TmpStr6); /* 219 * 10000 220 * * 221 * ( 222 * ( 223 * int 224 * ) 225 * aodt_atoif 226 * ( 227 * TmpStr6 228 * , 229 * 1 230 * , 231 * strlen 232 * ( 233 * TmpStr6 234 * ) 235 * ) 236 * ) 237 * ; 238 */ 239 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 240 TmpTimeVal2 = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 241 /* 242 * System.out.printf("YInc=%d tmptime=%f\n",YInc,TmpTimeVal2 243 * ); 244 */ 245 if ((TmpTimeVal2 < CurrentTime) && (FcstTimeIntValPrev != FcstTimeIntVal) 246 && (YInc < 6)) { 247 LocVar1 = ((int) (FcstTimeIntVal + HMSTimeIntVal)) / 240000; 248 LocVar2 = (((int) (FcstTimeIntVal + HMSTimeIntVal)) % 240000); 249 TimeArray[YInc] = Functions 250 .calctime(JulianDayIntVal + LocVar1, LocVar2); 251 NSFactor = (TmpStr7.charAt(TmpStr7.length() - 1) == 'N') ? 1.0 : -1.0; 252 WEFactor = (TmpStr8.charAt(TmpStr8.length() - 1) == 'W') ? 1.0 : -1.0; 253 LatitudeArray[YInc] = NSFactor 254 * Double.parseDouble(TmpStr7.substring(0, TmpStr7.length() - 1)) 255 / 10.0; /* 256 * (aodt_atoif(TmpStr7,1,strlen(TmpStr7 257 * )))/10.0; 258 */ 259 LongitudeArray[YInc] = WEFactor 260 * Double.parseDouble(TmpStr8.substring(0, TmpStr8.length() - 1)) 261 / 10.0; /* 262 * (aodt_atoif(TmpStr8,1,strlen(TmpStr8 263 * )))/10.0; 264 */ 265 StrengthArray[YInc] = Double.parseDouble(TmpStr9); /* 266 * aodt_atoif 267 * ( 268 * TmpStr9 269 * , 270 * 1 271 * , 272 * 4 273 * ) 274 * ; 275 */ 276 YInc++; 277 FcstTimeIntValPrev = FcstTimeIntVal; 278 XInc = YInc; 279 } 280 } 281 } 282 } else if (ForecastFileType == 1) { /* NHC */ 283 /* read NHC forecast file, quit at EOF */ 284 DayIntValXX = 0; 285 MonthIntValXX = 0; 286 YearIntValXX = 0; 287 JulianDayIntValXX = 0; 288 DayIntVal = 0; 289 MonthIntVal = 0; 290 YearIntVal = 0; 291 JulianDayIntVal = 0; 292 boolean NewNHCFormatFlag = false; 293 boolean FoundMonthTF = false; 294 boolean FoundForecast = false; 295 while ((in.hasNextLine()) && (XInc < 6)) { 296 String forecastRec = in.nextLine(); 297 String[] tokens = forecastRec.split(delims); 298 if (!FoundMonthTF) { 299 if ((tokens.length == 7) 300 && (tokens[1].equals("AM") || tokens[1].equals("PM"))) { 301 /* 302 * this is reading the header at the top of the 303 * forecast file. It is done to obtain the current 304 * month and year of the forecast so that we can 305 * check it accurately against the image date/time 306 */ 307 DayIntValXX = Integer.parseInt(tokens[5].substring(0, 2)); /* 308 * ( 309 * int 310 * ) 311 * aodt_atoif 312 * ( 313 * TmpStr6 314 * , 315 * 1 316 * , 317 * 2 318 * ) 319 * ; 320 */ 321 YearIntValXX = Integer.parseInt(tokens[6].substring(0, 4)); /* 322 * ( 323 * int 324 * ) 325 * aodt_atoif 326 * ( 327 * TmpStr7 328 * , 329 * 1 330 * , 331 * 4 332 * ) 333 * ; 334 */ 335 while ((!tokens[4].equals(MonthID_StringX[MonthIntValXX])) 336 && (MonthIntValXX < 12)) { 337 MonthIntValXX++; 338 } 339 JulianDayIntValXX = Functions.idmyyd(DayIntValXX, MonthIntValXX + 1, 340 YearIntValXX); 341 FoundMonthTF = true; 342 /* 343 * System.out.printf( 344 * "XX julday=%d day=%d month=%d year=%d\n" 345 * ,JulianDayIntValXX 346 * ,DayIntValXX,MonthIntValXX+1,YearIntValXX); 347 */ 348 } 349 MonthIntVal = MonthIntValXX; 350 YearIntVal = YearIntValXX; 351 } else { 352 if ((FoundForecast) && (tokens.length >= 6)) { 353 /* System.out.printf("length=%d\n",tokens.length); */ 354 if (XInc == 0) { 355 if (tokens[0].equals("INITIAL")) { 356 NewNHCFormatFlag = false; 357 } else if ((tokens[0].equals("INIT")) && (YearIntVal >= 2011)) { 358 NewNHCFormatFlag = true; 359 } else { 360 NewNHCFormatFlag = false; 361 } 362 /* 363 * System.out.printf("newformatflag=%b\n", 364 * NewNHCFormatFlag); 365 */ 366 } 367 int iadd = (tokens[0].length() == 0) ? 1 : 0; 368 if ((NewNHCFormatFlag) || ((!NewNHCFormatFlag) && (XInc == 0))) { 369 TmpStr1 = tokens[0 + iadd]; 370 TmpStr2 = tokens[1 + iadd]; 371 TmpStr3 = tokens[2 + iadd]; 372 TmpStr4 = tokens[3 + iadd]; 373 TmpStr5 = tokens[4 + iadd]; 374 TmpStr6 = tokens[5 + iadd]; 375 } else { 376 TmpStr1 = tokens[0 + iadd]; 377 TmpStr2 = tokens[2 + iadd]; 378 TmpStr3 = tokens[3 + iadd]; 379 TmpStr4 = tokens[4 + iadd]; 380 TmpStr5 = tokens[5 + iadd]; 381 TmpStr6 = tokens[6 + iadd]; 382 } 383 /* 384 * System.out.printf( 385 * "1=%s* 1a=%s* 2=%s* 3=%s* 4=%s* 5=%s* 6=%s*\n" 386 * ,TmpStr1 387 * ,TmpStr1a,TmpStr2,TmpStr3,TmpStr4,TmpStr5, 388 * TmpStr6); 389 */ 390 if (TmpStr6.substring(0, 2).equals("KT")) { 391 if (TmpStr2.charAt(7) == 'Z') { 392 DayIntVal = Integer.parseInt(TmpStr2.substring(0, 2)); /* 393 * ( 394 * ( 395 * int 396 * ) 397 * aodt_atoif 398 * ( 399 * TmpStr2 400 * , 401 * 1 402 * , 403 * 7 404 * ) 405 * ) 406 * / 407 * 10000 408 * ; 409 */ 410 HMSTimeIntVal = 100 * (Integer 411 .parseInt(TmpStr2.substring(3, 7))); /* 412 * 100 413 * * 414 * ( 415 * ( 416 * ( 417 * int 418 * ) 419 * aodt_atoif 420 * ( 421 * TmpStr2 422 * , 423 * 1 424 * , 425 * 7 426 * ) 427 * ) 428 * % 429 * 10000 430 * ) 431 * ; 432 */ 433 if (DayIntVal < DayIntValXX) { 434 MonthIntVal++; 435 if (MonthIntVal == 12) { 436 YearIntVal++; 437 MonthIntVal = 0; 438 } 439 JulianDayIntVal = Functions.idmyyd(DayIntVal, 440 MonthIntVal + 1, YearIntVal); 441 } else { 442 JulianDayIntVal = JulianDayIntValXX 443 + (DayIntVal - DayIntValXX); 444 } 445 TimeArray[XInc] = Functions.calctime(JulianDayIntVal, 446 HMSTimeIntVal); 447 NSFactor = (TmpStr3.charAt(TmpStr3.length() - 1) == 'N') ? 1.0 448 : -1.0; 449 WEFactor = (TmpStr4.charAt(TmpStr4.length() - 1) == 'W') ? 1.0 450 : -1.0; 451 LatitudeArray[XInc] = NSFactor 452 * Double.parseDouble(TmpStr3.substring(0, 453 TmpStr3.length() - 1)); 454 LongitudeArray[XInc] = WEFactor 455 * Double.parseDouble(TmpStr4.substring(0, 456 TmpStr4.length() - 1)); 457 StrengthArray[XInc] = Integer.parseInt(TmpStr5); 458 XInc++; 459 } 460 } 461 } else { 462 if (tokens[0].equals("FORECAST") && tokens[1].equals("POSITIONS")) 463 FoundForecast = true; 464 } 465 } 466 } 467 } else if (ForecastFileType == 2) { 468 /* 469 * read JTWC forecast file, quit at EOF 470 * 471 * o.k... since JTWC does not put the month and year on their 472 * bulletins, they will need to be "made up". We will assume 473 * that the forecast is current and the month and year from the 474 * image is equal to the month and year of the forecast file. 475 */ 476 int[] ReturnValues = Functions.adt_yddmy((int) CurrentTime); 477 DayIntValXX = ReturnValues[0]; 478 MonthIntValXX = ReturnValues[1]; 479 YearIntValXX = ReturnValues[2]; 480 /* System.out.printf("DayIntValXX=%d\n",DayIntValXX); */ 481 /* System.out.printf("MonthIntValXX=%d\n",MonthIntValXX); */ 482 /* System.out.printf("YearIntValXX=%d\n",YearIntValXX); */ 483 int datexxx = 0; 484 int monthxxx = 0; 485 int yearxxx = 0; 486 int DayIntValSub = 0; 487 JulianDayIntVal = 0; 488 while (in.hasNextLine()) { 489 String forecastRec = in.nextLine(); 490 String[] tokens = forecastRec.split(delims); 491 if (tokens.length >= 5) { 492 int iadd = (tokens[0].length() == 0) ? 1 : 0; 493 TmpStr1 = tokens[0 + iadd]; 494 TmpStr2 = tokens[1 + iadd]; 495 TmpStr3 = tokens[2 + iadd]; 496 TmpStr4 = tokens[3 + iadd]; 497 if (TmpStr2.equals("---")) { 498 if (XInc == 0) { 499 TmpStr5 = tokens[4 + iadd]; 500 /* 501 * System.out.printf( 502 * "XInc=%d : 1=%s* 2=%s* 3=%s* 4=%s* 5=%s* \n" 503 * ,XInc 504 * ,TmpStr1,TmpStr2,TmpStr3,TmpStr4,TmpStr5); 505 */ 506 DayIntVal = Integer.parseInt(TmpStr1.substring(0, 2)); 507 HMSTimeIntVal = 100 * Integer.parseInt(TmpStr1.substring(2, 6)); 508 /* 509 * System.out.printf( 510 * "dayintval=%d hmstimeintval=%d\n" 511 * ,DayIntVal,HMSTimeIntVal); 512 */ 513 DayIntValSub = DayIntValXX - DayIntVal; 514 int[] ReturnValues2 = Functions.adt_yddmy(ImageDate); 515 datexxx = ReturnValues2[0]; 516 monthxxx = ReturnValues2[1]; 517 yearxxx = ReturnValues2[2]; 518 if (DayIntVal == DayIntValXX) { 519 /* 520 * dates are the same... probably o.k.... 521 * should check times 522 */ 523 JulianDayIntVal = (int) CurrentTime; 524 } else if ((DayIntValSub <= 2) && (DayIntValSub >= 0)) { 525 /* 526 * this is probably o.k too... should check 527 * times 528 */ 529 JulianDayIntVal = (int) CurrentTime + (DayIntVal - DayIntValXX); 530 } else { 531 /* 532 * dates are invalid. Either image date is 533 * before forecast or is well beyond 534 * forecast availability 535 */ 536 if (DayIntValSub < -27) { 537 /* 538 * System.out.printf("month crossing\n"); 539 */ 540 /* 541 * System.out.printf("datexxx=%d\n",datexxx 542 * ); 543 */ 544 if ((datexxx <= 2) && (monthxxx == 1)) { 545 /* 546 * System.out.printf( 547 * "year crossing... image during new year: %d %d\n" 548 * ,yearxxx-1,DayIntVal); 549 */ 550 JulianDayIntVal = Functions.idmyyd(DayIntVal, 12, 551 yearxxx - 1); 552 } else { 553 JulianDayIntVal = Functions.idmyyd(DayIntVal, 554 monthxxx - 1, yearxxx); 555 } 556 /* 557 * System.out.printf("JulianDayIntVal=%d\n" 558 * ,JulianDayIntVal); 559 */ 560 } else { 561 ReturnFlagValue = -1; 562 } 563 } 564 /* 565 * System.out.printf("JulianDayIntVal=%d\n", 566 * JulianDayIntVal); 567 */ 568 TimeArray[XInc] = Functions 569 .calctime(JulianDayIntVal, HMSTimeIntVal); 570 /* 571 * System.out.printf("TimeArray[%d]=%f\n",XInc, 572 * TimeArray[XInc]); 573 */ 574 NSFactor = (TmpStr4.charAt(TmpStr4.length() - 1) == 'N') ? 1.0 575 : -1.0; 576 WEFactor = (TmpStr5.charAt(TmpStr5.length() - 1) == 'W') ? 1.0 577 : -1.0; 578 LatitudeArray[XInc] = NSFactor 579 * Double.parseDouble(TmpStr4.substring(0, 580 TmpStr4.length() - 1)); 581 LongitudeArray[XInc] = WEFactor 582 * Double.parseDouble(TmpStr5.substring(0, 583 TmpStr5.length() - 1)); 584 } else { 585 /* 586 * System.out.printf( 587 * "XInc=%d : 1=%s* 2=%s* 3=%s* 4=%s* \n" 588 * ,XInc,TmpStr1,TmpStr2,TmpStr3,TmpStr4); 589 */ 590 DayIntVal = Integer.parseInt(TmpStr1.substring(0, 2)); 591 HMSTimeIntVal = 100 * Integer.parseInt(TmpStr1.substring(2, 6)); 592 /* 593 * System.out.printf( 594 * "dayintval=%d hmstimeintval=%d\n" 595 * ,DayIntVal,HMSTimeIntVal); 596 */ 597 DayIntValSub = DayIntValXX - DayIntVal; 598 if (DayIntValSub < -27) { 599 if ((monthxxx - 1) == 0) { 600 JulianDayIntVal = Functions.idmyyd(DayIntVal, 12, 601 yearxxx - 1); 602 } else { 603 JulianDayIntVal = Functions.idmyyd(DayIntVal, monthxxx - 1, 604 yearxxx); 605 } 606 } else { 607 if (DayIntValSub > 27) { 608 if ((monthxxx + 1) > 12) { 609 JulianDayIntVal = Functions.idmyyd(DayIntVal, 1, 610 yearxxx + 1); 611 } else { 612 JulianDayIntVal = Functions.idmyyd(DayIntVal, 613 monthxxx + 1, yearxxx); 614 } 615 } else { 616 JulianDayIntVal = Functions.idmyyd(DayIntVal, monthxxx, 617 yearxxx); 618 } 619 } 620 /* 621 * System.out.printf("JulianDayIntVal=%d\n", 622 * JulianDayIntVal); 623 */ 624 TimeArray[XInc] = Functions 625 .calctime(JulianDayIntVal, HMSTimeIntVal); 626 /* 627 * System.out.printf("TimeArray[%d]=%f\n",XInc, 628 * TimeArray[XInc]); 629 */ 630 NSFactor = (TmpStr3.charAt(TmpStr3.length() - 1) == 'N') ? 1.0 631 : -1.0; 632 WEFactor = (TmpStr4.charAt(TmpStr4.length() - 1) == 'W') ? 1.0 633 : -1.0; 634 LatitudeArray[XInc] = NSFactor 635 * Double.parseDouble(TmpStr3.substring(0, 636 TmpStr3.length() - 1)); 637 LongitudeArray[XInc] = WEFactor 638 * Double.parseDouble(TmpStr4.substring(0, 639 TmpStr4.length() - 1)); 640 } 641 } 642 if ((TmpStr1.equals("MAX")) && (TmpStr4.charAt(0) == '-')) { 643 TmpStr5 = tokens[4 + iadd]; 644 if (XInc == 0) { 645 StrengthArray[XInc] = Double.parseDouble(TmpStr5); 646 } 647 XInc++; 648 } 649 } 650 } 651 } else if (ForecastFileType == 3) { 652 /* generic forecast file input */ 653 while (in.hasNextLine()) { 654 String forecastRec = in.nextLine(); 655 String[] tokens = forecastRec.split(delims); 656 if (tokens.length >= 5) { 657 TmpStr1 = tokens[0]; 658 TmpStr2 = tokens[1]; 659 TmpStr3 = tokens[2]; 660 TmpStr4 = tokens[3]; 661 TmpStr5 = tokens[4]; 662 TmpStr6 = tokens[5]; 663 TmpStr7 = tokens[6]; 664 DayIntVal = Integer.parseInt(TmpStr1.substring(0, 2)); 665 MonthIntVal = Integer.parseInt(TmpStr2.substring(0, 2)); 666 YearIntVal = Integer.parseInt(TmpStr3.substring(0, 4)); 667 HMSTimeIntVal = 100 * Integer.parseInt(TmpStr4.substring(0, 4)); 668 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 669 TimeArray[XInc] = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 670 NSFactor = (TmpStr5.charAt(TmpStr5.length() - 1) == 'N') ? 1.0 : -1.0; 671 WEFactor = (TmpStr6.charAt(TmpStr6.length() - 1) == 'W') ? 1.0 : -1.0; 672 LatitudeArray[XInc] = NSFactor 673 * Double.parseDouble(TmpStr5.substring(0, TmpStr5.length() - 1)); 674 LongitudeArray[XInc] = WEFactor 675 * Double.parseDouble(TmpStr6.substring(0, TmpStr6.length() - 1)); 676 StrengthArray[XInc] = Double.parseDouble(TmpStr5); 677 XInc++; 678 } 679 } 680 } else if (ForecastFileType == 4) { 681 String delims4 = "[:+/ ]+"; 682 /* RSMC ICAO (FK?? or WT??) forecast file input */ 683 /* 684 * Convert the ICAO RSMC bulletin positions from degrees minutes 685 * to degrees and tenths of degrees. fix courtesy : YanLuo/NOAA 686 * 07/22/09 * 687 */ 688 int xxx1 = 0; 689 int xxx2 = 0; 690 double LatMultFact = 0.0; 691 double LonMultFact = 0.0; 692 while (in.hasNextLine()) { 693 String forecastRec = in.nextLine(); 694 String[] tokens = forecastRec.split(delims4); 695 if (tokens[0].equals("DTG")) { 696 TmpStr1 = tokens[1]; 697 /* System.out.printf("TmpStr1=%s*\n",TmpStr1); */ 698 DayIntVal = Integer.parseInt(TmpStr1.substring(6, 8)); 699 MonthIntVal = Integer.parseInt(TmpStr1.substring(4, 6)); 700 YearIntVal = Integer.parseInt(TmpStr1.substring(0, 4)); 701 if (tokens.length == 2) { 702 HMSTimeIntVal = 100 * Integer.parseInt(TmpStr1.substring(8, 12)); 703 } else { 704 TmpStr2 = tokens[2]; 705 HMSTimeIntVal = 100 * Integer.parseInt(TmpStr2.substring(0, 4)); 706 } 707 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 708 TimeArray[XInc] = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 709 /* 710 * System.out.printf("time0=%f hmstime=%d\n",TimeArray[XInc 711 * ],HMSTimeIntVal); 712 */ 713 } else if (tokens[0].equals("PSN")) { 714 TmpStr1 = tokens[1]; 715 TmpStr2 = tokens[2]; 716 LatMultFact = (TmpStr1.charAt(0) == 'N') ? 1.0 : -1.0; 717 LonMultFact = (TmpStr2.charAt(0) == 'W') ? 1.0 : -1.0; 718 xxx1 = Integer.parseInt(TmpStr1.substring(1, TmpStr1.length())); 719 xxx2 = Integer.parseInt(TmpStr2.substring(1, TmpStr2.length())); 720 /* initial lat/lon */ 721 double LatitudeWhole = ((double) xxx1) / 100.0; 722 double LatitudePart = ((double) xxx1 - (LatitudeWhole * 100.0)) / 60.0; 723 LatitudeArray[XInc] = LatMultFact * (LatitudeWhole + LatitudePart); 724 double LongitudeWhole = ((double) xxx2) / 100.0; 725 double LongitudePart = ((double) xxx2 - (LongitudeWhole * 100.0)) / 60.0; 726 LongitudeArray[XInc] = LonMultFact * (LongitudeWhole + LongitudePart); 727 XInc++; 728 } else if ((tokens[0].equals("MAX")) && (XInc == 0)) { 729 /* initial lat/lon */ 730 TmpStr1 = tokens[2]; 731 StrengthArray[XInc] = Double.parseDouble(TmpStr1.substring(0, 732 TmpStr1.length() - 2)); 733 } else if ((tokens[0].equals("FCST")) && (tokens[1].equals("PSN"))) { 734 int numtokens = tokens.length; 735 TmpStr1 = tokens[2]; 736 TmpStr2 = tokens[numtokens - 2]; 737 TmpStr3 = tokens[numtokens - 1]; 738 /* 739 * System.out.printf("1=%s* 2=%s* 3=%s*\n",TmpStr1,TmpStr2 740 * ,TmpStr3); 741 */ 742 LatMultFact = (TmpStr2.charAt(0) == 'N') ? 1.0 : -1.0; 743 LonMultFact = (TmpStr3.charAt(0) == 'W') ? 1.0 : -1.0; 744 xxx1 = Integer.parseInt(TmpStr2.substring(1, TmpStr2.length())); 745 xxx2 = Integer.parseInt(TmpStr3.substring(1, TmpStr3.length())); 746 int FcstHrAddIntVal = Integer.parseInt(TmpStr1.substring(0, 2)); 747 /* initial lat/lon */ 748 double LatitudeWhole = ((double) xxx1) / 100.0; 749 double LatitudePart = ((double) xxx1 - (LatitudeWhole * 100.0)) / 60.0; 750 LatitudeArray[XInc] = LatMultFact * (LatitudeWhole + LatitudePart); 751 double LongitudeWhole = ((double) xxx2) / 100.0; 752 double LongitudePart = ((double) xxx2 - (LongitudeWhole * 100.0)) / 60.0; 753 LongitudeArray[XInc] = LonMultFact * (LongitudeWhole + LongitudePart); 754 double FcstHrAddDblVal = ((double) FcstHrAddIntVal) / 24.0; 755 /* 756 * System.out.printf("XInc=%d time0=%f fcsthr=%f\n",XInc, 757 * TimeArray[0],FcstHrAddDblVal); 758 */ 759 TimeArray[XInc] = TimeArray[0] + FcstHrAddDblVal; 760 XInc++; 761 } 762 } 763 } else if (ForecastFileType == 5) { 764 /* RSMC WTIO30 forecast file input */ 765 String delims5 = "[,:/= ]+"; 766 while (in.hasNextLine()) { 767 String forecastRec = in.nextLine(); 768 String[] tokens = forecastRec.split(delims5); 769 if (tokens[0].equals("2.A")) { 770 TmpStr1 = tokens[2]; 771 TmpStr2 = tokens[3]; 772 TmpStr3 = tokens[4]; 773 TmpStr4 = tokens[6]; 774 YearIntVal = Integer.parseInt(TmpStr1); 775 MonthIntVal = Integer.parseInt(TmpStr2); 776 DayIntVal = Integer.parseInt(TmpStr3); 777 HMSTimeIntVal = 100 * Integer.parseInt(TmpStr4); 778 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 779 TimeArray[XInc] = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 780 forecastRec = in.nextLine(); 781 tokens = forecastRec.split(delims5); 782 if (tokens.length == 2) { 783 TmpStr1 = tokens[0]; 784 TmpStr2 = tokens[1]; 785 } else { 786 /* 787 * expecting line like WITHIN 20 NM RADIUS OF POINT 788 * 22.2S / 50.8E 789 */ 790 TmpStr1 = tokens[6]; 791 TmpStr2 = tokens[7]; 792 } 793 NSFactor = (TmpStr1.charAt(TmpStr1.length() - 1) == 'N') ? 1.0 : -1.0; 794 WEFactor = (TmpStr2.charAt(TmpStr2.length() - 1) == 'W') ? 1.0 : -1.0; 795 LatitudeArray[XInc] = NSFactor 796 * Double.parseDouble(TmpStr1.substring(0, TmpStr1.length() - 1)); 797 LongitudeArray[XInc] = WEFactor 798 * Double.parseDouble(TmpStr2.substring(0, TmpStr2.length() - 1)); 799 } else if (tokens[0].equals("5.A")) { 800 TmpStr1 = tokens[tokens.length - 2]; 801 StrengthArray[XInc] = Double.parseDouble(TmpStr1); 802 } else if (tokens[0].equals("1.B")) { 803 XInc = 1; 804 forecastRec = in.nextLine(); 805 tokens = forecastRec.split(delims5); 806 boolean ICAOValidFcstTF = true; 807 while ((ICAOValidFcstTF) && (XInc < 6)) { 808 TmpStr1 = tokens[1]; 809 TmpStr2 = tokens[2]; 810 TmpStr3 = tokens[3]; 811 TmpStr4 = tokens[4]; 812 TmpStr5 = tokens[6]; 813 TmpStr6 = tokens[7]; 814 TmpStr7 = tokens[10]; 815 YearIntVal = Integer.parseInt(TmpStr1); 816 MonthIntVal = Integer.parseInt(TmpStr2); 817 DayIntVal = Integer.parseInt(TmpStr3); 818 HMSTimeIntVal = 10000 * Integer.parseInt(TmpStr4); 819 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 820 TimeArray[XInc] = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 821 NSFactor = (TmpStr5.charAt(TmpStr5.length() - 1) == 'N') ? 1.0 : -1.0; 822 WEFactor = (TmpStr6.charAt(TmpStr6.length() - 1) == 'W') ? 1.0 : -1.0; 823 LatitudeArray[XInc] = NSFactor 824 * Double.parseDouble(TmpStr5.substring(0, TmpStr5.length() - 1)); 825 LongitudeArray[XInc] = WEFactor 826 * Double.parseDouble(TmpStr6.substring(0, TmpStr6.length() - 1)); 827 StrengthArray[XInc] = (double) Integer 828 .parseInt(TmpStr7.substring(0, 3)); 829 forecastRec = in.nextLine(); 830 tokens = forecastRec.split(delims5); 831 String TmpStr0 = tokens[0]; 832 if (tokens[0].equals("2.C")) { 833 ICAOValidFcstTF = false; 834 } else { 835 if (TmpStr0.charAt(2) != 'H') { 836 forecastRec = in.nextLine(); 837 ICAOValidFcstTF = false; 838 } 839 } 840 XInc++; 841 } 842 } 843 } 844 } else if (ForecastFileType == 6) { 845 /* TCWC AXAU Tech Bulletins file input */ 846 String delims6 = "[,:/ ]+"; 847 JulianDayIntVal = 0; 848 MonthIntVal = 0; 849 YearIntVal = 0; 850 while (in.hasNextLine()) { 851 String forecastRec = in.nextLine(); 852 String[] tokens = forecastRec.split(delims6); 853 if (tokens[0].equals("at")) { 854 /* initial date */ 855 TmpStr1 = tokens[1]; 856 TmpStr2 = tokens[3]; 857 TmpStr3 = tokens[4]; 858 TmpStr4 = tokens[5]; 859 YearIntVal = Integer.parseInt(TmpStr4); 860 MonthIntVal = Integer.parseInt(TmpStr3); 861 DayIntVal = Integer.parseInt(TmpStr2); 862 /* HMSTimeIntVal = 100*Integer.parseInt(TmpStr1); */ 863 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 864 } 865 if (tokens[0].equals("Data")) { 866 /* initial time */ 867 TmpStr1 = tokens[2]; 868 HMSTimeIntVal = 100 * Integer.parseInt(TmpStr1); 869 TimeArray[XInc] = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 870 } 871 if (tokens[0].equals("Latitude")) { 872 /* initial latitude */ 873 TmpStr1 = tokens[1]; 874 NSFactor = (TmpStr1.charAt(TmpStr1.length() - 1) == 'N') ? 1.0 : -1.0; 875 LatitudeArray[XInc] = NSFactor 876 * Double.parseDouble(TmpStr1.substring(0, TmpStr1.length() - 1)); 877 } 878 if (tokens[0].equals("Longitude")) { 879 /* initial longitude */ 880 TmpStr1 = tokens[1]; 881 WEFactor = (TmpStr1.charAt(TmpStr1.length() - 1) == 'W') ? 1.0 : -1.0; 882 LongitudeArray[XInc] = WEFactor 883 * Double.parseDouble(TmpStr1.substring(0, TmpStr1.length() - 1)); 884 } 885 if (tokens[0].equals("Maximum")) { 886 if (tokens[1].equals("10-Minute")) { 887 /* initial strength */ 888 TmpStr1 = tokens[3]; 889 StrengthArray[XInc] = (double) Integer.parseInt(TmpStr1); 890 } 891 } 892 if (tokens[0].equals("FORECAST")) { 893 XInc = 1; 894 forecastRec = in.nextLine(); 895 forecastRec = in.nextLine(); 896 forecastRec = in.nextLine(); 897 tokens = forecastRec.split(delims6); 898 boolean ICAOValidFcstTF = true; 899 while ((ICAOValidFcstTF) && (XInc < 6)) { 900 TmpStr1 = tokens[1]; 901 TmpStr2 = tokens[2]; 902 TmpStr3 = tokens[3]; 903 TmpStr4 = tokens[4]; 904 TmpStr5 = tokens[7]; 905 DayIntVal = Integer.parseInt(TmpStr1); 906 HMSTimeIntVal = 100 * Integer.parseInt(TmpStr2); 907 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 908 TimeArray[XInc] = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 909 NSFactor = (TmpStr3.charAt(TmpStr3.length() - 1) == 'N') ? 1.0 : -1.0; 910 WEFactor = (TmpStr4.charAt(TmpStr4.length() - 1) == 'W') ? 1.0 : -1.0; 911 LatitudeArray[XInc] = NSFactor 912 * Double.parseDouble(TmpStr3.substring(0, TmpStr3.length() - 1)); 913 LongitudeArray[XInc] = WEFactor 914 * Double.parseDouble(TmpStr4.substring(0, TmpStr4.length() - 1)); 915 StrengthArray[XInc] = (double) Integer.parseInt(TmpStr5); 916 if (TimeArray[XInc] < TimeArray[XInc - 1]) { 917 MonthIntVal = MonthIntVal + 1; 918 /* YearIntVal=YearIntVal; */ 919 if (MonthIntVal == 13) { 920 YearIntVal = YearIntVal + 1; 921 MonthIntVal = 1; 922 } 923 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, 924 YearIntVal); 925 TimeArray[XInc] = Functions 926 .calctime(JulianDayIntVal, HMSTimeIntVal); 927 } 928 forecastRec = in.nextLine(); 929 tokens = forecastRec.split(delims6); 930 if (tokens[0].equals("REMARKS")) { 931 ICAOValidFcstTF = false; 932 } 933 XInc++; 934 } 935 } 936 } 937 } else if (ForecastFileType == 8) { 938 /* BEST - best track b-deck file input */ 939 int LastDateValueInt = 1; 940 while (in.hasNextLine()) { 941 String forecastRec = in.nextLine(); 942 String[] tokens = forecastRec.split(delims); 943 /* 944 * AL, 04, 2010073106, , BEST, 0, 88N, 329W, 20, 1009, LO, 945 * 0, , 0, 0, 0, 0, 1011, 180, 75, 0, 0, 946 */ 947 if (tokens[3].equals("BEST")) { 948 TmpStr1 = tokens[2]; 949 TmpStr2 = tokens[5]; 950 TmpStr3 = tokens[6]; 951 TmpStr4 = tokens[7]; 952 /* 953 * System.out.printf("1=%s* 2=%s* 3=%s* 4=%s*\n",TmpStr1, 954 * TmpStr2,TmpStr3,TmpStr4); 955 */ 956 YearIntVal = Integer.parseInt(TmpStr1.substring(0, 4)); 957 MonthIntVal = Integer.parseInt(TmpStr1.substring(4, 6)); 958 DayIntVal = Integer.parseInt(TmpStr1.substring(6, 8)); 959 HMSTimeIntVal = 10000 * Integer.parseInt(TmpStr1.substring(8, 10)); 960 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 961 /* 962 * System.out.printf( 963 * "day=%d month=%d year=%d hms=%d julian=%d \n" 964 * ,DayIntVal 965 * ,MonthIntVal,YearIntVal,HMSTimeIntVal,JulianDayIntVal 966 * ); 967 */ 968 double TmpTimeVal1 = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 969 NSFactor = (TmpStr2.charAt(TmpStr2.length() - 1) == 'N') ? 1.0 : -1.0; 970 WEFactor = (TmpStr3.charAt(TmpStr3.length() - 1) == 'W') ? 1.0 : -1.0; 971 int CurrentDateValueInt = HMSTimeIntVal; 972 if (CurrentDateValueInt != LastDateValueInt) { 973 /* 974 * System.out.printf("tmptimeval=%f currenttime=%f\n" 975 * ,TmpTimeVal1,CurrentTime); 976 */ 977 if (TmpTimeVal1 < CurrentTime) { 978 TimeArray[0] = TmpTimeVal1; 979 LatitudeArray[0] = NSFactor 980 * Double.parseDouble(TmpStr2.substring(0, 981 TmpStr2.length() - 1)) / 10.0; 982 LongitudeArray[0] = WEFactor 983 * Double.parseDouble(TmpStr3.substring(0, 984 TmpStr3.length() - 1)) / 10.0; 985 StrengthArray[0] = (double) Integer.parseInt(TmpStr4); 986 } else { 987 if ((TmpTimeVal1 >= CurrentTime) && (XInc < 5)) { 988 XInc++; 989 TimeArray[XInc] = TmpTimeVal1; 990 LatitudeArray[XInc] = NSFactor 991 * Double.parseDouble(TmpStr2.substring(0, 992 TmpStr2.length() - 1)) / 10.0; 993 LongitudeArray[XInc] = WEFactor 994 * Double.parseDouble(TmpStr3.substring(0, 995 TmpStr3.length() - 1)) / 10.0; 996 StrengthArray[XInc] = (double) Integer.parseInt(TmpStr4); 997 } 998 } 999 } 1000 LastDateValueInt = CurrentDateValueInt; 1001 } 1002 } 1003 } else if (ForecastFileType == 9) { 1004 /* HURDAT - best track file input */ 1005 while (in.hasNextLine()) { 1006 String forecastRec = in.nextLine(); 1007 String[] tokens = forecastRec.split(delims); 1008 TmpStr1 = tokens[2]; 1009 TmpStr2 = tokens[3]; 1010 TmpStr3 = tokens[4]; 1011 TmpStr4 = tokens[5]; 1012 TmpStr5 = tokens[6]; 1013 TmpStr6 = tokens[7]; 1014 TmpStr7 = tokens[8]; 1015 YearIntVal = Integer.parseInt(TmpStr1); 1016 MonthIntVal = Integer.parseInt(TmpStr2); 1017 DayIntVal = Integer.parseInt(TmpStr3); 1018 HMSTimeIntVal = (10000 * Integer.parseInt(TmpStr4)); 1019 JulianDayIntVal = Functions.idmyyd(DayIntVal, MonthIntVal, YearIntVal); 1020 double TmpTimeVal1 = Functions.calctime(JulianDayIntVal, HMSTimeIntVal); 1021 /* 1022 * NSFactor = (TmpStr5.charAt(TmpStr5.length()-1)=='N') ? 1023 * 1.0 : -1.0; 1024 */ 1025 /* 1026 * WEFactor = (TmpStr6.charAt(TmpStr6.length()-1)=='W') ? 1027 * 1.0 : -1.0; 1028 */ 1029 NSFactor = 1.0; 1030 WEFactor = 1.0; 1031 if (TmpTimeVal1 < CurrentTime) { 1032 TimeArray[0] = TmpTimeVal1; 1033 LatitudeArray[0] = NSFactor 1034 * Double.parseDouble(TmpStr5.substring(0, TmpStr5.length() - 1)); 1035 LongitudeArray[0] = WEFactor 1036 * Double.parseDouble(TmpStr6.substring(0, TmpStr6.length() - 1)); 1037 StrengthArray[0] = (double) Integer.parseInt(TmpStr7); 1038 } else { 1039 if ((TmpTimeVal1 >= CurrentTime) && (XInc < 5)) { 1040 XInc++; 1041 TimeArray[XInc] = TmpTimeVal1; 1042 LatitudeArray[XInc] = NSFactor 1043 * Double.parseDouble(TmpStr5.substring(0, TmpStr5.length() - 1)); 1044 LongitudeArray[XInc] = WEFactor 1045 * Double.parseDouble(TmpStr6.substring(0, TmpStr6.length() - 1)); 1046 StrengthArray[XInc] = (double) Integer.parseInt(TmpStr7); 1047 } 1048 } 1049 } 1050 } else { 1051 ReturnFlagValue = -2; 1052 } 1053 } catch (Exception e) { 1054 System.err.println("Failed to read Forecast file..."); 1055 in.close(); 1056 return null; 1057 } 1058 1059 int ZInc; 1060 int MinFcstValue; 1061 int LastDateJulianHoldValue = 0; 1062 int CurrentYear = 0; 1063 double StrengthValue = 0; 1064 double LastDateValue = 0; 1065 boolean ChangeHemispheresTF = false; 1066 boolean YearChangeFlag = false; 1067 1068 /* System.out.printf("returnflagvalue=%d\n",ReturnFlagValue); */ 1069 if (ReturnFlagValue >= 0) { 1070 StrengthValue = StrengthArray[0]; 1071 MinFcstValue = XInc; 1072 /* initialize forecast info array */ 1073 for (ZInc = 0; ZInc < 5; ZInc++) { 1074 ForecastTimes[ZInc] = 9999999.5; 1075 ForecastLatitudes[ZInc] = 999.5; 1076 ForecastLongitudes[ZInc] = 999.5; 1077 } 1078 /* XInc--; */ 1079 XInc = Math.min(5, XInc); 1080 /* 1081 * System.out.printf("%d %f %f %f\n",0,TimeArray[0],LatitudeArray[0] 1082 * ,LongitudeArray[0]); 1083 */ 1084 LastDateValue = TimeArray[0]; 1085 ForecastTimes[0] = TimeArray[0]; 1086 for (ZInc = 1; ZInc < XInc; ZInc++) { 1087 ForecastTimes[ZInc] = TimeArray[ZInc]; 1088 if ((TimeArray[ZInc] - LastDateValue) > 100.0) { 1089 /* there has been a year change during the forecast time */ 1090 if (!YearChangeFlag) { 1091 LastDateJulianHoldValue = (int) LastDateValue; 1092 YearChangeFlag = true; 1093 } 1094 CurrentYear = ((int) TimeArray[ZInc]) / 1000; 1095 CurrentDayValue = TimeArray[ZInc] - (double) (CurrentYear * 1000); 1096 TimeArray[ZInc] = (double) ((int) LastDateJulianHoldValue + CurrentDayValue); 1097 LastDateValue = TimeArray[ZInc]; 1098 } 1099 /* 1100 * System.out.printf("%d %f %f %f\n",ZInc,TimeArray[ZInc], 1101 * LatitudeArray[ZInc],LongitudeArray[ZInc]); 1102 */ 1103 if (Math.abs(LongitudeArray[ZInc] - LongitudeArray[0]) > 180.0) { 1104 /* 1105 * System.out.printf( 1106 * "changing hemispheres... adjusting longitude\n"); 1107 */ 1108 ChangeHemispheresTF = true; 1109 if (LongitudeArray[0] < 0) { 1110 LongitudeArray[ZInc] = -360.0 + LongitudeArray[ZInc]; 1111 } else { 1112 LongitudeArray[ZInc] = 360.0 + LongitudeArray[ZInc]; 1113 } 1114 /* 1115 * System.out.printf("%d %f %f %f\n",ZInc,TimeArray[ZInc], 1116 * LatitudeArray[ZInc],LongitudeArray[ZInc]); 1117 */ 1118 } 1119 } 1120 if (YearChangeFlag) { 1121 /* System.out.printf("YearChangeFlag=TRUE\n"); */ 1122 /* System.out.printf("CurrentTime=%f\n",CurrentTime); */ 1123 /* 1124 * need to adjust current image time to fit into adjusted date 1125 * array 1126 */ 1127 if ((CurrentTime - TimeArray[0]) > 100.0) { 1128 CurrentYear = ((int) CurrentTime) / 1000; 1129 CurrentDayValue = CurrentTime - (double) (CurrentYear * 1000); 1130 CurrentTime = (double) ((int) LastDateJulianHoldValue + CurrentDayValue); 1131 /* System.out.printf("CurrentTime=%f\n",CurrentTime); */ 1132 } 1133 } 1134 if (CurrentTime < TimeArray[0]) { 1135 /* 1136 * check to see if latest image is only 15 minutes before 1137 * current forecast time 1138 */ 1139 if (CurrentTime > (TimeArray[0] - .015)) 1140 TimeArray[0] = CurrentTime; 1141 } 1142 1143 /* determine number of valid forecast times for given image time */ 1144 YInc = 0; 1145 while ((TimeArray[YInc] <= CurrentTime) && (YInc < XInc)) { 1146 YInc++; 1147 } 1148 /* 1149 * System.out.printf( 1150 * "yinc=%d xinc=%d curtime=%f time0=%f threshtime=%f\n" 1151 * ,YInc,XInc,CurrentTime,TimeArray[0],ThresholdTime); 1152 */ 1153 if ((YInc == 0) && (TimeArray[0] != CurrentTime)) { 1154 /* 1155 * printf( 1156 * "INVALID FORECAST FILE, IMAGE BEFORE/AFTER FORECAST TIMES\n" 1157 * ); 1158 */ 1159 System.out.printf("%d %f %f %d\n", -1, -99.99, -999.99, 99); 1160 ReturnFlagValue = -1; 1161 } 1162 if ((YInc == XInc) && (CurrentTime >= TimeArray[XInc])) { 1163 System.out.printf("%d %f %f %d\n", -2, -99.99, -999.99, 99); 1164 ReturnFlagValue = -1; 1165 } 1166 if (ReturnFlagValue >= 0) { 1167 if ((CurrentTime - ThresholdTime) > TimeArray[0]) { 1168 /* printf("FORECAST FILE MORE THAN 24 HOURS OLD\n"); */ 1169 System.out.printf("%d %f %f %f\n", -3, -99.99, -999.99, -99.99); 1170 ReturnFlagValue = -1; 1171 } else { 1172 for (ZInc = 0; ZInc <= MinFcstValue; ZInc++) { 1173 ForecastLatitudes[ZInc] = LatitudeArray[ZInc]; 1174 ForecastLongitudes[ZInc] = LongitudeArray[ZInc]; 1175 } 1176 1177 double InterpLatitude = adt_polint(TimeArray, LatitudeArray, XInc, CurrentTime); 1178 double InterpLongitude = adt_polint(TimeArray, LongitudeArray, XInc, 1179 CurrentTime); 1180 1181 if ((InterpLatitude <= -999.) || (InterpLongitude <= -999.)) { 1182 System.out.printf("%d %f %f %f\n", -4, -99.99, -999.99, -99.99); 1183 ReturnFlagValue = -1; 1184 } else { 1185 if (ChangeHemispheresTF) { 1186 if (InterpLongitude > 180.0) { 1187 InterpLongitude = -360.0 + InterpLongitude; 1188 } else if (InterpLongitude < -180.0) { 1189 InterpLongitude = 360.0 + InterpLongitude; 1190 } else { 1191 /* InterpLongitude=InterpLongitude; */ 1192 } 1193 } 1194 System.out.printf("%d %f %f %f\n", 1, InterpLatitude, InterpLongitude, 1195 StrengthValue); 1196 ReturnLatitudeInterpolation = InterpLatitude; 1197 ReturnLongitudeInterpolation = InterpLongitude; 1198 ReturnFlagValue = 0; 1199 } /* ReturnFlagValue=-4 */ 1200 } /* ReturnFlagValue=-3 */ 1201 } /* ReturnFlagValue=-1/-2 */ 1202 } /* ReturnFlagValue=-6 */ 1203 1204 in.close(); 1205 1206 ReturnCurrentIntensity = StrengthValue; 1207 1208 /* McIDAS-V Conversion */ 1209 ReturnLongitudeInterpolation = -1.0 * ReturnLongitudeInterpolation; 1210 logger.debug("ReadForecasts out..."); 1211 1212 return new double[] { (double) ReturnFlagValue, ReturnLatitudeInterpolation, 1213 ReturnLongitudeInterpolation, ReturnCurrentIntensity }; 1214 1215 } 1216 1217 /** 1218 * Polynomial interpolation scheme program derived from FORTRAN program 1219 * POLINT in : Numerical Recipies - The Art of Scientific Computing, 1986, 1220 * Press, Flannery, Teukolsky, and Vetterling, Cambridge Press 1221 * 1222 * @param TimeArrayInput 1223 * Array containing time values. 1224 * @param PositionArrayInput 1225 * Array containing variable to interpolate. 1226 * @param NumberOfPointsInput 1227 * Number of points in array. 1228 * @param CurrentTime 1229 * Time to interpolate to. 1230 * 1231 * @return Interpolated position value. Note: if value is {@code -999.5}, it 1232 * means that the denominator is 0, signifying that there was an 1233 * interpolation error. 1234 */ 1235 private static double adt_polint(double[] TimeArrayInput, double[] PositionArrayInput, 1236 int NumberOfPointsInput, double CurrentTime) { 1237 double PositionValue; 1238 double PositionError; 1239 double DenominatorValue; 1240 double TimeDifferenceValue1; 1241 double TimeDifferenceValue2; 1242 double TimeValue1; 1243 double TimeValue2; 1244 double[] LocalArray1 = new double[10]; 1245 double[] LocalArray2 = new double[10]; 1246 int XInc; 1247 int YInc; 1248 int StoreValue = 1; 1249 1250 TimeDifferenceValue1 = Math.abs(CurrentTime - TimeArrayInput[0]); 1251 for (XInc = 1; XInc <= NumberOfPointsInput; XInc++) { 1252 TimeDifferenceValue2 = Math.abs(CurrentTime - TimeArrayInput[XInc - 1]); 1253 if (TimeDifferenceValue2 < TimeDifferenceValue1) { 1254 StoreValue = XInc; 1255 TimeDifferenceValue1 = TimeDifferenceValue2; 1256 } 1257 /* 1258 * System.out.printf("Xinc-1=%d position array=%f\n",XInc-1, 1259 * PositionArrayInput[XInc-1]); 1260 */ 1261 LocalArray1[XInc - 1] = PositionArrayInput[XInc - 1]; 1262 LocalArray2[XInc - 1] = PositionArrayInput[XInc - 1]; 1263 } 1264 double PositionValueLocal = PositionArrayInput[StoreValue - 1]; 1265 PositionError = 0.0; 1266 StoreValue--; 1267 for (YInc = 1; YInc <= NumberOfPointsInput - 1; YInc++) { 1268 for (XInc = 1; XInc <= NumberOfPointsInput - YInc; XInc++) { 1269 TimeValue1 = TimeArrayInput[XInc - 1] - CurrentTime; 1270 TimeValue2 = TimeArrayInput[(XInc - 1) + YInc] - CurrentTime; 1271 PositionValue = LocalArray1[XInc] - LocalArray2[XInc - 1]; 1272 DenominatorValue = TimeValue1 - TimeValue2; 1273 if (DenominatorValue == 0.0) { 1274 /* interpolation error - denominator = 0 */ 1275 return -999.5; /* EXIT */ 1276 } 1277 DenominatorValue = PositionValue / DenominatorValue; 1278 LocalArray1[XInc - 1] = TimeValue1 * DenominatorValue; 1279 LocalArray2[XInc - 1] = TimeValue2 * DenominatorValue; 1280 /* 1281 * System.out.printf( 1282 * "YInc=%d XInc=%d demon=%f local1=%f local2=%f\n" 1283 * ,YInc,XInc,DenominatorValue 1284 * ,LocalArray1[XInc-1],LocalArray2[XInc-1]); 1285 */ 1286 } 1287 if ((2 * StoreValue) < (NumberOfPointsInput - YInc)) { 1288 PositionError = LocalArray1[StoreValue]; 1289 } else { 1290 PositionError = LocalArray2[StoreValue - 1]; 1291 StoreValue--; 1292 } 1293 PositionValueLocal = PositionValueLocal + PositionError; 1294 } 1295 /* 1296 * System.out.printf("interpolated position=%f error=%f\n", 1297 * PositionValueLocal,PositionError); 1298 */ 1299 double InterpolatedPosition = PositionValueLocal; 1300 1301 /* 1302 * NOTE : additional function return point above - return -1 if 1303 * interpolation fails/denominator is zero 1304 */ 1305 1306 return InterpolatedPosition; 1307 1308 } 1309 1310}