Add fix status changed signal to QgsGpsConnection

This commit is contained in:
Nyall Dawson 2022-10-31 10:33:34 +10:00
parent 8cd280c9f6
commit 3a89b5505b
5 changed files with 107 additions and 2 deletions

View File

@ -193,8 +193,24 @@ Returns the current gps information (lat, lon, etc.)
%End
signals:
void stateChanged( const QgsGpsInformation &info );
void nmeaSentenceReceived( const QString &substring ); // added to capture 'raw' data
%Docstring
Emitted whenever the GPS state is changed.
%End
void nmeaSentenceReceived( const QString &substring );
%Docstring
Emitted whenever the GPS device receives a raw NMEA sentence.
%End
void fixStatusChanged( Qgis::GpsFixStatus status );
%Docstring
Emitted when the GPS device fix status is changed.
.. versionadded:: 3.30
%End
protected:
@ -203,6 +219,7 @@ Returns the current gps information (lat, lon, etc.)
%Docstring
Parse available data source content
%End
};

View File

@ -109,6 +109,8 @@ QgsGpsConnection::QgsGpsConnection( QIODevice *dev )
{
if ( mSource )
QObject::connect( mSource.get(), &QIODevice::readyRead, this, &QgsGpsConnection::parseData );
QObject::connect( this, &QgsGpsConnection::stateChanged, this, &QgsGpsConnection::onStateChanged );
}
QgsGpsConnection::~QgsGpsConnection()
@ -139,6 +141,13 @@ bool QgsGpsConnection::close()
}
mSource->close();
if ( mLastFixStatus != Qgis::GpsFixStatus::NoData )
{
mLastFixStatus = Qgis::GpsFixStatus::NoData;
emit fixStatusChanged( mLastFixStatus );
}
return true;
}
@ -149,6 +158,12 @@ void QgsGpsConnection::cleanupSource()
mSource->close();
}
mSource.reset();
if ( mLastFixStatus != Qgis::GpsFixStatus::NoData )
{
mLastFixStatus = Qgis::GpsFixStatus::NoData;
emit fixStatusChanged( mLastFixStatus );
}
}
void QgsGpsConnection::setSource( QIODevice *source )
@ -160,6 +175,15 @@ void QgsGpsConnection::setSource( QIODevice *source )
clearLastGPSInformation();
}
void QgsGpsConnection::onStateChanged( const QgsGpsInformation &info )
{
if ( info.fixStatus() != mLastFixStatus )
{
mLastFixStatus = info.fixStatus();
emit fixStatusChanged( mLastFixStatus );
}
}
void QgsGpsConnection::clearLastGPSInformation()
{
mLastGPSInformation = QgsGpsInformation();

View File

@ -356,8 +356,25 @@ class CORE_EXPORT QgsGpsConnection : public QObject
QgsGpsInformation currentGPSInformation() const { return mLastGPSInformation; }
signals:
/**
* Emitted whenever the GPS state is changed.
*/
void stateChanged( const QgsGpsInformation &info );
void nmeaSentenceReceived( const QString &substring ); // added to capture 'raw' data
// TODO QGIS 4.0 -- move to QgsNmeaConnection, it makes no sense in the base class
/**
* Emitted whenever the GPS device receives a raw NMEA sentence.
*/
void nmeaSentenceReceived( const QString &substring );
/**
* Emitted when the GPS device fix status is changed.
*
* \since QGIS 3.30
*/
void fixStatusChanged( Qgis::GpsFixStatus status );
protected:
//! Data source (e.g. serial device, socket, file,...)
@ -367,6 +384,10 @@ class CORE_EXPORT QgsGpsConnection : public QObject
//! Connection status
Status mStatus = NotConnected;
private slots:
void onStateChanged( const QgsGpsInformation &info );
private:
//! Closes and deletes mSource
void cleanupSource();
@ -375,6 +396,12 @@ class CORE_EXPORT QgsGpsConnection : public QObject
protected slots:
//! Parse available data source content
virtual void parseData() = 0;
private:
//! Last fix status
Qgis::GpsFixStatus mLastFixStatus = Qgis::GpsFixStatus::NoData;
};
Q_DECLARE_METATYPE( QgsGpsInformation )

View File

@ -280,6 +280,7 @@ void QgsApplication::init( QString profileFolder )
qRegisterMetaType<QgsFeatureStoreList>( "QgsFeatureStoreList" );
qRegisterMetaType<Qgis::MessageLevel>( "Qgis::MessageLevel" );
qRegisterMetaType<Qgis::BrowserItemState>( "Qgis::BrowserItemState" );
qRegisterMetaType<Qgis::GpsFixStatus>( "Qgis::GpsFixStatus" );
qRegisterMetaType<QgsReferencedRectangle>( "QgsReferencedRectangle" );
qRegisterMetaType<QgsReferencedPointXY>( "QgsReferencedPointXY" );
qRegisterMetaType<QgsReferencedGeometry>( "QgsReferencedGeometry" );

