Skip to content

Commit

Permalink
GPS tracking improvements (apply #4071)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenmizuno authored and jef-n committed Aug 12, 2011
1 parent f71ecb9 commit ee21580
Show file tree
Hide file tree
Showing 16 changed files with 1,673 additions and 568 deletions.
826 changes: 615 additions & 211 deletions src/app/gps/qgsgpsinformationwidget.cpp

Large diffs are not rendered by default.

31 changes: 26 additions & 5 deletions src/app/gps/qgsgpsinformationwidget.h
Expand Up @@ -25,11 +25,15 @@
#include <qwt_plot_curve.h>
#include <qwt_polar_plot.h>
#include <qwt_polar_marker.h>

class QextSerialPort;
class QgsGPSConnection;
class QgsGPSTrackerThread;
struct QgsGPSInformation;
class QPointF;

class QgsLegend;
class QFile;
class QColor;

/**A dock widget that displays information from a GPS device and
* allows the user to capture features using gps readings to
Expand All @@ -44,8 +48,11 @@ class QgsGPSInformationWidget: public QWidget, private Ui::QgsGPSInformationWidg
private slots:
void on_mConnectButton_toggled( bool theFlag );
void displayGPSInformation( const QgsGPSInformation& info );
void setTrackColour( );
void on_mBtnTrackColour_clicked( );
void logNmeaSentence( const QString& nmeaString ); // added to handle 'raw' data
void updateCloseFeatureButton( QgsMapLayer * lyr );
void layerEditStateChanged();
// void setTrackColor( ); // no longer used
void on_mBtnTrackColor_clicked( );
void on_mSpinTrackWidth_valueChanged( int theValue );
void on_mBtnPosition_clicked( );
void on_mBtnSignal_clicked( );
Expand All @@ -56,17 +63,24 @@ class QgsGPSInformationWidget: public QWidget, private Ui::QgsGPSInformationWidg
void on_mBtnAddVertex_clicked( );
void on_mBtnCloseFeature_clicked( );
void on_mBtnResetFeature_clicked( );
void on_mCbxAutoAddVertices_toggled( bool theFlag );
// not needed void on_mCbxAutoAddVertices_toggled( bool theFlag );
void on_mBtnLogFile_clicked();

void connected( QgsGPSConnection * );
void timedout();

private:
enum FixStatus //GPS status
{
NoData, NoFix, Fix2D, Fix3D
};
void addVertex( );
void connectGps();
void connectGpsSlot( );
void disconnectGps();
void populateDevices();
void setStatusIndicator( const FixStatus statusValue );
void showStatusBarMessage( const QString& msg );
QgsGPSConnection* mNmea;
QgsMapCanvas * mpCanvas;
QgsGpsMarker * mpMapMarker;
Expand All @@ -76,10 +90,17 @@ class QgsGPSInformationWidget: public QWidget, private Ui::QgsGPSInformationWidg
QList< QwtPolarMarker * > mMarkerList;
void createRubberBand( );
QgsCoordinateReferenceSystem mWgs84CRS;
QPointF gpsToPixelPosition( const QgsPoint& point );
// not used QPointF gpsToPixelPosition( const QgsPoint& point );
QgsRubberBand * mpRubberBand;
QgsPoint mLastGpsPosition;
QList<QgsPoint> mCaptureList;
FixStatus mLastFixStatus;
QString mDateTimeFormat; // user specified format string in registry (no UI presented)
QgsLegend * mpLegend;
QgsVectorLayer * mpLastLayer;
QFile * mLogFile;
QTextStream mLogFileTextStream;
QColor mTrackColor;
};

#endif // QGSGPSINFORMATIONWIDGET_H
18 changes: 13 additions & 5 deletions src/app/gps/qgsgpsmarker.cpp
Expand Up @@ -14,7 +14,6 @@
***************************************************************************/

#include <QPainter>
#include <QSvgRenderer>

#include "qgsgpsmarker.h"
#include "qgscoordinatetransform.h"
Expand All @@ -27,6 +26,11 @@ QgsGpsMarker::QgsGpsMarker( QgsMapCanvas* mapCanvas )
{
mSize = 16;
mWgs84CRS.createFromOgcWmsCrs( "EPSG:4326" );
mSvg.load( QString( ":/images/north_arrows/gpsarrow2.svg" ) );
if ( ! mSvg.isValid() )
{
qDebug( "GPS marker not found!" );
}
}

void QgsGpsMarker::setSize( int theSize )
Expand Down Expand Up @@ -60,14 +64,18 @@ void QgsGpsMarker::setCenter( const QgsPoint& point )

void QgsGpsMarker::paint( QPainter* p )
{
QSvgRenderer mySVG;
if ( !mySVG.load( QString( ":/images/north_arrows/gpsarrow2.svg" ) ) )
if ( ! mSvg.isValid() )
{
qDebug( "GPS marker not found!" );
return;
}

// this needs to be done when the canvas is repainted to make for smoother map rendering
// if not done the map could be panned, but the cursor position won't be updated until the next valid GPS fix is received
QPointF pt = toCanvasCoordinates( mCenter );
setPos( pt );

float myHalfSize = mSize / 2.0;
mySVG.render( p, QRectF( 0 - myHalfSize , 0 - myHalfSize, mSize, mSize ) );
mSvg.render( p, QRectF( 0 - myHalfSize , 0 - myHalfSize, mSize, mSize ) );
}


Expand Down
2 changes: 2 additions & 0 deletions src/app/gps/qgsgpsmarker.h
Expand Up @@ -19,6 +19,7 @@
#include "qgsmapcanvasitem.h"
#include "qgscoordinatereferencesystem.h"
#include "qgspoint.h"
#include <QSvgRenderer>

class QPainter;

Expand Down Expand Up @@ -50,6 +51,7 @@ class QgsGpsMarker : public QgsMapCanvasItem

private:
QgsCoordinateReferenceSystem mWgs84CRS;
QSvgRenderer mSvg;

};

