File indexing completed on 2024-05-05 16:49:23
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 "weatherforecast.h" 0008 #include <QJsonArray> 0009 namespace KWeatherCore 0010 { 0011 class WeatherForecast::WeatherForecastPrivate 0012 { 0013 public: 0014 std::vector<DailyWeatherForecast> dailyWeatherForecast; 0015 QString timezone; 0016 double latitude, longitude; 0017 QDateTime createdTime = QDateTime::currentDateTime(); 0018 }; 0019 0020 WeatherForecast::WeatherForecast() 0021 : d(std::make_unique<WeatherForecastPrivate>()) 0022 { 0023 } 0024 WeatherForecast::WeatherForecast(const WeatherForecast &other) 0025 : QSharedData(QSharedData()) 0026 , d(std::make_unique<WeatherForecastPrivate>()) 0027 { 0028 *d = *other.d; 0029 } 0030 WeatherForecast::WeatherForecast(WeatherForecast &&other) = default; 0031 WeatherForecast::~WeatherForecast() = default; 0032 WeatherForecast &WeatherForecast::operator=(const WeatherForecast &other) 0033 { 0034 *d = *other.d; 0035 return *this; 0036 } 0037 QJsonObject WeatherForecast::toJson() const 0038 { 0039 QJsonObject obj; 0040 QJsonArray dayArray; 0041 for (auto d : dailyWeatherForecast()) { 0042 dayArray.append(d.toJson()); 0043 } 0044 obj[QStringLiteral("day")] = dayArray; 0045 obj[QStringLiteral("lat")] = latitude(); 0046 obj[QStringLiteral("lon")] = longitude(); 0047 obj[QStringLiteral("timezone")] = timezone(); 0048 return obj; 0049 } 0050 QExplicitlySharedDataPointer<WeatherForecast> 0051 WeatherForecast::fromJson(QJsonObject obj) 0052 { 0053 auto w = QExplicitlySharedDataPointer<WeatherForecast>(new WeatherForecast); 0054 std::vector<DailyWeatherForecast> dayVec; 0055 const auto &array = obj[QStringLiteral("day")].toArray(); 0056 for (const auto &d : array) { 0057 dayVec.push_back(DailyWeatherForecast::fromJson(d.toObject())); 0058 } 0059 w->setDailyWeatherForecast(dayVec); 0060 w->setCoordinate(obj[QStringLiteral("lat")].toDouble(), 0061 obj[QStringLiteral("lon")].toDouble()); 0062 w->setTimezone(obj[QStringLiteral("timezone")].toString()); 0063 return w; 0064 } 0065 const std::vector<DailyWeatherForecast> & 0066 WeatherForecast::dailyWeatherForecast() const 0067 { 0068 return d->dailyWeatherForecast; 0069 } 0070 double WeatherForecast::latitude() const 0071 { 0072 return d->latitude; 0073 } 0074 double WeatherForecast::longitude() const 0075 { 0076 return d->longitude; 0077 } 0078 const QDateTime &WeatherForecast::createdTime() const 0079 { 0080 return d->createdTime; 0081 } 0082 const QString &WeatherForecast::timezone() const 0083 { 0084 return d->timezone; 0085 } 0086 void WeatherForecast::setCoordinate(double latitude, double longitude) 0087 { 0088 d->latitude = latitude; 0089 d->longitude = longitude; 0090 } 0091 void WeatherForecast::setTimezone(QString timezone) 0092 { 0093 d->timezone = std::move(timezone); 0094 } 0095 void WeatherForecast::setDailyWeatherForecast( 0096 const std::vector<DailyWeatherForecast> &forecast) 0097 { 0098 d->dailyWeatherForecast = forecast; 0099 } 0100 void WeatherForecast::setDailyWeatherForecast( 0101 std::vector<DailyWeatherForecast> &&forecast) 0102 { 0103 d->dailyWeatherForecast = std::move(forecast); 0104 } 0105 void WeatherForecast::setSunriseForecast(const std::vector<Sunrise> &sunrise) 0106 { 0107 int i = 0, range = sunrise.size(); 0108 for (auto &day : d->dailyWeatherForecast) { 0109 if (i >= range) 0110 break; 0111 day.setSunrise(sunrise.at(i)); 0112 ++i; 0113 } 0114 } 0115 void WeatherForecast::setSunriseForecast(std::vector<Sunrise> &&sunrise) 0116 { 0117 int i = 0, range = sunrise.size(); 0118 for (auto day : d->dailyWeatherForecast) { 0119 if (i >= range) 0120 break; 0121 // if on the same day, add sunrise to day 0122 if (day.date().daysTo(sunrise.at(i).sunRise().date()) == 0) { 0123 day.setSunrise(std::move(sunrise[i])); 0124 ++i; 0125 } 0126 } 0127 } 0128 WeatherForecast & 0129 WeatherForecast::operator+=(const DailyWeatherForecast &forecast) 0130 { 0131 for (int i = dailyWeatherForecast().size() - 1; i >= 0; --i) { 0132 if (dailyWeatherForecast().at(i) == forecast) { 0133 d->dailyWeatherForecast[i] += forecast; 0134 return *this; 0135 } 0136 } 0137 0138 // if not find, append it at end 0139 d->dailyWeatherForecast.push_back(forecast); 0140 return *this; 0141 } 0142 WeatherForecast &WeatherForecast::operator+=(DailyWeatherForecast &&forecast) 0143 { 0144 for (int i = dailyWeatherForecast().size() - 1; i >= 0; --i) { 0145 if (dailyWeatherForecast().at(i) == forecast) { 0146 d->dailyWeatherForecast[i] += forecast; 0147 return *this; 0148 } 0149 } 0150 0151 // if not find, append it at end 0152 d->dailyWeatherForecast.push_back(std::move(forecast)); 0153 return *this; 0154 } 0155 WeatherForecast & 0156 WeatherForecast::operator+=(const HourlyWeatherForecast &forecast) 0157 { 0158 for (int i = dailyWeatherForecast().size() - 1; i >= 0; --i) { 0159 if (dailyWeatherForecast().at(i).date().isValid() && 0160 dailyWeatherForecast().at(i).date().daysTo( 0161 forecast.date().date()) == 0) { 0162 d->dailyWeatherForecast[i] += forecast; 0163 return *this; 0164 } else { 0165 break; 0166 } 0167 } 0168 0169 // if not find, append it at end 0170 DailyWeatherForecast newDay; 0171 newDay += forecast; 0172 d->dailyWeatherForecast.push_back(std::move(newDay)); 0173 return *this; 0174 } 0175 WeatherForecast &WeatherForecast::operator+=(HourlyWeatherForecast &&forecast) 0176 { 0177 for (int i = dailyWeatherForecast().size() - 1; i >= 0; --i) { 0178 if (dailyWeatherForecast().at(i).date().daysTo( 0179 forecast.date().date()) == 0) { 0180 d->dailyWeatherForecast[i] += std::move(forecast); 0181 return *this; 0182 } 0183 } 0184 0185 // if not find, append it at end 0186 auto newDay = DailyWeatherForecast(); 0187 newDay += forecast; 0188 d->dailyWeatherForecast.push_back(std::move(newDay)); 0189 return *this; 0190 } 0191 0192 }