Active Storms\n
\n"; $linkListActiveNonHurricane = ""; // appended to linkListActive $linkListRecent = "

Recent Storms

\n
\n"; $months = array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); $timeSort = function($obj1,$obj2){ return strnatcmp($obj2['latest_observation'], $obj1['latest_observation']); }; $stormidSort = function($obj1,$obj2){ return strnatcmp($obj2['folder'], $obj1['folder']); }; // not using this for floaters $locationSort = function($obj1,$obj2) { if ($obj1['lat'] == $obj2['lat']) { return $obj1['lon'] - $obj1['lon']; } return strnatcmp($obj2['lat'], $obj1['lat']); }; $catContent = file_get_contents($catFile); // returns false if not successful $Catalog = json_decode($catContent,$assoc=true); if (($catContent) && (json_last_error() === 0)) { // does the catalog file exist and is it valid json? // usort($Catalog['catalogs'],$timeSort); // all should be sorted by time sort($Catalog['catalogs'],$stormidSort); // all should be sorted by $stormid, ascending foreach($Catalog['catalogs'] as $storm_id => $floater){ $current_details = end($floater['locations']); $stormid = $floater['folder']; if (substr($stormid,0,2) == $stormArea) { // storm is in the selected region $dateArray = date_parse($floater['latest_observation']); $month = $months[$dateArray['month']-1]; $humanDateTime = $dateArray['day'] . " " . $month . " " . $dateArray['year'] . " - " . str_pad($dateArray['hour'],2,'0',STR_PAD_LEFT) . ":" . str_pad($dateArray['minute'],2,'0',STR_PAD_LEFT) . " UTC"; $dateOnly = $dateArray['day'] . " " . $month . " " . $dateArray['year'] ; $StartDateArray = date_parse($floater['initial_observation']); $S_month = $months[$StartDateArray['month']-1]; $humanStartTime = $StartDateArray['day'] . " " . $S_month . " " . $StartDateArray['year'] . " - " . str_pad($StartDateArray['hour'],2,'0',STR_PAD_LEFT) . ":" . str_pad($StartDateArray['minute'],2,'0',STR_PAD_LEFT) . " UTC"; $StartDateOnly = $StartDateArray['day'] . " " . $S_month . " " . $StartDateArray['year'] ; $startTD = new DateTime($floater['locations'][0]['timestamp']); // now an object $latestObsTD = new DateTime($current_details['timestamp']); // now an object $duration = $startTD->diff($latestObsTD); $nowTime = new DateTime(); // stormAge is how long since last observation $renderThumbnail = true; $renderH3Link = true; // 12/3/2018 - added so that the h3 link ages off w/ the thumbnail $stormAge = $latestObsTD->diff($nowTime); $stormAgeDays = $stormAge->format('%a'); // handles positive or negative if ($stormAgeDays > 30) { $renderThumbnail = false; // $renderH3Link = false; // 12/3/2018 - comment this to test the link to floater summary page } $lat = $current_details['lat']; $lon = $current_details['lon']; $latVal = substr($lat,0,-1); $lonVal = substr($lon,0,-1); $refLat = 35.2; // reference latitude of eastern NC $refLon = 75.5; // reference longitude of eastern NC $proximityDec = getDistance($latVal, $lonVal, $refLat, $refLon); $proximity = ceil($proximityDec / 100)*100; // $proximity = round($proximityDec); $loc = $floater['friendly_name']; $type = $current_details['classification']; if (isset($current_details['description'])) { $descr = $current_details['description']; } else { $descr = ""; } $prettyLatLon = substr($lat,0,-1) . "°" . substr($lat,-1,1) . " - " . substr($lon,0,-1) . "°" . substr($lon,-1,1); $sampleRaw = $path . 'FLOATER/' . $stormid . '/13/thumbnail.jpg'; $hashString = mt_rand(10000,99999); // cache prevention coding for thumbnails $sample = $sampleRaw . "?hash=" . $hashString; $link = "
"; $link .= "\n"; if ($renderThumbnail) { $link .= "current thumbnail for " . $loc . "\n"; } $link .= "

"; if ($renderH3Link) { $link .= ""; } $link .= $type . " " . $loc . " - " . $prettyLatLon; if ($renderH3Link) { $link .= ""; } $link .= "

