[Из песочницы] И снова Яндекс.Погода для сайта: время суток, направление ветра и прочие параметры
В продолжении поста о погоде «Яндекс.Погода для сайта в деталях». Прочитав данный пост, я пришел к выводу, что тема еще актуальна, и хотел бы дополнить выше упомянутую статью своими наработками.
ЗадачаНайти сервис, который отдавал бы данные погоды с прогнозом не менее 10 дней с русской локализацией, средними величинами, временами суток и дополнительными параметрами по заданному городу.Поиски решения
Опробовав разные сервисы отдающие данные погоды, я остановился на Яндекс.Погода, все условия задачи совпадали.Так как мне нужны были данные по одному городу, первое, что я сделал, это нашел идентификатор (id) города в списке, предоставленном здесь и подставил его в export.yandex.ru/weather-ng/forecasts/
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).
Список картинок, которые я нашел
Так как описание для каждого изображения может быть несколько, я добавлю по одному, для понимания состояния погоды.
bkn_-ra_d — облачно с прояснениями, небольшой дождь (день)
bkn_-ra_n — облачно с прояснениями, небольшой дождь (ночь)
bkn_-sn_d — облачно с прояснениями, небольшой снег (день)
bkn_-sn_n — облачно с прояснениями, небольшой снег (ночь)
bkn_d — переменная облачность (день)
bkn_n — переменная облачность (ночь)
bkn_ra_d — переменная облачность, дождь (день)
bkn_ra_n — переменная облачность, дождь (ночь)
bkn_sn_d — переменная облачность, снег (день)
bkn_sn_n — переменная облачность, снег (ночь)
bl — метель
fg_d — туман
ovc — облачно
ovc_-ra — облачно, временами дождь
ovc_-sn — облачно, временами снег
ovc_ra — облачно, дождь
ovc_sn — облачно, снег
ovc_ts_ra — облачно, дождь, гроза
skc_d — ясно (день)
skc_n — ясно (ночь)
Есть еще дополнительные иконки, но я не нашел где они используются, единственное отличие, это интенсивность осадков.
bkn_+ra_d,
bkn_+ra_n,
bkn_+sn_d,
bkn_+sn_n,
ovc_+ra,
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_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;?> мм рт. ст. |
