File indexing completed on 2024-04-21 03:44:50

0001 /*
0002     SPDX-FileCopyrightText: 2014 Akarsh Simha <akarsh.simha@kdemail.net>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "dms.h"
0010 
0011 #include <QDialog>
0012 #include <QPixmap>
0013 #include <QTemporaryFile>
0014 
0015 #include <memory>
0016 
0017 class QCheckBox;
0018 class QComboBox;
0019 class QImage;
0020 class QLabel;
0021 class QPushButton;
0022 class QSlider;
0023 class QString;
0024 
0025 class FOV;
0026 class KSDssDownloader;
0027 class KStarsDateTime;
0028 class SkyPoint;
0029 
0030 /**
0031  * @class EyepieceField
0032  * @short Renders the view through the eyepiece of various telescope types
0033  *
0034  * @author Akarsh Simha <akarsh.simha@kdemail.net>
0035  */
0036 class EyepieceField : public QDialog // FIXME: Rename to EyepieceView
0037 {
0038     Q_OBJECT
0039 
0040   public:
0041     /** Constructor */
0042     explicit EyepieceField(QWidget *parent = nullptr);
0043 
0044     /**
0045      * @short Show the eyepiece field dialog
0046      * @param sp Sky point to draw the eyepiece field around.
0047      * @param fov Pointer to the FOV object describing the field of view. If no pointer is
0048      * provided, tries to get from image. If no image is provided, assumes 1 degree.
0049      * @param imagePath Optional path to DSS or other image. North should be on the top of the image.
0050      * @note The SkyPoint must have correct Alt/Az coordinates, maybe by calling update()
0051      * already before calling this method.
0052      */
0053     void showEyepieceField(SkyPoint *sp, FOV const *const fov = nullptr, const QString &imagePath = QString());
0054 
0055     /**
0056      * @short Show the eyepiece field dialog
0057      * @param sp Sky point to draw the eyepiece field around.
0058      * @param fovWidth width of field-of-view in arcminutes
0059      * @param fovHeight height of field-of-view in arcminutes (if not supplied, is set to fovWidth)
0060      * @param imagePath Optional path to DSS or other image. North should be on the top of the image.
0061      * @note The SkyPoint must have correct Alt/Az coordinates, maybe by calling update() already
0062      * before calling this method.
0063      */
0064     void showEyepieceField(SkyPoint *sp, const double fovWidth, double fovHeight = -1.0,
0065                            const QString &imagePath = QString());
0066 
0067     /**
0068      * @short Generate the eyepiece field view and corresponding image view
0069      * @param sp Sky point to draw the render the eyepiece field around
0070      * @param skyChart A non-null pointer to replace with the eyepiece field image
0071      * @param skyImage An optionally non-null pointer to replace with the re-oriented sky image
0072      * @param fovWidth width of the field-of-view in arcminutes
0073      * @param fovHeight height of field-of-view in arcminutes (if not supplied, is set to fovWidth)
0074      * @param imagePath Optional path to DSS or other image. North
0075      * should be on the top of the image, and the size should be in
0076      * the metadata; otherwise 1.01 arcsec/pixel is assumed.
0077      * @note fovWidth can be zero/negative if imagePath is non-empty. If it is, the image
0078      * size is used for the FOV.
0079      * @note fovHeight can be zero/negative. If it is, fovWidth will be used. If fovWidth is also
0080      * zero, image size is used.
0081      */
0082     static void generateEyepieceView(SkyPoint *sp, QImage *skyChart, QImage *skyImage = nullptr, double fovWidth = -1.0,
0083                                      double fovHeight = -1.0, const QString &imagePath = QString());
0084 
0085     /**
0086      * @short Overloaded method provided for convenience. Obtains fovWidth/fovHeight from
0087      * FOV if non-null, else uses image
0088      */
0089     static void generateEyepieceView(SkyPoint *sp, QImage *skyChart, QImage *skyImage = nullptr,
0090                                      const FOV *fov = nullptr, const QString &imagePath = QString());
0091 
0092     /**
0093      * @short Orients the eyepiece view as needed, performs overlaying etc.
0094      * @param skyChart image which contains the sky chart, possibly generated using generateEyepieceView
0095      * @param skyImage optional image which contains the sky image, possibly generated using generateEyepieceView
0096      * @param renderChart pixmap onto which the sky chart is to be rendered
0097      * @param renderImage optional pixmap onto which the sky image is to be rendered
0098      * @param rotation optional, number of degrees by which to rotate the image(s)
0099      * @param scale optional, factor by which to scale the image(s)
0100      * @param flip optional, if true, the image is mirrored horizontally
0101      * @param invert optional, if true, the image is inverted, i.e. rotated by 180 degrees
0102      * @param overlay optional, if true, the sky image is overlaid on the sky map
0103      * @param invertColors optional, if true, the sky image is color-inverted
0104      */
0105     static void renderEyepieceView(const QImage *skyChart, QPixmap *renderChart, const double rotation = 0,
0106                                    const double scale = 1.0, const bool flip = false, const bool invert = false,
0107                                    const QImage *skyImage = nullptr, QPixmap *renderImage = nullptr,
0108                                    const bool overlay = false, const bool invertColors = false);
0109 
0110     /**
0111      * @short Convenience method that generates and the renders the eyepiece view
0112      * @note calls generateEyepieceView() followed by the raw form of renderEyepieceView() to render an eyepiece view
0113      */
0114     static void renderEyepieceView(SkyPoint *sp, QPixmap *renderChart, double fovWidth = -1.0, double fovHeight = -1.0,
0115                                    const double rotation = 0, const double scale = 1.0, const bool flip = false,
0116                                    const bool invert = false, const QString &imagePath = QString(),
0117                                    QPixmap *renderImage = nullptr, const bool overlay = false,
0118                                    const bool invertColors = false);
0119 
0120     /**
0121      * @short Finds the angle between "up" (i.e. direction of increasing altitude) and "north" (i.e. direction of increasing declination) at a given point in the sky
0122      * @attention Procedure does not account for precession and nutation at the moment
0123      * @note SkyPoint must already have Equatorial and Horizontal coordinate synced
0124      */
0125     static dms findNorthAngle(const SkyPoint *sp, const dms *lat);
0126 
0127   public slots:
0128 
0129     /**
0130      * @short Re-renders the view
0131      * Takes care of things like inverting colors, inverting orientation, flipping, rotation
0132      * @note Calls the static method renderEyepieceView to set things up
0133      */
0134     void render();
0135 
0136     /** Enforces a preset setting */
0137     void slotEnforcePreset(int index = -1);
0138 
0139     /** Save image */
0140     void slotExport();
0141 
0142   private slots:
0143     /** Downloads a DSS image */
0144     void slotDownloadDss();
0145 
0146     /** Loads a downloaded DSS image */
0147     void slotDssDownloaded(bool success);
0148 
0149   private:
0150     QLabel *m_skyChartDisplay { nullptr };
0151     QLabel *m_skyImageDisplay { nullptr };
0152     std::unique_ptr<QImage> m_skyChart;
0153     std::unique_ptr<QImage> m_skyImage;
0154     QSlider *m_rotationSlider { nullptr };
0155     QCheckBox *m_invertColors { nullptr };
0156     QCheckBox *m_overlay { nullptr };
0157     QCheckBox *m_invertView { nullptr };
0158     QCheckBox *m_flipView { nullptr };
0159     QComboBox *m_presetCombo { nullptr };
0160     QPushButton *m_getDSS { nullptr };
0161     const FOV *m_currentFOV;
0162     double m_fovWidth { 0 };
0163     double m_fovHeight { 0 };
0164     KSDssDownloader *m_dler { nullptr };
0165     KStarsDateTime *m_dt { nullptr };
0166     SkyPoint *m_sp { nullptr };
0167     double m_lat { 0 };
0168     QTemporaryFile m_tempFile;
0169     QPixmap m_renderImage, m_renderChart;
0170     bool m_usedAltAz { false };
0171 };