00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ion_bbcukmet.h"
00023
00024 class UKMETIon::Private : public QObject
00025 {
00026 public:
00027 Private() { m_url = 0;}
00028 ~Private() { delete m_url; }
00029
00030 private:
00031 struct XMLMapInfo {
00032 QString place;
00033 QString XMLurl;
00034 QString XMLforecastURL;
00035 bool ukPlace;
00036 QString sourceOptions;
00037 };
00038
00039 public:
00040
00041 QHash<QString, UKMETIon::Private::XMLMapInfo> m_place;
00042 QVector<QString> m_locations;
00043 QStringList m_matchLocations;
00044 bool isValid;
00045
00046 public:
00047
00048 QHash<QString, WeatherData> m_weatherData;
00049
00050
00051 QMap<KJob *, QXmlStreamReader*> m_jobXml;
00052 QMap<KJob *, QString> m_jobList;
00053
00054 QMap<KJob *, QXmlStreamReader*> m_obsJobXml;
00055 QMap<KJob *, QString> m_obsJobList;
00056
00057 QMap<KJob *, QXmlStreamReader *> m_forecastJobXml;
00058 QMap<KJob *, QString> m_forecastJobList;
00059
00060 KUrl *m_url;
00061 KIO::TransferJob *m_job;
00062
00063 int m_timezoneType;
00064 int m_measureType;
00065 };
00066
00067
00068
00069 UKMETIon::UKMETIon(QObject *parent, const QVariantList &args)
00070 : IonInterface(parent, args), d(new Private())
00071
00072 {
00073 Q_UNUSED(args)
00074 }
00075
00076 UKMETIon::~UKMETIon()
00077 {
00078
00079 foreach(const WeatherData &item, d->m_weatherData) {
00080 foreach(WeatherData::ForecastInfo *forecast, item.forecasts) {
00081 if (forecast) {
00082 delete forecast;
00083 }
00084 }
00085 }
00086
00087
00088 delete d;
00089 }
00090
00091
00092 void UKMETIon::init()
00093 {
00094 setInitialized(true);
00095 }
00096
00097
00098 bool UKMETIon::updateIonSource(const QString& source)
00099 {
00100
00101
00102
00103
00104 QStringList sourceAction = source.split('|');
00105
00106 if (sourceAction[1] == QString("validate")) {
00107
00108 findPlace(sourceAction[2], source);
00109 return true;
00110
00111 } else if (sourceAction[1] == QString("weather")) {
00112 if (sourceAction.count() >= 3) {
00113 d->m_place[QString("bbcukmet|%1").arg(sourceAction[2])].XMLurl = sourceAction[3];
00114 getXMLData(QString("%1|%2").arg(sourceAction[0]).arg(sourceAction[2]));
00115 return true;
00116 } else {
00117 return false;
00118 }
00119 }
00120 return false;
00121 }
00122
00123
00124 void UKMETIon::getXMLData(const QString& source)
00125 {
00126 KUrl url;
00127 url = d->m_place[source].XMLurl;
00128
00129 d->m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo);
00130 d->m_job->addMetaData("cookies", "none");
00131 d->m_obsJobXml.insert(d->m_job, new QXmlStreamReader);
00132 d->m_obsJobList.insert(d->m_job, source);
00133
00134 if (d->m_job) {
00135 connect(d->m_job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00136 SLOT(observation_slotDataArrived(KIO::Job *, const QByteArray &)));
00137 connect(d->m_job, SIGNAL(result(KJob *)), this, SLOT(observation_slotJobFinished(KJob *)));
00138 }
00139 }
00140
00141
00142 void UKMETIon::findPlace(const QString& place, const QString& source)
00143 {
00144 KUrl url;
00145 url = "http://www.bbc.co.uk/cgi-perl/weather/search/new_search.pl?x=0&y=0&=Submit&search_query=" + place + "&tmpl=wap";
00146
00147 d->m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo);
00148 d->m_job->addMetaData("cookies", "none");
00149 d->m_jobXml.insert(d->m_job, new QXmlStreamReader);
00150 d->m_jobList.insert(d->m_job, source);
00151
00152 if (d->m_job) {
00153 connect(d->m_job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00154 SLOT(setup_slotDataArrived(KIO::Job *, const QByteArray &)));
00155 connect(d->m_job, SIGNAL(result(KJob *)), this, SLOT(setup_slotJobFinished(KJob *)));
00156
00157
00158 connect(d->m_job, SIGNAL(redirection(KIO::Job *, const KUrl &)), this,
00159 SLOT(setup_slotRedirected(KIO::Job *, const KUrl &)));
00160 }
00161 }
00162
00163 void UKMETIon::getFiveDayForecast(const QString& source)
00164 {
00165 KUrl url;
00166 url = d->m_place[source].XMLforecastURL.replace("weather/5day.shtml", "weather/mobile/5day.wml");
00167
00168 d->m_job = KIO::get(url.url(), KIO::Reload, KIO::HideProgressInfo);
00169 d->m_job->addMetaData("cookies", "none");
00170 d->m_forecastJobXml.insert(d->m_job, new QXmlStreamReader);
00171 d->m_forecastJobList.insert(d->m_job, source);
00172
00173 if (d->m_job) {
00174 connect(d->m_job, SIGNAL(data(KIO::Job *, const QByteArray &)), this,
00175 SLOT(forecast_slotDataArrived(KIO::Job *, const QByteArray &)));
00176 connect(d->m_job, SIGNAL(result(KJob *)), this, SLOT(forecast_slotJobFinished(KJob *)));
00177 }
00178 }
00179
00180 bool UKMETIon::readSearchXMLData(const QString& key, QXmlStreamReader& xml)
00181 {
00182
00183 while (!xml.atEnd()) {
00184 xml.readNext();
00185
00186 if (xml.isEndElement()) {
00187 break;
00188 }
00189
00190 if (xml.isStartElement()) {
00191 if (xml.name() == "wml") {
00192 parseSearchLocations(key, xml);
00193 } else {
00194 parseUnknownElement(xml);
00195 }
00196 }
00197 }
00198
00199 return !xml.error();
00200 }
00201
00202 void UKMETIon::parseSearchLocations(const QString& source, QXmlStreamReader& xml)
00203 {
00204 int flag = 0;
00205 QString url;
00206 QString place;
00207 QStringList tokens;
00208 QString tmp;
00209 int counter = 2;
00210 int currentParagraph = 0;
00211
00212 Q_ASSERT(xml.isStartElement() && xml.name() == "wml");
00213
00214 while (!xml.atEnd()) {
00215 xml.readNext();
00216
00217 if (xml.isEndElement() && xml.name() == "wml") {
00218 break;
00219 }
00220
00221 if (xml.isStartElement() && xml.name() == "p") {
00222 currentParagraph++;
00223 }
00224
00225 if (currentParagraph == 2) {
00226 if (xml.isCharacters() && !xml.isWhitespace()) {
00227 QString dataText = xml.text().toString().trimmed();
00228 if (dataText.contains("No locations")) {
00229 break;
00230 }
00231 }
00232 }
00233
00234 if (xml.isStartElement()) {
00235 if (xml.name() == "a" && !xml.attributes().value("href").isEmpty()) {
00236 if (xml.attributes().value("href").toString().contains("5day.wml")) {
00237
00238
00239 tokens = xml.attributes().value("href").toString().split("=");
00240 if (xml.attributes().value("href").toString().contains("world")) {
00241 url = "http://feeds.bbc.co.uk/weather/feeds/obs/world/" + tokens[1] + ".xml";
00242 flag = 0;
00243 } else {
00244 url = "http://feeds.bbc.co.uk/weather/feeds/obs/id/" + tokens[1] + ".xml";
00245 flag = 1;
00246 }
00247 place = xml.readElementText();
00248 tmp = QString("bbcukmet|%1").arg(place);
00249
00250
00251 if (d->m_locations.contains(tmp)) {
00252
00253 QString dupePlace = place;
00254 tmp = QString("bbcukmet|%1").arg(QString("%1 (#%2)").arg(dupePlace).arg(counter));
00255 place = QString("%1 (#%2)").arg(dupePlace).arg(counter);
00256 counter++;
00257 }
00258
00259 if (flag) {
00260 d->m_place[tmp].XMLurl = url;
00261 d->m_place[tmp].place = place;
00262 d->m_place[tmp].ukPlace = true;
00263 } else {
00264 d->m_place[tmp].XMLurl = url;
00265 d->m_place[tmp].place = place;
00266 d->m_place[tmp].ukPlace = false;
00267 }
00268 d->m_locations.append(tmp);
00269 }
00270 }
00271 }
00272 }
00273 validate(source);
00274 }
00275
00276
00277 void UKMETIon::parseUnknownElement(QXmlStreamReader& xml)
00278 {
00279 while (!xml.atEnd()) {
00280 xml.readNext();
00281
00282 if (xml.isEndElement()) {
00283 break;
00284 }
00285
00286 if (xml.isStartElement()) {
00287 parseUnknownElement(xml);
00288 }
00289 }
00290 }
00291
00292 void UKMETIon::setup_slotRedirected(KIO::Job *job, const KUrl &url)
00293 {
00294 QString obsUrl;
00295 QString place;
00296 QString tmp;
00297 bool flag = false;
00298 QStringList tokens = url.url().split("=");
00299 if (url.url().contains("xhtml")) {
00300 if (url.url().contains("world")) {
00301 obsUrl = "http://feeds.bbc.co.uk/weather/feeds/obs/world/" + tokens[2] + ".xml";
00302 flag = false;
00303 } else {
00304 obsUrl = "http://feeds.bbc.co.uk/weather/feeds/obs/id/" + tokens[2] + ".xml";
00305 flag = true;
00306 }
00307 place = d->m_jobList[job].split("|")[2];
00308 tmp = QString("bbcukmet|%1").arg(place);
00309 place[0] = place[0].toUpper();
00310
00311 if (flag) {
00312 d->m_place[tmp].XMLurl = obsUrl;
00313 d->m_place[tmp].place = place;
00314 d->m_place[tmp].ukPlace = true;
00315 } else {
00316 d->m_place[tmp].XMLurl = obsUrl;
00317 d->m_place[tmp].place = place;
00318 d->m_place[tmp].ukPlace = false;
00319 }
00320 d->m_locations.append(tmp);
00321 validate(d->m_jobList[job]);
00322 }
00323 }
00324
00325 void UKMETIon::setup_slotDataArrived(KIO::Job *job, const QByteArray &data)
00326 {
00327 QByteArray local = data;
00328 if (data.isEmpty() || !d->m_jobXml.contains(job)) {
00329 return;
00330 }
00331
00332
00333 if (local.startsWith("<?xml version")) {
00334 local.replace("<?xml version=\"1.0\"?>", "<?xml version=\"1.0\" encoding=\"cp1252\" ?>");
00335 }
00336
00337
00338 d->m_jobXml[job]->addData(local);
00339 }
00340
00341 void UKMETIon::setup_slotJobFinished(KJob *job)
00342 {
00343 if (job->error() == 149) {
00344 setData(d->m_jobList[job], "validate", QString("bbcukmet|timeout"));
00345 disconnectSource(d->m_jobList[job], this);
00346 d->m_jobList.remove(job);
00347 delete d->m_jobXml[job];
00348 d->m_jobXml.remove(job);
00349 return;
00350 }
00351
00352 if (!d->m_locations.contains(QString("bbcukmet|%1").arg(d->m_jobList[job]))) {
00353 readSearchXMLData(d->m_jobList[job], *d->m_jobXml[job]);
00354 }
00355 d->m_jobList.remove(job);
00356 delete d->m_jobXml[job];
00357 d->m_jobXml.remove(job);
00358 }
00359
00360 void UKMETIon::observation_slotDataArrived(KIO::Job *job, const QByteArray &data)
00361 {
00362 QByteArray local = data;
00363 if (data.isEmpty() || !d->m_obsJobXml.contains(job)) {
00364 return;
00365 }
00366
00367
00368
00369 if (local.startsWith("<?xml version")) {
00370 local.replace("encoding=\"UTF-8\"?>", "encoding=\"cp1252\" ?>");
00371 }
00372
00373
00374 d->m_obsJobXml[job]->addData(local);
00375 }
00376
00377 void UKMETIon::observation_slotJobFinished(KJob *job)
00378 {
00379 setData(d->m_obsJobList[job], Data());
00380 readObservationXMLData(d->m_obsJobList[job], *d->m_obsJobXml[job]);
00381 d->m_obsJobList.remove(job);
00382 delete d->m_obsJobXml[job];
00383 d->m_obsJobXml.remove(job);
00384 }
00385
00386 void UKMETIon::forecast_slotDataArrived(KIO::Job *job, const QByteArray &data)
00387 {
00388 QByteArray local = data;
00389 if (data.isEmpty() || !d->m_forecastJobXml.contains(job)) {
00390 return;
00391 }
00392
00393
00394
00395 if (local.startsWith("<?xml version")) {
00396 local.replace("<?xml version=\"1.0\"?>", "<?xml version=\"1.0\" encoding=\"cp1252\" ?>");
00397 }
00398
00399 d->m_forecastJobXml[job]->addData(local);
00400 }
00401
00402 void UKMETIon::forecast_slotJobFinished(KJob *job)
00403 {
00404 setData(d->m_forecastJobList[job], Data());
00405 readFiveDayForecastXMLData(d->m_forecastJobList[job], *d->m_forecastJobXml[job]);
00406 d->m_forecastJobList.remove(job);
00407 delete d->m_forecastJobXml[job];
00408 d->m_forecastJobXml.remove(job);
00409 }
00410
00411 void UKMETIon::parsePlaceObservation(const QString &source, WeatherData& data, QXmlStreamReader& xml)
00412 {
00413 Q_ASSERT(xml.isStartElement() && xml.name() == "rss");
00414
00415 while (!xml.atEnd()) {
00416 xml.readNext();
00417
00418 if (xml.isEndElement() && xml.name() == "rss") {
00419 break;
00420 }
00421
00422 if (xml.isStartElement()) {
00423 if (xml.name() == "channel") {
00424 parseWeatherChannel(source, data, xml);
00425 }
00426 }
00427 }
00428 }
00429
00430 void UKMETIon::parseWeatherChannel(const QString& source, WeatherData& data, QXmlStreamReader& xml)
00431 {
00432 Q_ASSERT(xml.isStartElement() && xml.name() == "channel");
00433
00434 while (!xml.atEnd()) {
00435 xml.readNext();
00436
00437 if (xml.isEndElement() && xml.name() == "channel") {
00438 break;
00439 }
00440
00441 if (xml.isStartElement()) {
00442 if (xml.name() == "title") {
00443 data.stationName = xml.readElementText().split("Observations for")[1].trimmed();
00444 } else if (xml.name() == "item") {
00445 parseWeatherObservation(source, data, xml);
00446 } else {
00447 parseUnknownElement(xml);
00448 }
00449 }
00450 }
00451 }
00452
00453 void UKMETIon::parseWeatherObservation(const QString& source, WeatherData& data, QXmlStreamReader& xml)
00454 {
00455 Q_UNUSED(data)
00456 Q_ASSERT(xml.isStartElement() && xml.name() == "item");
00457
00458 while (!xml.atEnd()) {
00459 xml.readNext();
00460
00461 if (xml.isEndElement() && xml.name() == "item") {
00462 break;
00463 }
00464
00465 if (xml.isStartElement()) {
00466 if (xml.name() == "title") {
00467 QString conditionString = xml.readElementText();
00468
00469
00470 QStringList conditionData = conditionString.split(":");
00471
00472 data.obsTime = conditionData[0];
00473 data.condition = conditionData[1].split(".")[0].trimmed();
00474 } else if (xml.name() == "link") {
00475 d->m_place[source].XMLforecastURL = xml.readElementText();
00476 } else if (xml.name() == "description") {
00477 QString observeString = xml.readElementText();
00478 QStringList observeData = observeString.split(":");
00479
00480 data.temperature_C = observeData[1].split(QChar(176))[0].trimmed();
00481 data.temperature_F = observeData[1].split("(")[1].split(QChar(176))[0];
00482
00483 data.windDirection = observeData[2].split(",")[0].trimmed();
00484 data.windSpeed_miles = observeData[3].split(",")[0].split(" ")[1];
00485
00486 data.humidity = observeData[4].split(",")[0].split(" ")[1];
00487
00488 data.pressure = observeData[5].split(",")[0].split(" ")[1].split("mB")[0];
00489
00490 data.pressureTendency = observeData[5].split(",")[1].trimmed();
00491
00492 data.visibilityStr = observeData[6].trimmed();
00493
00494 } else {
00495 parseUnknownElement(xml);
00496 }
00497 }
00498 }
00499 }
00500
00501 bool UKMETIon::readObservationXMLData(const QString& source, QXmlStreamReader& xml)
00502 {
00503 WeatherData data;
00504
00505 while (!xml.atEnd()) {
00506 xml.readNext();
00507
00508 if (xml.isEndElement()) {
00509 break;
00510 }
00511
00512 if (xml.isStartElement()) {
00513 if (xml.name() == "rss") {
00514 parsePlaceObservation(source, data, xml);
00515 } else {
00516 parseUnknownElement(xml);
00517 }
00518 }
00519
00520 }
00521
00522 d->m_weatherData[source] = data;
00523
00524
00525 getFiveDayForecast(source);
00526
00527 return !xml.error();
00528 }
00529
00530 bool UKMETIon::readFiveDayForecastXMLData(const QString& source, QXmlStreamReader& xml)
00531 {
00532 while (!xml.atEnd()) {
00533 xml.readNext();
00534
00535 if (xml.isEndElement()) {
00536 break;
00537 }
00538
00539 if (xml.isStartElement()) {
00540 if (xml.name() == "wml") {
00541 parseFiveDayForecast(source, xml);
00542 } else {
00543 parseUnknownElement(xml);
00544 }
00545 }
00546 }
00547 updateWeather(source);
00548 return !xml.error();
00549 }
00550
00551 void UKMETIon::parseFiveDayForecast(const QString& source, QXmlStreamReader& xml)
00552 {
00553 Q_ASSERT(xml.isStartElement() && xml.name() == "wml");
00554
00555 int currentParagraph = 0;
00556 bool skipPlace = false;
00557 int dataItem = 0;
00558 int numberValue = 0;
00559
00560 enum DataItem {
00561 Day,
00562 Summary,
00563 MaxTemp,
00564 MinTemp,
00565 WindSpeed
00566 };
00567
00568
00569 d->m_weatherData[source].forecasts.clear();
00570
00571 WeatherData::ForecastInfo *forecast = new WeatherData::ForecastInfo;
00572
00573 QRegExp numParser("(Max|Min|Wind)\\s+-*([0-9]+)");
00574 while (!xml.atEnd()) {
00575 xml.readNext();
00576
00577 if (xml.isStartElement() && xml.name() == "p") {
00578 currentParagraph++;
00579 }
00580
00581 if (currentParagraph == 3) {
00582 if (xml.isCharacters() && !xml.isWhitespace()) {
00583 QString dataText = xml.text().toString().trimmed();
00584 if (!skipPlace) {
00585 skipPlace = true;
00586 } else {
00587 if (numParser.indexIn(dataText) != -1 && numParser.capturedTexts().count() >= 3) {
00588 numberValue = numParser.capturedTexts()[2].toInt();
00589 }
00590 switch (dataItem) {
00591 case Day:
00592 forecast->period = dataText;
00593 dataItem++;
00594 break;
00595 case Summary:
00596 forecast->summary = dataText;
00597 dataItem++;
00598 break;
00599 case MaxTemp:
00600 forecast->tempHigh = numberValue;
00601 dataItem++;
00602 break;
00603 case MinTemp:
00604 forecast->tempLow = numberValue;
00605 dataItem++;
00606 break;
00607 case WindSpeed:
00608 forecast->windSpeed = numberValue;
00609 forecast->windDirection = dataText.split("(")[1].split(")")[0];
00610 dataItem = 0;
00611 d->m_weatherData[source].forecasts.append(forecast);
00612 forecast = new WeatherData::ForecastInfo;
00613 break;
00614 };
00615 }
00616 }
00617 }
00618 }
00619
00620 delete forecast;
00621 }
00622
00623 void UKMETIon::setMeasureUnit(const QString& unitType)
00624 {
00625 d->m_measureType = unitType.toInt();
00626 }
00627
00628
00629 void UKMETIon::setTimezoneFormat(const QString& tz)
00630 {
00631 d->m_timezoneType = tz.toInt();
00632 }
00633
00634 bool UKMETIon::metricUnit()
00635 {
00636 if (d->m_measureType == KLocale::Metric) {
00637 return true;
00638 }
00639
00640
00641 return false;
00642 }
00643
00644
00645 bool UKMETIon::timezone()
00646 {
00647 if (d->m_timezoneType) {
00648 return true;
00649 }
00650
00651
00652 return false;
00653 }
00654
00655 void UKMETIon::validate(const QString& source)
00656 {
00657 bool beginflag = true;
00658
00659 if (!d->m_locations.count()) {
00660 QStringList invalidPlace = source.split('|');
00661 if (d->m_place[QString("bbcukmet|%1").arg(invalidPlace[2])].place.isEmpty()) {
00662 setData(source, "validate", QString("bbcukmet|invalid|multiple|%1").arg(invalidPlace[2]));
00663 }
00664 d->m_locations.clear();
00665 return;
00666 } else {
00667 QString placeList;
00668 foreach(const QString &place, d->m_locations) {
00669 if (beginflag) {
00670 placeList.append(QString("%1|extra|%2").arg(place.split("|")[1]).arg(d->m_place[place].XMLurl));
00671 beginflag = false;
00672 } else {
00673 placeList.append(QString("|place|%1|extra|%2").arg(place.split("|")[1]).arg(d->m_place[place].XMLurl));
00674 }
00675 }
00676 if (d->m_locations.count() > 1) {
00677 setData(source, "validate", QString("bbcukmet|valid|multiple|place|%1").arg(placeList));
00678 } else {
00679 placeList[0] = placeList[0].toUpper();
00680 setData(source, "validate", QString("bbcukmet|valid|single|place|%1").arg(placeList));
00681 }
00682 }
00683 d->m_locations.clear();
00684 }
00685
00686 void UKMETIon::updateWeather(const QString& source)
00687 {
00688 QString weatherSource = source;
00689 weatherSource.replace("bbcukmet|", "bbcukmet|weather|");
00690 weatherSource.append(QString("|%1").arg(d->m_place[source].XMLurl));
00691
00692 QMap<QString, QString> dataFields;
00693 QStringList fieldList;
00694 QVector<QString> forecastList;
00695 int i = 0;
00696
00697 setData(weatherSource, "Place", place(source));
00698 setData(weatherSource, "Station", station(source));
00699 setData(weatherSource, "Observation Period", observationTime(source));
00700 setData(weatherSource, "Current Conditions", condition(source));
00701
00702 setData(weatherSource, "Humidity", humidity(source));
00703 setData(weatherSource, "Visibility", visibility(source));
00704
00705 dataFields = temperature(source);
00706 setData(weatherSource, "Temperature", dataFields["temperature"]);
00707 setData(weatherSource, "Temperature Unit", dataFields["temperatureUnit"]);
00708
00709 dataFields = pressure(source);
00710 setData(weatherSource, "Pressure", dataFields["pressure"]);
00711 setData(weatherSource, "Pressure Unit", dataFields["pressureUnit"]);
00712 setData(weatherSource, "Pressure Tendency", dataFields["pressureTendency"]);
00713
00714 dataFields = wind(source);
00715 setData(weatherSource, "Wind Speed", dataFields["windSpeed"]);
00716 setData(weatherSource, "Wind Speed Unit", dataFields["windUnit"]);
00717 setData(weatherSource, "Wind Direction", dataFields["windDirection"]);
00718
00719
00720 forecastList = forecasts(source);
00721
00722 QString windSpeed;
00723 QString windUnit;
00724 foreach(const QString &forecastItem, forecastList) {
00725 fieldList = forecastItem.split('|');
00726 if (metricUnit()) {
00727 windSpeed = QString::number(WeatherFormula::milesToKM(fieldList[4].toFloat()), 'f', 1);
00728 windUnit = "km/h";
00729 } else {
00730 windSpeed = fieldList[4];
00731 windUnit = "mph";
00732 }
00733
00734 setData(weatherSource, QString("Short Forecast Day %1").arg(i), QString("%1|%2|%3|%4|%5|%6|%7") \
00735 .arg(fieldList[0]).arg(fieldList[1]).arg(fieldList[2]).arg(fieldList[3]) \
00736 .arg(windSpeed).arg(windUnit).arg(fieldList[5]));
00737 i++;
00738 }
00739
00740 setData(weatherSource, "Credit", "Supported by backstage.bbc.co.uk / Data from UK MET Office");
00741 }
00742
00743 QString UKMETIon::place(const QString& source)
00744 {
00745 return d->m_weatherData[source].stationName;
00746 }
00747
00748 QString UKMETIon::station(const QString& source)
00749 {
00750 return d->m_weatherData[source].stationName;
00751 }
00752
00753 QString UKMETIon::observationTime(const QString& source)
00754 {
00755 return d->m_weatherData[source].obsTime;
00756 }
00757
00758 QString UKMETIon::condition(const QString& source)
00759 {
00760 return d->m_weatherData[source].condition;
00761 }
00762
00763 QMap<QString, QString> UKMETIon::temperature(const QString& source)
00764 {
00765 QMap<QString, QString> temperatureInfo;
00766
00767 if (metricUnit()) {
00768 temperatureInfo.insert("temperature", QString("%1").arg(d->m_weatherData[source].temperature_C));
00769 temperatureInfo.insert("temperatureUnit", QString("%1C").arg(QChar(176)));
00770 } else {
00771 temperatureInfo.insert("temperature", QString("%1").arg(d->m_weatherData[source].temperature_F));
00772 temperatureInfo.insert("temperatureUnit", QString("%1F").arg(QChar(176)));
00773 }
00774 return temperatureInfo;
00775 }
00776
00777 QMap<QString, QString> UKMETIon::wind(const QString& source)
00778 {
00779 QMap<QString, QString> windInfo;
00780 if (d->m_weatherData[source].windSpeed_miles == "N/A") {
00781 windInfo.insert("windSpeed", "N/A");
00782 windInfo.insert("windUnit", "N/A");
00783 } else {
00784 if (metricUnit()) {
00785 windInfo.insert("windSpeed", QString::number(WeatherFormula::milesToKM(d->m_weatherData[source].windSpeed_miles.toFloat()), 'f', 1));
00786 windInfo.insert("windUnit", "km/h");
00787 } else {
00788 windInfo.insert("windSpeed", QString(d->m_weatherData[source].windSpeed_miles));
00789 windInfo.insert("windUnit", "mph");
00790 }
00791 }
00792 windInfo.insert("windDirection", d->m_weatherData[source].windDirection);
00793 return windInfo;
00794 }
00795
00796 QString UKMETIon::humidity(const QString& source)
00797 {
00798 if (d->m_weatherData[source].humidity == "N/A%") {
00799 return "N/A";
00800 }
00801 return d->m_weatherData[source].humidity;
00802 }
00803
00804 QString UKMETIon::visibility(const QString& source)
00805 {
00806 return d->m_weatherData[source].visibilityStr;
00807 }
00808
00809 QMap<QString, QString> UKMETIon::pressure(const QString& source)
00810 {
00811 QMap<QString, QString> pressureInfo;
00812 if (d->m_weatherData[source].pressure == "N/A") {
00813 pressureInfo.insert("pressure", "N/A");
00814 return pressureInfo;
00815 }
00816
00817 if (metricUnit()) {
00818 pressureInfo.insert("pressure", QString::number(WeatherFormula::millibarsToKilopascals(d->m_weatherData[source].pressure.toFloat()), 'f', 1));
00819 pressureInfo.insert("pressureUnit", "kPa");
00820 } else {
00821 pressureInfo.insert("pressure", QString::number(WeatherFormula::millibarsToInches(d->m_weatherData[source].pressure.toFloat()), 'f', 2));
00822 pressureInfo.insert("pressureUnit", "in");
00823 }
00824
00825 pressureInfo.insert("pressureTendency", d->m_weatherData[source].pressureTendency);
00826 return pressureInfo;
00827 }
00828
00829 QVector<QString> UKMETIon::forecasts(const QString& source)
00830 {
00831 QVector<QString> forecastData;
00832
00833 for (int i = 0; i < d->m_weatherData[source].forecasts.size(); ++i) {
00834 forecastData.append(QString("%1|%2|%3|%4|%5|%6") \
00835 .arg(d->m_weatherData[source].forecasts[i]->period) \
00836 .arg(d->m_weatherData[source].forecasts[i]->summary) \
00837 .arg(d->m_weatherData[source].forecasts[i]->tempHigh) \
00838 .arg(d->m_weatherData[source].forecasts[i]->tempLow) \
00839 .arg(d->m_weatherData[source].forecasts[i]->windSpeed) \
00840 .arg(d->m_weatherData[source].forecasts[i]->windDirection));
00841 }
00842
00843 return forecastData;
00844 }
00845
00846 #include "ion_bbcukmet.moc"