1 /* 2 SPDX-FileCopyrightText: 2001-2005 Jason Harris <jharris@30doradus.org> 3 SPDX-FileCopyrightText: 2003-2005 Pablo de Vicente <p.devicente@wanadoo.es> 4 5 SPDX-License-Identifier: GPL-2.0-or-later 6 */ 7 8 #pragma once 9 10 #include <KLocalizedString> 11 12 #include "cachingdms.h" 13 #include "timezonerule.h" 14 #include "kstarsdatetime.h" 15 16 /** 17 * @class GeoLocation 18 * Contains all relevant information for specifying a location 19 * on Earth: City Name, State/Province name, Country Name, 20 * Longitude, Latitude, Elevation, Time Zone, and Daylight Savings 21 * Time rule. 22 * 23 * @short Relevant data about an observing location on Earth. 24 * @author Jason Harris 25 * @version 1.0 26 */ 27 class GeoLocation 28 { 29 public: 30 /** Constructor using dms objects to specify longitude and latitude. 31 * @param lng the longitude 32 * @param lat the latitude 33 * @param name the name of the city/town/location 34 * @param province the name of the province/US state 35 * @param country the name of the country 36 * @param TZ the base time zone offset from Greenwich, UK 37 * @param TZrule pointer to the daylight savings time rule 38 * @param elevation the elevation above sea level (in meters) 39 * @param readOnly whether the location is read only or updatable. 40 * @param iEllips type of geodetic ellipsoid model 41 */ 42 GeoLocation(const dms &lng, const dms &lat, const QString &name = "Nowhere", const QString &province = "Nowhere", 43 const QString &country = "Nowhere", double TZ = 0, TimeZoneRule *TZrule = nullptr, 44 double elevation = -10, bool readOnly = false, int iEllips = 4); 45 46 /** Constructor using doubles to specify X, Y and Z referred to the center of the Earth. 47 * @param x the x-position, in m 48 * @param y the y-position, in m 49 * @param z the z-position, in m 50 * @param name the name of the city/town/location 51 * @param province the name of the province/US state 52 * @param country the name of the country 53 * @param TZ the base time zone offset from Greenwich, UK 54 * @param TZrule pointer to the daylight savings time rule 55 * @param elevation the elevation above sea level (in meters) 56 * @param readOnly whether the location is read only or updatable. 57 * @param iEllips type of geodetic ellipsoid model 58 */ 59 GeoLocation(double x, double y, double z, const QString &name = "Nowhere", const QString &province = "Nowhere", 60 const QString &country = "Nowhere", double TZ = 0, TimeZoneRule *TZrule = nullptr, 61 double elevation = -10, bool readOnly = false, int iEllips = 4); 62 63 /** @return pointer to the longitude dms object */ lng()64 const CachingDms *lng() const 65 { 66 return &Longitude; 67 } 68 69 /** @return pointer to the latitude dms object */ lat()70 const CachingDms *lat() const 71 { 72 return &Latitude; 73 } 74 75 /** @return elevation above seal level (meters) */ elevation()76 double elevation() const 77 { 78 return Elevation; 79 } 80 81 /** @return X position in m */ xPos()82 double xPos() const 83 { 84 return PosCartX; 85 } 86 87 /** @return Y position in m */ yPos()88 double yPos() const 89 { 90 return PosCartY; 91 } 92 93 /** @return Z position in m */ zPos()94 double zPos() const 95 { 96 return PosCartZ; 97 } 98 99 /** @return index identifying the geodetic ellipsoid model */ ellipsoid()100 int ellipsoid() const 101 { 102 return indexEllipsoid; 103 } 104 105 /** @return untranslated City name */ name()106 QString name() const 107 { 108 return Name; 109 } 110 111 /** @return translated City name */ 112 QString translatedName() const; 113 114 /** @return untranslated Province name */ province()115 QString province() const 116 { 117 return Province; 118 } 119 120 /** @return translated Province name */ 121 QString translatedProvince() const; 122 123 /** @return untranslated Country name */ country()124 QString country() const 125 { 126 return Country; 127 } 128 129 /** @return translated Country name */ 130 QString translatedCountry() const; 131 132 /** @return comma-separated city, province, country names (each localized) */ 133 QString fullName() const; 134 135 /** @return time zone without DST correction */ TZ0()136 double TZ0() const 137 { 138 return TimeZone; 139 } 140 141 /** @return time zone, including any DST correction. */ TZ()142 double TZ() const 143 { 144 if (TZrule) 145 return TimeZone + TZrule->deltaTZ(); 146 return TimeZone; 147 } 148 149 /** @return pointer to time zone rule object */ tzrule()150 TimeZoneRule *tzrule() 151 { 152 return TZrule; 153 } 154 155 /** Set Time zone. 156 * @param value the new time zone */ setTZ0(double value)157 void setTZ0(double value) 158 { 159 TimeZone = value; 160 } 161 162 /** Set Time zone rule. 163 * @param value pointer to the new time zone rule */ setTZRule(TimeZoneRule * value)164 void setTZRule(TimeZoneRule *value) 165 { 166 TZrule = value; 167 } 168 169 /** Set longitude according to dms argument. 170 * @param l the new longitude */ setLong(const dms & l)171 void setLong(const dms &l) 172 { 173 Longitude = l; 174 geodToCart(); 175 } 176 177 /** Set latitude according to dms argument. 178 * @param l the new latitude 179 */ setLat(const dms & l)180 void setLat(const dms &l) 181 { 182 Latitude = l; 183 geodToCart(); 184 } 185 186 /** Set elevation above sea level 187 * @param hg the new elevation (meters) 188 */ setElevation(double hg)189 void setElevation(double hg) 190 { 191 Elevation = hg; 192 geodToCart(); 193 } 194 195 /** Set X 196 * @param x the new x-position (meters) 197 */ setXPos(double x)198 void setXPos(double x) 199 { 200 PosCartX = x; 201 cartToGeod(); 202 } 203 /** Set Y 204 * @param y the new y-position (meters) 205 */ setYPos(double y)206 void setYPos(double y) 207 { 208 PosCartY = y; 209 cartToGeod(); 210 } 211 /** Set Z 212 * @param z the new z-position (meters) 213 */ setZPos(double z)214 void setZPos(double z) 215 { 216 PosCartZ = z; 217 cartToGeod(); 218 } 219 220 /** Update Latitude, Longitude and Height according to new ellipsoid. These are 221 * computed from XYZ which do NOT change on changing the ellipsoid. 222 * @param i index to identify the ellipsoid 223 */ 224 void changeEllipsoid(int i); 225 226 /** Set City name according to argument. 227 * @param n new city name 228 */ setName(const QString & n)229 void setName(const QString &n) 230 { 231 Name = n; 232 } 233 234 /** Set Province name according to argument. 235 * @param n new province name 236 */ setProvince(const QString & n)237 void setProvince(const QString &n) 238 { 239 Province = n; 240 } 241 242 /** Set Country name according to argument. 243 * @param n new country name 244 */ setCountry(const QString & n)245 void setCountry(const QString &n) 246 { 247 Country = n; 248 } 249 250 /** Converts from cartesian coordinates in meters to longitude, 251 * latitude and height on a standard geoid for the Earth. The 252 * geoid is characterized by two parameters: the semimajor axis 253 * and the flattening. 254 * 255 * @note The astronomical zenith is defined as the perpendicular to 256 * the real geoid. The geodetic zenith is the perpendicular to the 257 * standard geoid. Both zeniths differ due to local gravitational 258 * anomalies. 259 * 260 * Algorithm is from "GPS Satellite Surveying", A. Leick, page 184. 261 */ 262 void cartToGeod(); 263 264 /** Converts from longitude, latitude and height on a standard 265 * geoid of the Earth to cartesian coordinates in meters. The geoid 266 * is characterized by two parameters: the semimajor axis and the 267 * flattening. 268 * 269 * @note The astronomical zenith is defined as the perpendicular to 270 * the real geoid. The geodetic zenith is the perpendicular to the 271 * standard geoid. Both zeniths differ due to local gravitational 272 * anomalies. 273 * 274 * Algorithm is from "GPS Satellite Surveying", A. Leick, page 184. 275 */ 276 void geodToCart(); 277 278 /** The geoid is an elliposid which fits the shape of the Earth. It is 279 * characterized by two parameters: the semimajor axis and the 280 * flattening. 281 * 282 * @param i is the index which allows to identify the parameters for the 283 * chosen elliposid. 1="IAU76", 2="GRS80", 3="MERIT83", 4="WGS84", 284 * 5="IERS89". 285 */ 286 void setEllipsoid(int i); 287 288 /** 289 * @brief distanceTo Return the distance in km from this location to the given longitude and latitude 290 * @param longitude Target site longitude 291 * @param latitude Target site latitude 292 * @return distance in kilometers between this site and the target site. 293 */ 294 double distanceTo(const dms &longitude, const dms &latitude); 295 GSTtoLST(const dms & gst)296 dms GSTtoLST(const dms &gst) const 297 { 298 return dms(gst.Degrees() + Longitude.Degrees()); 299 } LSTtoGST(const dms & lst)300 dms LSTtoGST(const dms &lst) const 301 { 302 return dms(lst.Degrees() - Longitude.Degrees()); 303 } 304 305 KStarsDateTime UTtoLT(const KStarsDateTime &ut) const; 306 KStarsDateTime LTtoUT(const KStarsDateTime <) const; 307 308 /** Computes the velocity in km/s of an observer on the surface of the Earth 309 * referred to a system whose origin is the center of the Earth. The X and 310 * Y axis are contained in the equator and the X axis is towards the nodes 311 * line. The Z axis is along the poles. 312 * 313 * @param vtopo[] Topocentric velocity. The resultant velocity is available 314 * in this array. 315 * @param gt Greenwich sideral time for which we want to compute the topocentric velocity. 316 */ 317 void TopocentricVelocity(double vtopo[], const dms >); 318 319 /** @return Local Mean Sidereal Time. 320 * @param jd Julian date 321 */ 322 double LMST(double jd); 323 324 bool isReadOnly() const; 325 void setReadOnly(bool value); 326 327 private: 328 CachingDms Longitude, Latitude; 329 QString Name, Province, Country; 330 TimeZoneRule *TZrule; 331 double TimeZone, Elevation; 332 double axis, flattening; 333 long double PosCartX, PosCartY, PosCartZ; 334 int indexEllipsoid; 335 bool ReadOnly; 336 }; 337