Click the box titles below to expand:
How to's
XSLT
GOOGLE MAPS API
PHP
- PHP & Web Services — using SOAP to get meteorological data for a location
- PHP and Flickr accessing online photos through the phpFlickr class
Perl
Document Object Model (DOM)
UNIX
- Various snippets that make my life easier
- Create an Antelope Mail Archive
- Adding new projects to the Antelope contrib area using CVS
- Using Subversion to version control web sites
Generic Mapping Tools (GMT)
Miscellaneous
Projects
Courses Taught
Latest Favorites
- Best of Vim tips
- Make your pages load faster by combining and compressing javascript and css files
- Creating Liquid Faux Columns
- Setting up SSL under Apache 2 on SuSE
- PHP editing with ViM
- Getting equal-height columns in a three-column layout
- Star html Selector Bug
- Reset MySQL root account permissions
- How to write UNIX man pages
- Son of Suckerfish Dropdowns
- Aidan's PHP Repository
- Adium IM client
- ShapeShifter
- Install wiki on an iBook
- Quirksmode
- PHP
- GD
- JpGraph
- Vim Text Editor
- Generic Mapping Tools (GMT)
Mac OS X
Web Development
Beta
How To :: PHP & Web Services – using SOAP to get meteorological data for a location
1. The plan
So you want to show cool real time meteorological data on your website. In fact, you would like to show a five–day forecast for your exact location, and use the same images as NOAA use on their website. There are many ways of doing this, but seeing as I like PHP5 and I have been wanting to explore web–services, I decided to try and use PHP5's built–in SOAP functions. Luckily for me, NOAA already provides weather forecasts using Web Services Description Language (WSDL).
2. Ingredients — configuring PHP
First, you need to compile PHP5 with SOAP enabled. This is not the default. It is done by adding:
--enable-soap
to your compile command. You can test whether the SOAP functions are available by doing a couple of simple tests.
In your php.ini file there are a series of SOAP-related options, which I have set to the following values for testing purposes:
[soap] ; Enables or disables WSDL caching feature. soap.wsdl_cache_enabled=0 ; Sets the directory name where SOAP extension will put cache files. soap.wsdl_cache_dir="/tmp" ; (time to live) Sets the number of second while cached file will be used ; instead of original one. soap.wsdl_cache_ttl=0 ; maximum number of in memory cached wsdl files soap.wsdl_cache_limit=0
You basically want all caching turned off until you get the resultant XML just the way you want it.
3. Get the URL of the web–service
Once you have the URL, in this case http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl, you then need to instantiate a new SoapClient class. Using the code below does this, with the added bonus of the __getFunctions() function returning all the available functions for this web–service.
<?php $weather = new SoapClient( "http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" ) ; ?>
This query results in the following output:
[0]=> string(157) "string NDFDgen(decimal $latitude, decimal $longitude, productType $product, dateTime $startTime, dateTime $endTime, weatherParametersType $weatherParameters)" [1]=> string(113) "string NDFDgenByDay(decimal $latitude, decimal $longitude, date $startDate, integer $numDays, formatType $format)" }
This array shows the two functions available to you, NDFDgen and NDFDgenByDay and the various arguments they need in order to return some meaningful data to you. The web–service actually lists this on its page in the documentation tag:
The service has two exposed functions, NDFDgen and NDFDgenByDay. For the NDFDgen function, the client needs to provide a latitude and longitude pair and the product type. The client also needs to provide the start and end time of the period that it wants data for. For the time-series product, the client needs to provide an array of boolean values corresponding to which weather values should appear in the time series product. For the NDFDgenByDay function, the client needs to provide a latitude and longitude pair, the date it wants to start retrieving data for and the number of days worth of data. The client also needs to provide the format that is desired.
4. Define the metrics you want
From the NDFDgen function, you can see that one of the arguments is $weatherParameters. This is where you define what NOAA metrics you want to retrieve. There are many to choose from! The list below shows the available parameters. They need to be defined in an associative array:
- maxt : TRUE returns maximum temperature
- mint : TRUE returns minimum temperature
- temp : TRUE returns 3 hourly temperature
- dew : TRUE returns dewpoint temperature
- pop12 : TRUE returns POP12
- qpf : TRUE returns QPF
- sky : TRUE returns sky cover
- snow : TRUE returns snow amount
- wspd : TRUE returns wind speed
- wdir : TRUE returns wind direction
- wx : TRUE returns weather
- waveh : TRUE returns wave height
- icons : TRUE returns weather icon links
- rh : TRUE returns relative humidity
- appt : TRUE returns apparent temperature
- incw34 : TRUE returns Probability of a Tropical Cyclone Wind Speed >34 Knots (Incremental)
- incw50 : TRUE returns Probability of a Tropical Cyclone Wind Speed >50 Knots (Incremental)
- incw64 : TRUE returns Probability of a Tropical Cyclone Wind Speed >64 Knots (Incremental)
- cumw34 : TRUE returns Probability of a Tropical Cyclone Wind Speed >34 Knots (Cumulative)
- cumw50 : TRUE returns Probability of a Tropical Cyclone Wind Speed >50 Knots (Cumulative)
- cumw64 : TRUE returns Probability of a Tropical Cyclone Wind Speed >64 Knots (Cumulative)
- conhazo : TRUE returns probability of convection.
- ptornado : TRUE returns probability of tornadoes.
- phail : TRUE returns probability of hail.
- ptstmwinds : TRUE returns probability of damaging thunderstorms.
- pxtornado : TRUE returns probability of extreme tornadoes.
- pxhail : TRUE returns probability of extreme hail.
- pxtstmwinds : TRUE returns probability of extreme thunderstorm winds.
- ptotsvrtstm : TRUE returns probability of severe thunderstorms.
- pxtotsvrtstm : TRUE returns probability of extreme severe thunderstorms.
- wgust : TRUE returns wind gust
Define this in your PHP code as follows:
<?php "maxt" => true, "mint" => true, "temp" => true, "dew" => true, "pop12" => true, "qpf" => true, "sky" => true, "snow" => true, "wspd" => true, "wdir" => true, "wx" => true, "waveh" => true, "icons" => true, "rh" => true, "appt" => true, "incw34" => true, "incw50" => true, "incw64" => true, "cumw34" => true, "cumw50" => true, "cumw64" => true, "conhazo" => true, "ptornado" => true, "phail" => true, "ptstmwinds" => true, "pxtornado" => true, "pxhail" => true, "pxtstmwinds" => true, "ptotsvrtstm" => true, "pxtotsvrtstm" => true, "wgust" => true ) ; ?>
Now you are ready to make a basic SOAP request of this web–service!
5. Get the current day's weather for a latitude and longitude
The function NDFDgen requires:
- latitude – User supplied latitude (South latitude is negative)
- longitude – User supplied longitude (West Longitude is negative)
- product – User supplied product (time-series, glance, etc.)
- startTime – User supplied local time they want data for. This input is entered as a XML string (eg. 2004-04-13T12:00:00). This MUST be set to either now or some point in the future. If you insert a time in the past, you will get no data returned.
- endTime – User supplied local time they want data for. This input is entered as a XML string (eg. 2004-04-13T12:00:00). This MUST be set to either now or some point in the future. If you insert a time in the past, you will get no data returned.
<?php $test = $weather->NDFDgen( "35.225", "-120.111", "time-series", "2007-07-06T12:00:00", "2007-07-07T12:00:00", $weatherParameters ) ; echo $test ; ?>
The resultant XML from this SOAP query is:
Warning: Missing argument 1 for GeSHi::GeSHi(), called in /home/rnewman/public_html/howtos/php/soap_noaa_weather.php on line 238 and defined in /home/rnewman/public_html/ssi/geshi/geshi.php on line 411
Warning: Missing argument 2 for GeSHi::GeSHi(), called in /home/rnewman/public_html/howtos/php/soap_noaa_weather.php on line 238 and defined in /home/rnewman/public_html/ssi/geshi/geshi.php on line 411
<?xml version='1.0' ?> <dwml version='1.0' xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.nws.noaa.gov/forecasts/xml/DWMLgen/schema/DWML.xsd"> <head> <product concise-name="time-series" operational-mode="official" srsName="WGS 1984"> <title>NOAAs National Weather Service Forecast Data</title> <field>meteorological</field> <category>forecast</category> <creation-date refresh-frequency='PT1H'>2007-07-05T19:06:19Z</creation-date> </product> <source> <more-information>http://www.nws.noaa.gov/forecasts/xml/</more-information> <production-center>Meteorological Development Laboratory <sub-center>Product Generation Branch</sub-center></production-center> <disclaimer>http://www.nws.noaa.gov/disclaimer.html</disclaimer> <credit>http://www.weather.gov/</credit> <credit-logo>http://www.weather.gov/images/xml_logo.gif</credit-logo> <feedback>http://www.weather.gov/survey/nws-survey.php?code=xmlsoap</feedback> </source> </head> <data> <location> <location-key>point1</location-key> <point latitude="35.225" longitude="-120.111" /> </location> <time-layout time-coordinate="local" summarization="none"> <layout-key>k-p24h-n2-1</layout-key> <start-valid-time>2007-07-06T08:00:00-07:00</start-valid-time> <end-valid-time>2007-07-06T20:00:00-07:00</end-valid-time> <start-valid-time>2007-07-07T08:00:00-07:00</start-valid-time> <end-valid-time>2007-07-07T20:00:00-07:00</end-valid-time> </time-layout> <time-layout time-coordinate="local" summarization="none"> <layout-key>k-p24h-n1-2</layout-key> <start-valid-time>2007-07-06T20:00:00-07:00</start-valid-time> <end-valid-time>2007-07-07T09:00:00-07:00</end-valid-time> </time-layout> <time-layout time-coordinate="local" summarization="none"> <layout-key>k-p12h-n3-3</layout-key> <start-valid-time>2007-07-06T04:00:00-07:00</start-valid-time> <end-valid-time>2007-07-06T17:00:00-07:00</end-valid-time> <start-valid-time>2007-07-06T16:00:00-07:00</start-valid-time> <end-valid-time>2007-07-07T05:00:00-07:00</end-valid-time> <start-valid-time>2007-07-07T04:00:00-07:00</start-valid-time> <end-valid-time>2007-07-07T17:00:00-07:00</end-valid-time> </time-layout> <time-layout time-coordinate="local" summarization="none"> <layout-key>k-p24h-n2-4</layout-key> <start-valid-time>2007-07-06T05:00:00-07:00</start-valid-time> <end-valid-time>2007-07-07T05:00:00-07:00</end-valid-time> <start-valid-time>2007-07-07T05:00:00-07:00</start-valid-time> <end-valid-time>2007-07-08T05:00:00-07:00</end-valid-time> </time-layout> <time-layout time-coordinate="local" summarization="none"> <layout-key>k-p3h-n9-5</layout-key> <start-valid-time>2007-07-06T14:00:00-07:00</start-valid-time> <start-valid-time>2007-07-06T17:00:00-07:00</start-valid-time> <start-valid-time>2007-07-06T20:00:00-07:00</start-valid-time> <start-valid-time>2007-07-06T23:00:00-07:00</start-valid-time> <start-valid-time>2007-07-07T02:00:00-07:00</start-valid-time> <start-valid-time>2007-07-07T05:00:00-07:00</start-valid-time> <start-valid-time>2007-07-07T08:00:00-07:00</start-valid-time> <start-valid-time>2007-07-07T11:00:00-07:00</start-valid-time> <start-valid-time>2007-07-07T14:00:00-07:00</start-valid-time> </time-layout> <time-layout time-coordinate="local" summarization="none"> <layout-key>k-p6h-n5-6</layout-key> <start-valid-time>2007-07-06T10:00:00-07:00</start-valid-time> <end-valid-time>2007-07-06T17:00:00-07:00</end-valid-time> <start-valid-time>2007-07-06T16:00:00-07:00</start-valid-time> <end-valid-time>2007-07-06T23:00:00-07:00</end-valid-time> <start-valid-time>2007-07-06T22:00:00-07:00</start-valid-time> <end-valid-time>2007-07-07T05:00:00-07:00</end-valid-time> <start-valid-time>2007-07-07T04:00:00-07:00</start-valid-time> <end-valid-time>2007-07-07T11:00:00-07:00</end-valid-time> <start-valid-time>2007-07-07T10:00:00-07:00</start-valid-time> <end-valid-time>2007-07-07T17:00:00-07:00</end-valid-time> </time-layout> <time-layout time-coordinate="local" summarization="none"> <layout-key>k-p3h-n1-7</layout-key> <start-valid-time>2007-07-06T13:00:00-07:00</start-valid-time> <end-valid-time>2007-07-06T17:00:00-07:00</end-valid-time> </time-layout> <parameters applicable-location="point1"> <temperature type='maximum' units="Fahrenheit" time-layout="k-p24h-n2-1"> <name>Daily Maximum Temperature</name> <value>97</value> <value>95</value> </temperature> <temperature type='minimum' units="Fahrenheit" time-layout="k-p24h-n1-2"> <name>Daily Minimum Temperature</name> <value>61</value> </temperature> <temperature type='hourly' units="Fahrenheit" time-layout="k-p3h-n9-5"> <name>Temperature</name> <value>95</value> <value>96</value> <value>88</value> <value>76</value> <value>67</value> <value>62</value> <value>71</value> <value>86</value> <value>93</value> </temperature> <temperature type='dew point' units="Fahrenheit" time-layout="k-p3h-n9-5"> <name>Dew Point Temperature</name> <value>38</value> <value>38</value> <value>39</value> <value>40</value> <value>40</value> <value>41</value> <value>41</value> <value>42</value> <value>41</value> </temperature> <temperature type='apparent' units="Fahrenheit" time-layout="k-p3h-n9-5"> <name>Apparent Temperature</name> <value>91</value> <value>93</value> <value>85</value> <value>76</value> <value>67</value> <value>62</value> <value>71</value> <value>83</value> <value>89</value> </temperature> <precipitation type='liquid' units="inches" time-layout="k-p6h-n5-6"> <name>Liquid Precipitation Amount</name> <value>0.00</value> <value>0.00</value> <value>0.00</value> <value>0.00</value> <value>0.00</value> </precipitation> <precipitation type='snow' units="inches" time-layout="k-p3h-n1-7"> <name>Snow Amount</name> <value>0</value> </precipitation> <probability-of-precipitation type='12 hour' units="percent" time-layout="k-p12h-n3-3"> <name>12 Hourly Probability of Precipitation</name> <value>0</value> <value>0</value> <value>0</value> </probability-of-precipitation> <convective-hazard> <outlook time-layout="k-p24h-n2-4"> <name>Convective Hazard Outlook</name> <value>no thunderstorms</value> <value>no thunderstorms</value> </outlook> </convective-hazard> <convective-hazard> <severe-component type="severe thunderstorms" units="percent" time-layout="k-p24h-n2-4"> <name>Total Probability of Severe Thunderstorms</name> <value>0</value> <value>0</value> </severe-component> </convective-hazard> <convective-hazard> <severe-component type="extreme severe thunderstorms" units="percent" time-layout="k-p24h-n2-4"> <name>Total Probability of Extreme Severe Thunderstorms</name> <value>0</value> <value>0</value> </severe-component> </convective-hazard> <wind-speed type="incremental34" units="percent" time-layout="k-p6h-n5-6"> <name>Probability of a Tropical Cyclone Wind Speed >34 Knots (Incremental)</name> <value>0</value>