File indexing completed on 2024-04-28 04:42:42

0001 /*
0002  * SPDX-FileCopyrightText: 2020-2021 Han Young <hanyoung@protonmail.com>
0003  * SPDX-FileCopyrightText: 2020-2021 Devin Lin <espidev@gmail.com>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 #include "dailyweatherforecast.h"
0008 #include "kweathercore_p.h"
0009 #include "pendingweatherforecast_p.h"
0010 #include <QJsonArray>
0011 namespace KWeatherCore
0012 {
0013 class DailyWeatherForecast::DailyWeatherForecastPrivate
0014 {
0015 public:
0016     bool isValid = true;
0017 
0018     double maxTemp = std::numeric_limits<double>::lowest();
0019     double minTemp = std::numeric_limits<double>::max();
0020     double precipitation = 0; // mm
0021     double uvIndex = 0; // 0-1
0022     double humidity = 0; // %
0023     double pressure = 0; // hPa
0024     QString weatherIcon = QStringLiteral("weather-none-available");
0025     QString weatherDescription = QStringLiteral("Unknown");
0026     QDate date;
0027 
0028     std::vector<HourlyWeatherForecast> hourlyWeatherForecast;
0029 };
0030 DailyWeatherForecast::~DailyWeatherForecast() = default;
0031 DailyWeatherForecast::DailyWeatherForecast(DailyWeatherForecast &&other) = default;
0032 DailyWeatherForecast &DailyWeatherForecast::operator=(DailyWeatherForecast &&other) = default;
0033 DailyWeatherForecast::DailyWeatherForecast()
0034     : d(std::make_unique<DailyWeatherForecastPrivate>())
0035 {
0036 }
0037 DailyWeatherForecast::DailyWeatherForecast(const QDate &date)
0038     : d(std::make_unique<DailyWeatherForecastPrivate>())
0039 {
0040     d->date = date;
0041     d->isValid = false;
0042 }
0043 DailyWeatherForecast::DailyWeatherForecast(const DailyWeatherForecast &other)
0044     : d(std::make_unique<DailyWeatherForecastPrivate>())
0045 {
0046     *d = *other.d;
0047 }
0048 
0049 QJsonObject DailyWeatherForecast::toJson()
0050 {
0051     QJsonObject obj;
0052     QJsonArray hourlyArray;
0053     obj[QLatin1String("maxTemp")] = maxTemp();
0054     obj[QLatin1String("minTemp")] = minTemp();
0055     obj[QLatin1String("precipitation")] = precipitation();
0056     obj[QLatin1String("uvIndex")] = uvIndex();
0057     obj[QLatin1String("humidity")] = humidity();
0058     obj[QLatin1String("pressure")] = pressure();
0059     obj[QLatin1String("weatherIcon")] = weatherIcon();
0060     obj[QLatin1String("weatherDescription")] = weatherDescription();
0061     obj[QLatin1String("date")] = date().toString(Qt::ISODate);
0062     for (const auto &h : hourlyWeatherForecast()) {
0063         hourlyArray.append(h.toJson());
0064     }
0065     obj[QLatin1String("hourly")] = hourlyArray;
0066     return obj;
0067 }
0068 DailyWeatherForecast DailyWeatherForecast::fromJson(const QJsonObject &obj)
0069 {
0070     DailyWeatherForecast ret(QDate::fromString(obj[QLatin1String("date")].toString(), Qt::ISODate));
0071     ret.setMaxTemp(obj[QLatin1String("maxTemp")].toDouble());
0072     ret.setMinTemp(obj[QLatin1String("minTemp")].toDouble());
0073     ret.setPrecipitation(obj[QLatin1String("precipitation")].toDouble());
0074     ret.setUvIndex(obj[QLatin1String("uvIndex")].toDouble());
0075     ret.setHumidity(obj[QLatin1String("humidity")].toDouble());
0076     ret.setPressure(obj[QLatin1String("pressure")].toDouble());
0077     ret.setWeatherIcon(obj[QLatin1String("weatherIcon")].toString());
0078     ret.setWeatherDescription(obj[QLatin1String("weatherDescription")].toString());
0079     std::vector<HourlyWeatherForecast> hourlyVec;
0080     auto array = obj[QLatin1String("hourly")].toArray();
0081     for (int i = 0; i < array.size(); i++) {
0082         hourlyVec.push_back(HourlyWeatherForecast::fromJson(array.at(i).toObject()));
0083     }
0084     ret.setHourlyWeatherForecast(hourlyVec);
0085     return ret;
0086 }
0087 bool DailyWeatherForecast::isValid() const
0088 {
0089     return d->isValid;
0090 }
0091 void DailyWeatherForecast::setMaxTemp(double maxTemp)
0092 {
0093     d->maxTemp = maxTemp;
0094 }
0095 void DailyWeatherForecast::setMinTemp(double minTemp)
0096 {
0097     d->minTemp = minTemp;
0098 }
0099 void DailyWeatherForecast::setPrecipitation(double precipitation)
0100 {
0101     d->precipitation = precipitation;
0102 }
0103 void DailyWeatherForecast::setUvIndex(double uvIndex)
0104 {
0105     d->uvIndex = uvIndex;
0106 }
0107 void DailyWeatherForecast::setHumidity(double humidity)
0108 {
0109     d->humidity = humidity;
0110 }
0111 void DailyWeatherForecast::setPressure(double pressure)
0112 {
0113     d->pressure = pressure;
0114 }
0115 void DailyWeatherForecast::setWeatherIcon(const QString &icon)
0116 {
0117     d->weatherIcon = icon;
0118 }
0119 void DailyWeatherForecast::setWeatherDescription(const QString &description)
0120 {
0121     d->weatherDescription = std::move(description);
0122 }
0123 void DailyWeatherForecast::setDate(const QDate &date)
0124 {
0125     d->date = date;
0126 }
0127 void DailyWeatherForecast::setDate(const QDateTime &date)
0128 {
0129     d->date = date.date();
0130 }
0131 double DailyWeatherForecast::maxTemp() const
0132 {
0133     return d->maxTemp;
0134 }
0135 double DailyWeatherForecast::minTemp() const
0136 {
0137     return d->minTemp;
0138 }
0139 double DailyWeatherForecast::precipitation() const
0140 {
0141     return d->precipitation;
0142 }
0143 double DailyWeatherForecast::uvIndex() const
0144 {
0145     return d->uvIndex;
0146 }
0147 double DailyWeatherForecast::humidity() const
0148 {
0149     return d->humidity;
0150 }
0151 double DailyWeatherForecast::pressure() const
0152 {
0153     return d->pressure;
0154 }
0155 const QString &DailyWeatherForecast::weatherIcon() const
0156 {
0157     return d->weatherIcon;
0158 }
0159 const QString &DailyWeatherForecast::weatherDescription() const
0160 {
0161     return d->weatherDescription;
0162 }
0163 const QDate &DailyWeatherForecast::date() const
0164 {
0165     return d->date;
0166 }
0167 QDateTime DailyWeatherForecast::dateTime() const
0168 {
0169     return d->date.startOfDay();
0170 }
0171 const std::vector<HourlyWeatherForecast> &DailyWeatherForecast::hourlyWeatherForecast() const
0172 {
0173     return d->hourlyWeatherForecast;
0174 }
0175 void DailyWeatherForecast::setHourlyWeatherForecast(const std::vector<HourlyWeatherForecast> &forecast)
0176 {
0177     d->hourlyWeatherForecast = forecast;
0178 }
0179 void DailyWeatherForecast::setHourlyWeatherForecast(std::vector<HourlyWeatherForecast> &&forecast)
0180 {
0181     d->hourlyWeatherForecast = std::move(forecast);
0182 }
0183 
0184 DailyWeatherForecast &DailyWeatherForecast::operator+=(const HourlyWeatherForecast &forecast)
0185 {
0186     if (isValid()) {
0187         setDate(forecast.date().date());
0188         setWeatherDescription(forecast.weatherDescription());
0189         setWeatherIcon(forecast.weatherIcon());
0190         d->isValid = false;
0191     }
0192 
0193     if (date().daysTo(forecast.date().date()) == 0) {
0194         // set description and icon if it is higher ranked
0195         if (KWeatherCorePrivate::weatherIconPriorityRank(forecast.neutralWeatherIcon()) >= KWeatherCorePrivate::weatherIconPriorityRank(weatherIcon())) {
0196             setWeatherDescription(KWeatherCorePrivate::resolveAPIWeatherDesc(forecast.symbolCode() + QStringLiteral("_neutral")).desc);
0197             setWeatherIcon(forecast.neutralWeatherIcon());
0198         }
0199         setPrecipitation(precipitation() + forecast.precipitationAmount());
0200         setUvIndex(std::max(uvIndex(), forecast.uvIndex()));
0201         setHumidity(std::max(humidity(), forecast.humidity()));
0202         setPressure(std::max(pressure(), forecast.pressure()));
0203         setMaxTemp(std::max(maxTemp(), forecast.temperature()));
0204         setMinTemp(std::min(minTemp(), forecast.temperature()));
0205     }
0206 
0207     d->hourlyWeatherForecast.push_back(forecast);
0208     return *this;
0209 }
0210 
0211 bool DailyWeatherForecast::operator==(const DailyWeatherForecast &forecast) const
0212 {
0213     return (date() == forecast.date());
0214 }
0215 
0216 bool DailyWeatherForecast::operator<(const DailyWeatherForecast &forecast) const
0217 {
0218     return date() < forecast.date();
0219 }
0220 DailyWeatherForecast &DailyWeatherForecast::operator=(const DailyWeatherForecast &other)
0221 {
0222     *d = *other.d;
0223     return *this;
0224 }
0225 }
0226 
0227 #include "moc_dailyweatherforecast.cpp"