#! /usr/bin/perl
# example: ndfdgraph.cgi?lonlat=-82.35,35.51&var=temp
use CGI;
use XML::XPath;
$args = CGI::param('args');
($lon,$lat,$var,$rand) = split(',', $args);
$lon = Scrub($lon);
$lat = Scrub($lat);
$var = Scrub($var);
# (see http://www.weather.gov/forecasts/xml/rest.php for documentation)
$ndfdurl = "http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdXMLclient.php"
. "?lat=$lat"
. "&lon=$lon"
. "&product=time-series"
. "&begin=2009-09-01T00:00:00"
. "&end=2013-01-01T00:00:00"
. "&$var=$var";
$xmlresponse = `wget -q -O - '$ndfdurl'`;
my $xp = XML::XPath->new(xml => $xmlresponse);
@times = ();
foreach my $start_valid_time ($xp->find('//data/time-layout/start-valid-time')->get_nodelist){
push(@times, $start_valid_time->string_value);
}
@values = ();
foreach my $value ($xp->find('//parameters/*/value')->get_nodelist){
push(@values, $value->string_value);
}
($sec0,$min0,$hour0,$mday0,$mon0,$year0,$wday0,$yday0,$isdst0) =
localtime(time);
($sec1,$min1,$hour1,$mday1,$mon1,$year1,$wday1,$yday1,$isdst1) =
localtime(time + 60*60*24); # now + one day (number of seconds in a day is 60*60*24)
$time0 = sprintf("%04d%02d%02d%02d%02d", $year0+1900, $mon0+1, $mday0, $hour0, $min0);
$time1 = sprintf("%04d%02d%02d%02d%02d", $year1+1900, $mon1+1, $mday1, $hour1, $min1);
print("Content-type: text/xml\n\n");
print <<EOF
<mugl>
<legend opacity=".80" visible="true">
<icon width="20" height="20" border="0"/>
</legend>
<horizontalaxis type="datetime" min="${time0}" max="${time1}">
<labels format="%H:00%L%d %n" spacing="1D 12H 6H 4H 2H 1H" />
<title/>
</horizontalaxis>
<verticalaxis id="ftemp" type="number" min="50" max="80">
<title angle="90" anchor="0 -1">Degrees Fahrenheit</title>
</verticalaxis>
<plot>
<legend label="Forecast Temperature"/>
<verticalaxis><variable ref="temp"/></verticalaxis>
<renderer type="line">
<option name="linecolor" value="blue"/>
<option name="dotcolor" value="blue"/>
<option name="dotsize" value="2"/>
</renderer>
</plot>
<data>
<variables>
<variable id="time" type="datetime"/>
<variable id="temp"/>
</variables>
<values>
EOF
;
for ($i=0; $i<=$#times; ++$i) {
printf("%s,%s\n", MuglDateFormat($times[$i]), $values[$i]);
}
print <<EOF
</values>
</data>
</mugl>
EOF
;
sub MuglDateFormat {
my $date = shift;
$year = substr($date, 0, 4);
$mon = substr($date, 5, 2);
$day = substr($date, 8, 2);
$hour = substr($date, 11, 2);
$min = substr($date, 14, 2);
$sec = substr($date, 17, 2);
return sprintf("%04d%02d%02d%02d%02d",
$year, $mon, $day, $hour, $min);
}
sub NdfdDateFormat {
my $date = shift;
$year = substr($date, 0, 4);
$mon = substr($date, 4, 2);
$day = substr($date, 6, 2);
$hour = substr($date, 8, 2);
$min = substr($date, 10, 2);
$sec = substr($date, 12, 2);
return sprintf("%04d-%02d-%02dT%02d:%02d:%02d",
$year, $mon, $day, $hour, $min, $sec);
}
### maxt Maximum Temperature
### mint Minimum Temperature
### temp 3 Hourly Temperature
### dew Dewpoint Temperature
### appt Apparent Temperature
### pop12 12 Hour Probability of Precipitation
### qpf Liquid Precipitation Amount
### snow Snowfall Amount
### sky Cloud Cover Amount
### rh Relative Humidity
### wspd Wind Speed
### wdir Wind Direction
### wx Weather
### icons Weather Icons
### waveh Wave Height
### incw34 Probabilistic Tropical Cyclone Wind Speed >34 Knots (Incremental)
### incw50 Probabilistic Tropical Cyclone Wind Speed >50 Knots (Incremental)
### incw64 Probabilistic Tropical Cyclone Wind Speed >64 Knots (Incremental)
### cumw34 Probabilistic Tropical Cyclone Wind Speed >34 Knots (Cumulative)
### cumw50 Probabilistic Tropical Cyclone Wind Speed >50 Knots (Cumulative)
### cumw64 Probabilistic Tropical Cyclone Wind Speed >64 Knots (Cumulative)
### wgust Wind Gust
### conhazo Convective Hazard Outlook
### ptornado Probability of Tornadoes
### phail Probability of Hail
### ptstmwinds Probability of Damaging Thunderstorm Winds
### pxtornado Probability of Extreme Tornadoes
### pxhail Probability of Extreme Hail
### pxtstmwinds Probability of Extreme Thunderstorm Winds
### ptotsvrtstm Probability of Severe Thunderstorms
### pxtotsvrtstm Probability of Extreme Severe Thunderstorms
### tmpabv14d Probability of 8- To 14-Day Average Temperature Above Normal
### tmpblw14d Probability of 8- To 14-Day Average Temperature Below Normal
### tmpabv30d Probability of One-Month Average Temperature Above Normal
### tmpblw30d Probability of One-Month Average Temperature Below Normal
### tmpabv90d Probability of Three-Month Average Temperature Above Normal
### tmpblw90d Probability of Three-Month Average Temperature Below Normal
### prcpabv14d Probability of 8- To 14-Day Total Precipitation Above Median
### prcpblw14d Probability of 8- To 14-Day Total Precipitation Below Median
### prcpabv30d Probability of One-Month Total Precipitation Above Median
### prcpblw30d Probability of One-Month Total Precipitation Below Median
### prcpabv90d Probability of Three-Month Total Precipitation Above Median
### prcpblw90d Probability of Three-Month Total Precipitation Below Median
### precipa_r Real-time Mesoscale Analysis Precipitation
### sky_r Real-time Mesoscale Analysis GOES Effective Cloud Amount
### td_r Real-time Mesoscale Analysis Dewpoint Temperature
### temp_r Real-time Mesoscale Analysis Temperature
### wdir_r Real-time Mesoscale Analysis Wind Direction
### wwa Watches, Warnings, and Advisories
### wspd_r Real-time Mesoscale Analysis Wind Speed
########################################################################
sub ScrubDate {
my $date = shift;
my $year = substr($date, 0, 4);
my $mon = substr($date, 4, 2);
my $day = substr($date, 6, 2);
my $hour = substr($date, 8, 2);
my $min = substr($date, 10, 2);
return sprintf("%04d%02d%02d%02d%02d00",
$year, $mon, $day, $hour, $min);
}
sub Scrub {
my $x = shift;
$x =~ s/[^A-Za-z0-9_\.-]//g;
return $x;
}