View File

@ -192,27 +192,53 @@ void TestQgsNmeaConnection::testFixStatus()
{
ReplayNmeaConnection connection;
QSignalSpy statusSpy( &connection, &QgsGpsConnection::fixStatusChanged );
QgsGpsInformation info = connection.push( QStringLiteral( "$GPRMC,220516,V,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70" ) );
QVERIFY( !info.isValid() );
QCOMPARE( info.fixStatus(), Qgis::GpsFixStatus::NoFix );
QCOMPARE( statusSpy.count(), 1 );
QCOMPARE( statusSpy.constLast().at( 0 ).value< Qgis::GpsFixStatus >(), Qgis::GpsFixStatus::NoFix );
// no fix status change
connection.push( QStringLiteral( "$GPRMC,220516,V,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70" ) );
QCOMPARE( statusSpy.count(), 1 );
// simulate 3d fix
connection.push( QStringLiteral( "$GPGSA,A,3,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C" ) );
info = connection.push( QStringLiteral( "$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70" ) );
QVERIFY( info.isValid() );
QCOMPARE( info.fixStatus(), Qgis::GpsFixStatus::Fix3D );
QCOMPARE( statusSpy.count(), 2 );
QCOMPARE( statusSpy.constLast().at( 0 ).value< Qgis::GpsFixStatus >(), Qgis::GpsFixStatus::Fix3D );
// no fix status change
connection.push( QStringLiteral( "$GPGSA,A,3,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C" ) );
QCOMPARE( statusSpy.count(), 2 );
// simulate 2d fix
connection.push( QStringLiteral( "$GPGSA,A,2,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C" ) );
info = connection.push( QStringLiteral( "$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70" ) );
QVERIFY( info.isValid() );
QCOMPARE( info.fixStatus(), Qgis::GpsFixStatus::Fix2D );
QCOMPARE( statusSpy.count(), 3 );
QCOMPARE( statusSpy.constLast().at( 0 ).value< Qgis::GpsFixStatus >(), Qgis::GpsFixStatus::Fix2D );
// no fix status change
connection.push( QStringLiteral( "$GPGSA,A,2,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C" ) );
QCOMPARE( statusSpy.count(), 3 );
// simulate fix not available
connection.push( QStringLiteral( "$GPGSA,A,1,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C" ) );
info = connection.push( QStringLiteral( "$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70" ) );
QVERIFY( !info.isValid() );
QCOMPARE( info.fixStatus(), Qgis::GpsFixStatus::NoFix );
QCOMPARE( statusSpy.count(), 4 );
QCOMPARE( statusSpy.constLast().at( 0 ).value< Qgis::GpsFixStatus >(), Qgis::GpsFixStatus::NoFix );
// no fix status change
connection.push( QStringLiteral( "$GPGSA,A,1,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C" ) );
QCOMPARE( statusSpy.count(), 4 );
// invalid fix due to bad lat / long values
connection.push( QStringLiteral( "$GPGSA,A,2,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C" ) );
@ -222,6 +248,9 @@ void TestQgsNmeaConnection::testFixStatus()
QGSCOMPARENEAR( info.longitude, -0.70400000, 0.00001 );
QVERIFY( !info.isValid() );
QCOMPARE( statusSpy.count(), 5 );
QCOMPARE( statusSpy.constLast().at( 0 ).value< Qgis::GpsFixStatus >(), Qgis::GpsFixStatus::Fix2D );
info = connection.push( QStringLiteral( "$GPRMC,220516,A,9933.82,S,00042.24,W,173.8,231.8,130694,004.2,W*70" ) );
QGSCOMPARENEAR( info.latitude, -99.563666, 0.00001 );
QGSCOMPARENEAR( info.longitude, -0.70400000, 0.00001 );
@ -237,6 +266,13 @@ void TestQgsNmeaConnection::testFixStatus()
QGSCOMPARENEAR( info.latitude, 19.5636666667, 0.00001 );
QGSCOMPARENEAR( info.longitude, 192.5373333333, 0.00001 );
QVERIFY( !info.isValid() );
QCOMPARE( statusSpy.count(), 5 );
connection.close();
QCOMPARE( statusSpy.count(), 6 );
QCOMPARE( statusSpy.constLast().at( 0 ).value< Qgis::GpsFixStatus >(), Qgis::GpsFixStatus::NoData );
}
QGSTEST_MAIN( TestQgsNmeaConnection )