File indexing completed on 2024-07-14 07:17:21

0001 /*
0002     SPDX-FileCopyrightText: 2005 Thomas Kabelmann <thomas.kabelmann@gmx.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "horizoncomponent.h"
0008 
0009 #include "dms.h"
0010 #include "kstarsdata.h"
0011 #include "Options.h"
0012 #include "skylabeler.h"
0013 #ifdef KSTARS_LITE
0014 #include "skymaplite.h"
0015 #else
0016 #include "skymap.h"
0017 #endif
0018 #include "skypainter.h"
0019 #include "projections/projector.h"
0020 
0021 #include <QPointF>
0022 
0023 #define NCIRCLE 360 //number of points used to define equator, ecliptic and horizon
0024 
0025 HorizonComponent::HorizonComponent(SkyComposite *parent) : PointListComponent(parent)
0026 {
0027     KStarsData *data = KStarsData::Instance();
0028     emitProgressText(i18n("Creating horizon"));
0029 
0030     //Define Horizon
0031     for (unsigned int i = 0; i < NCIRCLE; ++i)
0032     {
0033         std::shared_ptr<SkyPoint> o(new SkyPoint());
0034 
0035         o->setAz(i * 360. / NCIRCLE);
0036         o->setAlt(0.0);
0037 
0038         o->HorizontalToEquatorial(data->lst(), data->geo()->lat());
0039         pointList().append(o);
0040     }
0041 }
0042 
0043 bool HorizonComponent::selected()
0044 {
0045     return Options::showHorizon() || Options::showGround();
0046 }
0047 
0048 void HorizonComponent::update(KSNumbers *)
0049 {
0050     if (!selected())
0051         return;
0052 
0053     KStarsData *data = KStarsData::Instance();
0054 
0055     for (auto &p : pointList())
0056     {
0057         p->HorizontalToEquatorial(data->lst(), data->geo()->lat());
0058     }
0059 }
0060 
0061 //Only half of the Horizon circle is ever valid, the invalid half is "behind" the observer.
0062 //To select the valid half, we start with the azimuth of the central focus point.
0063 //The valid horizon points have azimuth between this az +- 90
0064 //This is true for Equatorial or Horizontal coordinates
0065 void HorizonComponent::draw(SkyPainter *skyp)
0066 {
0067     if (!selected())
0068         return;
0069 
0070     KStarsData *data = KStarsData::Instance();
0071 
0072     skyp->setPen(QPen(QColor(data->colorScheme()->colorNamed("HorzColor")), 2, Qt::SolidLine));
0073 
0074     if (Options::showGround())
0075         skyp->setBrush(QColor(data->colorScheme()->colorNamed("HorzColor")));
0076     else
0077         skyp->setBrush(Qt::NoBrush);
0078 
0079     SkyPoint labelPoint;
0080     bool drawLabel;
0081     skyp->drawHorizon(Options::showGround(), &labelPoint, &drawLabel);
0082 
0083     if (drawLabel)
0084     {
0085         SkyPoint labelPoint2;
0086         labelPoint2.setAlt(0.0);
0087         labelPoint2.setAz(labelPoint.az().Degrees() + 1.0);
0088         labelPoint2.HorizontalToEquatorial(data->lst(), data->geo()->lat());
0089     }
0090 
0091     drawCompassLabels();
0092 }
0093 
0094 void HorizonComponent::drawCompassLabels()
0095 {
0096 #ifndef KSTARS_LITE
0097     SkyPoint c;
0098     QPointF cpoint;
0099     bool visible;
0100 
0101     const Projector *proj = SkyMap::Instance()->projector();
0102     KStarsData *data      = KStarsData::Instance();
0103 
0104     SkyLabeler *skyLabeler = SkyLabeler::Instance();
0105     // Set proper color for labels
0106     QColor color(data->colorScheme()->colorNamed("CompassColor"));
0107     skyLabeler->setPen(QPen(QBrush(color), 1, Qt::SolidLine));
0108 
0109     double az = -0.01;
0110     static QString name[8];
0111     name[0] = i18nc("Northeast", "NE");
0112     name[1] = i18nc("East", "E");
0113     name[2] = i18nc("Southeast", "SE");
0114     name[3] = i18nc("South", "S");
0115     name[4] = i18nc("Southwest", "SW");
0116     name[5] = i18nc("West", "W");
0117     name[6] = i18nc("Northwest", "NW");
0118     name[7] = i18nc("North", "N");
0119 
0120     for (const auto &item : name)
0121     {
0122         az += 45.0;
0123         c.setAz(az);
0124         c.setAlt(0.0);
0125         if (!Options::useAltAz())
0126         {
0127             c.HorizontalToEquatorial(data->lst(), data->geo()->lat());
0128         }
0129 
0130         cpoint = proj->toScreen(&c, false, &visible);
0131         if (visible && proj->onScreen(cpoint))
0132         {
0133             skyLabeler->drawGuideLabel(cpoint, item, 0.0);
0134         }
0135     }
0136 #endif
0137 }