[Из песочницы] И снова Яндекс.Погода для сайта: время суток, направление ветра и прочие параметры

В продолжении поста о погоде «Яндекс.Погода для сайта в деталях». Прочитав данный пост, я пришел к выводу, что тема еще актуальна, и хотел бы дополнить выше упомянутую статью своими наработками.396e5125ecb34b8fbe3ad649695d13e7.jpg

ЗадачаНайти сервис, который отдавал бы данные погоды с прогнозом не менее 10 дней с русской локализацией, средними величинами, временами суток и дополнительными параметрами по заданному городу.Поиски решения Опробовав разные сервисы отдающие данные погоды, я остановился на Яндекс.Погода, все условия задачи совпадали.Так как мне нужны были данные по одному городу, первое, что я сделал, это нашел идентификатор (id) города в списке, предоставленном здесь и подставил его в export.yandex.ru/weather-ng/forecasts/.xml. В итоге я получил xml-файл с данными по погоде выбранного мной города.Разбор изображений На втором этапе нужно было получить собственные изображения состояния погоды. В xml-файле этот параметр обозначен как image-v3. Чтобы получить весь список изображений, а так же описание для каждого состояния я набросал небольшой кустарный скрипт, который парсит города из доступного списка и собирает все в два массива на вывод. // парсер изображений и описания состояний $col = 1; // кол-во дней (до 10, увеличивается время выдачи) $data_file = 'http://weather.yandex.ru/static/cities.xml'; $xml = simplexml_load_file ($data_file);

foreach ($xml→country as $key => $value) { foreach ($value→city as $key1 => $value1): $out = getWeather ($value1[«id»], $col); foreach ($out as $day): foreach ($day['weather'] as $weather): $types[(string)$weather['weather_type']] = (string)$weather['image']; // массив описаний состояния с изображением $images[(string)$weather['image']] = (string)$weather['weather_type']; // массив изображений с описанием состояния endforeach; endforeach; endforeach; } foreach ($types as $type=>$img): ?>.png» width=»48» height=»48» /> — '; endforeach; /* заполняем массив при помощи функции, первый параметр идентификатор города, другие параметры необязательны — в этом случае используется значения по умолчанию */ function getWeather ($city, $col = 10) { $data_file = 'http://export.yandex.ru/weather-ng/forecasts/'.$city.'.xml'; // загружаем файл прогноза погоды для выбранного города $xml = simplexml_load_file ($data_file); // загружаем xml файл через simple_xml

$out = array (); // массив вывода прогноза $counter = 0; // счетчик количества дней, для которых доступен прогноз

if ($xml→day): foreach ($xml→day as $day):

if ($counter == $col) break; for ($i=0;$i<=3;$i++) { $out[$counter]['weather'][$i]['image'] = $day->day_part[$i]→{'image-v3'}; $out[$counter]['weather'][$i]['weather_type'] = $day→day_part[$i]→weather_type; } $counter++ ; endforeach; endif; return $out; } На выходе получаем два массива данных, первый выводит весь список с описанием состояний и картинкой, второй выводит картинки с одним из видов описания состояния. Хочу заметить, что для одного изображения могут использоваться разные типы описаний состояния погоды. Параметр $col в скрипте, указывает на количество дней, который нужно обработать, максимум 10, по умолчанию 1, для уменьшения времени выдачи.Примечание: скрипт работает довольно долго (особенно на локалхосте), т.к. городов много, поэтому желательно увеличить время выполнения php-скриптов (max_execution_time, max_input_time), а так же максимальный объем памяти скрипта (memory_limit).

