• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 15291801018

28 May 2025 04:52AM UTC coverage: 11.931% (-0.02%) from 11.951%
15291801018

push

github

alex-w
Added new set of navigational stars (XIX century)

0 of 6 new or added lines in 2 files covered. (0.0%)

14124 existing lines in 74 files now uncovered.

14635 of 122664 relevant lines covered (11.93%)

18291.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

19.46
/src/core/StelLocation.cpp
1
/*
2
 * Copyright (C) 2008 Fabien Chereau
3
 *
4
 * This program is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU General Public License
6
 * as published by the Free Software Foundation; either version 2
7
 * of the License, or (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
17
 */
18

19
#include "StelLocation.hpp"
20
#include "StelCore.hpp"
21
#include "StelLocationMgr.hpp"
22
#include "StelUtils.hpp"
23
#include "StelModuleMgr.hpp"
24
#include "StelApp.hpp"
25
#include "Planet.hpp"
26
#include "SolarSystem.hpp"
27
#include <QTimeZone>
28
#include <QStringList>
29

30
const float StelLocation::DEFAULT_LIGHT_POLLUTION_LUMINANCE = StelCore::bortleScaleIndexToLuminance(2);
31

32
int StelLocation::metaTypeId = initMetaType();
33
int StelLocation::initMetaType()
19✔
34
{
35
        int id = qRegisterMetaType<StelLocation>();
19✔
36
#if (QT_VERSION<QT_VERSION_CHECK(6,0,0))
37
        qRegisterMetaTypeStreamOperators<StelLocation>();
38
#endif
39
        return id;
19✔
40
}
41

42
StelLocation::StelLocation(const QString &lName, const QString &lState, const QString &lRegion, const QString &plName, const float lng, const float lat, const int alt,
228✔
43
                                                   const int populationK, const QString &timeZone, const int bortleIndex, const QChar roleKey, const QString &landscapeID)
228✔
44
        : name(lName)
228✔
45
        , region(lRegion)
228✔
46
        , state(lState)
228✔
47
        , planetName(plName)
228✔
48
        , altitude(alt)
228✔
49
        , lightPollutionLuminance(StelCore::bortleScaleIndexToLuminance(bortleIndex))
228✔
50
        , landscapeKey(landscapeID)
228✔
51
        , population(populationK)
228✔
52
        , role(roleKey)
228✔
53
        , ianaTimeZone(timeZone)
228✔
54
        , isUserLocation(true)
228✔
55
        , longitude(lng)
228✔
56
        , latitude(lat)
228✔
57
{
58
}
228✔
59

60
StelLocation::StelLocation(const QString &lName, const QString &lState, const QString &lRegion, const float lng, const float lat, const int alt,
228✔
61
                                                   const int populationK, const QString &timeZone, const int bortleIndex, const QChar roleKey, const QString &landscapeID)
228✔
62
        : StelLocation(lName, lState, lRegion, "Earth", lng, lat, alt, populationK, timeZone, bortleIndex, roleKey, landscapeID)
228✔
63
{
64
}
228✔
65

66
// Output the location as a string ready to be stored in the user_location file
UNCOV
67
QString StelLocation::serializeToLine() const
×
68
{
69
        QString sanitizedTZ=StelLocationMgr::sanitizeTimezoneStringForLocationDB(ianaTimeZone);
×
UNCOV
70
        return QString("%1\t%2\t%3\t%4\t%5\t%6\t%7\t%8\t%9\t%10\t%11\t%12").arg(
×
71
                        name,
×
72
                        state,
×
73
                        region,
×
74
                        role,
×
75
                        QString::number(population/1000),
×
76
                        latitude<0 ? QString("%1S").arg(-latitude, 0, 'f', 6) : QString("%1N").arg(latitude, 0, 'f', 6),
×
77
                        longitude<0 ? QString("%1W").arg(-longitude, 0, 'f', 6) : QString("%1E").arg(longitude, 0, 'f', 6),
×
78
                        QString::number(altitude),
×
79
            QString::number(lightPollutionLuminance.isValid() ? lightPollutionLuminance.toFloat() : DEFAULT_LIGHT_POLLUTION_LUMINANCE)
×
80
            ).arg(
81
                        sanitizedTZ,
UNCOV
82
                        planetName,
×
UNCOV
83
                        landscapeKey);
×
84
}
×
85

86
QString StelLocation::getID() const
×
87
{
88
        if (name.isEmpty())
×
UNCOV
89
                return QString("%1, %2").arg(latitude).arg(longitude);
×
90

91
        if (!region.isEmpty())
×
UNCOV
92
                return QString("%1, %2").arg(name, region);
×
93
        else
94
                return name;
×
95
}
96

97
float StelLocation::getLatitude(bool suppressObserver)  const
467✔
98
{
99
        if (!suppressObserver && role==QChar('o'))
467✔
UNCOV
100
                return 90.f;
×
101
        else
102
                return latitude;
467✔
103
}
104

