Kstars

modcalcplanets.cpp
1 /*
2  SPDX-FileCopyrightText: 2004-2005 Pablo de Vicente <[email protected]>
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 
16 modCalcPlanets::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 
46 void modCalcPlanets::slotLocation()
47 {
48  QPointer<LocationDialog> ld = new LocationDialog(this);
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 
59 void 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 
124 void 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 
132 void 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 
139 void 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 
146 void modCalcPlanets::showEquatorialCoords(const dms &ra, const dms &dec)
147 {
148  RABox->show(ra);
149  DecBox->show(dec);
150 }
151 
152 void modCalcPlanets::showTopocentricCoords(const dms &az, const dms &el)
153 {
154  AzBox->show(az);
155  AltBox->show(el);
156 }
157 
158 void modCalcPlanets::slotPlanetsCheckedBatch()
159 {
160  PlanetComboBoxBatch->setEnabled(!PlanetCheckBatch->isChecked());
161 }
162 
163 void modCalcPlanets::slotUtCheckedBatch()
164 {
165  UTBoxBatch->setEnabled(!UTCheckBatch->isChecked());
166 }
167 
168 void modCalcPlanets::slotDateCheckedBatch()
169 {
170  DateBoxBatch->setEnabled(!DateCheckBatch->isChecked());
171 }
172 
173 void modCalcPlanets::slotLongCheckedBatch()
174 {
175  LongBoxBatch->setEnabled(!LongCheckBatch->isChecked());
176 }
177 
178 void modCalcPlanets::slotLatCheckedBatch()
179 {
180  LatBoxBatch->setEnabled(!LatCheckBatch->isChecked());
181 }
182 
183 void 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 
211 unsigned 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 }
const dms & alt() const
Definition: skypoint.h:281
static KStarsDateTime currentDateTime()
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
const dms & helEcLong() const
Definition: ksplanetbase.h:109
long double djd() const
QString fullName() const
Definition: geolocation.cpp:46
QTime fromString(const QString &string, Qt::DateFormat format)
virtual bool open(QIODevice::OpenMode mode) override
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition: cachingdms.h:18
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
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.
QString trimmed() const const
double rsun() const
Definition: ksplanetbase.h:130
bool isValid() const const
double rearth() const
Definition: ksplanetbase.h:139
const dms & helEcLat() const
Definition: ksplanetbase.h:112
bool exists() const const
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
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
const QString toHMSString(const bool machineReadable=false, const bool highPrecision=false) const
Definition: dms.cpp:370
Provides necessary information about the Moon. A subclass of SkyObject that provides information need...
Definition: ksmoon.h:25
Provides necessary information about the Sun.
Definition: kssun.h:23
QString i18n(const char *text, const TYPE &arg...)
const QString toDMSString(const bool forceSign=false, const bool machineReadable=false, const bool highPrecision=false) const
Definition: dms.cpp:279
Store several time-dependent astronomical quantities.
Definition: ksnumbers.h:42
const CachingDms & dec() const
Definition: skypoint.h:269
const CachingDms * lat() const
Definition: geolocation.h:70
bool atEnd() const const
char * toString(const T &value)
const dms & ecLong() const
Definition: ksplanetbase.h:91
GeoLocation * geo()
Definition: kstarsdata.h:229
QString readLine(qint64 maxlen)
const T & at(int i) const const
QString toString(qlonglong i) const const
bool isValid() const const
virtual void close() override
void setupUi(QWidget *widget)
int indexOf(QStringView str, int from) const const
Provides necessary information about objects in the solar system.
Definition: ksplanet.h:32
void show()
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
QDate fromString(const QString &string, Qt::DateFormat format)
static CachingDms fromString(const QString &s, bool deg)
Construct an angle from the given string.
Definition: cachingdms.cpp:121
const CachingDms & ra() const
Definition: skypoint.h:263
void processLines(QTextStream &istream)
QByteArray toLocal8Bit() const const
const dms & ecLat() const
Definition: ksplanetbase.h:94
QString message
QString & append(QChar ch)
Provides necessary information about objects in the solar system.
Definition: ksplanetbase.h:49
const dms & az() const
Definition: skypoint.h:275
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Aug 8 2022 04:13:23 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.