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"