Pull to refresh

Поговорим о погоде

PHP *
За последнее время мне пришлось довольно основательно пообщаться с несколькими сервисами Yahoo! В этой заметке расскажу об одном из них, который для многих может оказаться полезным. Это сервис прогноза погоды Yahoo! Weather.

Года два назад я искал в сети удобный и открытый источник подобных данных, но так ничего и не нашел. Все отечественные сервисы экспортировали данные за деньги (отпугивала скорее не цена, а наличие возни с оплатой), а западные — либо не предоставляли данных в удобном для автоматической обработки формате, либо не знали о существовании города, в котором я живу.

Yahoo! Weather порадовал отсутствием перечисленных недостатков. Информация о текущей погоде, а так же прогноз на ближайшие 5 дней экспортируется с их сервера в формате RSS. На мой взгляд, выбор этого формата притянут за уши, т.к. погодная RSS «лента» содержит всего однин item. Те же данные можно было бы экспортировать в более лаконичном виде, но в Yahoo, по всей видимости, расчитывали на стандартные методы обработки RSS, что тоже довольно весомый довод. Стандарт — это все-таки стандарт.

Адрес RSS фида для интересующего города можно найти на сайте weather.yahoo.com.



В общем виде URL выглядит следующим образом:

xml.weather.yahoo.com/forecastrss?p=код_города&u=единицы_измерения

Первый параметр — идентификатор интересующего города. Второй параметр определяет, в каких единицах будет выдаваться температура. Значение «c» соответствует градусам Цельсия, «f» — градусам Фаренгейта.
Несколько примеров:



Автоматизируем это



Описанный ниже класс YahooWeather (PHP5) предназначен для загрузки RSS по HTTP и предварительной обработки данных.

<?php

class YahooWeather {
	// Ветер
	public $wind_chill;
	public $wind_direction;
	public $wind_speed;
	
	// Атмосферные показатели
	public $humidity;
	public $visibility;
	public $pressure;
	
	// Время восхода и заката переводим в формат unix time
	public $sunrise;
	public $sunset;
	
	// Текущая температура воздуха и погода
	public $temp;
	public $condition_text;
	public $condition_code;
	
	// Прогноз погоды на 5 дней
	public $forecast;
	
	public $units;
	
	function __construct($code, $units = 'c', $lang = 'en') {
		$this->units = ($units == 'c')?'c':'f';
		
		$url = 'http://xml.weather.yahoo.com/forecastrss?p='.
			$code.'&u='.$this->units;
		
		$xml_contents = file_get_contents($url);
		if($xml_contents === false) 
			throw new Exception('Error loading '.$url);
		
		$xml = new SimpleXMLElement($xml_contents);
		
		// Ветер
		$tmp = $xml->xpath('/rss/channel/yweather:wind');
		if($tmp === false) throw new Exception("Error parsing XML.");
		$tmp = $tmp[0];
		
		$this->wind_chill = (int)$tmp['chill'];
		$this->wind_direction = (int)$tmp['direction'];
		$this->wind_speed = (int)$tmp['speed'];
		
		// Атмосферные показатели
		$tmp = $xml->xpath('/rss/channel/yweather:atmosphere');
		if($tmp === false) throw new Exception("Error parsing XML.");
		$tmp = $tmp[0];
		
		$this->humidity = (int)$tmp['humidity'];
		$this->visibility = (int)$tmp['visibility'];
		$this->pressure = (int)$tmp['pressure'];
		
		// Время восхода и заката переводим в формат unix time
		$tmp = $xml->xpath('/rss/channel/yweather:astronomy');
		if($tmp === false) throw new Exception("Error parsing XML.");
		$tmp = $tmp[0];
		
		$this->sunrise = strtotime($tmp['sunrise']);
		$this->sunset = strtotime($tmp['sunset']);
		
		// Текущая температура воздуха и погода
		$tmp = $xml->xpath('/rss/channel/item/yweather:condition');
		if($tmp === false) throw new Exception("Error parsing XML.");
		$tmp = $tmp[0];
		
		$this->temp = (int)$tmp['temp'];
		$this->condition_text = strtolower((string)$tmp['text']);
		$this->condition_code = (int)$tmp['code'];
		
		// Прогноз погоды на 5 дней
		$forecast = array();
		$tmp = $xml->xpath('/rss/channel/item/yweather:forecast');
		if($tmp === false) throw new Exception("Error parsing XML.");
		
		foreach($tmp as $day) {
			$this->forecast[] = array(
				'date' => strtotime((string)$day['date']),
				'low' => (int)$day['low'],
				'high' => (int)$day['high'],
				'text' => (string)$day['text'],
				'code' => (int)$day['code']
			);
		}
	}
	
	public function __toString() {
		$u = "°".(($this->units == 'c')?'C':'F');
		return $this->temp.' '.$u.', '.$this->condition_text;
	}
}

?>


Пример использования:

<?php

try {
	$weather = new YahooWeather('RSXX0091');
} catch(Exception $e) {
	echo "Caught exception: ".$e->getMessage();
	exit();
}

echo '<h1>'.$weather.'</h1>';

echo "<pre>";
print_r($weather);
echo "</pre>";

?>


Вывод:



Временные значения восхода и заката солнца (поля sunrise и sunset соответственно) автоматически переводятся в формат unix time. стоит так же обратить внимание на то, что по непонятной причине Yahoo! выдает явно некорректное значение атмосферного давления (0). Но само наличие соответствующего атрибута в XML дает некоторую надежду на то, что рано или поздно экспорт этих данных починят.

Поле condition_code используется для хранения кодового обозначения погодных условий. Текстовая расшифровка текущего значения хранится в поле condition_text, а полный перечень возможных вариантов приведен в следующей таблице:

Код Описание
0 tornado
1 tropical storm
2 hurricane
3 severe thunderstorms
4 thunderstorms
5 mixed rain and snow
6 mixed rain and sleet
7 mixed snow and sleet
8 freezing drizzle
9 drizzle
10 freezing rain
11 showers
12 showers
13 snow flurries
14 light snow showers
15 blowing snow
16 snow
17 hail
18 sleet
19 dust
20 foggy
21 haze
22 smoky
23 blustery
24 windy
25 cold
26 cloudy
27 mostly cloudy (night)
28 mostly cloudy (day)
29 partly cloudy (night)
30 partly cloudy (day)
31 clear (night)
32 sunny
33 fair (night)
34 fair (day)
35 mixed rain and hail
36 hot
37 isolated thunderstorms
38 scattered thunderstorms
39 scattered thunderstorms
40 scattered showers
41 heavy snow
42 scattered snow showers
43 heavy snow
44 partly cloudy
45 thundershowers
46 snow showers
47 isolated thundershowers
3200  not available


Статья опубликована на блоге paradigm.ru.

Ссылки по теме



Tags: phprssyahooпрогноз погодысервисы
Hubs: PHP
Total votes 41: ↑35 and ↓6 +29
Comments 43
Comments Comments 43

Popular right now