File indexing completed on 2024-04-28 15:09:01

0001 /*  Ekos Alignment View
0002     Child of AlignView with few additions necessary for Alignment functions
0003 
0004     SPDX-FileCopyrightText: 2017 Jasem Mutlaq <mutlaqja@ikarustech.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "alignview.h"
0010 
0011 #include "ekos_align_debug.h"
0012 #include "kstarsdata.h"
0013 #include <math.h>
0014 #include "Options.h"
0015 #include "fitsviewer/fitsdata.h"
0016 
0017 #include <QPainter>
0018 #include <QtConcurrent>
0019 
0020 AlignView::AlignView(QWidget *parent, FITSMode mode, FITSScale filter) : FITSView(parent, mode, filter)
0021 {
0022 }
0023 
0024 void AlignView::drawOverlay(QPainter *painter, double scale)
0025 {
0026     Q_UNUSED(scale);
0027     painter->setOpacity(0.5);
0028     FITSView::drawOverlay(painter, getScale());
0029     painter->setOpacity(1);
0030 
0031     // drawRaAxis/Triangle/StarCircle all make sure their points are valid.
0032     drawRaAxis(painter);
0033     drawTriangle(painter, correctionFrom, correctionTo, correctionAltTo);
0034     drawStarCircle(painter, starCircle, 35.0, Qt::yellow);
0035 }
0036 
0037 bool AlignView::injectWCS(double orientation, double ra, double dec, double pixscale, bool eastToTheRight, bool block)
0038 {
0039     m_ImageData->injectWCS(orientation, ra, dec, pixscale, eastToTheRight);
0040 
0041     if (block)
0042     {
0043         if (wcsWatcher.isRunning() == false && m_ImageData->getWCSState() == FITSData::Idle)
0044         {
0045             // Load WCS async
0046             QFuture<bool> future = QtConcurrent::run(m_ImageData.data(), &FITSData::loadWCS);
0047             wcsWatcher.setFuture(future);
0048         }
0049         return true;
0050     }
0051     // This should probably not be called in a UI thread when extras is true.
0052     return m_ImageData->loadWCS();
0053 }
0054 
0055 void AlignView::reset()
0056 {
0057     correctionFrom = QPointF();
0058     correctionTo = QPointF();
0059     correctionAltTo = QPointF();
0060     markerCrosshair = QPointF();
0061     celestialPolePoint = QPointF();
0062     raAxis = QPointF();
0063     starCircle = QPointF();
0064     releaseImage();
0065 }
0066 
0067 void AlignView::setCorrectionParams(const QPointF &from, const QPointF &to, const QPointF &altTo)
0068 {
0069     if (m_ImageData.isNull())
0070         return;
0071 
0072     correctionFrom = from;
0073     correctionTo = to;
0074     correctionAltTo = altTo;
0075     markerCrosshair = to;
0076 
0077     updateFrame(true);
0078 }
0079 
0080 void AlignView::setStarCircle(const QPointF &pixel)
0081 {
0082     starCircle = pixel;
0083     updateFrame(true);
0084 }
0085 
0086 void AlignView::drawTriangle(QPainter *painter, const QPointF &from, const QPointF &to, const QPointF &altTo)
0087 {
0088     if (from.isNull() && to.isNull() && altTo.isNull())
0089         return;
0090 
0091     painter->setRenderHint(QPainter::Antialiasing);
0092     painter->setBrush(Qt::NoBrush);
0093 
0094     const double scale = getScale();
0095 
0096     // Some of the points may be out of the image.
0097     painter->setPen(QPen(Qt::magenta, 2));
0098     painter->drawLine(from.x() * scale, from.y() * scale, to.x() * scale, to.y() * scale);
0099 
0100     painter->setPen(QPen(Qt::yellow, 3));
0101     painter->drawLine(from.x() * scale, from.y() * scale, altTo.x() * scale, altTo.y() * scale);
0102 
0103     painter->setPen(QPen(Qt::green, 3));
0104     painter->drawLine(altTo.x() * scale, altTo.y() * scale, to.x() * scale, to.y() * scale);
0105 
0106     // In limited memory mode, WCS data is not loaded so no Equatorial Gridlines are drawn
0107     // so we have to at least draw the NCP/SCP locations
0108     //    if (Options::limitedResourcesMode() && !celestialPolePoint.isNull()
0109     //            && m_ImageData->contains(celestialPolePoint))
0110     //    {
0111     //        QPen pen;
0112     //        pen.setWidth(2);
0113     //        pen.setColor(Qt::darkRed);
0114     //        painter->setPen(pen);
0115     //        double x  = celestialPolePoint.x() * scale;
0116     //        double y  = celestialPolePoint.y() * scale;
0117     //        double sr = 3 * scale;
0118 
0119     //        if (KStarsData::Instance()->geo()->lat()->Degrees() > 0)
0120     //            painter->drawText(x + sr, y + sr, i18nc("North Celestial Pole", "NCP"));
0121     //        else
0122     //            painter->drawText(x + sr, y + sr, i18nc("South Celestial Pole", "SCP"));
0123     //    }
0124 }
0125 
0126 void AlignView::drawStarCircle(QPainter *painter, const QPointF &center, double radius, const QColor &color)
0127 {
0128     if (center.isNull())
0129         return;
0130 
0131     painter->setRenderHint(QPainter::Antialiasing);
0132     painter->setBrush(Qt::NoBrush);
0133 
0134     const double scale = getScale();
0135     QPointF pt(center.x() * scale, center.y() * scale);
0136 
0137     // Could get fancy and change from yellow to green when closer to the green line.
0138     painter->setPen(QPen(color, 1));
0139     painter->drawEllipse(pt, radius, radius);
0140 }
0141 
0142 void AlignView::drawRaAxis(QPainter *painter)
0143 {
0144     if (raAxis.isNull() || !m_ImageData->contains(raAxis))
0145         return;
0146 
0147     QPen pen(Qt::green);
0148     pen.setWidth(2);
0149     pen.setStyle(Qt::DashLine);
0150     painter->setPen(pen);
0151     painter->setBrush(Qt::NoBrush);
0152 
0153     const double scale = getScale();
0154     const QPointF center(raAxis.x() * scale, raAxis.y() * scale);
0155 
0156     // Big Radius
0157     const double r = 200 * scale;
0158 
0159     // Small radius
0160     const double sr = r / 25.0;
0161 
0162     painter->drawEllipse(center, sr, sr);
0163     painter->drawEllipse(center, r, r);
0164     pen.setColor(Qt::darkGreen);
0165     painter->setPen(pen);
0166     painter->drawText(center.x() + sr, center.y() + sr, i18n("RA Axis"));
0167 }
0168 
0169 void AlignView::setRaAxis(const QPointF &value)
0170 {
0171     raAxis = value;
0172     updateFrame(true);
0173 }
0174 
0175 void AlignView::setCelestialPole(const QPointF &value)
0176 {
0177     celestialPolePoint = value;
0178     updateFrame(true);
0179 }
0180 
0181 void AlignView::setRefreshEnabled(bool enable)
0182 {
0183     if (enable)
0184         setCursorMode(crosshairCursor);
0185     else
0186         setCursorMode(selectCursor);
0187 }
0188 
0189 void AlignView::processMarkerSelection(int x, int y)
0190 {
0191     Q_UNUSED(x)
0192     Q_UNUSED(y)
0193 }
0194 
0195 void AlignView::holdOnToImage()
0196 {
0197     keptImagePointer = m_ImageData;
0198 }
0199 
0200 void AlignView::releaseImage()
0201 {
0202     keptImagePointer.reset();
0203 }