Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qnmeapositioninfosource.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
6#include "qlocationutils_p.h"
7
8#include <QIODevice>
9#include <QBasicTimer>
10#include <QTimerEvent>
11#include <QTimer>
12#include <array>
13#include <QDebug>
14#include <QtCore/QtNumeric>
15#include <QtCore/QDateTime>
16#include <QtCore/QTimeZone>
17
18#include <algorithm>
19
21
22#define USE_POSITION_NMEA_PIMPL 0
23
24#if USE_POSITION_NMEA_PIMPL
26{
27public:
29
30 QList<QByteArray> nmeaSentences;
31};
32
33
34QGeoPositionInfoPrivateNmea::~QGeoPositionInfoPrivateNmea()
35{
36
37}
38#else
40#endif
41
42static bool propagateCoordinate(QGeoPositionInfo &dst, const QGeoPositionInfo &src, bool force = true)
43{
44 bool updated = false;
45 QGeoCoordinate c = dst.coordinate();
46 const QGeoCoordinate & srcCoordinate = src.coordinate();
47 if (qIsFinite(src.coordinate().latitude())
48 && (!qIsFinite(dst.coordinate().latitude()) || force)) {
49 updated |= (c.latitude() != srcCoordinate.latitude());
50 c.setLatitude(src.coordinate().latitude());
51 }
52 if (qIsFinite(src.coordinate().longitude())
53 && (!qIsFinite(dst.coordinate().longitude()) || force)) {
54 updated |= (c.longitude() != srcCoordinate.longitude());
55 c.setLongitude(src.coordinate().longitude());
56 }
57 if (qIsFinite(src.coordinate().altitude())
58 && (!qIsFinite(dst.coordinate().altitude()) || force)) {
59 updated |= (c.altitude() != srcCoordinate.altitude());
60 c.setAltitude(src.coordinate().altitude());
61 }
62 dst.setCoordinate(c);
63 return updated;
64}
65
67{
68 if (!dst.timestamp().date().isValid() && src.timestamp().isValid()) { // time was supposed to be set/the same already. Date can be overwritten.
69 dst.setTimestamp(src.timestamp());
70 return true;
71 }
72 return false;
73}
74
75static bool propagateAttributes(QGeoPositionInfo &dst, const QGeoPositionInfo &src, bool force = true)
76{
77 bool updated = false;
78 static Q_DECL_CONSTEXPR std::array<QGeoPositionInfo::Attribute, 6> attrs {
85 for (const auto a: attrs) {
86 if (src.hasAttribute(a) && (!dst.hasAttribute(a) || force)) {
87 updated |= (dst.attribute(a) != src.attribute(a));
88 dst.setAttribute(a, src.attribute(a));
89 }
90 }
91
92 return updated;
93}
94
95// returns false if src does not contain any additional or different data than dst,
96// true otherwise.
98{
99 bool updated = false;
100
101 updated |= propagateCoordinate(dst, src);
102 updated |= propagateDate(dst, src);
103 updated |= propagateAttributes(dst, src);
104
105#if USE_POSITION_NMEA_PIMPL
107 dstPimpl->nmeaSentences.append(nmeaSentence);
108#else
109 Q_UNUSED(nmeaSentence);
110#endif
111 return updated;
112}
113
114static qint64 msecsTo(const QDateTime &from, const QDateTime &to)
115{
116 if (!from.time().isValid() || !to.time().isValid())
117 return 0;
118
119 if (!from.date().isValid() || !to.date().isValid()) // use only time
120 return from.time().msecsTo(to.time());
121
122 return from.msecsTo(to);
123}
124
126 = default;
127
129 : QNmeaReader(sourcePrivate), m_update(*new QGeoPositionInfoPrivateNmea)
130{
131 // An env var controlling the number of milliseconds to use to withold
132 // an update and wait for additional data to combine.
133 // The update will be pushed earlier than this if a newer update will be received.
134 // The update will be withold longer than this amount of time if additional
135 // valid data will keep arriving within this time frame.
136 bool ok = false;
137 int pushDelay = qEnvironmentVariableIntValue("QT_NMEA_PUSH_DELAY", &ok);
138 if (ok)
139 pushDelay = std::clamp(pushDelay, -1, 1000);
140 else
141 pushDelay = 20;
142
143 if (pushDelay >= 0) {
145 m_timer.setInterval(pushDelay);
147 this->notifyNewUpdate();
148 });
149 }
150 m_pushDelay = pushDelay;
151}
152
154 = default;
155
157{
158 while (m_proxy->m_device->canReadLine()) {
159 const QTime infoTime = m_update.timestamp().time(); // if update has been set, time must be valid.
160 const QDate infoDate = m_update.timestamp().date(); // this one might not be valid, as some sentences do not contain it
161
163 QGeoPositionInfo pos(*pimpl);
164
165 char buf[1024];
166 qint64 size = m_proxy->m_device->readLine(buf, sizeof(buf));
167 if (size <= 0)
168 continue;
169
170 const bool oldFix = m_hasFix;
171 bool hasFix;
172 const bool parsed = m_proxy->parsePosInfoFromNmeaData(
173 QByteArrayView{buf, static_cast<qsizetype>(size)}, &pos, &hasFix);
174
175 if (!parsed) {
176 // got garbage, don't stop the timer
177 continue;
178 }
179
180 m_hasFix |= hasFix;
181 m_updateParsed = true;
182
183 // Date may or may not be valid, as some packets do not have date.
184 // If date isn't valid, match is performed on time only.
185 // Hence, make sure that packet blocks are generated with
186 // the sentences containing the full timestamp (e.g., GPRMC) *first* !
187 if (infoTime.isValid()) {
188 if (pos.timestamp().time().isValid()) {
189 const bool newerTime = infoTime < pos.timestamp().time();
190 const bool newerDate = (infoDate.isValid() // if time is valid but one date or both are not,
191 && pos.timestamp().date().isValid()
192 && infoDate < pos.timestamp().date());
193 if (newerTime || newerDate) {
194 // Effectively read data for different update, that is also newer,
195 // so flush retained update, and copy the new pos into m_update
196 const QDate updateDate = m_update.timestamp().date();
197 const QDate lastPushedDate = m_lastPushedTS.date();
198 const bool newerTimestampSinceLastPushed = m_update.timestamp() > m_lastPushedTS;
199 const bool invalidDate = !(updateDate.isValid() && lastPushedDate.isValid());
200 const bool newerTimeSinceLastPushed = m_update.timestamp().time() > m_lastPushedTS.time();
201 if ( newerTimestampSinceLastPushed || (invalidDate && newerTimeSinceLastPushed)) {
204 }
205 m_timer.stop();
206 // next update data
208 m_update = pos;
209 m_hasFix = hasFix;
210 } else {
211 if (infoTime == pos.timestamp().time())
212 // timestamps match -- merge into m_update
214 // Reset the timer only if new info has been received.
215 // Else the source might be keep repeating outdated info until
216 // new info become available.
217 m_timer.stop();
218 }
219 // else discard out of order outdated info.
220 }
221 } else {
222 // no timestamp available in parsed update-- merge into m_update
224 m_timer.stop();
225 }
226 } else {
227 // there was no info with valid TS. Overwrite with whatever is parsed.
228#if USE_POSITION_NMEA_PIMPL
229 pimpl->nmeaSentences.append(QByteArray(buf, size));
230#endif
232 m_update = pos;
233 m_timer.stop();
234 }
235 }
236
237 if (m_updateParsed) {
238 if (m_pushDelay < 0)
240 else
241 m_timer.start();
242 }
243}
244
246{
247 const bool newerTime = m_update.timestamp().time() > m_lastPushedTS.time();
248 const bool newerDate = (m_update.timestamp().date().isValid()
251 if (newerTime || newerDate) {
254 }
255 m_timer.stop();
256}
257
258
259//============================================================
260
262 : QNmeaReader(sourcePrivate),
263 m_currTimerId(-1),
264 m_hasValidDateTime(false)
265{
266}
267
269{
270 if (m_currTimerId > 0)
271 killTimer(m_currTimerId);
272}
273
275{
276 if (m_currTimerId > 0) // we are already reading
277 return;
278
279 if (!m_hasValidDateTime) { // first update
281
282 if (!setFirstDateTime()) {
283 //m_proxy->notifyReachedEndOfFile();
284 qWarning("QNmeaPositionInfoSource: cannot find NMEA sentence with valid date & time");
285 return;
286 }
287
288 m_hasValidDateTime = true;
289 simulatePendingUpdate();
290
291 } else {
292 // previously read to EOF, but now new data has arrived
293 processNextSentence();
294 }
295}
296
298 QByteArray &m_nextLine,
300 QQueue<QPendingGeoPositionInfo> &m_pendingUpdates,
301 bool &hasFix)
302{
303 int timeToNextUpdate = -1;
304 QDateTime prevTs;
305 if (!m_pendingUpdates.isEmpty())
306 prevTs = m_pendingUpdates.head().info.timestamp();
307
308 // find the next update with a valid time (as long as the time is valid,
309 // we can calculate when the update should be emitted)
310 while (!m_nextLine.isEmpty() || (m_proxy->m_device && m_proxy->m_device->bytesAvailable() > 0)) {
311 char static_buf[1024];
312 char *buf = static_buf;
313 QByteArray nextLine;
314 qint64 size = 0;
315 if (!m_nextLine.isEmpty()) {
316 // Read something in the previous call, but TS was later.
317 size = m_nextLine.size();
318 nextLine = m_nextLine;
319 m_nextLine.clear();
320 buf = nextLine.data();
321 } else {
322 size = m_proxy->m_device->readLine(buf, sizeof(static_buf));
323 }
324
325 if (size <= 0)
326 continue;
327
328 const QTime infoTime = info.timestamp().time(); // if info has been set, time must be valid.
329 const QDate infoDate = info.timestamp().date(); // this one might not be valid, as some sentences do not contain it
330
331 /*
332 Packets containing time information are GGA, RMC, ZDA, GLL:
333
334 GGA : GPS fix data - only time
335 GLL : geographic latitude and longitude - only time
336 RMC : recommended minimum FPOS/transit data - date and time
337 ZDA : only timestamp - date and time
338
339 QLocationUtils is currently also capable of parsing VTG and GSA sentences:
340
341 VTG: containing Track made good and ground speed
342 GSA: overall satellite data, w. accuracies (ends up into PositionInfo)
343
344 Since these sentences contain no timestamp, their content will be merged with the content
345 from any prior sentence that had timestamp info, if any is available.
346 */
347
349 QGeoPositionInfo pos(*pimpl);
350 if (m_proxy->parsePosInfoFromNmeaData(
351 QByteArrayView{buf, static_cast<qsizetype>(size)}, &pos, &hasFix)) {
352 // Date may or may not be valid, as some packets do not have date.
353 // If date isn't valid, match is performed on time only.
354 // Hence, make sure that packet blocks are generated with
355 // the sentences containing the full timestamp (e.g., GPRMC) *first* !
356 if (infoTime.isValid()) {
357 if (pos.timestamp().time().isValid()) {
358 const bool newerTime = infoTime < pos.timestamp().time();
359 const bool newerDate = (infoDate.isValid() // if time is valid but one date or both are not,
360 && pos.timestamp().date().isValid()
361 && infoDate < pos.timestamp().date());
362 if (newerTime || newerDate) {
363 // Effectively read data for different update, that is also newer, so copy buf into m_nextLine
364 m_nextLine = QByteArray(buf, size);
365 break;
366 } else {
367 if (infoTime == pos.timestamp().time())
368 // timestamps match -- merge into info
370 // else discard out of order outdated info.
371 }
372 } else {
373 // no timestamp available -- merge into info
375 }
376 } else {
377 // there was no info with valid TS. Overwrite with whatever is parsed.
378#if USE_POSITION_NMEA_PIMPL
379 pimpl->nmeaSentences.append(QByteArray(buf, size));
380#endif
381 info = pos;
382 }
383
384 if (prevTs.time().isValid()) {
385 timeToNextUpdate = msecsTo(prevTs, info.timestamp());
386 if (timeToNextUpdate < 0) // Somehow parsing expired packets, reset info
388 }
389 }
390 }
391
392 return timeToNextUpdate;
393}
394
395bool QNmeaSimulatedReader::setFirstDateTime()
396{
397 // find the first update with valid date and time
399 bool hasFix = false;
400 processSentence(info, m_nextLine, m_proxy, m_pendingUpdates, hasFix);
401
402 if (info.timestamp().time().isValid()) { // NMEA may have sentences with only time and no date. These would generate invalid positions
404 pending.info = info;
405 pending.hasFix = hasFix;
406 m_pendingUpdates.enqueue(pending);
407 return true;
408 }
409 return false;
410}
411
412void QNmeaSimulatedReader::simulatePendingUpdate()
413{
414 if (!m_pendingUpdates.isEmpty()) {
415 // will be dequeued in processNextSentence()
416 QPendingGeoPositionInfo &pending = m_pendingUpdates.head();
417 m_proxy->notifyNewUpdate(&pending.info, pending.hasFix);
418 }
419
420 processNextSentence();
421}
422
424{
425 killTimer(event->timerId());
426 m_currTimerId = -1;
427 simulatePendingUpdate();
428}
429
430void QNmeaSimulatedReader::processNextSentence()
431{
433 bool hasFix = false;
434
435 int timeToNextUpdate = processSentence(info, m_nextLine, m_proxy, m_pendingUpdates, hasFix);
436 if (timeToNextUpdate < 0)
437 return;
438
439 m_pendingUpdates.dequeue();
440
442 pending.info = info;
443 pending.hasFix = hasFix;
444 m_pendingUpdates.enqueue(pending);
445 m_currTimerId = startTimer(timeToNextUpdate);
446}
447
448
449//============================================================
450
451
453 : QObject(parent),
454 m_updateMode(updateMode),
455 m_device(0),
456 m_invokedStart(false),
457 m_positionError(QGeoPositionInfoSource::UnknownSourceError),
458 m_userEquivalentRangeError(qQNaN()),
459 m_source(parent),
460 m_nmeaReader(0),
461 m_updateTimer(0),
462 m_requestTimer(0),
463 m_horizontalAccuracy(qQNaN()),
464 m_verticalAccuracy(qQNaN()),
465 m_noUpdateLastInterval(false),
466 m_updateTimeoutSent(false),
467 m_connectedReadyRead(false)
468{
469}
470
472{
473 delete m_nmeaReader;
474 delete m_updateTimer;
475}
476
477bool QNmeaPositionInfoSourcePrivate::openSourceDevice()
478{
479 if (!m_device) {
480 qWarning("QNmeaPositionInfoSource: no QIODevice data source, call setDevice() first");
481 return false;
482 }
483
485 qWarning("QNmeaPositionInfoSource: cannot open QIODevice data source");
486 return false;
487 }
488
489 connect(m_device, SIGNAL(aboutToClose()), SLOT(sourceDataClosed()));
490 connect(m_device, SIGNAL(readChannelFinished()), SLOT(sourceDataClosed()));
491 connect(m_device, SIGNAL(destroyed()), SLOT(sourceDataClosed()));
492
493 return true;
494}
495
496void QNmeaPositionInfoSourcePrivate::sourceDataClosed()
497{
498 if (m_nmeaReader && m_device && m_device->bytesAvailable())
499 m_nmeaReader->readAvailableData();
500}
501
503{
504 if (m_nmeaReader)
505 m_nmeaReader->readAvailableData();
506}
507
508bool QNmeaPositionInfoSourcePrivate::initialize()
509{
510 if (m_nmeaReader)
511 return true;
512
513 if (!openSourceDevice())
514 return false;
515
517 m_nmeaReader = new QNmeaRealTimeReader(this);
518 else
519 m_nmeaReader = new QNmeaSimulatedReader(this);
520
521 return true;
522}
523
524void QNmeaPositionInfoSourcePrivate::prepareSourceDevice()
525{
526 // some data may already be available
528 if (m_nmeaReader && m_device->bytesAvailable())
529 m_nmeaReader->readAvailableData();
530 }
531
532 if (!m_connectedReadyRead) {
534 m_connectedReadyRead = true;
535 }
536}
537
539 QGeoPositionInfo *posInfo, bool *hasFix)
540{
541 return m_source->parsePosInfoFromNmeaData(data, posInfo, hasFix);
542}
543
545{
546 if (m_invokedStart)
547 return;
548
550
551 m_invokedStart = true;
552 m_pendingUpdate = QGeoPositionInfo();
553 m_noUpdateLastInterval = false;
554
555 bool initialized = initialize();
556 if (!initialized) {
558 return;
559 }
560
562 // skip over any buffered data - we only want the newest data.
563 // Don't do this in requestUpdate. In that case bufferedData is good to have/use.
564 if (m_device->bytesAvailable()) {
565 if (m_device->isSequential())
566 m_device->readAll();
567 else
569 }
570 }
571
572 if (m_updateTimer)
573 m_updateTimer->stop();
574
575 if (m_source->updateInterval() > 0) {
576 if (!m_updateTimer)
577 m_updateTimer = new QBasicTimer;
578 m_updateTimer->start(m_source->updateInterval(), this);
579 }
580
581 if (initialized)
582 prepareSourceDevice();
583}
584
586{
587 m_invokedStart = false;
588 if (m_updateTimer)
589 m_updateTimer->stop();
590 m_pendingUpdate = QGeoPositionInfo();
591 m_noUpdateLastInterval = false;
592}
593
595{
596 if (m_requestTimer && m_requestTimer->isActive())
597 return;
598
600
601 if (msec <= 0 || msec < m_source->minimumUpdateInterval()) {
603 return;
604 }
605
606 if (!m_requestTimer) {
607 m_requestTimer = new QTimer(this);
608 connect(m_requestTimer, SIGNAL(timeout()), SLOT(updateRequestTimeout()));
609 }
610
611 bool initialized = initialize();
612 if (!initialized) {
614 return;
615 }
616
617 m_requestTimer->start(msec);
618 prepareSourceDevice();
619}
620
621void QNmeaPositionInfoSourcePrivate::updateRequestTimeout()
622{
623 m_requestTimer->stop();
625}
626
628{
629 // include <QDebug> before uncommenting
630 //qDebug() << "QNmeaPositionInfoSourcePrivate::notifyNewUpdate()" << update->timestamp() << hasFix << m_invokedStart << (m_requestTimer && m_requestTimer->isActive());
631
632 QDate date = update->timestamp().date();
633 if (date.isValid()) {
634 m_currentDate = date;
635 } else {
636 // some sentence have time but no date
637 QTime time = update->timestamp().time();
638 if (time.isValid() && m_currentDate.isValid())
639 update->setTimestamp(QDateTime(m_currentDate, time, QTimeZone::UTC));
640 }
641
642 // Some attributes are sent in separate NMEA sentences. Save and restore the accuracy
643 // measurements.
645 m_horizontalAccuracy = update->attribute(QGeoPositionInfo::HorizontalAccuracy);
646 else if (!qIsNaN(m_horizontalAccuracy))
647 update->setAttribute(QGeoPositionInfo::HorizontalAccuracy, m_horizontalAccuracy);
648
650 m_verticalAccuracy = update->attribute(QGeoPositionInfo::VerticalAccuracy);
651 else if (!qIsNaN(m_verticalAccuracy))
652 update->setAttribute(QGeoPositionInfo::VerticalAccuracy, m_verticalAccuracy);
653
654 if (hasFix && update->isValid()) {
655 if (m_requestTimer && m_requestTimer->isActive()) { // User called requestUpdate()
656 m_requestTimer->stop();
657 emitUpdated(*update);
658 } else if (m_invokedStart) { // user called startUpdates()
659 if (m_updateTimer && m_updateTimer->isActive()) { // update interval > 0
660 // for periodic updates, only want the most recent update
661 m_pendingUpdate = *update; // Set what to send in timerEvent()
662 if (m_noUpdateLastInterval) {
663 // if the update was invalid when timerEvent was last called, a valid update
664 // should be sent ASAP
665 emitPendingUpdate();
666 m_noUpdateLastInterval = false;
667 }
668 } else { // update interval <= 0
669 emitUpdated(*update);
670 }
671 }
672 m_lastUpdate = *update; // Set in any case, if update is valid. Used in lastKnownPosition().
673 }
674}
675
677{
678 emitPendingUpdate();
679}
680
681void QNmeaPositionInfoSourcePrivate::emitPendingUpdate()
682{
683 if (m_pendingUpdate.isValid()) {
684 m_updateTimeoutSent = false;
685 m_noUpdateLastInterval = false;
686 emitUpdated(m_pendingUpdate);
687 m_pendingUpdate = QGeoPositionInfo();
688 } else { // invalid update
689 if (m_noUpdateLastInterval && !m_updateTimeoutSent) {
690 m_updateTimeoutSent = true;
691 m_pendingUpdate = QGeoPositionInfo(); // Invalid already, but clear just in case.
693 }
694 m_noUpdateLastInterval = true;
695 }
696}
697
698void QNmeaPositionInfoSourcePrivate::emitUpdated(const QGeoPositionInfo &update)
699{
700 // check for duplication already done in QNmeaRealTimeReader::notifyNewUpdate
701 // and QNmeaRealTimeReader::readAvailableData
702 m_lastUpdate = update;
703 emit m_source->positionUpdated(update);
704}
705
706//=========================================================
707
759
767
788
802
818#if QT_DEPRECATED_SINCE(7, 0)
820 QGeoPositionInfo *posInfo, bool *hasFix)
821{
822#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
824 d->m_userEquivalentRangeError, hasFix);
825#else
826 return parsePosInfoFromNmeaData(QByteArrayView{data, size}, posInfo, hasFix);
827#endif
828}
829#endif // QT_DEPRECATED_SINCE(7, 0)
830
832 QGeoPositionInfo *posInfo, bool *hasFix)
833{
834#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
835 return parsePosInfoFromNmeaData(data.data(), static_cast<int>(data.size()),
836 posInfo, hasFix);
837#else
839 d->m_userEquivalentRangeError, hasFix);
840#endif
841}
842
843
851
865{
866 if (device != d->m_device) {
867 if (!d->m_device)
868 d->m_device = device;
869 else
870 qWarning("QNmeaPositionInfoSource: source device has already been set");
871 }
872}
873
878{
879 return d->m_device;
880}
881
886{
887 int interval = msec;
888 if (interval != 0)
889 interval = qMax(msec, minimumUpdateInterval());
891 if (d->m_invokedStart) {
892 d->stopUpdates();
893 d->startUpdates();
894 }
895}
896
904
912
917{
918 d->requestUpdate(msec == 0 ? 60000 * 5 : msec); // 5min default timeout
919}
920
925{
926 // the bool value does not matter since we only use satellite positioning
927 return d->m_lastUpdate;
928}
929
933QGeoPositionInfoSource::PositioningMethods QNmeaPositionInfoSource::supportedPositioningMethods() const
934{
936}
937
942{
943 return 2; // Some chips are capable of over 100 updates per seconds.
944}
945
953
960
962
963#include "moc_qnmeapositioninfosource_p.cpp"
964#include "moc_qnmeapositioninfosource.cpp"
IOBluetoothDevice * device
\inmodule QtCore
Definition qbasictimer.h:18
void start(int msec, QObject *obj)
\obsolete Use chrono overload instead.
void stop()
Stops the timer.
bool isActive() const noexcept
Returns true if the timer is running and has not been stopped; otherwise returns false.
Definition qbasictimer.h:34
\inmodule QtCore
Definition qbytearray.h:57
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
void clear()
Clears the contents of the byte array and makes it null.
\inmodule QtCore\reentrant
Definition qdatetime.h:283
qint64 msecsTo(const QDateTime &) const
Returns the number of milliseconds from this datetime to the other datetime.
QTime time() const
Returns the time part of the datetime.
QDate date() const
Returns the date part of the datetime.
\inmodule QtCore \reentrant
Definition qdatetime.h:29
constexpr bool isValid() const
Returns true if this date is valid; otherwise returns false.
Definition qdatetime.h:71
\inmodule QtPositioning
void setLatitude(double latitude)
Sets the latitude (in decimal degrees) to latitude.
static QGeoPositionInfoPrivate * get(const QGeoPositionInfo &info)
\inmodule QtPositioning
int updateInterval
This property holds the requested interval in milliseconds between each update.
void positionUpdated(const QGeoPositionInfo &update)
If startUpdates() or requestUpdate() is called, this signal is emitted when an update becomes availab...
void errorOccurred(QGeoPositionInfoSource::Error)
This signal is emitted after an error occurred.
Error
The Error enumeration represents the errors which can occur.
virtual void setUpdateInterval(int msec)
\inmodule QtPositioning
bool isValid() const
Returns true if the timestamp() and coordinate() values are both valid.
qreal attribute(Attribute attribute) const
Returns the value of the specified attribute as a qreal value.
void setAttribute(Attribute attribute, qreal value)
Sets the value for attribute to value.
void setTimestamp(const QDateTime &timestamp)
Sets the date and time at which this position was reported to timestamp.
QDateTime timestamp() const
Returns the date and time at which this position was reported, in UTC time.
bool hasAttribute(Attribute attribute) const
Returns true if the specified attribute is present for this QGeoPositionInfo object.
\inmodule QtCore \reentrant
Definition qiodevice.h:34
virtual bool open(QIODeviceBase::OpenMode mode)
Opens the device and sets its OpenMode to mode.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
qint64 readLine(char *data, qint64 maxlen)
This function reads a line of ASCII characters from the device, up to a maximum of maxSize - 1 bytes,...
bool isOpen() const
Returns true if the device is open; otherwise returns false.
QByteArray readAll()
Reads all remaining data from the device, and returns it as a byte array.
QIODeviceBase::OpenMode openMode() const
Returns the mode in which the device has been opened; i.e.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success,...
virtual bool canReadLine() const
Returns true if a complete line of data can be read from the device; otherwise returns false.
bool isEmpty() const noexcept
Definition qlist.h:401
static bool getPosInfoFromNmea(QByteArrayView bv, QGeoPositionInfo *info, double uere, bool *hasFix=nullptr)
void notifyNewUpdate(QGeoPositionInfo *update, bool fixStatus)
bool parsePosInfoFromNmeaData(QByteArrayView data, QGeoPositionInfo *posInfo, bool *hasFix)
QNmeaPositionInfoSource::UpdateMode m_updateMode
QNmeaPositionInfoSourcePrivate(QNmeaPositionInfoSource *parent, QNmeaPositionInfoSource::UpdateMode updateMode)
QGeoPositionInfoSource::Error m_positionError
void timerEvent(QTimerEvent *event) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
\inmodule QtPositioning
double userEquivalentRangeError() const
Returns the current User Equivalent Range Error (UERE).
void setUserEquivalentRangeError(double uere)
Sets the User Equivalent Range Error (UERE) to uere.
UpdateMode updateMode() const
Returns the update mode.
PositioningMethods supportedPositioningMethods() const override
\reimp
UpdateMode
Defines the available update modes.
bool parsePosInfoFromNmeaData(QByteArrayView data, QGeoPositionInfo *posInfo, bool *hasFix)
Parses an NMEA sentence string into a QGeoPositionInfo.
int minimumUpdateInterval() const override
\reimp
Error error() const override
\reimp
QIODevice * device() const
Returns the NMEA data source.
QNmeaPositionInfoSource(UpdateMode updateMode, QObject *parent=nullptr)
Constructs a QNmeaPositionInfoSource instance with the given parent and updateMode.
void setError(QGeoPositionInfoSource::Error positionError)
void setDevice(QIODevice *source)
Sets the NMEA data source to device.
QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly=false) const override
\reimp
~QNmeaPositionInfoSource()
Destroys the position source.
void setUpdateInterval(int msec) override
\reimp
void requestUpdate(int timeout=0) override
\reimp
QNmeaPositionInfoSourcePrivate * m_proxy
virtual void readAvailableData()=0
virtual ~QNmeaReader()
~QNmeaRealTimeReader() override
QNmeaRealTimeReader(QNmeaPositionInfoSourcePrivate *sourcePrivate)
void timerEvent(QTimerEvent *event) override
This event handler can be reimplemented in a subclass to receive timer events for the object.
QNmeaSimulatedReader(QNmeaPositionInfoSourcePrivate *sourcePrivate)
\inmodule QtCore
Definition qobject.h:103
int startTimer(int interval, Qt::TimerType timerType=Qt::CoarseTimer)
This is an overloaded function that will start a timer of type timerType and a timeout of interval mi...
Definition qobject.cpp:1817
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition qobject.cpp:1912
void enqueue(const T &t)
Adds value t to the tail of the queue.
Definition qqueue.h:18
T & head()
Returns a reference to the queue's head item.
Definition qqueue.h:20
T dequeue()
Removes the head item in the queue and returns it.
Definition qqueue.h:19
\inmodule QtCore \reentrant
Definition qdatetime.h:215
bool isValid() const
Returns true if the time is valid; otherwise returns false.
int msecsTo(QTime t) const
Returns the number of milliseconds from this time to t.
\inmodule QtCore
Definition qcoreevent.h:366
\inmodule QtCore
Definition qtimer.h:20
void setSingleShot(bool singleShot)
Definition qtimer.cpp:552
void start(int msec)
Starts or restarts the timer with a timeout interval of msec milliseconds.
Definition qtimer.cpp:241
void setInterval(int msec)
Definition qtimer.cpp:579
bool isActive() const
Returns true if the timer is running (pending); otherwise returns false.
Definition qtimer.cpp:167
void stop()
Stops the timer.
Definition qtimer.cpp:267
void timeout(QPrivateSignal)
This signal is emitted when the timer times out.
#define this
Definition dialogs.cpp:9
QDate date
[1]
Combined button and popup list for selecting options.
#define Q_DECL_CONSTEXPR
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall * pending
static struct AttrInfo attrs[]
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
bool qIsFinite(qfloat16 f) noexcept
Definition qfloat16.h:285
bool qIsNaN(qfloat16 f) noexcept
Definition qfloat16.h:284
#define qWarning
Definition qlogging.h:166
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
QGeoPositionInfoPrivate QGeoPositionInfoPrivateNmea
static bool propagateCoordinate(QGeoPositionInfo &dst, const QGeoPositionInfo &src, bool force=true)
static int processSentence(QGeoPositionInfo &info, QByteArray &m_nextLine, QNmeaPositionInfoSourcePrivate *m_proxy, QQueue< QPendingGeoPositionInfo > &m_pendingUpdates, bool &hasFix)
static bool propagateAttributes(QGeoPositionInfo &dst, const QGeoPositionInfo &src, bool force=true)
static qint64 msecsTo(const QDateTime &from, const QDateTime &to)
static bool propagateDate(QGeoPositionInfo &dst, const QGeoPositionInfo &src)
static bool mergePositions(QGeoPositionInfo &dst, const QGeoPositionInfo &src, QByteArray nmeaSentence)
Q_CORE_EXPORT Q_DECL_CONST_FUNCTION double qQNaN()
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLbitfield GLuint64 timeout
[4]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum src
GLenum GLenum dst
GLenum GLuint GLenum GLsizei const GLchar * buf
struct _cl_event * event
const GLubyte * c
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
#define emit
#define Q_UNUSED(x)
ptrdiff_t qsizetype
Definition qtypes.h:165
long long qint64
Definition qtypes.h:60
QHostInfo info
[0]