105
float StelLocation::getLongitude(bool suppressObserver) const
934✔
106
{
107
        if (!suppressObserver && role==QChar('o'))
934✔
UNCOV
108
                return 0.f;
×
109
        else
110
                return longitude;
934✔
111
}
112

113
// GZ TODO: These operators may require sanitizing for timezone names!
UNCOV
114
QDataStream& operator<<(QDataStream& out, const StelLocation& loc)
×
115
{
116
        const auto lum = loc.lightPollutionLuminance.toFloat();
×
UNCOV
117
        const int bortleScaleIndex = loc.lightPollutionLuminance.isValid() ? StelCore::luminanceToBortleScaleIndex(lum) : -1;
×
118
        out << loc.name << loc.state << loc.region << loc.role << loc.population << loc.getLatitude() << loc.getLongitude() << loc.altitude << bortleScaleIndex << loc.ianaTimeZone << loc.planetName << loc.landscapeKey << loc.isUserLocation;
×
119
        return out;
×
120
}
121

UNCOV
122
QDataStream& operator>>(QDataStream& in, StelLocation& loc)
×
123
{
124
        int bortleScaleIndex;
125
        float lng, lat;
UNCOV
126
        in >> loc.name >> loc.state >> loc.region >> loc.role >> loc.population >> lat >> lng >> loc.altitude >> bortleScaleIndex >> loc.ianaTimeZone >> loc.planetName >> loc.landscapeKey >> loc.isUserLocation;
×
UNCOV
127
        loc.setLongitude(lng);
×
128
        loc.setLatitude(lat);
×
129
        if(bortleScaleIndex > 0)
×
130
                loc.lightPollutionLuminance = StelCore::bortleScaleIndexToLuminance(bortleScaleIndex);
×
131
        return in;
×
132
}
133

UNCOV
134
QString StelLocation::getRegionFromCode(const QString &code)
×
135
{
136
        QString region;
×
UNCOV
137
        if (code.toInt()>0) // OK, this is code of geographical region
×
138
                region = StelLocationMgr::pickRegionFromCode(code.toInt());
×
139
        else
140
        {
UNCOV
141
                if (code.size() == 2) // The string equals to 2 chars - this is the ISO 3166-1 alpha 2 code for country
×
UNCOV
142
                        region = StelLocationMgr::pickRegionFromCountryCode(code);
×
143
                else
144
                        region = StelLocationMgr::pickRegionFromCountry(code); // This is the English name of country
×
145
        }
146
        if (region.isEmpty())
×
UNCOV
147
                region = code; // OK, this is just region
×
148

149
        return region;
×
UNCOV
150
}
×
151

152
// Parse a location from a line serialization
UNCOV
153
StelLocation StelLocation::createFromLine(const QString& rawline)
×
154
{
155
        StelLocation loc;
×
UNCOV
156
        const QStringList& splitline = rawline.split("\t");
×
157
        loc.name    = splitline.at(0).trimmed();
×
158
        loc.state   = splitline.at(1).trimmed();
×
159
        loc.region = getRegionFromCode(splitline.at(2).trimmed());
×
160
        loc.role    = splitline.at(3).at(0).toUpper();
×
161
        if (loc.role.isNull())
×
162
                loc.role = 'X';
×
163
        loc.population = static_cast<int> (splitline.at(4).toFloat()*1000);
×
164

165
        const QString& latstring = splitline.at(5).trimmed();
×
166
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
167
        loc.latitude = latstring.left(latstring.size() - 1).toFloat();
×
168
#else
169
        loc.latitude = latstring.leftRef(latstring.size() - 1).toFloat();
170
#endif
UNCOV
171
        if (latstring.endsWith('S'))
×
UNCOV
172
                loc.latitude=-loc.latitude;
×
173

174
        const QString& lngstring = splitline.at(6).trimmed();
×
175
#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0))
176
        loc.longitude = lngstring.left(lngstring.size() - 1).toFloat();
×
177
#else
178
        loc.longitude = lngstring.leftRef(lngstring.size() - 1).toFloat();
179
#endif
UNCOV
180
        if (lngstring.endsWith('W'))
×
UNCOV
181
                loc.longitude=-loc.longitude;
×
182

183
        loc.altitude = static_cast<int>(splitline.at(7).toFloat());
×
184

185
        if (splitline.size()>8)
×
186
        {
187
                bool ok;
UNCOV
188
                const auto bortleScaleIndex = splitline.at(8).toInt(&ok);
×
UNCOV
189
                if(bortleScaleIndex > 0)
×
190
                        loc.lightPollutionLuminance = StelCore::bortleScaleIndexToLuminance(bortleScaleIndex);
×
191
                if (ok==false)
×
192
                        loc.lightPollutionLuminance = DEFAULT_LIGHT_POLLUTION_LUMINANCE;
×
193
        }
194
        else
UNCOV
195
                loc.lightPollutionLuminance = DEFAULT_LIGHT_POLLUTION_LUMINANCE;
×
196

197
        if (splitline.size()>9)
×
198
        {
199
                // Parse time zone
UNCOV
200
                loc.ianaTimeZone = splitline.at(9).trimmed();
×
201
                // GZ Check whether the timezone ID is available in the current Qt/IANA list?
202
                if ( ! QTimeZone::isTimeZoneIdAvailable(loc.ianaTimeZone.toUtf8()))
×
203
                {
204
                        // Try to find a currently used IANA string from our known replacements.
UNCOV
205
                        QString fitName=StelLocationMgr::sanitizeTimezoneStringFromLocationDB(loc.ianaTimeZone);
×
UNCOV
206
                        qDebug() << "StelLocation::createFromLine(): TimeZone name for " << loc.name << " not found. Translating" << loc.ianaTimeZone << " to " << fitName;
×
207
                        loc.ianaTimeZone=fitName;
×
208
                }
×
209
        }
210

211
        // Parse planet name
UNCOV
212
        if (splitline.size()>10)
×
UNCOV
213
                loc.planetName = splitline.at(10).trimmed();
×
214
        else
215
                loc.planetName = "Earth"; // Earth by default
×
216

217
        // Parse optional associated landscape key
UNCOV
218
        if (splitline.size()>11)
×
UNCOV
219
                loc.landscapeKey = splitline.at(11).trimmed();
×
220

221
        return loc;
×
UNCOV
222
}
×
223

