Kstars

geolocation.cpp
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#include "geolocation.h"
9
10#include "timezonerule.h"
11
12GeoLocation::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
28GeoLocation::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 {
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
148void 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
166double 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
183bool GeoLocation::isReadOnly() const
184{
185 return ReadOnly;
186}
187
188void GeoLocation::setReadOnly(bool value)
189{
190 ReadOnly = value;
191}
192
193KStarsDateTime 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
203KStarsDateTime GeoLocation::LTtoUT(const KStarsDateTime &lt) const
204{
205 KStarsDateTime ut = lt.addSecs(int(-3600. * TZ()));
207 // 2017-08-11 (Jasem): setUtcOffset is deprecated
208 //ut.setUtcOffset(0);
209
210 return ut;
211}
212
213double 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}
void setRadians(const double &a) override
Sets the angle in radians.
Definition cachingdms.h:136
void SinCos(double &s, double &c) const
Get the sine and cosine together.
Definition cachingdms.h:175
QString country() const
QString fullName() const
void cartToGeod()
Converts from cartesian coordinates in meters to longitude, latitude and height on a standard geoid f...
void geodToCart()
Converts from longitude, latitude and height on a standard geoid of the Earth to cartesian coordinate...
QString translatedCountry() const
void setEllipsoid(int i)
The geoid is an elliposid which fits the shape of the Earth.
double elevation() const
Definition geolocation.h:76
double distanceTo(const dms &longitude, const dms &latitude)
distanceTo Return the distance in km from this location to the given longitude and latitude
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.
void changeEllipsoid(int i)
Update Latitude, Longitude and Height according to new ellipsoid.
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...
QString province() const
double TZ() const
QString translatedName() const
QString translatedProvince() const
TimeZoneRule * tzrule()
double LMST(double jd)
QString name() const
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
KStarsDateTime addSecs(double s) const
This class provides the information needed to determine whether Daylight Savings Time (DST; a....
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
void SinCos(double &s, double &c) const
Compute Sine and Cosine of the angle simultaneously.
Definition dms.h:447
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:385
double radians() const
Express the angle in radians.
Definition dms.h:325
QString i18nc(const char *context, const char *text, const TYPE &arg...)
char * data()
void setTimeSpec(Qt::TimeSpec spec)
QString arg(Args &&... args) const const
bool isEmpty() const const
QByteArray toUtf8() const const
LocalTime
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:16:39 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.