1 /*
2     SPDX-FileCopyrightText: 2009 Prakash Mohan <prakash.mohan@kdemail.net>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "skyobjects/kssun.h"
10 #include "skyobjects/ksmoon.h"
11 #include "kstarsdatetime.h"
12 
13 /**
14  *@class KSAlmanac
15  *
16  *A class that implements methods to find sun rise, sun set, twilight
17  *begin / end times, moon rise and moon set times.
18  *
19  *@short Implement methods to find important times in a day
20  *@author Prakash Mohan
21  *@version 1.0
22  */
23 
24 class GeoLocation;
25 
26 class KSAlmanac
27 {
28   public:
29     /**
30          *@brief KSAlmanac constructor initializing an almanac for the current KStarsData::Instance geolocation and time.
31          */
32     KSAlmanac();
33 
34     /**
35          *@brief KSAlmanac constructor initializing an almanac for an arbitrary geolocation and time.
36          *@param midnight is the midnight date and time to consider as beginning of the day at the "geo" location.
37          *@param geo is the GeoLocation to use for this almanac, defaulting to the KStarsData::Instance geolocation.
38          *@note if the timespec of midnight is local time, its UTC value at the geolocation "geo" will be used instead.
39          */
40     KSAlmanac(const KStarsDateTime &midnight, const GeoLocation *geo = nullptr);
41 
42     /**
43          *@short Get/set the date for computations to the given date.
44          *@param utc_midnight and local_midnight are the midnight date and time to consider as beginning of the day at the geo_ location, either UTC or local.
45          *@note The time must be the local time midnight of the day the almanac is required for, so that
46          *      resulting ephemerides are calculated around that time.
47          *@note These functions are not merged into a single timespec-aware one for backwards compatilibity.
48          */
49     /** @{ */
50     void setDate(const KStarsDateTime &utc_midnight);
setDateFromLT(const KStarsDateTime & local_midnight)51     void setDateFromLT(const KStarsDateTime &local_midnight) { setDate(geo->LTtoUT(local_midnight)); }
getDate()52     KStarsDateTime getDate() const { return dt; }
53     /** @} */
54 
55     /**
56          *@short Set the location for computations to the given location
57          *@param geo_ The location to set for computations
58          */
59     void setLocation(const GeoLocation *geo_);
60 
61     /**
62          *All the functions returns the fraction of the day given by getDate()
63          *as their return value
64          */
getSunRise()65     inline double getSunRise() const { return SunRise; }
getSunSet()66     inline double getSunSet() const { return SunSet; }
getMoonRise()67     inline double getMoonRise() const { return MoonRise; }
getMoonSet()68     inline double getMoonSet() const { return MoonSet; }
getDuskAstronomicalTwilight()69     inline double getDuskAstronomicalTwilight() const { return DuskAstronomicalTwilight; }
getDawnAstronomicalTwilight()70     inline double getDawnAstronomicalTwilight() const { return DawnAstronomicalTwilight; }
71 
72     /**
73          *These functions return the max and min altitude of the sun during the course of the day in degrees
74          */
getSunMaxAlt()75     inline double getSunMaxAlt() const { return SunMaxAlt; }
getSunMinAlt()76     inline double getSunMinAlt() const { return SunMinAlt; }
77 
78     /**
79          *@return the moon phase in degrees at the given date/time. Ranges is [0, 180]
80          */
getMoonPhase()81     inline double getMoonPhase() const { return MoonPhase; }
82 
83     /**
84          *@return get the moon illuminated fraction at the given date/time. Range is [0.,1.]
85          */
getMoonIllum()86     inline double getMoonIllum() const { return m_Moon.illum(); }
87 
sunRise()88     inline QTime sunRise() const { return SunRiseT; }
sunSet()89     inline QTime sunSet() const { return SunSetT; }
moonRise()90     inline QTime moonRise() const { return MoonRiseT; }
moonSet()91     inline QTime moonSet() const { return MoonSetT; }
92 
93     /**
94          *@short Convert the zenithal distance of the sun to fraction of the day
95          *@param z Zenithal angular distance
96          *@return Time as a fraction of the day, at which the zenithal distance is attained by the sun
97          *@note This is accurate only for zenithal angles close to sunset. TODO: Make this more accurate
98          */
99     double sunZenithAngleToTime(double z) const;
100 
101   private:
102     void update();
103 
104     /**
105           * This function computes the rise and set time for the given SkyObject. This is done in order to
106           * have a common function for the computation of the Sun and Moon rise and set times.
107           */
108     void RiseSetTime(SkyObject *o, double *riseTime, double *setTime, QTime *RiseTime, QTime *SetTime);
109 
110     /**
111          * Compute the dawn and dusk times in a [-12,+12] hours around the day midnight of this KSAlmanac, if any, as well as min and max altitude.
112          * - If the day midnight of this KSAlmanac is during astronomical night time, dusk will be before dawn.
113          * - If the day midnight of this KSAlmanac is during twilight or day time, dawn will be before dusk.
114          * - If there is no astronomical night time, dawn and dusk will be set to the time of minimal altitude of the Sun.
115          * - If there is no twilight or day time, dawn and dusk will be set to the time of minimal altitude of the Sun.
116          */
117     void findDawnDusk(double altitude = -18.0);
118 
119     /**
120          * Computes the moon phase at the given date/time
121          */
122     void findMoonPhase();
123 
124     /**
125          * FIXME: More code duplication!
126          * findAltitude should really be part of KSEngine. Copying from ObservingList.
127          * returns in degrees
128          */
129     double findAltitude(const SkyPoint *p, double hour);
130 
131     KSSun m_Sun;
132     KSMoon m_Moon;
133     KStarsDateTime dt;
134 
135     const GeoLocation *geo { nullptr };
136     double SunRise { 0 };
137     double SunSet { 0 };
138     double MoonRise { 0 };
139     double MoonSet { 0 };
140     double DuskAstronomicalTwilight { 0 };
141     double DawnAstronomicalTwilight { 0 };
142     double SunMinAlt { 0 };
143     double SunMaxAlt { 0 };
144     double MoonPhase { 0 };
145     QTime SunRiseT, SunSetT, MoonRiseT, MoonSetT, DuskAstronomicalTwilightT, DawnAstronomicalTwilightT;
146 };
147