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
qdeclarativeposition.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Jolla Ltd.
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4// Qt-Security score:significant reason:default
5
6#include <QtCore/QtNumeric>
8#include <QtQml/qqml.h>
9#include <qnmeapositioninfosource.h>
10#include <QFile>
11
13
14/*!
15 \qmltype Position
16 //! \nativetype QDeclarativePosition
17 \inqmlmodule QtPositioning
18 \since 5.2
19
20 \brief The Position type holds positional data at a particular point in time,
21 such as coordinate (longitude, latitude, altitude) and speed.
22
23 The Position type holds values related to geographic location such as
24 a \l coordinate (longitude, latitude, and altitude), the \l timestamp when
25 the Position was obtained, the \l speed at that time, and the accuracy of
26 the data.
27
28 Primarily, it is used in the \l{PositionSource::position}{position} property
29 of a \l{PositionSource}, as the basic unit of data available from the system
30 location data source.
31
32 Not all properties of a Position object are necessarily valid or available
33 (for example latitude and longitude may be valid, but speed update has not been
34 received or set manually). As a result, corresponding "valid" properties
35 are available (for example \l{coordinate} and \l{longitudeValid}, \l{latitudeValid}
36 etc) to discern whether the data is available and valid in this position
37 update.
38
39 Position objects are read-only and can only be produced by a PositionSource.
40
41 \section2 Example Usage
42
43 See the example given for the \l {PositionSource} type, or the
44 \l {Satellite Info} example application.
45
46 \sa PositionSource, coordinate
47*/
48
49namespace
50{
51
52bool equalOrNaN(qreal a, qreal b)
53{
54 return a == b || (qIsNaN(a) && qIsNaN(b));
55}
56
57bool exclusiveNaN(qreal a, qreal b)
58{
59 return qIsNaN(a) != qIsNaN(b);
60}
61
62}
63
64QDeclarativePosition::QDeclarativePosition(QObject *parent)
65: QObject(parent)
66{
67}
68
69QDeclarativePosition::~QDeclarativePosition()
70{
71}
72
73void QDeclarativePosition::setPosition(const QGeoPositionInfo &info)
74{
75 // timestamp
76 const QDateTime pTimestamp = m_info.timestamp();
77 const QDateTime timestamp = info.timestamp();
78 const bool timestampChanged = pTimestamp != timestamp;
79
80 // coordinate
81 const QGeoCoordinate pCoordinate = m_info.coordinate();
82 const QGeoCoordinate coordinate = info.coordinate();
83 const bool coordinateChanged = pCoordinate != coordinate;
84 const bool latitudeValidChanged = exclusiveNaN(pCoordinate.latitude(), coordinate.latitude());
85 const bool longitudeValidChanged =
86 exclusiveNaN(pCoordinate.longitude(), coordinate.longitude());
87 const bool altitudeValidChanged = exclusiveNaN(pCoordinate.altitude(), coordinate.altitude());
88
89 // direction
90 const qreal pDirection = m_info.attribute(QGeoPositionInfo::Direction);
91 const qreal direction = info.attribute(QGeoPositionInfo::Direction);
92 const bool directionChanged = !equalOrNaN(pDirection, direction);
93 const bool directionValidChanged = exclusiveNaN(pDirection, direction);
94
95 // ground speed
96 const qreal pSpeed = m_info.attribute(QGeoPositionInfo::GroundSpeed);
97 const qreal speed = info.attribute(QGeoPositionInfo::GroundSpeed);
98 const bool speedChanged = !equalOrNaN(pSpeed, speed);
99 const bool speedValidChanged = exclusiveNaN(pSpeed, speed);
100
101 // vertical speed
102 const qreal pVerticalSpeed = m_info.attribute(QGeoPositionInfo::VerticalSpeed);
103 const qreal verticalSpeed = info.attribute(QGeoPositionInfo::VerticalSpeed);
104 const bool verticalSpeedChanged = !equalOrNaN(pVerticalSpeed, verticalSpeed);
105 const bool verticalSpeedValidChanged = exclusiveNaN(pVerticalSpeed, verticalSpeed);
106
107 // magnetic variation
108 const qreal pMagneticVariation = m_info.attribute(QGeoPositionInfo::MagneticVariation);
109 const qreal magneticVariation = info.attribute(QGeoPositionInfo::MagneticVariation);
110 const bool magneticVariationChanged = !equalOrNaN(pMagneticVariation, magneticVariation);
111 const bool magneticVariationValidChanged = exclusiveNaN(pMagneticVariation, magneticVariation);
112
113 // horizontal accuracy
114 const qreal pHorizontalAccuracy = m_info.attribute(QGeoPositionInfo::HorizontalAccuracy);
115 const qreal horizontalAccuracy = info.attribute(QGeoPositionInfo::HorizontalAccuracy);
116 const bool horizontalAccuracyChanged = !equalOrNaN(pHorizontalAccuracy, horizontalAccuracy);
117 const bool horizontalAccuracyValidChanged =
118 exclusiveNaN(pHorizontalAccuracy, horizontalAccuracy);
119
120 // vertical accuracy
121 const qreal pVerticalAccuracy = m_info.attribute(QGeoPositionInfo::VerticalAccuracy);
122 const qreal verticalAccuracy = info.attribute(QGeoPositionInfo::VerticalAccuracy);
123 const bool verticalAccuracyChanged = !equalOrNaN(pVerticalAccuracy, verticalAccuracy);
124 const bool verticalAccuracyValidChanged = exclusiveNaN(pVerticalAccuracy, verticalAccuracy);
125
126 // direction accuracy
127 const qreal pDirectionAccuracy = m_info.attribute(QGeoPositionInfo::DirectionAccuracy);
128 const qreal directionAccuracy = info.attribute(QGeoPositionInfo::DirectionAccuracy);
129 const bool directionAccuracyChanged = !equalOrNaN(pDirectionAccuracy, directionAccuracy);
130 const bool directionAccuracyValidChanged = exclusiveNaN(pDirectionAccuracy, directionAccuracy);
131
132 m_info = info;
133
134 if (timestampChanged)
135 m_computedTimestamp.notify();
136
137 if (coordinateChanged)
138 m_computedCoordinate.notify();
139 if (latitudeValidChanged)
140 m_computedLatitudeValid.notify();
141 if (longitudeValidChanged)
142 m_computedLongitudeValid.notify();
143 if (altitudeValidChanged)
144 m_computedAltitudeValid.notify();
145
146 if (directionChanged)
147 m_computedDirection.notify();
148 if (directionValidChanged)
149 m_computedDirectionValid.notify();
150
151 if (speedChanged)
152 m_computedSpeed.notify();
153 if (speedValidChanged)
154 m_computedSpeedValid.notify();
155
156 if (verticalSpeedChanged)
157 m_computedVerticalSpeed.notify();
158 if (verticalSpeedValidChanged)
159 m_computedVerticalSpeedValid.notify();
160
161 if (horizontalAccuracyChanged)
162 m_computedHorizontalAccuracy.notify();
163 if (horizontalAccuracyValidChanged)
164 m_computedHorizontalAccuracyValid.notify();
165
166 if (verticalAccuracyChanged)
167 m_computedVerticalAccuracy.notify();
168 if (verticalAccuracyValidChanged)
169 m_computedVerticalAccuracyValid.notify();
170
171 if (magneticVariationChanged)
172 m_computedMagneticVariation.notify();
173 if (magneticVariationValidChanged)
174 m_computedMagneticVariationValid.notify();
175
176 if (directionAccuracyChanged)
177 m_computedDirectionAccuracy.notify();
178 if (directionAccuracyValidChanged)
179 m_computedDirectionAccuracyValid.notify();
180}
181
182const QGeoPositionInfo &QDeclarativePosition::position() const
183{
184 return m_info;
185}
186
187QBindable<bool> QDeclarativePosition::bindableLatitudeValid() const
188{
189 return QBindable<bool>(&m_computedLatitudeValid);
190}
191
192QBindable<bool> QDeclarativePosition::bindableLongitudeValid() const
193{
194 return QBindable<bool>(&m_computedLongitudeValid);
195}
196
197QBindable<bool> QDeclarativePosition::bindableAltitudeValid() const
198{
199 return QBindable<bool>(&m_computedAltitudeValid);
200}
201
202QBindable<QGeoCoordinate> QDeclarativePosition::bindableCoordinate() const
203{
204 return QBindable<QGeoCoordinate>(&m_computedCoordinate);
205}
206
207QBindable<QDateTime> QDeclarativePosition::bindableTimestamp() const
208{
209 return QBindable<QDateTime>(&m_computedTimestamp);
210}
211
212QBindable<double> QDeclarativePosition::bindableSpeed() const
213{
214 return QBindable<double>(&m_computedSpeed);
215}
216
217QBindable<bool> QDeclarativePosition::bindableSpeedValid() const
218{
219 return QBindable<bool>(&m_computedSpeedValid);
220}
221
222QBindable<qreal> QDeclarativePosition::bindableHorizontalAccuracy() const
223{
224 return QBindable<qreal>(&m_computedHorizontalAccuracy);
225}
226
227QBindable<qreal> QDeclarativePosition::binableVerticalAccuracy() const
228{
229 return QBindable<qreal>(&m_computedVerticalAccuracy);
230}
231
232QBindable<bool> QDeclarativePosition::bindableHorizontalAccuracyValid() const
233{
234 return QBindable<bool>(&m_computedHorizontalAccuracyValid);
235}
236
237QBindable<bool> QDeclarativePosition::bindableVerticalAccuracyValid() const
238{
239 return QBindable<bool>(&m_computedVerticalAccuracyValid);
240}
241
242QBindable<bool> QDeclarativePosition::bindableDirectionValid() const
243{
244 return QBindable<bool>(&m_computedDirectionValid);
245}
246
247QBindable<double> QDeclarativePosition::bindableDirection() const
248{
249 return QBindable<double>(&m_computedDirection);
250}
251
252QBindable<bool> QDeclarativePosition::bindableVerticalSpeedValid() const
253{
254 return QBindable<bool>(&m_computedVerticalSpeedValid);
255}
256
257QBindable<double> QDeclarativePosition::bindableVerticalSpeed() const
258{
259 return QBindable<double>(&m_computedVerticalSpeed);
260}
261
262QBindable<double> QDeclarativePosition::bindableMagneticVariation() const
263{
264 return QBindable<double>(&m_computedMagneticVariation);
265}
266
267QBindable<bool> QDeclarativePosition::bindableMagneticVariationValid() const
268{
269 return QBindable<bool>(&m_computedMagneticVariationValid);
270}
271
272QBindable<double> QDeclarativePosition::bindableDirectionAccuracy() const
273{
274 return QBindable<double>(&m_computedDirectionAccuracy);
275}
276
277QBindable<bool> QDeclarativePosition::bindableDirectionAccuracyValid() const
278{
279 return QBindable<bool>(&m_computedDirectionAccuracyValid);
280}
281
282/*!
283 \qmlproperty coordinate Position::coordinate
284
285 This property holds the latitude, longitude, and altitude value of the Position.
286
287 It is a read-only property.
288
289 \sa longitudeValid, latitudeValid, altitudeValid
290*/
291QGeoCoordinate QDeclarativePosition::coordinate() const
292{
293 return m_computedCoordinate.value();
294}
295
296QGeoCoordinate QDeclarativePosition::coordinateActualCalculation() const
297{
298 return m_info.coordinate();
299}
300
301/*!
302 \qmlproperty bool Position::latitudeValid
303
304 This property is true if coordinate's latitude has been set
305 (to indicate whether that data has been received or not, as every update
306 does not necessarily contain all data).
307
308 \sa coordinate
309*/
310bool QDeclarativePosition::isLatitudeValid() const
311{
312 return m_computedLatitudeValid.value();
313}
314
315bool QDeclarativePosition::isLatitudeValidActualCalculation() const
316{
317 return !qIsNaN(m_info.coordinate().latitude());
318}
319
320/*!
321 \qmlproperty bool Position::longitudeValid
322
323 This property is true if coordinate's longitude has been set
324 (to indicate whether that data has been received or not, as every update
325 does not necessarily contain all data).
326
327 \sa coordinate
328*/
329bool QDeclarativePosition::isLongitudeValid() const
330{
331 return m_computedLongitudeValid.value();
332}
333
334bool QDeclarativePosition::isLongitudeValidActualCalculation() const
335{
336 return !qIsNaN(m_info.coordinate().longitude());
337}
338
339/*!
340 \qmlproperty bool Position::speedValid
341
342 This property is true if \l speed has been set
343 (to indicate whether that data has been received or not, as every update
344 does not necessarily contain all data).
345
346 \sa speed
347*/
348bool QDeclarativePosition::isSpeedValid() const
349{
350 return m_computedSpeedValid.value();
351}
352
353bool QDeclarativePosition::isSpeedValidActualCalculation() const
354{
355 return !qIsNaN(m_info.attribute(QGeoPositionInfo::GroundSpeed));
356}
357
358/*!
359 \qmlproperty bool Position::altitudeValid
360
361 This property is true if coordinate's altitude has been set
362 (to indicate whether that data has been received or not, as every update
363 does not necessarily contain all data).
364
365 \sa coordinate
366*/
367bool QDeclarativePosition::isAltitudeValid() const
368{
369 return m_computedAltitudeValid.value();
370}
371
372bool QDeclarativePosition::isAltitudeValidActualCalculation() const
373{
374 return !qIsNaN(m_info.coordinate().altitude());
375}
376
377/*!
378 \qmlproperty double Position::speed
379
380 This property holds the value of speed (groundspeed, meters / second).
381
382 It is a read-only property.
383
384 \sa speedValid, coordinate
385*/
386double QDeclarativePosition::speed() const
387{
388 return m_computedSpeed.value();
389}
390
391double QDeclarativePosition::speedActualCalculation() const
392{
393 return m_info.attribute(QGeoPositionInfo::GroundSpeed);
394}
395
396/*!
397 \qmlproperty real Position::horizontalAccuracy
398
399 This property holds the horizontal accuracy of the coordinate (in meters).
400
401 \sa horizontalAccuracyValid, coordinate
402*/
403qreal QDeclarativePosition::horizontalAccuracy() const
404{
405 return m_computedHorizontalAccuracy.value();
406}
407
408qreal QDeclarativePosition::horizontalAccuracyActualCalculation() const
409{
410 return m_info.attribute(QGeoPositionInfo::HorizontalAccuracy);
411}
412
413/*!
414 \qmlproperty bool Position::horizontalAccuracyValid
415
416 This property is true if \l horizontalAccuracy has been set
417 (to indicate whether that data has been received or not, as every update
418 does not necessarily contain all data).
419
420 \sa horizontalAccuracy
421*/
422bool QDeclarativePosition::isHorizontalAccuracyValid() const
423{
424 return m_computedHorizontalAccuracyValid.value();
425}
426
427bool QDeclarativePosition::isHorizontalAccuracyValidActualCalculation() const
428{
429 return !qIsNaN(m_info.attribute(QGeoPositionInfo::HorizontalAccuracy));
430}
431
432/*!
433 \qmlproperty real Position::verticalAccuracy
434
435 This property holds the vertical accuracy of the coordinate (in meters).
436
437 \sa verticalAccuracyValid, coordinate
438*/
439qreal QDeclarativePosition::verticalAccuracy() const
440{
441 return m_computedVerticalAccuracy.value();
442}
443
444qreal QDeclarativePosition::verticalAccuracyActualCalculation() const
445{
446 return m_info.attribute(QGeoPositionInfo::VerticalAccuracy);
447}
448
449/*!
450 \qmlproperty bool Position::verticalAccuracyValid
451
452 This property is true if \l verticalAccuracy has been set
453 (to indicate whether that data has been received or not, as every update
454 does not necessarily contain all data).
455
456 \sa verticalAccuracy
457*/
458bool QDeclarativePosition::isVerticalAccuracyValid() const
459{
460 return m_computedVerticalAccuracyValid.value();
461}
462
463bool QDeclarativePosition::isVerticalAccuracyValidActualCalculation() const
464{
465 return !qIsNaN(m_info.attribute(QGeoPositionInfo::VerticalAccuracy));
466}
467
468/*!
469 \qmlproperty date Position::timestamp
470
471 This property holds the timestamp when this position
472 was received. If the property has not been set, it is invalid.
473
474 It is a read-only property.
475*/
476QDateTime QDeclarativePosition::timestamp() const
477{
478 return m_computedTimestamp.value();
479}
480
481QDateTime QDeclarativePosition::timestampActualCalculation() const
482{
483 return m_info.timestamp();
484}
485
486/*!
487 \qmlproperty bool Position::directionValid
488 \since Qt Positioning 5.3
489
490 This property is true if \l direction has been set (to indicate whether that data has been
491 received or not, as every update does not necessarily contain all data).
492
493 \sa direction
494*/
495bool QDeclarativePosition::isDirectionValid() const
496{
497 return m_computedDirectionValid.value();
498}
499
500bool QDeclarativePosition::isDirectionValidActualCalculation() const
501{
502 return !qIsNaN(m_info.attribute(QGeoPositionInfo::Direction));
503}
504
505/*!
506 \qmlproperty double Position::direction
507 \since Qt Positioning 5.3
508
509 This property holds the value of the direction of travel in degrees from true north.
510
511 It is a read-only property.
512
513 \sa directionValid
514*/
515double QDeclarativePosition::direction() const
516{
517 return m_computedDirection.value();
518}
519
520double QDeclarativePosition::directionActualCalculation() const
521{
522 return m_info.attribute(QGeoPositionInfo::Direction);
523}
524
525/*!
526 \qmlproperty bool Position::verticalSpeedValid
527 \since Qt Positioning 5.3
528
529 This property is true if \l verticalSpeed has been set (to indicate whether that data has been
530 received or not, as every update does not necessarily contain all data).
531
532 \sa verticalSpeed
533*/
534bool QDeclarativePosition::isVerticalSpeedValid() const
535{
536 return m_computedVerticalSpeedValid.value();
537}
538
539bool QDeclarativePosition::isVerticalSpeedValidActualCalculation() const
540{
541 return !qIsNaN(m_info.attribute(QGeoPositionInfo::VerticalSpeed));
542}
543
544/*!
545 \qmlproperty double Position::verticalSpeed
546 \since Qt Positioning 5.3
547
548 This property holds the value of the vertical speed in meters per second.
549
550 It is a read-only property.
551
552 \sa verticalSpeedValid
553*/
554double QDeclarativePosition::verticalSpeed() const
555{
556 return m_computedVerticalSpeed.value();
557}
558
559double QDeclarativePosition::verticalSpeedActualCalculation() const
560{
561 return m_info.attribute(QGeoPositionInfo::VerticalSpeed);
562}
563
564/*!
565 \qmlproperty bool Position::magneticVariationValid
566 \since Qt Positioning 5.4
567
568 This property is true if \l magneticVariation has been set (to indicate whether that data has been
569 received or not, as every update does not necessarily contain all data).
570
571 \sa magneticVariation
572*/
573bool QDeclarativePosition::isMagneticVariationValid() const
574{
575 return m_computedMagneticVariationValid.value();
576}
577
578bool QDeclarativePosition::isMagneticVariationValidActualCalculation() const
579{
580 return !qIsNaN(m_info.attribute(QGeoPositionInfo::MagneticVariation));
581}
582
583/*!
584 \qmlproperty double Position::magneticVariation
585 \since Qt Positioning 5.4
586
587 This property holds the angle between the horizontal component of the
588 magnetic field and true north, in degrees. Also known as magnetic
589 declination. A positive value indicates a clockwise direction from
590 true north and a negative value indicates a counter-clockwise direction.
591
592 It is a read-only property.
593
594 \sa magneticVariationValid
595*/
596double QDeclarativePosition::magneticVariation() const
597{
598 return m_computedMagneticVariation.value();
599}
600
601double QDeclarativePosition::magneticVariationActualCalculation() const
602{
603 return m_info.attribute(QGeoPositionInfo::MagneticVariation);
604}
605
606/*!
607 \qmlproperty bool Position::directionAccuracyValid
608 \since Qt Positioning 6.3
609
610 This property is \c true if \l directionAccuracy has been set.
611
612 \sa directionAccuracy
613*/
614bool QDeclarativePosition::isDirectionAccuracyValid() const
615{
616 return m_computedDirectionAccuracyValid.value();
617}
618
619bool QDeclarativePosition::isDirectionAccuracyValidActualCalculation() const
620{
621 return !qIsNaN(m_info.attribute(QGeoPositionInfo::DirectionAccuracy));
622}
623
624/*!
625 \qmlproperty double Position::directionAccuracy
626 \since Qt Positioning 6.3
627
628 This property holds the accuracy of the provided \l direction in degrees.
629 This property is valid for Android and macOS/iOS only. See
630 \l {QGeoPositionInfo::Attribute} documentation for more details.
631
632 \sa direction, directionAccuracyValid
633*/
634double QDeclarativePosition::directionAccuracy() const
635{
636 return m_computedDirectionAccuracy.value();
637}
638
639double QDeclarativePosition::directionAccuracyActualCalculation() const
640{
641 return m_info.attribute(QGeoPositionInfo::DirectionAccuracy);
642}
643
644QT_END_NAMESPACE
645
646#include "moc_qdeclarativeposition_p.cpp"
Combined button and popup list for selecting options.
bool equalOrNaN(qreal a, qreal b)
bool exclusiveNaN(qreal a, qreal b)