Kstars

eyepiecefield.cpp
1 /*
2  SPDX-FileCopyrightText: 2014 Akarsh Simha <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "eyepiecefield.h"
8 
9 #include "exporteyepieceview.h"
10 #include "fov.h"
11 #include "ksdssdownloader.h"
12 #include "kstars.h"
13 #include "ksnotification.h"
14 #include "Options.h"
15 #include "skymap.h"
16 #include "skyqpainter.h"
17 
18 #include <QBitmap>
19 #include <QCheckBox>
20 #include <QComboBox>
21 #include <QHBoxLayout>
22 #include <QLabel>
23 #include <QPushButton>
24 #include <QSlider>
25 #include <QSvgGenerator>
26 #include <QSvgRenderer>
27 #include <QVBoxLayout>
28 
29 #include <kstars_debug.h>
30 
32 {
33 #ifdef Q_OS_OSX
35 #endif
36 
37  setWindowTitle(i18nc("@title:window", "Eyepiece Field View"));
38 
39  m_sp = nullptr;
40  m_dt = nullptr;
41  m_currentFOV = nullptr;
42  m_fovWidth = m_fovHeight = 0;
43  m_dler = nullptr;
44 
45  QWidget *mainWidget = new QWidget(this);
46  QVBoxLayout *mainLayout = new QVBoxLayout;
47  mainLayout->addWidget(mainWidget);
48  setLayout(mainLayout);
49 
51  buttonBox->addButton(i18nc("Export image", "Export"), QDialogButtonBox::AcceptRole);
52  mainLayout->addWidget(buttonBox);
53  connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
54  connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotExport()));
55 
56  QVBoxLayout *rows = new QVBoxLayout;
57  mainWidget->setLayout(rows);
58 
59  m_skyChartDisplay = new QLabel;
60  m_skyChartDisplay->setBackgroundRole(QPalette::Base);
61  m_skyChartDisplay->setScaledContents(false);
62  m_skyChartDisplay->setMinimumWidth(400);
63 
64  m_skyImageDisplay = new QLabel;
65  m_skyImageDisplay->setBackgroundRole(QPalette::Base);
66  m_skyImageDisplay->setScaledContents(false);
67  m_skyImageDisplay->setMinimumWidth(400);
69 
70  QHBoxLayout *imageLayout = new QHBoxLayout;
71  rows->addLayout(imageLayout);
72  imageLayout->addWidget(m_skyChartDisplay);
73  imageLayout->addWidget(m_skyImageDisplay);
74 
75  m_invertView = new QCheckBox(i18n("Invert view"), this);
76  m_flipView = new QCheckBox(i18n("Flip view"), this);
77  m_overlay = new QCheckBox(i18n("Overlay"), this);
78  m_invertColors = new QCheckBox(i18n("Invert colors"), this);
79  m_getDSS = new QPushButton(i18n("Fetch DSS image"), this);
80 
81  m_getDSS->setVisible(false);
82 
83  QHBoxLayout *optionsLayout = new QHBoxLayout;
84  optionsLayout->addWidget(m_invertView);
85  optionsLayout->addWidget(m_flipView);
86  optionsLayout->addStretch();
87  optionsLayout->addWidget(m_overlay);
88  optionsLayout->addWidget(m_invertColors);
89  optionsLayout->addWidget(m_getDSS);
90 
91  rows->addLayout(optionsLayout);
92 
93  m_rotationSlider = new QSlider(Qt::Horizontal, this);
94  m_rotationSlider->setMaximum(180);
95  m_rotationSlider->setMinimum(-180);
96  m_rotationSlider->setTickInterval(30);
97  m_rotationSlider->setPageStep(30);
98 
99  QLabel *sliderLabel = new QLabel(i18n("Rotation:"), this);
100 
101  m_presetCombo = new QComboBox(this);
102  m_presetCombo->addItem(i18n("None"));
103  m_presetCombo->addItem(i18n("Vanilla"));
104  m_presetCombo->addItem(i18n("Flipped"));
105  m_presetCombo->addItem(i18n("Refractor"));
106  m_presetCombo->addItem(i18n("Dobsonian"));
107 
108  QLabel *presetLabel = new QLabel(i18n("Preset:"), this);
109 
110  QHBoxLayout *rotationLayout = new QHBoxLayout;
111  rotationLayout->addWidget(sliderLabel);
112  rotationLayout->addWidget(m_rotationSlider);
113  rotationLayout->addWidget(presetLabel);
114  rotationLayout->addWidget(m_presetCombo);
115 
116  rows->addLayout(rotationLayout);
117 
118  connect(m_invertView, SIGNAL(stateChanged(int)), this, SLOT(render()));
119  connect(m_flipView, SIGNAL(stateChanged(int)), this, SLOT(render()));
120  connect(m_invertColors, SIGNAL(stateChanged(int)), this, SLOT(render()));
121  connect(m_overlay, SIGNAL(stateChanged(int)), this, SLOT(render()));
122  connect(m_rotationSlider, SIGNAL(valueChanged(int)), this, SLOT(render()));
123  connect(m_presetCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotEnforcePreset(int)));
124  connect(m_presetCombo, SIGNAL(activated(int)), this, SLOT(slotEnforcePreset(int)));
125  connect(m_getDSS, SIGNAL(clicked()), this, SLOT(slotDownloadDss()));
126 }
127 
129 {
130  if (index == -1)
131  index = m_presetCombo->currentIndex();
132  if (index == -1)
133  index = 0;
134 
135  if (index == 0)
136  return; // Preset "None" makes no changes
137 
138  double altAzRot = (m_usedAltAz ? 0.0 : findNorthAngle(m_sp, KStarsData::Instance()->geo()->lat()).Degrees());
139  if (altAzRot > 180.0)
140  altAzRot -= 360.0;
141  double dobRot = altAzRot - m_sp->alt().Degrees(); // set rotation to altitude CW
142  if (dobRot > 180.0)
143  dobRot -= 360.0;
144  if (dobRot < -180.0)
145  dobRot += 360.0;
146  switch (index)
147  {
148  case 1:
149  // Preset vanilla
150  m_rotationSlider->setValue(0.0); // reset rotation
151  m_invertView->setChecked(false); // reset inversion
152  m_flipView->setChecked(false); // reset flip
153  break;
154  case 2:
155  // Preset flipped
156  m_rotationSlider->setValue(0.0); // reset rotation
157  m_invertView->setChecked(false); // reset inversion
158  m_flipView->setChecked(true); // set flip
159  break;
160  case 3:
161  // Preset refractor
162  m_rotationSlider->setValue(altAzRot);
163  m_invertView->setChecked(true);
164  m_flipView->setChecked(false);
165  break;
166  case 4:
167  // Preset Dobsonian
168  m_rotationSlider->setValue(dobRot); // set rotation for dob
169  m_invertView->setChecked(true); // set inversion
170  m_flipView->setChecked(false);
171  break;
172  default:
173  break;
174  }
175 }
176 
177 void EyepieceField::showEyepieceField(SkyPoint *sp, FOV const *const fov, const QString &imagePath)
178 {
179  double fovWidth, fovHeight;
180 
181  Q_ASSERT(sp);
182 
183  // See if we were supplied a sky image; if so, load its metadata
184  // Set up the new sky map FOV and pointing. full map FOV = 4 times the given FOV.
185  if (fov)
186  {
187  fovWidth = fov->sizeX();
188  fovHeight = fov->sizeY();
189  }
190  else if (QFile::exists(imagePath))
191  {
192  fovWidth = fovHeight = -1.0; // figure out from the image.
193  }
194  else
195  {
196  //Q_ASSERT( false );
197  // Don't crash the program
198  KSNotification::error(i18n(("No image found. Please specify the exact FOV.")));
199  return;
200  }
201 
202  showEyepieceField(sp, fovWidth, fovHeight, imagePath);
203  m_currentFOV = fov;
204 }
205 
206 void EyepieceField::showEyepieceField(SkyPoint *sp, const double fovWidth, double fovHeight, const QString &imagePath)
207 {
208  if (m_skyChart.get() == nullptr)
209  m_skyChart.reset(new QImage());
210 
211  if (QFile::exists(imagePath))
212  {
213  qCDebug(KSTARS) << "Image path " << imagePath << " exists";
214  if (m_skyImage.get() == nullptr)
215  {
216  qCDebug(KSTARS) << "Sky image did not exist, creating.";
217  m_skyImage.reset(new QImage());
218  }
219  }
220  else
221  {
222  m_skyImage.reset();
223  }
224 
225  m_usedAltAz = Options::useAltAz();
226  generateEyepieceView(sp, m_skyChart.get(), m_skyImage.get(), fovWidth, fovHeight, imagePath);
227 
228  // Keep a copy for local purposes (computation of field rotation etc.)
229  if (m_sp != sp)
230  {
231  if (m_sp)
232  delete m_sp;
233  m_sp = new SkyPoint(*sp);
234  }
235 
236  // Update our date/time
237  delete m_dt;
238  m_dt = new KStarsDateTime(KStarsData::Instance()->ut());
239 
240  // Enforce preset as per selection, since we have loaded a new eyepiece view
241  slotEnforcePreset(-1);
242  // Render the display
243  render();
244  m_fovWidth = fovWidth;
245  m_fovHeight = fovHeight;
246  m_currentFOV = nullptr;
247 }
248 
249 void EyepieceField::generateEyepieceView(SkyPoint *sp, QImage *skyChart, QImage *skyImage, const FOV *fov,
250  const QString &imagePath)
251 {
252  if (fov)
253  {
254  generateEyepieceView(sp, skyChart, skyImage, fov->sizeX(), fov->sizeY(), imagePath);
255  }
256  else
257  {
258  generateEyepieceView(sp, skyChart, skyImage, -1.0, -1.0, imagePath);
259  }
260 }
261 
262 void EyepieceField::generateEyepieceView(SkyPoint *sp, QImage *skyChart, QImage *skyImage, double fovWidth,
263  double fovHeight, const QString &imagePath)
264 {
265  SkyMap *map = SkyMap::Instance();
266  KStars *ks = KStars::Instance();
267 
268  Q_ASSERT(sp);
269  Q_ASSERT(map);
270  Q_ASSERT(ks);
271  Q_ASSERT(skyChart);
272 
273  if (!skyChart)
274  return;
275 
276  if (!map) // Requires initialization of Sky map.
277  return;
278 
279  if (fovWidth <= 0)
280  {
281  if (!QFile::exists(imagePath))
282  return;
283  // Otherwise, we will assume that the user wants the FOV of the image and we'll try to guess it from there
284  }
285  if (fovHeight <= 0)
286  fovHeight = fovWidth;
287 
288  // Get DSS image width / height
289  double dssWidth = 0, dssHeight = 0;
290 
291  if (QFile::exists(imagePath))
292  {
293  KSDssImage dssImage(imagePath);
294  dssWidth = dssImage.getMetadata().width;
295  dssHeight = dssImage.getMetadata().height;
296  if (!dssImage.getMetadata().isValid() || dssWidth == 0 || dssHeight == 0)
297  {
298  // Metadata unavailable, guess based on most common DSS arcsec/pixel
299  //const double dssArcSecPerPixel = 1.01;
300  dssWidth = dssImage.getImage().width() * 1.01 / 60.0;
301  dssHeight = dssImage.getImage().height() * 1.01 / 60.0;
302  }
303  qCDebug(KSTARS) << "DSS width: " << dssWidth << " height: " << dssHeight;
304  }
305 
306  // Set FOV width/height from DSS if necessary
307  if (fovWidth <= 0)
308  {
309  fovWidth = dssWidth;
310  fovHeight = dssHeight;
311  }
312 
313  // Grab the sky chart
314  // Save the current state of the sky map
315  SkyPoint *oldFocus = map->focus();
316  double oldZoomFactor = Options::zoomFactor();
317 
318  // Set the right zoom
319  ks->setApproxFOV(((fovWidth > fovHeight) ? fovWidth : fovHeight) / 15.0);
320 
321  // map->setFocus( sp ); // FIXME: Why does setFocus() need a non-const SkyPoint pointer?
322  KStarsData *const data = KStarsData::Instance();
323  sp->updateCoords(data->updateNum(), true, data->geo()->lat(), data->lst(), false);
324  map->setClickedPoint(sp);
325  map->slotCenter();
326  qApp->processEvents();
327 
328  // Repeat -- dirty workaround for some problem in KStars
329  map->setClickedPoint(sp);
330  map->slotCenter();
331  qApp->processEvents();
332 
333  // determine screen arcminutes per pixel value
334  const double arcMinToScreen = dms::PI * Options::zoomFactor() / 10800.0;
335 
336  // Vector export
337  QTemporaryFile myTempSvgFile;
338  myTempSvgFile.open();
339 
340  // export as SVG
341  QSvgGenerator svgGenerator;
342  svgGenerator.setFileName(myTempSvgFile.fileName());
343  // svgGenerator.setTitle(i18n(""));
344  // svgGenerator.setDescription(i18n(""));
345  svgGenerator.setSize(QSize(map->width(), map->height()));
346  svgGenerator.setResolution(qMax(map->logicalDpiX(), map->logicalDpiY()));
347  svgGenerator.setViewBox(QRect(map->width() / 2.0 - arcMinToScreen * fovWidth / 2.0,
348  map->height() / 2.0 - arcMinToScreen * fovHeight / 2.0, arcMinToScreen * fovWidth,
349  arcMinToScreen * fovHeight));
350 
351  SkyQPainter painter(KStars::Instance(), &svgGenerator);
352  painter.begin();
353 
354  map->exportSkyImage(&painter);
355 
356  painter.end();
357 
358  // Render SVG file on raster QImage canvas
359  QSvgRenderer svgRenderer(myTempSvgFile.fileName());
360  QImage *mySkyChart = new QImage(arcMinToScreen * fovWidth * 2.0, arcMinToScreen * fovHeight * 2.0,
361  QImage::Format_ARGB32); // 2 times bigger in both dimensions.
362  QPainter p2(mySkyChart);
363  svgRenderer.render(&p2);
364  p2.end();
365  *skyChart = *mySkyChart;
366  delete mySkyChart;
367 
368  myTempSvgFile.close();
369 
370  // Reset the sky-map
371  map->setZoomFactor(oldZoomFactor);
372  map->setClickedPoint(oldFocus);
373  map->slotCenter();
374  qApp->processEvents();
375 
376  // Repeat -- dirty workaround for some problem in KStars
377  map->setZoomFactor(oldZoomFactor);
378  map->setClickedPoint(oldFocus);
379  map->slotCenter();
380  qApp->processEvents();
381  map->forceUpdate();
382 
383  // Prepare the sky image
384  if (QFile::exists(imagePath) && skyImage)
385  {
386  QImage *mySkyImage = new QImage(int(arcMinToScreen * fovWidth * 2.0), int(arcMinToScreen * fovHeight * 2.0),
388 
389  mySkyImage->fill(Qt::transparent);
390 
391  QPainter p(mySkyImage);
392  QImage rawImg(imagePath);
393 
394  if (rawImg.isNull())
395  {
396  qWarning() << "Image constructed from " << imagePath
397  << "is a null image! Are you sure you supplied an image file? Continuing nevertheless...";
398  }
399 
400  QImage img = rawImg.scaled(arcMinToScreen * dssWidth * 2.0, arcMinToScreen * dssHeight * 2.0,
402  const auto ksd = KStarsData::Instance();
403  sp->updateCoordsNow(ksd->updateNum());
404 
405  if (Options::useAltAz())
406  {
407  // Need to rotate the image so that up is towards zenith rather than north.
408  sp->EquatorialToHorizontal(ksd->lst(), ksd->geo()->lat());
409  dms northBearing = findNorthAngle(sp, ksd->geo()->lat());
410  qCDebug(KSTARS) << "North angle = " << northBearing.toDMSString();
411 
412  QTransform transform;
413 
414  transform.rotate(northBearing.Degrees());
415  img = img.transformed(transform, Qt::SmoothTransformation);
416  }
417  p.drawImage(
418  QPointF(mySkyImage->width() / 2.0 - img.width() / 2.0, mySkyImage->height() / 2.0 - img.height() / 2.0),
419  img);
420  p.end();
421 
422  *skyImage = *mySkyImage;
423  delete mySkyImage;
424  }
425 }
426 
427 void EyepieceField::renderEyepieceView(const QImage *skyChart, QPixmap *renderChart, const double rotation,
428  const double scale, const bool flip, const bool invert, const QImage *skyImage,
429  QPixmap *renderImage, const bool overlay, const bool invertColors)
430 {
431  QTransform transform;
432  bool deleteRenderImage = false;
433  transform.rotate(rotation);
434  if (flip)
435  transform.scale(-1, 1);
436  if (invert)
437  transform.scale(-1, -1);
438  transform.scale(scale, scale);
439 
440  Q_ASSERT(skyChart && renderChart);
441  if (!skyChart || !renderChart)
442  return;
443 
444  *renderChart = QPixmap::fromImage(skyChart->transformed(transform, Qt::SmoothTransformation));
445 
446  if (skyImage)
447  {
448  Q_ASSERT(overlay || renderImage); // in debug mode, check for calls that supply skyImage but not renderImage
449  }
450  if (overlay && !renderImage)
451  {
452  renderImage = new QPixmap(); // temporary, used for rendering skymap before overlay is done.
453  deleteRenderImage = true; // we created it, so we must delete it.
454  }
455 
456  if (skyImage && renderImage)
457  {
458  if (skyImage->isNull())
459  qWarning() << "Sky image supplied to renderEyepieceView() for rendering is a Null image!";
460  QImage i;
461  i = skyImage->transformed(transform, Qt::SmoothTransformation);
462  if (invertColors)
463  i.invertPixels();
464  *renderImage = QPixmap::fromImage(i);
465  }
466  if (overlay && skyImage)
467  {
468  QColor skyColor = KStarsData::Instance()->colorScheme()->colorNamed("SkyColor");
470  skyChart->createMaskFromColor(skyColor.rgb()).transformed(transform, Qt::SmoothTransformation));
471  renderChart->setMask(mask);
472  QPainter p(renderImage);
473  p.drawImage(QPointF(renderImage->width() / 2.0 - renderChart->width() / 2.0,
474  renderImage->height() / 2.0 - renderChart->height() / 2.0),
475  renderChart->toImage());
476  QPixmap temp(renderImage->width(), renderImage->height());
477  temp.fill(skyColor);
478  QPainter p2(&temp);
479  p2.drawImage(QPointF(0, 0), renderImage->toImage());
480  p2.end();
481  p.end();
482  *renderChart = *renderImage = temp;
483  }
484  if (deleteRenderImage)
485  delete renderImage;
486 }
487 
488 void EyepieceField::renderEyepieceView(SkyPoint *sp, QPixmap *renderChart, double fovWidth, double fovHeight,
489  const double rotation, const double scale, const bool flip, const bool invert,
490  const QString &imagePath, QPixmap *renderImage, const bool overlay,
491  const bool invertColors)
492 {
493  QImage *skyChart, *skyImage = nullptr;
494  skyChart = new QImage();
495  if (QFile::exists(imagePath) && (renderImage || overlay))
496  skyImage = new QImage();
497  generateEyepieceView(sp, skyChart, skyImage, fovWidth, fovHeight, imagePath);
498  renderEyepieceView(skyChart, renderChart, rotation, scale, flip, invert, skyImage, renderImage, overlay,
499  invertColors);
500  delete skyChart;
501  delete skyImage;
502 }
503 
505 {
506  double rotation = m_rotationSlider->value();
507  bool flip = m_flipView->isChecked();
508  bool invert = m_invertView->isChecked();
509  bool invertColors = m_invertColors->isChecked();
510  bool overlay = m_overlay->isChecked() && m_skyImage.get();
511 
512  Q_ASSERT(m_skyChart.get());
513 
514  renderEyepieceView(m_skyChart.get(), &m_renderChart, rotation, 1.0, flip, invert, m_skyImage.get(), &m_renderImage,
515  overlay, invertColors);
516 
517  m_skyChartDisplay->setVisible(!overlay);
518  if (m_skyImage.get() != nullptr)
519  {
520  m_skyImageDisplay->setVisible(true);
521  m_overlay->setVisible(true);
522  m_invertColors->setVisible(true);
523  m_getDSS->setVisible(false);
524  }
525  else
526  {
527  m_skyImageDisplay->setVisible(false);
528  m_overlay->setVisible(false);
529  m_invertColors->setVisible(false);
530  m_getDSS->setVisible(true);
531  }
532 
533  if (!overlay)
534  m_skyChartDisplay->setPixmap(m_renderChart.scaled(m_skyChartDisplay->width(), m_skyChartDisplay->height(),
536  if (m_skyImage.get() != nullptr)
537  m_skyImageDisplay->setPixmap(m_renderImage.scaled(m_skyImageDisplay->width(), m_skyImageDisplay->height(),
539 
540  update();
541  show();
542 }
543 
544 void EyepieceField::slotDownloadDss()
545 {
546  double fovWidth = 0, fovHeight = 0;
547  if (m_fovWidth == 0 && m_currentFOV == nullptr)
548  {
549  fovWidth = fovHeight = 15.0;
550  }
551  else if (m_currentFOV)
552  {
553  fovWidth = m_currentFOV->sizeX();
554  fovHeight = m_currentFOV->sizeY();
555  }
556  if (!m_dler)
557  {
558  m_dler = new KSDssDownloader(this);
559  connect(m_dler, SIGNAL(downloadComplete(bool)), SLOT(slotDssDownloaded(bool)));
560  }
562  m_tempFile.open();
563  QUrl srcUrl = QUrl(KSDssDownloader::getDSSURL(m_sp, fovWidth, fovHeight, "all", &md));
564  m_dler->startSingleDownload(srcUrl, m_tempFile.fileName(), md);
565  m_tempFile.close();
566 }
567 
568 void EyepieceField::slotDssDownloaded(bool success)
569 {
570  if (!success)
571  {
572  KSNotification::sorry(i18n("Failed to download DSS/SDSS image."));
573  return;
574  }
575  else
576  showEyepieceField(m_sp, m_fovWidth, m_fovHeight, m_tempFile.fileName());
577 }
578 
580 {
581  bool overlay = m_overlay->isChecked() && m_skyImage.get();
582  new ExportEyepieceView(m_sp, *m_dt, ((m_skyImage.get() && !overlay) ? &m_renderImage : nullptr),
583  &m_renderChart, this);
584 }
585 
587 {
588  Q_ASSERT(sp && lat);
589 
590  // NOTE: northAngle1 is the correction due to lunisolar precession
591  // (needs testing and checking). northAngle2 is the correction due
592  // to going from equatorial to horizontal coordinates.
593 
594  // FIXME: The following code is a guess at how to handle
595  // precession. While it might work in many cases, it might fail in
596  // some. Careful testing will be needed to ensure that all
597  // conditions are met, esp. with getting the signs right when
598  // using arccosine! Nutation and planetary precession corrections
599  // have not been included. -- asimha
600  // TODO: Look at the Meeus book and see if it has some formulas -- asimha
601  const double equinoxPrecessionPerYear =
602  (50.35 /
603  3600.0); // Equinox precession in ecliptic longitude per year in degrees (ref: http://star-www.st-and.ac.uk/~fv/webnotes/chapt16.htm)
604  dms netEquinoxPrecession(((sp->getLastPrecessJD() - J2000) / 365.25) * equinoxPrecessionPerYear);
605  double cosNorthAngle1 =
606  (netEquinoxPrecession.cos() - sp->dec0().sin() * sp->dec().sin()) / (sp->dec0().cos() * sp->dec().cos());
607  double northAngle1 = acos(cosNorthAngle1);
608  if (sp->getLastPrecessJD() < J2000)
609  northAngle1 = -northAngle1;
610  if (sp->dec0().Degrees() < 0)
611  northAngle1 = -northAngle1;
612  // We trust that EquatorialToHorizontal has been called on sp, after all, how else can it have an alt/az representation.
613  // Use spherical cosine rule (the triangle with vertices at sp, zenith and NCP) to compute the angle between direction of increasing altitude and north
614  double cosNorthAngle2 = (lat->sin() - sp->alt().sin() * sp->dec().sin()) / (sp->alt().cos() * sp->dec().cos());
615  double northAngle2 = acos(cosNorthAngle2); // arccosine is blind to sign of the angle
616  if (sp->az().reduce().Degrees() < 180.0) // if on the eastern hemisphere, flip sign
617  northAngle2 = -northAngle2;
618  double northAngle = northAngle1 + northAngle2;
619  qCDebug(KSTARS) << "Data: alt = " << sp->alt().toDMSString() << "; az = " << sp->az().toDMSString() << "; ra, dec ("
620  << sp->getLastPrecessJD() / 365.25 << ") = " << sp->ra().toHMSString() << "," << sp->dec().toDMSString()
621  << "; ra0,dec0 (J2000.0) = " << sp->ra0().toHMSString() << "," << sp->dec0().toDMSString();
622  qCDebug(KSTARS) << "PA corrections: precession cosine = " << cosNorthAngle1 << "; angle = " << northAngle1
623  << "; horizontal = " << cosNorthAngle2 << "; angle = " << northAngle2;
624  return dms(northAngle * 180 / M_PI);
625 }
const dms & alt() const
Definition: skypoint.h:281
Definition: fov.h:27
double sin() const
Get the sine of this angle.
Definition: cachingdms.h:190
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
void begin() override
Begin painting.
The QPainter-based painting backend.
Definition: skyqpainter.h:28
static constexpr double PI
PI is a const static member; it's public so that it can be used anywhere, as long as dms....
Definition: dms.h:380
void setMinimum(int)
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
EyepieceField(QWidget *parent=nullptr)
Constructor.
QWidget(QWidget *parent, Qt::WindowFlags f)
void render(QPainter *painter)
int height() const const
void startSingleDownload(const QUrl srcUrl, const QString &destFileName, KSDssImage::Metadata &md)
Stateful single-download of a supplied URL.
virtual void reject()
void fill(uint pixelValue)
void setSizePolicy(QSizePolicy)
void setScaledContents(bool)
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
void setSize(const QSize &size)
Helps download a DSS image.
void update()
QRgb rgb() const const
CachingDms * lst()
Definition: kstarsdata.h:223
Structure to hold some DSS image metadata.
Definition: ksdssimage.h:35
void fill(const QColor &color)
static void renderEyepieceView(const QImage *skyChart, QPixmap *renderChart, const double rotation=0, const double scale=1.0, const bool flip=false, const bool invert=false, const QImage *skyImage=nullptr, QPixmap *renderImage=nullptr, const bool overlay=false, const bool invertColors=false)
Orients the eyepiece view as needed, performs overlaying etc.
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
void setChecked(bool)
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
void addStretch(int stretch)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setMaximum(int)
const QString toHMSString(const bool machineReadable=false, const bool highPrecision=false) const
Definition: dms.cpp:370
QImage transformed(const QMatrix &matrix, Qt::TransformationMode mode) const const
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags)
virtual QString fileName() const const override
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
static KStars * Instance()
Definition: kstars.h:125
void setValue(int)
Dialog to export the eyepiece view as an image, with some annotations for field-use.
double getLastPrecessJD() const
Definition: skypoint.h:294
virtual void setVisible(bool visible)
virtual void updateCoords(const KSNumbers *num, bool includePlanets=true, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, bool forceRecompute=false)
Determine the current coordinates (RA, Dec) from the catalog coordinates (RA0, Dec0),...
Definition: skypoint.cpp:582
void rejected()
bool end()
void setResolution(int dpi)
IgnoreAspectRatio
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
void setWindowFlags(Qt::WindowFlags type)
const CachingDms & dec() const
Definition: skypoint.h:269
const CachingDms * lat() const
Definition: geolocation.h:70
Provides a class to hold a DSS Image along with its metadata.
Definition: ksdssimage.h:20
ColorScheme * colorScheme()
Definition: kstarsdata.h:171
Horizontal
GeoLocation * geo()
Definition: kstarsdata.h:229
void setWindowTitle(const QString &)
bool isNull() const const
void setMask(const QBitmap &mask)
void setBackgroundRole(QPalette::ColorRole role)
float width
Width in arcminutes.
Definition: ksdssimage.h:79
void addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role)
double cos() const
Get the cosine of this angle.
Definition: cachingdms.h:204
virtual void updateCoordsNow(const KSNumbers *num)
updateCoordsNow Shortcut for updateCoords( const KSNumbers *num, false, nullptr, nullptr,...
Definition: skypoint.h:382
virtual void close() override
This is the main window for KStars. In addition to the GUI elements, the class contains the program c...
Definition: kstars.h:92
int height() const const
void render()
Re-renders the view Takes care of things like inverting colors, inverting orientation,...
QImage toImage() const const
double cos() const
Compute the Angle's Cosine.
Definition: dms.h:290
float height
Height in arcminutes.
Definition: ksdssimage.h:77
void show()
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
QPixmap scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
void setViewBox(const QRect &viewBox)
void setTickInterval(int ti)
const CachingDms & ra() const
Definition: skypoint.h:263
const CachingDms & dec0() const
Definition: skypoint.h:257
const double & Degrees() const
Definition: dms.h:141
Canvas widget for displaying the sky bitmap; also handles user interaction events.
Definition: skymap.h:52
QRegion mask() const const
void setFileName(const QString &fileName)
void end() override
End and finalize painting.
const CachingDms & ra0() const
Definition: skypoint.h:251
void invertPixels(QImage::InvertMode mode)
void showEyepieceField(SkyPoint *sp, FOV const *const fov=nullptr, const QString &imagePath=QString())
Show the eyepiece field dialog.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void addItem(const QString &text, const QVariant &userData)
void setMinimumWidth(int minw)
void addLayout(QLayout *layout, int stretch)
QImage createMaskFromColor(QRgb color, Qt::MaskMode mode) const const
void slotEnforcePreset(int index=-1)
Enforces a preset setting.
Q_SCRIPTABLE Q_NOREPLY void setApproxFOV(double FOV_Degrees)
DBUS interface function.
Definition: kstarsdbus.cpp:969
const dms reduce() const
return the equivalent angle between 0 and 360 degrees.
Definition: dms.cpp:251
double sin() const
Compute the Angle's Sine.
Definition: dms.h:258
void slotExport()
Save image.
void setLayout(QLayout *layout)
SmoothTransformation
void setPixmap(const QPixmap &)
QColor colorNamed(const QString &name) const
Retrieve a color by name.
Definition: colorscheme.cpp:86
static QString getDSSURL(const SkyPoint *const p, const QString &version="all", struct KSDssImage::Metadata *md=nullptr)
High-level method to create a URL to obtain a DSS image for a given SkyPoint.
static void generateEyepieceView(SkyPoint *sp, QImage *skyChart, QImage *skyImage=nullptr, double fovWidth=-1.0, double fovHeight=-1.0, const QString &imagePath=QString())
Generate the eyepiece field view and corresponding image view.
transparent
void setPageStep(int)
int width() const const
static dms findNorthAngle(const SkyPoint *sp, const dms *lat)
Finds the angle between "up" (i.e.
QBitmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
void accepted()
const dms & az() const
Definition: skypoint.h:275
int width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Mon Aug 15 2022 04:04:01 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.