Expand Down
53 changes: 14 additions & 39 deletions src/app/qgisapp.cpp
Expand Up @@ -452,6 +452,18 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
addDockWidget( Qt::LeftDockWidgetArea, mBrowserWidget );
mBrowserWidget->hide();

// create the GPS tool on starting QGIS - this is like the Browser
mpGpsWidget = new QgsGPSInformationWidget( mMapCanvas );
//create the dock widget
mpGpsDock = new QDockWidget( tr( "GPS Information" ), this );
mpGpsDock->setObjectName( "GPSInformation" );
mpGpsDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
addDockWidget( Qt::LeftDockWidgetArea, mpGpsDock );
// add to the Panel submenu
// now add our widget to the dock - ownership of the widget is passed to the dock
mpGpsDock->setWidget( mpGpsWidget );
mpGpsDock->hide();

mInternalClipboard = new QgsClipboard; // create clipboard
mQgisInterface = new QgisAppInterface( this ); // create the interfce

Expand Down Expand Up @@ -630,6 +642,8 @@ QgisApp::~QgisApp()

delete mPythonUtils;

delete mpGpsWidget;

deletePrintComposers();
removeAnnotationItems();

Expand Down Expand Up @@ -729,11 +743,6 @@ void QgisApp::readSettings()
{
showTileScale();
}
// Restore state of GPS Tracker
if ( settings.value( "/gps/widgetEnabled", false ).toBool() )
{
showGpsTool();
}
}


Expand Down Expand Up @@ -830,7 +839,6 @@ void QgisApp::createActions()
connect( mActionSetLayerCRS, SIGNAL( triggered() ), this, SLOT( setLayerCRS() ) );
connect( mActionSetProjectCRSFromLayer, SIGNAL( triggered() ), this, SLOT( setProjectCRSFromLayer() ) );
connect( mActionTileScale, SIGNAL( triggered() ), this, SLOT( showTileScale() ) );
connect( mActionGpsTool, SIGNAL( triggered() ), this, SLOT( showGpsTool() ) );
connect( mActionLayerProperties, SIGNAL( triggered() ), this, SLOT( layerProperties() ) );
connect( mActionLayerSubsetString, SIGNAL( triggered() ), this, SLOT( layerSubsetString() ) );
connect( mActionAddToOverview, SIGNAL( triggered() ), this, SLOT( isInOverview() ) );
Expand Down Expand Up @@ -1871,17 +1879,6 @@ void QgisApp::saveWindowState()
settings.setValue( "/UI/tileScaleEnabled", false );
}

