00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ion_envcan.h"
00023
00024 class EnvCanadaIon::Private : public QObject
00025 {
00026 public:
00027 Private() { m_url = 0; }
00028 ~Private() { delete m_url; }
00029
00030 private:
00031 struct XMLMapInfo {
00032 QString cityName;
00033 QString territoryName;
00034 QString cityCode;
00035 QString sourceOptions;
00036 };
00037
00038 public:
00039
00040 QHash<QString, EnvCanadaIon::Private::XMLMapInfo> m_place;
00041 QHash<QString, QString> m_locations;
00042 QString m_code;
00043 QString m_territory;
00044 QString m_cityName;
00045
00046
00047 QHash<QString, WeatherData> m_weatherData;
00048
00049
00050 QMap<KJob *, QXmlStreamReader*> m_jobXml;
00051 QMap<KJob *, QString> m_jobList;
00052 QXmlStreamReader m_xmlSetup;
00053 KUrl *m_url;
00054 KIO::TransferJob *m_job;
00055
00056 int m_timezoneType;
00057 int m_measureType;
00058 };
00059
00060
00061
00062 EnvCanadaIon::EnvCanadaIon(QObject *parent, const QVariantList &args)
00063 : IonInterface(parent, args), d(new Private())
00064 {
00065 }
00066
00067 EnvCanadaIon::~EnvCanadaIon()
00068 {
00069
00070 foreach(const WeatherData &item, d->m_weatherData) {
00071 foreach(WeatherData::WarningInfo *warning, item.warnings) {
00072 if (warning) {
00073 delete warning;
00074 }
00075 }
00076 foreach(WeatherData::ForecastInfo *forecast, item.forecasts) {
00077 if (forecast) {
00078 delete forecast;
00079 }
00080 }
00081 }
00082
00083
00084 delete d;
00085 }
00086
00087
00088 void EnvCanadaIon::init()
00089 {
00090
00091 getXMLSetup();
00092 }
00093
00094 QStringList EnvCanadaIon::validate(const QString& source) const
00095 {
00096 QStringList placeList;
00097 QHash<QString, QString>::const_iterator it = d->m_locations.constBegin();
00098 while (it != d->m_locations.constEnd()) {
00099 if (it.value().toLower().contains(source.toLower())) {
00100 placeList.append(QString("place|%1").arg(it.value().split("|")[1]));
00101 }
00102 ++it;
00103 }
00104
00105
00106 if (placeList.isEmpty()) {
00107 return QStringList();
00108 }
00109 placeList.sort();
00110 return placeList;
00111 }
00112
00113
00114 bool EnvCanadaIon::updateIonSource(const QString& source)
00115 {
00116 kDebug() << "updateIonSource() SOURCE: " << source;
00117
00118
00119
00120
00121 QStringList sourceAction = source.split('|');
00122 if (sourceAction[1] == QString("validate")) {
00123 kDebug() << "Initiate Validating of place: " << sourceAction[2];
00124
00125 QStringList result = validate(QString("%1|%2").arg(sourceAction[0]).arg(sourceAction[2]));
00126
00127 if (result.size() == 1) {
00128 setData(source, "validate", QString("envcan|valid|single|%1").arg(result.join("|")));
00129 return true;
00130 } else if (result.size() > 1) {
00131 setData(source, "validate", QString("envcan|valid|multiple|%1").arg(result.join("|")));
00132 return true;
00133 } else if (result.size() == 0) {
00134 setData(source, "validate", QString("envcan|invalid|single|%1").arg(sourceAction[2]));
00135 return true;
00136 }
00137
00138 } else if (sourceAction[1] == QString("weather")) {
00139 getXMLData(source);
00140 return true;
00141 }
00142 return false;
00143 }
00144
00145
00146 void EnvCanadaIon::getXMLSetup()
00147 {
00148
00149 d->m_url = new KUrl("http://dd.weatheroffice.ec.gc.ca/EC_sites/xml/siteList.xml");
00150
00151 KIO::TransferJob *job = KIO::get(d->m_url->url(), KIO::NoReload, KIO::HideProgressInfo);
00152
00153 if (job) {
00154 connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00155 SLOT(setup_slotDataArrived(KIO::Job *, const QByteArray &)));
00156 connect(job, SIGNAL(result(KJob *)), this, SLOT(setup_slotJobFinished(KJob *)));
00157 }
00158 }
00159
00160
00161 void EnvCanadaIon::getXMLData(const QString& source)
00162 {
00163 KUrl url;
00164
00165
00166 QString dataKey = source;
00167 dataKey.replace("|weather", "");
00168 kDebug() << "DATA KEY: " << dataKey;
00169
00170 url = "http://dd.weatheroffice.ec.gc.ca/EC_sites/xml/" + d->m_place[dataKey].territoryName + "/" + d->m_place[dataKey].cityCode + "_e.xml";
00171
00172 kDebug() << "URL Location: " << url.url();
00173
00174 d->m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo);
00175 d->m_jobXml.insert(d->m_job, new QXmlStreamReader);
00176 d->m_jobList.insert(d->m_job, source);
00177
00178 if (d->m_job) {
00179 connect(d->m_job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00180 SLOT(slotDataArrived(KIO::Job *, const QByteArray &)));
00181 connect(d->m_job, SIGNAL(result(KJob *)), this, SLOT(slotJobFinished(KJob *)));
00182 }
00183 }
00184
00185 void EnvCanadaIon::setup_slotDataArrived(KIO::Job *job, const QByteArray &data)
00186 {
00187 Q_UNUSED(job)
00188
00189 if (data.isEmpty()) {
00190 return;
00191 }
00192
00193
00194 d->m_xmlSetup.addData(data);
00195 }
00196
00197 void EnvCanadaIon::slotDataArrived(KIO::Job *job, const QByteArray &data)
00198 {
00199
00200 if (data.isEmpty() || !d->m_jobXml.contains(job)) {
00201 return;
00202 }
00203
00204
00205 d->m_jobXml[job]->addData(data);
00206 }
00207
00208 void EnvCanadaIon::slotJobFinished(KJob *job)
00209 {
00210
00211 kDebug() << "WE FINISHED JOB!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
00212 setData(d->m_jobList[job], Data());
00213 readXMLData(d->m_jobList[job], *d->m_jobXml[job]);
00214 d->m_jobList.remove(job);
00215 delete d->m_jobXml[job];
00216 d->m_jobXml.remove(job);
00217 }
00218
00219 void EnvCanadaIon::setup_slotJobFinished(KJob *job)
00220 {
00221 Q_UNUSED(job)
00222 readXMLSetup();
00223 setInitialized(true);
00224 kDebug() << "We're INITIALIZED... GO!";
00225 }
00226
00227
00228 bool EnvCanadaIon::readXMLSetup()
00229 {
00230 QString tmp;
00231 kDebug() << "readXMLSetup()";
00232 while (!d->m_xmlSetup.atEnd()) {
00233 d->m_xmlSetup.readNext();
00234
00235 if (d->m_xmlSetup.isStartElement()) {
00236
00237
00238 if (d->m_xmlSetup.name() == "site") {
00239 d->m_code = d->m_xmlSetup.attributes().value("code").toString();
00240 }
00241
00242 if (d->m_xmlSetup.name() == "nameEn") {
00243 d->m_cityName = d->m_xmlSetup.readElementText();
00244 }
00245
00246 if (d->m_xmlSetup.name() == "provinceCode") {
00247 d->m_territory = d->m_xmlSetup.readElementText();
00248 tmp = "envcan|" + d->m_cityName + ", " + d->m_territory;
00249
00250
00251 d->m_place[tmp].cityCode = d->m_code;
00252 d->m_place[tmp].territoryName = d->m_territory;
00253 d->m_place[tmp].cityName = d->m_cityName;
00254
00255
00256 kDebug() << "KEY NAME: " << tmp;
00257 d->m_locations[tmp] = tmp;
00258 }
00259 }
00260
00261 }
00262 return !d->m_xmlSetup.error();
00263 }
00264
00265 WeatherData EnvCanadaIon::parseWeatherSite(WeatherData& data, QXmlStreamReader& xml)
00266 {
00267 while (!xml.atEnd()) {
00268 xml.readNext();
00269
00270 if (xml.isStartElement()) {
00271 if (xml.name() == "license") {
00272 xml.readElementText();
00273 } else if (xml.name() == "location") {
00274 parseLocations(data, xml);
00275 } else if (xml.name() == "warnings") {
00276
00277 data.warnings.clear();
00278 parseWarnings(data, xml);
00279 } else if (xml.name() == "currentConditions") {
00280 parseConditions(data, xml);
00281 } else if (xml.name() == "forecastGroup") {
00282
00283 data.forecasts.clear();
00284 parseWeatherForecast(data, xml);
00285 } else if (xml.name() == "yesterdayConditions") {
00286 parseYesterdayWeather(data, xml);
00287 } else if (xml.name() == "riseSet") {
00288 parseAstronomicals(data, xml);
00289 } else if (xml.name() == "almanac") {
00290 parseWeatherRecords(data, xml);
00291 } else {
00292 parseUnknownElement(xml);
00293 }
00294 }
00295 }
00296 return data;
00297 }
00298
00299
00300 bool EnvCanadaIon::readXMLData(const QString& source, QXmlStreamReader& xml)
00301 {
00302 WeatherData data;
00303 data.comforttemp = "N/A";
00304 data.recordHigh = 0.0;
00305 data.recordLow = 0.0;
00306
00307 QString dataKey = source;
00308 dataKey.replace("|weather", "");
00309 data.shortTerritoryName = d->m_place[dataKey].territoryName;
00310 while (!xml.atEnd()) {
00311 xml.readNext();
00312
00313 if (xml.isEndElement()) {
00314 break;
00315 }
00316
00317 if (xml.isStartElement()) {
00318 if (xml.name() == "siteData") {
00319 data = parseWeatherSite(data, xml);
00320 } else {
00321 parseUnknownElement(xml);
00322 }
00323 }
00324 }
00325
00326 d->m_weatherData[source] = data;
00327 updateWeather(source);
00328 return !xml.error();
00329 }
00330
00331 void EnvCanadaIon::parseDateTime(WeatherData& data, QXmlStreamReader& xml, WeatherData::WarningInfo *warning)
00332 {
00333
00334 Q_ASSERT(xml.isStartElement() && xml.name() == "dateTime");
00335
00336
00337 QString dateType = xml.attributes().value("name").toString();
00338 QString dateZone = xml.attributes().value("zone").toString();
00339
00340
00341 while (!xml.atEnd()) {
00342 xml.readNext();
00343
00344 if (xml.isEndElement()) {
00345 break;
00346 }
00347
00348 if (xml.isStartElement()) {
00349 if (dateType == "xmlCreation") {
00350 return;
00351 }
00352 if (xml.name() == "year") {
00353 xml.readElementText();
00354 } else if (xml.name() == "month") {
00355 xml.readElementText();
00356 } else if (xml.name() == "day") {
00357 xml.readElementText();
00358 } else if (xml.name() == "hour")
00359 xml.readElementText();
00360 else if (xml.name() == "minute")
00361 xml.readElementText();
00362 else if (xml.name() == "timeStamp")
00363 xml.readElementText();
00364 else if (xml.name() == "textSummary") {
00365 if (timezone() && dateZone == "UTC") {
00366
00367
00368 if (dateType == "eventIssue") {
00369 if (warning) {
00370 warning->timestamp = xml.readElementText();
00371 }
00372 } else if (dateType == "observation") {
00373 data.obsTimestamp = xml.readElementText();
00374 } else if (dateType == "forecastIssue") {
00375 data.forecastTimestamp = xml.readElementText();
00376 } else if (dateType == "sunrise") {
00377 data.sunriseTimestamp = xml.readElementText();
00378 } else if (dateType == "sunset") {
00379 data.sunsetTimestamp = xml.readElementText();
00380 } else if (dateType == "moonrise") {
00381 data.moonriseTimestamp = xml.readElementText();
00382 } else if (dateType == "moonset") {
00383 data.moonsetTimestamp = xml.readElementText();
00384 }
00385
00386 } else if (dateZone != "UTC") {
00387 if (dateType == "eventIssue") {
00388 if (warning) {
00389 warning->timestamp = xml.readElementText();
00390 }
00391 } else if (dateType == "observation") {
00392 data.obsTimestamp = xml.readElementText();
00393 } else if (dateType == "forecastIssue") {
00394 data.forecastTimestamp = xml.readElementText();
00395 } else if (dateType == "sunrise") {
00396 data.sunriseTimestamp = xml.readElementText();
00397 } else if (dateType == "sunset") {
00398 data.sunsetTimestamp = xml.readElementText();
00399 } else if (dateType == "moonrise") {
00400 data.moonriseTimestamp = xml.readElementText();
00401 } else if (dateType == "moonset") {
00402 data.moonsetTimestamp = xml.readElementText();
00403 }
00404 }
00405 }
00406 }
00407 }
00408 }
00409
00410 void EnvCanadaIon::parseLocations(WeatherData& data, QXmlStreamReader& xml)
00411 {
00412 Q_ASSERT(xml.isStartElement() && xml.name() == "location");
00413
00414 while (!xml.atEnd()) {
00415 xml.readNext();
00416
00417 if (xml.isEndElement()) {
00418 break;
00419 }
00420
00421 if (xml.isStartElement()) {
00422 if (xml.name() == "country") {
00423 data.countryName = xml.readElementText();
00424 } else if (xml.name() == "province" || xml.name() == "territory") {
00425 data.longTerritoryName = xml.readElementText();
00426 } else if (xml.name() == "name") {
00427 data.cityName = xml.readElementText();
00428 } else if (xml.name() == "region") {
00429 data.regionName = xml.readElementText();
00430 } else {
00431 parseUnknownElement(xml);
00432 }
00433 }
00434 }
00435 }
00436
00437 void EnvCanadaIon::parseWindInfo(WeatherData& data, QXmlStreamReader& xml)
00438 {
00439 Q_ASSERT(xml.isStartElement() && xml.name() == "wind");
00440
00441 while (!xml.atEnd()) {
00442 xml.readNext();
00443
00444 if (xml.isEndElement()) {
00445 break;
00446 }
00447
00448 if (xml.isStartElement()) {
00449 if (xml.name() == "speed") {
00450 data.windSpeed = xml.readElementText();
00451 } else if (xml.name() == "gust") {
00452 data.windGust = xml.readElementText();
00453 } else if (xml.name() == "direction") {
00454 data.windDirection = xml.readElementText();
00455 } else {
00456 parseUnknownElement(xml);
00457 }
00458 }
00459 }
00460 }
00461
00462 void EnvCanadaIon::parseConditions(WeatherData& data, QXmlStreamReader& xml)
00463 {
00464
00465 Q_ASSERT(xml.isStartElement() && xml.name() == "currentConditions");
00466 data.temperature = "N/A";
00467 data.dewpoint = "N/A";
00468 data.condition = "N/A";
00469 data.comforttemp = "N/A";
00470 data.stationID = "N/A";
00471 data.pressure = 0.0;
00472 data.pressureTendency = "N/A";
00473 data.visibility = 0;
00474 data.humidity = "N/A";
00475 data.windSpeed = "N/A";
00476 data.windGust = "N/A";
00477
00478 while (!xml.atEnd()) {
00479 xml.readNext();
00480
00481 if (xml.isEndElement() && xml.name() == "currentConditions")
00482 break;
00483
00484 if (xml.isStartElement()) {
00485 if (xml.name() == "station") {
00486 data.stationID = xml.attributes().value("code").toString();
00487 } else if (xml.name() == "dateTime") {
00488 parseDateTime(data, xml);
00489 } else if (xml.name() == "condition") {
00490 data.condition = xml.readElementText();
00491 } else if (xml.name() == "temperature") {
00492 data.temperature = xml.readElementText();;
00493 } else if (xml.name() == "dewpoint") {
00494 data.dewpoint = xml.readElementText();
00495 } else if (xml.name() == "humidex" || xml.name() == "windChill") {
00496 data.comforttemp = xml.readElementText();
00497 } else if (xml.name() == "pressure") {
00498 data.pressureTendency = xml.attributes().value("tendency").toString();
00499 if (data.pressureTendency.isEmpty()) {
00500 data.pressureTendency = "steady";
00501 }
00502 data.pressure = xml.readElementText().toFloat();
00503 } else if (xml.name() == "visibility") {
00504 data.visibility = xml.readElementText().toFloat();
00505 } else if (xml.name() == "relativeHumidity") {
00506 data.humidity = xml.readElementText();
00507 } else if (xml.name() == "wind") {
00508 parseWindInfo(data, xml);
00509 }
00510
00511
00512
00513 }
00514 }
00515 }
00516
00517 void EnvCanadaIon::parseWarnings(WeatherData &data, QXmlStreamReader& xml)
00518 {
00519 WeatherData::WarningInfo* warning = new WeatherData::WarningInfo;
00520
00521 Q_ASSERT(xml.isStartElement() && xml.name() == "warnings");
00522 QString warningURL = xml.attributes().value("url").toString();
00523 while (!xml.atEnd()) {
00524 xml.readNext();
00525
00526 if (xml.isEndElement() && xml.name() == "warnings") {
00527 break;
00528 }
00529
00530 if (xml.isStartElement()) {
00531 if (xml.name() == "dateTime") {
00532 parseDateTime(data, xml, warning);
00533 if (!warning->timestamp.isEmpty() && !warning->url.isEmpty()) {
00534 data.warnings.append(warning);
00535 warning = new WeatherData::WarningInfo;
00536 }
00537 } else if (xml.name() == "event") {
00538
00539 warning->url = warningURL;
00540 warning->type = xml.attributes().value("type").toString();
00541 warning->priority = xml.attributes().value("priority").toString();
00542 warning->description = xml.attributes().value("description").toString();
00543 } else {
00544 if (xml.name() != "dateTime") {
00545 parseUnknownElement(xml);
00546 }
00547 }
00548 }
00549 }
00550 delete warning;
00551 }
00552
00553
00554 void EnvCanadaIon::parseWeatherForecast(WeatherData& data, QXmlStreamReader& xml)
00555 {
00556 WeatherData::ForecastInfo* forecast = new WeatherData::ForecastInfo;
00557 Q_ASSERT(xml.isStartElement() && xml.name() == "forecastGroup");
00558
00559 while (!xml.atEnd()) {
00560 xml.readNext();
00561
00562 if (xml.isEndElement() && xml.name() == "forecastGroup") {
00563 break;
00564 }
00565
00566 if (xml.isStartElement()) {
00567 if (xml.name() == "dateTime") {
00568 parseDateTime(data, xml);
00569 } else if (xml.name() == "regionalNormals") {
00570 parseRegionalNormals(data, xml);
00571 } else if (xml.name() == "forecast") {
00572 parseForecast(data, xml, forecast);
00573 forecast = new WeatherData::ForecastInfo;
00574 } else {
00575 parseUnknownElement(xml);
00576 }
00577 }
00578 }
00579 delete forecast;
00580 }
00581
00582 void EnvCanadaIon::parseRegionalNormals(WeatherData& data, QXmlStreamReader& xml)
00583 {
00584 Q_ASSERT(xml.isStartElement() && xml.name() == "regionalNormals");
00585
00586 while (!xml.atEnd()) {
00587 xml.readNext();
00588
00589 if (xml.isEndElement()) {
00590 break;
00591 }
00592
00593 if (xml.isStartElement()) {
00594 if (xml.name() == "textSummary") {
00595 xml.readElementText();
00596 } else if (xml.name() == "temperature" && xml.attributes().value("class") == "high") {
00597 data.normalHigh = xml.readElementText();
00598 } else if (xml.name() == "temperature" && xml.attributes().value("class") == "low") {
00599 data.normalLow = xml.readElementText();
00600 }
00601 }
00602 }
00603 }
00604
00605 void EnvCanadaIon::parseForecast(WeatherData& data, QXmlStreamReader& xml, WeatherData::ForecastInfo *forecast)
00606 {
00607
00608 Q_ASSERT(xml.isStartElement() && xml.name() == "forecast");
00609
00610 while (!xml.atEnd()) {
00611 xml.readNext();
00612
00613 if (xml.isEndElement() && xml.name() == "forecast") {
00614 data.forecasts.append(forecast);
00615 break;
00616 }
00617
00618 if (xml.isStartElement()) {
00619 if (xml.name() == "period") {
00620 forecast->forecastPeriod = xml.readElementText();
00621 } else if (xml.name() == "textSummary") {
00622 forecast->forecastSummary = xml.readElementText();
00623 } else if (xml.name() == "abbreviatedForecast") {
00624 parseShortForecast(forecast, xml);
00625 } else if (xml.name() == "temperatures") {
00626 parseForecastTemperatures(forecast, xml);
00627 } else if (xml.name() == "winds") {
00628 parseWindForecast(forecast, xml);
00629 } else if (xml.name() == "precipitation") {
00630 parsePrecipitationForecast(forecast, xml);
00631 } else if (xml.name() == "uv") {
00632 data.UVRating = xml.attributes().value("category").toString();
00633 parseUVIndex(data, xml);
00634
00635
00636 } else {
00637 if (xml.name() != "forecast") {
00638 parseUnknownElement(xml);
00639 }
00640 }
00641 }
00642 }
00643 }
00644
00645 void EnvCanadaIon::parseShortForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
00646 {
00647 Q_ASSERT(xml.isStartElement() && xml.name() == "abbreviatedForecast");
00648
00649 while (!xml.atEnd()) {
00650 xml.readNext();
00651
00652 if (xml.isEndElement() && xml.name() == "abbreviatedForecast") {
00653 break;
00654 }
00655
00656 if (xml.isStartElement()) {
00657 if (xml.name() == "pop") {
00658 forecast->popPrecent = xml.readElementText();
00659 }
00660 if (xml.name() == "textSummary") {
00661 forecast->shortForecast = xml.readElementText();
00662 }
00663 }
00664 }
00665 }
00666
00667 void EnvCanadaIon::parseUVIndex(WeatherData& data, QXmlStreamReader& xml)
00668 {
00669 Q_ASSERT(xml.isStartElement() && xml.name() == "uv");
00670
00671 while (!xml.atEnd()) {
00672 xml.readNext();
00673
00674 if (xml.isEndElement() && xml.name() == "uv") {
00675 break;
00676 }
00677
00678 if (xml.isStartElement()) {
00679 if (xml.name() == "index") {
00680 data.UVIndex = xml.readElementText();
00681 }
00682 if (xml.name() == "textSummary") {
00683 xml.readElementText();
00684 }
00685 }
00686 }
00687 }
00688
00689 void EnvCanadaIon::parseForecastTemperatures(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
00690 {
00691 Q_ASSERT(xml.isStartElement() && xml.name() == "temperatures");
00692
00693 while (!xml.atEnd()) {
00694 xml.readNext();
00695
00696 if (xml.isEndElement() && xml.name() == "temperatures") {
00697 break;
00698 }
00699
00700 if (xml.isStartElement()) {
00701 if (xml.name() == "temperature" && xml.attributes().value("class") == "low") {
00702 forecast->forecastTempLow = xml.readElementText();
00703 } else if (xml.name() == "temperature" && xml.attributes().value("class") == "high") {
00704 forecast->forecastTempHigh = xml.readElementText();
00705 } else if (xml.name() == "textSummary") {
00706 xml.readElementText();
00707 }
00708 }
00709 }
00710 }
00711
00712 void EnvCanadaIon::parsePrecipitationForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
00713 {
00714 Q_ASSERT(xml.isStartElement() && xml.name() == "precipitation");
00715
00716 while (!xml.atEnd()) {
00717 xml.readNext();
00718
00719 if (xml.isEndElement() && xml.name() == "precipitation") {
00720 break;
00721 }
00722
00723 if (xml.isStartElement()) {
00724
00725 if (xml.name() == "textSummary") {
00726 forecast->precipForecast = xml.readElementText();
00727 } else if (xml.name() == "precipType") {
00728 forecast->precipType = xml.readElementText();
00729 } else if (xml.name() == "accumulation") {
00730 parsePrecipTotals(forecast, xml);
00731 }
00732 }
00733 }
00734 }
00735
00736 void EnvCanadaIon::parsePrecipTotals(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
00737 {
00738 Q_ASSERT(xml.isStartElement() && xml.name() == "accumulation");
00739
00740 while (!xml.atEnd()) {
00741 xml.readNext();
00742
00743 if (xml.isEndElement() && xml.name() == "accumulation") {
00744 break;
00745 }
00746
00747 if (xml.name() == "name") {
00748 xml.readElementText();
00749 } else if (xml.name() == "amount") {
00750 forecast->precipTotalExpected = xml.readElementText();
00751 }
00752 }
00753 }
00754
00755 void EnvCanadaIon::parseWindForecast(WeatherData::ForecastInfo *forecast, QXmlStreamReader& xml)
00756 {
00757 Q_ASSERT(xml.isStartElement() && xml.name() == "winds");
00758
00759 while (!xml.atEnd()) {
00760 xml.readNext();
00761
00762 if (xml.isEndElement() && xml.name() == "winds") {
00763 break;
00764 }
00765
00766 if (xml.isStartElement()) {
00767 if (xml.name() == "textSummary") {
00768 forecast->windForecast = xml.readElementText();
00769 } else {
00770 if (xml.name() != "winds") {
00771 parseUnknownElement(xml);
00772 }
00773 }
00774 }
00775 }
00776 }
00777
00778 void EnvCanadaIon::parseYesterdayWeather(WeatherData& data, QXmlStreamReader& xml)
00779 {
00780 Q_ASSERT(xml.isStartElement() && xml.name() == "yesterdayConditions");
00781
00782 while (!xml.atEnd()) {
00783 xml.readNext();
00784
00785 if (xml.isEndElement()) {
00786 break;
00787 }
00788
00789 if (xml.isStartElement()) {
00790 if (xml.name() == "temperature" && xml.attributes().value("class") == "high") {
00791 data.prevHigh = xml.readElementText();
00792 } else if (xml.name() == "temperature" && xml.attributes().value("class") == "low") {
00793 data.prevLow = xml.readElementText();
00794 } else if (xml.name() == "precip") {
00795 data.prevPrecipType = xml.attributes().value("units").toString();
00796 if (data.prevPrecipType.isEmpty()) {
00797 data.prevPrecipType = "N/A";
00798 }
00799 data.prevPrecipTotal = xml.readElementText();
00800 }
00801 }
00802 }
00803 }
00804
00805 void EnvCanadaIon::parseWeatherRecords(WeatherData& data, QXmlStreamReader& xml)
00806 {
00807 Q_ASSERT(xml.isStartElement() && xml.name() == "almanac");
00808
00809 while (!xml.atEnd()) {
00810 xml.readNext();
00811
00812 if (xml.isEndElement() && xml.name() == "almanac") {
00813 break;
00814 }
00815
00816 if (xml.isStartElement()) {
00817 if (xml.name() == "temperature" && xml.attributes().value("class") == "extremeMax") {
00818 data.recordHigh = xml.readElementText().toFloat();
00819 } else if (xml.name() == "temperature" && xml.attributes().value("class") == "extremeMin") {
00820 data.recordLow = xml.readElementText().toFloat();
00821 } else if (xml.name() == "precipitation" && xml.attributes().value("class") == "extremeRainfall") {
00822 data.recordRain = xml.readElementText().toFloat();
00823 } else if (xml.name() == "precipitation" && xml.attributes().value("class") == "extremeSnowfall") {
00824 data.recordSnow = xml.readElementText().toFloat();
00825 }
00826 }
00827 }
00828 }
00829
00830 void EnvCanadaIon::parseAstronomicals(WeatherData& data, QXmlStreamReader& xml)
00831 {
00832 Q_ASSERT(xml.isStartElement() && xml.name() == "riseSet");
00833
00834 while (!xml.atEnd()) {
00835 xml.readNext();
00836
00837 if (xml.isEndElement() && xml.name() == "riseSet") {
00838 break;
00839 }
00840
00841 if (xml.isStartElement()) {
00842 if (xml.name() == "disclaimer") {
00843 xml.readElementText();
00844 } else if (xml.name() == "dateTime") {
00845 parseDateTime(data, xml);
00846 }
00847 }
00848 }
00849 }
00850
00851
00852 void EnvCanadaIon::parseUnknownElement(QXmlStreamReader& xml)
00853 {
00854
00855 while (!xml.atEnd()) {
00856 xml.readNext();
00857
00858 if (xml.isEndElement()) {
00859 break;
00860 }
00861
00862 if (xml.isStartElement()) {
00863 parseUnknownElement(xml);
00864 }
00865 }
00866 }
00867
00868 void EnvCanadaIon::setMeasureUnit(const QString& unitType)
00869 {
00870 d->m_measureType = unitType.toInt();
00871 }
00872
00873 void EnvCanadaIon::setTimezoneFormat(const QString& tz)
00874 {
00875 d->m_timezoneType = tz.toInt();
00876 }
00877
00878 bool EnvCanadaIon::metricUnit()
00879 {
00880 if (d->m_measureType == KLocale::Metric) {
00881 return true;
00882 }
00883
00884
00885 return false;
00886 }
00887
00888 bool EnvCanadaIon::timezone()
00889 {
00890 if (d->m_timezoneType) {
00891 return true;
00892 }
00893
00894
00895 return false;
00896 }
00897
00898 void EnvCanadaIon::updateWeather(const QString& source)
00899 {
00900 QMap<QString, QString> dataFields;
00901 QStringList fieldList;
00902 QVector<QString> forecastList;
00903 int i = 0;
00904
00905 kDebug() << "updateWeather() BEGIN";
00906 setData(source, "Country", country(source));
00907 kDebug() << "SOURCE = " << source;
00908 setData(source, "Place", QString("%1, %2").arg(city(source)).arg(territory(source)));
00909 kDebug() << "KEEP GOING" << source;
00910 setData(source, "Region", region(source));
00911 setData(source, "Station", station(source));
00912
00913
00914 setData(source, "Observation Period", observationTime(source));
00915 setData(source, "Current Conditions", condition(source));
00916 dataFields = temperature(source);
00917 setData(source, "Temperature", dataFields["temperature"]);
00918
00919
00920 if (dataFields["comfortTemperature"] != "N/A" && !dataFields["comfortTemperature"].isEmpty()) {
00921 if (dataFields["comfortTemperature"].toFloat() <= 0 || (dataFields["comfortTemperature"].toFloat() <= 32 && !metricUnit())) {
00922 setData(source, "Windchill", QString("%1%2").arg(dataFields["comfortTemperature"]).arg(QChar(176)));
00923 setData(source, "Humidex", "N/A");
00924 } else {
00925 setData(source, "Humidex", QString("%1%2").arg(dataFields["comfortTemperature"]).arg(QChar(176)));
00926 setData(source, "Windchill", "N/A");
00927 }
00928 } else {
00929 setData(source, "Windchill", "N/A");
00930 setData(source, "Humidex", "N/A");
00931 }
00932
00933 setData(source, "Temperature Unit", dataFields["temperatureUnit"]);
00934
00935 setData(source, "Dewpoint", dewpoint(source));
00936 if (dewpoint(source) != "N/A") {
00937 setData(source, "Dewpoint Unit", dataFields["temperatureUnit"]);
00938 }
00939
00940 dataFields = pressure(source);
00941 setData(source, "Pressure", dataFields["pressure"]);
00942
00943 if (dataFields["pressure"] != "N/A") {
00944 setData(source, "Pressure Tendency", dataFields["pressureTendency"]);
00945 setData(source, "Pressure Unit", dataFields["pressureUnit"]);
00946 }
00947
00948 dataFields = visibility(source);
00949 setData(source, "Visibility", dataFields["visibility"]);
00950 if (dataFields["visibility"] != "N/A") {
00951 setData(source, "Visibility Unit", dataFields["visibilityUnit"]);
00952 }
00953
00954 setData(source, "Humidity", humidity(source));
00955
00956 dataFields = wind(source);
00957 setData(source, "Wind Speed", dataFields["windSpeed"]);
00958 if (dataFields["windSpeed"] != "N/A") {
00959 setData(source, "Wind Speed Unit", dataFields["windUnit"]);
00960 }
00961 setData(source, "Wind Gust", dataFields["windGust"]);
00962 setData(source, "Wind Direction", dataFields["windDirection"]);
00963 setData(source, "Wind Gust Unit", dataFields["windGustUnit"]);
00964
00965 dataFields = regionalTemperatures(source);
00966 setData(source, "Normal High", dataFields["normalHigh"]);
00967 setData(source, "Normal Low", dataFields["normalLow"]);
00968 if (dataFields["normalHigh"] != "N/A" && dataFields["normalLow"] != "N/A") {
00969 setData(source, "Regional Temperature Unit", dataFields["regionalTempUnit"]);
00970 }
00971
00972
00973 dataFields = uvIndex(source);
00974 setData(source, "UV Index", dataFields["uvIndex"]);
00975 if (dataFields["uvIndex"] != "N/A") {
00976 setData(source, "UV Rating", dataFields["uvRating"]);
00977 }
00978
00979 dataFields = warnings(source);
00980
00981
00982 for (int i = 0; i < EnvCanadaIon::MAX_WARNINGS; i++) {
00983 if (!dataFields[QString("watch %1").arg(i)].isEmpty()) {
00984 fieldList = dataFields[QString("watch %1").arg(i)].split('|');
00985 setData(source, QString("Watch Priority %1").arg(i), fieldList[0]);
00986 setData(source, QString("Watch Description %1").arg(i), fieldList[1]);
00987 setData(source, QString("Watch Info %1").arg(i), fieldList[2]);
00988 setData(source, QString("Watch Timestamp %1").arg(i), fieldList[3]);
00989 }
00990 if (!dataFields[QString("warning %1").arg(i)].isEmpty()) {
00991 fieldList = dataFields[QString("warning %1").arg(i)].split('|');
00992 setData(source, QString("Warning Priority %1").arg(i), fieldList[0]);
00993 setData(source, QString("Warning Description %1").arg(i), fieldList[1]);
00994 setData(source, QString("Warning Info %1").arg(i), fieldList[2]);
00995 setData(source, QString("Warning Timestamp %1").arg(i), fieldList[3]);
00996 }
00997 }
00998
00999 forecastList = forecasts(source);
01000 foreach(const QString &forecastItem, forecastList) {
01001 fieldList = forecastItem.split('|');
01002
01003
01004 if (metricUnit()) {
01005 setData(source, QString("Short Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5") \
01006 .arg(fieldList[0]).arg(fieldList[1]).arg(fieldList[3]).arg(fieldList[4]).arg(fieldList[5]));
01007
01008 setData(source, QString("Long Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6|%7|%8") \
01009 .arg(fieldList[0]).arg(fieldList[2]).arg(fieldList[3]).arg(fieldList[4]).arg(fieldList[6]) \
01010 .arg(fieldList[7]).arg(fieldList[8]).arg(fieldList[9]));
01011 } else {
01012 setData(source, QString("Short Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5") \
01013 .arg(fieldList[0]).arg(fieldList[1]).arg(fieldList[3] == "N/A" ? "N/A" : \
01014 QString::number(WeatherFormula::celsiusToF(fieldList[3].toFloat()), 'd', 0)) \
01015 .arg(fieldList[4] == "N/A" ? "N/A" : QString::number(WeatherFormula::celsiusToF(fieldList[4].toFloat()), 'd', 0)).arg(fieldList[5]));
01016
01017 setData(source, QString("Long Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6|%7|%8") \
01018 .arg(fieldList[0]).arg(fieldList[2]).arg(fieldList[3] == "N/A" ? "N/A" : \
01019 QString::number(WeatherFormula::celsiusToF(fieldList[3].toFloat()), 'd', 0)) \
01020 .arg(fieldList[4] == "N/A" ? "N/A" : QString::number(WeatherFormula::celsiusToF(fieldList[4].toFloat()), 'd', 0)).arg(fieldList[6]).arg(fieldList[7]) \
01021 .arg(fieldList[8]).arg(fieldList[9]));
01022 }
01023
01024 i++;
01025 }
01026
01027 dataFields = yesterdayWeather(source);
01028 setData(source, "Yesterday High", dataFields["prevHigh"]);
01029 setData(source, "Yesterday Low", dataFields["prevLow"]);
01030
01031 if (dataFields["prevHigh"] != "N/A" && dataFields["prevLow"] != "N/A") {
01032 setData(source , "Yesterday Temperature Unit", dataFields["yesterdayTempUnit"]);
01033 }
01034
01035 setData(source, "Yesterday Precip Total", dataFields["prevPrecip"]);
01036 setData(source, "Yesterday Precip Unit", dataFields["prevPrecipUnit"]);
01037
01038 dataFields = sunriseSet(source);
01039 setData(source, "Sunrise At", dataFields["sunrise"]);
01040 setData(source, "Sunset At", dataFields["sunset"]);
01041
01042 dataFields = moonriseSet(source);
01043 setData(source, "Moonrise At", dataFields["moonrise"]);
01044 setData(source, "Moonset At", dataFields["moonset"]);
01045
01046 dataFields = weatherRecords(source);
01047 setData(source, "Record High Temperature", dataFields["recordHigh"]);
01048 setData(source, "Record Low Temperature", dataFields["recordLow"]);
01049 if (dataFields["recordHigh"] != "N/A" && dataFields["recordLow"] != "N/A") {
01050 setData(source, "Record Temperature Unit", dataFields["recordTempUnit"]);
01051 }
01052
01053 setData(source, "Record Rainfall", dataFields["recordRain"]);
01054 setData(source, "Record Rainfall Unit", dataFields["recordRainUnit"]);
01055 setData(source, "Record Snowfall", dataFields["recordSnow"]);
01056 setData(source, "Record Snowfall Unit", dataFields["recordSnowUnit"]);
01057
01058 setData(source, "Credit", "Meteorological data is provided by Environment Canada");
01059 kDebug() << "updateWeather FINISH Send it out!";
01060 }
01061
01062 QString EnvCanadaIon::country(const QString& source)
01063 {
01064 return d->m_weatherData[source].countryName;
01065 }
01066 QString EnvCanadaIon::territory(const QString& source)
01067 {
01068 return d->m_weatherData[source].shortTerritoryName;
01069 }
01070 QString EnvCanadaIon::city(const QString& source)
01071 {
01072 return d->m_weatherData[source].cityName;
01073 }
01074 QString EnvCanadaIon::region(const QString& source)
01075 {
01076 return d->m_weatherData[source].regionName;
01077 }
01078 QString EnvCanadaIon::station(const QString& source)
01079 {
01080 if (!d->m_weatherData[source].stationID.isEmpty()) {
01081 return d->m_weatherData[source].stationID.toUpper();
01082 }
01083
01084 return QString("N/A");
01085 }
01086
01087 QString EnvCanadaIon::observationTime(const QString& source)
01088 {
01089 return d->m_weatherData[source].obsTimestamp;
01090 }
01091 QString EnvCanadaIon::condition(const QString& source)
01092 {
01093 if (d->m_weatherData[source].condition.isEmpty()) {
01094 d->m_weatherData[source].condition = "N/A";
01095 }
01096 return d->m_weatherData[source].condition;
01097 }
01098
01099 QString EnvCanadaIon::dewpoint(const QString& source)
01100 {
01101 if (metricUnit()) {
01102 if (!d->m_weatherData[source].dewpoint.isEmpty()) {
01103 return QString::number(d->m_weatherData[source].dewpoint.toFloat(), 'f', 1);
01104 }
01105 }
01106
01107 if (!d->m_weatherData[source].dewpoint.isEmpty()) {
01108 return QString::number(WeatherFormula::celsiusToF(d->m_weatherData[source].dewpoint.toFloat()), 'f', 1);
01109 }
01110
01111 return QString("N/A");
01112 }
01113
01114 QString EnvCanadaIon::humidity(const QString& source)
01115 {
01116 if (!d->m_weatherData[source].humidity.isEmpty()) {
01117 return QString("%1%").arg(d->m_weatherData[source].humidity);
01118 }
01119 return QString("N/A");
01120 }
01121
01122 QMap<QString, QString> EnvCanadaIon::visibility(const QString& source)
01123 {
01124 QMap<QString, QString> visibilityInfo;
01125
01126 if (!d->m_weatherData[source].visibility == 0) {
01127 if (metricUnit()) {
01128 visibilityInfo.insert("visibility", QString::number(d->m_weatherData[source].visibility, 'f', 1));
01129 visibilityInfo.insert("visibilityUnit", "km");
01130 } else {
01131 visibilityInfo.insert("visibility", QString::number(WeatherFormula::kilometersToMI(d->m_weatherData[source].visibility), 'f', 2));
01132 visibilityInfo.insert("visibilityUnit", "mi");
01133 }
01134 } else {
01135 visibilityInfo.insert("visibility", "N/A");
01136 }
01137 return visibilityInfo;
01138 }
01139
01140 QMap<QString, QString> EnvCanadaIon::temperature(const QString& source)
01141 {
01142 QMap<QString, QString> temperatureInfo;
01143 if (metricUnit()) {
01144 if (!d->m_weatherData[source].temperature.isEmpty()) {
01145 temperatureInfo.insert("temperature", QString::number(d->m_weatherData[source].temperature.toFloat(), 'f', 1));
01146 }
01147 temperatureInfo.insert("temperatureUnit", QString("%1C").arg(QChar(176)));
01148 } else {
01149 if (!d->m_weatherData[source].temperature.isEmpty()) {
01150 temperatureInfo.insert("temperature", QString::number(WeatherFormula::celsiusToF(d->m_weatherData[source].temperature.toFloat()), 'f', 1));
01151 } else {
01152 temperatureInfo.insert("temperature", "N/A");
01153 }
01154 temperatureInfo.insert("temperatureUnit", QString("%1F").arg(QChar(176)));
01155 }
01156 temperatureInfo.insert("comfortTemperature", "N/A");
01157
01158 if (d->m_weatherData[source].comforttemp != "N/A") {
01159 if (metricUnit()) {
01160 temperatureInfo.insert("comfortTemperature", d->m_weatherData[source].comforttemp);
01161 } else {
01162 if (!d->m_weatherData[source].comforttemp.isEmpty()) {
01163 temperatureInfo.insert("comfortTemperature", QString::number(WeatherFormula::celsiusToF(d->m_weatherData[source].comforttemp.toFloat()), 'f', 1));
01164 }
01165 }
01166 }
01167 return temperatureInfo;
01168 }
01169
01170 QMap<QString, QString> EnvCanadaIon::warnings(const QString& source)
01171 {
01172 QMap<QString, QString> warningData;
01173 QString warnType;
01174 for (int i = 0; i < d->m_weatherData[source].warnings.size(); ++i) {
01175 if (d->m_weatherData[source].warnings[i]->type == "watch") {
01176 warnType = QString("watch %1").arg(i);
01177 } else {
01178 warnType = QString("warning %1").arg(i);
01179 }
01180 warningData[warnType] = QString("%1|%2|%3|%4").arg(d->m_weatherData[source].warnings[i]->priority) \
01181 .arg(d->m_weatherData[source].warnings[i]->description) \
01182 .arg(d->m_weatherData[source].warnings[i]->url) \
01183 .arg(d->m_weatherData[source].warnings[i]->timestamp);
01184 }
01185 return warningData;
01186 }
01187
01188 QVector<QString> EnvCanadaIon::forecasts(const QString& source)
01189 {
01190 QVector<QString> forecastData;
01191
01192
01193 for (int i = 0; i < d->m_weatherData[source].forecasts.size(); ++i) {
01194 if (d->m_weatherData[source].forecasts[i]->forecastPeriod.isEmpty()) {
01195 d->m_weatherData[source].forecasts[i]->forecastPeriod = "N/A";
01196 }
01197 if (d->m_weatherData[source].forecasts[i]->shortForecast.isEmpty()) {
01198 d->m_weatherData[source].forecasts[i]->shortForecast = "N/A";
01199 }
01200 if (d->m_weatherData[source].forecasts[i]->forecastSummary.isEmpty()) {
01201 d->m_weatherData[source].forecasts[i]->forecastSummary = "N/A";
01202 }
01203 if (d->m_weatherData[source].forecasts[i]->forecastTempHigh.isEmpty()) {
01204 d->m_weatherData[source].forecasts[i]->forecastTempHigh = "N/A";
01205 }
01206 if (d->m_weatherData[source].forecasts[i]->forecastTempLow.isEmpty()) {
01207 d->m_weatherData[source].forecasts[i]->forecastTempLow = "N/A";
01208 }
01209 if (d->m_weatherData[source].forecasts[i]->popPrecent.isEmpty()) {
01210 d->m_weatherData[source].forecasts[i]->popPrecent = "N/A";
01211 }
01212 if (d->m_weatherData[source].forecasts[i]->windForecast.isEmpty()) {
01213 d->m_weatherData[source].forecasts[i]->windForecast = "N/A";
01214 }
01215 if (d->m_weatherData[source].forecasts[i]->precipForecast.isEmpty()) {
01216 d->m_weatherData[source].forecasts[i]->precipForecast = "N/A";
01217 }
01218 if (d->m_weatherData[source].forecasts[i]->precipType.isEmpty()) {
01219 d->m_weatherData[source].forecasts[i]->precipType = "N/A";
01220 }
01221 if (d->m_weatherData[source].forecasts[i]->precipTotalExpected.isEmpty()) {
01222 d->m_weatherData[source].forecasts[i]->precipTotalExpected = "N/A";
01223 }
01224 }
01225
01226 for (int i = 0; i < d->m_weatherData[source].forecasts.size(); ++i) {
01227 forecastData.append(QString("%1|%2|%3|%4|%5|%6|%7|%8|%9|%10") \
01228 .arg(d->m_weatherData[source].forecasts[i]->forecastPeriod) \
01229 .arg(d->m_weatherData[source].forecasts[i]->shortForecast) \
01230 .arg(d->m_weatherData[source].forecasts[i]->forecastSummary) \
01231 .arg(d->m_weatherData[source].forecasts[i]->forecastTempHigh) \
01232 .arg(d->m_weatherData[source].forecasts[i]->forecastTempLow) \
01233 .arg(d->m_weatherData[source].forecasts[i]->popPrecent) \
01234 .arg(d->m_weatherData[source].forecasts[i]->windForecast) \
01235 .arg(d->m_weatherData[source].forecasts[i]->precipForecast) \
01236 .arg(d->m_weatherData[source].forecasts[i]->precipType) \
01237 .arg(d->m_weatherData[source].forecasts[i]->precipTotalExpected));
01238 }
01239 return forecastData;
01240 }
01241
01242 QMap<QString, QString> EnvCanadaIon::pressure(const QString& source)
01243 {
01244 QMap<QString, QString> pressureInfo;
01245
01246 if (d->m_weatherData[source].pressure == 0) {
01247 pressureInfo.insert("pressure", "N/A");
01248 return pressureInfo;
01249 } else {
01250 if (metricUnit()) {
01251 pressureInfo.insert("pressure", QString::number(d->m_weatherData[source].pressure, 'f', 1));
01252 pressureInfo.insert("pressureUnit", "kPa");
01253 } else {
01254 pressureInfo.insert("pressure", QString::number(WeatherFormula::kilopascalsToInches(d->m_weatherData[source].pressure), 'f', 2));
01255 pressureInfo.insert("pressureUnit", "in");
01256 }
01257 pressureInfo.insert("pressureTendency", d->m_weatherData[source].pressureTendency);
01258 }
01259 return pressureInfo;
01260 }
01261
01262 QMap<QString, QString> EnvCanadaIon::wind(const QString& source)
01263 {
01264 QMap<QString, QString> windInfo;
01265
01266
01267 if (d->m_weatherData[source].windSpeed.isEmpty()) {
01268 windInfo.insert("windSpeed", "N/A");
01269 windInfo.insert("windUnit", "N/A");
01270 } else if (d->m_weatherData[source].windSpeed.toInt() == 0) {
01271 windInfo.insert("windSpeed", "Calm");
01272 windInfo.insert("windUnit", "N/A");
01273 } else {
01274 if (metricUnit()) {
01275 windInfo.insert("windSpeed", QString::number(d->m_weatherData[source].windSpeed.toInt()));
01276 windInfo.insert("windUnit", "km/h");
01277 } else {
01278 windInfo.insert("windSpeed", QString::number(WeatherFormula::kilometersToMI(d->m_weatherData[source].windSpeed.toInt()), 'f', 1));
01279 windInfo.insert("windUnit", "mph");
01280 }
01281 }
01282
01283
01284 if (d->m_weatherData[source].windGust.isEmpty()) {
01285 windInfo.insert("windGust", "N/A");
01286 windInfo.insert("windGustUnit", "N/A");
01287 } else {
01288 if (metricUnit()) {
01289 windInfo.insert("windGust", QString::number(d->m_weatherData[source].windGust.toInt()));
01290 windInfo.insert("windGustUnit", "km/h");
01291 } else {
01292 windInfo.insert("windGust", QString::number(WeatherFormula::kilometersToMI(d->m_weatherData[source].windGust.toInt()), 'f', 1));
01293 windInfo.insert("windGustUnit", "mph");
01294 }
01295 }
01296
01297 if (d->m_weatherData[source].windDirection.isEmpty() && d->m_weatherData[source].windSpeed.isEmpty()) {
01298 windInfo.insert("windDirection", "N/A");
01299 } else if (d->m_weatherData[source].windSpeed.toInt() == 0) {
01300 windInfo.insert("windDirection", "VR");
01301 } else {
01302 windInfo.insert("windDirection", d->m_weatherData[source].windDirection);
01303 }
01304 return windInfo;
01305 }
01306
01307 QMap<QString, QString> EnvCanadaIon::uvIndex(const QString& source)
01308 {
01309 QMap<QString, QString> uvInfo;
01310
01311 if (d->m_weatherData[source].UVRating.isEmpty()) {
01312 uvInfo.insert("uvRating", "N/A");
01313 } else {
01314 uvInfo.insert("uvRating", d->m_weatherData[source].UVRating);
01315 }
01316
01317 if (d->m_weatherData[source].UVIndex.isEmpty()) {
01318 uvInfo.insert("uvIndex", "N/A");
01319 } else {
01320 uvInfo.insert("uvIndex", d->m_weatherData[source].UVIndex);
01321 }
01322
01323 return uvInfo;
01324 }
01325
01326 QMap<QString, QString> EnvCanadaIon::regionalTemperatures(const QString& source)
01327 {
01328 QMap<QString, QString> regionalTempInfo;
01329
01330 if (d->m_weatherData[source].normalHigh.isEmpty()) {
01331 regionalTempInfo.insert("normalHigh", "N/A");
01332 } else {
01333 if (metricUnit()) {
01334 regionalTempInfo.insert("normalHigh", d->m_weatherData[source].normalHigh);
01335 } else {
01336 regionalTempInfo.insert("normalHigh", QString("%1").arg(WeatherFormula::celsiusToF(d->m_weatherData[source].normalHigh.toFloat())));
01337 }
01338 }
01339
01340 if (d->m_weatherData[source].normalLow.isEmpty()) {
01341 regionalTempInfo.insert("normalLow", "N/A");
01342 } else {
01343 if (metricUnit()) {
01344 regionalTempInfo.insert("normalLow", d->m_weatherData[source].normalLow);
01345 } else {
01346 regionalTempInfo.insert("normalLow", QString("%1").arg(WeatherFormula::celsiusToF(d->m_weatherData[source].normalLow.toFloat())));
01347 }
01348 }
01349
01350 if (metricUnit()) {
01351 regionalTempInfo.insert("regionalTempUnit", QString("%1C").arg(QChar(176)));
01352 } else {
01353 regionalTempInfo.insert("regionalTempUnit", QString("%1F").arg(QChar(176)));
01354 }
01355
01356 return regionalTempInfo;
01357 }
01358
01359 QMap<QString, QString> EnvCanadaIon::yesterdayWeather(const QString& source)
01360 {
01361 QMap<QString, QString> yesterdayInfo;
01362
01363 if (d->m_weatherData[source].prevHigh.isEmpty()) {
01364 yesterdayInfo.insert("prevHigh", "N/A");
01365 } else {
01366 if (metricUnit()) {
01367 yesterdayInfo.insert("prevHigh", d->m_weatherData[source].prevHigh);
01368 } else {
01369 yesterdayInfo.insert("prevHigh", QString::number(WeatherFormula::celsiusToF(d->m_weatherData[source].prevHigh.toFloat())));
01370 }
01371 }
01372
01373 if (d->m_weatherData[source].prevLow.isEmpty()) {
01374 yesterdayInfo.insert("prevLow", "N/A");
01375 } else {
01376 if (metricUnit()) {
01377 yesterdayInfo.insert("prevLow", d->m_weatherData[source].prevLow);
01378 } else {
01379 yesterdayInfo.insert("prevLow", QString::number(WeatherFormula::celsiusToF(d->m_weatherData[source].prevLow.toFloat()), 'f', 1));
01380 }
01381 }
01382
01383 if (metricUnit()) {
01384 yesterdayInfo.insert("yesterdayTempUnit", QString("%1C").arg(QChar(176)));
01385 } else {
01386 yesterdayInfo.insert("yesterdayTempUnit", QString("%1F").arg(QChar(176)));
01387 }
01388
01389 if (d->m_weatherData[source].prevPrecipTotal == "Trace") {
01390 yesterdayInfo.insert("prevPrecip", "Trace");
01391 return yesterdayInfo;
01392 }
01393
01394 if (d->m_weatherData[source].prevPrecipTotal.isEmpty()) {
01395 yesterdayInfo.insert("prevPrecip", "N/A");
01396 } else {
01397 if (metricUnit()) {
01398 yesterdayInfo.insert("prevPrecipTotal", d->m_weatherData[source].prevPrecipTotal);
01399 yesterdayInfo.insert("prevPrecipUnit", d->m_weatherData[source].prevPrecipType);
01400 } else {
01401 yesterdayInfo.insert("prevPrecipTotal", QString::number(WeatherFormula::millimetersToIN(d->m_weatherData[source].prevPrecipTotal.toFloat()), 'f', 1));
01402 yesterdayInfo.insert("prevPrecipUnit", QString("in"));
01403 }
01404 }
01405
01406 return yesterdayInfo;
01407 }
01408
01409 QMap<QString, QString> EnvCanadaIon::sunriseSet(const QString& source)
01410 {
01411 QMap<QString, QString> sunInfo;
01412
01413 if (d->m_weatherData[source].sunriseTimestamp.isEmpty()) {
01414 sunInfo.insert("sunrise", "N/A");
01415 } else {
01416 sunInfo.insert("sunrise", d->m_weatherData[source].sunriseTimestamp);
01417 }
01418
01419 if (d->m_weatherData[source].sunsetTimestamp.isEmpty()) {
01420 sunInfo.insert("sunset", "N/A");
01421 } else {
01422 sunInfo.insert("sunset", d->m_weatherData[source].sunsetTimestamp);
01423 }
01424
01425 return sunInfo;
01426 }
01427
01428 QMap<QString, QString> EnvCanadaIon::moonriseSet(const QString& source)
01429 {
01430 QMap<QString, QString> moonInfo;
01431
01432 if (d->m_weatherData[source].moonriseTimestamp.isEmpty()) {
01433 moonInfo.insert("moonrise", "N/A");
01434 } else {
01435 moonInfo.insert("moonrise", d->m_weatherData[source].moonriseTimestamp);
01436 }
01437
01438 if (d->m_weatherData[source].moonsetTimestamp.isEmpty()) {
01439 moonInfo.insert("moonset", "N/A");
01440 } else {
01441 moonInfo.insert("moonset", d->m_weatherData[source].moonsetTimestamp);
01442 }
01443
01444 return moonInfo;
01445 }
01446
01447 QMap<QString, QString> EnvCanadaIon::weatherRecords(const QString& source)
01448 {
01449 QMap<QString, QString> recordInfo;
01450
01451 if (d->m_weatherData[source].recordHigh == 0) {
01452 recordInfo.insert("recordHigh", "N/A");
01453 } else {
01454 if (metricUnit()) {
01455 recordInfo.insert("recordHigh", QString("%1").arg(d->m_weatherData[source].recordHigh));
01456 } else {
01457 recordInfo.insert("recordHigh", QString::number(WeatherFormula::celsiusToF(d->m_weatherData[source].recordHigh), 'f', 1));
01458 }
01459 }
01460
01461 if (d->m_weatherData[source].recordLow == 0) {
01462 recordInfo.insert("recordLow", "N/A");
01463 } else {
01464 if (metricUnit()) {
01465 recordInfo.insert("recordLow", QString("%1").arg(d->m_weatherData[source].recordLow));
01466 } else {
01467 recordInfo.insert("recordLow", QString::number(WeatherFormula::celsiusToF(d->m_weatherData[source].recordLow), 'f', 1));
01468 }
01469
01470 }
01471
01472 if (metricUnit()) {
01473 recordInfo.insert("recordTempUnit", QString("%1C").arg(QChar(176)));
01474 } else {
01475 recordInfo.insert("recordTempUnit", QString("%1F").arg(QChar(176)));
01476 }
01477
01478 if (d->m_weatherData[source].recordRain == 0) {
01479 recordInfo.insert("recordRain", "N/A");
01480 } else {
01481 if (metricUnit()) {
01482 recordInfo.insert("recordRain", QString("%1").arg(d->m_weatherData[source].recordRain));
01483 recordInfo.insert("recordRainUnit", QString("mm"));
01484 } else {
01485 recordInfo.insert("recordRain", QString::number(WeatherFormula::millimetersToIN(d->m_weatherData[source].recordRain), 'f', 1));
01486 recordInfo.insert("recordRainUnit", QString("in"));
01487 }
01488 }
01489
01490 if (d->m_weatherData[source].recordSnow == 0) {
01491 recordInfo.insert("recordSnow", "N/A");
01492 } else {
01493 if (metricUnit()) {
01494 recordInfo.insert("recordSnow", QString("%1").arg(d->m_weatherData[source].recordSnow));
01495 recordInfo.insert("recordSnowUnit", QString("cm"));
01496 } else {
01497 recordInfo.insert("recordSnow", QString::number(WeatherFormula::centimetersToIN(d->m_weatherData[source].recordSnow), 'f', 1));
01498 recordInfo.insert("recordSnowUnit", QString("in"));
01499 }
01500 }
01501
01502 return recordInfo;
01503 }
01504
01505 #include "ion_envcan.moc"