File indexing completed on 2024-07-14 10:52:45

0001 /*
0002     SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org>
0003     SPDX-FileCopyrightText: 2021 Valentin Boettcher <hiro at protagon.space; @hiro98:tchncs.de>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include "dms.h"
0011 #include "skyobject.h"
0012 #include "nan.h"
0013 #include "texturemanager.h"
0014 #include <QString>
0015 #include <QByteArray>
0016 #include <QImage>
0017 #include <array>
0018 #include <utility>
0019 
0020 class KSPopupMenu;
0021 class KStarsData;
0022 class CatalogComponent;
0023 class CatalogEntryData;
0024 namespace CatalogsDB
0025 {
0026 struct Catalog;
0027 }
0028 
0029 /**
0030  * A simple container object to hold the minimum information for a Deep
0031  * Sky Object to be drawn on the skymap.  Detailed information about the
0032  * object (like `Catalog` information) will be loaded from it's birthing
0033  * database when needed. Based on the original DeepSkyObject by Jason
0034  * Harris.
0035  *
0036  * You shouldn't create a CatalogObject manually!
0037  *
0038  * \todo maybe just turn the const members public
0039  */
0040 class CatalogObject : public SkyObject
0041 {
0042     friend class AddCatalogObject;
0043 
0044   public:
0045     using oid = QByteArray;
0046 
0047     /**
0048      * @param id oid (hash) of the object
0049      * @param t Type of object
0050      * @param r Right Ascension
0051      * @param d Declination
0052      * @param m magnitude (brightness)
0053      * @param n Primary name
0054      * @param lname Long name (common name)
0055      * @param catalog_identifier a catalog specific identifier
0056      * @param catalog_id catalog id
0057      * @param a major axis (arcminutes)
0058      * @param b minor axis (arcminutes)
0059      * @param pa position angle (degrees)
0060      * @param flux integrated flux (optional)
0061      * @param database_path the path to the birthing database of this
0062      * object, used to load additional information on-demand
0063      */
0064     CatalogObject(oid id = {}, const SkyObject::TYPE t = SkyObject::STAR,
0065                   const dms &r = dms(0.0), const dms &d = dms(0.0),
0066                   const float m = NaN::f, const QString &n = QString(),
0067                   const QString &lname              = QString(),
0068                   const QString &catalog_identifier = QString(),
0069                   const int catalog_id = -1, const float a = 0.0, const float b = 0.0,
0070                   const double pa = 0.0, const float flux = 0,
0071                   const QString &database_path = "")
0072         : SkyObject(t, r, d, m, n, catalog_identifier, lname),
0073           m_catalog_identifier{ catalog_identifier }, m_catalog_id{ catalog_id },
0074           m_database_path{ database_path }, m_major_axis{ a }, m_minor_axis{ b },
0075           m_position_angle{ pa }, m_flux{ flux }
0076     {
0077         if (id.length() == 0)
0078             m_object_id = getId();
0079         else
0080             m_object_id = std::move(id);
0081     };
0082 
0083     ~CatalogObject() override = default;
0084 
0085     /**
0086      * @return the string for the skymap label of the object.
0087      */
0088     QString labelString() const override;
0089 
0090     /**
0091      * Clones the object and returns a pointer to it. This is legacy
0092      * code.
0093      *
0094      * @deprecated do not use in new code
0095      */
0096     CatalogObject *clone() const override;
0097 
0098     /**
0099      * Generates a KStars internal UID from the object id.
0100      */
0101     SkyObject::UID getUID() const override;
0102 
0103     /**
0104      * @return the object's integrated flux, unit value is stored in
0105      * the custom catalog component.
0106      */
0107     inline float flux() const { return m_flux; }
0108 
0109     /**
0110      * @return the object's major axis length, in arcminutes.
0111      */
0112     inline float a() const { return m_major_axis; }
0113 
0114     /**
0115      * @return the object's minor axis length, in arcminutes.
0116      */
0117     inline float b() const { return m_minor_axis; }
0118 
0119     /**
0120      * @return the object's aspect ratio (MinorAxis/MajorAxis). Returns 1.0
0121      * if the object's MinorAxis=0.0.
0122      */
0123     float e() const;
0124 
0125     /**
0126      * @return the object's position angle in degrees, measured clockwise from North.
0127      */
0128     inline double pa() const override { return m_position_angle; }
0129 
0130     /**
0131      * Get information about the catalog that this objects stems from.
0132      *
0133      * The catalog information will be loaded from the catalog
0134      * database on demand.
0135      */
0136     const CatalogsDB::Catalog getCatalog() const;
0137 
0138     /**
0139      * Get the id of the catalog this object belongs to.
0140      */
0141     int catalogId() const { return m_catalog_id; }
0142 
0143     /**
0144      * @return the pixel distance for offseting the object's name label
0145      */
0146     double labelOffset() const override;
0147 
0148     /**
0149      * Update the cooridnates and the horizontal coordinates if
0150      * updateID or updateNumID have changed (global).
0151      */
0152     void JITupdate();
0153 
0154     /**
0155      * Initialize the popup menu for a `CatalogObject`.
0156      */
0157     void initPopupMenu(KSPopupMenu *pmenu) override;
0158 
0159     /**
0160      * \return the catalog specific identifier. (For example UGC ...)
0161      */
0162 
0163     const QString &catalogIdentifier() const { return m_catalog_identifier; };
0164 
0165     friend bool operator==(const CatalogObject &c1, const CatalogObject &c2)
0166     {
0167         return c1.m_object_id == c2.m_object_id;
0168     }
0169 
0170     friend bool operator!=(const CatalogObject &c1, const CatalogObject &c2)
0171     {
0172         return !(c1 == c2);
0173     }
0174 
0175     /**
0176      * \returns the unique ID of this object (not the physical ID =
0177      * m_object_id) by hashing unique properties of the object.
0178      *
0179      * This method provides the reference implementation for the oid hash.
0180      */
0181     const oid getId() const;
0182     static const oid getId(const SkyObject::TYPE type, const double ra, const double dec,
0183                            const QString &name, const QString &catalog_identifier);
0184 
0185     /**
0186      * \returns the physical object id of the catalogobject
0187      */
0188     const oid getObjectId() const { return m_object_id; };
0189 
0190     /**
0191      * Set the catalog identifier to \p `cat_ident`.
0192      */
0193     void setCatalogIdentifier(const QString &cat_ident)
0194     {
0195         m_catalog_identifier = cat_ident;
0196     }
0197 
0198     /**
0199      * Set the major axis to \p `a`.
0200      */
0201     void setMaj(const float a) { m_major_axis = a; }
0202 
0203     /**
0204      * Set the minor axis to \p `b`.
0205      */
0206     void setMin(const float b) { m_minor_axis = b; }
0207 
0208     /**
0209      * Set the flux to \p `flux`.
0210      */
0211     void setFlux(const float flux) { m_flux = flux; }
0212 
0213     /**
0214      * Set the position angle to \p `pa`.
0215      */
0216     void setPA(const double pa) { m_position_angle = pa; }
0217 
0218     /**
0219      * Set the magnitude of the object.
0220      */
0221     void setMag(const double mag) { SkyObject::setMag(mag); };
0222 
0223     /**
0224      * Load the image for this object.
0225      */
0226     void load_image();
0227 
0228     /**
0229      * Get the image for this object.
0230      *
0231      * @returns [has image?, the image]
0232      */
0233     inline std::pair<bool, const QImage &> image() const
0234     {
0235         return { !m_image.isNull(), m_image };
0236     }
0237 
0238   private:
0239     /**
0240      * The unique physical object identifier (hash).
0241      */
0242     oid m_object_id;
0243 
0244     /**
0245      * A catalog specific identifier.
0246      */
0247     QString m_catalog_identifier;
0248 
0249     /**
0250      * The id of the catalog, the object is originating from.
0251      *
0252      * A value of -1 means that the catalog is unknown. This member is
0253      * not exposed publicly because it is only useful along with
0254      * `m_database_path`.
0255      */
0256     int m_catalog_id;
0257 
0258     /**
0259      * The database path which this object was loaded from.
0260      */
0261     std::reference_wrapper<const QString> m_database_path;
0262 
0263     /**
0264      * Whether the image for this catalog object has been loaded.
0265      */
0266     bool m_image_loaded{ false };
0267 
0268     /**
0269      * The image for this object (if any).
0270      *
0271      * @todo use std::optional
0272      */
0273     QImage m_image;
0274 
0275     //@{
0276     /**
0277      * Astronical metadata.
0278      *
0279      * Those values may make sense depending on the type of the
0280      * object. A value of `-1` always means: "it doesn't make sense
0281      * here".
0282      */
0283     float m_major_axis;
0284     float m_minor_axis;
0285 
0286     double m_position_angle;
0287     float m_flux;
0288     //@}
0289 
0290     //@{
0291     /**
0292      * Update id counters.
0293      */
0294     quint64 m_updateID{ 0 };
0295     quint64 m_updateNumID{ 0 };
0296     //@}
0297 };