Skip to content

Commit

Permalink
[gps] Catch NMEA UTC times for date-less streams (#51346)
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvn committed Jan 1, 2023
1 parent f716f6c commit 2aacff1
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 8 deletions.
2 changes: 2 additions & 0 deletions python/core/auto_generated/gps/qgsgpsinformation.sip.in
Expand Up @@ -50,6 +50,8 @@ Encapsulates information relating to a GPS position fix.

double hvacc;

QTime utcTime;

QDateTime utcDateTime;

QChar fixMode;
Expand Down
6 changes: 6 additions & 0 deletions src/core/gps/qgsgpsinformation.h
Expand Up @@ -129,6 +129,12 @@ class CORE_EXPORT QgsGpsInformation
double hvacc;
#endif

/**
* The time at which this position was reported, in UTC time.
* \since QGIS 3.30
*/
QTime utcTime;

/**
* The date and time at which this position was reported, in UTC time.
*/
Expand Down
21 changes: 17 additions & 4 deletions src/core/gps/qgsnmeaconnection.cpp
Expand Up @@ -199,6 +199,19 @@ void QgsNmeaConnection::processGgaSentence( const char *data, int len )
mLastGPSInformation.elevation = result.elv;
mLastGPSInformation.elevation_diff = result.diff;

const QTime time( result.utc.hour, result.utc.min, result.utc.sec, result.utc.msec );
if ( time.isValid() )
{
mLastGPSInformation.utcTime = time;
if ( mLastGPSInformation.utcDateTime.isValid() )
{
mLastGPSInformation.utcDateTime.setTimeSpec( Qt::UTC );
mLastGPSInformation.utcDateTime.setTime( time );
}
QgsDebugMsgLevel( QStringLiteral( "utc time:" ), 2 );
QgsDebugMsgLevel( mLastGPSInformation.utcTime.toString(), 2 );
}

mLastGPSInformation.quality = result.sig;
if ( result.sig >= 0 && result.sig <= 8 )
{
Expand Down Expand Up @@ -285,17 +298,17 @@ void QgsNmeaConnection::processRmcSentence( const char *data, int len )
mLastGPSInformation.direction = result.direction;
mLastGPSInformation.status = result.status; // A,V

//date and time
const QDate date( result.utc.year + 1900, result.utc.mon + 1, result.utc.day );
const QTime time( result.utc.hour, result.utc.min, result.utc.sec, result.utc.msec ); // added msec part
const QTime time( result.utc.hour, result.utc.min, result.utc.sec, result.utc.msec );
if ( date.isValid() && time.isValid() )
{
mLastGPSInformation.utcTime = time;
mLastGPSInformation.utcDateTime.setTimeSpec( Qt::UTC );
mLastGPSInformation.utcDateTime.setDate( date );
mLastGPSInformation.utcDateTime.setTime( time );
QgsDebugMsgLevel( QStringLiteral( "utc time:" ), 2 );
QgsDebugMsgLevel( QStringLiteral( "utc date/time:" ), 2 );
QgsDebugMsgLevel( mLastGPSInformation.utcDateTime.toString(), 2 );
QgsDebugMsgLevel( QStringLiteral( "local time:" ), 2 );
QgsDebugMsgLevel( QStringLiteral( "local date/time:" ), 2 );
QgsDebugMsgLevel( mLastGPSInformation.utcDateTime.toLocalTime().toString(), 2 );
}

Expand Down
1 change: 1 addition & 0 deletions src/core/gps/qgsqtlocationconnection.cpp
Expand Up @@ -69,6 +69,7 @@ void QgsQtLocationConnection::parseData()
mLastGPSInformation.speed = mInfo.attribute( QGeoPositionInfo::GroundSpeed ) * 3.6; // m/s to km/h
mLastGPSInformation.direction = mInfo.attribute( QGeoPositionInfo::Direction );
mLastGPSInformation.utcDateTime = mInfo.timestamp();
mLastGPSInformation.utcTime = mInfo.timestamp().time();
mLastGPSInformation.fixType = mInfo.coordinate().type() + 1;
switch ( mInfo.coordinate().type() )
{
Expand Down
19 changes: 15 additions & 4 deletions tests/src/core/testqgsnmeaconnection.cpp
Expand Up @@ -124,17 +124,21 @@ void TestQgsNmeaConnection::testBasic()
QCOMPARE( info.elevation, 0 );
QVERIFY( std::isnan( info.direction ) );

info = connection.push( QStringLiteral( "$GPRMC,084111.185,A,6938.6531,N,01856.8527,E,0.16,2.00,220120,,,A*6E" ) );
info = connection.push( QStringLiteral( "$GPGGA,084112.185,6938.6532,N,01856.8526,E,1,04,1.4,35.0,M,29.4,M,,0000*63" ) );
QVERIFY( info.isValid() );
QVERIFY( info.satInfoComplete );
QCOMPARE( info.bestFixStatus( constellation ), Qgis::GpsFixStatus::NoData );
QCOMPARE( info.qualityDescription(), QStringLiteral( "Autonomous" ) );
QGSCOMPARENEAR( info.latitude, 69.6442183333, 0.00001 );
QGSCOMPARENEAR( info.longitude, 18.947545, 0.00001 );
QCOMPARE( info.elevation, 0 );
QGSCOMPARENEAR( info.direction, 2.0000000000, 0.0001 );
QCOMPARE( info.elevation, 35 );
// At this stage, we have no direction information, waiting for an GPRMC sentence
QCOMPARE( info.direction, std::numeric_limits<double>::quiet_NaN() );
// At this stage, having only received an GPGGA sentence, the date remains unknown
QCOMPARE( info.utcDateTime, QDateTime() );
QCOMPARE( info.utcTime, QTime( 8, 41, 12, 185 ) );

info = connection.push( QStringLiteral( "$GPGGA,084112.185,6938.6532,N,01856.8526,E,1,04,1.4,35.0,M,29.4,M,,0000*63" ) );
info = connection.push( QStringLiteral( "$GPRMC,084111.185,A,6938.6531,N,01856.8527,E,0.16,2.00,220120,,,A*6E" ) );
QVERIFY( info.isValid() );
QVERIFY( info.satInfoComplete );
QCOMPARE( info.bestFixStatus( constellation ), Qgis::GpsFixStatus::NoData );
Expand All @@ -143,6 +147,13 @@ void TestQgsNmeaConnection::testBasic()
QGSCOMPARENEAR( info.longitude, 18.947545, 0.00001 );
QCOMPARE( info.elevation, 35 );
QGSCOMPARENEAR( info.direction, 2.0000000000, 0.0001 );
// The (optional) GPRMC sentence came in, we now have a date and a time value.
QDateTime dateTime;
dateTime.setTimeSpec( Qt::UTC );
dateTime.setDate( QDate( 2020, 1, 22 ) );
dateTime.setTime( QTime( 8, 41, 11, 185 ) );
QCOMPARE( info.utcDateTime, dateTime );
QCOMPARE( info.utcTime, dateTime.time() );

info = connection.push( QStringLiteral( "$GPGSA,A,3,07,05,16,26,,,,,,,,,3.4,1.4,3.1*33" ) );
QVERIFY( info.isValid() );
Expand Down

0 comments on commit 2aacff1

Please sign in to comment.