0.0000000001) ? $dLat/$dPhi : cos($coord1['lat']); //if $dLon over 180� take shorter rhumb across 180� meridian: if (abs($dLon) > pi()) { $dLon = $dLon>0 ? -1*(2*pi()-$dLon) : (2*pi()+$dLon); } $dist = sqrt($dLat*$dLat + $q*$q*$dLon*$dLon) * R; $dir = fmod(rad2deg(atan2($dPhi,$dLon*-1))+270,360); return array($dist,$dir); } //$fp = fopen('http://www.aoml.noaa.gov/hrd/hurdat/tracks1851to2008_atl_reanal.html','r') or die ("can't open file"); //$basin="L"; $fp = fopen('http://www.nhc.noaa.gov/tracks1949to2008_epa.txt','r') or die ("can't open file"); $basin="E"; $storm_id=0; while ($s = fgets($fp,1024)) { //some rows doesn't have the 80 characters format (ie. 2008), so we pad them with spaces for unpack to work $str_len=strlen($s); $s=$str_len<80?str_pad($s,80," "):$s; if(strlen($s)<80) print($s); //parse the header if(stripos($s,"SNBR=")) { $fields = unpack('A6SeqNum1/A11StartDate/A2M/A3StormDays/A3StormNum/A5SNBR/A5TotalStormNum/A12StormName/A5XING/A2HitUS/A4SSS/A1HitUSCat/A20Padding/A1LastStorm',$s); $fields_StartDate=explode('/',trim($fields["StartDate"])); $year=$fields_StartDate[2]; $start_date=$year.$fields_StartDate[0].$fields_StartDate[1]; $storm_days=trim($fields["StormDays"]); $total_storm_num=trim($fields["TotalStormNum"]); $storm_num=trim($fields["StormNum"]); $storm_name=trim($fields["StormName"]); $hit_US=trim($fields["HitUS"]); $hit_US_cat=$fields["HitUSCat"]; $last_storm=$fields["LastStorm"]=='L'?1:0; $sql_storm_header="INSERT INTO StormHeader SET start_date='$start_date',storm_days='$storm_days'," . "storm_num='$storm_num',total_storm_num='$total_storm_num',storm_name='$storm_name'," . "hit_US='$hit_US',hit_US_cat='$hit_US_cat'," . "last_storm=$last_storm,basin='$basin' "; $res_storm_header=mysql_query($sql_storm_header); $storm_id=mysql_insert_id(); $may_be_xyear=false; $lat=0; $lon=0; //parse the observations } elseif (stripos($s,"/") && !stripos($s,"Z") && $storm_id) { $fields = unpack('A6SeqNum2/A5ObsDate/A1StormType00/A3Lat00/A5Long00/A4WindSpeed00/A4Pressure00/'. 'A1StormType06/A3Lat06/A5Long06/A4WindSpeed06/A4Pressure06/'. 'A1StormType12/A3Lat12/A5Long12/A4WindSpeed12/A4Pressure12/'. 'A1StormType18/A3Lat18/A5Long18/A4WindSpeed18/A4Pressure18/A1Asterisk',$s); $fields_ObsDate=explode('/',trim($fields["ObsDate"])); $latitude=0; $longitude=0; $direction=-1; $translational_speed=-1; $dist_dir=array(); for($i=0;$i<=18;$i=$i+6) { $gmt_time=$gmt=str_pad($i,2,"0",STR_PAD_LEFT); $gmt_time=str_pad($gmt_time,6,"0"); //for crossyear storms, we have to make a special consideration $obs_year=$may_be_xyear && $fields_ObsDate[0].$fields_ObsDate[1]!='1231'?$year+1:$year; if($fields_ObsDate[0].$fields_ObsDate[1]=='1231') { $may_be_xyear=true; } $obs_date=$obs_year.$fields_ObsDate[0].$fields_ObsDate[1].$gmt_time; $storm_type=$fields["StormType$gmt"]; $latitude=$fields["Lat$gmt"]/10; $longitude=trim($fields["Long$gmt"])/10>180?360-trim($fields["Long$gmt"])/10:-1*(trim($fields["Long$gmt"])/10); $wind_speed=trim($fields["WindSpeed$gmt"]); $central_pressure=trim($fields["Pressure".$gmt]); if($latitude) { //calculate the current bearing and translational speed (just valid when tracking points > 1) if($lat) { $dist_dir=loxodrome(array("lat"=>$lat,"lon"=>$lon),array("lat"=>$latitude,"lon"=>$longitude)); $direction=round($dist_dir[1]); $translational_speed=round($dist_dir[0]/(6*1.852));//in knots } $lat=$latitude; $lon=$longitude; $coordinate = "PointFromWKB(Point($longitude,$latitude))"; //all observations from each storm will be inserted as a block, hence the string appending $sql_values="('$storm_id','$obs_date','$storm_type','$latitude','$longitude','$wind_speed','$central_pressure','$translational_speed','$direction',$coordinate)"; $sql_append_values.=$sql_append_values?",$sql_values":"VALUES$sql_values"; } } $sql_storm_obs="INSERT INTO StormObservations (storm_id,obs_date,storm_type,latitude,longitude,wind_speed," . "central_pressure,translational_speed,direction,coordinate) ".$sql_append_values; $res_storm_obs=mysql_query($sql_storm_obs); $sql_append_values=''; //parse the footer } elseif(strlen(trim($s)) && $storm_id) { $fields = unpack('A6SeqNum3/A2MaxIntensity/A40LocHitUS/A32Remarks',$s); $max_intensity=$fields["MaxIntensity"]; $remarks=trim($fields["Remarks"]); $sql_storm_header_upd="UPDATE StormHeader SET max_intensity='$max_intensity',remarks='$remarks' " . "WHERE storm_id=$storm_id"; $res_storm_header_upd=mysql_query($sql_storm_header_upd); $fields_LocHitUS=preg_split( "/(\d)/",$fields["LocHitUS"],-1,PREG_SPLIT_DELIM_CAPTURE); $fields_LocHitUS=array_filter($fields_LocHitUS); for($i=0;$i