// Persist state of GPS Tracker
if ( mpGpsWidget )
{
settings.setValue( "/gps/widgetEnabled", true );
delete mpGpsWidget;
}
else
{
settings.setValue( "/gps/widgetEnabled", false );
}

QgsPluginRegistry::instance()->unloadAll();
}

Expand Down Expand Up @@ -4518,28 +4515,6 @@ void QgisApp::setProjectCRSFromLayer()
mMapCanvas->refresh();
}

void QgisApp::showGpsTool()
{
if ( !mpGpsWidget )
{
mpGpsWidget = new QgsGPSInformationWidget( mMapCanvas );
//create the dock widget
mpGpsDock = new QDockWidget( tr( "GPS Information" ), this );
mpGpsDock->setObjectName( "GPSInformation" );
mpGpsDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea );
addDockWidget( Qt::LeftDockWidgetArea, mpGpsDock );
// add to the Panel submenu
mPanelMenu->addAction( mpGpsDock->toggleViewAction() );
// now add our widget to the dock - ownership of the widget is passed to the dock
mpGpsDock->setWidget( mpGpsWidget );
mpGpsWidget->show();
}
else
{
mpGpsDock->setVisible( mpGpsDock->isHidden() );
}
}

void QgisApp::showTileScale()
{
if ( !mpTileScaleWidget )
Expand Down
3 changes: 0 additions & 3 deletions src/app/qgisapp.h
Expand Up @@ -265,7 +265,6 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QAction *actionSetLayerCRS() { return mActionSetLayerCRS; }
QAction *actionSetProjectCRSFromLayer() { return mActionSetProjectCRSFromLayer; }
QAction *actionTileScale() { return mActionTileScale; }
QAction *actionGpsTool() { return mActionGpsTool; }
QAction *actionLayerProperties() { return mActionLayerProperties; }
QAction *actionLayerSubsetString() { return mActionLayerSubsetString; }
QAction *actionAddToOverview() { return mActionAddToOverview; }
Expand Down Expand Up @@ -483,8 +482,6 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
void setLayerCRS();
//! Assign layer CRS to project
void setProjectCRSFromLayer();
//! Show GPS tool
void showGpsTool();
//! Show tile scale slider
void showTileScale();
//! zoom to extent of layer
Expand Down
2 changes: 1 addition & 1 deletion src/core/gps/nmeatime.h
Expand Up @@ -32,7 +32,7 @@ extern "C"
int hour; /**< Hours since midnight - [0,23] */
int min; /**< Minutes after the hour - [0,59] */
int sec; /**< Seconds after the minute - [0,59] */
int hsec; /**< Hundredth part of second - [0,99] */
int msec; /**< Thousandths part of second - [0,999] */

} nmeaTIME;

Expand Down
15 changes: 13 additions & 2 deletions src/core/gps/parse.c
Expand Up @@ -75,11 +75,22 @@ int _nmea_parse_time( const char *buff, int buff_sz, nmeaTIME *res )
) );
break;
case sizeof( "hhmmss.s" ) - 1:
success = ( 4 == nmea_scanf( buff, buff_sz,
"%2d%2d%2d.%d", &( res->hour ), &( res->min ), &( res->sec ), &( res->msec )
) );
res->msec = res->msec * 100; // tenths sec * 100 = thousandths
break;
case sizeof( "hhmmss.ss" ) - 1:
success = ( 4 == nmea_scanf( buff, buff_sz,
"%2d%2d%2d.%d", &( res->hour ), &( res->min ), &( res->sec ), &( res->msec )
) );
res->msec = res->msec * 10; // hundredths sec * 10 = thousandths
break;
case sizeof( "hhmmss.sss" ) - 1:
success = ( 4 == nmea_scanf( buff, buff_sz,
"%2d%2d%2d.%d", &( res->hour ), &( res->min ), &( res->sec ), &( res->hsec )
"%2d%2d%2d.%d", &( res->hour ), &( res->min ), &( res->sec ), &( res->msec )
) );
// already thousandths
break;
default:
nmea_error( "Parse of time error (format error)!" );
Expand Down Expand Up @@ -380,7 +391,7 @@ void nmea_GPGGA2info( nmeaGPGGA *pack, nmeaINFO *info )
info->utc.hour = pack->utc.hour;
info->utc.min = pack->utc.min;
info->utc.sec = pack->utc.sec;
info->utc.hsec = pack->utc.hsec;
info->utc.msec = pack->utc.msec;
info->sig = pack->sig;
info->HDOP = pack->HDOP;
info->elv = pack->elv;
Expand Down
9 changes: 7 additions & 2 deletions src/core/gps/qextserialport/qextserialenumerator.h
Expand Up @@ -13,9 +13,14 @@