Список картинок, которые я нашел Так как описание для каждого изображения может быть несколько, я добавлю по одному, для понимания состояния погоды.47edde011b164b82b193d3c32a213700.png bkn_-ra_d — облачно с прояснениями, небольшой дождь (день)8ebea75edeec405287d87a46d82f043f.png bkn_-ra_n — облачно с прояснениями, небольшой дождь (ночь)ec25e71d16e14cc08efa996ff1aa80ec.png bkn_-sn_d — облачно с прояснениями, небольшой снег (день)dcd96e2511d8405a95a683a53d43e518.png bkn_-sn_n — облачно с прояснениями, небольшой снег (ночь)9496d7b4c2ae4da9b9efbde9d7a9f962.png bkn_d — переменная облачность (день)90d21961cf754d53895638cf4314aa7b.png bkn_n — переменная облачность (ночь)e4ee2fc0ec8e41eabeef667d0ffbe4fe.png bkn_ra_d — переменная облачность, дождь (день)e2d770a807d44f16a83c0ac4e7513774.png bkn_ra_n — переменная облачность, дождь (ночь)7e436b4f1c244b8e9ff25fc7e369bc2c.png bkn_sn_d — переменная облачность, снег (день)b92e06c840384870831aa70cb8f0b514.png bkn_sn_n — переменная облачность, снег (ночь)0bcb15c4195048b59c271f36274c0fbc.png bl — метельeb7d615121864feabbe8f8daa039c6a4.png fg_d — туман693bf62e913144db9d001b7ce348a537.png ovc — облачно2fa5b9bca3b5400ba9fd703c6402e3b5.png ovc_-ra — облачно, временами дождьac7bf2c54476438fa6f0b5b16e340335.png ovc_-sn — облачно, временами снег97de1b13ca5c427a8484f88dadd77d65.png ovc_ra — облачно, дождь380129f8188545b096eb9e6c0a0cbfa5.png ovc_sn — облачно, снегbdfbb9072edb4631a5eba2263381c4c5.png ovc_ts_ra — облачно, дождь, грозаfafbec39704b4139b8bb60b1e4f27bb7.png skc_d — ясно (день)38daab00a7104faeae55ade2e0c07933.png skc_n — ясно (ночь)

Есть еще дополнительные иконки, но я не нашел где они используются, единственное отличие, это интенсивность осадков.

dfa991104f454592a3c22edab1a2fc6c.png bkn_+ra_d, 3e535bfa70de4c918c1542b08399f713.png bkn_+ra_n, 94fb17574009401ea5f4775bb3224fce.png bkn_+sn_d, 8bc4be113aca47638d895038cbe35d93.png bkn_+sn_n, a6fe08796bd74e519ac5c92b34ca597f.png ovc_+ra, a28608a71c65490f9536c9a82ffe35b4.png ovc_+sn

Реализация задачи После того, как я нашел все изображения, мне оставалось только запрашивать xml-файл с параметрами города и нарисовать выдачу. На сервере я настроил данный скрипт по крону, раз в полчаса, дабы не грузить лишний раз Яндекс: $city_id = 27612; // id Москвы $url = 'http://export.yandex.ru/weather-ng/forecasts/'.$city_id.'.xml'; $userAgent = 'Googlebot/2.1 (+http://www.google.com/bot.html)'; $xml = $_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'weather_'.$city_id.'.xml'; $ch = curl_init ($url); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt ($ch, CURLOPT_BINARYTRANSFER, true); curl_setopt ($ch, CURLOPT_USERAGENT, $userAgent); $output = curl_exec ($ch); $fh = fopen ($xml, 'w'); fwrite ($fh, $output); fclose ($fh); Конечно, можно использовать кэширование в скрипте и сохранять в сериализованном виде (как в предыдущем посте), кому как удобней, но я остановился на своём велосипеде.Далее мне осталось только загружать полученный xml-файл и стилизовать выдачу. Дабы не усложнять и не писать километровые классы, я скомпоную все в один файл.

$city_id = 27612; // id Москвы $xml = $_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'weather_'.$city_id.'.xml'; if (file_exists ($xml)): $data = simplexml_load_file ($xml); //грузим ?>

day as $day):?>
Утром Днем Вечером Ночью
day_part[$i]→{'temperature-data'}→avg);?> °C

day_part[$i]→weather_type;?>

ветер: day_part[$i]→wind_direction).' '.$day→day_part[$i]→wind_speed;?> м/с

влажность: day_part[$i]→humidity;?>%

давление: day_part[$i]→pressure;?> мм рт. ст.

0? '+'.$temp: $temp; } // получаем направления ветра function getWindDirection ($wind) { $wind = (string)$wind; $wind_direction = array ('s'=>'↑ ю','n'=>'↓ с','w'=>'→ з','e'=>'← в','sw'=>'↗ юз','se'=>'↖ юв','nw'=>'↘ сз','ne'=>'↙ св'); return $wind_direction[$wind]; } Скрипт выводит 10 дней по временам суток, направление ветра стрелками, как в Яндекс.Погода, так же берет усредненные значения температуры $day→day_part[$i]→{'temperature-data'}→avg, что дает нам одну цифру вместо двух.Заключение С поставленной задачей справились. В статье я хотел немного расширить представление информации сервисом Яндекс.Погода, расписывать все параметры не стал, их полный список можно посмотреть в xml-файле выдачи.

© Habrahabr.ru