БлогNot. И снова обновлять погодный сервис (пробуем openweathermap.org)

И снова обновлять погодный сервис (пробуем openweathermap.org)

Вот и мой погодный сервис от Yahoo тоже сдох, разбираться в причинах лень, видно, сговорились против меня извечные враги духовных скрепок и не хотят, чтоб у меня на стартовой странице браузера в коммуникаторе был очень лёгкий по траффику прогноз :)

Попробуем отечественный по происхождению сервис openweathermap.org, он тоже предоставляет API, правда, нужна регистрация: Get API key and Start.

Потом можно взять City ID отсюда, но сервис понимает и стандартные наименования городов латиницей, так что на сей раз делать настройки городов не буду, а ограничусь родным Нск.

Получив ID, нетрудно извлечь с сервера данные как файл и распарсить их как SimplexmlElement. Перед этим в заголовке HTTP следует послать клиенту информацию о кодировке UTF-8 (Юникод, соответственно сам скрипт нужно размещать тоже в Юникоде).

Для бесплатных юзеров есть ограничения на количество дней прогноза, но нам больше 5 и не надо, и на частоту обращений к серверу, но меня раз в секунду вполне устроит.

Посвятив пару часов работе, я написал соответствующий сервис.

Ниже приводится ссылка на сервис в работе и его исходный код (без HTML-обрамления).

Обратите внимание, что мой ID из листинга удалён и заменён на !!! (переменная $appid).

 Сервис openweathermap в работе

<?php
 $city = 'Novosibirsk'; //город латиницей... можно попробовать кириллицей или id
 $mode = 'xml'; //формат, в котором получим данные (или json)
 $units = 'metric'; //единицы измерения (или imperial)
 $lang = 'ru'; //язык
 $cnt = 5; //количество дней, не более 16, бесплатно до 5
 //Строкой ниже - неверный ключ, получите свой!
 $appid = '!!!'; //ключ API, см. статью
 $hoursplus = 6; //количество часов, которые прибавляем (отнимаем) от Гринвича
 
 header('Content-Type: text/html; charset=utf-8'); // кодировка страницы
// header("x-api-key: $appid"); //свой ключ API теперь нужно посылать в заголовке!
 $url = //URL для запроса
  'http://api.openweathermap.org/data/2.5/forecast/daily?'.
  "appid=$appid&q=$city&mode=$mode&units=$units&cnt=$cnt&lang=$lang";
 $data = @file_get_contents ($url); //Запрос к API
 if ($data) {
  $xmldata = new SimplexmlElement($data); //помещаем данные в массив
  //...и долго над ним издеваемся:
  $city= $xmldata->location->name;
  $latitude = round(xml_attribute($xmldata->location->location, 'latitude'),2);
  $longitude = round(xml_attribute($xmldata->location->location, 'longitude'),2);
  $sunrise = get_time_from_xml(xml_attribute($xmldata->sun, 'rise'),$hoursplus);
  $sunset = get_time_from_xml(xml_attribute($xmldata->sun, 'set'),$hoursplus); 
  echo "$city ($latitude;$longitude); Восход: ".$sunrise." Закат: ".$sunset."<br>\n";
  $w = Array('Вс','Пн','Вт','Ср','Чт','Пт','Сб'); //дни недели
  $winds = Array( //коды ветров
   'N'=>'С', 'NNW'=>'С/СЗ', 'NW'=>'СЗ', 'WNW'=>'З/СЗ',
   'W'=>'З', 'WSW'=>'З/ЮЗ', 'SW'=>'ЮЗ', 'SSW'=>'Ю/ЮЗ',
   'S'=>'Ю', 'SSE'=>'Ю/ЮВ', 'SE'=>'ЮВ', 'ESE'=>'В/ЮВ',
   'E'=>'В', 'ENE'=>'В/СВ', 'NE'=>'СВ', 'NNE'=>'С/СВ'
   );
  for ($i=0; $i<count($xmldata->forecast->time); $i++) { //цикл по дням прогноза
   $day = xml_attribute($xmldata->forecast->time[$i], 'day');
   $dt = date('d.m',strtotime($day));
   $wd = $w[date('w',strtotime($day))]; 
   echo $dt.', '.$wd.': '; //22.04, Пт: 
   $min = round(xml_attribute($xmldata->forecast->time[$i]->temperature, 'min'),0);
   if ($min>0) $min = '+'.$min;
   $max = round(xml_attribute($xmldata->forecast->time[$i]->temperature, 'max'),0);
   if ($max>0) $max = '+'.$max;
   if ($min!=$max) $temperature = $min.'/'.$max;
   else $temperature = $min;
   echo $temperature.'&deg;'; // -2/+3
   $name = xml_attribute($xmldata->forecast->time[$i]->symbol, 'name');
   echo ', '.$name; //, ясно
   $wind = xml_attribute($xmldata->forecast->time[$i]->windDirection, 'code');
   if (array_key_exists($wind,$winds)) 
	echo ', <font size="1">ветер:</font> '.$winds[$wind].', '.
     round(xml_attribute($xmldata->forecast->time[$i]->windSpeed, 'mps'),0).' м/с'; //ветер: З, 3 м/с
   $pressure = xml_attribute($xmldata->forecast->time[$i]->pressure, 'value');
   $pressure = round($pressure * 0.75006375541921,0); //переводим из hPa в mmHg
   if ($pressure) echo ', <font size="1">давление:</font> '.$pressure.' мм'; //давление: 755 мм
   $humidity = round(xml_attribute($xmldata->forecast->time[$i]->humidity, 'value'),0);
   if ($humidity) echo ', <font size="1">влажность:</font> '.$humidity.'%'; //влажность: 76%
   //$clouds = round(xml_attribute($xmldata->forecast->time[$i]->clouds, 'all'),0);
   //echo ', облачность '.$clouds.'%';
   echo "<br>\n";
  } //конец for по дням
/*
  //отладочная печать всего XML:
  echo '<pre>'; print_r($xmldata); echo '</pre>';
*/
 } //конец if ($data)
 else {
  echo "Сервис (временно?) недоступен";
 }

 function xml_attribute($object, $attribute) { //функция для извлечения атрибута XML
  if (isset($object[$attribute])) return (string) $object[$attribute];
 }

 function get_time_from_xml($time,$correct) { 
  //сдвинуть время $time вида 2016-04-21T23:06:58 на $correct часов
  $correct = ($correct>=0?'+':'-').abs($correct);
  return date('H:i',strtotime($correct." hours", strtotime($time)));
 }
?>

22.04.2016, 21:10 [14552 просмотра]


теги: новосибирск php погода xml сервис прогноз

показать комментарии (1)