#ifdef Q_OS_WIN
#ifdef __MINGW32__
#ifdef _WIN32_WINNT
#if _WIN32_WINNT < 0x0500
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#else
#define _WIN32_WINNT 0x0500
#define _WIN32_WINDOWS 0x0500
#define WINVER 0x0500
#endif
#endif
#include <windows.h>
#include <setupapi.h>
Expand Down
7 changes: 7 additions & 0 deletions src/core/gps/qgsgpsconnection.cpp
Expand Up @@ -94,6 +94,13 @@ void QgsGPSConnection::clearLastGPSInformation()
mLastGPSInformation.satellitesInView.clear();
mLastGPSInformation.speed = 0;
mLastGPSInformation.vdop = 0;
mLastGPSInformation.quality = -1; // valid values: 0,1,2, maybe others
mLastGPSInformation.satellitesUsed = 0;
mLastGPSInformation.fixMode = ' ';
mLastGPSInformation.fixType = 0; // valid values: 1,2,3
mLastGPSInformation.status = ' '; // valid values: A,V
mLastGPSInformation.utcDateTime.setDate( QDate() );
mLastGPSInformation.satPrn.clear();
mLastGPSInformation.utcDateTime.setTime( QTime() );
mLastGPSInformation.satInfoComplete = false;
}
9 changes: 9 additions & 0 deletions src/core/gps/qgsgpsconnection.h
Expand Up @@ -20,6 +20,7 @@

#include <QDateTime>
#include <QObject>
#include <QString>

class QIODevice;

Expand All @@ -44,6 +45,13 @@ struct CORE_EXPORT QgsGPSInformation
double hdop;
double vdop;
QDateTime utcDateTime;
QChar fixMode;
int fixType;
int quality; // from GPGGA
int satellitesUsed; // from GPGGA
QChar status; // from GPRMC A,V
QList<int>satPrn; // list of SVs in use; needed for QgsSatelliteInfo.inUse and other uses
bool satInfoComplete; // based on GPGSV sentences - to be used to determine when to graph signal and satellite position
};

/**Abstract base class for connection to a GPS device*/
Expand Down Expand Up @@ -81,6 +89,7 @@ class CORE_EXPORT QgsGPSConnection : public QObject

signals:
void stateChanged( const QgsGPSInformation& info );
void nmeaSentenceReceived( const QString& substring ); // added to capture 'raw' data

protected:
/**Data source (e.g. serial device, socket, file,...)*/
Expand Down
4 changes: 1 addition & 3 deletions src/core/gps/qgsgpsdetector.cpp
Expand Up @@ -89,7 +89,7 @@ QList< QPair<QString, QString> > QgsGPSDetector::availablePorts()
QgsGPSDetector::QgsGPSDetector( QString portName )
{
mConn = 0;
mBaudList << BAUD4800 << BAUD9600 << BAUD38400;
mBaudList << BAUD4800 << BAUD9600 << BAUD38400 << BAUD57600; //add 57600 for SXBlueII GPS unit

if ( portName.isEmpty() )
{
Expand All @@ -102,8 +102,6 @@ QgsGPSDetector::QgsGPSDetector( QString portName )

mPortIndex = 0;
mBaudIndex = -1;

advance();
}

QgsGPSDetector::~QgsGPSDetector()
Expand Down

0 comments on commit ee21580

Please sign in to comment.