CRH.noaa.gov redirects (no point forecasts)
// Version 2.02 - 02-Mar-2007 - added auto-failover to CRH and better include in page.
// Version 2.03 - 29-Apr-2007 - modified for /images/wtf -> /forecast/images change
// Version 2.04 - 05-Jun-2007 - improvement to auto-failover
// Version 2.05 - 29-Jun-2007 - additional check for alternative no-icon forecast, then failover.
// Version 2.06 - 24-Nov-2007 - rewrite for zone forecast, intrepret icons from text-only forecast
// Version 2.07 - 24-Nov-2007 - support new zone forecast with different temp formats
// Version 2.08 - 25-Nov-2007 - fix zone forecast icons, new temp formats supported
// Version 2.09 - 26-Nov-2007 - add support for new temperature phrases and below zero temps
// Version 2.10 - 17-Dec-2007 - added safety features from Mike Challis http://www.carmosaic.com/weather/
// Version 2.11 - 20-Dec-2007 - added cache-refresh on request, fixed rising/falling temp arrow
// Version 2.12 - 31-Dec-2007 - fixed New Year"s to New Year's display problem
// Version 2.13 - 01-Jan-2008 - added integration features for carterlake/WD/PHP/AJAX template set
// Version 2.14 - 14-Jan-2009 - corrected Zone forecast parsing for below zero temperatures
// Version 2.15 - 28-Feb-2010 - updated Zone forecast parsing for new phrases
// Version 2.16 - 14-Dec-2010 - added support for warning messages from NWS and $forecastwarnings string
// Version 2.17 - 08-Jan-2011 - fixed validation issue when NWS uses '&' in condition
// Version 2.18 - 27-Feb-2011 - added support for common cache directory
// Version 3.00 - 12-Mar-2011 - support for multi-forecast added by Curly at http://www.ricksturf.com/
// Version 3.01 - 01-Oct-2011 - added support for alternative animated icon set from http://www.meteotreviglio.com/
// Version 3.02 - 05-Oct-2011 - corrected warning links to forecast.weather.gov
// Version 3.03 - 02-Jul-2012 - added fixes for NWS website changes
// Version 3.04 - 03-Jul-2012 - added fixes for W3C validation issues
// Version 3.05 - 05-Jul-2012 - added fixes for Zone forecast use with new NWS website design
// Version 3.06 - 07-Jul-2012 - fixed validation issue for Rising/Falling temp arrows with new NWS website design
// Version 3.07 - 09-Aug-2012 - fixed failover to Zone forecast with new NWS website design
// Version 3.08 - 23-Nov-2012 - fixed issue with Zone forecast parsing due to NWS website changes
// Version 3.09 - 28-Jun-2013 - added fixes for Zone forecast parsing due to NWS website changes
// Version 3.10 - 18-Nov-2013 - fixed issue with Zone forecast URL due to NWS website changes
// Version 3.11 - 13-Mar-2014 - fixed point forecast text non-display due to NWS website changes
// Version 3.12 - 15-Mar-2014 - fixes for Zone forecast, warnings and auto-correct old URLs
// Version 3.13 - 17-Mar-2015 - fixes for Zone forecast w/new NWS site design
// Version 3.14 - 31-Mar-2015 - fixes for NWS site changes
// Version 3.15 - 13-May-2015 - fix for Zone forecast w/NWS website change
// Version 3.16 - 15-May-2015 - fixes for different Zone forecast format in failover
// Version 4.00 - 06-Jul-2015 - added support for DualImage processing
// Version 4.01 - 07-Jul-2015 - fixed HTML for $forecasticons for new NWS website
// Version 4.02 - 07-Nov-2015 - fixed Zone forecast when using .gif icons issue
// Version 4.03 - 27-Feb-2018 - switched to curl processing and https for weather.gov access
// Version 4.04 - 12-Apr-2018 - fixes for Zone forecast Warning extraction for weather.gov changes
// Version 4.05 - 21-May-2018 - fix for NWS point-printable forecast page change
//
$Version = 'advforecast2.php (multi) - V4.05 - 21-May-2018';
//
//import NOAA Forecast info
//data ends up in four different arrays:
//$forecasticons[x] x = 0 thru 9 This is the icon and text around it
//$forecasttemp[x] x= 0 thru 9 This is forecast temperature with styling
//$forecasttitles[x] x = 0 thru 12 This is the title word for the text forecast time period
//$forecasttext[x] x = 0 thru 12 This is the detail text for the text forecast time period
//
//$forecastupdated This is the time of last update
//$forecastcity This is the city name for the forecast
//$forecastoffice This is the NWS Office providing the forecast
//$forecastwarnings This is the text/links to NWS Warnings, Watches, Advisories, Outlooks, Special Statements
//
//Also, in order for this to work correctly, you need the NOAA icons (or make your own...
//there are 750!). These need to be placed in the path where the original NOAA icons
//are located. In my case, they are at: \forecast\images\
//properly (so make a folder in your web HTML root called "forecast", then make a folder in it
//called "images", and place the icons in this folder)
//
//http://saratoga-weather.org/saratoga-icons.zip
//
//URL below --MUST BE-- the Printable Point Forecast from the NOAA website
//
//Not every area of the US has a printable point forecast
//
//This script will ONLY WORK with a printable point forecast!
//
//To find yours in your area:
//
//Go to www.weather.gov
//Put your city, state in the search box and press Search
//Scroll down to the "Additional Forecasts & Info" on the page displayed
//Click on Printable Forecast
// copy the URL from your browser into the $fileName variable below.
// Also put your NOAA Warning Zone (like ssZnnn) in caps in the $NOAAZone variable below.
//
// also set your NOAA warning zone here to use for automatic backup in case
// the point printable forecast is not available.
//
// ----------------------SETTINGS---------------------------------------------
// V3.00 -- this following array can be used for multiple forecasts in standalone mode
// for template use, add a $SITE['NWSforecasts'] entry in Settings.php to have these entries.
// to activate the definitions below, replace the /* with //* to uncomment the array definition
/*
$NWSforecasts = array(
// the entries below are for testing use.. replace them with your own entries if using the script
// outside the AJAX/PHP templates.
// ZONE|Location|point-forecast-URL (separated by | characters
"CAZ513|Saratoga, CA (WRH)|http://forecast.weather.gov/MapClick.php?CityName=Saratoga&state=CA&site=MTR&textField1=37.2639&textField2=-122.022&e=1&TextType=2",
"NEZ052|Omaha, NE (CRH)|http://forecast.weather.gov/MapClick.php?lat=41.2586&lon=-95.9378&unit=0&lg=english&FcstType=text&TextType=2",
"ALZ266|Gulf Shores, AL (SRH)|http://forecast.weather.gov/MapClick.php?CityName=Gulf+Shores&state=AL&site=MOB&textField1=30.27&textField2=-87.7015&e=0&TextType=2",
'MDZ022|Salisbury, MD (ERH)|http://forecast.weather.gov/MapClick.php?lat=38.36818&lon=-75.59761&unit=0&lg=english&FcstType=text&TextType=2',
'AKZ101|Anchorage, AK (ARH)|http://forecast.weather.gov/MapClick.php?lat=61.21806&lon=-149.90027780000003&unit=0&lg=english&FcstType=text&TextType=2',
'HIZ005|Honolulu, HI (HRH)|http://forecast.weather.gov/MapClick.php?lat=21.30694&lon=-157.85833330000003&unit=0&lg=english&FcstType=text&TextType=2',
'IAZ068|Riverdale, IA|http://forecast.weather.gov/MapClick.php?lat=41.5354&lon=-90.4671&unit=0&lg=english&FcstType=text&TextType=2',
'MEZ030|Bar Harbor, ME|http://forecast.weather.gov/MapClick.php?lat=44.76&lon=-67.5477&unit=0&lg=english&FcstType=text&TextType=2',
'TXZ147|Fairfield, TX|http://forecast.weather.gov/MapClick.php?&lat=31.7188&lon=-96.1655&lg=english&FcstType=text&TextType=2',
'SDZ021|Millbank, SD|http://forecast.weather.gov/MapClick.php?lat=45.194&lon=-96.6869&unit=0&lg=english&FcstType=text&TextType=2',
'MNZ034|Brainerd, MN|http://forecast.weather.gov/MapClick.php?lat=46.3544&lon=-94.1941&unit=0&lg=english&FcstType=text&TextType=2',
'COZ010|Vail, CO|http://forecast.weather.gov/MapClick.php?lat=39.5864&lon=-106.3822&unit=0&lg=english&FcstType=text&TextType=2',
'CAZ072|South Lake Tahoe, CA|http://forecast.weather.gov/MapClick.php?lat=38.93333&lon=-119.98333&unit=0&lg=english&FcstType=text&TextType=2',
'WAZ037|Colville, WA|http://forecast.weather.gov/MapClick.php?lat=48.5433&lon=-117.8951&unit=0&lg=english&FcstType=text&TextType=2',
'ILZ014|Hoffman Estates, IL|http://forecast.weather.gov/MapClick.php?lat=42.03921&lon=-88.11001&unit=0&lg=english&FcstType=text&TextType=2',
'NDZ027|Grand Forks, ND|http://forecast.weather.gov/MapClick.php?lat=47.9169&lon=-97.072&unit=0&lg=english&FcstType=text&TextType=2',
'MTZ055|Bozeman, MT|http://forecast.weather.gov/MapClick.php?lat=45.6354&lon=-111.0633&unit=0&lg=english&FcstType=text&TextType=2',
"AZZ023|Phoenix|http://forecast.weather.gov/MapClick.php?CityName=Phoenix&state=AZ&site=PSR&textField1=33.646&textField2=-112.007&e=0&TextType=2",
'KSZ078|Dodge City, KS|http://forecast.weather.gov/MapClick.php?lat=37.7528&lon=-100.0171&unit=0&lg=english&FcstType=text&TextType=2',
'OKZ020|Stillwater, OK|http://forecast.weather.gov/MapClick.php?lat=36.1156&lon=-97.0584&unit=0&lg=english&FcstType=text&TextType=2',
'GAZ034|Lawrenceville, GA|http://forecast.weather.gov/MapClick.php?CityName=Lawrenceville&state=GA&site=FFC&lat=33.9495&lon=-83.9922&TextType=2',
'ARZ011|Rockhouse, AR|http://forecast.weather.gov/MapClick.php?lat=36.289&lon=-93.7258&unit=0&lg=english&FcstType=text&TextType=2',
'ARZ040|Mena, AR|http://forecast.weather.gov/MapClick.php?lat=34.6036&lon=-94.2631&unit=0&lg=english&FcstType=text&TextType=2',
'MOZ090|Springfield, MO|http://forecast.weather.gov/MapClick.php?lat=37.1962&lon=-93.2861&unit=0&lg=english&FcstType=text&TextType=2',
'MTZ019|Plentywood, MT|http://forecast.weather.gov/MapClick.php?lat=48.7747&lon=-104.5625&unit=0&lg=english&FcstType=text&TextType=2',
'ARZ044|Little Rock, AR|http://forecast.weather.gov/MapClick.php?lat=34.7224&lon=-92.3541&unit=0&lg=english&FcstType=text&TextType=2',
"NYZ040|Hessville, NY|http://forecast.weather.gov/MapClick.php?CityName=Hessville&state=NY&site=MTR&textField1=42.8739&textField2=-74.687&e=1&TextType=2",
"NYZ049|Albany, NY|http://forecast.weather.gov/MapClick.php?CityName=Albany&state=NY&site=MTR&textField1=42.6525&textField2=-73.757&e=0&TextType=2",
"NYZ056|Binghamton, NY|http://forecast.weather.gov/MapClick.php?CityName=Binghamton&state=NY&site=MTR&textField1=42.0956&textField2=-75.910&e=0&TextType=2",
"MAZ017|Boston, MA|http://forecast.weather.gov/MapClick.php?CityName=Boston&state=MA&site=MTR&textField1=42.3586&textField2=-71.060&e=0&TextType=2",
"MNZ060|Robbinsdale, MN|http://forecast.weather.gov/MapClick.php?lat=45.02233988655459&lon=-93.34722518920898&site=mpx&unit=0&lg=en&FcstType=text&TextType=2"
);
//*/
//
$NOAAZone = 'CAZ513'; // change this line to your NOAA warning zone.
// set $fileName to the URL for the point-printable forecast for your area
$fileName = "http://forecast.weather.gov/MapClick.php?CityName=Saratoga&state=CA&site=MTR&textField1=37.2639&textField2=-122.022&e=1&TextType=2";
//
#$iconDir = './forecast/imagesPNG-86x86/';
#$iconDir = './forecast/imagesGIF-55x58/';
$iconDir = './forecast/images/';
$iconType = '.jpg'; // default type='.jpg' -- use '.gif' for animated icons from http://www.meteotreviglio.com/
$cacheFileDir = './'; // default cache file directory
$iconHeight = 55; // default height of conditions icon (saratoga-icons.zip)
$iconWidth = 55; // default width of conditions icon (saratoga-icons.zip)
$refreshTime = 600; // default refresh of cache 600=10 minutes
// ----------------------END OF SETTINGS--------------------------------------
$forceDualIconURL = false; // for TESTING prior to 7-Jul-2015 when new icons were used by NWS
//
// overrides from Settings.php if available
if(file_exists('Settings.php')) { include_once('Settings.php'); }
global $SITE;
if (isset($SITE['NWSforecasts'])) {$NWSforecasts = $SITE['NWSforecasts']; }
if (isset($SITE['cacheFileDir'])) {$cacheFileDir = $SITE['cacheFileDir']; }
if (isset($SITE['noaazone'])) {$NOAAZone = $SITE['noaazone'];}
if (isset($SITE['fcsturlNWS'])) {$fileName = $SITE['fcsturlNWS'];}
if (isset($SITE['fcsticonsdir'])) {$iconDir = $SITE['fcsticonsdir'];}
if (isset($SITE['fcsticonstype'])) {$iconType = $SITE['fcsticonstype'];}
if (isset($SITE['fcsticonsheight'])) {$iconHeight = $SITE['fcsticonsheight'];}
if (isset($SITE['fcsticonswidth'])) {$iconWidth = $SITE['fcsticonswidth'];}
// end of overrides from Settings.php
$doDebug = (isset($_REQUEST['debug']) and preg_match('|y|i',$_REQUEST['debug']))?true:false;
// get the selected zone code
$haveZone = '0';
if (!empty($_GET['z']) && preg_match("/^[0-9]+$/i", htmlspecialchars($_GET['z']))) {
$haveZone = htmlspecialchars(strip_tags($_GET['z'])); // valid zone syntax from input
}
$DualImageAvailable = file_exists("./DualImage.php")?true:false;
#$DualImageAvailable = false;
if(!isset($NWSforecasts[0])) {
// print "\n";
$NWSforecasts = array("$NOAAZone||$fileName"); // create default entry
}
// print "\n";
// Set the default zone. The first entry in the $SITE['NWSforecasts'] array.
list($Nz,$Nl,$Nn) = explode('|',$NWSforecasts[0].'|||');
$NOAAZone = $Nz;
$NOAAlocation = $Nl;
$fileName = $Nn;
$newFormat = false;
if(!isset($NWSforecasts[$haveZone])) {
$haveZone = 0;
}
// locations added to the drop down menu and set selected zone values
$dDownMenu = '';
for ($m=0;$m ]*>(.*)
';
}
// This is version 1.2 with Ken's modifications from Saratoga Weather
// http://saratoga-weather.org/
// You can now force the cache to update by adding ?force=1 to the end of the URL
if ( empty($_REQUEST['force']) )
$_REQUEST['force']="0";
$Force = $_REQUEST['force'];
$forceBackup = false;
if ($Force > 1) {$forceBackup = true; }
$cacheName = $cacheFileDir."forecast-".$NOAAZone."-$haveZone.txt";
// dont change the next line....
//$backupfileName = "http://forecast.weather.gov/MapClick.php?zoneid=$NOAAZone&TextType=2";
// new Zone URL with V3.10:
$backupfileName = "https://forecast.weather.gov/MapClick.php?zoneid=$NOAAZone&zflg=1";
// /MapClick.php?zoneid=CAZ513&zflg=1
if (isset($_REQUEST['sce']) && strtolower($_REQUEST['sce']) == 'view' ) {
//--self downloader --
$filenameReal = __FILE__;
$download_size = filesize($filenameReal);
header('Pragma: public');
header('Cache-Control: private');
header('Cache-Control: no-cache, must-revalidate');
header("Content-type: text/plain");
header("Accept-Ranges: bytes");
header("Content-Length: $download_size");
header('Connection: close');
readfile($filenameReal);
exit;
}
$fcstPeriods = array( // for filling in the '
',$start); }
$length = $finish-$start;
$forecastop = substr($html, $start, $length);
$Status .= "\n";
/*
'); }
$start = $startgrab;
$finish = strpos($html, '
|Uis', $forecastop, $headers);
}
$forecaststuff = $headers[2];
$Status .= "\n";
// Breakup multi-day forecasts if needed
$i = 0;
foreach ($headers[1] as $j => $period) {
if (preg_match('/^(.*) (Through|And) (.*)/i',$period,$mtemp)) { // got period1 thru period2
list($fcstLow,$fcstHigh) = explode("\t",split_fcst($headers[2][$j]));
$startPeriod = $mtemp[1];
$periodType = $mtemp[2];
$endPeriod = $mtemp[3];
$startIndex = 0;
$endIndex = 0;
$Status .= "\n";
for ($k=0;$k',$startgrab);
$finish = strpos($html, '
',$start);
$length = $finish-$start;
$forecastop = substr($html, $start, $length);
// print "\n";
// Chop up each icon html and place in array
preg_match_all("|
\s+$|is',"",$forecasticons[$i]);
$forecasticons[$i] = preg_replace('|
|is',"
",$forecasticons[$i]);
$forecasticons[$i] = preg_replace('|
|is','" />
',$forecasticons[$i]);
$forecasticons[$i] = preg_replace('|(.*)|Uis',
"$2",$forecasticons[$i]);
// $Status .= "\n";
preg_match_all('|
([^<]+)(
[1] =>
[2] => Partly Sunny
then Slight
Chance
T-storms
[3] => High: 52 °F
)
[1] => Array
(
[0] => Friday
[1] =>
[2] => Patchy Fog
then Mostly
Sunny
[3] => High: 80 °F
)
*/
$forecasttemp[$i] = $matches[1][3];
if(preg_match('|High|i',$forecasttemp[$i])) {
$color = '#FF0000';
$tHL = 'Hi';
} else {
$color = '#0000FF';
$tHL = 'Lo';
}
$tIcon = str_replace('">','"/>
',$matches[1][1]); # HTML Strict
if(!$DualImageAvailable and preg_match('|DualImage.php\?([^"]+)"|',$tIcon,$tMatch)) {
# Oops.. take first image and posible PoP for static image instead.
$targs = $tMatch[1];
$Status .= "\n";
$tIcon = str_replace('DualImage.php?'.$targs,$fn,$tIcon);
}
}
$forecasttemp[$i] = preg_replace('|^(.*) (.*)°F|Uis',
"$tHL $2 °F",$forecasttemp[$i]);
$forecasticons[$i] = $matches[1][0] . $tIcon . $matches[1][2];
$forecasticons[$i] = str_replace('
','
',$forecasticons[$i]);
$Status .= "\n\n";
} else {
if(isset($matches[2][0]) and preg_match('||i',$matches[2][0])) {
$t = $matches[2][0];
//
$t = preg_replace('|
]*>|i',
"
",$t);
$matches[2][0] = $t;
$forecasticons[$i] = str_replace('
','
',$forecasticons[$i]);
$Status .= "\n\n";
}
}
if (! $isZone and !$newFormat) {
$forecasttemp[$i] = $matches[1][0] . $matches[2][0]; // just the temp line
# mchallis added security feature
$forecasttemp[$i] = strip_tags($forecasttemp[$i], '');
}
// remove the temp from the forecasticons
if(isset($matches[0][0])) {
$forecasticons[$i] = preg_replace('|'.$matches[0][0].'|is','',$forecasticons[$i]);
}
// fix up the
to be
for XHTML compatibility
$forecasticons[$i] = str_replace('
','
',$forecasticons[$i]);
# mchallis added security feature
$forecasticons[$i] = strip_tags($forecasticons[$i], '');
// $forecasttemp[$i] = preg_replace('|
|Uis','
',$forecasttemp[$i]);
// $forecasttemp[$i] = trim($forecasttemp[$i]);
$forecasticons[$i] = preg_replace('/&/','&',$forecasticons[$i]);
$forecasticons[$i] = preg_replace('|Thunderstorm|','T-Storm',$forecasticons[$i]);
$forecasticons[$i] = preg_replace('|height="[^"]+"|i',"height=\"$iconHeight\"",
$forecasticons[$i]);
$forecasticons[$i] = preg_replace('|width="[^"]+"|i',"width=\"$iconWidth\"",$forecasticons[$i]);
}
// $Status .= "\n";
// end saratoga-weather.org XHTML 1.0-Strict mod
if ($isZone) { // special handling for ERH->CRH redirection
/*
Last Update:
850 AM PDT MON MAR 16 2015
*/
// Grab the Last Update date and time.
preg_match('|Last Update(.*?)
|', $html, $betweenspan);
if(!isset($betweenspan[1])) {
// Last Update: 150 AM PST FRI NOV 23 2012
preg_match('|Last Update: \s*
San Francisco Bay Area/Monterey, CA Local Forecast Office
More Information:
*/
preg_match('||Uis',$html,$betweenspan);
if(!isset($betweenspan[1])) {
preg_match('|
Issued by: ([^<]+)
|Uis',$html,$betweenspan);
}
// $Status .= "\n";
if(isset($betweenspan[1])) {
$forecastoffice = 'NWS ' . trim($betweenspan[1]);
} else {
$forecastoffice = '';
}
$Status .= "\n";
} else { // begin regular handling
// Now get just the bottom of the NWS page for editing
// preg_match('|
National Weather Service Forecast for:
Issued by: |
Updated: |
|
'') { print $forecastwarnings; } ?>
$forecasttitles[$i] | \n";
print "$forecasttext[$i] | \n"; print "\n"; } ?>
Forecast from NOAA-NWS
for .
'.jpg') {
print "
Animated forecast icons courtesy of www.meteotreviglio.com.";
}
?>