|
37 | 37 | #include "qgswkbptr.h"
|
38 | 38 | #include "qgssettings.h"
|
39 | 39 | #include "qgsstatusbar.h"
|
| 40 | +#include "gmath.h" |
40 | 41 |
|
41 | 42 | // QWT Charting widget
|
42 | 43 |
|
@@ -82,6 +83,7 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *thepCanvas, QWid
|
82 | 83 | mpLastLayer = nullptr;
|
83 | 84 |
|
84 | 85 | mLastGpsPosition = QgsPointXY( 0.0, 0.0 );
|
| 86 | + mLastNmeaPosition.lat = nmea_degree2radian( 0.0 ); mLastNmeaPosition.lon = nmea_degree2radian( 0.0 ); |
85 | 87 |
|
86 | 88 | mpMapMarker = nullptr;
|
87 | 89 | mpRubberBand = nullptr;
|
@@ -255,6 +257,44 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *thepCanvas, QWid
|
255 | 257 |
|
256 | 258 | mStackedWidget->setCurrentIndex( 3 ); // force to Options
|
257 | 259 | 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 | + |
258 | 298 | }
|
259 | 299 |
|
260 | 300 | QgsGpsInformationWidget::~QgsGpsInformationWidget()
|
@@ -535,6 +575,7 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
|
535 | 575 | }
|
536 | 576 | else // unknown status (not likely)
|
537 | 577 | {
|
| 578 | + |
538 | 579 | }
|
539 | 580 |
|
540 | 581 | // set visual status indicator -- do only on change of state
|
@@ -639,15 +680,28 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
|
639 | 680 | }
|
640 | 681 |
|
641 | 682 | QgsPointXY myNewCenter;
|
| 683 | + nmeaPOS newNmeaPosition; |
642 | 684 | if ( validFlag )
|
643 | 685 | {
|
644 | 686 | myNewCenter = QgsPointXY( info.longitude, info.latitude );
|
| 687 | + newNmeaPosition.lat = nmea_degree2radian( info.latitude ); newNmeaPosition.lon = nmea_degree2radian( info.longitude ); |
645 | 688 | }
|
646 | 689 | else
|
647 | 690 | {
|
648 | 691 | myNewCenter = mLastGpsPosition;
|
| 692 | + newNmeaPosition = mLastNmeaPosition; |
649 | 693 | }
|
| 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; |
650 | 698 |
|
| 699 | + } |
| 700 | + if ( validFlag && mAcquisitionEnabled ) |
| 701 | + { |
| 702 | + // position updated by valid data, reset timer |
| 703 | + switchAcquisition(); |
| 704 | + } |
651 | 705 | if ( mStackedWidget->currentIndex() == 0 ) //position
|
652 | 706 | {
|
653 | 707 | mTxtLatitude->setText( QString::number( info.latitude, 'f', 8 ) );
|
@@ -679,7 +733,7 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
|
679 | 733 | if ( mLastGpsPosition != myNewCenter )
|
680 | 734 | {
|
681 | 735 | mLastGpsPosition = myNewCenter;
|
682 |
| - |
| 736 | + mLastNmeaPosition = newNmeaPosition; |
683 | 737 | // Pan based on user specified behavior
|
684 | 738 | if ( radRecenterMap->isChecked() || radRecenterWhenNeeded->isChecked() )
|
685 | 739 | {
|
@@ -1137,3 +1191,64 @@ void QgsGpsInformationWidget::showStatusBarMessage( const QString &msg )
|
1137 | 1191 | {
|
1138 | 1192 | QgisApp::instance()->statusBarIface()->showMessage( msg );
|
1139 | 1193 | }
|
| 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 | +} |
0 commit comments