Skip to content

Commit 53dbca2

Browse files
rossianyalldawson
authored andcommitted
[FEATURE] GPS acquisition interval and distance threshold options
Adds an acquisition interval parameter and a distance threshold parameter to the gps plugin in order to keep the cursor still when the receiver is in static conditions.
1 parent a756fb1 commit 53dbca2

File tree

4 files changed

+385
-149
lines changed

4 files changed

+385
-149
lines changed

external/nmea/gmath.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#define NMEA_GMATH_H
2929

3030
#include "info.h"
31+
#include <qgis_core.h>
3132

3233
#define NMEA_PI (3.141592653589793) //!< PI value
3334
#define NMEA_PI180 (NMEA_PI / 180) //!< PI division by 180
@@ -47,7 +48,7 @@ extern "C"
4748
* degree VS radian
4849
*/
4950

50-
double nmea_degree2radian( double val );
51+
double CORE_EXPORT nmea_degree2radian( double val );
5152
double nmea_radian2degree( double val );
5253

5354
/*
@@ -75,7 +76,7 @@ double nmea_meters2dop( double meters );
7576
void nmea_info2pos( const nmeaINFO *info, nmeaPOS *pos );
7677
void nmea_pos2info( const nmeaPOS *pos, nmeaINFO *info );
7778

78-
double nmea_distance(
79+
double CORE_EXPORT nmea_distance(
7980
const nmeaPOS *from_pos,
8081
const nmeaPOS *to_pos
8182
);

src/app/gps/qgsgpsinformationwidget.cpp

+116-1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "qgswkbptr.h"
3838
#include "qgssettings.h"
3939
#include "qgsstatusbar.h"
40+
#include "gmath.h"
4041

4142
// QWT Charting widget
4243

@@ -82,6 +83,7 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *thepCanvas, QWid
8283
mpLastLayer = nullptr;
8384

8485
mLastGpsPosition = QgsPointXY( 0.0, 0.0 );
86+
mLastNmeaPosition.lat = nmea_degree2radian( 0.0 ); mLastNmeaPosition.lon = nmea_degree2radian( 0.0 );
8587

8688
mpMapMarker = nullptr;
8789
mpRubberBand = nullptr;
@@ -255,6 +257,44 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *thepCanvas, QWid
255257

256258
mStackedWidget->setCurrentIndex( 3 ); // force to Options
257259
mBtnPosition->setFocus( Qt::TabFocusReason );
260+
261+
mAcquisitionIntValidator = new QIntValidator( 0, MAXACQUISITIONINTERVAL, this );
262+
mDistanceThresholdValidator = new QIntValidator( 0, MAXDISTANCETHRESHOLD, this );
263+
mAcquisitionTimer = std::unique_ptr<QTimer>( new QTimer( this ) );
264+
mAcquisitionTimer->setSingleShot( true );
265+
mCboAcquisitionInterval->setInsertPolicy( QComboBox::NoInsert );
266+
mCboDistanceThreshold->setInsertPolicy( QComboBox::NoInsert );
267+
mCboAcquisitionInterval->addItem( QStringLiteral( "0" ), 0 );
268+
mCboAcquisitionInterval->addItem( QStringLiteral( "2" ), 2 );
269+
mCboAcquisitionInterval->addItem( QStringLiteral( "5" ), 5 );
270+
mCboAcquisitionInterval->addItem( QStringLiteral( "10" ), 10 );
271+
mCboAcquisitionInterval->addItem( QStringLiteral( "15" ), 15 );
272+
mCboAcquisitionInterval->addItem( QStringLiteral( "30" ), 30 );
273+
mCboAcquisitionInterval->addItem( QStringLiteral( "60" ), 60 );
274+
mCboAcquisitionInterval->addItem( tr( "" ) );
275+
mCboDistanceThreshold->addItem( QStringLiteral( "0" ), 0 );
276+
mCboDistanceThreshold->addItem( QStringLiteral( "3" ), 3 );
277+
mCboDistanceThreshold->addItem( QStringLiteral( "5" ), 5 );
278+
mCboDistanceThreshold->addItem( QStringLiteral( "10" ), 10 );
279+
mCboDistanceThreshold->addItem( QStringLiteral( "15" ), 15 );
280+
mCboDistanceThreshold->addItem( tr( "" ) );
281+
mCboAcquisitionInterval->setCurrentIndex( 0 );
282+
mCboAcquisitionInterval->setCurrentIndex( 0 );
283+
connect( mAcquisitionTimer.get(), &QTimer::timeout,
284+
this, &QgsGPSInformationWidget::switchAcquisition );
285+
connect( mCboAcquisitionInterval, static_cast<void( QComboBox::* )( const QString & )>( &QComboBox::activated ),
286+
this, &QgsGPSInformationWidget::cboAcquisitionIntervalActivated );
287+
connect( mCboDistanceThreshold, static_cast<void( QComboBox::* )( const QString & )>( &QComboBox::activated ),
288+
this, &QgsGPSInformationWidget::cboDistanceThresholdActivated );
289+
mAcIntervalEdit = new QLineEdit;
290+
mDistThresholdEdit = new QLineEdit;
291+
mAcIntervalEdit->setValidator( mAcquisitionIntValidator );
292+
mDistThresholdEdit->setValidator( mDistanceThresholdValidator );
293+
connect( mAcIntervalEdit, &QLineEdit::editingFinished,
294+
this, &QgsGPSInformationWidget::cboAcquisitionIntervalEdited );
295+
connect( mDistThresholdEdit, &QLineEdit::editingFinished,
296+
this, &QgsGPSInformationWidget::cboDistanceThresholdEdited );
297+
258298
}
259299

260300
QgsGpsInformationWidget::~QgsGpsInformationWidget()
@@ -535,6 +575,7 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
535575
}
536576
else // unknown status (not likely)
537577
{
578+
538579
}
539580

540581
// set visual status indicator -- do only on change of state
@@ -639,15 +680,28 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
639680
}
640681

641682
QgsPointXY myNewCenter;
683+
nmeaPOS newNmeaPosition;
642684
if ( validFlag )
643685
{
644686
myNewCenter = QgsPointXY( info.longitude, info.latitude );
687+
newNmeaPosition.lat = nmea_degree2radian( info.latitude ); newNmeaPosition.lon = nmea_degree2radian( info.longitude );
645688
}
646689
else
647690
{
648691
myNewCenter = mLastGpsPosition;
692+
newNmeaPosition = mLastNmeaPosition;
649693
}
694+
if ( !mAcquisitionEnabled || ( nmea_distance( &newNmeaPosition, &mLastNmeaPosition ) < mDistanceThreshold ) )
695+
{
696+
// do not update position if update is disabled by timer or distance is under threshold
697+
myNewCenter = mLastGpsPosition;
650698

699+
}
700+
if ( validFlag && mAcquisitionEnabled )
701+
{
702+
// position updated by valid data, reset timer
703+
switchAcquisition();
704+
}
651705
if ( mStackedWidget->currentIndex() == 0 ) //position
652706
{
653707
mTxtLatitude->setText( QString::number( info.latitude, 'f', 8 ) );
@@ -679,7 +733,7 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
679733
if ( mLastGpsPosition != myNewCenter )
680734
{
681735
mLastGpsPosition = myNewCenter;
682-
736+
mLastNmeaPosition = newNmeaPosition;
683737
// Pan based on user specified behavior
684738
if ( radRecenterMap->isChecked() || radRecenterWhenNeeded->isChecked() )
685739
{
@@ -1137,3 +1191,64 @@ void QgsGpsInformationWidget::showStatusBarMessage( const QString &msg )
11371191
{
11381192
QgisApp::instance()->statusBarIface()->showMessage( msg );
11391193
}
1194+
void QgsGPSInformationWidget::setAcquisitionInterval( int interval )
1195+
{
1196+
mAcquisitionInterval = interval * 1000;
1197+
if ( mAcquisitionTimer->isActive() )
1198+
mAcquisitionTimer->stop();
1199+
mAcquisitionEnabled = true;
1200+
switchAcquisition();
1201+
1202+
}
1203+
void QgsGPSInformationWidget::setDistanceThreshold( int distance )
1204+
{
1205+
mDistanceThreshold = distance;
1206+
}
1207+
void QgsGPSInformationWidget::cboAcquisitionIntervalActivated( const QString &text )
1208+
{
1209+
if ( text == "" )
1210+
{
1211+
mCboAcquisitionInterval->setEditable( true );
1212+
mCboAcquisitionInterval->setLineEdit( mAcIntervalEdit );
1213+
mCboAcquisitionInterval->clearEditText();
1214+
}
1215+
else
1216+
{
1217+
setAcquisitionInterval( text.toInt() );
1218+
}
1219+
}
1220+
void QgsGPSInformationWidget::cboDistanceThresholdActivated( const QString &text )
1221+
{
1222+
if ( text == "" )
1223+
{
1224+
mCboDistanceThreshold->setEditable( true );
1225+
mCboDistanceThreshold->setLineEdit( mDistThresholdEdit );
1226+
mCboDistanceThreshold->clearEditText();
1227+
1228+
}
1229+
else
1230+
{
1231+
setDistanceThreshold( text.toInt() );
1232+
}
1233+
}
1234+
void QgsGPSInformationWidget::cboAcquisitionIntervalEdited()
1235+
{
1236+
setAcquisitionInterval( mAcIntervalEdit->text().toInt() );
1237+
}
1238+
void QgsGPSInformationWidget::cboDistanceThresholdEdited()
1239+
{
1240+
setDistanceThreshold( mDistThresholdEdit->text().toInt() );
1241+
}
1242+
void QgsGPSInformationWidget::switchAcquisition()
1243+
{
1244+
if ( mAcquisitionInterval > 0 )
1245+
{
1246+
if ( mAcquisitionEnabled )
1247+
mAcquisitionTimer->start( mAcquisitionInterval );
1248+
else
1249+
//wait only acquisitionInterval/10 for new valid data
1250+
mAcquisitionTimer->start( mAcquisitionInterval / 10 );
1251+
// anyway switch to enabled / disabled acquisition
1252+
mAcquisitionEnabled = !mAcquisitionEnabled;
1253+
}
1254+
}

src/app/gps/qgsgpsinformationwidget.h

+20-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include "ui_qgsgpsinformationwidgetbase.h"
2121

22+
#include "gmath.h"
23+
#include "info.h"
2224
#include "qgsmapcanvas.h"
2325
#include "qgsgpsmarker.h"
2426
#include "qgsmaptoolcapture.h"
@@ -28,6 +30,8 @@
2830
#include <qwt_polar_grid.h>
2931
#include <qwt_polar_marker.h>
3032
#endif
33+
#define MAXACQUISITIONINTERVAL 300 // max gps information acquisition suspension interval (in seconds)
34+
#define MAXDISTANCETHRESHOLD 10 // max gps distance threshold (in meters)
3135

3236
class QextSerialPort;
3337
class QgsGpsConnection;
@@ -71,7 +75,11 @@ class QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInformationWidg
7175

7276
void connected( QgsGpsConnection * );
7377
void timedout();
74-
78+
void switchAcquisition();
79+
void cboAcquisitionIntervalActivated( const QString & );
80+
void cboDistanceThresholdActivated( const QString & );
81+
void cboAcquisitionIntervalEdited();
82+
void cboDistanceThresholdEdited();
7583
private:
7684
enum FixStatus //GPS status
7785
{
@@ -84,6 +92,8 @@ class QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInformationWidg
8492
void populateDevices();
8593
void setStatusIndicator( FixStatus statusValue );
8694
void showStatusBarMessage( const QString &msg );
95+
void setAcquisitionInterval( int );
96+
void setDistanceThreshold( int );
8797
QgsGpsConnection *mNmea = nullptr;
8898
QgsMapCanvas *mpCanvas = nullptr;
8999
QgsGpsMarker *mpMapMarker = nullptr;
@@ -95,6 +105,7 @@ class QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInformationWidg
95105
QList< QwtPolarMarker * > mMarkerList;
96106
#endif
97107
void createRubberBand();
108+
98109
QgsCoordinateReferenceSystem mWgs84CRS;
99110
// not used QPointF gpsToPixelPosition( const QgsPoint& point );
100111
QgsRubberBand *mpRubberBand = nullptr;
@@ -106,6 +117,14 @@ class QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInformationWidg
106117
QFile *mLogFile = nullptr;
107118
QTextStream mLogFileTextStream;
108119
QColor mTrackColor;
120+
QIntValidator *mAcquisitionIntValidator = nullptr;
121+
QIntValidator *mDistanceThresholdValidator = nullptr;
122+
QLineEdit *mAcIntervalEdit = nullptr, *mDistThresholdEdit = nullptr;
123+
nmeaPOS mLastNmeaPosition;
124+
std::unique_ptr<QTimer> mAcquisitionTimer;
125+
bool mAcquisitionEnabled = true;
126+
unsigned int mAcquisitionInterval = 0;
127+
unsigned int mDistanceThreshold = 0;
109128
};
110129

111130
#endif // QGSGPSINFORMATIONWIDGET_H

0 commit comments

Comments
 (0)