14#include <QPainterPath>
16#include "skymapdrawabstract.h"
21#include "kstarsdata.h"
24#include "skyobjects/skyobject.h"
25#include "skyobjects/catalogobject.h"
26#include "catalogsdb.h"
27#include "skyobjects/starobject.h"
28#include "skyobjects/ksplanetbase.h"
30#include "observinglist.h"
31#include "skycomponents/constellationboundarylines.h"
32#include "skycomponents/skylabeler.h"
33#include "skycomponents/skymapcomposite.h"
34#include "skyqpainter.h"
35#include "projections/projector.h"
36#include "projections/lambertprojector.h"
38#include <config-kstars.h>
41#include <basedevice.h>
42#include "indi/indilistener.h"
43#include "indi/driverinfo.h"
44#include "indi/indistd.h"
45#include "indi/indimount.h"
46#include "indi/indidome.h"
49bool SkyMapDrawAbstract::m_DrawLock =
false;
63 SkyLabeler::Instance()->draw(p);
68 foreach (
FOV *fov, m_KStarsData->getVisibleFOVs())
70 if (fov->lockCelestialPole())
72 SkyPoint centerSkyPoint = SkyMap::Instance()->projector()->fromScreen(p.
viewport().
center(), KStarsData::Instance());
74 double northRotation = SkyMap::Instance()->projector()->findNorthPA(¢erSkyPoint, screenSkyPoint.
x(),
76 fov->setCenter(centerSkyPoint);
77 fov->setNorthPA(northRotation);
79 fov->
draw(p, Options::zoomFactor());
91 if (m_SkyMap->rotationStart.x() > 0 && m_SkyMap->rotationStart.y() > 0)
101 if (m_SkyMap->rulerMode)
103 m_SkyMap->updateAngleRuler();
111 if (INDIListener::Instance()->size() == 0)
114 QColor domeColor = m_KStarsData->colorScheme()->colorNamed(
"DomeColor");
119 for (
auto &oneDevice : INDIListener::devices())
121 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::DOME_INTERFACE) || oneDevice->isConnected() ==
false)
124 auto dome = oneDevice->getDome();
129 double shutterWidth = dome->getShutterWidth();
130 double azimuth = dome->position();
132 if (shutterWidth <= 0)
136 double radius = dome->getDomeRadius();
141 double circumference = 2 * M_PI * radius;
143 double angularWidth = (shutterWidth / circumference) * 360.0;
144 double halfWidth = angularWidth / 2.0;
149 const int steps = 50;
151 const int topSteps = 20;
154 bool started =
false;
155 for (
int i = 0; i <= steps; i++)
157 double alt = (90.0 * i) / steps;
160 point.
setAz(
dms(azimuth - halfWidth));
165 QPointF screen = m_SkyMap->m_proj->toScreen(&point,
true, &visible);
181 for (
int i = 0; i <= topSteps; i++)
183 double fraction = double(i) / topSteps;
184 double az = azimuth - halfWidth + angularWidth * fraction;
192 QPointF screen = m_SkyMap->m_proj->toScreen(&point,
true, &visible);
198 for (
int i = steps; i >= 0; i--)
200 double alt = (90.0 * i) / steps;
203 point.
setAz(
dms(azimuth + halfWidth));
208 QPointF screen = m_SkyMap->m_proj->toScreen(&point,
true, &visible);
227 m_SkyMap->m_proj->toScreen(m_SkyMap->AngularRuler.point(
229 m_SkyMap->m_proj->toScreen(m_SkyMap->AngularRuler.point(
235 auto* data = m_KStarsData;
236 const SkyPoint centerSkyPoint = m_SkyMap->m_proj->fromScreen(
241 double northRotation = m_SkyMap->m_proj->findNorthPA(
242 ¢erSkyPoint, centerScreenPoint.
x(), centerScreenPoint.
y());
243 double zenithRotation = m_SkyMap->m_proj->findZenithPA(
244 ¢erSkyPoint, centerScreenPoint.
x(), centerScreenPoint.
y());
246 QColor overlayColor(data->colorScheme()->colorNamed(
"CompassColor"));
248 auto drawArrow = [&](
double angle,
const QString & marker,
const float labelRadius,
const bool primary)
250 constexpr float radius = 150.0f;
253 QColor color = overlayColor;
259 arrowstem.
moveTo(0.f, 0.f);
260 arrowstem.
lineTo(0.f, -radius + radius / 7.5f);
262 transform.translate(centerScreenPoint.
x(), centerScreenPoint.
y());
263 transform.rotate(angle);
264 arrowstem = transform.map(arrowstem);
268 arrowhead.
moveTo(0.f, 0.f);
269 arrowhead.
lineTo(-radius / 30.f, radius / 7.5f);
270 arrowhead.
lineTo(radius / 30.f, radius / 7.5f);
271 arrowhead.
lineTo(0.f, 0.f);
272 arrowhead.
addText(
QPointF(-1.1 * fontMetrics.averageCharWidth() * marker.size(),
273 radius / 7.5f + 1.2f * fontMetrics.ascent()),
275 transform.translate(0, -radius);
276 arrowhead = transform.map(arrowhead);
279 if (labelRadius > 0.f)
281 QRectF angleMarkerRect(centerScreenPoint.
x() - labelRadius, centerScreenPoint.
y() - labelRadius,
282 2.f * labelRadius, 2.f * labelRadius);
284 if (abs(angle) < 0.01)
288 double arcAngle = angle <= 0. ? -angle : 360. - angle;
289 p.
drawArc(angleMarkerRect, 90 * 16,
int(arcAngle * 16.));
293 angleLabel.
addText(
QPointF(-(fontMetrics.averageCharWidth()*angleLabelText.
size()) / 2.f, 1.2f * fontMetrics.ascent()),
294 QFont(), angleLabelText);
296 transform.translate(centerScreenPoint.
x(), centerScreenPoint.
y());
297 transform.rotate(angle);
298 transform.translate(0, -labelRadius);
299 transform.rotate(90);
300 angleLabel = transform.map(angleLabel);
305 auto eastRotation = northRotation + (m_SkyMap->m_proj->viewParams().mirror ? 90 : -90);
306 drawArrow(northRotation,
i18nc(
"North",
"N"), 80.f, !Options::useAltAz());
307 drawArrow(eastRotation,
i18nc(
"East",
"E"), -1.f, !Options::useAltAz());
308 drawArrow(zenithRotation,
i18nc(
"Zenith",
"Z"), 40.f, Options::useAltAz());
314 if (m_SkyMap->ZoomRect.isValid())
317 p.
drawRect(m_SkyMap->ZoomRect.x(), m_SkyMap->ZoomRect.y(), m_SkyMap->ZoomRect.width(),
318 m_SkyMap->ZoomRect.height());
325 (m_SkyMap->slewing || (m_SkyMap->clockSlewing && m_KStarsData->clock()->isActive())) && Options::hideOnSlew();
326 if (checkSlewing && Options::hideLabels())
329 SkyLabeler *skyLabeler = SkyLabeler::Instance();
332 skyLabeler->
setPen(m_KStarsData->colorScheme()->colorNamed(
"UserLabelColor"));
334 bool drawPlanets = Options::showSolarSystem() && !(checkSlewing && Options::hidePlanets());
335 bool drawComets = drawPlanets && Options::showComets();
336 bool drawAsteroids = drawPlanets && Options::showAsteroids();
337 bool drawOther = Options::showDeepSky() && Options::showOther() && !(checkSlewing && Options::hideOther());
338 bool drawStars = Options::showStars();
339 bool hideFaintStars = checkSlewing && Options::hideStars();
342 if (m_SkyMap->focusObject() !=
nullptr && Options::useAutoLabel())
345 m_SkyMap->m_proj->toScreen(m_SkyMap->focusObject());
353 if (obj->
type() == SkyObject::STAR || obj->
type() == SkyObject::CATALOG_STAR ||
354 obj->
type() == SkyObject::MULT_STAR)
359 if (hideFaintStars && obj->
mag() > Options::magLimitHideStar())
362 if (obj->
type() == SkyObject::PLANET)
366 if (obj->
name() ==
i18n(
"Sun") && !Options::showSun())
368 if (obj->
name() ==
i18n(
"Mercury") && !Options::showMercury())
370 if (obj->
name() ==
i18n(
"Venus") && !Options::showVenus())
372 if (obj->
name() ==
i18n(
"Moon") && !Options::showMoon())
374 if (obj->
name() ==
i18n(
"Mars") && !Options::showMars())
376 if (obj->
name() ==
i18n(
"Jupiter") && !Options::showJupiter())
378 if (obj->
name() ==
i18n(
"Saturn") && !Options::showSaturn())
380 if (obj->
name() ==
i18n(
"Uranus") && !Options::showUranus())
382 if (obj->
name() ==
i18n(
"Neptune") && !Options::showNeptune())
386 if ((obj->
type() >= SkyObject::OPEN_CLUSTER && obj->
type() <= SkyObject::GALAXY) ||
387 (obj->
type() >= SkyObject::ASTERISM && obj->
type() <= SkyObject::QUASAR) ||
388 (obj->
type() == SkyObject::RADIO_SOURCE))
390 if (((
CatalogObject *)obj)->getCatalog().
id == -1 && !drawOther)
393 if (obj->
type() == SkyObject::COMET && !drawComets)
395 if (obj->
type() == SkyObject::ASTEROID && !drawAsteroids)
398 if (!m_SkyMap->m_proj->checkVisibility(obj))
400 QPointF o = m_SkyMap->m_proj->toScreen(obj);
401 if (!m_SkyMap->m_proj->onScreen(o))
416 for (
auto oneFOV : KStarsData::Instance()->getTransientFOVs())
418 QVariant visible = oneFOV->property(
"visible");
422 if (oneFOV->objectName() ==
"sensor_fov")
424 oneFOV->setColor(
KStars::Instance()->data()->colorScheme()->colorNamed(
"SensorFOVColor").name());
426 KStarsData::Instance());
428 double northRotation = SkyMap::Instance()->projector()->findNorthPA(¢erSkyPoint, screenSkyPoint.
x(),
430 oneFOV->setCenter(centerSkyPoint);
431 oneFOV->setNorthPA(northRotation);
432 oneFOV->draw(psky, Options::zoomFactor());
434 else if (oneFOV->objectName() ==
"solver_fov")
436 bool isVisible =
false;
442 QPointF point = SkyMap::Instance()->projector()->toScreen(&p,
true, &isVisible);
443 double northRotation = SkyMap::Instance()->projector()->findNorthPA(&p, point.
x(), point.
y());
444 oneFOV->setNorthPA(northRotation);
445 oneFOV->draw(psky, Options::zoomFactor());
456 if (!Options::showTargetCrosshair())
459 if (INDIListener::Instance()->size() == 0)
463 psky.
setPen(
QPen(
QColor(m_KStarsData->colorScheme()->colorNamed(
"TargetColor"))));
465 float pxperdegree = Options::zoomFactor() / 57.3;
467 for (
auto &oneDevice : INDIListener::devices())
469 if (!(oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE) || oneDevice->isConnected() ==
false)
472 auto mount = oneDevice->getMount();
476 auto coordNP = mount->currentCoordinates();
478 QPointF P = m_SkyMap->m_proj->toScreen(&coordNP);
479 if (Options::useAntialias())
481 float s1 = 0.5 * pxperdegree;
482 float s2 = pxperdegree;
483 float s3 = 2.0 * pxperdegree;
487 float x1 = x0 - 0.5 * s1;
488 float y1 = y0 - 0.5 * s1;
489 float x2 = x0 - 0.5 * s2;
490 float y2 = y0 - 0.5 * s2;
491 float x3 = x0 - 0.5 * s3;
492 float y3 = y0 - 0.5 * s3;
507 int s1 = int(0.5 * pxperdegree);
508 int s2 = int(pxperdegree);
509 int s3 = int(2.0 * pxperdegree);
513 int x1 = x0 - s1 / 2;
514 int y1 = y0 - s1 / 2;
515 int x2 = x0 - s2 / 2;
516 int y2 = y0 - s2 / 2;
517 int x3 = x0 - s3 / 2;
518 int y3 = y0 - s3 / 2;
548 bool vectorStarState;
549 vectorStarState = painter->getVectorStars();
557 qDebug() << Q_FUNC_INFO <<
"Scaling true while exporting Sky Image";
558 double xscale = double(painter->
device()->
width()) / double(m_SkyMap->width());
559 double yscale = double(painter->
device()->
height()) / double(m_SkyMap->height());
560 double scale = qMin(xscale, yscale);
561 qDebug() << Q_FUNC_INFO <<
"xscale: " << xscale <<
"yscale: " << yscale <<
"chosen scale: " << scale;
562 painter->
scale(scale, scale);
566 m_KStarsData->skyComposite()->draw(painter);
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
A simple class encapsulating a Field-of-View symbol.
void draw(QPainter &p, float zoomFactor)
draw the FOV symbol on a QPainter
KStarsData is the backbone of KStars.
static KStars * Instance()
The purpose of this class is to prevent labels from overlapping.
void resetFont()
sets the font in SkyLabeler and in psky back to the zoom dependent value that was set in reset().
void setPen(const QPen &pen)
sets the pen used for drawing labels on the sky.
void useStdFont()
sets the font in SkyLabeler and in psky to the font psky had originally when reset() was called.
bool drawNameLabel(SkyObject *obj, const QPointF &_p, const qreal padding_factor=1)
Tries to draw a label for an object.
static void setDrawLock(bool state)
Acquire / release a draw lock.
void drawOrientationArrows(QPainter &p)
Draw north and zenith arrows to show the orientation while rotating the sky map.
void drawZoomBox(QPainter &psky)
Draw a dotted-line rectangle which traces the potential new field-of-view in ZoomBox mode.
void drawTelescopeSymbols(QPainter &psky)
Draw symbols at the position of each Telescope currently being controlled by KStars.
void drawAngleRuler(QPainter &psky)
Draw a dashed line from the Angular-Ruler start point to the current mouse cursor,...
void drawSolverFOV(QPainter &psky)
Draw FOV of solved image in Ekos Alignment Module.
void drawObjectLabels(QList< SkyObject * > &labelObjects)
Draw "user labels".
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 drawOverlays(QPainter &p, bool drawFov=true)
Draw the overlays on top of the sky map.
void drawDomeSlits(QPainter &psky)
Draw dome slits for connected domes.
SkyMapDrawAbstract(SkyMap *sm)
Constructor that sets data and m_SkyMap, and initializes the FPS counters.
This is the canvas on which the sky is painted.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
virtual QString name(void) const
The sky coordinates of a point in the sky.
const CachingDms & ra() const
void HorizontalToEquatorialNow()
Convenience method for Horizontal -> Equatorial at simulation time.
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
void setAlt(dms alt)
Sets Alt, the Altitude.
void setAz(dms az)
Sets Az, the Azimuth.
The QPainter-based painting backend.
void end() override
End and finalize painting.
void drawSkyBackground() override
Draw the sky background.
void setVectorStars(bool vectorStars)
void begin() override
Begin painting.
An angle, stored as degrees, but expressible in many ways.
const double & Degrees() const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void setAlphaF(float alpha)
QPaintDevice * device() const const
void drawArc(const QRect &rectangle, int startAngle, int spanAngle)
void drawEllipse(const QPoint ¢er, int rx, int ry)
void drawLine(const QLine &line)
void drawRect(const QRect &rectangle)
void drawText(const QPoint &position, const QString &text)
void fillPath(const QPainterPath &path, const QBrush &brush)
void scale(qreal sx, qreal sy)
void setBrush(Qt::BrushStyle style)
void setPen(Qt::PenStyle style)
void setRenderHint(RenderHint hint, bool on)
void strokePath(const QPainterPath &path, const QPen &pen)
QRect viewport() const const
void addText(const QPointF &point, const QFont &font, const QString &text)
void lineTo(const QPointF &endPoint)
void moveTo(const QPointF &point)
QPoint center() const const
QString number(double n, char format, int precision)
qsizetype size() const const
bool isNull() const const
bool toBool() const const