Kstars

skymapdrawabstract.cpp
1 /*
2  SPDX-FileCopyrightText: 2001 Jason Harris <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 // This file implements the class SkyMapDrawAbstract, and is almost
8 // identical to the older skymapdraw.cpp file, written by Jason
9 // Harris. Essentially, skymapdraw.cpp was renamed and modified.
10 // -- asimha (2011)
11 
12 #include <QPainter>
13 #include <QPixmap>
14 
15 #include "skymapdrawabstract.h"
16 #include "skymap.h"
17 #include "Options.h"
18 #include "fov.h"
19 #include "kstars.h"
20 #include "kstarsdata.h"
21 #include "ksnumbers.h"
22 #include "ksutils.h"
23 #include "skyobjects/skyobject.h"
24 #include "skyobjects/catalogobject.h"
25 #include "catalogsdb.h"
26 #include "skyobjects/starobject.h"
27 #include "skyobjects/ksplanetbase.h"
28 #include "simclock.h"
29 #include "observinglist.h"
30 #include "skycomponents/constellationboundarylines.h"
31 #include "skycomponents/skylabeler.h"
32 #include "skycomponents/skymapcomposite.h"
33 #include "skyqpainter.h"
34 #include "projections/projector.h"
35 #include "projections/lambertprojector.h"
36 
37 #include <config-kstars.h>
38 
39 #ifdef HAVE_INDI
40 #include <basedevice.h>
41 #include "indi/indilistener.h"
42 #include "indi/driverinfo.h"
43 #include "indi/indistd.h"
44 #include "indi/indimount.h"
45 #endif
46 
47 bool SkyMapDrawAbstract::m_DrawLock = false;
48 
49 SkyMapDrawAbstract::SkyMapDrawAbstract(SkyMap *sm) : m_KStarsData(KStarsData::Instance()), m_SkyMap(sm)
50 {
51  //m_fpstime.start();
52  //m_framecount = 0;
53 }
54 
56 {
57  if (!KStars::Instance())
58  return;
59 
60  //draw labels
61  SkyLabeler::Instance()->draw(p);
62 
63  if (drawFov)
64  {
65  //draw FOV symbol
66  foreach (FOV *fov, m_KStarsData->getVisibleFOVs())
67  {
68  if (fov->lockCelestialPole())
69  {
70  SkyPoint centerSkyPoint = SkyMap::Instance()->projector()->fromScreen(p.viewport().center(), KStarsData::Instance()->lst(),
71  KStarsData::Instance()->geo()->lat());
72  QPointF screenSkyPoint = p.viewport().center();
73  double northRotation = SkyMap::Instance()->projector()->findNorthPA(&centerSkyPoint, screenSkyPoint.x(),
74  screenSkyPoint.y());
75  fov->setCenter(centerSkyPoint);
76  fov->setNorthPA(northRotation);
77  }
78  fov->draw(p, Options::zoomFactor());
79  }
80  }
81 
82  drawSolverFOV(p);
83 
85 
86  drawZoomBox(p);
87 
88  // FIXME: Maybe we should take care of this differently. Maybe
89  // drawOverlays should remain in SkyMap, since it just calls
90  // certain drawing functions which are implemented in
91  // SkyMapDrawAbstract. Really, it doesn't draw anything on its
92  // own.
93  if (m_SkyMap->rulerMode)
94  {
95  m_SkyMap->updateAngleRuler();
96  drawAngleRuler(p);
97  }
98 }
99 
101 {
102  //FIXME use sky painter.
103  p.setPen(QPen(m_KStarsData->colorScheme()->colorNamed("AngularRuler"), 3.0, Qt::DotLine));
104  p.drawLine(
105  m_SkyMap->m_proj->toScreen(m_SkyMap->AngularRuler.point(
106  0)), // FIXME: More ugliness. m_proj should probably be a single-instance class, or we should have our own instance etc.
107  m_SkyMap->m_proj->toScreen(m_SkyMap->AngularRuler.point(
108  1))); // FIXME: Again, AngularRuler should be something better -- maybe a class in itself. After all it's used for more than one thing after we integrate the StarHop feature.
109 }
110 
112 {
113  //draw the manual zoom-box, if it exists
114  if (m_SkyMap->ZoomRect.isValid())
115  {
116  p.setPen(QPen(Qt::white, 1.0, Qt::DotLine));
117  p.drawRect(m_SkyMap->ZoomRect.x(), m_SkyMap->ZoomRect.y(), m_SkyMap->ZoomRect.width(),
118  m_SkyMap->ZoomRect.height());
119  }
120 }
121 
123 {
124  bool checkSlewing =
125  (m_SkyMap->slewing || (m_SkyMap->clockSlewing && m_KStarsData->clock()->isActive())) && Options::hideOnSlew();
126  if (checkSlewing && Options::hideLabels())
127  return;
128 
129  SkyLabeler *skyLabeler = SkyLabeler::Instance();
130  skyLabeler->resetFont(); // use the zoom dependent font
131 
132  skyLabeler->setPen(m_KStarsData->colorScheme()->colorNamed("UserLabelColor"));
133 
134  bool drawPlanets = Options::showSolarSystem() && !(checkSlewing && Options::hidePlanets());
135  bool drawComets = drawPlanets && Options::showComets();
136  bool drawAsteroids = drawPlanets && Options::showAsteroids();
137  bool drawOther = Options::showDeepSky() && Options::showOther() && !(checkSlewing && Options::hideOther());
138  bool drawStars = Options::showStars();
139  bool hideFaintStars = checkSlewing && Options::hideStars();
140 
141  //Attach a label to the centered object
142  if (m_SkyMap->focusObject() != nullptr && Options::useAutoLabel())
143  {
144  QPointF o =
145  m_SkyMap->m_proj->toScreen(m_SkyMap->focusObject()); // FIXME: Same thing. m_proj should be accessible here.
146  skyLabeler->drawNameLabel(m_SkyMap->focusObject(), o);
147  }
148 
149  foreach (SkyObject *obj, labelObjects)
150  {
151  //Only draw an attached label if the object is being drawn to the map
152  //reproducing logic from other draw funcs here...not an optimal solution
153  if (obj->type() == SkyObject::STAR || obj->type() == SkyObject::CATALOG_STAR ||
154  obj->type() == SkyObject::MULT_STAR)
155  {
156  if (!drawStars)
157  continue;
158  // if ( obj->mag() > Options::magLimitDrawStar() ) continue;
159  if (hideFaintStars && obj->mag() > Options::magLimitHideStar())
160  continue;
161  }
162  if (obj->type() == SkyObject::PLANET)
163  {
164  if (!drawPlanets)
165  continue;
166  if (obj->name() == i18n("Sun") && !Options::showSun())
167  continue;
168  if (obj->name() == i18n("Mercury") && !Options::showMercury())
169  continue;
170  if (obj->name() == i18n("Venus") && !Options::showVenus())
171  continue;
172  if (obj->name() == i18n("Moon") && !Options::showMoon())
173  continue;
174  if (obj->name() == i18n("Mars") && !Options::showMars())
175  continue;
176  if (obj->name() == i18n("Jupiter") && !Options::showJupiter())
177  continue;
178  if (obj->name() == i18n("Saturn") && !Options::showSaturn())
179  continue;
180  if (obj->name() == i18n("Uranus") && !Options::showUranus())
181  continue;
182  if (obj->name() == i18n("Neptune") && !Options::showNeptune())
183  continue;
184  //if ( obj->name() == i18n( "Pluto" ) && ! Options::showPluto() ) continue;
185  }
186  if ((obj->type() >= SkyObject::OPEN_CLUSTER && obj->type() <= SkyObject::GALAXY) ||
187  (obj->type() >= SkyObject::ASTERISM && obj->type() <= SkyObject::QUASAR) ||
188  (obj->type() == SkyObject::RADIO_SOURCE))
189  {
190  if (((CatalogObject *)obj)->getCatalog().id == -1 && !drawOther)
191  continue;
192  }
193  if (obj->type() == SkyObject::COMET && !drawComets)
194  continue;
195  if (obj->type() == SkyObject::ASTEROID && !drawAsteroids)
196  continue;
197 
198  if (!m_SkyMap->m_proj->checkVisibility(obj))
199  continue; // FIXME: m_proj should be a member of this class.
200  QPointF o = m_SkyMap->m_proj->toScreen(obj);
201  if (!m_SkyMap->m_proj->onScreen(o))
202  continue;
203 
204  skyLabeler->drawNameLabel(obj, o);
205  }
206 
207  skyLabeler->useStdFont(); // use the StdFont for the guides.
208 }
209 
211 {
212  Q_UNUSED(psky)
213 
214 #ifdef HAVE_INDI
215 
216  for (auto oneFOV : KStarsData::Instance()->getTransientFOVs())
217  {
218  QVariant visible = oneFOV->property("visible");
219  if (visible.isNull() || visible.toBool() == false)
220  continue;
221 
222  if (oneFOV->objectName() == "sensor_fov")
223  {
224  oneFOV->setColor(KStars::Instance()->data()->colorScheme()->colorNamed("SensorFOVColor").name());
225  SkyPoint centerSkyPoint = SkyMap::Instance()->projector()->fromScreen(psky.viewport().center(),
226  KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
227  QPointF screenSkyPoint = psky.viewport().center();
228  double northRotation = SkyMap::Instance()->projector()->findNorthPA(&centerSkyPoint, screenSkyPoint.x(),
229  screenSkyPoint.y());
230  oneFOV->setCenter(centerSkyPoint);
231  oneFOV->setNorthPA(northRotation);
232  oneFOV->draw(psky, Options::zoomFactor());
233  }
234  else if (oneFOV->objectName() == "solver_fov")
235  {
236  bool isVisible = false;
237  SkyPoint p = oneFOV->center();
238  if (std::isnan(p.ra().Degrees()))
239  continue;
240 
241  p.EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
242  QPointF point = SkyMap::Instance()->projector()->toScreen(&p, true, &isVisible);
243  double northRotation = SkyMap::Instance()->projector()->findNorthPA(&p, point.x(), point.y());
244  oneFOV->setNorthPA(northRotation);
245  oneFOV->draw(psky, Options::zoomFactor());
246  }
247  }
248 #endif
249 }
250 
252 {
253  Q_UNUSED(psky)
254 
255 #ifdef HAVE_INDI
256  if (!Options::showTargetCrosshair())
257  return;
258 
259  if (INDIListener::Instance()->size() == 0)
260  return;
261  SkyPoint indi_sp;
262 
263  psky.setPen(QPen(QColor(m_KStarsData->colorScheme()->colorNamed("TargetColor"))));
264  psky.setBrush(Qt::NoBrush);
265  float pxperdegree = Options::zoomFactor() / 57.3;
266 
267  for (auto &oneDevice : INDIListener::Instance()->getDevices())
268  {
269  if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE) || oneDevice->isConnected() == false)
270  continue;
271 
272  auto mount = dynamic_cast<ISD::Mount *>(oneDevice->getConcreteDevice(INDI::BaseDevice::TELESCOPE_INTERFACE));
273  if (!mount)
274  continue;
275 
276  auto coordNP = mount->currentCoordinates();
277 
278  QPointF P = m_SkyMap->m_proj->toScreen(&coordNP);
279  if (Options::useAntialias())
280  {
281  float s1 = 0.5 * pxperdegree;
282  float s2 = pxperdegree;
283  float s3 = 2.0 * pxperdegree;
284 
285  float x0 = P.x();
286  float y0 = P.y();
287  float x1 = x0 - 0.5 * s1;
288  float y1 = y0 - 0.5 * s1;
289  float x2 = x0 - 0.5 * s2;
290  float y2 = y0 - 0.5 * s2;
291  float x3 = x0 - 0.5 * s3;
292  float y3 = y0 - 0.5 * s3;
293 
294  //Draw radial lines
295  psky.drawLine(QPointF(x1, y0), QPointF(x3, y0));
296  psky.drawLine(QPointF(x0 + s2, y0), QPointF(x0 + 0.5 * s1, y0));
297  psky.drawLine(QPointF(x0, y1), QPointF(x0, y3));
298  psky.drawLine(QPointF(x0, y0 + 0.5 * s1), QPointF(x0, y0 + s2));
299  //Draw circles at 0.5 & 1 degrees
300  psky.drawEllipse(QRectF(x1, y1, s1, s1));
301  psky.drawEllipse(QRectF(x2, y2, s2, s2));
302 
303  psky.drawText(QPointF(x0 + s2 + 2., y0), mount->getDeviceName());
304  }
305  else
306  {
307  int s1 = int(0.5 * pxperdegree);
308  int s2 = int(pxperdegree);
309  int s3 = int(2.0 * pxperdegree);
310 
311  int x0 = int(P.x());
312  int y0 = int(P.y());
313  int x1 = x0 - s1 / 2;
314  int y1 = y0 - s1 / 2;
315  int x2 = x0 - s2 / 2;
316  int y2 = y0 - s2 / 2;
317  int x3 = x0 - s3 / 2;
318  int y3 = y0 - s3 / 2;
319 
320  //Draw radial lines
321  psky.drawLine(QPoint(x1, y0), QPoint(x3, y0));
322  psky.drawLine(QPoint(x0 + s2, y0), QPoint(x0 + s1 / 2, y0));
323  psky.drawLine(QPoint(x0, y1), QPoint(x0, y3));
324  psky.drawLine(QPoint(x0, y0 + s1 / 2), QPoint(x0, y0 + s2));
325  //Draw circles at 0.5 & 1 degrees
326  psky.drawEllipse(QRect(x1, y1, s1, s1));
327  psky.drawEllipse(QRect(x2, y2, s2, s2));
328 
329  psky.drawText(QPoint(x0 + s2 + 2, y0), mount->getDeviceName());
330  }
331  }
332 #endif
333 }
334 
336 {
337  SkyQPainter p(m_SkyMap, pd);
338  p.begin();
340 
341  exportSkyImage(&p, scale);
342 
343  p.end();
344 }
345 
347 {
348  bool vectorStarState;
349  vectorStarState = painter->getVectorStars();
350  painter->setVectorStars(
351  true); // Since we are exporting an image, we may use vector stars without worrying about time
352  painter->setRenderHint(QPainter::Antialiasing, Options::useAntialias());
353 
354  if (scale)
355  {
356  //scale sky image to fit paint device
357  qDebug() << Q_FUNC_INFO << "Scaling true while exporting Sky Image";
358  double xscale = double(painter->device()->width()) / double(m_SkyMap->width());
359  double yscale = double(painter->device()->height()) / double(m_SkyMap->height());
360  double scale = qMin(xscale, yscale);
361  qDebug() << Q_FUNC_INFO << "xscale: " << xscale << "yscale: " << yscale << "chosen scale: " << scale;
362  painter->scale(scale, scale);
363  }
364 
365  painter->drawSkyBackground();
366  m_KStarsData->skyComposite()->draw(painter);
367  drawOverlays(*painter);
368  painter->setVectorStars(vectorStarState); // Restore the state of the painter
369 }
370 
371 /* JM 2016-05-03: Not needed since we're not using OpenGL for now
372  * void SkyMapDrawAbstract::calculateFPS()
373 {
374  if(m_framecount == 25) {
375  //float sec = m_fpstime.elapsed()/1000.;
376  // qDebug() << Q_FUNC_INFO << "FPS " << m_framecount/sec;
377  m_framecount = 0;
378  m_fpstime.restart();
379  }
380  ++m_framecount;
381 }*/
382 
384 {
385  m_DrawLock = state;
386 }
SmoothPixmapTransform
bool isNull() const const
Definition: fov.h:27
void begin() override
Begin painting.
int width() const const
The QPainter-based painting backend.
Definition: skyqpainter.h:28
void setPen(const QColor &color)
void drawEllipse(const QRectF &rectangle)
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
void drawRect(const QRectF &rectangle)
const QList< FOV * > getVisibleFOVs() const
Definition: kstarsdata.h:305
void drawSkyBackground() override
Draw the sky background.
void drawTelescopeSymbols(QPainter &psky)
Draw symbols at the position of each Telescope currently being controlled by KStars.
CachingDms * lst()
Definition: kstarsdata.h:223
void resetFont()
sets the font in SkyLabeler and in psky back to the zoom dependent value that was set in reset().
Definition: skylabeler.cpp:222
virtual QString name(void) const
Definition: skyobject.h:145
int width() const const
void drawAngleRuler(QPainter &psky)
Draw a dashed line from the Angular-Ruler start point to the current mouse cursor,...
float mag() const
Definition: skyobject.h:206
int x() const const
int y() const const
void drawOverlays(QPainter &p, bool drawFov=true)
Draw the overlays on top of the sky map.
void setPen(const QPen &pen)
sets the pen used for drawing labels on the sky.
Definition: skylabeler.cpp:197
void drawObjectLabels(QList< SkyObject * > &labelObjects)
Draw "user labels".
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 drawText(const QPointF &position, const QString &text)
void draw(QPainter &p, float zoomFactor)
draw the FOV symbol on a QPainter
Definition: fov.cpp:230
int height() const const
static KStars * Instance()
Definition: kstars.h:125
int type(void) const
Definition: skyobject.h:188
void drawZoomBox(QPainter &psky)
Draw a dotted-line rectangle which traces the potential new field-of-view in ZoomBox mode.
bool onScreen(const QPointF &p) const
Check whether the projected point is on-screen.
Definition: projector.cpp:98
void draw(SkyPainter *skyp) override
Delegate draw requests to all sub components psky Reference to the QPainter on which to paint.
QString i18n(const char *text, const TYPE &arg...)
void draw(QPainter &p)
KStars Lite version of the function above.
Definition: skylabeler.cpp:388
const CachingDms * lat() const
Definition: geolocation.h:70
void scale(qreal sx, qreal sy)
ColorScheme * colorScheme()
Definition: kstarsdata.h:171
GeoLocation * geo()
Definition: kstarsdata.h:229
SkyMapDrawAbstract(SkyMap *sm)
Constructor that sets data and m_SkyMap, and initializes the FPS counters.
bool isValid() const const
Q_INVOKABLE SimClock * clock()
Definition: kstarsdata.h:217
QPoint center() const const
double findNorthPA(const SkyPoint *o, float x, float y) const
Determine the on-screen position angle of a SkyPont with recept with NCP.
Definition: projector.cpp:237
void setBrush(const QBrush &brush)
bool toBool() const const
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:165
void setVectorStars(bool vectorStars)
Definition: skyqpainter.h:67
void drawSolverFOV(QPainter &psky)
Draw FOV of solved image in Ekos Alignment Module.
int height() const const
qreal x() const const
qreal y() const const
const CachingDms & ra() const
Definition: skypoint.h:263
SkyObject * focusObject() const
Retrieve the object which is centered in the sky map.
Definition: skymap.h:261
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
bool drawNameLabel(SkyObject *obj, const QPointF &_p, const qreal padding_factor=1)
Tries to draw a label for an object.
Definition: skylabeler.cpp:161
const double & Degrees() const
Definition: dms.h:141
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 exportSkyImage(QPaintDevice *pd, bool scale=false)
Draw the current Sky map to a pixmap which is to be printed or exported to a file.
void end() override
End and finalize painting.
void drawLine(const QLineF &line)
QRect viewport() const const
QPaintDevice * device() const const
void updateAngleRuler()
update the geometry of the angle ruler.
Definition: skymap.cpp:1312
void useStdFont()
sets the font in SkyLabeler and in psky to the font psky had originally when reset() was called.
Definition: skylabeler.cpp:217
const Projector * projector() const
Get the current projector.
Definition: skymap.h:299
SkyPoint * point(int i) const
Definition: skyline.h:44
void setRenderHint(QPainter::RenderHint hint, bool on)
Q_INVOKABLE bool isActive()
Whether the clock is active or not is a bit complicated by the introduction of "manual mode".
Definition: simclock.cpp:96
QColor colorNamed(const QString &name) const
Retrieve a color by name.
Definition: colorscheme.cpp:86
A simple container object to hold the minimum information for a Deeb Sky Object to be drawn on the sk...
Definition: catalogobject.h:40
Information about an object in the sky.
Definition: skyobject.h:41
static void setDrawLock(bool state)
Acquire / release a draw lock.
bool checkVisibility(const SkyPoint *p) const
Determine if the skypoint p is likely to be visible in the display window.
Definition: projector.cpp:183
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Tue Aug 16 2022 04:00:59 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.