Kstars

mosaic.cpp
1 /*
2  SPDX-FileCopyrightText: 2015 Jasem Mutlaq <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "mosaic.h"
8 #include "ui_mosaic.h"
9 #include "mosaictilesmanager.h"
10 #include "kstars.h"
11 #include "Options.h"
12 #include "scheduler.h"
13 #include "skymap.h"
14 #include "ekos/manager.h"
15 #include "projections/projector.h"
16 
17 #include "ekos_scheduler_debug.h"
18 
19 namespace Ekos
20 {
21 
22 Mosaic::Mosaic(QString targetName, SkyPoint center, QWidget *parent): QDialog(parent), ui(new Ui::mosaicDialog())
23 {
24  ui->setupUi(this);
25 
26  // Initial optics information is taken from Ekos options
27  ui->focalLenSpin->setValue(Options::telescopeFocalLength());
28  ui->pixelWSizeSpin->setValue(Options::cameraPixelWidth());
29  ui->pixelHSizeSpin->setValue(Options::cameraPixelHeight());
30  ui->cameraWSpin->setValue(Options::cameraWidth());
31  ui->cameraHSpin->setValue(Options::cameraHeight());
32  ui->rotationSpin->setValue(Options::cameraRotation());
33 
34  // Initial job location is the home path appended with the target name
35  ui->jobsDir->setText(QDir::cleanPath(QDir::homePath() + QDir::separator() + targetName.replace(' ', '_')));
36  ui->selectJobsDirB->setIcon(QIcon::fromTheme("document-open-folder"));
37 
38  // The update timer avoids stacking updates which crash the sky map renderer
39  updateTimer = new QTimer(this);
40  updateTimer->setSingleShot(true);
41  updateTimer->setInterval(1000);
42  connect(updateTimer, &QTimer::timeout, this, &Ekos::Mosaic::constructMosaic);
43 
44  // Scope optics information
45  // - Changing the optics configuration changes the FOV, which changes the target field dimensions
46  connect(ui->focalLenSpin, &QDoubleSpinBox::editingFinished, this, &Ekos::Mosaic::calculateFOV);
47  connect(ui->cameraWSpin, &QSpinBox::editingFinished, this, &Ekos::Mosaic::calculateFOV);
48  connect(ui->cameraHSpin, &QSpinBox::editingFinished, this, &Ekos::Mosaic::calculateFOV);
49  connect(ui->pixelWSizeSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &Ekos::Mosaic::calculateFOV);
50  connect(ui->pixelHSizeSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &Ekos::Mosaic::calculateFOV);
51  connect(ui->rotationSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &Ekos::Mosaic::calculateFOV);
52 
53  // Mosaic configuration
54  // - Changing the target field dimensions changes the grid dimensions
55  // - Changing the overlap field changes the grid dimensions (more intuitive than changing the field)
56  // - Changing the grid dimensions changes the target field dimensions
57  connect(ui->targetHFOVSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
58  &Ekos::Mosaic::updateGridFromTargetFOV);
59  connect(ui->targetWFOVSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
60  &Ekos::Mosaic::updateGridFromTargetFOV);
61  connect(ui->overlapSpin, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this,
62  &Ekos::Mosaic::updateGridFromTargetFOV);
63  connect(ui->mosaicWSpin, QOverload<int>::of(&QSpinBox::valueChanged), this, &Ekos::Mosaic::updateTargetFOVFromGrid);
64  connect(ui->mosaicHSpin, QOverload<int>::of(&QSpinBox::valueChanged), this, &Ekos::Mosaic::updateTargetFOVFromGrid);
65 
66  // Lazy update for s-shape
67  connect(ui->reverseOddRows, &QCheckBox::toggled, this, [&]()
68  {
69  renderedHFOV = 0;
70  updateTimer->start();
71  });
72 
73  // Buttons
74  connect(ui->resetB, &QPushButton::clicked, this, &Ekos::Mosaic::updateTargetFOVFromGrid);
75  connect(ui->selectJobsDirB, &QPushButton::clicked, this, &Ekos::Mosaic::saveJobsDirectory);
76  connect(ui->fetchB, &QPushButton::clicked, this, &Mosaic::fetchINDIInformation);
77 
78  // The sky map is a pixmap background, and the mosaic tiles are rendered over it
79  //m_TilesScene = new MosaicTilesScene(this);
80  m_SkyPixmapItem = m_TilesScene.addPixmap(targetPix);
81  m_SkyPixmapItem->setTransformationMode(Qt::TransformationMode::SmoothTransformation);
82  m_MosaicTilesManager = new MosaicTilesManager(this);
83  connect(m_MosaicTilesManager, &MosaicTilesManager::newOffset, this, [this](const QPointF & offset)
84  {
85  // Find out new center
86  QPointF cartesianCenter = SkyMap::Instance()->projector()->toScreen(&m_CenterPoint);
87  QPointF destinationCenter = cartesianCenter + offset;
88  SkyPoint newCenter = SkyMap::Instance()->projector()->fromScreen(destinationCenter,
89  KStarsData::Instance()->lst(),
90  KStarsData::Instance()->geo()->lat());
91  SkyPoint J2000Center = newCenter.catalogueCoord(KStars::Instance()->data()->ut().djd());
92  setCenter(J2000Center);
93  updateTimer->start();
94  });
95  m_TilesScene.addItem(m_MosaicTilesManager);
96  ui->mosaicView->setScene(&m_TilesScene);
97 
98  // Always use Equatorial Mode in Mosaic mode
99  m_RememberAltAzOption = Options::useAltAz();
100  Options::setUseAltAz(false);
101  m_RememberShowGround = Options::showGround();
102  Options::setShowGround(false);
103 
104  // Rendering options
105  connect(ui->transparencySlider, QOverload<int>::of(&QSlider::valueChanged), this, [&](int v)
106  {
107  ui->transparencySlider->setToolTip(QString("%1%").arg(v));
108  m_MosaicTilesManager->setPainterAlpha(v);
109  updateTimer->start();
110  });
111  connect(ui->transparencyAuto, &QCheckBox::toggled, this, [&](bool v)
112  {
113  ui->transparencySlider->setEnabled(!v);
114  if (v)
115  updateTimer->start();
116  });
117 
118  // Job options
119  connect(ui->alignEvery, QOverload<int>::of(&QSpinBox::valueChanged), this, &Ekos::Mosaic::rewordStepEvery);
120  connect(ui->focusEvery, QOverload<int>::of(&QSpinBox::valueChanged), this, &Ekos::Mosaic::rewordStepEvery);
121  ui->alignEvery->valueChanged(0);
122  ui->focusEvery->valueChanged(0);
123 
124  // Center, fetch optics and adjust size
125  setCenter(center);
126  fetchINDIInformation();
127  adjustSize();
128 }
129 
130 Mosaic::~Mosaic()
131 {
132  delete updateTimer;
133  Options::setUseAltAz(m_RememberAltAzOption);
134  Options::setShowGround(m_RememberShowGround);
135 }
136 
137 QString Mosaic::getJobsDir() const
138 {
139  return ui->jobsDir->text();
140 }
141 
142 bool Mosaic::isScopeInfoValid() const
143 {
144  if (0 < ui->focalLenSpin->value())
145  if (0 < ui->cameraWSpin->value() && 0 < ui->cameraWSpin->value())
146  if (0 < ui->pixelWSizeSpin->value() && 0 < ui->pixelHSizeSpin->value())
147  return true;
148  return false;
149 }
150 
151 double Mosaic::getTargetWFOV() const
152 {
153  double const xFOV = ui->cameraWFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
154  return ui->cameraWFOVSpin->value() + xFOV * (ui->mosaicWSpin->value() - 1);
155 }
156 
157 double Mosaic::getTargetHFOV() const
158 {
159  double const yFOV = ui->cameraHFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
160  return ui->cameraHFOVSpin->value() + yFOV * (ui->mosaicHSpin->value() - 1);
161 }
162 
163 double Mosaic::getTargetMosaicW() const
164 {
165  // If FOV is invalid, or target FOV is null, or target FOV is smaller than camera FOV, we get one tile
166  if (!isScopeInfoValid() || !ui->targetWFOVSpin->value() || ui->targetWFOVSpin->value() <= ui->cameraWFOVSpin->value())
167  return 1;
168 
169  // Else we get one tile, plus as many overlapping camera FOVs in the remnant of the target FOV
170  double const xFOV = ui->cameraWFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
171  int const tiles = 1 + ceil((ui->targetWFOVSpin->value() - ui->cameraWFOVSpin->value()) / xFOV);
172  //Ekos::Manager::Instance()->schedulerModule()->appendLogText(QString("[W] Target FOV %1, camera FOV %2 after overlap %3, %4 tiles.").arg(ui->targetWFOVSpin->value()).arg(ui->cameraWFOVSpin->value()).arg(xFOV).arg(tiles));
173  return tiles;
174 }
175 
176 double Mosaic::getTargetMosaicH() const
177 {
178  // If FOV is invalid, or target FOV is null, or target FOV is smaller than camera FOV, we get one tile
179  if (!isScopeInfoValid() || !ui->targetHFOVSpin->value() || ui->targetHFOVSpin->value() <= ui->cameraHFOVSpin->value())
180  return 1;
181 
182  // Else we get one tile, plus as many overlapping camera FOVs in the remnant of the target FOV
183  double const yFOV = ui->cameraHFOVSpin->value() * (1 - ui->overlapSpin->value() / 100.0);
184  int const tiles = 1 + ceil((ui->targetHFOVSpin->value() - ui->cameraHFOVSpin->value()) / yFOV);
185  //Ekos::Manager::Instance()->schedulerModule()->appendLogText(QString("[H] Target FOV %1, camera FOV %2 after overlap %3, %4 tiles.").arg(ui->targetHFOVSpin->value()).arg(ui->cameraHFOVSpin->value()).arg(yFOV).arg(tiles));
186  return tiles;
187 }
188 
189 int Mosaic::exec()
190 {
191  premosaicZoomFactor = Options::zoomFactor();
192 
193  int const result = QDialog::exec();
194 
195  // Revert various options
196  updateTimer->stop();
197  SkyMap *map = SkyMap::Instance();
198  if (map && 0 < premosaicZoomFactor)
199  map->setZoomFactor(premosaicZoomFactor);
200 
201  return result;
202 }
203 
204 void Mosaic::accept()
205 {
206  //createJobs();
207  QDialog::accept();
208 }
209 
210 void Mosaic::saveJobsDirectory()
211 {
212  QString dir = QFileDialog::getExistingDirectory(KStars::Instance(), i18nc("@title:window", "FITS Save Directory"),
213  ui->jobsDir->text());
214 
215  if (!dir.isEmpty())
216  ui->jobsDir->setText(dir);
217 }
218 
219 void Mosaic::setCenter(const SkyPoint &value)
220 {
221  m_CenterPoint = value;
222  m_CenterPoint.apparentCoord(static_cast<long double>(J2000), KStars::Instance()->data()->ut().djd());
223 }
224 
225 void Mosaic::setCameraSize(uint16_t width, uint16_t height)
226 {
227  ui->cameraWSpin->setValue(width);
228  ui->cameraHSpin->setValue(height);
229 }
230 
231 void Mosaic::setPixelSize(double pixelWSize, double pixelHSize)
232 {
233  ui->pixelWSizeSpin->setValue(pixelWSize);
234  ui->pixelHSizeSpin->setValue(pixelHSize);
235 }
236 
237 void Mosaic::setFocalLength(double focalLength)
238 {
239  ui->focalLenSpin->setValue(focalLength);
240 }
241 
242 void Mosaic::calculateFOV()
243 {
244  if (!isScopeInfoValid())
245  return;
246 
247  ui->fovGroup->setEnabled(true);
248 
249  ui->targetWFOVSpin->setMinimum(ui->cameraWFOVSpin->value());
250  ui->targetHFOVSpin->setMinimum(ui->cameraHFOVSpin->value());
251 
252  Options::setTelescopeFocalLength(ui->focalLenSpin->value());
253  Options::setCameraPixelWidth(ui->pixelWSizeSpin->value());
254  Options::setCameraPixelHeight(ui->pixelHSizeSpin->value());
255  Options::setCameraWidth(ui->cameraWSpin->value());
256  Options::setCameraHeight(ui->cameraHSpin->value());
257 
258  // Calculate FOV in arcmins
259  double const fov_x =
260  206264.8062470963552 * ui->cameraWSpin->value() * ui->pixelWSizeSpin->value() / 60000.0 / ui->focalLenSpin->value();
261  double const fov_y =
262  206264.8062470963552 * ui->cameraHSpin->value() * ui->pixelHSizeSpin->value() / 60000.0 / ui->focalLenSpin->value();
263 
264  ui->cameraWFOVSpin->setValue(fov_x);
265  ui->cameraHFOVSpin->setValue(fov_y);
266 
267  double const target_fov_w = getTargetWFOV();
268  double const target_fov_h = getTargetHFOV();
269 
270  if (ui->targetWFOVSpin->value() < target_fov_w)
271  {
272  bool const sig = ui->targetWFOVSpin->blockSignals(true);
273  ui->targetWFOVSpin->setValue(target_fov_w);
274  ui->targetWFOVSpin->blockSignals(sig);
275  }
276 
277  if (ui->targetHFOVSpin->value() < target_fov_h)
278  {
279  bool const sig = ui->targetHFOVSpin->blockSignals(true);
280  ui->targetHFOVSpin->setValue(target_fov_h);
281  ui->targetHFOVSpin->blockSignals(sig);
282  }
283 
284  updateTimer->start();
285 }
286 
287 void Mosaic::updateTargetFOV()
288 {
289  KStars *ks = KStars::Instance();
290  SkyMap *map = SkyMap::Instance();
291 
292  // Render the required FOV
293  renderedWFOV = ui->targetWFOVSpin->value();// * cos(ui->rotationSpin->value() * dms::DegToRad);
294  renderedHFOV = ui->targetHFOVSpin->value();// * sin(ui->rotationSpin->value() * dms::DegToRad);
295 
296  // Pick thrice the largest FOV to obtain a proper zoom
297  double const spacing = ui->mosaicWSpin->value() < ui->mosaicHSpin->value() ? ui->mosaicHSpin->value() :
298  ui->mosaicWSpin->value();
299  double const scale = 1.0 + 2.0 / (1.0 + spacing);
300  double const renderedFOV = scale * (renderedWFOV < renderedHFOV ? renderedHFOV : renderedWFOV);
301 
302  // Check the aspect ratio of the sky map, assuming the map zoom considers the width (see KStars::setApproxFOV)
303  double const aspect_ratio = map->width() / map->height();
304 
305  // Set the zoom (in degrees) that gives the expected FOV for the map aspect ratio, and center the target
306  ks->setApproxFOV(renderedFOV * aspect_ratio / 60.0);
307  //center.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
308  map->setClickedObject(nullptr);
309  map->setClickedPoint(&m_CenterPoint);
310  map->slotCenter();
311 
312  // Wait for the map to stop slewing, so that HiPS renders properly
313  while(map->isSlewing())
314  qApp->processEvents();
315  qApp->processEvents();
316 
317  // Compute the horizontal and vertical resolutions, deduce the actual FOV of the map in arcminutes
318  pixelsPerArcminRA = pixelsPerArcminDE = Options::zoomFactor() * dms::DegToRad / 60.0;
319 
320  // Get the sky map image - don't bother subframing, it causes imprecision sometimes
321  QImage fullSkyChart(QSize(map->width(), map->height()), QImage::Format_RGB32);
322  map->exportSkyImage(&fullSkyChart, false);
323  qApp->processEvents();
324  m_SkyPixmapItem->setPixmap(QPixmap::fromImage(fullSkyChart));
325 
326  // Relocate
327  QRectF sceneRect = m_SkyPixmapItem->boundingRect().translated(-m_SkyPixmapItem->boundingRect().center());
328  m_TilesScene.setSceneRect(sceneRect);
329  m_SkyPixmapItem->setOffset(sceneRect.topLeft());
330  m_SkyPixmapItem->setPos(QPointF());
331 
332 }
333 
334 void Mosaic::resizeEvent(QResizeEvent *)
335 {
336  // Adjust scene rect to avoid rounding holes on border
337  QRectF adjustedSceneRect(m_TilesScene.sceneRect());
338  adjustedSceneRect.setTop(adjustedSceneRect.top() + 2);
339  adjustedSceneRect.setLeft(adjustedSceneRect.left() + 2);
340  adjustedSceneRect.setRight(adjustedSceneRect.right() - 2);
341  adjustedSceneRect.setBottom(adjustedSceneRect.bottom() - 2);
342 
343  ui->mosaicView->fitInView(adjustedSceneRect, Qt::KeepAspectRatioByExpanding);
344  ui->mosaicView->centerOn(QPointF());
345 }
346 
347 void Mosaic::showEvent(QShowEvent *)
348 {
349  resizeEvent(nullptr);
350 }
351 
352 void Mosaic::resetFOV()
353 {
354  if (!isScopeInfoValid())
355  return;
356 
357  ui->targetWFOVSpin->setValue(getTargetWFOV());
358  ui->targetHFOVSpin->setValue(getTargetHFOV());
359 }
360 
361 void Mosaic::updateTargetFOVFromGrid()
362 {
363  if (!isScopeInfoValid())
364  return;
365 
366  double const targetWFOV = getTargetWFOV();
367  double const targetHFOV = getTargetHFOV();
368 
369  if (ui->targetWFOVSpin->value() != targetWFOV)
370  {
371  bool const sig = ui->targetWFOVSpin->blockSignals(true);
372  ui->targetWFOVSpin->setValue(targetWFOV);
373  ui->targetWFOVSpin->blockSignals(sig);
374  updateTimer->start();
375  }
376 
377  if (ui->targetHFOVSpin->value() != targetHFOV)
378  {
379  bool const sig = ui->targetHFOVSpin->blockSignals(true);
380  ui->targetHFOVSpin->setValue(targetHFOV);
381  ui->targetHFOVSpin->blockSignals(sig);
382  updateTimer->start();
383  }
384 }
385 
386 void Mosaic::updateGridFromTargetFOV()
387 {
388  if (!isScopeInfoValid())
389  return;
390 
391  double const expectedW = getTargetMosaicW();
392  double const expectedH = getTargetMosaicH();
393 
394  if (expectedW != ui->mosaicWSpin->value())
395  {
396  bool const sig = ui->mosaicWSpin->blockSignals(true);
397  ui->mosaicWSpin->setValue(expectedW);
398  ui->mosaicWSpin->blockSignals(sig);
399  }
400 
401  if (expectedH != ui->mosaicHSpin->value())
402  {
403  bool const sig = ui->mosaicHSpin->blockSignals(true);
404  ui->mosaicHSpin->setValue(expectedH);
405  ui->mosaicHSpin->blockSignals(sig);
406  }
407 
408  // Update unconditionally, as we may be updating the overlap or the target FOV covered by the mosaic
409  updateTimer->start();
410 }
411 
412 void Mosaic::constructMosaic()
413 {
414  updateTimer->stop();
415 
416  if (!isScopeInfoValid())
417  return;
418 
419  updateTargetFOV();
420 
421  if (m_MosaicTilesManager->getPA() != ui->rotationSpin->value())
422  Options::setCameraRotation(ui->rotationSpin->value());
423 
424  qCDebug(KSTARS_EKOS_SCHEDULER) << "Tile FOV in pixels W:" << ui->cameraWFOVSpin->value() * pixelsPerArcminRA << "H:"
425  << ui->cameraHFOVSpin->value() * pixelsPerArcminDE;
426 
427  m_MosaicTilesManager->setPos(0, 0);
428  m_MosaicTilesManager->setSkyCenter(m_CenterPoint);
429  m_MosaicTilesManager->setGridDimensions(ui->mosaicWSpin->value(), ui->mosaicHSpin->value());
430  m_MosaicTilesManager->setPositionAngle(ui->rotationSpin->value());
431  m_MosaicTilesManager->setSingleTileFOV(ui->cameraWFOVSpin->value() * pixelsPerArcminRA,
432  ui->cameraHFOVSpin->value() * pixelsPerArcminDE);
433  m_MosaicTilesManager->setMosaicFOV(ui->targetWFOVSpin->value() * pixelsPerArcminRA,
434  ui->targetHFOVSpin->value() * pixelsPerArcminDE);
435  m_MosaicTilesManager->setOverlap(ui->overlapSpin->value() / 100);
436  m_MosaicTilesManager->setPixelScale(QSizeF(pixelsPerArcminRA * 60.0, pixelsPerArcminDE * 60.0));
437  m_MosaicTilesManager->updateTiles(m_MosaicTilesManager->mapToItem(m_SkyPixmapItem,
438  m_SkyPixmapItem->boundingRect().center()),
439  ui->reverseOddRows->checkState() == Qt::CheckState::Checked);
440 
441  ui->jobCountSpin->setValue(m_MosaicTilesManager->getWidth() * m_MosaicTilesManager->getHeight());
442 
443  if (ui->transparencyAuto->isChecked())
444  {
445  // Tiles should be more transparent when many are overlapped
446  // Overlap < 50%: low transparency, as only two tiles will overlap on a line
447  // 50% < Overlap < 75%: mid transparency, as three tiles will overlap one a line
448  // 75% < Overlap: high transparency, as four tiles will overlap on a line
449  // Slider controlling transparency provides [5%,50%], which is scaled to 0-200 alpha.
450 
451  if (1 < ui->jobCountSpin->value())
452  ui->transparencySlider->setValue(40 - ui->overlapSpin->value() / 2);
453  else
454  ui->transparencySlider->setValue(40);
455 
456  ui->transparencySlider->update();
457  }
458 
459  resizeEvent(nullptr);
460  m_MosaicTilesManager->show();
461 
462  ui->mosaicView->update();
463 }
464 
465 QList <Mosaic::Job> Mosaic::getJobs() const
466 {
467  qCDebug(KSTARS_EKOS_SCHEDULER) << "Mosaic Tile W:" << m_MosaicTilesManager->boundingRect().width() << "H:" <<
468  m_MosaicTilesManager->boundingRect().height();
469 
470  QList <Mosaic::Job> result;
471 
472  // We have two items:
473  // 1. SkyMapItem is the pixmap we fetch from KStars that shows the sky field.
474  // 2. MosaicItem is the constructed mosaic boxes.
475  // We already know the center (RA0,DE0) of the SkyMapItem.
476  // We Map the coordinate of each tile to the SkyMapItem to find out where the tile center is located
477  // on the SkyMapItem pixmap.
478  // We calculate the difference between the tile center and the SkyMapItem center and then find the tile coordinates
479  // in J2000 coords.
480  for (int i = 0; i < m_MosaicTilesManager->getHeight(); i++)
481  {
482  for (int j = 0; j < m_MosaicTilesManager->getWidth(); j++)
483  {
484  MosaicTilesManager::OneTile * const tile = m_MosaicTilesManager->getTile(i, j);
485  qCDebug(KSTARS_EKOS_SCHEDULER) << "Tile #" << i * m_MosaicTilesManager->getWidth() + j << "Center:" << tile->center;
486 
487  Job ts;
488  ts.center.setRA0(tile->skyCenter.ra0().Hours());
489  ts.center.setDec0(tile->skyCenter.dec0().Degrees());
490  ts.rotation = -m_MosaicTilesManager->getPA();
491 
492  ts.doAlign =
493  (0 < ui->alignEvery->value()) &&
494  (0 == ((j + i * m_MosaicTilesManager->getHeight()) % ui->alignEvery->value()));
495 
496  ts.doFocus =
497  (0 < ui->focusEvery->value()) &&
498  (0 == ((j + i * m_MosaicTilesManager->getHeight()) % ui->focusEvery->value()));
499 
500  qCDebug(KSTARS_EKOS_SCHEDULER) << "Tile RA0:" << tile->skyCenter.ra0().toHMSString() << "DE0:" <<
501  tile->skyCenter.dec0().toDMSString();
502  result.append(ts);
503  }
504  }
505 
506  return result;
507 }
508 
509 void Mosaic::fetchINDIInformation()
510 {
511  QDBusInterface alignInterface("org.kde.kstars",
512  "/KStars/Ekos/Align",
513  "org.kde.kstars.Ekos.Align",
515 
516  QDBusReply<QList<double>> cameraReply = alignInterface.call("cameraInfo");
517  if (cameraReply.isValid())
518  {
519  QList<double> const values = cameraReply.value();
520 
521  setCameraSize(values[0], values[1]);
522  setPixelSize(values[2], values[3]);
523  }
524 
525  QDBusReply<QList<double>> telescopeReply = alignInterface.call("telescopeInfo");
526  if (telescopeReply.isValid())
527  {
528  QList<double> const values = telescopeReply.value();
529  setFocalLength(values[0]);
530  }
531 
532  QDBusReply<QList<double>> solutionReply = alignInterface.call("getSolutionResult");
533  if (solutionReply.isValid())
534  {
535  QList<double> const values = solutionReply.value();
536  if (values[0] > INVALID_VALUE)
537  ui->rotationSpin->setValue(values[0]);
538  }
539 
540  calculateFOV();
541 }
542 
543 void Mosaic::rewordStepEvery(int v)
544 {
545  QSpinBox * sp = dynamic_cast<QSpinBox *>(sender());
546  if (0 < v)
547  sp->setSuffix(i18np(" Scheduler job", " Scheduler jobs", v));
548  else
549  sp->setSuffix(i18n(" (first only)"));
550 }
551 
552 }
void append(const T &value)
void adjustSize()
QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags)
void setSuffix(const QString &suffix)
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:66
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
QChar separator()
bool isValid() const const
static constexpr double DegToRad
DegToRad is a const static member equal to the number of radians in one degree (dms::PI/180....
Definition: dms.h:385
void clicked(bool checked)
QIcon fromTheme(const QString &name)
QString homePath()
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void valueChanged(double d)
void toggled(bool checked)
static KStars * Instance()
Definition: kstars.h:125
QRectF translated(qreal dx, qreal dy) const const
KeepAspectRatioByExpanding
QString i18n(const char *text, const TYPE &arg...)
QDBusConnection sessionBus()
QPointF topLeft() const const
void timeout()
bool isEmpty() const const
virtual void accept()
virtual int exec()
GeoCoordinates geo(const QVariant &location)
This is the main window for KStars. In addition to the GUI elements, the class contains the program c...
Definition: kstars.h:92
void setupUi(QWidget *widget)
QString & replace(int position, int n, QChar after)
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString cleanPath(const QString &path)
KIOFILEWIDGETS_EXPORT QString dir(const QString &fileClass)
virtual SkyPoint fromScreen(const QPointF &p, dms *LST, const dms *lat, bool onlyAltAz=false) const
Determine RA, Dec coordinates of the pixel at (dx, dy), which are the screen pixel coordinate offsets...
Definition: projector.cpp:406
void editingFinished()
void apparentCoord(long double jd0, long double jdf)
Computes the apparent coordinates for this SkyPoint for any epoch, accounting for the effects of prec...
Definition: skypoint.cpp:700
Canvas widget for displaying the sky bitmap; also handles user interaction events.
Definition: skymap.h:52
QPointF toScreen(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=nullptr) const
This is exactly the same as toScreenVec but it returns a QPointF.
Definition: projector.cpp:93
void valueChanged(int value)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
Q_SCRIPTABLE Q_NOREPLY void setApproxFOV(double FOV_Degrees)
DBUS interface function.
Definition: kstarsdbus.cpp:969
const Projector * projector() const
Get the current projector.
Definition: skymap.h:299
void valueChanged(int i)
QFuture< void > map(Sequence &sequence, MapFunctor function)
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
QVector< V > values(const QMultiHash< K, V > &c)
QDBusReply::Type value() const const
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
Definition: skypoint.cpp:710
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 19 2022 03:57:52 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.