224
// Compute great-circle distance between two locations
UNCOV
225
float StelLocation::distanceDegrees(const float long1, const float lat1, const float long2, const float lat2)
×
226
{
227
        static const float DEGREES=M_PIf/180.0f;
UNCOV
228
        return std::acos( std::sin(lat1*DEGREES)*std::sin(lat2*DEGREES) +
×
UNCOV
229
                          std::cos(lat1*DEGREES)*std::cos(lat2*DEGREES) *
×
230
                          std::cos((long1-long2)*DEGREES) ) / DEGREES;
×
231
}
232
double StelLocation::distanceKm(Planet *planet, const double long1, const double lat1, const double long2, const double lat2)
×
233
{
234
        static const double DEGREES=M_PI/180.0;
UNCOV
235
        const double f = 1.0 - planet->getOneMinusOblateness(); // flattening
×
UNCOV
236
        const double a = planet->getEquatorialRadius()*AU;
×
237

238
        const double F = (lat1+lat2)*0.5*DEGREES;
×
UNCOV
239
        const double G = (lat1-lat2)*0.5*DEGREES;
×
240
        const double L = (long1-long2)*0.5*DEGREES;
×
241

242
        const double sinG=sin(G), cosG=cos(G), sinF=sin(F), cosF=cos(F), sinL=sin(L), cosL=cos(L);
×
UNCOV
243
        const double S  = sinG*sinG*cosL*cosL+cosF*cosF*sinL*sinL;
×
244
        const double C  = cosG*cosG*cosL*cosL+sinF*sinF*sinL*sinL;
×
245
        const double om = atan(sqrt(S/C));
×
246
        const double R  = sqrt(S*C)/om;
×
247
        const double D  = 2.*om*a;
×
248
        const double H1 = (3.0*R-1.0)/(2.0*C);
×
249
        const double H2 = (3.0*R+1.0)/(2.0*S);
×
250
        return D*(1.0+f*(H1*sinF*sinF*cosG*cosG-H2*cosF*cosF*sinG*sinG));
×
251
}
252
double StelLocation::distanceKm(const double otherLong, const double otherLat) const
×
253
{
254
        PlanetP planet=GETSTELMODULE(SolarSystem)->searchByEnglishName(planetName);
×
UNCOV
255
        return distanceKm(planet.data(), static_cast<double>(longitude), static_cast<double>(latitude), otherLong, otherLat);
×
256
}
×
257

258
double StelLocation::getAzimuthForLocation(double longObs, double latObs, double longTarget, double latTarget)
×
259
{
260
        longObs    *= M_PI_180;
×
UNCOV
261
        latObs     *= M_PI_180;
×
262
        longTarget *= M_PI_180;
×
263
        latTarget  *= M_PI_180;
×
264

265
        double az = atan2(sin(longTarget-longObs), cos(latObs)*tan(latTarget)-sin(latObs)*cos(longTarget-longObs));
×
UNCOV
266
        if (StelApp::getInstance().getFlagSouthAzimuthUsage())
×
267
                az += M_PI;
×
268
        return StelUtils::fmodpos(M_180_PI * az, 360.0);
×
269
}
270

UNCOV
271
double StelLocation::getAzimuthForLocation(double longTarget, double latTarget) const
×
272
{
273
        return getAzimuthForLocation(static_cast<double>(longitude), static_cast<double>(latitude), longTarget, latTarget);
×
274
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc