File indexing completed on 2024-05-05 16:49:21
0001 /* 0002 * SPDX-FileCopyrightText: 2020-2021 Han Young <hanyoung@protonmail.com> 0003 * SPDX-FileCopyrightText: 2020 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 Sunrise sunrise; 0029 std::vector<HourlyWeatherForecast> hourlyWeatherForecast; 0030 }; 0031 DailyWeatherForecast::~DailyWeatherForecast() = default; 0032 DailyWeatherForecast::DailyWeatherForecast(DailyWeatherForecast &&other) = 0033 default; 0034 DailyWeatherForecast & 0035 DailyWeatherForecast::operator=(DailyWeatherForecast &&other) = default; 0036 DailyWeatherForecast::DailyWeatherForecast() 0037 : d(std::make_unique<DailyWeatherForecastPrivate>()) 0038 { 0039 } 0040 DailyWeatherForecast::DailyWeatherForecast(const QDate &date) 0041 : d(std::make_unique<DailyWeatherForecastPrivate>()) 0042 { 0043 d->date = date; 0044 d->isValid = false; 0045 } 0046 DailyWeatherForecast::DailyWeatherForecast(const DailyWeatherForecast &other) 0047 : d(std::make_unique<DailyWeatherForecastPrivate>()) 0048 { 0049 *d = *other.d; 0050 } 0051 0052 QJsonObject DailyWeatherForecast::toJson() 0053 { 0054 QJsonObject obj; 0055 QJsonArray hourlyArray; 0056 obj[QStringLiteral("maxTemp")] = maxTemp(); 0057 obj[QStringLiteral("minTemp")] = minTemp(); 0058 obj[QStringLiteral("precipitation")] = precipitation(); 0059 obj[QStringLiteral("uvIndex")] = uvIndex(); 0060 obj[QStringLiteral("humidity")] = humidity(); 0061 obj[QStringLiteral("pressure")] = pressure(); 0062 obj[QStringLiteral("weatherIcon")] = weatherIcon(); 0063 obj[QStringLiteral("weatherDescription")] = weatherDescription(); 0064 obj[QStringLiteral("date")] = date().toString(Qt::ISODate); 0065 for (const auto &h : hourlyWeatherForecast()) { 0066 hourlyArray.append(h.toJson()); 0067 } 0068 obj[QStringLiteral("hourly")] = hourlyArray; 0069 obj[QStringLiteral("sunrise")] = sunrise().toJson(); 0070 return obj; 0071 } 0072 DailyWeatherForecast DailyWeatherForecast::fromJson(QJsonObject obj) 0073 { 0074 DailyWeatherForecast ret( 0075 QDate::fromString(obj[QStringLiteral("date")].toString(), Qt::ISODate)); 0076 ret.setMaxTemp(obj[QStringLiteral("maxTemp")].toDouble()); 0077 ret.setMinTemp(obj[QStringLiteral("minTemp")].toDouble()); 0078 ret.setPrecipitation(obj[QStringLiteral("precipitation")].toDouble()); 0079 ret.setUvIndex(obj[QStringLiteral("uvIndex")].toDouble()); 0080 ret.setHumidity(obj[QStringLiteral("humidity")].toDouble()); 0081 ret.setPressure(obj[QStringLiteral("pressure")].toDouble()); 0082 ret.setWeatherIcon(obj[QStringLiteral("weatherIcon")].toString()); 0083 ret.setWeatherDescription( 0084 obj[QStringLiteral("weatherDescription")].toString()); 0085 ret.setSunrise(Sunrise::fromJson(obj[QStringLiteral("sunrise")].toObject())); 0086 std::vector<HourlyWeatherForecast> hourlyVec; 0087 auto array = obj[QStringLiteral("hourly")].toArray(); 0088 for (int i = 0; i < array.size(); i++) { 0089 hourlyVec.push_back( 0090 HourlyWeatherForecast::fromJson(array.at(i).toObject())); 0091 } 0092 ret.setHourlyWeatherForecast(hourlyVec); 0093 return ret; 0094 } 0095 bool DailyWeatherForecast::isValid() const 0096 { 0097 return d->isValid; 0098 } 0099 void DailyWeatherForecast::setMaxTemp(double maxTemp) 0100 { 0101 d->maxTemp = maxTemp; 0102 } 0103 void DailyWeatherForecast::setMinTemp(double minTemp) 0104 { 0105 d->minTemp = minTemp; 0106 } 0107 void DailyWeatherForecast::setPrecipitation(double precipitation) 0108 { 0109 d->precipitation = precipitation; 0110 } 0111 void DailyWeatherForecast::setUvIndex(double uvIndex) 0112 { 0113 d->uvIndex = uvIndex; 0114 } 0115 void DailyWeatherForecast::setHumidity(double humidity) 0116 { 0117 d->humidity = humidity; 0118 } 0119 void DailyWeatherForecast::setPressure(double pressure) 0120 { 0121 d->pressure = pressure; 0122 } 0123 void DailyWeatherForecast::setWeatherIcon(const QString &icon) 0124 { 0125 d->weatherIcon = icon; 0126 } 0127 void DailyWeatherForecast::setWeatherDescription(const QString &description) 0128 { 0129 d->weatherDescription = std::move(description); 0130 } 0131 void DailyWeatherForecast::setDate(const QDate &date) 0132 { 0133 d->date = date; 0134 } 0135 void DailyWeatherForecast::setDate(const QDateTime &date) 0136 { 0137 d->date = date.date(); 0138 } 0139 double DailyWeatherForecast::maxTemp() const 0140 { 0141 return d->maxTemp; 0142 } 0143 double DailyWeatherForecast::minTemp() const 0144 { 0145 return d->minTemp; 0146 } 0147 double DailyWeatherForecast::precipitation() const 0148 { 0149 return d->precipitation; 0150 } 0151 double DailyWeatherForecast::uvIndex() const 0152 { 0153 return d->uvIndex; 0154 } 0155 double DailyWeatherForecast::humidity() const 0156 { 0157 return d->humidity; 0158 } 0159 double DailyWeatherForecast::pressure() const 0160 { 0161 return d->pressure; 0162 } 0163 const QString &DailyWeatherForecast::weatherIcon() const 0164 { 0165 return d->weatherIcon; 0166 } 0167 const QString &DailyWeatherForecast::weatherDescription() const 0168 { 0169 return d->weatherDescription; 0170 } 0171 const QDate &DailyWeatherForecast::date() const 0172 { 0173 return d->date; 0174 } 0175 QDateTime DailyWeatherForecast::dateTime() const 0176 { 0177 return d->date.startOfDay(); 0178 } 0179 const Sunrise &DailyWeatherForecast::sunrise() const 0180 { 0181 return d->sunrise; 0182 } 0183 const std::vector<HourlyWeatherForecast> & 0184 DailyWeatherForecast::hourlyWeatherForecast() const 0185 { 0186 return d->hourlyWeatherForecast; 0187 } 0188 void DailyWeatherForecast::setSunrise(Sunrise sunrise) 0189 { 0190 d->sunrise = std::move(sunrise); 0191 } 0192 void DailyWeatherForecast::setHourlyWeatherForecast( 0193 const std::vector<HourlyWeatherForecast> &forecast) 0194 { 0195 d->hourlyWeatherForecast = forecast; 0196 } 0197 void DailyWeatherForecast::setHourlyWeatherForecast( 0198 std::vector<HourlyWeatherForecast> &&forecast) 0199 { 0200 d->hourlyWeatherForecast = std::move(forecast); 0201 } 0202 DailyWeatherForecast & 0203 DailyWeatherForecast::operator+(const DailyWeatherForecast &forecast) 0204 { 0205 if (date().isNull()) { 0206 setDate(forecast.date()); 0207 setWeatherDescription(forecast.weatherDescription()); 0208 setWeatherIcon(forecast.weatherIcon()); 0209 d->isValid = false; 0210 } 0211 0212 if (*this == forecast) { 0213 setPrecipitation(precipitation() + forecast.precipitation()); 0214 setUvIndex(std::max(uvIndex(), forecast.uvIndex())); 0215 setHumidity(std::max(humidity(), forecast.humidity())); 0216 setPressure(std::max(pressure(), forecast.pressure())); 0217 setMaxTemp(std::max(maxTemp(), forecast.maxTemp())); 0218 setMinTemp(std::min(minTemp(), forecast.minTemp())); 0219 } 0220 0221 return *this; 0222 } 0223 0224 DailyWeatherForecast & 0225 DailyWeatherForecast::operator+=(const DailyWeatherForecast &forecast) 0226 { 0227 return *this + forecast; 0228 } 0229 0230 DailyWeatherForecast & 0231 DailyWeatherForecast::operator+=(const HourlyWeatherForecast &forecast) 0232 { 0233 if (isValid()) { 0234 setDate(forecast.date().date()); 0235 setWeatherDescription(forecast.weatherDescription()); 0236 setWeatherIcon(forecast.weatherIcon()); 0237 d->isValid = false; 0238 } 0239 if (date().daysTo(forecast.date().date()) == 0) { 0240 // set description and icon if it is higher ranked 0241 if (rank[forecast.neutralWeatherIcon()] >= rank[weatherIcon()]) { 0242 setWeatherDescription( 0243 apiDescMap[forecast.symbolCode() + QStringLiteral("_neutral")] 0244 .desc); 0245 setWeatherIcon(forecast.neutralWeatherIcon()); 0246 } 0247 setPrecipitation(precipitation() + forecast.precipitationAmount()); 0248 setUvIndex(std::max(uvIndex(), forecast.uvIndex())); 0249 setHumidity(std::max(humidity(), forecast.humidity())); 0250 setPressure(std::max(pressure(), forecast.pressure())); 0251 setMaxTemp(std::max(maxTemp(), forecast.temperature())); 0252 setMinTemp(std::min(minTemp(), forecast.temperature())); 0253 } 0254 0255 d->hourlyWeatherForecast.push_back(forecast); 0256 return *this; 0257 } 0258 0259 bool DailyWeatherForecast::operator==( 0260 const DailyWeatherForecast &forecast) const 0261 { 0262 return (date() == forecast.date()); 0263 } 0264 0265 bool DailyWeatherForecast::operator<(const DailyWeatherForecast &forecast) const 0266 { 0267 return date() < forecast.date(); 0268 } 0269 DailyWeatherForecast & 0270 DailyWeatherForecast::operator=(const DailyWeatherForecast &other) 0271 { 0272 *d = *other.d; 0273 return *this; 0274 } 0275 }