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