Kstars

modcalcdaylength.cpp
1/*
2 SPDX-FileCopyrightText: 2002 Pablo de Vicente <vicente@oan.es>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "modcalcdaylength.h"
8
9#include "geolocation.h"
10#include "kstarsdata.h"
11#include "ksnotification.h"
12#include "dialogs/locationdialog.h"
13#include "skyobjects/ksmoon.h"
14#include "skyobjects/kssun.h"
15#include "skyobjects/skyobject.h"
16
17#include <KLineEdit>
18
19// Qt version calming
20#include <qtendl.h>
21
22modCalcDayLength::modCalcDayLength(QWidget *parentSplit) : QFrame(parentSplit)
23{
24 setupUi(this);
25
26 showCurrentDate();
27 initGeo();
28 slotComputeAlmanac();
29
30 connect(Date, SIGNAL(dateChanged(QDate)), this, SLOT(slotComputeAlmanac()));
31 connect(Location, SIGNAL(clicked()), this, SLOT(slotLocation()));
32
33 connect(LocationBatch, SIGNAL(clicked()), this, SLOT(slotLocationBatch()));
34 connect(InputFileBatch, SIGNAL(urlSelected(QUrl)), this, SLOT(slotCheckFiles()));
35 connect(OutputFileBatch, SIGNAL(urlSelected(QUrl)), this, SLOT(slotCheckFiles()));
36 connect(RunButtonBatch, SIGNAL(clicked()), this, SLOT(slotRunBatch()));
37 connect(ViewButtonBatch, SIGNAL(clicked()), this, SLOT(slotViewBatch()));
38
39 RunButtonBatch->setEnabled(false);
40 ViewButtonBatch->setEnabled(false);
41
42 show();
43}
44
45void modCalcDayLength::showCurrentDate(void)
46{
48 Date->setDate(dt.date());
49}
50
51void modCalcDayLength::initGeo(void)
52{
53 KStarsData *data = KStarsData::Instance();
54 geoPlace = data->geo();
55 geoBatch = data->geo();
56 Location->setText(geoPlace->fullName());
57 LocationBatch->setText(geoBatch->fullName());
58}
59
60QTime modCalcDayLength::lengthOfDay(const QTime &setQTime, const QTime &riseQTime)
61{
62 QTime dL(0, 0, 0);
63 int dds = riseQTime.secsTo(setQTime);
64 QTime dLength = dL.addSecs(dds);
65
66 return dLength;
67}
68
69void modCalcDayLength::slotLocation()
70{
72 if (ld->exec() == QDialog::Accepted)
73 {
74 GeoLocation *newGeo = ld->selectedCity();
75 if (newGeo)
76 {
77 geoPlace = newGeo;
78 Location->setText(geoPlace->fullName());
79 }
80 }
81 delete ld;
82
83 slotComputeAlmanac();
84}
85
86void modCalcDayLength::slotLocationBatch()
87{
89 if (ld->exec() == QDialog::Accepted)
90 {
91 GeoLocation *newGeo = ld->selectedCity();
92 if (newGeo)
93 {
94 geoBatch = newGeo;
95 LocationBatch->setText(geoBatch->fullName());
96 }
97 }
98 delete ld;
99}
100
101void modCalcDayLength::updateAlmanac(const QDate &d, GeoLocation *geo)
102{
103 //Determine values needed for the Almanac
104 long double jd0 = KStarsDateTime(d, QTime(8, 0, 0)).djd();
105 KSNumbers num(jd0);
106
107 //Sun
108 KSSun Sun;
109 Sun.findPosition(&num);
110
111 QTime ssTime = Sun.riseSetTime(KStarsDateTime(jd0), geo, false);
112 QTime srTime = Sun.riseSetTime(KStarsDateTime(jd0), geo, true);
113 QTime stTime = Sun.transitTime(KStarsDateTime(jd0), geo);
114
115 dms ssAz = Sun.riseSetTimeAz(KStarsDateTime(jd0), geo, false);
116 dms srAz = Sun.riseSetTimeAz(KStarsDateTime(jd0), geo, true);
117 dms stAlt = Sun.transitAltitude(KStarsDateTime(jd0), geo);
118
119 //In most cases, the Sun will rise and set:
120 if (ssTime.isValid())
121 {
122 ssAzString = ssAz.toDMSString();
123 stAltString = stAlt.toDMSString();
124 srAzString = srAz.toDMSString();
125
126 ssTimeString = QLocale().toString(ssTime, "hh:mm:ss");
127 srTimeString = QLocale().toString(srTime, "hh:mm:ss");
128 stTimeString = QLocale().toString(stTime, "hh:mm:ss");
129
130 QTime daylength = lengthOfDay(ssTime, srTime);
131 //daylengthString = QLocale().toString(daylength);
132 daylengthString = QLocale().toString(daylength, "hh:mm:ss");
133
134 //...but not always!
135 }
136 else if (stAlt.Degrees() > 0.)
137 {
138 ssAzString = i18n("Circumpolar");
139 stAltString = stAlt.toDMSString();
140 srAzString = i18n("Circumpolar");
141
142 ssTimeString = "--:--";
143 srTimeString = "--:--";
144 stTimeString = QLocale().toString(stTime, "hh:mm:ss");
145 daylengthString = "24:00";
146 }
147 else if (stAlt.Degrees() < 0.)
148 {
149 ssAzString = i18n("Does not rise");
150 stAltString = stAlt.toDMSString();
151 srAzString = i18n("Does not set");
152
153 ssTimeString = "--:--";
154 srTimeString = "--:--";
155 stTimeString = QLocale().toString(stTime, "hh:mm:ss");
156 daylengthString = "00:00";
157 }
158
159 //Moon
160 KSMoon Moon;
161
162 QTime msTime = Moon.riseSetTime(KStarsDateTime(jd0), geo, false);
163 QTime mrTime = Moon.riseSetTime(KStarsDateTime(jd0), geo, true);
165
166 dms msAz = Moon.riseSetTimeAz(KStarsDateTime(jd0), geo, false);
167 dms mrAz = Moon.riseSetTimeAz(KStarsDateTime(jd0), geo, true);
169
170 //In most cases, the Moon will rise and set:
171 if (msTime.isValid())
172 {
173 msAzString = msAz.toDMSString();
174 mtAltString = mtAlt.toDMSString();
175 mrAzString = mrAz.toDMSString();
176
177 msTimeString = QLocale().toString(msTime, "hh:mm:ss");
178 mrTimeString = QLocale().toString(mrTime, "hh:mm:ss");
179 mtTimeString = QLocale().toString(mtTime, "hh:mm:ss");
180
181 //...but not always!
182 }
183 else if (mtAlt.Degrees() > 0.)
184 {
185 msAzString = i18n("Circumpolar");
186 mtAltString = mtAlt.toDMSString();
187 mrAzString = i18n("Circumpolar");
188
189 msTimeString = "--:--";
190 mrTimeString = "--:--";
191 mtTimeString = QLocale().toString(mtTime, "hh:mm:ss");
192 }
193 else if (mtAlt.Degrees() < 0.)
194 {
195 msAzString = i18n("Does not rise");
196 mtAltString = mtAlt.toDMSString();
197 mrAzString = i18n("Does not rise");
198
199 msTimeString = "--:--";
200 mrTimeString = "--:--";
201 mtTimeString = QLocale().toString(mtTime, "hh:mm:ss");
202 }
203
204 //after calling riseSetTime Phase needs to reset, setting it before causes Phase to set nan
205 Moon.findPosition(&num);
206 Moon.findPhase(nullptr);
207 lunarphaseString = Moon.phaseName() + " (" + QString::number(int(100 * Moon.illum())) + "%)";
208
209 //Fix length of Az strings
210 if (srAz.Degrees() < 100.0)
211 srAzString = ' ' + srAzString;
212 if (ssAz.Degrees() < 100.0)
213 ssAzString = ' ' + ssAzString;
214 if (mrAz.Degrees() < 100.0)
215 mrAzString = ' ' + mrAzString;
216 if (msAz.Degrees() < 100.0)
217 msAzString = ' ' + msAzString;
218}
219
220void modCalcDayLength::slotComputeAlmanac()
221{
222 updateAlmanac(Date->date(), geoPlace);
223
224 SunSet->setText(ssTimeString);
225 SunRise->setText(srTimeString);
226 SunTransit->setText(stTimeString);
227 SunSetAz->setText(ssAzString);
228 SunRiseAz->setText(srAzString);
229 SunTransitAlt->setText(stAltString);
230 DayLength->setText(daylengthString);
231
232 MoonSet->setText(msTimeString);
233 MoonRise->setText(mrTimeString);
234 MoonTransit->setText(mtTimeString);
235 MoonSetAz->setText(msAzString);
236 MoonRiseAz->setText(mrAzString);
237 MoonTransitAlt->setText(mtAltString);
238 LunarPhase->setText(lunarphaseString);
239}
240
241void modCalcDayLength::slotCheckFiles()
242{
243 bool flag = !InputFileBatch->lineEdit()->text().isEmpty() && !OutputFileBatch->lineEdit()->text().isEmpty();
244 RunButtonBatch->setEnabled(flag);
245}
246
247void modCalcDayLength::slotRunBatch()
248{
249 QString inputFileName = InputFileBatch->url().toLocalFile();
250
252 {
254 if (!f.open(QIODevice::ReadOnly))
255 {
256 QString message = i18n("Could not open file %1.", f.fileName());
257 KSNotification::sorry(message, i18n("Could Not Open File"));
258 return;
259 }
260
262 processLines(istream);
263 ViewButtonBatch->setEnabled(true);
264
265 f.close();
266 }
267 else
268 {
269 QString message = i18n("Invalid file: %1", inputFileName);
270 KSNotification::sorry(message, i18n("Invalid file"));
271 return;
272 }
273}
274
275void modCalcDayLength::processLines(QTextStream &istream)
276{
277 QFile fOut(OutputFileBatch->url().toLocalFile());
280
281 //Write header
282 ostream << "# " << i18nc("%1 is a location on earth", "Almanac for %1", geoBatch->fullName())
283 << QString(" [%1, %2]").arg(geoBatch->lng()->toDMSString(), geoBatch->lat()->toDMSString())
284 << "\n# " << i18n("computed by KStars") << Qt::endl
285 << "# " << "SRise: Sun Rise" << Qt::endl
286 << "# " << "STran: Sun Transit" << Qt::endl
287 << "# " << "SSet: Sun Set" << Qt::endl
288 << "# " << "SRiseAz: Azimuth of Sun Rise" << Qt::endl
289 << "# " << "STranAlt: Altitude of Sun Transit" << Qt::endl
290 << "# " << "SSetAz: Azimuth of Sun Set" << Qt::endl
291 << "# " << "STranAlt: Altitude of Sun Transit" << Qt::endl
292 << "# " << "DayLen: Day Duration in hours" << Qt::endl
293 << "# " << "MRise: Moon Rise" << Qt::endl
294 << "# " << "MTran: Moon Transit" << Qt::endl
295 << "# " << "MSet: Moon Set" << Qt::endl
296 << "# " << "MRiseAz: Azimuth of Moon Rise" << Qt::endl
297 << "# " << "MTranAkt: Altitude of Moon Transit" << Qt::endl
298 << "# " << "MSetAz: Azimuth of Moon Set" << Qt::endl
299 << "# " << "LunarPhase: Lunar Phase and Illumination Percentage" << Qt::endl
300 << "# " << Qt::endl
301 << "# Date,SRise,STran,SSet,SRiseAz,STranAlt,SSetAz,DayLen,MRise,MTran,MSet,"
302 << "MRiseAz,MTranAlt,MSetAz,LunarPhase" << Qt::endl
303 << "#" << Qt::endl;
304
305 QString line;
306 QDate d;
307
308 while (!istream.atEnd())
309 {
310 line = istream.readLine();
311 line = line.trimmed();
312
313 //Parse the line as a date, then compute Almanac values
315 if (d.isValid())
316 {
317 updateAlmanac(d, geoBatch);
318 ostream << d.toString(Qt::ISODate) << "," <<
319 srTimeString << "," <<
320 stTimeString << "," <<
321 ssTimeString << "," <<
322 srAzString << "," <<
323 stAltString << "," <<
324 ssAzString << "," <<
325 daylengthString << "," <<
326 mrTimeString << "," <<
327 mtTimeString << "," <<
328 msTimeString << "," <<
329 mrAzString << "," <<
330 mtAltString << "," <<
331 msAzString << "," <<
332 lunarphaseString << Qt::endl;
333 }
334 }
335}
336
337void modCalcDayLength::slotViewBatch()
338{
339 QFile fOut(OutputFileBatch->url().toLocalFile());
342 QStringList text;
343
344 while (!istream.atEnd())
345 text.append(istream.readLine());
346
347 fOut.close();
348
349 KMessageBox::informationList(nullptr, i18n("Results of Almanac calculation"), text, OutputFileBatch->url().toLocalFile());
350}
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
QString fullName() const
const CachingDms * lat() const
Definition geolocation.h:70
const CachingDms * lng() const
Definition geolocation.h:64
Provides necessary information about the Moon.
Definition ksmoon.h:26
QString phaseName() const
Definition ksmoon.cpp:288
double illum() const
Definition ksmoon.h:49
void findPhase(const KSSun *Sun=nullptr)
Determine the phase angle of the moon, and assign the appropriate moon image.
Definition ksmoon.cpp:268
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
void findPosition(const KSNumbers *num, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, const KSPlanetBase *Earth=nullptr)
Find position, including correction for Figure-of-the-Earth.
Child class of KSPlanetBase; encapsulates information about the Sun.
Definition kssun.h:24
KStarsData is the backbone of KStars.
Definition kstarsdata.h:72
GeoLocation * geo()
Definition kstarsdata.h:230
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
static KStarsDateTime currentDateTime()
long double djd() const
Dialog for changing the geographic location of the observer.
dms riseSetTimeAz(const KStarsDateTime &dt, const GeoLocation *geo, bool rst) const
dms transitAltitude(const KStarsDateTime &dt, const GeoLocation *geo) const
QTime transitTime(const KStarsDateTime &dt, const GeoLocation *geo) const
The same iteration technique described in riseSetTime() is used here.
QTime riseSetTime(const KStarsDateTime &dt, const GeoLocation *geo, bool rst, bool exact=true) const
Determine the time at which the point will rise or set.
Definition skyobject.cpp:93
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void informationList(QWidget *parent, const QString &text, const QStringList &strlist, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
QDate fromString(QStringView string, QStringView format, QCalendar cal)
bool exists() const const
void append(QList< T > &&value)
QString toString(QDate date, FormatType format) const const
QString arg(Args &&... args) const const
QString number(double n, char format, int precision)
QString trimmed() const const
QTextStream & endl(QTextStream &stream)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:04 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.