1 /***************************************************************************
2 * Copyright (C) 2007-2009 by Shawn Starr <shawn.starr@rogers.com> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
18 ***************************************************************************/
20 /* Ion for Environment Canada XML data */
22 #include "ion_envcan.h"
24 class EnvCanadaIon::Private
: public QObject
37 QString territoryName
;
39 QString sourceOptions
;
44 QHash
<QString
, EnvCanadaIon::Private::XMLMapInfo
> m_place
;
45 QHash
<QString
, QString
> m_locations
;
50 // Weather information
51 QHash
<QString
, WeatherData
> m_weatherData
;
54 QMap
<KJob
*, QXmlStreamReader
*> m_jobXml
;
55 QMap
<KJob
*, QString
> m_jobList
;
56 QXmlStreamReader m_xmlSetup
;
58 KIO::TransferJob
*m_job
;
60 QDateTime m_dateFormat
;
65 EnvCanadaIon::EnvCanadaIon(QObject
*parent
, const QVariantList
&args
)
66 : IonInterface(parent
, args
), d(new Private())
70 EnvCanadaIon::~EnvCanadaIon()
72 // Destroy each watch/warning stored in a QVector
73 foreach(const WeatherData
&item
, d
->m_weatherData
) {
74 foreach(WeatherData::WeatherEvent
*warning
, item
.warnings
) {
80 foreach(WeatherData::WeatherEvent
*watch
, item
.watches
) {
86 foreach(WeatherData::ForecastInfo
*forecast
, item
.forecasts
) {
97 // Get the master list of locations to be parsed
98 void EnvCanadaIon::init()
100 // Get the real city XML URL so we can parse this
104 QMap
<QString
, IonInterface::ConditionIcons
> EnvCanadaIon::setupConditionIconMappings(void)
106 QMap
<QString
, ConditionIcons
> conditionList
;
109 conditionList
["mainly sunny"] = FewCloudsDay
;
110 conditionList
["mainly clear"] = FewCloudsNight
;
111 conditionList
["sunny"] = ClearDay
;
112 conditionList
["clear"] = ClearNight
;
114 // Available conditions
115 conditionList
["blowing snow"] = Snow
;
116 conditionList
["cloudy"] = Overcast
;
117 conditionList
["distance precipitation"] = LightRain
;
118 conditionList
["drifting snow"] = Flurries
;
119 conditionList
["drizzle"] = LightRain
;
120 conditionList
["dust"] = NotAvailable
;
121 conditionList
["dust devils"] = NotAvailable
;
122 conditionList
["fog"] = Mist
;
123 conditionList
["fog bank near station"] = Mist
;
124 conditionList
["fog depositing ice"] = Mist
;
125 conditionList
["fog patches"] = Mist
;
126 conditionList
["freezing drizzle"] = FreezingDrizzle
;
127 conditionList
["freezing rain"] = FreezingRain
;
128 conditionList
["funnel cloud"] = NotAvailable
;
129 conditionList
["hail"] = Hail
;
130 conditionList
["haze"] = Haze
;
131 conditionList
["heavy blowing snow"] = Snow
;
132 conditionList
["heavy drifting snow"] = Snow
;
133 conditionList
["heavy drizzle"] = LightRain
;
134 conditionList
["heavy hail"] = Hail
;
135 conditionList
["heavy mixed rain and drizzle"] = LightRain
;
136 conditionList
["heavy mixed rain and snow shower"] = RainSnow
;
137 conditionList
["heavy rain"] = Rain
;
138 conditionList
["heavy rain and snow"] = RainSnow
;
139 conditionList
["heavy rainshower"] = Rain
;
140 conditionList
["heavy snow"] = Snow
;
141 conditionList
["heavy snow pellets"] = Snow
;
142 conditionList
["heavy snowshower"] = Snow
;
143 conditionList
["heavy thunderstorm with hail"] = Thunderstorm
;
144 conditionList
["heavy thunderstorm with rain"] = Thunderstorm
;
145 conditionList
["ice crystals"] = Flurries
;
146 conditionList
["ice pellets"] = Hail
;
147 conditionList
["increasing cloud"] = Overcast
;
148 conditionList
["light drizzle"] = LightRain
;
149 conditionList
["light freezing drizzle"] = FreezingRain
;
150 conditionList
["light freezing rain"] = FreezingRain
;
151 conditionList
["light rain"] = LightRain
;
152 conditionList
["light rainshower"] = LightRain
;
153 conditionList
["light snow"] = LightSnow
;
154 conditionList
["light snow pellets"] = LightSnow
;
155 conditionList
["light snowshower"] = Flurries
;
156 conditionList
["lightning visible"] = Thunderstorm
;
157 conditionList
["mist"] = Mist
;
158 conditionList
["mixed rain and drizzle"] = LightRain
;
159 conditionList
["mixed rain and snow shower"] = RainSnow
;
160 conditionList
["not reported"] = NotAvailable
;
161 conditionList
["rain"] = Rain
;
162 conditionList
["rain and snow"] = RainSnow
;
163 conditionList
["rainshower"] = LightRain
;
164 conditionList
["recent drizzle"] = LightRain
;
165 conditionList
["recent dust or sand storm"] = NotAvailable
;
166 conditionList
["recent fog"] = Mist
;
167 conditionList
["recent freezing precipitation"] = FreezingDrizzle
;
168 conditionList
["recent hail"] = Hail
;
169 conditionList
["recent rain"] = Rain
;
170 conditionList
["recent rain and snow"] = RainSnow
;
171 conditionList
["recent rainshower"] = Rain
;
172 conditionList
["recent snow"] = Snow
;
173 conditionList
["recent snowshower"] = Flurries
;
174 conditionList
["recent thunderstorm"] = Thunderstorm
;
175 conditionList
["recent thunderstorm with hail"] = Thunderstorm
;
176 conditionList
["recent thunderstorm with heavy hail"] = Thunderstorm
;
177 conditionList
["recent thunderstorm with heavy rain"] = Thunderstorm
;
178 conditionList
["recent thunderstorm with rain"] = Thunderstorm
;
179 conditionList
["sand or dust storm"] = NotAvailable
;
180 conditionList
["severe sand or dust storm"] = NotAvailable
;
181 conditionList
["shallow fog"] = Mist
;
182 conditionList
["smoke"] = NotAvailable
;
183 conditionList
["snow"] = Snow
;
184 conditionList
["snow crystals"] = Flurries
;
185 conditionList
["snow grains"] = Flurries
;
186 conditionList
["squalls"] = Snow
;
187 conditionList
["thunderstorm with hail"] = Thunderstorm
;
188 conditionList
["thunderstorm with rain"] = Thunderstorm
;
189 conditionList
["thunderstorm with sand or dust storm"] = Thunderstorm
;
190 conditionList
["thunderstorm without precipitation"] = Thunderstorm
;
191 conditionList
["tornado"] = NotAvailable
;
192 return conditionList
;
196 QMap
<QString
, IonInterface::ConditionIcons
> EnvCanadaIon::setupForecastIconMappings(void)
198 QMap
<QString
, ConditionIcons
> forecastList
;
200 // Abbreviated forecast descriptions
201 forecastList
["a few flurries"] = Flurries
;
202 forecastList
["a few flurries mixed with ice pellets"] = RainSnow
;
203 forecastList
["a few flurries or rain showers"] = RainSnow
;
204 forecastList
["a few flurries or thundershowers"] = RainSnow
;
205 forecastList
["a few rain showers or flurries"] = RainSnow
;
206 forecastList
["a few rain showers or wet flurries"] = RainSnow
;
207 forecastList
["a few showers"] = LightRain
;
208 forecastList
["a few showers or drizzle"] = LightRain
;
209 forecastList
["a few showers or thundershowers"] = Thunderstorm
;
210 forecastList
["a few showers or thunderstorms"] = Thunderstorm
;
211 forecastList
["a few thundershowers"] = Thunderstorm
;
212 forecastList
["a few thunderstorms"] = Thunderstorm
;
213 forecastList
["a few wet flurries"] = RainSnow
;
214 forecastList
["a few wet flurries or rain showers"] = RainSnow
;
215 forecastList
["a mix of sun and cloud"] = PartlyCloudyDay
;
216 forecastList
["cloudy with sunny periods"] = PartlyCloudyDay
;
217 forecastList
["sunny"] = ClearDay
;
218 forecastList
["blizzard"] = Snow
;
219 forecastList
["clear"] = ClearNight
;
220 forecastList
["cloudy"] = Overcast
;
221 forecastList
["drizzle"] = LightRain
;
222 forecastList
["drizzle mixed with freezing drizzle"] = FreezingDrizzle
;
223 forecastList
["drizzle mixed with rain"] = LightRain
;
224 forecastList
["drizzle or freezing drizzle"] = LightRain
;
225 forecastList
["drizzle or rain"] = LightRain
;
226 forecastList
["flurries"] = Flurries
;
227 forecastList
["flurries at times heavy"] = Flurries
;
228 forecastList
["flurries at times heavy or rain snowers"] = RainSnow
;
229 forecastList
["flurries mixed with ice pellets"] = FreezingRain
;
230 forecastList
["flurries or ice pellets"] = FreezingRain
;
231 forecastList
["flurries or rain showers"] = RainSnow
;
232 forecastList
["flurries or thundershowers"] = Flurries
;
233 forecastList
["fog"] = Mist
;
234 forecastList
["fog developing"] = Mist
;
235 forecastList
["fog dissipating"] = Mist
;
236 forecastList
["fog patches"] = Mist
;
237 forecastList
["freezing drizzle"] = FreezingDrizzle
;
238 forecastList
["freezing rain"] = FreezingRain
;
239 forecastList
["freezing rain mixed with rain"] = FreezingRain
;
240 forecastList
["freezing rain mixed with snow"] = FreezingRain
;
241 forecastList
["freezing rain or ice pellets"] = FreezingRain
;
242 forecastList
["freezing rain or rain"] = FreezingRain
;
243 forecastList
["freezing rain or snow"] = FreezingRain
;
244 forecastList
["ice fog"] = Mist
;
245 forecastList
["ice fog developing"] = Mist
;
246 forecastList
["ice fog dissipating"] = Mist
;
247 forecastList
["ice pellet"] = Hail
;
248 forecastList
["ice pellet mixed with freezing rain"] = Hail
;
249 forecastList
["ice pellet mixed with snow"] = Hail
;
250 forecastList
["ice pellet or snow"] = RainSnow
;
251 forecastList
["light snow"] = LightSnow
;
252 forecastList
["light snow and blizzard"] = LightSnow
;
253 forecastList
["light snow and blizzard and blowing snow"] = Snow
;
254 forecastList
["light snow and blowing snow"] = LightSnow
;
255 forecastList
["light snow mixed with freezing drizzle"] = FreezingDrizzle
;
256 forecastList
["light snow mixed with freezing rain"] = FreezingRain
;
257 forecastList
["light snow or ice pellets"] = LightSnow
;
258 forecastList
["light snow or rain"] = RainSnow
;
259 forecastList
["light wet snow"] = RainSnow
;
260 forecastList
["light wet snow or rain"] = RainSnow
;
261 forecastList
["local snow squalls"] = Snow
;
262 forecastList
["near blizzard"] = Snow
;
263 forecastList
["overcast"] = Overcast
;
264 forecastList
["increasing cloudiness"] = Overcast
;
265 forecastList
["increasing clouds"] = Overcast
;
266 forecastList
["periods of drizzle"] = LightRain
;
267 forecastList
["periods of drizzle mixed with freezing drizzle"] = FreezingDrizzle
;
268 forecastList
["periods of drizzle mixed with rain"] = LightRain
;
269 forecastList
["periods of drizzle or freezing drizzle"] = FreezingDrizzle
;
270 forecastList
["periods of drizzle or rain"] = LightRain
;
271 forecastList
["periods of freezing drizzle"] = FreezingDrizzle
;
272 forecastList
["periods of freezing drizzle or drizzle"] = FreezingDrizzle
;
273 forecastList
["periods of freezing drizzle or rain"] = FreezingDrizzle
;
274 forecastList
["periods of freezing rain"] = FreezingRain
;
275 forecastList
["periods of freezing rain mixed with ice pellets"] = FreezingRain
;
276 forecastList
["periods of freezing rain mixed with rain"] = FreezingRain
;
277 forecastList
["periods of freezing rain mixed with snow"] = FreezingRain
;
278 forecastList
["periods of freezing rain mixed with freezing drizzle"] = FreezingRain
;
279 forecastList
["periods of freezing rain or ice pellets"] = FreezingRain
;
280 forecastList
["periods of freezing rain or rain"] = FreezingRain
;
281 forecastList
["periods of freezing rain or snow"] = FreezingRain
;
282 forecastList
["periods of ice pellet"] = Hail
;
283 forecastList
["periods of ice pellet mixed with freezing rain"] = Hail
;
284 forecastList
["periods of ice pellet mixed with snow"] = Hail
;
285 forecastList
["periods of ice pellet or freezing rain"] = Hail
;
286 forecastList
["periods of ice pellet or snow"] = Hail
;
287 forecastList
["periods of light snow"] = LightSnow
;
288 forecastList
["periods of light snow and blizzard"] = Snow
;
289 forecastList
["periods of light snow and blizzard and blowing snow"] = Snow
;
290 forecastList
["periods of light snow and blowing snow"] = LightSnow
;
291 forecastList
["periods of light snow mixed with freezing drizzle"] = RainSnow
;
292 forecastList
["periods of light snow mixed with freezing rain"] = RainSnow
;
293 forecastList
["periods of light snow mixed with ice pelletS"] = LightSnow
;
294 forecastList
["periods of light snow mixed with rain"] = RainSnow
;
295 forecastList
["periods of light snow or freezing drizzle"] = RainSnow
;
296 forecastList
["periods of light snow or freezing rain"] = RainSnow
;
297 forecastList
["periods of light snow or ice pellets"] = LightSnow
;
298 forecastList
["periods of light snow or rain"] = RainSnow
;
299 forecastList
["periods of light wet snow"] = LightSnow
;
300 forecastList
["periods of light wet snow mixed with rain"] = RainSnow
;
301 forecastList
["periods of light wet snow or rain"] = RainSnow
;
302 forecastList
["periods of rain"] = Rain
;
303 forecastList
["periods of rain mixed with freezing rain"] = Rain
;
304 forecastList
["periods of rain mixed with snow"] = RainSnow
;
305 forecastList
["periods of rain or drizzle"] = Rain
;
306 forecastList
["periods of rain or freezing rain"] = Rain
;
307 forecastList
["periods of rain or thundershowers"] = Thunderstorm
;
308 forecastList
["periods of rain or thunderstorms"] = Thunderstorm
;
309 forecastList
["periods of rain or snow"] = RainSnow
;
310 forecastList
["periods of snow"] = Snow
;
311 forecastList
["periods of snow and blizzard"] = Snow
;
312 forecastList
["periods of snow and blizzard and blowing snow"] = Snow
;
313 forecastList
["periods of snow and blowing snow"] = Snow
;
314 forecastList
["periods of snow mixed with freezing drizzle"] = RainSnow
;
315 forecastList
["periods of snow mixed with freezing rain"] = RainSnow
;
316 forecastList
["periods of snow mixed with ice pellets"] = Snow
;
317 forecastList
["periods of snow mixed with rain"] = RainSnow
;
318 forecastList
["periods of snow or freezing drizzle"] = RainSnow
;
319 forecastList
["periods of snow or freezing rain"] = RainSnow
;
320 forecastList
["periods of snow or ice pellets"] = Snow
;
321 forecastList
["periods of snow or rain"] = RainSnow
;
322 forecastList
["periods of rain or snow"] = RainSnow
;
323 forecastList
["periods of wet snow"] = Snow
;
324 forecastList
["periods of wet snow mixed with rain"] = RainSnow
;
325 forecastList
["periods of wet snow or rain"] = RainSnow
;
326 forecastList
["rain"] = Rain
;
327 forecastList
["rain at times heavy"] = Rain
;
328 forecastList
["rain at times heavy mixed with freezing rain"] = FreezingRain
;
329 forecastList
["rain at times heavy mixed with snow"] = RainSnow
;
330 forecastList
["rain at times heavy or drizzle"] = Rain
;
331 forecastList
["rain at times heavy or freezing rain"] = Rain
;
332 forecastList
["rain at times heavy or snow"] = RainSnow
;
333 forecastList
["rain at times heavy or thundershowers"] = Thunderstorm
;
334 forecastList
["rain at times heavy or thunderstorms"] = Thunderstorm
;
335 forecastList
["rain mixed with freezing rain"] = FreezingRain
;
336 forecastList
["rain mixed with snow"] = RainSnow
;
337 forecastList
["rain or drizzle"] = Rain
;
338 forecastList
["rain or freezing rain"] = Rain
;
339 forecastList
["rain or snow"] = RainSnow
;
340 forecastList
["rain or thundershowers"] = Thunderstorm
;
341 forecastList
["rain or thunderstorms"] = Thunderstorm
;
342 forecastList
["rain showers or flurries"] = RainSnow
;
343 forecastList
["rain showers or wet flurries"] = RainSnow
;
344 forecastList
["showers"] = Showers
;
345 forecastList
["showers at times heavy"] = Showers
;
346 forecastList
["showers at times heavy or thundershowers"] = Thunderstorm
;
347 forecastList
["showers at times heavy or thunderstorms"] = Thunderstorm
;
348 forecastList
["showers or drizzle"] = Showers
;
349 forecastList
["showers or thundershowers"] = Showers
;
350 forecastList
["showers or thunderstorms"] = Showers
;
351 forecastList
["smoke"] = NotAvailable
;
352 forecastList
["snow"] = Snow
;
353 forecastList
["snow and blizzard"] = Snow
;
354 forecastList
["snow and blizzard and blowing snow"] = Snow
;
355 forecastList
["snow and blowing snow"] = Snow
;
356 forecastList
["snow at times heavy"] = Snow
;
357 forecastList
["snow at times heavy and blizzard"] = Snow
;
358 forecastList
["snow at times heavy and blowing snow"] = Snow
;
359 forecastList
["snow at times heavy mixed with freezing drizzle"] = RainSnow
;
360 forecastList
["snow at times heavy mixed with freezing rain"] = RainSnow
;
361 forecastList
["snow at times heavy mixed with ice pellets"] = Snow
;
362 forecastList
["snow at times heavy mixed with rain"] = RainSnow
;
363 forecastList
["snow at times heavy or freezing rain"] = RainSnow
;
364 forecastList
["snow at times heavy or ice pellets"] = Snow
;
365 forecastList
["snow at times heavy or rain"] = RainSnow
;
366 forecastList
["snow mixed with freezing drizzle"] = RainSnow
;
367 forecastList
["snow mixed with freezing rain"] = RainSnow
;
368 forecastList
["snow mixed with ice pellets"] = Snow
;
369 forecastList
["snow mixed with rain"] = RainSnow
;
370 forecastList
["snow or freezing drizzle"] = RainSnow
;
371 forecastList
["snow or freezing rain"] = RainSnow
;
372 forecastList
["snow or ice pellets"] = Snow
;
373 forecastList
["snow or rain"] = RainSnow
;
374 forecastList
["snow squalls"] = Snow
;
375 forecastList
["sunny"] = ClearDay
;
376 forecastList
["sunny with cloudy periods"] = PartlyCloudyDay
;
377 forecastList
["thunderstorms"] = Thunderstorm
;
378 forecastList
["thunderstorms and possible hail"] = Thunderstorm
;
379 forecastList
["wet flurries"] = Flurries
;
380 forecastList
["wet flurries at times heavy"] = Flurries
;
381 forecastList
["wet flurries at times heavy or rain snowers"] = RainSnow
;
382 forecastList
["wet flurries or rain showers"] = RainSnow
;
383 forecastList
["wet snow"] = Snow
;
384 forecastList
["wet snow at times heavy"] = Snow
;
385 forecastList
["wet snow at times heavy mixed with rain"] = RainSnow
;
386 forecastList
["wet snow mixed with rain"] = RainSnow
;
387 forecastList
["wet snow or rain"] = RainSnow
;
388 forecastList
["windy"] = NotAvailable
;
390 forecastList
["chance of drizzle mixed with freezing drizzle"] = LightRain
;
391 forecastList
["chance of flurries mixed with ice pellets"] = Flurries
;
392 forecastList
["chance of flurries or ice pellets"] = Flurries
;
393 forecastList
["chance of flurries or rain showers"] = RainSnow
;
394 forecastList
["chance of flurries or thundershowers"] = RainSnow
;
395 forecastList
["chance of freezing drizzle"] = FreezingDrizzle
;
396 forecastList
["chance of freezing rain"] = FreezingRain
;
397 forecastList
["chance of freezing rain mixed with snow"] = RainSnow
;
398 forecastList
["chance of freezing rain or rain"] = FreezingRain
;
399 forecastList
["chance of freezing rain or snow"] = RainSnow
;
400 forecastList
["chance of light snow and blowing snow"] = LightSnow
;
401 forecastList
["chance of light snow mixed with freezing drizzle"] = LightSnow
;
402 forecastList
["chance of light snow mixed with ice pellets"] = LightSnow
;
403 forecastList
["chance of light snow mixed with rain"] = RainSnow
;
404 forecastList
["chance of light snow or freezing rain"] = RainSnow
;
405 forecastList
["chance of light snow or ice pellets"] = LightSnow
;
406 forecastList
["chance of light snow or rain"] = RainSnow
;
407 forecastList
["chance of light wet snow"] = Snow
;
408 forecastList
["chance of rain"] = Rain
;
409 forecastList
["chance of rain at times heavy"] = Rain
;
410 forecastList
["chance of rain mixed with snow"] = RainSnow
;
411 forecastList
["chance of rain or drizzle"] = Rain
;
412 forecastList
["chance of rain or freezing rain"] = Rain
;
413 forecastList
["chance of rain or snow"] = RainSnow
;
414 forecastList
["chance of rain showers or flurries"] = RainSnow
;
415 forecastList
["chance of rain showers or wet flurries"] = RainSnow
;
416 forecastList
["chance of severe thunderstorms"] = Thunderstorm
;
417 forecastList
["chance of showers at times heavy"] = Rain
;
418 forecastList
["chance of showers at times heavy or thundershowers"] = Thunderstorm
;
419 forecastList
["chance of showers at times heavy or thunderstorms"] = Thunderstorm
;
420 forecastList
["chance of showers or thundershowers"] = Showers
;
421 forecastList
["chance of showers or thunderstorms"] = Thunderstorm
;
422 forecastList
["chance of snow"] = Snow
;
423 forecastList
["chance of snow and blizzard"] = Snow
;
424 forecastList
["chance of snow mixed with freezing drizzle"] = Snow
;
425 forecastList
["chance of snow mixed with freezing rain"] = RainSnow
;
426 forecastList
["chance of snow mixed with rain"] = RainSnow
;
427 forecastList
["chance of snow or rain"] = RainSnow
;
428 forecastList
["chance of snow squalls"] = Snow
;
429 forecastList
["chance of thundershowers"] = Thunderstorm
;
430 forecastList
["chance of thunderstorms"] = Thunderstorm
;
431 forecastList
["chance of thunderstorms and possible hail"] = Thunderstorm
;
432 forecastList
["chance of wet flurries"] = Flurries
;
433 forecastList
["chance of wet flurries at times heavy"] = Flurries
;
434 forecastList
["chance of wet flurries or rain showers"] = RainSnow
;
435 forecastList
["chance of wet snow"] = Snow
;
436 forecastList
["chance of wet snow mixed with rain"] = RainSnow
;
437 forecastList
["chance of wet snow or rain"] = RainSnow
;
442 QMap
<QString
, IonInterface::ConditionIcons
> const& EnvCanadaIon::conditionIcons(void)
444 static QMap
<QString
, ConditionIcons
> const condval
= setupConditionIconMappings();
448 QMap
<QString
, IonInterface::ConditionIcons
> const& EnvCanadaIon::forecastIcons(void)
450 static QMap
<QString
, ConditionIcons
> const foreval
= setupForecastIconMappings();
454 QStringList
EnvCanadaIon::validate(const QString
& source
) const
456 QStringList placeList
;
457 QHash
<QString
, QString
>::const_iterator it
= d
->m_locations
.constBegin();
458 while (it
!= d
->m_locations
.constEnd()) {
459 if (it
.value().toLower().contains(source
.toLower())) {
460 placeList
.append(QString("place|%1").arg(it
.value().split('|')[1]));
465 // Check if placeList is empty if so, return nothing.
466 if (placeList
.isEmpty()) {
467 return QStringList();
473 // Get a specific Ion's data
474 bool EnvCanadaIon::updateIonSource(const QString
& source
)
476 // We expect the applet to send the source in the following tokenization:
477 // ionname|validate|place_name - Triggers validation of place
478 // ionname|weather|place_name - Triggers receiving weather of place
480 QStringList sourceAction
= source
.split('|');
482 // Guard: if the size of array is not 2 then we have bad data, return an error
483 if (sourceAction
.size() < 2) {
484 setData(source
, "validate", QString("envcan|timeout"));
488 if (sourceAction
[1] == QString("validate")) {
489 QStringList result
= validate(QString("%1|%2").arg(sourceAction
[0]).arg(sourceAction
[2]));
491 if (result
.size() == 1) {
492 setData(source
, "validate", QString("envcan|valid|single|%1").arg(result
.join("|")));
494 } else if (result
.size() > 1) {
495 setData(source
, "validate", QString("envcan|valid|multiple|%1").arg(result
.join("|")));
497 } else if (result
.size() == 0) {
498 setData(source
, "validate", QString("envcan|invalid|single|%1").arg(sourceAction
[2]));
502 } else if (sourceAction
[1] == QString("weather")) {
509 // Parses city list and gets the correct city based on ID number
510 void EnvCanadaIon::getXMLSetup()
512 d
->m_url
= new KUrl("http://dd.weatheroffice.ec.gc.ca/EC_sites/xml/siteList.xml");
514 KIO::TransferJob
*job
= KIO::get(d
->m_url
->url(), KIO::NoReload
, KIO::HideProgressInfo
);
517 connect(job
, SIGNAL(data(KIO::Job
*, const QByteArray
&)), this,
518 SLOT(setup_slotDataArrived(KIO::Job
*, const QByteArray
&)));
519 connect(job
, SIGNAL(result(KJob
*)), this, SLOT(setup_slotJobFinished(KJob
*)));
523 // Gets specific city XML data
524 void EnvCanadaIon::getXMLData(const QString
& source
)
528 // Demunge source name for key only.
529 QString dataKey
= source
;
530 dataKey
.remove("|weather");
531 url
= "http://dd.weatheroffice.ec.gc.ca/EC_sites/xml/" + d
->m_place
[dataKey
].territoryName
+ "/" + d
->m_place
[dataKey
].cityCode
+ "_e.xml";
532 //url="file:///home/spstarr/Desktop/s0000649_e.xml";
534 if (d
->m_place
[dataKey
].territoryName
.isEmpty() && d
->m_place
[dataKey
].cityCode
.isEmpty()) {
535 setData(source
, "validate", QString("envcan|timeout"));
539 d
->m_job
= KIO::get(url
.url(), KIO::Reload
, KIO::HideProgressInfo
);
540 d
->m_jobXml
.insert(d
->m_job
, new QXmlStreamReader
);
541 d
->m_jobList
.insert(d
->m_job
, source
);
544 connect(d
->m_job
, SIGNAL(data(KIO::Job
*, const QByteArray
&)), this,
545 SLOT(slotDataArrived(KIO::Job
*, const QByteArray
&)));
546 connect(d
->m_job
, SIGNAL(result(KJob
*)), this, SLOT(slotJobFinished(KJob
*)));
550 void EnvCanadaIon::setup_slotDataArrived(KIO::Job
*job
, const QByteArray
&data
)
554 if (data
.isEmpty()) {
559 d
->m_xmlSetup
.addData(data
);
562 void EnvCanadaIon::slotDataArrived(KIO::Job
*job
, const QByteArray
&data
)
565 if (data
.isEmpty() || !d
->m_jobXml
.contains(job
)) {
570 d
->m_jobXml
[job
]->addData(data
);
573 void EnvCanadaIon::slotJobFinished(KJob
*job
)
575 // Dual use method, if we're fetching location data to parse we need to do this first
576 setData(d
->m_jobList
[job
], Data());
577 readXMLData(d
->m_jobList
[job
], *d
->m_jobXml
[job
]);
578 d
->m_jobList
.remove(job
);
579 delete d
->m_jobXml
[job
];
580 d
->m_jobXml
.remove(job
);
583 void EnvCanadaIon::setup_slotJobFinished(KJob
*job
)
587 setInitialized(true);
590 // Parse the city list and store into a QMap
591 bool EnvCanadaIon::readXMLSetup()
594 while (!d
->m_xmlSetup
.atEnd()) {
595 d
->m_xmlSetup
.readNext();
597 if (d
->m_xmlSetup
.isStartElement()) {
599 // XML ID code to match filename
600 if (d
->m_xmlSetup
.name() == "site") {
601 d
->m_code
= d
->m_xmlSetup
.attributes().value("code").toString();
604 if (d
->m_xmlSetup
.name() == "nameEn") {
605 d
->m_cityName
= d
->m_xmlSetup
.readElementText(); // Name of cities
608 if (d
->m_xmlSetup
.name() == "provinceCode") {
609 d
->m_territory
= d
->m_xmlSetup
.readElementText(); // Provinces/Territory list
610 tmp
= "envcan|" + d
->m_cityName
+ ", " + d
->m_territory
; // Build the key name.
613 d
->m_place
[tmp
].cityCode
= d
->m_code
;
614 d
->m_place
[tmp
].territoryName
= d
->m_territory
;
615 d
->m_place
[tmp
].cityName
= d
->m_cityName
;
617 // Set the string list, we will use for the applet to display the available cities.
618 d
->m_locations
[tmp
] = tmp
;
623 return !d
->m_xmlSetup
.error();
626 WeatherData
EnvCanadaIon::parseWeatherSite(WeatherData
& data
, QXmlStreamReader
& xml
)
628 while (!xml
.atEnd()) {
631 if (xml
.isStartElement()) {
632 if (xml
.name() == "license") {
633 xml
.readElementText();
634 } else if (xml
.name() == "location") {
635 parseLocations(data
, xml
);
636 } else if (xml
.name() == "warnings") {
637 // Cleanup warning list on update
638 data
.warnings
.clear();
639 data
.watches
.clear();
640 parseWarnings(data
, xml
);
641 } else if (xml
.name() == "currentConditions") {
642 parseConditions(data
, xml
);
643 } else if (xml
.name() == "forecastGroup") {
644 // Clean up forecast list on update
645 data
.forecasts
.clear();
646 parseWeatherForecast(data
, xml
);
647 } else if (xml
.name() == "yesterdayConditions") {
648 parseYesterdayWeather(data
, xml
);
649 } else if (xml
.name() == "riseSet") {
650 parseAstronomicals(data
, xml
);
651 } else if (xml
.name() == "almanac") {
652 parseWeatherRecords(data
, xml
);
654 parseUnknownElement(xml
);
661 // Parse Weather data main loop, from here we have to decend into each tag pair
662 bool EnvCanadaIon::readXMLData(const QString
& source
, QXmlStreamReader
& xml
)
665 data
.comforttemp
= "N/A";
666 data
.recordHigh
= 0.0;
667 data
.recordLow
= 0.0;
669 QString dataKey
= source
;
670 dataKey
.remove("|weather");
671 data
.shortTerritoryName
= d
->m_place
[dataKey
].territoryName
;
672 while (!xml
.atEnd()) {
675 if (xml
.isEndElement()) {
679 if (xml
.isStartElement()) {
680 if (xml
.name() == "siteData") {
681 data
= parseWeatherSite(data
, xml
);
683 parseUnknownElement(xml
);
688 d
->m_weatherData
[source
] = data
;
689 updateWeather(source
);
693 void EnvCanadaIon::parseDateTime(WeatherData
& data
, QXmlStreamReader
& xml
, WeatherData::WeatherEvent
*event
)
696 Q_ASSERT(xml
.isStartElement() && xml
.name() == "dateTime");
698 // What kind of date info is this?
699 QString dateType
= xml
.attributes().value("name").toString();
700 QString dateZone
= xml
.attributes().value("zone").toString();
702 QString selectTimeStamp
;
704 while (!xml
.atEnd()) {
707 if (xml
.isEndElement()) {
711 if (xml
.isStartElement()) {
712 if (dateType
== "xmlCreation") {
715 if (dateZone
== "UTC") {
718 if (xml
.name() == "year") {
719 xml
.readElementText();
720 } else if (xml
.name() == "month") {
721 xml
.readElementText();
722 } else if (xml
.name() == "day") {
723 xml
.readElementText();
724 } else if (xml
.name() == "hour")
725 xml
.readElementText();
726 else if (xml
.name() == "minute")
727 xml
.readElementText();
728 else if (xml
.name() == "timeStamp")
729 selectTimeStamp
= xml
.readElementText();
730 else if (xml
.name() == "textSummary") {
731 if (dateType
== "eventIssue") {
733 event
->timestamp
= xml
.readElementText();
735 } else if (dateType
== "observation") {
736 xml
.readElementText();
737 d
->m_dateFormat
= QDateTime::fromString(selectTimeStamp
, "yyyyMMddHHmmss");
738 data
.obsTimestamp
= d
->m_dateFormat
.toString("dd.MM.yyyy @ hh:mm ap");
739 data
.iconPeriodHour
= d
->m_dateFormat
.toString("HH").toInt();
740 data
.iconPeriodAP
= d
->m_dateFormat
.toString("ap");
741 } else if (dateType
== "forecastIssue") {
742 data
.forecastTimestamp
= xml
.readElementText();
743 } else if (dateType
== "sunrise") {
744 data
.sunriseTimestamp
= xml
.readElementText();
745 } else if (dateType
== "sunset") {
746 data
.sunsetTimestamp
= xml
.readElementText();
747 } else if (dateType
== "moonrise") {
748 data
.moonriseTimestamp
= xml
.readElementText();
749 } else if (dateType
== "moonset") {
750 data
.moonsetTimestamp
= xml
.readElementText();
757 void EnvCanadaIon::parseLocations(WeatherData
& data
, QXmlStreamReader
& xml
)
759 Q_ASSERT(xml
.isStartElement() && xml
.name() == "location");
761 while (!xml
.atEnd()) {
764 if (xml
.isEndElement()) {
768 if (xml
.isStartElement()) {
769 if (xml
.name() == "country") {
770 data
.countryName
= xml
.readElementText();
771 } else if (xml
.name() == "province" || xml
.name() == "territory") {
772 data
.longTerritoryName
= xml
.readElementText();
773 } else if (xml
.name() == "name") {
774 data
.cityName
= xml
.readElementText();
775 } else if (xml
.name() == "region") {
776 data
.regionName
= xml
.readElementText();
778 parseUnknownElement(xml
);
784 void EnvCanadaIon::parseWindInfo(WeatherData
& data
, QXmlStreamReader
& xml
)
786 Q_ASSERT(xml
.isStartElement() && xml
.name() == "wind");
788 while (!xml
.atEnd()) {
791 if (xml
.isEndElement()) {
795 if (xml
.isStartElement()) {
796 if (xml
.name() == "speed") {
797 data
.windSpeed
= xml
.readElementText();
798 } else if (xml
.name() == "gust") {
799 data
.windGust
= xml
.readElementText();
800 } else if (xml
.name() == "direction") {
801 data
.windDirection
= xml
.readElementText();
802 } else if (xml
.name() == "bearing") {
803 data
.windDegrees
= xml
.attributes().value("degrees").toString();
805 parseUnknownElement(xml
);
811 void EnvCanadaIon::parseConditions(WeatherData
& data
, QXmlStreamReader
& xml
)
814 Q_ASSERT(xml
.isStartElement() && xml
.name() == "currentConditions");
815 data
.temperature
= "N/A";
816 data
.dewpoint
= "N/A";
817 data
.condition
= "N/A";
818 data
.comforttemp
= "N/A";
819 data
.stationID
= "N/A";
821 data
.pressureTendency
= "N/A";
823 data
.humidity
= "N/A";
824 data
.windSpeed
= "N/A";
825 data
.windGust
= "N/A";
827 while (!xml
.atEnd()) {
830 if (xml
.isEndElement() && xml
.name() == "currentConditions")
833 if (xml
.isStartElement()) {
834 if (xml
.name() == "station") {
835 data
.stationID
= xml
.attributes().value("code").toString();
836 } else if (xml
.name() == "dateTime") {
837 parseDateTime(data
, xml
);
838 } else if (xml
.name() == "condition") {
839 data
.condition
= xml
.readElementText();
840 } else if (xml
.name() == "temperature") {
841 data
.temperature
= xml
.readElementText();
842 } else if (xml
.name() == "dewpoint") {
843 data
.dewpoint
= xml
.readElementText();
844 } else if (xml
.name() == "humidex" || xml
.name() == "windChill") {
845 data
.comforttemp
= xml
.readElementText();
846 } else if (xml
.name() == "pressure") {
847 data
.pressureTendency
= xml
.attributes().value("tendency").toString();
848 if (data
.pressureTendency
.isEmpty()) {
849 data
.pressureTendency
= "steady";
851 data
.pressure
= xml
.readElementText().toFloat();
852 } else if (xml
.name() == "visibility") {
853 data
.visibility
= xml
.readElementText().toFloat();
854 } else if (xml
.name() == "relativeHumidity") {
855 data
.humidity
= xml
.readElementText();
856 } else if (xml
.name() == "wind") {
857 parseWindInfo(data
, xml
);
860 // parseUnknownElement(xml);
864 if (data
.temperature
.isEmpty()) {
865 data
.temperature
= "N/A";
869 void EnvCanadaIon::parseWarnings(WeatherData
&data
, QXmlStreamReader
& xml
)
871 WeatherData::WeatherEvent
*watch
= new WeatherData::WeatherEvent
;
872 WeatherData::WeatherEvent
*warning
= new WeatherData::WeatherEvent
;
874 Q_ASSERT(xml
.isStartElement() && xml
.name() == "warnings");
875 QString eventURL
= xml
.attributes().value("url").toString();
878 while (!xml
.atEnd()) {
881 if (xml
.isEndElement() && xml
.name() == "warnings") {
885 if (xml
.isStartElement()) {
886 if (xml
.name() == "dateTime") {
888 parseDateTime(data
, xml
, watch
);
891 parseDateTime(data
, xml
, warning
);
894 if (!warning
->timestamp
.isEmpty() && !warning
->url
.isEmpty()) {
895 data
.warnings
.append(warning
);
896 warning
= new WeatherData::WeatherEvent
;
898 if (!watch
->timestamp
.isEmpty() && !watch
->url
.isEmpty()) {
899 data
.watches
.append(watch
);
900 watch
= new WeatherData::WeatherEvent
;
903 } else if (xml
.name() == "event") {
904 // Append new event to list.
905 QString eventType
= xml
.attributes().value("type").toString();
906 if (eventType
== "watch") {
907 watch
->url
= eventURL
;
908 watch
->type
= eventType
;
909 watch
->priority
= xml
.attributes().value("priority").toString();
910 watch
->description
= xml
.attributes().value("description").toString();
914 if (eventType
== "warning") {
915 warning
->url
= eventURL
;
916 warning
->type
= eventType
;
917 warning
->priority
= xml
.attributes().value("priority").toString();
918 warning
->description
= xml
.attributes().value("description").toString();
922 if (xml
.name() != "dateTime") {
923 parseUnknownElement(xml
);
933 void EnvCanadaIon::parseWeatherForecast(WeatherData
& data
, QXmlStreamReader
& xml
)
935 WeatherData::ForecastInfo
* forecast
= new WeatherData::ForecastInfo
;
936 Q_ASSERT(xml
.isStartElement() && xml
.name() == "forecastGroup");
938 while (!xml
.atEnd()) {
941 if (xml
.isEndElement() && xml
.name() == "forecastGroup") {
945 if (xml
.isStartElement()) {
946 if (xml
.name() == "dateTime") {
947 parseDateTime(data
, xml
);
948 } else if (xml
.name() == "regionalNormals") {
949 parseRegionalNormals(data
, xml
);
950 } else if (xml
.name() == "forecast") {
951 parseForecast(data
, xml
, forecast
);
952 forecast
= new WeatherData::ForecastInfo
;
954 parseUnknownElement(xml
);
961 void EnvCanadaIon::parseRegionalNormals(WeatherData
& data
, QXmlStreamReader
& xml
)
963 Q_ASSERT(xml
.isStartElement() && xml
.name() == "regionalNormals");
965 while (!xml
.atEnd()) {
968 if (xml
.isEndElement()) {
972 if (xml
.isStartElement()) {
973 if (xml
.name() == "textSummary") {
974 xml
.readElementText();
975 } else if (xml
.name() == "temperature" && xml
.attributes().value("class") == "high") {
976 data
.normalHigh
= xml
.readElementText();
977 } else if (xml
.name() == "temperature" && xml
.attributes().value("class") == "low") {
978 data
.normalLow
= xml
.readElementText();
984 void EnvCanadaIon::parseForecast(WeatherData
& data
, QXmlStreamReader
& xml
, WeatherData::ForecastInfo
*forecast
)
987 Q_ASSERT(xml
.isStartElement() && xml
.name() == "forecast");
989 while (!xml
.atEnd()) {
992 if (xml
.isEndElement() && xml
.name() == "forecast") {
993 data
.forecasts
.append(forecast
);
997 if (xml
.isStartElement()) {
998 if (xml
.name() == "period") {
999 forecast
->forecastPeriod
= xml
.attributes().value("textForecastName").toString();
1000 } else if (xml
.name() == "textSummary") {
1001 forecast
->forecastSummary
= xml
.readElementText();
1002 } else if (xml
.name() == "abbreviatedForecast") {
1003 parseShortForecast(forecast
, xml
);
1004 } else if (xml
.name() == "temperatures") {
1005 parseForecastTemperatures(forecast
, xml
);
1006 } else if (xml
.name() == "winds") {
1007 parseWindForecast(forecast
, xml
);
1008 } else if (xml
.name() == "precipitation") {
1009 parsePrecipitationForecast(forecast
, xml
);
1010 } else if (xml
.name() == "uv") {
1011 data
.UVRating
= xml
.attributes().value("category").toString();
1012 parseUVIndex(data
, xml
);
1013 // else if (xml.name() == "frost") { FIXME: Wait until winter to see what this looks like.
1014 // parseFrost(xml, forecast);
1016 if (xml
.name() != "forecast") {
1017 parseUnknownElement(xml
);
1024 void EnvCanadaIon::parseShortForecast(WeatherData::ForecastInfo
*forecast
, QXmlStreamReader
& xml
)
1026 Q_ASSERT(xml
.isStartElement() && xml
.name() == "abbreviatedForecast");
1030 while (!xml
.atEnd()) {
1033 if (xml
.isEndElement() && xml
.name() == "abbreviatedForecast") {
1037 if (xml
.isStartElement()) {
1038 if (xml
.name() == "pop") {
1039 forecast
->popPrecent
= xml
.readElementText();
1041 if (xml
.name() == "textSummary") {
1042 shortText
= xml
.readElementText();
1043 QMap
<QString
, ConditionIcons
> forecastList
;
1044 forecastList
= forecastIcons();
1045 if ((forecast
->forecastPeriod
== "tonight") || (forecast
->forecastPeriod
.contains("night"))) {
1046 forecastList
["a few clouds"] = FewCloudsNight
;
1047 forecastList
["cloudy periods"] = PartlyCloudyNight
;
1048 forecastList
["chance of drizzle mixed with rain"] = ChanceShowersNight
;
1049 forecastList
["chance of drizzle"] = ChanceShowersNight
;
1050 forecastList
["chance of drizzle or rain"] = ChanceShowersNight
;
1051 forecastList
["chance of flurries"] = ChanceSnowNight
;
1052 forecastList
["chance of light snow"] = ChanceSnowNight
;
1053 forecastList
["chance of flurries at times heavy"] = ChanceSnowNight
;
1054 forecastList
["chance of showers or drizzle"] = ChanceShowersNight
;
1055 forecastList
["chance of showers"] = ChanceShowersNight
;
1056 forecastList
["clearing"] = ClearNight
;
1058 forecastList
["a few clouds"] = FewCloudsDay
;
1059 forecastList
["cloudy periods"] = PartlyCloudyDay
;
1060 forecastList
["chance of drizzle mixed with rain"] = ChanceShowersDay
;
1061 forecastList
["chance of drizzle"] = ChanceShowersDay
;
1062 forecastList
["chance of drizzle or rain"] = ChanceShowersDay
;
1063 forecastList
["chance of flurries"] = ChanceSnowDay
;
1064 forecastList
["chance of light snow"] = ChanceSnowDay
;
1065 forecastList
["chance of flurries at times heavy"] = ChanceSnowDay
;
1066 forecastList
["chance of showers or drizzle"] = ChanceShowersDay
;
1067 forecastList
["chance of showers"] = ChanceShowersDay
;
1068 forecastList
["clearing"] = ClearDay
;
1070 forecast
->shortForecast
= shortText
;
1071 forecast
->iconName
= getWeatherIcon(forecastList
, shortText
.toLower());
1077 void EnvCanadaIon::parseUVIndex(WeatherData
& data
, QXmlStreamReader
& xml
)
1079 Q_ASSERT(xml
.isStartElement() && xml
.name() == "uv");
1081 while (!xml
.atEnd()) {
1084 if (xml
.isEndElement() && xml
.name() == "uv") {
1088 if (xml
.isStartElement()) {
1089 if (xml
.name() == "index") {
1090 data
.UVIndex
= xml
.readElementText();
1092 if (xml
.name() == "textSummary") {
1093 xml
.readElementText();
1099 void EnvCanadaIon::parseForecastTemperatures(WeatherData::ForecastInfo
*forecast
, QXmlStreamReader
& xml
)
1101 Q_ASSERT(xml
.isStartElement() && xml
.name() == "temperatures");
1103 while (!xml
.atEnd()) {
1106 if (xml
.isEndElement() && xml
.name() == "temperatures") {
1110 if (xml
.isStartElement()) {
1111 if (xml
.name() == "temperature" && xml
.attributes().value("class") == "low") {
1112 forecast
->forecastTempLow
= xml
.readElementText();
1113 } else if (xml
.name() == "temperature" && xml
.attributes().value("class") == "high") {
1114 forecast
->forecastTempHigh
= xml
.readElementText();
1115 } else if (xml
.name() == "textSummary") {
1116 xml
.readElementText();
1122 void EnvCanadaIon::parsePrecipitationForecast(WeatherData::ForecastInfo
*forecast
, QXmlStreamReader
& xml
)
1124 Q_ASSERT(xml
.isStartElement() && xml
.name() == "precipitation");
1126 while (!xml
.atEnd()) {
1129 if (xml
.isEndElement() && xml
.name() == "precipitation") {
1133 if (xml
.isStartElement()) {
1134 //kDebug() << "parsePrecipitationForecast() ====> TAG: " << xml.name().toString();
1135 if (xml
.name() == "textSummary") {
1136 forecast
->precipForecast
= xml
.readElementText();
1137 } else if (xml
.name() == "precipType") {
1138 forecast
->precipType
= xml
.readElementText();
1139 } else if (xml
.name() == "accumulation") {
1140 parsePrecipTotals(forecast
, xml
);
1146 void EnvCanadaIon::parsePrecipTotals(WeatherData::ForecastInfo
*forecast
, QXmlStreamReader
& xml
)
1148 Q_ASSERT(xml
.isStartElement() && xml
.name() == "accumulation");
1150 while (!xml
.atEnd()) {
1153 if (xml
.isEndElement() && xml
.name() == "accumulation") {
1157 if (xml
.name() == "name") {
1158 xml
.readElementText();
1159 } else if (xml
.name() == "amount") {
1160 forecast
->precipTotalExpected
= xml
.readElementText();
1165 void EnvCanadaIon::parseWindForecast(WeatherData::ForecastInfo
*forecast
, QXmlStreamReader
& xml
)
1167 Q_ASSERT(xml
.isStartElement() && xml
.name() == "winds");
1169 while (!xml
.atEnd()) {
1172 if (xml
.isEndElement() && xml
.name() == "winds") {
1176 if (xml
.isStartElement()) {
1177 if (xml
.name() == "textSummary") {
1178 forecast
->windForecast
= xml
.readElementText();
1180 if (xml
.name() != "winds") {
1181 parseUnknownElement(xml
);
1188 void EnvCanadaIon::parseYesterdayWeather(WeatherData
& data
, QXmlStreamReader
& xml
)
1190 Q_ASSERT(xml
.isStartElement() && xml
.name() == "yesterdayConditions");
1192 while (!xml
.atEnd()) {
1195 if (xml
.isEndElement()) {
1199 if (xml
.isStartElement()) {
1200 if (xml
.name() == "temperature" && xml
.attributes().value("class") == "high") {
1201 data
.prevHigh
= xml
.readElementText();
1202 } else if (xml
.name() == "temperature" && xml
.attributes().value("class") == "low") {
1203 data
.prevLow
= xml
.readElementText();
1204 } else if (xml
.name() == "precip") {
1205 data
.prevPrecipType
= xml
.attributes().value("units").toString();
1206 if (data
.prevPrecipType
.isEmpty()) {
1207 data
.prevPrecipType
= QString::number(WeatherUtils::NoUnit
);
1209 data
.prevPrecipTotal
= xml
.readElementText();
1215 void EnvCanadaIon::parseWeatherRecords(WeatherData
& data
, QXmlStreamReader
& xml
)
1217 Q_ASSERT(xml
.isStartElement() && xml
.name() == "almanac");
1219 while (!xml
.atEnd()) {
1222 if (xml
.isEndElement() && xml
.name() == "almanac") {
1226 if (xml
.isStartElement()) {
1227 if (xml
.name() == "temperature" && xml
.attributes().value("class") == "extremeMax") {
1228 data
.recordHigh
= xml
.readElementText().toFloat();
1229 } else if (xml
.name() == "temperature" && xml
.attributes().value("class") == "extremeMin") {
1230 data
.recordLow
= xml
.readElementText().toFloat();
1231 } else if (xml
.name() == "precipitation" && xml
.attributes().value("class") == "extremeRainfall") {
1232 data
.recordRain
= xml
.readElementText().toFloat();
1233 } else if (xml
.name() == "precipitation" && xml
.attributes().value("class") == "extremeSnowfall") {
1234 data
.recordSnow
= xml
.readElementText().toFloat();
1240 void EnvCanadaIon::parseAstronomicals(WeatherData
& data
, QXmlStreamReader
& xml
)
1242 Q_ASSERT(xml
.isStartElement() && xml
.name() == "riseSet");
1244 while (!xml
.atEnd()) {
1247 if (xml
.isEndElement() && xml
.name() == "riseSet") {
1251 if (xml
.isStartElement()) {
1252 if (xml
.name() == "disclaimer") {
1253 xml
.readElementText();
1254 } else if (xml
.name() == "dateTime") {
1255 parseDateTime(data
, xml
);
1261 // handle when no XML tag is found
1262 void EnvCanadaIon::parseUnknownElement(QXmlStreamReader
& xml
)
1265 while (!xml
.atEnd()) {
1268 if (xml
.isEndElement()) {
1272 if (xml
.isStartElement()) {
1273 parseUnknownElement(xml
);
1278 void EnvCanadaIon::updateWeather(const QString
& source
)
1280 QMap
<QString
, QString
> dataFields
;
1281 QStringList fieldList
;
1282 QVector
<QString
> forecastList
;
1285 setData(source
, "Country", country(source
));
1286 setData(source
, "Place", QString("%1, %2").arg(city(source
)).arg(territory(source
)));
1287 setData(source
, "Region", region(source
));
1288 setData(source
, "Station", station(source
));
1290 // Real weather - Current conditions
1291 setData(source
, "Observation Period", observationTime(source
));
1292 setData(source
, "Current Conditions", condition(source
));
1294 // Tell applet which icon to use for conditions and provide mapping for condition type to the icons to display
1295 QMap
<QString
, ConditionIcons
> conditionList
;
1296 conditionList
= conditionIcons();
1298 if ((periodHour(source
) >= 0 && periodHour(source
) < 6) || (periodHour(source
) >= 18)) {
1299 conditionList
["decreasing cloud"] = FewCloudsNight
;
1300 conditionList
["mostly cloudy"] = PartlyCloudyNight
;
1301 conditionList
["partly cloudy"] = PartlyCloudyNight
;
1302 conditionList
["fair"] = FewCloudsNight
;
1304 conditionList
["decreasing cloud"] = FewCloudsDay
;
1305 conditionList
["mostly cloudy"] = PartlyCloudyDay
;
1306 conditionList
["partly cloudy"] = PartlyCloudyDay
;
1307 conditionList
["fair"] = FewCloudsDay
;
1310 setData(source
, "Condition Icon", getWeatherIcon(conditionList
, condition(source
)));
1312 dataFields
= temperature(source
);
1313 setData(source
, "Temperature", dataFields
["temperature"]);
1315 // Do we have a comfort temperature? if so display it
1316 if (dataFields
["comfortTemperature"] != "N/A" && !dataFields
["comfortTemperature"].isEmpty()) {
1317 if (dataFields
["comfortTemperature"].toFloat() <= 0) {
1318 setData(source
, "Windchill", QString("%1").arg(dataFields
["comfortTemperature"]));
1319 setData(source
, "Humidex", "N/A");
1321 setData(source
, "Humidex", QString("%1").arg(dataFields
["comfortTemperature"]));
1322 setData(source
, "Windchill", "N/A");
1325 setData(source
, "Windchill", "N/A");
1326 setData(source
, "Humidex", "N/A");
1329 setData(source
, "Temperature Unit", dataFields
["temperatureUnit"]);
1331 setData(source
, "Dewpoint", dewpoint(source
));
1332 if (dewpoint(source
) != "N/A") {
1333 setData(source
, "Dewpoint Unit", dataFields
["temperatureUnit"]);
1336 dataFields
= pressure(source
);
1337 setData(source
, "Pressure", dataFields
["pressure"]);
1339 if (dataFields
["pressure"] != "N/A") {
1340 setData(source
, "Pressure Tendency", dataFields
["pressureTendency"]);
1341 setData(source
, "Pressure Unit", dataFields
["pressureUnit"]);
1344 dataFields
= visibility(source
);
1345 setData(source
, "Visibility", dataFields
["visibility"]);
1346 if (dataFields
["visibility"] != "N/A") {
1347 setData(source
, "Visibility Unit", dataFields
["visibilityUnit"]);
1350 setData(source
, "Humidity", humidity(source
));
1352 dataFields
= wind(source
);
1353 setData(source
, "Wind Speed", dataFields
["windSpeed"]);
1354 if (dataFields
["windSpeed"] != "N/A") {
1355 setData(source
, "Wind Speed Unit", dataFields
["windUnit"]);
1357 setData(source
, "Wind Gust", dataFields
["windGust"]);
1358 setData(source
, "Wind Direction", dataFields
["windDirection"]);
1359 setData(source
, "Wind Degrees", dataFields
["windDegrees"]);
1360 setData(source
, "Wind Gust Unit", dataFields
["windGustUnit"]);
1362 dataFields
= regionalTemperatures(source
);
1363 setData(source
, "Normal High", dataFields
["normalHigh"]);
1364 setData(source
, "Normal Low", dataFields
["normalLow"]);
1365 if (dataFields
["normalHigh"] != "N/A" && dataFields
["normalLow"] != "N/A") {
1366 setData(source
, "Regional Temperature Unit", dataFields
["regionalTempUnit"]);
1369 // Check if UV index is available for the location
1370 dataFields
= uvIndex(source
);
1371 setData(source
, "UV Index", dataFields
["uvIndex"]);
1372 if (dataFields
["uvIndex"] != "N/A") {
1373 setData(source
, "UV Rating", dataFields
["uvRating"]);
1376 dataFields
= watches(source
);
1378 // Set number of forecasts per day/night supported
1379 setData(source
, QString("Total Watches Issued"), d
->m_weatherData
[source
].watches
.size());
1381 // Check if we have warnings or watches
1382 for (int i
= 0; i
< d
->m_weatherData
[source
].watches
.size(); i
++) {
1383 fieldList
= dataFields
[QString("watch %1").arg(i
)].split('|');
1384 setData(source
, QString("Watch Priority %1").arg(i
), fieldList
[0]);
1385 setData(source
, QString("Watch Description %1").arg(i
), fieldList
[1]);
1386 setData(source
, QString("Watch Info %1").arg(i
), fieldList
[2]);
1387 setData(source
, QString("Watch Timestamp %1").arg(i
), fieldList
[3]);
1390 dataFields
= warnings(source
);
1392 setData(source
, QString("Total Warnings Issued"), d
->m_weatherData
[source
].warnings
.size());
1394 for (int k
= 0; k
< d
->m_weatherData
[source
].warnings
.size(); k
++) {
1395 fieldList
= dataFields
[QString("warning %1").arg(k
)].split('|');
1396 setData(source
, QString("Warning Priority %1").arg(k
), fieldList
[0]);
1397 setData(source
, QString("Warning Description %1").arg(k
), fieldList
[1]);
1398 setData(source
, QString("Warning Info %1").arg(k
), fieldList
[2]);
1399 setData(source
, QString("Warning Timestamp %1").arg(k
), fieldList
[3]);
1402 forecastList
= forecasts(source
);
1404 // Set number of forecasts per day/night supported
1405 setData(source
, QString("Total Weather Days"), d
->m_weatherData
[source
].forecasts
.size());
1407 foreach(const QString
&forecastItem
, forecastList
) {
1408 fieldList
= forecastItem
.split('|');
1410 setData(source
, QString("Short Forecast Day %1").arg(i
), QString("%1|%2|%3|%4|%5|%6") \
1411 .arg(fieldList
[0]).arg(fieldList
[1]).arg(fieldList
[2]).arg(fieldList
[3]).arg(fieldList
[4]).arg(fieldList
[5]));
1414 setData(source, QString("Long Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6|%7|%8") \
1415 .arg(fieldList[0]).arg(fieldList[2]).arg(fieldList[3]).arg(fieldList[4]).arg(fieldList[6]) \
1416 .arg(fieldList[7]).arg(fieldList[8]).arg(fieldList[9]));
1421 dataFields
= yesterdayWeather(source
);
1422 setData(source
, "Yesterday High", dataFields
["prevHigh"]);
1423 setData(source
, "Yesterday Low", dataFields
["prevLow"]);
1425 if (dataFields
["prevHigh"] != "N/A" && dataFields
["prevLow"] != "N/A") {
1426 setData(source
, "Yesterday Temperature Unit", dataFields
["yesterdayTempUnit"]);
1429 setData(source
, "Yesterday Precip Total", dataFields
["prevPrecip"]);
1430 setData(source
, "Yesterday Precip Unit", dataFields
["prevPrecipUnit"]);
1432 dataFields
= sunriseSet(source
);
1433 setData(source
, "Sunrise At", dataFields
["sunrise"]);
1434 setData(source
, "Sunset At", dataFields
["sunset"]);
1436 dataFields
= moonriseSet(source
);
1437 setData(source
, "Moonrise At", dataFields
["moonrise"]);
1438 setData(source
, "Moonset At", dataFields
["moonset"]);
1440 dataFields
= weatherRecords(source
);
1441 setData(source
, "Record High Temperature", dataFields
["recordHigh"]);
1442 setData(source
, "Record Low Temperature", dataFields
["recordLow"]);
1443 if (dataFields
["recordHigh"] != "N/A" && dataFields
["recordLow"] != "N/A") {
1444 setData(source
, "Record Temperature Unit", dataFields
["recordTempUnit"]);
1447 setData(source
, "Record Rainfall", dataFields
["recordRain"]);
1448 setData(source
, "Record Rainfall Unit", dataFields
["recordRainUnit"]);
1449 setData(source
, "Record Snowfall", dataFields
["recordSnow"]);
1450 setData(source
, "Record Snowfall Unit", dataFields
["recordSnowUnit"]);
1452 setData(source
, "Credit", "Meteorological data is provided by Environment Canada");
1455 QString
EnvCanadaIon::country(const QString
& source
)
1457 return d
->m_weatherData
[source
].countryName
;
1459 QString
EnvCanadaIon::territory(const QString
& source
)
1461 return d
->m_weatherData
[source
].shortTerritoryName
;
1463 QString
EnvCanadaIon::city(const QString
& source
)
1465 return d
->m_weatherData
[source
].cityName
;
1467 QString
EnvCanadaIon::region(const QString
& source
)
1469 return d
->m_weatherData
[source
].regionName
;
1471 QString
EnvCanadaIon::station(const QString
& source
)
1473 if (!d
->m_weatherData
[source
].stationID
.isEmpty()) {
1474 return d
->m_weatherData
[source
].stationID
.toUpper();
1477 return QString("N/A");
1480 QString
EnvCanadaIon::observationTime(const QString
& source
)
1482 return d
->m_weatherData
[source
].obsTimestamp
;
1486 bool EnvCanadaIon::night(const QString& source)
1488 if (d->m_weatherData[source].iconPeriodAP == "pm") {
1495 int EnvCanadaIon::periodHour(const QString
& source
)
1497 return d
->m_weatherData
[source
].iconPeriodHour
;
1500 QString
EnvCanadaIon::condition(const QString
& source
)
1502 if (d
->m_weatherData
[source
].condition
.isEmpty()) {
1503 d
->m_weatherData
[source
].condition
= "N/A";
1505 return d
->m_weatherData
[source
].condition
;
1508 QString
EnvCanadaIon::dewpoint(const QString
& source
)
1510 if (!d
->m_weatherData
[source
].dewpoint
.isEmpty()) {
1511 return QString::number(d
->m_weatherData
[source
].dewpoint
.toFloat(), 'f', 1);
1513 return QString("N/A");
1516 QString
EnvCanadaIon::humidity(const QString
& source
)
1518 if (!d
->m_weatherData
[source
].humidity
.isEmpty()) {
1519 return QString("%1%").arg(d
->m_weatherData
[source
].humidity
);
1521 return QString("N/A");
1524 QMap
<QString
, QString
> EnvCanadaIon::visibility(const QString
& source
)
1526 QMap
<QString
, QString
> visibilityInfo
;
1528 if (!d
->m_weatherData
[source
].visibility
== 0) {
1529 visibilityInfo
.insert("visibility", QString::number(d
->m_weatherData
[source
].visibility
, 'f', 1));
1530 visibilityInfo
.insert("visibilityUnit", QString::number(WeatherUtils::Kilometers
));
1532 visibilityInfo
.insert("visibility", "N/A");
1534 return visibilityInfo
;
1537 QMap
<QString
, QString
> EnvCanadaIon::temperature(const QString
& source
)
1539 QMap
<QString
, QString
> temperatureInfo
;
1540 if (!d
->m_weatherData
[source
].temperature
.isEmpty()) {
1541 temperatureInfo
.insert("temperature", QString::number(d
->m_weatherData
[source
].temperature
.toFloat(), 'f', 1));
1544 if (d
->m_weatherData
[source
].temperature
== "N/A") {
1545 temperatureInfo
.insert("temperature", "N/A");
1548 temperatureInfo
.insert("temperatureUnit", QString::number(WeatherUtils::Celsius
));
1549 temperatureInfo
.insert("comfortTemperature", "N/A");
1551 if (d
->m_weatherData
[source
].comforttemp
!= "N/A") {
1552 temperatureInfo
.insert("comfortTemperature", d
->m_weatherData
[source
].comforttemp
);
1554 return temperatureInfo
;
1557 QMap
<QString
, QString
> EnvCanadaIon::watches(const QString
& source
)
1559 QMap
<QString
, QString
> watchData
;
1561 for (int i
= 0; i
< d
->m_weatherData
[source
].watches
.size(); ++i
) {
1562 watchType
= QString("watch %1").arg(i
);
1563 watchData
[watchType
] = QString("%1|%2|%3|%4").arg(d
->m_weatherData
[source
].watches
[i
]->priority
) \
1564 .arg(d
->m_weatherData
[source
].watches
[i
]->description
) \
1565 .arg(d
->m_weatherData
[source
].watches
[i
]->url
) \
1566 .arg(d
->m_weatherData
[source
].watches
[i
]->timestamp
);
1571 QMap
<QString
, QString
> EnvCanadaIon::warnings(const QString
& source
)
1573 QMap
<QString
, QString
> warningData
;
1575 for (int i
= 0; i
< d
->m_weatherData
[source
].warnings
.size(); ++i
) {
1576 warnType
= QString("warning %1").arg(i
);
1577 warningData
[warnType
] = QString("%1|%2|%3|%4").arg(d
->m_weatherData
[source
].warnings
[i
]->priority
) \
1578 .arg(d
->m_weatherData
[source
].warnings
[i
]->description
) \
1579 .arg(d
->m_weatherData
[source
].warnings
[i
]->url
) \
1580 .arg(d
->m_weatherData
[source
].warnings
[i
]->timestamp
);
1585 QVector
<QString
> EnvCanadaIon::forecasts(const QString
& source
)
1587 QVector
<QString
> forecastData
;
1589 // Do some checks for empty data
1590 for (int i
= 0; i
< d
->m_weatherData
[source
].forecasts
.size(); ++i
) {
1591 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.isEmpty()) {
1592 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
= "N/A";
1594 if (d
->m_weatherData
[source
].forecasts
[i
]->shortForecast
.isEmpty()) {
1595 d
->m_weatherData
[source
].forecasts
[i
]->shortForecast
= "N/A";
1597 if (d
->m_weatherData
[source
].forecasts
[i
]->iconName
.isEmpty()) {
1598 d
->m_weatherData
[source
].forecasts
[i
]->iconName
= "N/A";
1600 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastSummary
.isEmpty()) {
1601 d
->m_weatherData
[source
].forecasts
[i
]->forecastSummary
= "N/A";
1603 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastTempHigh
.isEmpty()) {
1604 d
->m_weatherData
[source
].forecasts
[i
]->forecastTempHigh
= "N/A";
1606 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastTempLow
.isEmpty()) {
1607 d
->m_weatherData
[source
].forecasts
[i
]->forecastTempLow
= "N/A";
1609 if (d
->m_weatherData
[source
].forecasts
[i
]->popPrecent
.isEmpty()) {
1610 d
->m_weatherData
[source
].forecasts
[i
]->popPrecent
= "N/A";
1612 if (d
->m_weatherData
[source
].forecasts
[i
]->windForecast
.isEmpty()) {
1613 d
->m_weatherData
[source
].forecasts
[i
]->windForecast
= "N/A";
1615 if (d
->m_weatherData
[source
].forecasts
[i
]->precipForecast
.isEmpty()) {
1616 d
->m_weatherData
[source
].forecasts
[i
]->precipForecast
= "N/A";
1618 if (d
->m_weatherData
[source
].forecasts
[i
]->precipType
.isEmpty()) {
1619 d
->m_weatherData
[source
].forecasts
[i
]->precipType
= "N/A";
1621 if (d
->m_weatherData
[source
].forecasts
[i
]->precipTotalExpected
.isEmpty()) {
1622 d
->m_weatherData
[source
].forecasts
[i
]->precipTotalExpected
= "N/A";
1626 for (int i
= 0; i
< d
->m_weatherData
[source
].forecasts
.size(); ++i
) {
1627 // We need to shortform the day/night strings.
1628 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("Tonight")) {
1629 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("Tonight", "nite");
1632 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("night")) {
1633 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("night", "nt");
1636 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("Saturday")) {
1637 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("Saturday", "Sat");
1640 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("Sunday")) {
1641 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("Sunday", "Sun");
1644 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("Monday")) {
1645 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("Monday", "Mon");
1648 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("Tuesday")) {
1649 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("Tuesday", "Tue");
1652 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("Wednesday")) {
1653 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("Wednesday", "Wed");
1656 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("Thursday")) {
1657 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("Thursday", "Thu");
1659 if (d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.contains("Friday")) {
1660 d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
.replace("Friday", "Fri");
1663 forecastData
.append(QString("%1|%2|%3|%4|%5|%6") \
1664 .arg(d
->m_weatherData
[source
].forecasts
[i
]->forecastPeriod
) \
1665 .arg(d
->m_weatherData
[source
].forecasts
[i
]->iconName
) \
1666 .arg(d
->m_weatherData
[source
].forecasts
[i
]->shortForecast
) \
1667 .arg(d
->m_weatherData
[source
].forecasts
[i
]->forecastTempHigh
) \
1668 .arg(d
->m_weatherData
[source
].forecasts
[i
]->forecastTempLow
) \
1669 .arg(d
->m_weatherData
[source
].forecasts
[i
]->popPrecent
));
1671 return forecastData
;
1674 QMap
<QString
, QString
> EnvCanadaIon::pressure(const QString
& source
)
1676 QMap
<QString
, QString
> pressureInfo
;
1678 if (d
->m_weatherData
[source
].pressure
== 0) {
1679 pressureInfo
.insert("pressure", "N/A");
1680 return pressureInfo
;
1682 pressureInfo
.insert("pressure", QString::number(d
->m_weatherData
[source
].pressure
, 'f', 1));
1683 pressureInfo
.insert("pressureUnit", QString::number(WeatherUtils::Kilopascals
));
1684 pressureInfo
.insert("pressureTendency", d
->m_weatherData
[source
].pressureTendency
);
1686 return pressureInfo
;
1689 QMap
<QString
, QString
> EnvCanadaIon::wind(const QString
& source
)
1691 QMap
<QString
, QString
> windInfo
;
1693 // May not have any winds
1694 if (d
->m_weatherData
[source
].windSpeed
.isEmpty()) {
1695 windInfo
.insert("windSpeed", "N/A");
1696 windInfo
.insert("windUnit", QString::number(WeatherUtils::NoUnit
));
1697 } else if (d
->m_weatherData
[source
].windSpeed
.toInt() == 0) {
1698 windInfo
.insert("windSpeed", "Calm");
1699 windInfo
.insert("windUnit", QString::number(WeatherUtils::NoUnit
));
1701 windInfo
.insert("windSpeed", QString::number(d
->m_weatherData
[source
].windSpeed
.toInt()));
1702 windInfo
.insert("windUnit", QString::number(WeatherUtils::KilometersAnHour
));
1705 // May not always have gusty winds
1706 if (d
->m_weatherData
[source
].windGust
.isEmpty()) {
1707 windInfo
.insert("windGust", "N/A");
1708 windInfo
.insert("windGustUnit", QString::number(WeatherUtils::NoUnit
));
1710 windInfo
.insert("windGust", QString::number(d
->m_weatherData
[source
].windGust
.toInt()));
1711 windInfo
.insert("windGustUnit", QString::number(WeatherUtils::KilometersAnHour
));
1714 if (d
->m_weatherData
[source
].windDirection
.isEmpty() && d
->m_weatherData
[source
].windSpeed
.isEmpty()) {
1715 windInfo
.insert("windDirection", "N/A");
1716 windInfo
.insert("windDegrees", "N/A");
1717 } else if (d
->m_weatherData
[source
].windSpeed
.toInt() == 0) {
1718 windInfo
.insert("windDirection", "VR");
1720 windInfo
.insert("windDirection", d
->m_weatherData
[source
].windDirection
);
1721 windInfo
.insert("windDegrees", d
->m_weatherData
[source
].windDegrees
);
1726 QMap
<QString
, QString
> EnvCanadaIon::uvIndex(const QString
& source
)
1728 QMap
<QString
, QString
> uvInfo
;
1730 if (d
->m_weatherData
[source
].UVRating
.isEmpty()) {
1731 uvInfo
.insert("uvRating", "N/A");
1733 uvInfo
.insert("uvRating", d
->m_weatherData
[source
].UVRating
);
1736 if (d
->m_weatherData
[source
].UVIndex
.isEmpty()) {
1737 uvInfo
.insert("uvIndex", "N/A");
1739 uvInfo
.insert("uvIndex", d
->m_weatherData
[source
].UVIndex
);
1745 QMap
<QString
, QString
> EnvCanadaIon::regionalTemperatures(const QString
& source
)
1747 QMap
<QString
, QString
> regionalTempInfo
;
1749 if (d
->m_weatherData
[source
].normalHigh
.isEmpty()) {
1750 regionalTempInfo
.insert("normalHigh", "N/A");
1752 regionalTempInfo
.insert("normalHigh", d
->m_weatherData
[source
].normalHigh
);
1755 if (d
->m_weatherData
[source
].normalLow
.isEmpty()) {
1756 regionalTempInfo
.insert("normalLow", "N/A");
1758 regionalTempInfo
.insert("normalLow", d
->m_weatherData
[source
].normalLow
);
1761 regionalTempInfo
.insert("regionalTempUnit", QString::number(WeatherUtils::Celsius
));
1762 return regionalTempInfo
;
1765 QMap
<QString
, QString
> EnvCanadaIon::yesterdayWeather(const QString
& source
)
1767 QMap
<QString
, QString
> yesterdayInfo
;
1769 if (d
->m_weatherData
[source
].prevHigh
.isEmpty()) {
1770 yesterdayInfo
.insert("prevHigh", "N/A");
1772 yesterdayInfo
.insert("prevHigh", d
->m_weatherData
[source
].prevHigh
);
1775 if (d
->m_weatherData
[source
].prevLow
.isEmpty()) {
1776 yesterdayInfo
.insert("prevLow", "N/A");
1778 yesterdayInfo
.insert("prevLow", d
->m_weatherData
[source
].prevLow
);
1781 yesterdayInfo
.insert("yesterdayTempUnit", QString::number(WeatherUtils::Celsius
));
1783 if (d
->m_weatherData
[source
].prevPrecipTotal
== "Trace") {
1784 yesterdayInfo
.insert("prevPrecip", "Trace");
1785 return yesterdayInfo
;
1788 if (d
->m_weatherData
[source
].prevPrecipTotal
.isEmpty()) {
1789 yesterdayInfo
.insert("prevPrecip", "N/A");
1791 yesterdayInfo
.insert("prevPrecipTotal", d
->m_weatherData
[source
].prevPrecipTotal
);
1792 if (d
->m_weatherData
[source
].prevPrecipType
== "mm") {
1793 yesterdayInfo
.insert("prevPrecipUnit", QString::number(WeatherUtils::Millimeters
));
1794 } else if (d
->m_weatherData
[source
].prevPrecipType
== "cm") {
1795 yesterdayInfo
.insert("prevPrecipUnit", QString::number(WeatherUtils::Centimeters
));
1797 yesterdayInfo
.insert("prevPrecipUnit", QString::number(WeatherUtils::NoUnit
));
1801 return yesterdayInfo
;
1804 QMap
<QString
, QString
> EnvCanadaIon::sunriseSet(const QString
& source
)
1806 QMap
<QString
, QString
> sunInfo
;
1808 if (d
->m_weatherData
[source
].sunriseTimestamp
.isEmpty()) {
1809 sunInfo
.insert("sunrise", "N/A");
1811 sunInfo
.insert("sunrise", d
->m_weatherData
[source
].sunriseTimestamp
);
1814 if (d
->m_weatherData
[source
].sunsetTimestamp
.isEmpty()) {
1815 sunInfo
.insert("sunset", "N/A");
1817 sunInfo
.insert("sunset", d
->m_weatherData
[source
].sunsetTimestamp
);
1823 QMap
<QString
, QString
> EnvCanadaIon::moonriseSet(const QString
& source
)
1825 QMap
<QString
, QString
> moonInfo
;
1827 if (d
->m_weatherData
[source
].moonriseTimestamp
.isEmpty()) {
1828 moonInfo
.insert("moonrise", "N/A");
1830 moonInfo
.insert("moonrise", d
->m_weatherData
[source
].moonriseTimestamp
);
1833 if (d
->m_weatherData
[source
].moonsetTimestamp
.isEmpty()) {
1834 moonInfo
.insert("moonset", "N/A");
1836 moonInfo
.insert("moonset", d
->m_weatherData
[source
].moonsetTimestamp
);
1842 QMap
<QString
, QString
> EnvCanadaIon::weatherRecords(const QString
& source
)
1844 QMap
<QString
, QString
> recordInfo
;
1846 if (d
->m_weatherData
[source
].recordHigh
== 0) {
1847 recordInfo
.insert("recordHigh", "N/A");
1849 recordInfo
.insert("recordHigh", QString("%1").arg(d
->m_weatherData
[source
].recordHigh
));
1852 if (d
->m_weatherData
[source
].recordLow
== 0) {
1853 recordInfo
.insert("recordLow", "N/A");
1855 recordInfo
.insert("recordLow", QString("%1").arg(d
->m_weatherData
[source
].recordLow
));
1858 recordInfo
.insert("recordTempUnit", QString::number(WeatherUtils::Celsius
));
1860 if (d
->m_weatherData
[source
].recordRain
== 0) {
1861 recordInfo
.insert("recordRain", "N/A");
1863 recordInfo
.insert("recordRain", QString("%1").arg(d
->m_weatherData
[source
].recordRain
));
1864 recordInfo
.insert("recordRainUnit", QString::number(WeatherUtils::Millimeters
));
1867 if (d
->m_weatherData
[source
].recordSnow
== 0) {
1868 recordInfo
.insert("recordSnow", "N/A");
1870 recordInfo
.insert("recordSnow", QString("%1").arg(d
->m_weatherData
[source
].recordSnow
));
1871 recordInfo
.insert("recordSnowUnit", QString::number(WeatherUtils::Centimeters
));
1877 #include "ion_envcan.moc"