Services_Weather
[ class tree: Services_Weather ] [ index: Services_Weather ] [ all elements ]

Source for file Globalweather.php

Documentation is available at Globalweather.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  3.  
  4. /**
  5.  * PEAR::Services_Weather_Globalweather
  6.  *
  7.  * PHP versions 4 and 5
  8.  *
  9.  * <LICENSE>
  10.  * Copyright (c) 2005, Alexander Wirtz
  11.  * All rights reserved.
  12.  *
  13.  * Redistribution and use in source and binary forms, with or without
  14.  * modification, are permitted provided that the following conditions
  15.  * are met:
  16.  * o Redistributions of source code must retain the above copyright notice,
  17.  *   this list of conditions and the following disclaimer.
  18.  * o Redistributions in binary form must reproduce the above copyright notice,
  19.  *   this list of conditions and the following disclaimer in the documentation
  20.  *   and/or other materials provided with the distribution.
  21.  * o Neither the name of the software nor the names of its contributors
  22.  *   may be used to endorse or promote products derived from this software
  23.  *   without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  26.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  29.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35.  * POSSIBILITY OF SUCH DAMAGE.
  36.  * </LICENSE>
  37.  *
  38.  * @category    Web Services
  39.  * @package     Services_Weather
  40.  * @author      Alexander Wirtz <alex@pc4p.net>
  41.  * @copyright   2005 Alexander Wirtz
  42.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  43.  * @version     CVS: $Id: Globalweather.php,v 1.34 2005/11/13 21:56:16 eru Exp $
  44.  * @link        http://pear.php.net/package/Services_Weather
  45.  * @link        http://www.capescience.com/webservices/globalweather/index.shtml
  46.  * @example     examples/globalweather-basic.php    globalweather-basic.php
  47.  * @filesource
  48.  */
  49.  
  50. require_once "Services/Weather/Common.php";
  51.  
  52. // {{{ class Services_Weather_Globalweather
  53. /**
  54.  * This class acts as an interface to the soap service of capescience.com.
  55.  * It searches for given locations and retrieves current weather data.
  56.  *
  57.  * GlobalWeather is a SOAP frontend for METAR data, provided by CapeScience.
  58.  * If you want to use METAR, you should try this class first, as it is much
  59.  * more comfortable (and also a bit faster) than the native METAR-class
  60.  * provided by this package. On the other hand, this service won't supply
  61.  * TAFs, the forecast system accompanying METAR, so you have to make
  62.  * the call here...
  63.  *
  64.  * For a working example, please take a look at
  65.  *     docs/Services_Weather/examples/globalweather-basic.php
  66.  *
  67.  *
  68.  * @category    Web Services
  69.  * @package     Services_Weather
  70.  * @author      Alexander Wirtz <alex@pc4p.net>
  71.  * @copyright   2005 Alexander Wirtz
  72.  * @license     http://www.opensource.org/licenses/bsd-license.php  BSD License
  73.  * @version     Release: 1.4.0
  74.  * @link        http://pear.php.net/package/Services_Weather
  75.  * @link        http://www.capescience.com/webservices/globalweather/index.shtml
  76.  * @example     examples/globalweather-basic.php    globalweather-basic.php
  77.  */
  78.  
  79.     // {{{ properties
  80.     /**
  81.      * WSDL object, provided by CapeScience
  82.      *
  83.      * @var     object                      $_wsdl 
  84.      * @access  private
  85.      */
  86.     var $_wsdl;
  87.  
  88.     /**
  89.      * SOAP object to access station data, provided by CapeScience
  90.      *
  91.      * @var     object                      $_stationSoap 
  92.      * @access  private
  93.      */
  94.     var $_stationSoap;
  95.  
  96.     /**
  97.      * SOAP object to access weather data, provided by CapeScience
  98.      *
  99.      * @var      object                      $_weatherSoap 
  100.      * @access   private
  101.      */
  102.     var $_weatherSoap;
  103.     // }}}
  104.  
  105.     // {{{ constructor
  106.     /**
  107.      * Constructor
  108.      *
  109.      * Requires SOAP to be installed
  110.      *
  111.      * @param   array                       $options 
  112.      * @param   mixed                       $error 
  113.      * @throws  PEAR_Error
  114.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  115.      * @access  private
  116.      */
  117.     function Services_Weather_Globalweather($options, &$error)
  118.     {
  119.         $perror = null;
  120.         $this->Services_Weather_Common($options, $perror);
  121.         if (Services_Weather::isError($perror)) {
  122.             $error = $perror;
  123.         }
  124.     }
  125.     // }}}
  126.  
  127.     // {{{ _connectServer()
  128.     /**
  129.      * Connects to the SOAP server and retrieves the WSDL data
  130.      *
  131.      * @return  PEAR_Error|bool
  132.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  133.      * @access  private
  134.      */
  135.     function _connectServer()
  136.     {
  137.         include_once "SOAP/Client.php";
  138.         $this->_wsdl = new SOAP_WSDL("http://live.capescience.com/wsdl/GlobalWeather.wsdl", $this->_httpOptions);
  139.         if (isset($this->_wsdl->fault) && Services_Weather::isError($this->_wsdl->fault)) {
  140.             $error = Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA, __FILE__, __LINE__);
  141.             return;
  142.         }
  143.  
  144.         eval($this->_wsdl->generateAllProxies());
  145.         if (!class_exists("WebService_GlobalWeather_StationInfo") || !class_exists("WebService_GlobalWeather_GlobalWeather")) {
  146.             $error = Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA, __FILE__, __LINE__);
  147.             return;
  148.         }
  149.  
  150.         $this->_stationSoap = &new WebService_GlobalWeather_StationInfo;
  151.         $this->_weatherSoap = &new WebService_GlobalWeather_GlobalWeather;
  152.  
  153.         return true;
  154.     }
  155.     // }}}
  156.  
  157.     // {{{ _checkLocationID()
  158.     /**
  159.      * Checks the id for valid values and thus prevents silly requests to
  160.      * GlobalWeather server
  161.      *
  162.      * @param   string                      $id 
  163.      * @return  PEAR_Error|bool
  164.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_NO_LOCATION
  165.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_INVALID_LOCATION
  166.      * @access  private
  167.      */
  168.     function _checkLocationID($id)
  169.     {
  170.         if (is_array($id) || is_object($id) || !strlen($id)) {
  171.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_NO_LOCATION, __FILE__, __LINE__);
  172.         } elseif ($this->_stationSoap->isValidCode($id) === false) {
  173.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_INVALID_LOCATION, __FILE__, __LINE__);
  174.         }
  175.  
  176.         return true;
  177.     }
  178.     // }}}
  179.  
  180.     // {{{ searchLocation()
  181.     /**
  182.      * Searches IDs for given location, returns array of possible locations
  183.      * or single ID
  184.      *
  185.      * @param   string                      $location 
  186.      * @param   bool                        $useFirst       If set, first ID of result-array is returned
  187.      * @return  PEAR_Error|array|string
  188.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  189.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
  190.      * @access  public
  191.      */
  192.     function searchLocation($location, $useFirst = false)
  193.     {
  194.         // Check, if the stationSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  195.         if (!$this->_stationSoap) {
  196.             $status = $this->_connectServer();
  197.             if (Services_Weather::isError($status)) {
  198.                 return $status;
  199.             }
  200.         }
  201.  
  202.         // Get search data from server and unserialize
  203.         $search = $this->_stationSoap->searchByName($location);
  204.  
  205.         if (Services_Weather::isError($search)) {
  206.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA, __FILE__, __LINE__);
  207.         } else {
  208.             if (!is_array($search) || !sizeof($search)) {
  209.                 return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION, __FILE__, __LINE__);
  210.             } else {
  211.                 if (!$useFirst && (sizeof($search) > 1)) {
  212.                     $searchReturn = array();
  213.                     for ($i = 0; $i < sizeof($search); $i++) {
  214.                         $searchReturn[$search[$i]->icao] = $search[$i]->name.", ".$search[$i]->country;
  215.                     }
  216.                 } elseif ($useFirst || (sizeof($search) == 1)) {
  217.                     $searchReturn = $search[0]->icao;
  218.                 }
  219.             }
  220.         }
  221.  
  222.         return $searchReturn;
  223.     }
  224.     // }}}
  225.  
  226.     // {{{ searchLocationByCountry()
  227.     /**
  228.      * Returns IDs with location-name for a given country or all available
  229.      * countries, if no value was given
  230.      *
  231.      * @param   string                      $country 
  232.      * @return  PEAR_Error|array
  233.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
  234.      * @throws  PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
  235.      * @access  public
  236.      */
  237.     function searchLocationByCountry($country = "")
  238.     {
  239.         // Return the available countries as no country was given
  240.         if (!strlen($country)) {
  241.             $countries = $this->_stationSoap->listCountries();
  242.             if (Services_Weather::isError($countries)) {
  243.                 return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA, __FILE__, __LINE__);
  244.             }
  245.             return $countries;
  246.         }
  247.  
  248.         // Check, if the stationSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  249.         if (!$this->_stationSoap) {
  250.             $status = $this->_connectServer();
  251.             if (Services_Weather::isError($status)) {
  252.                 return $status;
  253.             }
  254.         }
  255.  
  256.         // Now for the real search
  257.         $countryLocs = $this->_stationSoap->searchByCountry($country);
  258.         // Check result for validity
  259.         if (Services_Weather::isError($countryLocs)) {
  260.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA, __FILE__, __LINE__);
  261.         } elseif (!is_array($countryLocs)) {
  262.             return Services_Weather::raiseError(SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION, __FILE__, __LINE__);
  263.         }
  264.  
  265.         // Construct the result
  266.         $locations = array();
  267.         foreach ($countryLocs as $location) {
  268.             $locations[$location->icao] = $location->name.", ".$location->country;
  269.         }
  270.         asort($locations);
  271.  
  272.         return $locations;
  273.     }
  274.     // }}}
  275.  
  276.     // {{{ getLocation()
  277.     /**
  278.      * Returns the data for the location belonging to the ID
  279.      *
  280.      * @param   string                      $id 
  281.      * @return  PEAR_Error|array
  282.      * @throws  PEAR_Error
  283.      * @access  public
  284.      */
  285.     function getLocation($id = "")
  286.     {
  287.         $status = $this->_checkLocationID($id);
  288.  
  289.         if (Services_Weather::isError($status)) {
  290.             return $status;
  291.         }
  292.  
  293.         $locationReturn = array();
  294.  
  295.         if ($this->_cacheEnabled && ($location = $this->_cache->get("GW-".$id, "location"))) {
  296.             // Get data from cache
  297.             $this->_location = $location;
  298.             $locationReturn["cache"] = "HIT";
  299.         } else {
  300.             // Check, if the stationSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  301.             if (!$this->_stationSoap) {
  302.                 $status = $this->_connectServer();
  303.                 if (Services_Weather::isError($status)) {
  304.                     return $status;
  305.                 }
  306.             }
  307.  
  308.             $location = $this->_stationSoap->getStation($id);
  309.  
  310.             if (Services_Weather::isError($location)) {
  311.                 return $location;
  312.             }
  313.  
  314.             $this->_location = $location;
  315.  
  316.             if ($this->_cacheEnabled) {
  317.                 // ...and cache it
  318.                 $expire = constant("SERVICES_WEATHER_EXPIRES_LOCATION");
  319.                 $this->_cache->extSave("GW-".$id, $this->_location, "", $expire, "location");
  320.             }
  321.             $locationReturn["cache"] = "MISS";
  322.         }
  323.         if (strlen($this->_location->region) && strlen($this->_location->country)) {
  324.             $locname = $this->_location->name.", ".$this->_location->region.", ".$this->_location->country;
  325.         } elseif (strlen($this->_location->country)) {
  326.             $locname = $this->_location->name.", ".$this->_location->country;
  327.         } else {
  328.             $locname = $this->_location->name;
  329.         }
  330.         $locationReturn["name"]      = $locname;
  331.         $locationReturn["latitude"]  = $this->_location->latitude;
  332.         $locationReturn["longitude"] = $this->_location->longitude;
  333.         $locationReturn["sunrise"]   = date($this->_timeFormat, $this->calculateSunRiseSet(gmmktime(), SUNFUNCS_RET_TIMESTAMP, $this->_location->latitude, $this->_location->longitude, SERVICES_WEATHER_SUNFUNCS_SUNRISE_ZENITH, 0, true));
  334.         $locationReturn["sunset"]    = date($this->_timeFormat, $this->calculateSunRiseSet(gmmktime(), SUNFUNCS_RET_TIMESTAMP, $this->_location->latitude, $this->_location->longitude, SERVICES_WEATHER_SUNFUNCS_SUNSET_ZENITH,  0, false));
  335.         $locationReturn["elevation"] = $this->_location->elevation;
  336.  
  337.         return $locationReturn;
  338.     }
  339.     // }}}
  340.  
  341.     // {{{ getWeather()
  342.     /**
  343.      * Returns the weather-data for the supplied location
  344.      *
  345.      * @param   string                      $id 
  346.      * @param   string                      $unitsFormat 
  347.      * @return  PEAR_Error|array
  348.      * @throws  PEAR_Error
  349.      * @access  public
  350.      */
  351.     function getWeather($id = "", $unitsFormat = "")
  352.     {
  353.         static $clouds;
  354.         if (!isset($clouds)) {
  355.             $clouds    = array(
  356.                 "sky clear",
  357.                 "few",
  358.                 "scattered",
  359.                 "broken",
  360.                 "overcast",
  361.             );
  362.         }
  363.  
  364.         $status = $this->_checkLocationID($id);
  365.  
  366.         if (Services_Weather::isError($status)) {
  367.             return $status;
  368.         }
  369.  
  370.         // Get other data
  371.         $units    = $this->getUnitsFormat($unitsFormat);
  372.  
  373.         $weatherReturn = array();
  374.         if ($this->_cacheEnabled && ($weather = $this->_cache->get("GW-".$id, "weather"))) {
  375.             // Same procedure...
  376.             $this->_weather = $weather;
  377.             $weatherReturn["cache"] = "HIT";
  378.         } else {
  379.             // Check, if the weatherSoap-Object is present. If not, connect to the Server and retrieve the WDSL data
  380.             if (!$this->_weatherSoap) {
  381.                 $status = $this->_connectServer();
  382.                 if (Services_Weather::isError($status)) {
  383.                     return $status;
  384.                 }
  385.             }
  386.  
  387.             // ...as last function
  388.             $weather = $this->_weatherSoap->getWeatherReport($id);
  389.  
  390.             if (Services_Weather::isError($weather)) {
  391.                 return $weather;
  392.             }
  393.  
  394.             $this->_weather = $weather;
  395.  
  396.             if ($this->_cacheEnabled) {
  397.                 // ...and cache it
  398.                 $expire = constant("SERVICES_WEATHER_EXPIRES_WEATHER");
  399.                 $this->_cache->extSave("GW-".$id, $this->_weather, "", $expire, "weather");
  400.             }
  401.             $weatherReturn["cache"] = "MISS";
  402.         }
  403.  
  404.         $update = trim(str_replace(array("T", "Z"), " ", $this->_weather->timestamp))." GMT";
  405.  
  406.         $weatherReturn["update"]            = gmdate(trim($this->_dateFormat." ".$this->_timeFormat), strtotime($update));
  407.         $weatherReturn["updateRaw"]         = $this->_weather->timestamp;
  408.         if (strlen($this->_weather->station->region) && strlen($this->_weather->station->country)) {
  409.             $locname = $this->_weather->station->name.", ".$this->_weather->station->region.", ".$this->_weather->station->country;
  410.         } elseif (strlen($this->_weather->station->country)) {
  411.             $locname = $this->_weather->station->name.", ".$this->_weather->station->country;
  412.         } else {
  413.             $locname = $this->_weather->station->name;
  414.         }
  415.         $weatherReturn["station"]           = $locname;
  416.         $weatherReturn["wind"]              = $this->convertSpeed($this->_weather->wind->prevailing_speed, "mps", $units["wind"]);
  417.         $weatherReturn["windDegrees"]       = $this->_weather->wind->prevailing_direction->degrees;
  418.         $weatherReturn["windDirection"]     = $this->_weather->wind->prevailing_direction->compass;
  419.         if ($this->_weather->wind->prevailing_speed != $this->_weather->wind->gust_speed) {
  420.             $weatherReturn["windGust"]      = $this->convertSpeed($this->_weather->wind->gust_speed, "mps", $units["wind"]);
  421.         }
  422.         if ($this->_weather->wind->varying_from_direction != "" && $this->_weather->wind->varying_to_direction != "") {
  423.             $weatherReturn["windVar"]       = array (
  424.                 "from" => $this->_weather->wind->varying_from_direction,
  425.                 "to"   => $this->_weather->wind->varying_to_direction
  426.             );
  427.         }
  428.  
  429.         $weatherReturn["visibility"]        = $this->convertDistance($this->_weather->visibility->distance / 1000, "km", $units["vis"]);
  430.         $weatherReturn["visQualifier"]      = $this->_weather->visibility->qualifier;
  431.  
  432.         $condition = array();
  433.         for ($i = 0; $i < sizeof($this->_weather->phenomena); $i++) {
  434.             $condition[] = $this->_weather->phenomena[$i]->string;
  435.         }
  436.         $weatherReturn["condition"]         = implode(", ", $condition);
  437.  
  438.         if (is_array($this->_weather->sky->layers)) {
  439.             $layers = array();
  440.             for ($i = 0; $i < sizeof($this->_weather->sky->layers); $i++) {
  441.                 if (strtoupper($this->_weather->sky->layers[$i]->type) != "CLEAR") {
  442.                     $layers[$i]             = array();
  443.                     $layers[$i]["amount"]   = $clouds[$this->_weather->sky->layers[$i]->extent];
  444.                     $layers[$i]["height"]   = $this->convertDistance($this->_weather->sky->layers[$i]->altitude, "m", $units["height"]);
  445.                     if (strtoupper($this->_weather->sky->layers[$i]->type) != "CLOUD") {
  446.                         $layers[$i]["type"] = ucwords(str_replace("_", "", $this->_weather->sky->layers[$i]->type));
  447.                     }
  448.                 }
  449.             }
  450.             if (sizeof($layers)) {
  451.                 $weatherReturn["clouds"]        = $layers;
  452.             }
  453.         }
  454.  
  455.         $weatherReturn["temperature"]       = $this->convertTemperature($this->_weather->temperature->ambient, "c", $units["temp"]);
  456.         $feltTemperature = $this->calculateWindChill($this->convertTemperature($weatherReturn["temperature"], $units["temp"], "f"), $this->convertSpeed($weatherReturn["wind"], $units["wind"], "mph"));
  457.         $weatherReturn["feltTemperature"]   = $this->convertTemperature($feltTemperature, "f", $units["temp"]);
  458.         $weatherReturn["dewPoint"]          = $this->convertTemperature($this->_weather->temperature->dewpoint, "c", $units["temp"]);
  459.         $weatherReturn["humidity"]          = $this->_weather->temperature->relative_humidity;
  460.         $weatherReturn["pressure"]          = $this->convertPressure($this->_weather->pressure->altimeter, "hpa", $units["pres"]);
  461.  
  462.         return $weatherReturn;
  463.     }
  464.     // }}}
  465.  
  466.     // {{{ getForecast()
  467.     /**
  468.      * GlobalWeather has no forecast per se, so this function is just for
  469.      * compatibility purposes.
  470.      *
  471.      * @param   string                      $int 
  472.      * @param   int                         $days 
  473.      * @param   string                      $unitsFormat 
  474.      * @return  bool 
  475.      * @access  public
  476.      * @deprecated
  477.      */
  478.     function getForecast($id = null, $days = null, $unitsFormat = null)
  479.     {
  480.         return false;
  481.     }
  482.     // }}}
  483. }
  484. // }}}
  485. ?>

Documentation generated on Mon, 11 Mar 2019 14:37:51 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.