Skip to content

Commit

Permalink
[FEATURE][gps] Allow showing a bearing line from the GPS location
Browse files Browse the repository at this point in the history
pointed in the GPS's direction

Allows users to view a "current path" directional line as they
navigate using a GPS
  • Loading branch information
nyalldawson committed Dec 10, 2019
1 parent 9356cd8 commit e262056
Show file tree
Hide file tree
Showing 6 changed files with 424 additions and 319 deletions.
2 changes: 2 additions & 0 deletions src/app/gps/qgsgpsbearingitem.cpp
Expand Up @@ -32,6 +32,8 @@ QgsGpsBearingItem::QgsGpsBearingItem( QgsMapCanvas *mapCanvas )
mSymbol->setColor( QColor( 255, 0, 0 ) );
mWgs84CRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:4326" ) );

setZValue( 199 );

connect( mMapCanvas, &QgsMapCanvas::rotationChanged, this, &QgsGpsBearingItem::updateLine );
connect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, &QgsGpsBearingItem::updateLine );
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/gps/qgsgpsbearingitem.h
Expand Up @@ -27,7 +27,7 @@ class QgsLineSymbol;
* \ingroup app
* A canvas item for showing the bearing of the GPS device
*/
class QgsGpsBearingItem : public QObject, QgsMapCanvasLineSymbolItem
class QgsGpsBearingItem : public QObject, public QgsMapCanvasLineSymbolItem
{
Q_OBJECT

Expand Down
80 changes: 71 additions & 9 deletions src/app/gps/qgsgpsinformationwidget.cpp
Expand Up @@ -41,6 +41,8 @@
#include "qgsmapcanvas.h"
#include "qgsmessagebar.h"
#include "qgsbearingutils.h"
#include "qgsgpsbearingitem.h"
#include "qgssymbollayerutils.h"

// QWT Charting widget

Expand Down Expand Up @@ -93,8 +95,6 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *mapCanvas, QWidg
mLastNmeaPosition.lat = nmea_degree2radian( 0.0 );
mLastNmeaPosition.lon = nmea_degree2radian( 0.0 );

mMapMarker = nullptr;
mRubberBand = nullptr;
populateDevices();
QWidget *mpHistogramWidget = mStackedWidget->widget( 1 );
#ifndef WITH_QWTPOLAR
Expand Down Expand Up @@ -191,8 +191,31 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *mapCanvas, QWidg

mBtnTrackColor->setAllowOpacity( true );
mBtnTrackColor->setColorDialogTitle( tr( "Track Color" ) );
// Restore state

mBearingLineStyleButton->setSymbolType( QgsSymbol::Line );

QgsSettings mySettings;

QDomDocument doc;
QDomElement elem;
QString symbolXml = mySettings.value( QStringLiteral( "gps/bearingLineSymbol" ) ).toString();
if ( !symbolXml.isEmpty() )
{
doc.setContent( symbolXml );
elem = doc.documentElement();
std::unique_ptr< QgsLineSymbol > bearingSymbol( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( elem, QgsReadWriteContext() ) );
if ( bearingSymbol )
mBearingLineStyleButton->setSymbol( bearingSymbol.release() );
}

connect( mBearingLineStyleButton, &QgsSymbolButton::changed, this, [ = ]
{
if ( mMapBearingItem )
mMapBearingItem->setSymbol( std::unique_ptr< QgsSymbol >( mBearingLineStyleButton->clonedSymbol< QgsLineSymbol >() ) );
} );

// Restore state

mGroupShowMarker->setChecked( mySettings.value( QStringLiteral( "gps/showMarker" ), "true" ).toBool() );
mSliderMarkerSize->setValue( mySettings.value( QStringLiteral( "gps/markerSize" ), "12" ).toInt() );
mSpinTrackWidth->setValue( mySettings.value( QStringLiteral( "gps/trackWidth" ), "2" ).toInt() );
Expand Down Expand Up @@ -254,6 +277,7 @@ QgsGpsInformationWidget::QgsGpsInformationWidget( QgsMapCanvas *mapCanvas, QWidg
radRecenterWhenNeeded->setChecked( true );
}
mRotateMapCheckBox->setChecked( mySettings.value( QStringLiteral( "gps/rotateMap" ), false ).toBool() );
mShowBearingLineCheck->setChecked( mySettings.value( QStringLiteral( "gps/showBearingLine" ), false ).toBool() );

mWgs84CRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:4326" ) );

Expand Down Expand Up @@ -363,6 +387,7 @@ QgsGpsInformationWidget::~QgsGpsInformationWidget()
}

delete mMapMarker;
delete mMapBearingItem;
delete mRubberBand;

#ifdef WITH_QWTPOLAR
Expand Down Expand Up @@ -420,6 +445,12 @@ QgsGpsInformationWidget::~QgsGpsInformationWidget()
mySettings.setValue( QStringLiteral( "gps/panMode" ), "none" );
}
mySettings.setValue( QStringLiteral( "gps/rotateMap" ), mRotateMapCheckBox->isChecked() );
mySettings.setValue( QStringLiteral( "gps/showBearingLine" ), mShowBearingLineCheck->isChecked() );

