Free Weather Forecast
I noticed on the National Weather Service’s website they now allow you to grab the forecast by REST, whereas before they only supported SOAP requests. This makes grabbing the forecast much simpler than it was before.
If you use SOAP there are many methods to grab the data, but if you use REST there are only 2. With REST you can either use DWMLgen which lets you get a little more specific information or NDFDgenByDay which is a little simpler and lets you pick either 12 hour or 24 hour increments (so you can get each day broken in half as in day and night or the full day). The response is sent back as XML for either method so you can format the data how you like.
For the example we are doing, we are going to keep it simple and use a single location, NDFDgenByDay and a 24 hourly period. We will also set it up so that we send the longitude and latitude for Austin, TX, the current date as the start date and request 7 days worth of data.
You’ll want to get the longitude of the location you want the forecast for. The simplest way is to use Google Maps and type in your city and state and search. Then put your cursor slightly below the green arrow, basically as soon as it is not linking to the arrow. Now double click and the map may shift slightly. Now click on the Link to this page text and you will get a box and copy whats in the first textfield. You’ll get a huge URL like the one below.
http://maps.google.com/maps?ie=UTF8&oe=utf-8&client=firefox-a&q=Austin,+TX,+USA&ll=30.270928,-97.742615&spn=0.432311,0.6427&z=11
What we want is the longitude and latitude. In that long URL you’ll see &ll= and after it will be the longitude and latitude separated by a comma. And in this case it is 30.270928,-97.742615.
So let’s make the request and write it to a file. Here is the PHP to do that.
< ?php
//custom function to write a file
simple_write_file($filename, $data)
{
//write file
$fp = @fopen($filename, 'w'); //suppress error
if ($fp)
{
flock($fp, LOCK_EX);//lock file for writing
fwrite($fp, $data);
flock($fp, LOCK_UN);//release write lock
fclose($fp);
$output = '';
}
else
$output = 'Failed to open file.';
return $output;
}
$parameters = array('lat' => 30.270928, 'lon' => -97.742615, 'startDate' => date('Y-m-d'), 'numDays' => 7, 'format' => urlencode('24 hourly'));
$data = file_get_contents('http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?&lat='.$parameters['lat'].'&lon='.$parameters['lon'].'&format='.$parameters['format'].'&startDate='.$parameters['startDate'].'&numDays='.$parameters['numDays']);
simple_write_file('forecast.xml', $data);//NOTE: this will write the error to the file if it encounters one, but this is just for testing purposes
?>
The NWS recommends to make a new request 15 minutes after the hour and to cache the data for an hour. So you’ll want to write the code to cache it, but for this example we can just check the file and see if it’s good and then play with that file without having to make requests each time. Now here is some PHP code using SimpleXML to parse through the data in that file.
< ?php
$output = '';
//php5
if (file_exists('forecast.xml'))
{
$today = date('l');
$today_index = -1;
$xmlstr = file_get_contents('forecast.xml');
$xml = simplexml_load_string($xmlstr);
$xml_weather = $xml->data->parameters;//shorthand
$count = count($xml_weather->temperature->value);
$output .= '<ul id="weather_forecast">';
for($x = 0; $x < $count; $x++)
{
$output .= '<li>';
//convert time to timestamp
$timestamp = strtotime($xml->data->{'time-layout'}->{'start-valid-time'}[$x]);
$day = date('l', $timestamp);
//get the day of the week
$output .= '<strong class="day_of_week">';
if ($today == $day)
{
$output .= 'Today';
$today_index = $x + 1;
}
else if ($today_index == $x)
$output .= 'Tomorrow';
else
$output .= $day;
$output .= '</strong>';
//store it for shorthand multiple use
$condition = $xml_weather->weather->{'weather-conditions'}[$x]->attributes()->{'weather-summary'};
//icon image
$output .= ' ';
$output .= '<img src="';
$output .= basename($xml_weather-/>{'conditions-icon'}->{'icon-link'}[$x]);//get the filename, we are going to host the icons on our server
$output .= '" alt="' . htmlentities($condition, ENT_QUOTES) . '" />';//alt text is the condition
//conditions
$output .= ' ';
$output .= '<strong class="condition">';
$output .= $condition;
$output .= '</strong>';
//NOTE: 7th day low will usually be null, so dont bother showing the high
if ($x < 6)
{
//high and low
$output .= ' ';
$output .= '<span class="temperature">';
$output .= '<span class="temperature_high">' . $xml_weather->temperature[0]->value[$x] . '°</span>';//high
$output .= ' / ';
$output .= '<span class="temperature_low">' . $xml_weather->temperature[1]->value[$x] . '°</span>';//low
$output .= '';
}
//NOTE: precipitation is broken into 12hr periods and the 7th day's evening precipitation will usually be null
$output .= '';
}
$output .= '</ul>';
$output .= '<p class="credits">Weather by <a href="' . $xml->head->source->credit . '">NOAA</a></p>';
}
echo $output;
?>
The benefits to the NWS service are: you can make a request for up to 200 locations in one call, you can get weather from the past or several days ahead and use it on a commercial site.
Now combine this code with code I did before on getting current conditions and you one step closer to building your own portal. As I mentioned before, you can’t claim to have copyright on the data, but it is public domain information.