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