Kstars

modcalcplanets.cpp
1/*
2 SPDX-FileCopyrightText: 2004-2005 Pablo de Vicente <p.devicentea@wanadoo.es>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "modcalcplanets.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
16modCalcPlanets::modCalcPlanets(QWidget *parentSplit) : QFrame(parentSplit)
17{
18 setupUi(this);
19
21
22 DateTimeBox->setDateTime(dt);
23 DateBoxBatch->setDate(dt.date());
24 UTBoxBatch->setTime(dt.time());
25
26 geoPlace = KStarsData::Instance()->geo();
27 LocationButton->setText(geoPlace->fullName());
28
29 RABox->setUnits(dmsBox::HOURS);
30
31 // signals and slots connections
32 connect(PlanetComboBox, SIGNAL(activated(int)), this, SLOT(slotComputePosition()));
33 connect(DateTimeBox, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(slotComputePosition()));
34 connect(LocationButton, SIGNAL(clicked()), this, SLOT(slotLocation()));
35
36 connect(UTCheckBatch, SIGNAL(clicked()), this, SLOT(slotUtCheckedBatch()));
37 connect(DateCheckBatch, SIGNAL(clicked()), this, SLOT(slotDateCheckedBatch()));
38 connect(LatCheckBatch, SIGNAL(clicked()), this, SLOT(slotLatCheckedBatch()));
39 connect(LongCheckBatch, SIGNAL(clicked()), this, SLOT(slotLongCheckedBatch()));
40 connect(PlanetCheckBatch, SIGNAL(clicked()), this, SLOT(slotPlanetsCheckedBatch()));
41
42 slotComputePosition();
43 show();
44}
45
46void modCalcPlanets::slotLocation()
47{
49
50 if (ld->exec() == QDialog::Accepted)
51 {
52 geoPlace = ld->selectedCity();
53 LocationButton->setText(geoPlace->fullName());
54 slotComputePosition();
55 }
56 delete ld;
57}
58
59void modCalcPlanets::slotComputePosition()
60{
61 KStarsDateTime dt(DateTimeBox->dateTime());
62 long double julianDay = dt.djd();
63 KSNumbers num(julianDay);
64 CachingDms LST(geoPlace->GSTtoLST(dt.gst()));
65
66 // Earth
67 KSPlanet Earth(i18n("Earth"));
68 Earth.findPosition(&num);
69
70 // Earth is special case!
71 if (PlanetComboBox->currentIndex() == 2)
72 {
73 showCoordinates(Earth);
74 return;
75 }
76
77 // Pointer to hold planet data. Pointer is used since it has to
78 // hold objects of different type. It's safe to use new/delete
79 // because exceptions are disallowed.
80 std::unique_ptr<KSPlanetBase> p;
81
82 switch (PlanetComboBox->currentIndex())
83 {
84 case 0:
85 p.reset(new KSPlanet(KSPlanetBase::MERCURY));
86 break;
87 case 1:
88 p.reset(new KSPlanet(KSPlanetBase::VENUS));
89 break;
90 case 3:
91 p.reset(new KSPlanet(KSPlanetBase::MARS));
92 break;
93 case 4:
94 p.reset(new KSPlanet(KSPlanetBase::JUPITER));
95 break;
96 case 5:
97 p.reset(new KSPlanet(KSPlanetBase::SATURN));
98 break;
99 case 6:
100 p.reset(new KSPlanet(KSPlanetBase::URANUS));
101 break;
102 case 7:
103 p.reset(new KSPlanet(KSPlanetBase::NEPTUNE));
104 break;
105 /*case 8:
106 p.reset(new KSPluto(); break;*/
107 case 8:
108 p.reset(new KSMoon());
109 break;
110 case 9:
111 p.reset(new KSSun());
112 p->setRsun(0.0);
113 break;
114 }
115 if (p.get() == nullptr)
116 return;
117
118 // Show data.
119 p->findPosition(&num, geoPlace->lat(), &LST, &Earth);
120 p->EquatorialToHorizontal(&LST, geoPlace->lat());
121 showCoordinates(*p);
122}
123
124void modCalcPlanets::showCoordinates(const KSPlanetBase &ksp)
125{
126 showHeliocentricEclipticCoords(ksp.helEcLong(), ksp.helEcLat(), ksp.rsun());
127 showGeocentricEclipticCoords(ksp.ecLong(), ksp.ecLat(), ksp.rearth());
128 showEquatorialCoords(ksp.ra(), ksp.dec());
129 showTopocentricCoords(ksp.az(), ksp.alt());
130}
131
132void modCalcPlanets::showHeliocentricEclipticCoords(const dms &hLong, const dms &hLat, double dist)
133{
134 HelioLongBox->show(hLong);
135 HelioLatBox->show(hLat);
136 HelioDistBox->setText(QLocale().toString(dist, 6));
137}
138
139void modCalcPlanets::showGeocentricEclipticCoords(const dms &eLong, const dms &eLat, double dist)
140{
141 GeoLongBox->show(eLong);
142 GeoLatBox->show(eLat);
143 GeoDistBox->setText(QLocale().toString(dist, 6));
144}
145
146void modCalcPlanets::showEquatorialCoords(const dms &ra, const dms &dec)
147{
148 RABox->show(ra);
149 DecBox->show(dec);
150}
151
152void modCalcPlanets::showTopocentricCoords(const dms &az, const dms &el)
153{
154 AzBox->show(az);
155 AltBox->show(el);
156}
157
158void modCalcPlanets::slotPlanetsCheckedBatch()
159{
160 PlanetComboBoxBatch->setEnabled(!PlanetCheckBatch->isChecked());
161}
162
163void modCalcPlanets::slotUtCheckedBatch()
164{
165 UTBoxBatch->setEnabled(!UTCheckBatch->isChecked());
166}
167
168void modCalcPlanets::slotDateCheckedBatch()
169{
170 DateBoxBatch->setEnabled(!DateCheckBatch->isChecked());
171}
172
173void modCalcPlanets::slotLongCheckedBatch()
174{
175 LongBoxBatch->setEnabled(!LongCheckBatch->isChecked());
176}
177
178void modCalcPlanets::slotLatCheckedBatch()
179{
180 LatBoxBatch->setEnabled(!LatCheckBatch->isChecked());
181}
182
183void modCalcPlanets::slotRunBatch()
184{
185 const QString inputFileName = InputFileBoxBatch->url().toLocalFile();
186
187 // We open the input file and read its content
188
189 if (QFile::exists(inputFileName))
190 {
191 QFile f(inputFileName);
192 if (!f.open(QIODevice::ReadOnly))
193 {
194 QString message = i18n("Could not open file %1.", f.fileName());
195 KSNotification::sorry(message, i18n("Could Not Open File"));
196 return;
197 }
198
199 QTextStream istream(&f);
200 processLines(istream);
201 f.close();
202 }
203 else
204 {
205 QString message = i18n("Invalid file: %1", inputFileName);
206 KSNotification::sorry(message, i18n("Invalid file"));
207 InputFileBoxBatch->setUrl(QUrl());
208 }
209}
210
211unsigned int modCalcPlanets::requiredBatchFields()
212{
213 unsigned int i = 0;
214
215 if (PlanetCheckBatch->isChecked())
216 i++;
217 if (UTCheckBatch->isChecked())
218 i++;
219 if (DateCheckBatch->isChecked())
220 i++;
221 if (LongCheckBatch->isChecked())
222 i++;
223 if (LatCheckBatch->isChecked())
224 i++;
225
226 return i;
227}
228
230{
231 // we open the output file
232
233 const QString outputFileName = OutputFileBoxBatch->url().toLocalFile();
234 QFile fOut(outputFileName);
236 QTextStream ostream(&fOut);
237 bool lineIsValid = true;
238
239 QChar space = ' ';
240 QString planetB;
241 unsigned int i = 0, nline = 0;
242 QTime utB;
243 QDate dtB;
244 CachingDms longB, latB, hlongB, hlatB, glongB, glatB, raB, decB, azmB, altB;
245 double rSunB(0.0), rEarthB(0.0);
246
247 //Initialize planet names
248 QString pn;
249 QStringList pNames, pNamesi18n;
250 pNames << "Mercury"
251 << "Venus"
252 << "Earth"
253 << "Mars"
254 << "Jupiter"
255 << "Saturn"
256 << "Uranus"
257 << "Neptune" /* << "Pluto" */
258 << "Sun"
259 << "Moon";
260 pNamesi18n << i18n("Mercury") << i18n("Venus") << i18n("Earth") << i18n("Mars") << i18n("Jupiter") << i18n("Saturn")
261 << i18n("Uranus") << i18n("Neptune") /* << i18nc("Asteroid name (optional)", "Pluto") */
262 << i18n("Sun") << i18n("Moon");
263
264 ///Parse the input file
265 int numberOfRequiredFields = requiredBatchFields();
266 while (!istream.atEnd())
267 {
268 QString lineToWrite;
269 QString line = istream.readLine();
270 line = line.trimmed();
271
272 //Go through the line, looking for parameters
273
274 QStringList fields = line.split(' ');
275
276 if (fields.count() != numberOfRequiredFields)
277 {
278 lineIsValid = false;
279 qWarning() << i18n("Incorrect number of fields in line %1: ", nline)
280 << i18n("Present fields %1. ", fields.count())
281 << i18n("Required fields %1. ", numberOfRequiredFields);
282 nline++;
283 continue;
284 }
285
286 i = 0;
287 if (PlanetCheckBatch->isChecked())
288 {
289 planetB = fields[i];
290 int j = pNamesi18n.indexOf(planetB);
291 if (j == -1)
292 {
293 qWarning() << i18n("Unknown planet ") << fields[i] << i18n(" in line %1: ", nline);
294 continue;
295 }
296 pn = pNames.at(j); //untranslated planet name
297 i++;
298 }
299 else
300 {
301 planetB = PlanetComboBoxBatch->currentText();
302 }
303 if (AllRadioBatch->isChecked() || PlanetCheckBatch->isChecked())
304 {
305 lineToWrite = planetB;
306 lineToWrite += space;
307 }
308
309 // Read Ut and write in ostream if corresponds
310 if (UTCheckBatch->isChecked())
311 {
312 utB = QTime::fromString(fields[i]);
313 if (!utB.isValid())
314 {
315 qWarning() << i18n("Line %1 contains an invalid time", nline);
316 lineIsValid = false;
317 nline++;
318 continue;
319 }
320 i++;
321 }
322 else
323 {
324 utB = UTBoxBatch->time();
325 }
326 if (AllRadioBatch->isChecked() || UTCheckBatch->isChecked())
327 lineToWrite += QLocale().toString(utB).append(space);
328
329 // Read date and write in ostream if corresponds
330 if (DateCheckBatch->isChecked())
331 {
332 dtB = QDate::fromString(fields[i], Qt::ISODate);
333 if (!dtB.isValid())
334 {
335 qWarning() << i18n("Line %1 contains an invalid date: ", nline) << fields[i];
336 lineIsValid = false;
337 nline++;
338 continue;
339 }
340 i++;
341 }
342 else
343 {
344 dtB = DateBoxBatch->date();
345 }
346 if (AllRadioBatch->isChecked() || DateCheckBatch->isChecked())
347 lineToWrite += QLocale().toString(dtB, QLocale::LongFormat).append(space);
348
349 // Read Longitude and write in ostream if corresponds
350
351 if (LongCheckBatch->isChecked())
352 {
353 longB = CachingDms::fromString(fields[i], true);
354 i++;
355 }
356 else
357 {
358 longB = LongBoxBatch->createDms();
359 }
360 if (AllRadioBatch->isChecked() || LongCheckBatch->isChecked())
361 lineToWrite += longB.toDMSString() + space;
362
363 // Read Latitude
364 if (LatCheckBatch->isChecked())
365 {
366 latB = CachingDms::fromString(fields[i], true);
367 i++;
368 }
369 else
370 {
371 latB = LatBoxBatch->createDms();
372 }
373 if (AllRadioBatch->isChecked() || LatCheckBatch->isChecked())
374 lineToWrite += latB.toDMSString() + space;
375
376 KStarsDateTime edt(dtB, utB);
377 CachingDms LST = edt.gst() + longB;
378
379 KSNumbers num(edt.djd());
380 KSPlanet Earth(i18n("Earth"));
381 Earth.findPosition(&num);
382
383 // FIXME: allocate new object for every iteration is probably not wisest idea.
384 KSPlanetBase *kspb = nullptr;
385 /*if ( pn == "Pluto" ) {
386 kspb = new KSPluto();
387 } else*/
388 if (pn == i18n("Sun"))
389 {
390 kspb = new KSSun();
391 }
392 else if (pn == i18n("Moon"))
393 {
394 kspb = new KSMoon();
395 }
396 else
397 {
398 kspb = new KSPlanet(i18n(pn.toLocal8Bit()), QString(), Qt::white, 1.0);
399 }
400 kspb->findPosition(&num, &latB, &LST, &Earth);
401 kspb->EquatorialToHorizontal(&LST, &latB);
402
403 // Heliocentric Ecl. coords.
404 hlongB = kspb->helEcLong();
405 hlatB = kspb->helEcLat();
406 rSunB = kspb->rsun();
407 // Geocentric Ecl. coords.
408 glongB = kspb->ecLong();
409 glatB = kspb->ecLat();
410 rEarthB = kspb->rearth();
411 // Equatorial coords.
412 decB = kspb->dec();
413 raB = kspb->ra();
414 // Topocentric Coords.
415 azmB = kspb->az();
416 altB = kspb->alt();
417
418 ostream << lineToWrite;
419
420 if (HelioEclCheckBatch->isChecked())
421 ostream << hlongB.toDMSString() << space << hlatB.toDMSString() << space << rSunB << space;
422 if (GeoEclCheckBatch->isChecked())
423 ostream << glongB.toDMSString() << space << glatB.toDMSString() << space << rEarthB << space;
424 if (EquatorialCheckBatch->isChecked())
425 ostream << raB.toHMSString() << space << decB.toDMSString() << space;
426 if (HorizontalCheckBatch->isChecked())
427 ostream << azmB.toDMSString() << space << altB.toDMSString() << space;
428 ostream << '\n';
429
430 // Delete object
431 delete kspb;
432
433 nline++;
434 }
435
436 if (!lineIsValid)
437 {
438 QString message = i18n("Errors found while parsing some lines in the input file");
439 KSNotification::sorry(message, i18n("Errors in lines"));
440 }
441
442 fOut.close();
443}
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition cachingdms.h:19
static CachingDms fromString(const QString &s, bool deg)
Construct an angle from the given string.
QString fullName() const
const CachingDms * lat() const
Definition geolocation.h:70
Provides necessary information about the Moon.
Definition ksmoon.h:26
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
A subclass of TrailObject that provides additional information needed for most solar system objects.
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.
const dms & helEcLat() const
const dms & helEcLong() const
const dms & ecLat() const
const dms & ecLong() const
double rearth() const
double rsun() const
A subclass of KSPlanetBase for seven of the major planets in the solar system (Earth and Pluto have t...
Definition ksplanet.h:33
Child class of KSPlanetBase; encapsulates information about the Sun.
Definition kssun.h:24
GeoLocation * geo()
Definition kstarsdata.h:232
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.
const CachingDms & dec() const
Definition skypoint.h:269
const CachingDms & ra() const
Definition skypoint.h:263
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition skypoint.cpp:77
const dms & az() const
Definition skypoint.h:275
const dms & alt() const
Definition skypoint.h:281
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
const QString toDMSString(const bool forceSign=false, const bool machineReadable=false, const bool highPrecision=false) const
Definition dms.cpp:287
const QString toHMSString(const bool machineReadable=false, const bool highPrecision=false) const
Definition dms.cpp:378
void processLines(QTextStream &istream)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
QDate fromString(QStringView string, QStringView format, QCalendar cal)
bool isValid(int year, int month, int day)
bool exists() const const
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
virtual void close() override
const_reference at(qsizetype i) const const
QString toString(QDate date, FormatType format) const const
QString & append(QChar ch)
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QByteArray toLocal8Bit() const const
QString trimmed() const const
qsizetype indexOf(const QRegularExpression &re, qsizetype from) const const
bool atEnd() const const
QString readLine(qint64 maxlen)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QTime fromString(QStringView string, QStringView format)
bool isValid(int h, int m, int s, int ms)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:04:47 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.