Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
rossia authored and nyalldawson committed Jun 29, 2018
1 parent a756fb1 commit 53dbca2
Show file tree
Hide file tree
Showing 4 changed files with 385 additions and 149 deletions.
5 changes: 3 additions & 2 deletions external/nmea/gmath.h
Expand Up @@ -28,6 +28,7 @@
#define NMEA_GMATH_H

#include "info.h"
#include <qgis_core.h>

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

double nmea_degree2radian( double val );
double CORE_EXPORT nmea_degree2radian( double val );
double nmea_radian2degree( double val );

/*
Expand Down Expand Up @@ -75,7 +76,7 @@ double nmea_meters2dop( double meters );
void nmea_info2pos( const nmeaINFO *info, nmeaPOS *pos );
void nmea_pos2info( const nmeaPOS *pos, nmeaINFO *info );

double nmea_distance(
double CORE_EXPORT nmea_distance(
const nmeaPOS *from_pos,
const nmeaPOS *to_pos
);
Expand Down
117 changes: 116 additions & 1 deletion src/app/gps/qgsgpsinformationwidget.cpp
Expand Up @@ -37,6 +37,7 @@
#include "qgswkbptr.h"
#include "qgssettings.h"
#include "qgsstatusbar.h"
#include "gmath.h"

// QWT Charting widget

Expand Down Expand Up @@ -82,6 +83,7 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *thepCanvas, QWid
mpLastLayer = nullptr;

mLastGpsPosition = QgsPointXY( 0.0, 0.0 );
mLastNmeaPosition.lat = nmea_degree2radian( 0.0 ); mLastNmeaPosition.lon = nmea_degree2radian( 0.0 );

mpMapMarker = nullptr;
mpRubberBand = nullptr;
Expand Down Expand Up @@ -255,6 +257,44 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *thepCanvas, QWid

mStackedWidget->setCurrentIndex( 3 ); // force to Options
mBtnPosition->setFocus( Qt::TabFocusReason );

mAcquisitionIntValidator = new QIntValidator( 0, MAXACQUISITIONINTERVAL, this );
mDistanceThresholdValidator = new QIntValidator( 0, MAXDISTANCETHRESHOLD, this );
mAcquisitionTimer = std::unique_ptr<QTimer>( new QTimer( this ) );
mAcquisitionTimer->setSingleShot( true );
mCboAcquisitionInterval->setInsertPolicy( QComboBox::NoInsert );
mCboDistanceThreshold->setInsertPolicy( QComboBox::NoInsert );
mCboAcquisitionInterval->addItem( QStringLiteral( "0" ), 0 );
mCboAcquisitionInterval->addItem( QStringLiteral( "2" ), 2 );
mCboAcquisitionInterval->addItem( QStringLiteral( "5" ), 5 );
mCboAcquisitionInterval->addItem( QStringLiteral( "10" ), 10 );
mCboAcquisitionInterval->addItem( QStringLiteral( "15" ), 15 );
mCboAcquisitionInterval->addItem( QStringLiteral( "30" ), 30 );
mCboAcquisitionInterval->addItem( QStringLiteral( "60" ), 60 );
mCboAcquisitionInterval->addItem( tr( "" ) );
mCboDistanceThreshold->addItem( QStringLiteral( "0" ), 0 );
mCboDistanceThreshold->addItem( QStringLiteral( "3" ), 3 );
mCboDistanceThreshold->addItem( QStringLiteral( "5" ), 5 );
mCboDistanceThreshold->addItem( QStringLiteral( "10" ), 10 );
mCboDistanceThreshold->addItem( QStringLiteral( "15" ), 15 );
mCboDistanceThreshold->addItem( tr( "" ) );
mCboAcquisitionInterval->setCurrentIndex( 0 );
mCboAcquisitionInterval->setCurrentIndex( 0 );
connect( mAcquisitionTimer.get(), &QTimer::timeout,
this, &QgsGPSInformationWidget::switchAcquisition );
connect( mCboAcquisitionInterval, static_cast<void( QComboBox::* )( const QString & )>( &QComboBox::activated ),
this, &QgsGPSInformationWidget::cboAcquisitionIntervalActivated );
connect( mCboDistanceThreshold, static_cast<void( QComboBox::* )( const QString & )>( &QComboBox::activated ),
this, &QgsGPSInformationWidget::cboDistanceThresholdActivated );
mAcIntervalEdit = new QLineEdit;
mDistThresholdEdit = new QLineEdit;
mAcIntervalEdit->setValidator( mAcquisitionIntValidator );
mDistThresholdEdit->setValidator( mDistanceThresholdValidator );
connect( mAcIntervalEdit, &QLineEdit::editingFinished,
this, &QgsGPSInformationWidget::cboAcquisitionIntervalEdited );
connect( mDistThresholdEdit, &QLineEdit::editingFinished,
this, &QgsGPSInformationWidget::cboDistanceThresholdEdited );

}

QgsGpsInformationWidget::~QgsGpsInformationWidget()
Expand Down Expand Up @@ -535,6 +575,7 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
}
else // unknown status (not likely)
{

}

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

QgsPointXY myNewCenter;
nmeaPOS newNmeaPosition;
if ( validFlag )
{
myNewCenter = QgsPointXY( info.longitude, info.latitude );
newNmeaPosition.lat = nmea_degree2radian( info.latitude ); newNmeaPosition.lon = nmea_degree2radian( info.longitude );
}
else
{
myNewCenter = mLastGpsPosition;
newNmeaPosition = mLastNmeaPosition;
}
if ( !mAcquisitionEnabled || ( nmea_distance( &newNmeaPosition, &mLastNmeaPosition ) < mDistanceThreshold ) )
{
// do not update position if update is disabled by timer or distance is under threshold
myNewCenter = mLastGpsPosition;

}
if ( validFlag && mAcquisitionEnabled )
{
// position updated by valid data, reset timer
switchAcquisition();
}
if ( mStackedWidget->currentIndex() == 0 ) //position
{
mTxtLatitude->setText( QString::number( info.latitude, 'f', 8 ) );
Expand Down Expand Up @@ -679,7 +733,7 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
if ( mLastGpsPosition != myNewCenter )
{
mLastGpsPosition = myNewCenter;

mLastNmeaPosition = newNmeaPosition;
// Pan based on user specified behavior
if ( radRecenterMap->isChecked() || radRecenterWhenNeeded->isChecked() )
{
Expand Down Expand Up @@ -1137,3 +1191,64 @@ void QgsGpsInformationWidget::showStatusBarMessage( const QString &msg )
{
QgisApp::instance()->statusBarIface()->showMessage( msg );
}
void QgsGPSInformationWidget::setAcquisitionInterval( int interval )
{
mAcquisitionInterval = interval * 1000;
if ( mAcquisitionTimer->isActive() )
mAcquisitionTimer->stop();
mAcquisitionEnabled = true;
switchAcquisition();

}
void QgsGPSInformationWidget::setDistanceThreshold( int distance )
{
mDistanceThreshold = distance;
}
void QgsGPSInformationWidget::cboAcquisitionIntervalActivated( const QString &text )
{
if ( text == "" )
{
mCboAcquisitionInterval->setEditable( true );
mCboAcquisitionInterval->setLineEdit( mAcIntervalEdit );
mCboAcquisitionInterval->clearEditText();
}
else
{
setAcquisitionInterval( text.toInt() );
}
}
void QgsGPSInformationWidget::cboDistanceThresholdActivated( const QString &text )
{
if ( text == "" )
{
mCboDistanceThreshold->setEditable( true );
mCboDistanceThreshold->setLineEdit( mDistThresholdEdit );
mCboDistanceThreshold->clearEditText();

}
else
{
setDistanceThreshold( text.toInt() );
}
}
void QgsGPSInformationWidget::cboAcquisitionIntervalEdited()
{
setAcquisitionInterval( mAcIntervalEdit->text().toInt() );
}
void QgsGPSInformationWidget::cboDistanceThresholdEdited()
{
setDistanceThreshold( mDistThresholdEdit->text().toInt() );
}
void QgsGPSInformationWidget::switchAcquisition()
{
if ( mAcquisitionInterval > 0 )
{
if ( mAcquisitionEnabled )
mAcquisitionTimer->start( mAcquisitionInterval );
else
//wait only acquisitionInterval/10 for new valid data
mAcquisitionTimer->start( mAcquisitionInterval / 10 );
// anyway switch to enabled / disabled acquisition
mAcquisitionEnabled = !mAcquisitionEnabled;
}
}
21 changes: 20 additions & 1 deletion src/app/gps/qgsgpsinformationwidget.h
Expand Up @@ -19,6 +19,8 @@

#include "ui_qgsgpsinformationwidgetbase.h"

#include "gmath.h"
#include "info.h"
#include "qgsmapcanvas.h"
#include "qgsgpsmarker.h"
#include "qgsmaptoolcapture.h"
Expand All @@ -28,6 +30,8 @@
#include <qwt_polar_grid.h>
#include <qwt_polar_marker.h>
#endif
#define MAXACQUISITIONINTERVAL 300 // max gps information acquisition suspension interval (in seconds)
#define MAXDISTANCETHRESHOLD 10 // max gps distance threshold (in meters)

class QextSerialPort;
class QgsGpsConnection;
Expand Down Expand Up @@ -71,7 +75,11 @@ class QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInformationWidg

void connected( QgsGpsConnection * );
void timedout();

void switchAcquisition();
void cboAcquisitionIntervalActivated( const QString & );
void cboDistanceThresholdActivated( const QString & );
void cboAcquisitionIntervalEdited();
void cboDistanceThresholdEdited();
private:
enum FixStatus //GPS status
{
Expand All @@ -84,6 +92,8 @@ class QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInformationWidg
void populateDevices();
void setStatusIndicator( FixStatus statusValue );
void showStatusBarMessage( const QString &msg );
void setAcquisitionInterval( int );
void setDistanceThreshold( int );
QgsGpsConnection *mNmea = nullptr;
QgsMapCanvas *mpCanvas = nullptr;
QgsGpsMarker *mpMapMarker = nullptr;
Expand All @@ -95,6 +105,7 @@ class QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInformationWidg
QList< QwtPolarMarker * > mMarkerList;
#endif
void createRubberBand();

QgsCoordinateReferenceSystem mWgs84CRS;
// not used QPointF gpsToPixelPosition( const QgsPoint& point );
QgsRubberBand *mpRubberBand = nullptr;
Expand All @@ -106,6 +117,14 @@ class QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInformationWidg
QFile *mLogFile = nullptr;
QTextStream mLogFileTextStream;
QColor mTrackColor;
QIntValidator *mAcquisitionIntValidator = nullptr;
QIntValidator *mDistanceThresholdValidator = nullptr;
QLineEdit *mAcIntervalEdit = nullptr, *mDistThresholdEdit = nullptr;
nmeaPOS mLastNmeaPosition;
std::unique_ptr<QTimer> mAcquisitionTimer;
bool mAcquisitionEnabled = true;
unsigned int mAcquisitionInterval = 0;
unsigned int mDistanceThreshold = 0;
};

#endif // QGSGPSINFORMATIONWIDGET_H

0 comments on commit 53dbca2

Please sign in to comment.