QDomDocument doc;
QDomElement elem = QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "Symbol" ), mBearingLineStyleButton->symbol(), doc, QgsReadWriteContext() );
doc.appendChild( elem );
mySettings.setValue( QStringLiteral( "gps/bearingLineSymbol" ), doc.toString() );
}

void QgsGpsInformationWidget::mSpinTrackWidth_valueChanged( int value )
Expand Down Expand Up @@ -603,6 +634,11 @@ void QgsGpsInformationWidget::disconnectGps()
delete mMapMarker;
mMapMarker = nullptr;
}
if ( mMapBearingItem )
{
delete mMapBearingItem;
mMapBearingItem = nullptr;
}
mGPSPlainTextEdit->appendPlainText( tr( "Disconnected…" ) );
mConnectButton->setChecked( false );
mConnectButton->setText( tr( "&Connect" ) );
Expand Down Expand Up @@ -866,17 +902,44 @@ void QgsGpsInformationWidget::displayGPSInformation( const QgsGpsInformation &in
}
} // mLastGpsPosition != myNewCenter

if ( mRotateMapCheckBox->isChecked() && !std::isnan( info.direction ) )
if ( !std::isnan( info.direction ) )
{
double trueNorth = 0;
try
{
const double trueNorth = QgsBearingUtils::bearingTrueNorth( mMapCanvas->mapSettings().destinationCrs(), QgsProject::instance()->transformContext(), mMapCanvas->mapSettings().visibleExtent().center() );
mMapCanvas->setRotation( trueNorth - info.direction );
trueNorth = QgsBearingUtils::bearingTrueNorth( mMapCanvas->mapSettings().destinationCrs(), QgsProject::instance()->transformContext(), mMapCanvas->mapSettings().visibleExtent().center() );
}
catch ( QgsException & )
{
mMapCanvas->setRotation( - info.direction );

}

if ( mRotateMapCheckBox->isChecked() )
{
mMapCanvas->setRotation( trueNorth - info.direction );
}

if ( mShowBearingLineCheck )
{
if ( ! mMapBearingItem )
{
mMapBearingItem = new QgsGpsBearingItem( mMapCanvas );
mMapBearingItem->setSymbol( std::unique_ptr< QgsSymbol >( mBearingLineStyleButton->clonedSymbol< QgsLineSymbol >() ) );
}

mMapBearingItem->setGpsPosition( myNewCenter );
mMapBearingItem->setGpsBearing( info.direction - trueNorth );
}
else if ( mMapBearingItem )
{
delete mMapBearingItem;
mMapBearingItem = nullptr;
}
}
else if ( mMapBearingItem )
{
delete mMapBearingItem;
mMapBearingItem = nullptr;
}

// new marker position after recentering
Expand Down Expand Up @@ -1382,9 +1445,8 @@ void QgsGpsInformationWidget::cboDistanceThresholdEdited()
setDistanceThreshold( mCboDistanceThreshold->currentText().toUInt() );
}

void QgsGpsInformationWidget::timestampFormatChanged( int index )
void QgsGpsInformationWidget::timestampFormatChanged( int )
{
Q_UNUSED( index );
QgsSettings().setValue( QStringLiteral( "gps/timestampFormat" ), mCboTimestampFormat->currentData( ).toInt() );
const bool enabled { static_cast<Qt::TimeSpec>( mCboTimestampFormat->currentData( ).toInt() ) == Qt::TimeSpec::TimeZone };
mCboTimeZones->setEnabled( enabled );
Expand Down
3 changes: 3 additions & 0 deletions src/app/gps/qgsgpsinformationwidget.h
Expand Up @@ -37,6 +37,7 @@ class QgsGpsTrackerThread;
struct QgsGpsInformation;
class QgsMapCanvas;
class QgsFeature;
class QgsGpsBearingItem;

class QFile;
class QColor;
Expand Down Expand Up @@ -102,6 +103,8 @@ class APP_EXPORT QgsGpsInformationWidget: public QWidget, private Ui::QgsGpsInfo
QgsGpsConnection *mNmea = nullptr;
QgsMapCanvas *mMapCanvas = nullptr;
QgsGpsMarker *mMapMarker = nullptr;
QgsGpsBearingItem *mMapBearingItem = nullptr;

QwtPlot *mPlot = nullptr;
QwtPlotCurve *mCurve = nullptr;
#ifdef WITH_QWTPOLAR
Expand Down
1 change: 1 addition & 0 deletions src/app/gps/qgsgpsmarker.cpp
Expand Up @@ -30,6 +30,7 @@ QgsGpsMarker::QgsGpsMarker( QgsMapCanvas *mapCanvas )
mSize = 16;
mWgs84CRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:4326" ) );
mSvg.load( QStringLiteral( ":/images/north_arrows/gpsarrow2.svg" ) );
setZValue( 200 );
}

void QgsGpsMarker::setSize( int size )
Expand Down

0 comments on commit e262056

Please sign in to comment.