Kstars

geolocation.cpp
1 /*
2  SPDX-FileCopyrightText: 2001-2005 Jason Harris <[email protected]>
3  SPDX-FileCopyrightText: 2003-2005 Pablo de Vicente <[email protected]>
4 
5  SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "geolocation.h"
9 
10 #include "timezonerule.h"
11 
12 GeoLocation::GeoLocation(const dms &lng, const dms &lat, const QString &name, const QString &province, const QString &country,
13  double tz, TimeZoneRule *tzrule, double elevation, bool readOnly, int iEllips) :
14  Longitude(lng), Latitude(lat)
15 {
16  Name = name;
17  Province = province;
18  Country = country;
19  TimeZone = tz;
20  TZrule = tzrule;
21  Elevation = elevation;
22  indexEllipsoid = iEllips;
23  ReadOnly = readOnly;
24  setEllipsoid(indexEllipsoid);
25  geodToCart();
26 }
27 
28 GeoLocation::GeoLocation(double x, double y, double z, const QString &name, const QString &province,
29  const QString &country, double TZ, TimeZoneRule *tzrule, double elevation, bool readOnly, int iEllips)
30 {
31  PosCartX = x;
32  PosCartY = y;
33  PosCartZ = z;
34  Name = name;
35  Province = province;
36  Country = country;
37  TimeZone = TZ;
38  TZrule = tzrule;
39  Elevation = elevation;
40  indexEllipsoid = iEllips;
41  ReadOnly = readOnly;
42  setEllipsoid(indexEllipsoid);
43  cartToGeod();
44 }
45 
47 {
48  if (country().isEmpty())
49  return translatedName();
50  else if (province().isEmpty())
51  {
52  return QString("%1, %2").arg(translatedName(), translatedCountry());
53  }
54  else
55  {
56  return QString("%1, %2, %3").arg(translatedName(), translatedProvince(), translatedCountry());
57  }
58 }
59 
61 {
62  static const double A[] = { 6378140.0, 6378137.0, 6378137.0, 6378137.0, 6378136.0 };
63  static const double F[] = { 0.0033528131779, 0.0033528106812, 0.0033528131779, 0.00335281066474, 0.0033528131779 };
64 
65  Q_ASSERT(i >= 0 && (unsigned int)i < sizeof(A) / sizeof(A[0]) && "Index must be in bounds");
66  axis = A[i];
67  flattening = F[i];
68 }
69 
71 {
72  setEllipsoid(index);
73  cartToGeod();
74 }
75 
77 {
78  QString context;
79  if (province().isEmpty())
80  {
81  context = QString("City in %1").arg(country());
82  }
83  else
84  {
85  context = QString("City in %1 %2").arg(province(), country());
86  }
87  return Name.isEmpty() ? QString() : i18nc(context.toUtf8().data(), Name.toUtf8().data());
88 }
89 
91 {
92  return Province.isEmpty() ?
93  QString() :
94  i18nc(QString("Region/state in " + country()).toUtf8().data(), Province.toUtf8().data());
95 }
96 
98 {
99  return Country.isEmpty() ? QString() : i18nc("Country name", Country.toUtf8().data());
100 }
101 
103 {
104  static const double RIT = 2.7778e-6;
105  double e2, rpro, lat1, xn, sqrtP2, latd, sinl;
106 
107  e2 = 2 * flattening - flattening * flattening;
108 
109  sqrtP2 = sqrt(PosCartX * PosCartX + PosCartY * PosCartY);
110 
111  rpro = PosCartZ / sqrtP2;
112  latd = atan2(rpro, (1 - e2));
113  lat1 = 0.;
114 
115  while (fabs(latd - lat1) > RIT)
116  {
117  double s1 = sin(latd);
118 
119  lat1 = latd;
120  xn = axis / (sqrt(1 - e2 * s1 * s1));
121  latd = atan2(static_cast<long double>(rpro) * (1 + e2 * xn * s1), PosCartZ);
122  }
123 
124  sinl = sin(latd);
125  xn = axis / (sqrt(1 - e2 * sinl * sinl));
126 
127  Elevation = sqrtP2 / cos(latd) - xn;
128  Longitude.setRadians(atan2(PosCartY, PosCartX));
129  Latitude.setRadians(latd);
130 }
131 
133 {
134  double e2, xn;
135  double sinLong, cosLong, sinLat, cosLat;
136 
137  e2 = 2 * flattening - flattening * flattening;
138 
139  Longitude.SinCos(sinLong, cosLong);
140  Latitude.SinCos(sinLat, cosLat);
141 
142  xn = axis / (sqrt(1 - e2 * sinLat * sinLat));
143  PosCartX = (xn + Elevation) * cosLat * cosLong;
144  PosCartY = (xn + Elevation) * cosLat * sinLong;
145  PosCartZ = (xn * (1 - e2) + Elevation) * sinLat;
146 }
147 
148 void GeoLocation::TopocentricVelocity(double vtopo[], const dms &gst)
149 {
150  double Wearth = 7.29211510e-5; // rads/s
151  dms angularVEarth;
152 
153  dms time = GSTtoLST(gst);
154  // angularVEarth.setRadians(time.Hours()*Wearth*3600.);
155  double se, ce;
156  // angularVEarth.SinCos(se,ce);
157  time.SinCos(se, ce);
158 
159  double d0 = sqrt(PosCartX * PosCartX + PosCartY * PosCartY);
160  // km/s
161  vtopo[0] = -d0 * Wearth * se / 1000.;
162  vtopo[1] = d0 * Wearth * ce / 1000.;
163  vtopo[2] = 0.;
164 }
165 
166 double GeoLocation::LMST(double jd)
167 {
168  int divresult;
169  double ut, tu, gmst, theta;
170 
171  ut = (jd + 0.5) - floor(jd + 0.5);
172  jd -= ut;
173  tu = (jd - 2451545.) / 36525.;
174 
175  gmst = 24110.54841 + tu * (8640184.812866 + tu * (0.093104 - tu * 6.2e-6));
176  divresult = (int)((gmst + 8.6400e4 * 1.00273790934 * ut) / 8.6400e4);
177  gmst = (gmst + 8.6400e4 * 1.00273790934 * ut) - (double)divresult * 8.6400e4;
178  theta = 2. * dms::PI * gmst / (24. * 60. * 60.);
179  divresult = (int)((theta + Longitude.radians()) / (2. * dms::PI));
180  return ((theta + Longitude.radians()) - (double)divresult * 2. * dms::PI);
181 }
182 
183 bool GeoLocation::isReadOnly() const
184 {
185  return ReadOnly;
186 }
187 
188 void GeoLocation::setReadOnly(bool value)
189 {
190  ReadOnly = value;
191 }
192 
193 KStarsDateTime GeoLocation::UTtoLT(const KStarsDateTime &ut) const
194 {
195  KStarsDateTime lt = ut.addSecs(int(3600. * TZ()));
196  // 2017-08-11 (Jasem): setUtcOffset is deprecated
197  //lt.setUtcOffset(int(3600. * TZ()));
199 
200  return lt;
201 }
202 
203 KStarsDateTime GeoLocation::LTtoUT(const KStarsDateTime &lt) const
204 {
205  KStarsDateTime ut = lt.addSecs(int(-3600. * TZ()));
206  ut.setTimeSpec(Qt::UTC);
207  // 2017-08-11 (Jasem): setUtcOffset is deprecated
208  //ut.setUtcOffset(0);
209 
210  return ut;
211 }
212 
213 double GeoLocation::distanceTo(const dms &longitude, const dms &latitude)
214 {
215  const double R = 6378.135;
216 
217  double diffLongitude = (Longitude - longitude).radians();
218  double diffLatitude = (Latitude - latitude).radians();
219 
220  double a = sin(diffLongitude / 2) * sin(diffLongitude / 2) + cos(Longitude.radians()) * cos(longitude.radians()) *
221  sin(diffLatitude / 2) * sin(diffLatitude / 2);
222  double c = 2 * atan2(sqrt(a), sqrt(1 - a));
223 
224  double distance = R * c;
225 
226  return distance;
227 }
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
static constexpr double PI
PI is a const static member; it's public so that it can be used anywhere, as long as dms....
Definition: dms.h:380
double distanceTo(const dms &longitude, const dms &latitude)
distanceTo Return the distance in km from this location to the given longitude and latitude
QString fullName() const
Definition: geolocation.cpp:46
LocalTime
void changeEllipsoid(int i)
Update Latitude, Longitude and Height according to new ellipsoid.
Definition: geolocation.cpp:70
void SinCos(double &s, double &c) const
Get the sine and cosine together.
Definition: cachingdms.h:175
void SinCos(double &s, double &c) const
Compute Sine and Cosine of the angle simultaneously.
Definition: dms.h:439
void geodToCart()
Converts from longitude, latitude and height on a standard geoid of the Earth to cartesian coordinate...
double TZ() const
Definition: geolocation.h:142
TimeZoneRule * tzrule()
Definition: geolocation.h:150
GeoLocation(const dms &lng, const dms &lat, const QString &name="Nowhere", const QString &province="Nowhere", const QString &country="Nowhere", double TZ=0, TimeZoneRule *TZrule=nullptr, double elevation=-10, bool readOnly=false, int iEllips=4)
Constructor using dms objects to specify longitude and latitude.
Definition: geolocation.cpp:12
KStarsDateTime addSecs(double s) const
QString country() const
Definition: geolocation.h:124
void setRadians(const double &a) override
Sets the angle in radians.
Definition: cachingdms.h:136
double elevation() const
Definition: geolocation.h:76
bool isEmpty() const const
QByteArray toUtf8() const const
QString translatedName() const
Definition: geolocation.cpp:76
double LMST(double jd)
void setTimeSpec(Qt::TimeSpec spec)
QString translatedCountry() const
Definition: geolocation.cpp:97
QString translatedProvince() const
Definition: geolocation.cpp:90
QString name() const
Definition: geolocation.h:106
QString province() const
Definition: geolocation.h:115
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
double radians() const
Express the angle in radians.
Definition: dms.h:320
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void cartToGeod()
Converts from cartesian coordinates in meters to longitude, latitude and height on a standard geoid f...
void setEllipsoid(int i)
The geoid is an elliposid which fits the shape of the Earth.
Definition: geolocation.cpp:60
void TopocentricVelocity(double vtopo[], const dms &gt)
Computes the velocity in km/s of an observer on the surface of the Earth referred to a system whose o...
char * data()
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Tue Aug 16 2022 04:00:55 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.