Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qlocationutils_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4#ifndef QLOCATIONUTILS_P_H
5#define QLOCATIONUTILS_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/QtGlobal>
19#include <math.h> // needed for non-std:: versions of functions
20#include <qmath.h>
21#include <QtPositioning/QGeoCoordinate>
22#include <QtPositioning/QNmeaSatelliteInfoSource>
23#include <QtPositioning/private/qpositioningglobal_p.h>
24
25static const double offsetEpsilon = 1e-12; // = 0.000000000001
26static const double leftOffset = -180.0 + offsetEpsilon;
27static const double rightOffset = 180.0 - offsetEpsilon;
28
29QT_BEGIN_NAMESPACE
30class QTime;
31class QByteArray;
32
33class QGeoPositionInfo;
34class QGeoSatelliteInfo;
35class Q_POSITIONING_EXPORT QLocationUtils
36{
37public:
38 enum CardinalDirection {
39 CardinalN,
40 CardinalE,
41 CardinalS,
42 CardinalW,
43 CardinalNE,
44 CardinalSE,
45 CardinalSW,
46 CardinalNW,
47 CardinalNNE,
48 CardinalENE,
49 CardinalESE,
50 CardinalSSE,
51 CardinalSSW,
52 CardinalWSW,
53 CardinalWNW,
54 CardinalNNW
55 };
56
57 enum NmeaSentence {
58 NmeaSentenceInvalid,
59 NmeaSentenceGGA, // Fix information
60 NmeaSentenceGSA, // Overall Satellite data, such as HDOP and VDOP
61 NmeaSentenceGLL, // Lat/Lon data
62 NmeaSentenceRMC, // Recommended minimum data for gps
63 NmeaSentenceVTG, // Vector track an Speed over the Ground
64 NmeaSentenceZDA, // Date and Time
65 NmeaSentenceGSV // Per-Satellite Info
66 };
67
68 inline static bool isValidLat(double lat) {
69 return lat >= -90.0 && lat <= 90.0;
70 }
71 inline static bool isValidLong(double lng) {
72 return lng >= -180.0 && lng <= 180.0;
73 }
74
75 inline static double clipLat(double lat, double clipValue = 90.0) {
76 if (lat > clipValue)
77 lat = clipValue;
78 else if (lat < -clipValue)
79 lat = -clipValue;
80 return lat;
81 }
82
83 inline static double wrapLong(double lng) {
84 if (lng > 180.0)
85 lng -= 360.0;
86 else if (lng < -180.0)
87 lng += 360.0;
88 return lng;
89 }
90
91 inline static CardinalDirection azimuthToCardinalDirection4(double azimuth)
92 {
93 azimuth = fmod(azimuth, 360.0);
94 if (azimuth < 45.0 || azimuth > 315.0 )
95 return CardinalN;
96 else if (azimuth < 135.0)
97 return CardinalE;
98 else if (azimuth < 225.0)
99 return CardinalS;
100 else
101 return CardinalW;
102 }
103
104 inline static CardinalDirection azimuthToCardinalDirection8(double azimuth)
105 {
106 azimuth = fmod(azimuth, 360.0);
107 if (azimuth < 22.5 || azimuth > 337.5 )
108 return CardinalN;
109 else if (azimuth < 67.5)
110 return CardinalNE;
111 else if (azimuth < 112.5)
112 return CardinalE;
113 else if (azimuth < 157.5)
114 return CardinalSE;
115 else if (azimuth < 202.5)
116 return CardinalS;
117
118 else if (azimuth < 247.5)
119 return CardinalSW;
120 else if (azimuth < 292.5)
121 return CardinalW;
122 else
123 return CardinalNW;
124 }
125
126 inline static CardinalDirection azimuthToCardinalDirection16(double azimuth)
127 {
128 azimuth = fmod(azimuth, 360.0);
129 if (azimuth < 11.5 || azimuth > 348.75 )
130 return CardinalN;
131 else if (azimuth < 33.75)
132 return CardinalNNE;
133 else if (azimuth < 56.25)
134 return CardinalNE;
135 else if (azimuth < 78.75)
136 return CardinalENE;
137 else if (azimuth < 101.25)
138 return CardinalE;
139 else if (azimuth < 123.75)
140 return CardinalESE;
141 else if (azimuth < 146.25)
142 return CardinalSE;
143 else if (azimuth < 168.75)
144 return CardinalSSE;
145 else if (azimuth < 191.25)
146 return CardinalS;
147
148 else if (azimuth < 213.75)
149 return CardinalSSW;
150 else if (azimuth < 236.25)
151 return CardinalSW;
152 else if (azimuth < 258.75)
153 return CardinalWSW;
154 else if (azimuth < 281.25)
155 return CardinalW;
156 else if (azimuth < 303.75)
157 return CardinalWNW;
158 else if (azimuth < 326.25)
159 return CardinalNW;
160 else
161 return CardinalNNW;
162 }
163
164 // For values exceeding +- 720.0
165 inline static double wrapLongExt(double lng) {
166 double remainder = fmod(lng + 180.0, 360.0);
167 return fmod(remainder + 360.0, 360.0) - 180.0;
168 }
169
170 // Mirrors the azimuth against the X axis. Azimuth assumed to be in [0,360[
171 inline static double mirrorAzimuthX(double azimuth) {
172 if (azimuth <= 90.0)
173 return 180.0 - azimuth;
174 else
175 return 180.0 + (360.0 - azimuth);
176 }
177
178 // Mirrors the azimuth against the Y axis. Azimuth assumed to be in [0,360[
179 inline static double mirrorAzimuthY(double azimuth) {
180 if (azimuth == 0.0)
181 return 0.0;
182 return 360.0 - azimuth;
183 }
184
185 inline static double radians(double degrees)
186 {
187 return qDegreesToRadians(degrees);
188 }
189
190 inline static double degrees(double radians)
191 {
192 return qRadiansToDegrees(radians);
193 }
194
195 inline static double earthMeanRadius()
196 {
197 return 6371007.2;
198 }
199
200 inline static double earthMeanCircumference()
201 {
202 return earthMeanRadius() * 2.0 * M_PI;
203 }
204
205 inline static double mercatorMaxLatitude()
206 {
207 return 85.05113;
208 }
209
210 inline static QGeoCoordinate antipodalPoint(const QGeoCoordinate &p)
211 {
212 return QGeoCoordinate(-p.latitude(), wrapLong(p.longitude() + 180.0));
213 }
214
215 // Leftmost longitude before wrapping kicks in
216 inline static double mapLeftLongitude(double centerLongitude)
217 {
218 return wrapLong(centerLongitude + leftOffset);
219 }
220
221 // Rightmost longitude before wrapping kicks in
222 inline static double mapRightLongitude(double centerLongitude)
223 {
224 return wrapLong(centerLongitude - leftOffset);
225 }
226
227 inline static void split_double(double input, float *hipart, float *lopart)
228 {
229 *hipart = (float) input;
230 double delta = input - ((double) *hipart);
231 *lopart = (float) delta;
232 }
233
234 static qreal metersPerPixel(qreal zoomLevel, const QGeoCoordinate &coordinate)
235 {
236 const qreal metersPerTile = earthMeanCircumference() * std::cos(radians(coordinate.latitude())) / std::pow(2, zoomLevel);
237 return metersPerTile / 256.0;
238 }
239
240 /*
241 returns the NMEA sentence type.
242 */
243 static NmeaSentence getNmeaSentenceType(QByteArrayView bv);
244
245 /*
246 Returns the satellite system type based on the message type.
247 See https://gpsd.gitlab.io/gpsd/NMEA.html#_talker_ids for reference
248 */
249 static QGeoSatelliteInfo::SatelliteSystem getSatelliteSystem(QByteArrayView bv);
250
251 /*
252 Returns the satellite system type based on the satellite id.
253 See https://gpsd.gitlab.io/gpsd/NMEA.html#_satellite_ids for reference
254 */
255 static QGeoSatelliteInfo::SatelliteSystem getSatelliteSystemBySatelliteId(int satId);
256
257 /*
258 Creates a QGeoPositionInfo from a GGA, GLL, RMC, VTG or ZDA sentence.
259
260 Note:
261 - GGA and GLL sentences have time but not date so the update's
262 QDateTime object will have an invalid date.
263 - RMC reports date with a two-digit year so in this case the year
264 is assumed to be after the year 2000.
265 */
266 static bool getPosInfoFromNmea(QByteArrayView bv,
267 QGeoPositionInfo *info, double uere,
268 bool *hasFix = nullptr);
269
270 /*
271 Retruns a list of QGeoSatelliteInfo in the view.
272
273 Note: this function has to be called repeatedly until it returns
274 QNmeaSatelliteInfoSource::FullyParsed.
275 Reason being that GSV sentences can be split into multiple samples, so
276 getting the full data requires parsing multiple sentences.
277 */
278 static QNmeaSatelliteInfoSource::SatelliteInfoParseStatus
279 getSatInfoFromNmea(QByteArrayView bv, QList<QGeoSatelliteInfo> &infos, QGeoSatelliteInfo::SatelliteSystem &system);
280
281 /*
282 Parses GSA for satellites in use.
283
284 Returns satellite system type or QGeoSatelliteInfo::Undefined if parsing
285 failed
286 */
287 static QGeoSatelliteInfo::SatelliteSystem getSatInUseFromNmea(QByteArrayView bv,
288 QList<int> &pnrsInUse);
289
290 /*
291 Returns true if the given NMEA sentence has a valid checksum.
292 */
293 static bool hasValidNmeaChecksum(QByteArrayView bv);
294
295 /*
296 Returns time from a string in hhmmss or hhmmss.z+ format.
297 */
298 static bool getNmeaTime(const QByteArray &bytes, QTime *time);
299
300 /*
301 Accepts for example ("2734.7964", 'S', "15306.0124", 'E') and returns the
302 lat-long values. Fails if lat or long fail isValidLat() or isValidLong().
303 */
304 static bool getNmeaLatLong(const QByteArray &latString,
305 char latDirection,
306 const QByteArray &lngString,
307 char lngDirection,
308 double *lat,
309 double *lon);
310};
311
312QT_END_NAMESPACE
313
314#endif
Combined button and popup list for selecting options.
static const double leftOffset
static const double offsetEpsilon
static const double rightOffset
#define M_PI
Definition qmath.h:201