Information on PHP SOAP

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

I need to query the National Digital Forecast Database for weather forecast information, but I am having a hard time understanding SOAP. Could somebody please point me in the direction of some good tutorials? I found a PHP script called nuSOAP that is supposed to make it easier, and I just finished recompiling PHP on my server with SOAP support enabled, so I'm willing to use either method.

Any help would be appreciated. Smiling

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

My motto is:

When in doubt, check W3Schools

hope this helps Smiling

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Yes, I did read that, but it doesn't provide any help for a PHP implementation.

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

Did you look at PHP XML info?

[oopsie - Opera 9.62 has been "double posting" here and at LinkedIn...]

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Did you look at PHP XML info?

No, but parsing XML isn't the problem. I have been using PHP's SimpleXML, and it works wonders. Smiling

What I can't master is the method of requesting and receiving data from a SOAP server, I can handle parsing the data once I get it.

They have: 33 posts

Joined: Nov 2008

PHP SOAP Extension supports WSDL.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

So?

JeevesBond's picture

He has: 3,956 posts

Joined: Jun 2002

Did you get anywhere with this? Using the example http://www.weather.gov/forecasts/xml/sample_products/ndfdXML.tar (taken from their documentation), the example form and the NuSOAP samples, I managed to create a call with some made-up parameters to the SOAP server and get a response. Unfortunately the response was an error message, but it's just because the parameters wrong.

I used the NuSoap library as well. It seemed better documented/supported by weather.gov Here's my code:

<?php
require('lib/nusoap.php');

// Define new object and specify location of wsdl file.
$soapclient = new nusoap_client('http://www.weather.gov/forecasts/xml/SOAP_server/ndfdXMLserver.php');
$err = $soapclient->getError();

if (
$err) {
  echo
'<h2>Constructor error</h2><pre>' . $err . '</pre>';
  echo
'<h2>Debug</h2><pre>' . htmlspecialchars($soapclient->getDebug(), ENT_QUOTES) . '</pre>';
  exit();
}

$parameters = array(
 
'product' => 'time-series',
 
'latitude'   => 38.99,
 
'longitude'  => -77.99,
 
'startTime' => '2007-01-01T00:00:00',
 
'endTime'   => '2008-01-01T00:00:00',
 
'weatherParameters' => array(
   
'temp'  => TRUE,
  ),
);
$result = $soapclient->call('NDFDgen', $parameters, 'uri:DWMLgen', 'uri:DWMLgen/NDFDgen');

print_r($result);
?>

a Padded Cell our articles site!

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

I was able to get something functional. Here is the main function from my data model:

<?php
public function get_forecast_by_zip($zip, &$cached = false)
{
   
$zip = (int)$zip;
   
   
$query = $this->db->query("SELECT * FROM Forecasts WHERE zip = $zip && CURRENT_TIMESTAMP - updated < 3600 LIMIT 1");
   
   
$row = $query->result();

    if (isset(
$row[0]))
    {
       
$cached = true;
        return
$row[0]->data;
    }
   
   
/* still here?  looks like we will have to fetch it from the NDFD */
   
   
$latlon = $this->get_lat_lon_by_zip($zip);
   
    if (!
$latlon)
    {
        return
false;
    }
    else
    {
        list(
$lat, $lon) = explode(',', $latlon);
    }
   
   
$parameters = array('product'    => 'time-series',
                       
'startDate' => '2008-11-05T06:00:00',
                       
'numDays'   => 5,
                       
'format'    => '24 hourly',
                       
'latitude'  => $lat,
                       
'longitude'    => $lon);
   
   
    try
    {
       
$c = new nusoap_client('http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl', 'wsdl');
       
       
$result = $c->call('NDFDgen', $parameters, '', '', false, true);
    }
    catch (
Exception $ex)
    {
        return
false;
    }
   
   
/* cache the result in the db to save it for later */
   
   
$data['zip'] = $zip;
   
$data['lat'] = $lat;
   
$data['lon'] = $lon;
   
$data['data'] = $c->return['dwmlOut'];
   
   
$query = $this->db->query("DELETE FROM Forecasts WHERE zip = $zip LIMIT 1");
   
$this->db->insert('Forecasts', $data);
   
    return
$c->return['dwmlOut'];
}
?>

I get back an XML file with every product they offer, so I'm still working on getting the parameters right. I'm confused on the ->call() statement. What does "'uri:DWMLgen', 'uri:DWMLgen/NDFDgen'" mean? I saw those in the example. Although I don't have that, it still seems to work ok.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Just when I start to get somewhere with this, I realize that the NDFD doesn't provide all the information I need. I am still lacking the detailed forecast & almanac information. With the help from someone on an NDFD mailing list, I found a place to get the detailed forecast (http://www.weather.gov/data/LOT/ZFPLOT, where LOT is the station to query). Oh boy, another parser to write!! Plain

I'm still looking for a place to fetch almanac info. There should be a search engine to search for different data sources. If anyone knows of one, please let me know. Smiling

JeevesBond's picture

He has: 3,956 posts

Joined: Jun 2002

Wow, sounds like a pain! Smiling

Thanks for sharing that information, might help someone else searching around.

They have: 8 posts

Joined: Dec 2008

Prog4mm3r...

Thanks for the help with the weather service project. I too have been working to get that working. Have you gotten any further?

You mentioned looking for almanac information. What were you looking for? I had been searching for sunrise/sunset, but discovered it was a PHP function already.

In particular, I was having a hard time find precipitation data. It seems the source you are using will have that information.

Thanks again,
Frank

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

You mentioned looking for almanac information. What were you looking for? I had been searching for sunrise/sunset, but discovered it was a PHP function already.

Is it a native PHP function? I have found code that calculates it, and it only needs the location (lat/lon) and the date.

In particular, I was having a hard time find precipitation data. It seems the source you are using will have that information.

Yes, I did find a data source with precip data. That would be the National Digital Forecast Database. You can send example queries using this page.

I'm writing a post on my PHP blog that will show at least 4 data sources where you can find weather information. That article will be published Thursday.

They have: 8 posts

Joined: Dec 2008

Wow!

Thanks for that information. I will look at the sources. I really appreciate your reply.

Here are the four lines of code I use to get SS & SR. I assume they are always available in PHP 5(?)

$offset = -6;
$zenith=90+50/60; #adjust if desired
$sr=date_sunrise(time(), SUNFUNCS_RET_STRING, $lat, $lon, $zenith, $offset);
$ss=date_sunset(time(), SUNFUNCS_RET_STRING, $lat, $lon, $zenith, $offset);

Thanks again,
Frank

They have: 8 posts

Joined: Dec 2008

Rather than forecasted data, I would like to find recent past data for precipitation. E.G. 1" rain in past 6 hours... 2" snow if past 24 hours, etc...

I've looked everywhere I can think of and have had no luck. It would seem that that information should be readily available and it probably is, but I just haven't looked under the right rock.

Thanks again for your interest.

Frank

They have: 8 posts

Joined: Dec 2008

You know... I got to looking at the link you provided and found something that may work at: (the link is for Kansas City area)

http://www.nohrsc.noaa.gov/interactive/html/graph.html?station=KMCI&w=60...

This allows you to set begin and end times and a csv file will be returned.

We shall see...

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Here are the four lines of code I use to get SS & SR. I assume they are always available in PHP 5(?)

Sweet, thanks for posting those functions. I just looked those up on php.net, and yes, they are available in PHP 5+.

Where did you find that CSV data? Is there a page that describes it?

They have: 8 posts

Joined: Dec 2008

The precipitation source is working well. I did send a request for the csv file via the url link and a file was returned. I then imported it into mySQL and it is available.

The site is:

National Operational Hydrologic Remote Sensing Center
Interactive Snow Information

(It includes all forms of precipitation as far as I can tell.)

http://www.nohrsc.noaa.gov/interactive/html/graph.html?station=KMCI is a good start, you can enter any icao from there.

From that URL, you can access 24 different outputs, which are either graphic or text. The one I will use is #13, which is a csv file.

There is quite a bit of information on that page.

I am working on a php routine that returns the nearest icao code (like "KMCI") from a set of coordinates, but that I don't know the right way to do that. I am sure lots of others have done that already, and I am hoping to take advantage of their hard work. That way you could get the appropriate weather data by lat/lon rather than have to know the icao code for access.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

I am working on a php routine that returns the nearest icao code (like "KMCI") from a set of coordinates, but that I don't know the right way to do that. I am sure lots of others have done that already, and I am hoping to take advantage of their hard work. That way you could get the appropriate weather data by lat/lon rather than have to know the icao code for access.

I can help you there. Visit this link to get a list of all weather stations:

http://www.weather.gov/xml/current_obs/index.xml

I use the SimpleXMLElement class to parse the file and insert it into the database. Let me know if you want a code sample for that. I have mine written up in a framework, so it won't run as a standalone script.

Now for the part of querying for the closest station. Check out this query from the weather project I'm working on:

SELECT *, SQRT(POW(69.1 * (latitude - $lat), 2) + POW(69.1 * ($lon - longitude) * COS(latitude / 57.3 ), 2 )) AS distance FROM Stations ORDER BY distance ASC LIMIT 1

Set the $lat and $lon variables to the location where you are trying to find the closest station, and the closest one will be returned. I will admit that I had to Google for this query, I didn't write it myself.

They have: 8 posts

Joined: Dec 2008

Amazing!

It works perfectly.

I already had a table of 2,172 USA ICAOs along with their lats, longs, and elevations. I'm not sure that they all have weather outputing capability, but I've looked at perhaps 25 and they have worked. Some seem to have more elements than others.

Also have a table of "all"(?) ICAOs... perhaps 24,400. Not real sure of the value of that, but fwiw.

Thanks to you, I can now assemble this thing. I was thinking that I had to find a formula that dealt specifically with ICAOs. After reading your words above, it struck me that ICAOs are beside the point.

Again, thanks again!
Frank

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Glad to help. Smiling

I already had a table of 2,172 USA ICAOs along with their lats, longs, and elevations.

Hmmm...When I import my station list from the XML file in my previous post, I only get 2,009 records. Can you attach your list of 2,172 stations? I wonder which ones they aren't including.

They have: 8 posts

Joined: Dec 2008

I was going to guess why the sizes are different, but there are too many possibilities....

You will notice the name of the file... It doesn't include non-USA ICAOs. But, if you want those, let me know. I don't know that the larger file is as clean as this one....

CU,
Frank

PS--- I changed the extension to txt from csv so I could upload it.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

What does the last field represent?

They have: 8 posts

Joined: Dec 2008

The first field is date and time. The 2nd to the last (penultimate) field is date and the last field is "hour".... So, more or less, they just split the first column into two columns and put them on the right.

..... maybe you are asking about the ICAO table, which you probably are. It is the elevation of the ICAO station.

Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.