File indexing completed on 2024-04-21 14:43:59

0001 /*
0002     SPDX-FileCopyrightText: 2001-2005 Jason Harris <jharris@30doradus.org>
0003     SPDX-FileCopyrightText: 2003-2005 Pablo de Vicente <p.devicente@wanadoo.es>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include <KLocalizedString>
0011 
0012 #include "cachingdms.h"
0013 #include "timezonerule.h"
0014 #include "kstarsdatetime.h"
0015 
0016 /**
0017  * @class GeoLocation
0018  * Contains all relevant information for specifying a location
0019  * on Earth: City Name, State/Province name, Country Name,
0020  * Longitude, Latitude, Elevation, Time Zone, and Daylight Savings
0021  * Time rule.
0022  *
0023  * @short Relevant data about an observing location on Earth.
0024  * @author Jason Harris
0025  * @version 1.0
0026  */
0027 class GeoLocation
0028 {
0029     public:
0030         /** Constructor using dms objects to specify longitude and latitude.
0031              * @param lng the longitude
0032              * @param lat the latitude
0033              * @param name the name of the city/town/location
0034              * @param province the name of the province/US state
0035              * @param country the name of the country
0036              * @param TZ the base time zone offset from Greenwich, UK
0037              * @param TZrule pointer to the daylight savings time rule
0038              * @param elevation the elevation above sea level (in meters)
0039              * @param readOnly whether the location is read only or updatable.
0040              * @param iEllips type of geodetic ellipsoid model
0041              */
0042         GeoLocation(const dms &lng, const dms &lat, const QString &name = "Nowhere", const QString &province = "Nowhere",
0043                     const QString &country = "Nowhere", double TZ = 0, TimeZoneRule *TZrule = nullptr,
0044                     double elevation = -10, bool readOnly = false, int iEllips = 4);
0045 
0046         /** Constructor using doubles to specify X, Y and Z referred to the center of the Earth.
0047              * @param x the x-position, in m
0048              * @param y the y-position, in m
0049              * @param z the z-position, in m
0050              * @param name the name of the city/town/location
0051              * @param province the name of the province/US state
0052              * @param country the name of the country
0053              * @param TZ the base time zone offset from Greenwich, UK
0054              * @param TZrule pointer to the daylight savings time rule
0055              * @param elevation the elevation above sea level (in meters)
0056              * @param readOnly whether the location is read only or updatable.
0057              * @param iEllips type of geodetic ellipsoid model
0058              */
0059         GeoLocation(double x, double y, double z, const QString &name = "Nowhere", const QString &province = "Nowhere",
0060                     const QString &country = "Nowhere", double TZ = 0, TimeZoneRule *TZrule = nullptr,
0061                     double elevation = -10, bool readOnly = false, int iEllips = 4);
0062 
0063         /** @return pointer to the longitude dms object */
0064         const CachingDms *lng() const
0065         {
0066             return &Longitude;
0067         }
0068 
0069         /** @return pointer to the latitude dms object */
0070         const CachingDms *lat() const
0071         {
0072             return &Latitude;
0073         }
0074 
0075         /** @return elevation above seal level (meters) */
0076         double elevation() const
0077         {
0078             return Elevation;
0079         }
0080 
0081         /** @return X position in m */
0082         double xPos() const
0083         {
0084             return PosCartX;
0085         }
0086 
0087         /** @return Y position in m */
0088         double yPos() const
0089         {
0090             return PosCartY;
0091         }
0092 
0093         /** @return Z position in m */
0094         double zPos() const
0095         {
0096             return PosCartZ;
0097         }
0098 
0099         /** @return index identifying the geodetic ellipsoid model */
0100         int ellipsoid() const
0101         {
0102             return indexEllipsoid;
0103         }
0104 
0105         /** @return untranslated City name */
0106         QString name() const
0107         {
0108             return Name;
0109         }
0110 
0111         /** @return translated City name */
0112         QString translatedName() const;
0113 
0114         /** @return untranslated Province name */
0115         QString province() const
0116         {
0117             return Province;
0118         }
0119 
0120         /** @return translated Province name */
0121         QString translatedProvince() const;
0122 
0123         /** @return untranslated Country name */
0124         QString country() const
0125         {
0126             return Country;
0127         }
0128 
0129         /** @return translated Country name */
0130         QString translatedCountry() const;
0131 
0132         /** @return comma-separated city, province, country names (each localized) */
0133         QString fullName() const;
0134 
0135         /** @return time zone without DST correction */
0136         double TZ0() const
0137         {
0138             return TimeZone;
0139         }
0140 
0141         /** @return time zone, including any DST correction. */
0142         double TZ() const
0143         {
0144             if (TZrule)
0145                 return TimeZone + TZrule->deltaTZ();
0146             return TimeZone;
0147         }
0148 
0149         /** @return pointer to time zone rule object */
0150         TimeZoneRule *tzrule()
0151         {
0152             return TZrule;
0153         }
0154 
0155         /** Set Time zone.
0156              * @param value the new time zone */
0157         void setTZ0(double value)
0158         {
0159             TimeZone = value;
0160         }
0161 
0162         /** Set Time zone rule.
0163              * @param value pointer to the new time zone rule */
0164         void setTZRule(TimeZoneRule *value)
0165         {
0166             TZrule = value;
0167         }
0168 
0169         /** Set longitude according to dms argument.
0170              * @param l the new longitude */
0171         void setLong(const dms &l)
0172         {
0173             Longitude = l;
0174             geodToCart();
0175         }
0176 
0177         /** Set latitude according to dms argument.
0178              * @param l the new latitude
0179              */
0180         void setLat(const dms &l)
0181         {
0182             Latitude = l;
0183             geodToCart();
0184         }
0185 
0186         /** Set elevation above sea level
0187              * @param hg the new elevation (meters)
0188              */
0189         void setElevation(double hg)
0190         {
0191             Elevation = hg;
0192             geodToCart();
0193         }
0194 
0195         /** Set X
0196              * @param x the new x-position (meters)
0197              */
0198         void setXPos(double x)
0199         {
0200             PosCartX = x;
0201             cartToGeod();
0202         }
0203         /** Set Y
0204              * @param y the new y-position (meters)
0205              */
0206         void setYPos(double y)
0207         {
0208             PosCartY = y;
0209             cartToGeod();
0210         }
0211         /** Set Z
0212              * @param z the new z-position (meters)
0213              */
0214         void setZPos(double z)
0215         {
0216             PosCartZ = z;
0217             cartToGeod();
0218         }
0219 
0220         /** Update Latitude, Longitude and Height according to new ellipsoid. These are
0221              * computed from XYZ which do NOT change on changing the ellipsoid.
0222              * @param i index to identify the ellipsoid
0223              */
0224         void changeEllipsoid(int i);
0225 
0226         /** Set City name according to argument.
0227              * @param n new city name
0228              */
0229         void setName(const QString &n)
0230         {
0231             Name = n;
0232         }
0233 
0234         /** Set Province name according to argument.
0235              * @param n new province name
0236              */
0237         void setProvince(const QString &n)
0238         {
0239             Province = n;
0240         }
0241 
0242         /** Set Country name according to argument.
0243              * @param n new country name
0244              */
0245         void setCountry(const QString &n)
0246         {
0247             Country = n;
0248         }
0249 
0250         /** Converts from cartesian coordinates in meters to longitude,
0251              * latitude and height on a standard geoid for the Earth. The
0252              * geoid is characterized by two parameters: the semimajor axis
0253              * and the flattening.
0254              *
0255              * @note The astronomical zenith is defined as the perpendicular to
0256              * the real geoid. The geodetic zenith is the perpendicular to the
0257              * standard geoid. Both zeniths differ due to local gravitational
0258              * anomalies.
0259              *
0260              * Algorithm is from "GPS Satellite Surveying", A. Leick, page 184.
0261              */
0262         void cartToGeod();
0263 
0264         /** Converts from longitude, latitude and height on a standard
0265              * geoid of the Earth to cartesian coordinates in meters. The geoid
0266              * is characterized by two parameters: the semimajor axis and the
0267              * flattening.
0268              *
0269              * @note The astronomical zenith is defined as the perpendicular to
0270              * the real geoid. The geodetic zenith is the perpendicular to the
0271              * standard geoid. Both zeniths differ due to local gravitational
0272              * anomalies.
0273              *
0274              * Algorithm is from "GPS Satellite Surveying", A. Leick, page 184.
0275              */
0276         void geodToCart();
0277 
0278         /** The geoid is an elliposid which fits the shape of the Earth. It is
0279              * characterized by two parameters: the semimajor axis and the
0280              * flattening.
0281              *
0282              * @param i is the index which allows to identify the parameters for the
0283              * chosen elliposid. 1="IAU76", 2="GRS80", 3="MERIT83", 4="WGS84",
0284              * 5="IERS89".
0285              */
0286         void setEllipsoid(int i);
0287 
0288         /**
0289          * @brief distanceTo Return the distance in km from this location to the given longitude and latitude
0290          * @param longitude Target site longitude
0291          * @param latitude Target site latitude
0292          * @return distance in kilometers between this site and the target site.
0293          */
0294         double distanceTo(const dms &longitude, const dms &latitude);
0295 
0296         dms GSTtoLST(const dms &gst) const
0297         {
0298             return dms(gst.Degrees() + Longitude.Degrees());
0299         }
0300         dms LSTtoGST(const dms &lst) const
0301         {
0302             return dms(lst.Degrees() - Longitude.Degrees());
0303         }
0304 
0305         KStarsDateTime UTtoLT(const KStarsDateTime &ut) const;
0306         KStarsDateTime LTtoUT(const KStarsDateTime &lt) const;
0307 
0308         /** Computes the velocity in km/s of an observer on the surface of the Earth
0309              * referred to a system whose origin is the center of the Earth. The X and
0310              * Y axis are contained in the equator and the X axis is towards the nodes
0311              * line. The Z axis is along the poles.
0312              *
0313              * @param vtopo[] Topocentric velocity. The resultant velocity is available
0314              *        in this array.
0315              * @param gt Greenwich sideral time for which we want to compute the topocentric velocity.
0316              */
0317         void TopocentricVelocity(double vtopo[], const dms &gt);
0318 
0319         /** @return Local Mean Sidereal Time.
0320              * @param jd Julian date
0321              */
0322         double LMST(double jd);
0323 
0324         bool isReadOnly() const;
0325         void setReadOnly(bool value);
0326 
0327     private:
0328         CachingDms Longitude, Latitude;
0329         QString Name, Province, Country;
0330         TimeZoneRule *TZrule;
0331         double TimeZone, Elevation;
0332         double axis, flattening;
0333         long double PosCartX, PosCartY, PosCartZ;
0334         int indexEllipsoid;
0335         bool ReadOnly;
0336 };