\n"; $link .= "
\n"; if (($stormArea == "AL") && ($lonVal < 70)) { // only render this value for storms that are out in the Atlantic somewhere $link .= "
Proximity:
\n
Approximately " . $proximity . " miles from U.S. East Coast.
\n"; } // accessing current meso locs to see which should be rendered with a given Floater information $M1LatVal = substr($activeMesoArray[0],0,-1); $M1LonVal = substr($activeMesoArray[1],0,-1); $M2LatVal = substr($activeMesoArray[2],0,-1); $M2LonVal = substr($activeMesoArray[3],0,-1); // comparing location of M1 to current Floater $latDiff1 = abs($latVal - $M1LatVal); $lonDiff1 = abs($lonVal - $M1LonVal); $posDiff1 = $latDiff1 + $lonDiff1; $MesoURL1 = "MESO_band.php?sat=" . $sat . "&lat=" . $activeMesoArray[0] . "&lon=" . $activeMesoArray[1] . "&band=13&length=30"; // echo "
posDiff1: " . $posDiff1; if ($posDiff1 < 5) { $Link1 = "
• Mesoscale loop 1"; } else { $Link1 = ""; } if(($M2LatVal !== "") && ($M2LonVal !== "")) { // if these 2 are empty, then there is no M2, and we don't do this block // comparing location of M2 to current Floater $latDiff2 = abs($latVal - $M2LatVal); $lonDiff2 = abs($lonVal - $M2LonVal); $posDiff2 = $latDiff2 + $lonDiff2; // echo "
posDiff2: " . $posDiff2; $MesoURL2 = "MESO_band.php?sat=" . $sat . "&lat=" . $activeMesoArray[2] . "&lon=" . $activeMesoArray[3] . "&band=13&length=30"; if ($posDiff2 < 5) { $Link2 = "
• Mesoscale loop 2"; } else { $Link2 = ""; } } $bothLinks = $Link1 . $Link2; $link .= "
Available images and loops for " . $loc .":
\n
"; // floater links for storms < 30 days old or currently active storms if ($renderThumbnail) { $link .= "• Storm channels and loops
\n"; } // show the FTP link for floater's images $link .= "• FTP Downloads\n"; $isActive = false; if (in_array($stormid,$Catalog['meta']['active_storms'])) { $isActive = true; } if ($isActive == true) { if (strlen($bothLinks) > 10) { $link .= $bothLinks; } } if (($stormArea == "AL") && ($isActive == true)) { // test to render the US East Coast sector view if (($latVal < 50) && ($latVal > 25) && ($lonVal < 80) && ($lonVal > 62)) { $link .= "
• U.S. East Coast\n"; } // test to render Gulf Of Mexico if (($latVal < 32) && ($latVal > 15) && ($lonVal > 78) && ($lonVal < 98)) { $link .= "
• Gulf of Mexico\n"; } // test to render Caribbean view if (($latVal < 40) && ($latVal > 0) && ($lonVal > 48) && ($lonVal < 85)) { $link .= "
• Caribbean view\n"; } // test to render TAW if (($latVal < 40) && ($latVal > 0) && ($lonVal > 10) && ($lonVal < 90)) { $link .= "
• Tropical Atlantic - wide view\n"; } } $link .= "
\n"; $link .= "
Latest NHC update:
\n
" . $humanDateTime . "
\n"; $link .= "
Started:
\n
" . $StartDateOnly . "
\n
Duration:
\n"; $link .= "
" . $duration->format('%d Day %h Hours') . "
\n"; if ($descr !== "") { $link .= "
Description:
\n
" . $descr . "
\n
\n"; } else { $link .= "
\n"; } $link .= "
\n"; if ((in_array($stormid,$Catalog['meta']['active_storms'])) && (strtolower($type)== "hurricane")) { $linkListActive .= $link; } if ((in_array($stormid,$Catalog['meta']['active_storms'])) && (strtolower($type)!== "hurricane")) { $linkListActiveNonHurricane .= $link; } else { $linkListRecent .= $link; } } $Link1 = ""; $Link2 = ""; $bothLinks = ""; // reset after each pass through the loop } // end of foreach $linkListActive .= $linkListActiveNonHurricane; if (strlen($linkListActive) < 60) { $linkListActive .= "

There are currently no active storms in this region.


\n"; } if (strlen($linkListRecent) < 60) { $linkListRecent .= "

There are no recently active storms in this region.

\n"; } $linkListActive .= "

\n\n"; $linkListRecent .= "\n"; $linkList = $linkListActive . $linkListRecent; } else { // catalog.json doesn't exist; render error messaging into the block $linkList = "

Error

\n

There are currently no storms being tracked by the NHC.
Please check back for future updates.

\n"; } return $linkList; } ?>