Jacek Kowalski
2012-08-29 2f65eaef741c369606bb73ae83b32eb25df88420
commit | author | age
2fb07e 1 <?php
JK 2 class api_yrno_parse {
3     protected $xml;
4     protected $dane;
5     
6     var $symbols = array(
7         1 => 'Słonecznie',
8         2 => 'Lekkie zachmurzenie',
9         3 => 'Częściowe zachmurzenie',
10         4 => 'Zachmurzenie',
11         5 => 'Lekki deszcz z przejaśnieniami',
12         6 => 'Lekki deszcz i burze',
13         7 => 'Lekki deszcz ze śniegiem',
14         8 => 'Śnieg',
15         9 => 'Lekki deszcz',
16         10 => 'Deszcz',
17         11 => 'Burze z deszczem',
18         12 => 'Deszcz ze śniegiem',
19         13 => 'Śnieg',
20         14 => 'Burze ze śniegiem',
21         15 => 'Mgły',
22         16 => 1,
23         17 => 2,
24         18 => 5,
25         19 => 8,
26         20 => 'Deszcz ze śniegiem, burze, możliwe przejaśnienia',
27         21 => 'Burze ze śniegiem, możliwe przejaśnienia',
28         22 => 'Lekki deszcz i burze',
29         23 => 'Deszcz ze śniegiem, burze'
30     );
31     
32     var $wind = array(
33         'N' => 'północny',
34         'NW' => 'północno-zachodni',
35         'W' => 'zachodni',
36         'SW' => 'południowo-zachodni',
37         'S' => 'południowy',
38         'SE' => 'południowo-wschodni',
39         'E' => 'wschodni',
40         'NE' => 'północno-wschodni',
41     );
42     
43     function __construct($xml) {
44         libxml_use_internal_errors();
45         $this->xml = simplexml_load_string($xml);
46         libxml_clear_errors();
47         
48         if(!$this->xml) {
49             throw new Exception('Niepoprawny format danych meteorologicznych!');
50         }
51     }
52     
53     function mktime($time) {
54         return strtotime(substr($time, 0, -1));
55     }
56     
57     function wind($dir) {
58         if(isset($this->wind[$dir])) {
59             return $this->wind[$dir];
60         }
61         else
62         {
63             return '';
64         }
65     }
66     
67     function parseForecast() {
68         $this->dane = array(
69             '0h' => array(),
70             '3h' => array(),
71             '6h' => array(),
72         );
73         
74         foreach($this->xml->product->time as $time) {
75             $to = $this->mktime((string)$time->attributes()->to);
76             $from = $this->mktime((string)$time->attributes()->from);
77             
78             $time = $time->location;
79             
80             if($to == $from) {
81                 $this->dane['0h'][$to] = array(
82                     'temp' => (string)$time->temperature->attributes()->value,
83                     'wind_speed' => (string)$time->windSpeed->attributes()->mps,
84                     'wind_dir' => (string)$time->windDirection->attributes()->name,
85                     'humidity' => (string)$time->humidity->attributes()->value,
86                     'pressure' => (string)$time->pressure->attributes()->value,
87                 );
88             }
89             elseif($to-$from > 0) {
90                 if($to-$from > 14400) {
91                     $put = '6h';
92                 }
93                 else
94                 {
95                     $put = '3h';
96                 }
97                 
98                 $icon = (int)$time->symbol->attributes()->number;
99                 if(is_int($this->symbols[$icon])) {
100                     $icon = $this->symbols[$icon];
101                 }
102                 
103                 $this->dane[$put][$to] = array(
104                     'from' => $from,
105                     'to' => $to,
106                     'icon' => $icon
107                 );
108             }
109         }
110     }
111     
112     function getCurrentIcon() {
113         $now = time();
114         foreach($this->dane['3h'] as $value) {
115             if($value['from'] <= $now && $now < $value['to']) {
116                 return $value['icon'];
117             }
118         }
119         
120         return NULL;
121     }
122     
123     function getCurrentWeather() {
124         $dist = PHP_INT_MAX;
125         $current = NULL;
126         foreach($this->dane['0h'] as $time => $value) {
127             if(abs($time - time()) < $dist) {
128                 $dist = abs($time - time());
129                 $current = $value;
130             }
131             else
132             {
133                 break;
134             }
135         }
136         
137         return $current;
138     }
139     
140     function getDaypartWeather($timestamp) {
141         $start = strtotime('6:00', $timestamp);
142         $dayend = strtotime('19:30', $timestamp);
143         $end = $start + 22*3600;
144         
145         $wind = $temp = array(
146             'day' => array(),
147             'night' => array(),
148         );
149         
150         foreach($this->dane['0h'] as $time => $value) {
151             $part = NULL;
152             if($start <= $time && $time < $dayend) {
153                 $part = 'day';
154             }
155             elseif($dayend < $time && $time <= $end) {
156                 $part = 'night';
157             }
158             elseif($end <= $time) {
159                 break;
160             }
161             
162             if($part !== NULL) {
163                 if(!isset($temp[$part]['from']) || $value['temp'] < $temp[$part]['from']) {
164                     $temp[$part]['from'] = $value['temp'];
165                 }
166                 if(!isset($temp[$part]['to']) || $value['temp'] > $temp[$part]['to']) {
167                     $temp[$part]['to'] = $value['temp'];
168                 }
169                 
170                 if(!isset($wind[$part]['from']) || $value['wind_speed'] < $wind[$part]['from']) {
171                     $wind[$part]['from'] = $value['wind_speed'];
172                 }
173                 if(!isset($wind[$part]['to']) || $value['wind_speed'] > $wind[$part]['to']) {
174                     $wind[$part]['to'] = $value['wind_speed'];
175                 }
176             }
177         }
178         
179         if($temp['day'] == array() || $wind['day'] == array()) {
180             unset($temp['day']);
181             unset($wind['day']);
182         }
183         
184         return array($temp, $wind);
185     }
186     
187     function getDaypartIcon($timestamp) {
188         $start = strtotime('6:00', $timestamp);
189         $end = strtotime('24:00', $timestamp);
190         
191         $return = array();
192         foreach($this->dane['3h'] as $time => $value) {
193             if($start <= $value['from'] && $value['to'] <= $end) {
194                 $return[] = $value['icon'];
195             }
196             elseif($end <= $value['from']) {
197                 break;
198             }
199         }
200         
201         return $return;
202     }
203 }
204
205 function yrno_weather($lat, $lon) {
206     $down = new DownloadHelper('http://api.yr.no/weatherapi/locationforecastlts/1.1/?lat='.urlencode($lat).';lon='.urlencode($lon));
207     $down->setopt(CURLOPT_USERAGENT, 'BotGG/'.main::VERSION_NUM.' WeatherModule/1.0 (http://bot.jacekk.net/weather.html)');
208     try {
209         $data = $down->exec();
210         $data = new api_yrno_parse($data);
211         $data->parseForecast();
212     }
213     catch(Exception $e) {
214         $down->cacheFor(600);
215         return FALSE;
216     }
217     
218     $down->cacheFor(7200);
219     return $data;
220 }
221 ?>