Click the box titles below to expand:

How to's

XSLT

GOOGLE MAPS API

PHP

Perl

Document Object Model (DOM)

UNIX

Generic Mapping Tools (GMT)

Miscellaneous

Projects

Courses Taught

Latest Favorites

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.

  1. <?php
  2. $weather = new SoapClient( "http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl" ) ;
  3. var_dump( $weather->__getFunctions() ) ;
  4. ?>

This query results in the following output:

  1. array(2) {
  2. [0]=>
  3. string(157) "string NDFDgen(decimal $latitude, decimal $longitude, productType $product, dateTime $startTime, dateTime $endTime, weatherParametersType $weatherParameters)"
  4. [1]=>
  5. string(113) "string NDFDgenByDay(decimal $latitude, decimal $longitude, date $startDate, integer $numDays, formatType $format)"
  6. }

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:

Define this in your PHP code as follows:

  1. <?php
  2. $weatherParameters = array(
  3. "maxt" => true,
  4. "mint" => true,
  5. "temp" => true,
  6. "dew" => true,
  7. "pop12" => true,
  8. "qpf" => true,
  9. "sky" => true,
  10. "snow" => true,
  11. "wspd" => true,
  12. "wdir" => true,
  13. "wx" => true,
  14. "waveh" => true,
  15. "icons" => true,
  16. "rh" => true,
  17. "appt" => true,
  18. "incw34" => true,
  19. "incw50" => true,
  20. "incw64" => true,
  21. "cumw34" => true,
  22. "cumw50" => true,
  23. "cumw64" => true,
  24. "conhazo" => true,
  25. "ptornado" => true,
  26. "phail" => true,
  27. "ptstmwinds" => true,
  28. "pxtornado" => true,
  29. "pxhail" => true,
  30. "pxtstmwinds" => true,
  31. "ptotsvrtstm" => true,
  32. "pxtotsvrtstm" => true,
  33. "wgust" => true
  34. ) ;
  35. ?>

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:

  1. <?php
  2. $test = $weather->NDFDgen(
  3. "35.225",
  4. "-120.111",
  5. "time-series",
  6. "2007-07-06T12:00:00",
  7. "2007-07-07T12:00:00",
  8. $weatherParameters ) ;
  9. echo $test ;
  10. ?>

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
  1. <?xml version='1.0' ?>
  2. <dwml version='1.0' xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:noNamespaceSchemaLocation="http://www.nws.noaa.gov/forecasts/xml/DWMLgen/schema/DWML.xsd">
  5. <head>
  6. <product concise-name="time-series" operational-mode="official" srsName="WGS 1984">
  7. <title>NOAAs National Weather Service Forecast Data</title>
  8. <field>meteorological</field>
  9. <category>forecast</category>
  10. <creation-date refresh-frequency='PT1H'>2007-07-05T19:06:19Z</creation-date>
  11. </product>
  12. <source>
  13. <more-information>http://www.nws.noaa.gov/forecasts/xml/</more-information>
  14. <production-center>Meteorological Development Laboratory <sub-center>Product Generation Branch</sub-center></production-center>
  15. <disclaimer>http://www.nws.noaa.gov/disclaimer.html</disclaimer>
  16. <credit>http://www.weather.gov/</credit>
  17. <credit-logo>http://www.weather.gov/images/xml_logo.gif</credit-logo>
  18. <feedback>http://www.weather.gov/survey/nws-survey.php?code=xmlsoap</feedback>
  19. </source>
  20. </head>
  21. <data>
  22. <location>
  23. <location-key>point1</location-key>
  24. <point latitude="35.225" longitude="-120.111" />
  25. </location>
  26. <time-layout time-coordinate="local" summarization="none">
  27. <layout-key>k-p24h-n2-1</layout-key>
  28. <start-valid-time>2007-07-06T08:00:00-07:00</start-valid-time>
  29. <end-valid-time>2007-07-06T20:00:00-07:00</end-valid-time>
  30. <start-valid-time>2007-07-07T08:00:00-07:00</start-valid-time>
  31. <end-valid-time>2007-07-07T20:00:00-07:00</end-valid-time>
  32. </time-layout>
  33. <time-layout time-coordinate="local" summarization="none">
  34. <layout-key>k-p24h-n1-2</layout-key>
  35. <start-valid-time>2007-07-06T20:00:00-07:00</start-valid-time>
  36. <end-valid-time>2007-07-07T09:00:00-07:00</end-valid-time>
  37. </time-layout>
  38. <time-layout time-coordinate="local" summarization="none">
  39. <layout-key>k-p12h-n3-3</layout-key>
  40. <start-valid-time>2007-07-06T04:00:00-07:00</start-valid-time>
  41. <end-valid-time>2007-07-06T17:00:00-07:00</end-valid-time>
  42. <start-valid-time>2007-07-06T16:00:00-07:00</start-valid-time>
  43. <end-valid-time>2007-07-07T05:00:00-07:00</end-valid-time>
  44. <start-valid-time>2007-07-07T04:00:00-07:00</start-valid-time>
  45. <end-valid-time>2007-07-07T17:00:00-07:00</end-valid-time>
  46. </time-layout>
  47. <time-layout time-coordinate="local" summarization="none">
  48. <layout-key>k-p24h-n2-4</layout-key>
  49. <start-valid-time>2007-07-06T05:00:00-07:00</start-valid-time>
  50. <end-valid-time>2007-07-07T05:00:00-07:00</end-valid-time>
  51. <start-valid-time>2007-07-07T05:00:00-07:00</start-valid-time>
  52. <end-valid-time>2007-07-08T05:00:00-07:00</end-valid-time>
  53. </time-layout>
  54. <time-layout time-coordinate="local" summarization="none">
  55. <layout-key>k-p3h-n9-5</layout-key>
  56. <start-valid-time>2007-07-06T14:00:00-07:00</start-valid-time>
  57. <start-valid-time>2007-07-06T17:00:00-07:00</start-valid-time>
  58. <start-valid-time>2007-07-06T20:00:00-07:00</start-valid-time>
  59. <start-valid-time>2007-07-06T23:00:00-07:00</start-valid-time>
  60. <start-valid-time>2007-07-07T02:00:00-07:00</start-valid-time>
  61. <start-valid-time>2007-07-07T05:00:00-07:00</start-valid-time>
  62. <start-valid-time>2007-07-07T08:00:00-07:00</start-valid-time>
  63. <start-valid-time>2007-07-07T11:00:00-07:00</start-valid-time>
  64. <start-valid-time>2007-07-07T14:00:00-07:00</start-valid-time>
  65. </time-layout>
  66. <time-layout time-coordinate="local" summarization="none">
  67. <layout-key>k-p6h-n5-6</layout-key>
  68. <start-valid-time>2007-07-06T10:00:00-07:00</start-valid-time>
  69. <end-valid-time>2007-07-06T17:00:00-07:00</end-valid-time>
  70. <start-valid-time>2007-07-06T16:00:00-07:00</start-valid-time>
  71. <end-valid-time>2007-07-06T23:00:00-07:00</end-valid-time>
  72. <start-valid-time>2007-07-06T22:00:00-07:00</start-valid-time>
  73. <end-valid-time>2007-07-07T05:00:00-07:00</end-valid-time>
  74. <start-valid-time>2007-07-07T04:00:00-07:00</start-valid-time>
  75. <end-valid-time>2007-07-07T11:00:00-07:00</end-valid-time>
  76. <start-valid-time>2007-07-07T10:00:00-07:00</start-valid-time>
  77. <end-valid-time>2007-07-07T17:00:00-07:00</end-valid-time>
  78. </time-layout>
  79. <time-layout time-coordinate="local" summarization="none">
  80. <layout-key>k-p3h-n1-7</layout-key>
  81. <start-valid-time>2007-07-06T13:00:00-07:00</start-valid-time>
  82. <end-valid-time>2007-07-06T17:00:00-07:00</end-valid-time>
  83. </time-layout>
  84.  
  85. <parameters applicable-location="point1">
  86. <temperature type='maximum' units="Fahrenheit" time-layout="k-p24h-n2-1">
  87. <name>Daily Maximum Temperature</name>
  88. <value>97</value>
  89. <value>95</value>
  90. </temperature>
  91. <temperature type='minimum' units="Fahrenheit" time-layout="k-p24h-n1-2">
  92. <name>Daily Minimum Temperature</name>
  93. <value>61</value>
  94. </temperature>
  95. <temperature type='hourly' units="Fahrenheit" time-layout="k-p3h-n9-5">
  96. <name>Temperature</name>
  97. <value>95</value>
  98. <value>96</value>
  99. <value>88</value>
  100. <value>76</value>
  101. <value>67</value>
  102. <value>62</value>
  103. <value>71</value>
  104. <value>86</value>
  105. <value>93</value>
  106. </temperature>
  107. <temperature type='dew point' units="Fahrenheit" time-layout="k-p3h-n9-5">
  108. <name>Dew Point Temperature</name>
  109. <value>38</value>
  110. <value>38</value>
  111. <value>39</value>
  112. <value>40</value>
  113. <value>40</value>
  114. <value>41</value>
  115. <value>41</value>
  116. <value>42</value>
  117. <value>41</value>
  118. </temperature>
  119. <temperature type='apparent' units="Fahrenheit" time-layout="k-p3h-n9-5">
  120. <name>Apparent Temperature</name>
  121. <value>91</value>
  122. <value>93</value>
  123. <value>85</value>
  124. <value>76</value>
  125. <value>67</value>
  126. <value>62</value>
  127. <value>71</value>
  128. <value>83</value>
  129. <value>89</value>
  130. </temperature>
  131. <precipitation type='liquid' units="inches" time-layout="k-p6h-n5-6">
  132. <name>Liquid Precipitation Amount</name>
  133. <value>0.00</value>
  134. <value>0.00</value>
  135. <value>0.00</value>
  136. <value>0.00</value>
  137. <value>0.00</value>
  138. </precipitation>
  139. <precipitation type='snow' units="inches" time-layout="k-p3h-n1-7">
  140. <name>Snow Amount</name>
  141. <value>0</value>
  142. </precipitation>
  143. <probability-of-precipitation type='12 hour' units="percent" time-layout="k-p12h-n3-3">
  144. <name>12 Hourly Probability of Precipitation</name>
  145. <value>0</value>
  146. <value>0</value>
  147. <value>0</value>
  148. </probability-of-precipitation>
  149. <convective-hazard>
  150. <outlook time-layout="k-p24h-n2-4">
  151. <name>Convective Hazard Outlook</name>
  152. <value>no thunderstorms</value>
  153. <value>no thunderstorms</value>
  154. </outlook>
  155. </convective-hazard>
  156. <convective-hazard>
  157. <severe-component type="severe thunderstorms" units="percent" time-layout="k-p24h-n2-4">
  158. <name>Total Probability of Severe Thunderstorms</name>
  159. <value>0</value>
  160. <value>0</value>
  161. </severe-component>
  162. </convective-hazard>
  163. <convective-hazard>
  164. <severe-component type="extreme severe thunderstorms" units="percent" time-layout="k-p24h-n2-4">
  165. <name>Total Probability of Extreme Severe Thunderstorms</name>
  166. <value>0</value>
  167. <value>0</value>
  168. </severe-component>
  169. </convective-hazard>
  170. <wind-speed type="incremental34" units="percent" time-layout="k-p6h-n5-6">
  171. <name>Probability of a Tropical Cyclone Wind Speed >34 Knots (Incremental)</name>
  172. <value>0</value>