Skip to content

Commit

Permalink
Add track total distance calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 11, 2022
1 parent dc755b6 commit 32db68b
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
31 changes: 31 additions & 0 deletions src/app/gps/qgsappgpsdigitizing.cpp
Expand Up @@ -89,6 +89,11 @@ QgsAppGpsDigitizing::QgsAppGpsDigitizing( QgsAppGpsConnection *connection, QgsMa
{
QgsProject::instance()->gpsSettings()->setDestinationLayer( qobject_cast< QgsVectorLayer *> ( QgisApp::instance()->activeLayer() ) );
}

connect( QgsProject::instance(), &QgsProject::transformContextChanged, this, &QgsAppGpsDigitizing::updateDistanceArea );
connect( QgsProject::instance(), &QgsProject::ellipsoidChanged, this, &QgsAppGpsDigitizing::updateDistanceArea );

updateDistanceArea();
}

QgsAppGpsDigitizing::~QgsAppGpsDigitizing()
Expand All @@ -97,6 +102,21 @@ QgsAppGpsDigitizing::~QgsAppGpsDigitizing()
mRubberBand = nullptr;
}

double QgsAppGpsDigitizing::totalTrackLength() const
{
QVector<QgsPointXY> points;
QgsGeometry::convertPointList( mCaptureListWgs84, points );
return mDa.measureLine( points );
}

double QgsAppGpsDigitizing::trackDirectLength() const
{
if ( mCaptureListWgs84.empty() )
return 0;

return mDa.measureLine( { QgsPointXY( mCaptureListWgs84.constFirst() ), QgsPointXY( mCaptureListWgs84.constLast() )} );
}

void QgsAppGpsDigitizing::addVertex()
{
if ( !mRubberBand )
Expand Down Expand Up @@ -136,6 +156,8 @@ void QgsAppGpsDigitizing::addVertex()

if ( trackWasEmpty )
emit trackIsEmptyChanged( false );

emit trackChanged();
}

void QgsAppGpsDigitizing::resetTrack()
Expand All @@ -149,6 +171,7 @@ void QgsAppGpsDigitizing::resetTrack()

if ( !trackWasEmpty )
emit trackIsEmptyChanged( true );
emit trackChanged();
}

void QgsAppGpsDigitizing::createFeature()
Expand Down Expand Up @@ -356,6 +379,8 @@ void QgsAppGpsDigitizing::createFeature()
if ( mCaptureListWgs84.empty() )
emit trackIsEmptyChanged( true );

emit trackChanged();

break;
}

Expand Down Expand Up @@ -593,6 +618,12 @@ void QgsAppGpsDigitizing::stopLogging()
}
}

void QgsAppGpsDigitizing::updateDistanceArea()
{
mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
mDa.setSourceCrs( mWgs84CRS, QgsProject::instance()->transformContext() );
}

void QgsAppGpsDigitizing::createRubberBand()
{
delete mRubberBand;
Expand Down
23 changes: 23 additions & 0 deletions src/app/gps/qgsappgpsdigitizing.h
Expand Up @@ -50,6 +50,20 @@ class APP_EXPORT QgsAppGpsDigitizing: public QObject
QgsAppGpsDigitizing( QgsAppGpsConnection *connection, QgsMapCanvas *canvas, QObject *parent = nullptr );
~QgsAppGpsDigitizing() override;

/**
* Returns the total length of the current digitized track (in meters).
*
* The returned length is calculated using ellipsoidal calculations.
*/
double totalTrackLength() const;

/**
* Returns the direct length from the first vertex in the track to the last (in meters).
*
* The returned length is calculated using ellipsoidal calculations.
*/
double trackDirectLength() const;

public slots:
void addVertex();
void resetTrack();
Expand All @@ -64,6 +78,11 @@ class APP_EXPORT QgsAppGpsDigitizing: public QObject
*/
void trackIsEmptyChanged( bool isEmpty );

/**
* Emitted whenever the recorded track is changed.
*/
void trackChanged();

private slots:
void gpsSettingsChanged();
void updateTrackAppearance();
Expand All @@ -79,6 +98,8 @@ class APP_EXPORT QgsAppGpsDigitizing: public QObject
void startLogging();
void stopLogging();

void updateDistanceArea();

private:
void createRubberBand();
QVariant timestamp( QgsVectorLayer *vlayer, int idx );
Expand Down Expand Up @@ -119,6 +140,8 @@ class APP_EXPORT QgsAppGpsDigitizing: public QObject
std::unique_ptr< QFile > mLogFile;
QTextStream mLogFileTextStream;

QgsDistanceArea mDa;

friend class TestQgsGpsIntegration;
};

Expand Down
2 changes: 0 additions & 2 deletions src/app/layers/qgsapplayerhandling.cpp
Expand Up @@ -36,8 +36,6 @@
#include "qgslayertreenode.h"
#include "qgslayertree.h"
#include "qgslayertreeview.h"
#include "qgslayertreemodel.h"
#include "qgslayertreeutils.h"
#include "qgsgui.h"
#include "qgsmbtiles.h"
#include "qgsmessagelog.h"
Expand Down
60 changes: 60 additions & 0 deletions tests/src/app/testqgsgpsintegration.cpp
Expand Up @@ -26,6 +26,7 @@
#include "gps/qgsappgpssettingsmenu.h"
#include "options/qgsgpsoptions.h"
#include "qgsprojectgpssettings.h"
#include "qgsgpsconnection.h"
#include "nmeatime.h"

#include <QSignalSpy>
Expand All @@ -50,6 +51,7 @@ class TestQgsGpsIntegration : public QgsTest
void testTimestampWrite();
void testMultiPartLayers();
void testFollowActiveLayer();
void testTrackDistance();

private:
QDateTime _testWrite( QgsVectorLayer *vlayer, QgsAppGpsDigitizing &gpsDigitizing, const QString &fieldName, Qt::TimeSpec timeSpec, bool commit = false );
Expand Down Expand Up @@ -433,6 +435,64 @@ void TestQgsGpsIntegration::testFollowActiveLayer()
QCOMPARE( QgsProject::instance()->gpsSettings()->destinationLayer(), tempLayerLineString );
}

void TestQgsGpsIntegration::testTrackDistance()
{
QgsVectorLayer *lineString = new QgsVectorLayer( QStringLiteral( "Linestring?crs=epsg:4326&field=intf:int&field=stringf:string" ),
QStringLiteral( "vl" ),
QStringLiteral( "memory" ) );
QgsProject::instance()->addMapLayer( lineString );

QgsMapCanvas *canvas = mQgisApp->mapCanvas();
QgsAppGpsConnection connection( nullptr );

QgsAppGpsDigitizing gpsDigitizing( &connection, canvas );
QgsProject::instance()->gpsSettings()->setDestinationFollowsActiveLayer( true );
mQgisApp->setActiveLayer( lineString );
QCOMPARE( QgsProject::instance()->gpsSettings()->destinationLayer(), lineString );
lineString->startEditing();

QSignalSpy spy( &gpsDigitizing, &QgsAppGpsDigitizing::trackChanged );

QgsGpsInformation info;
info.latitude = 45;
info.longitude = 100;

gpsDigitizing.gpsStateChanged( info );
gpsDigitizing.addVertex();
QCOMPARE( spy.count(), 1 );

QCOMPARE( gpsDigitizing.totalTrackLength(), 0 );
QCOMPARE( gpsDigitizing.trackDirectLength(), 0 );

info.latitude = 46;
info.longitude = 100;

gpsDigitizing.gpsStateChanged( info );
gpsDigitizing.addVertex();
QCOMPARE( spy.count(), 2 );

QgsProject::instance()->setCrs( QgsCoordinateReferenceSystem( "EPSG:3857" ) );
QCOMPARE( QgsProject::instance()->ellipsoid(), QStringLiteral( "NONE" ) );
QGSCOMPARENEAR( gpsDigitizing.totalTrackLength(), 1, 0.01 );
QGSCOMPARENEAR( gpsDigitizing.trackDirectLength(), 1, 0.01 );
QgsProject::instance()->setEllipsoid( QStringLiteral( "EPSG:7030" ) );
QCOMPARE( QgsProject::instance()->ellipsoid(), QStringLiteral( "EPSG:7030" ) );
QGSCOMPARENEAR( gpsDigitizing.totalTrackLength(), 111141.548, 1 );
QGSCOMPARENEAR( gpsDigitizing.trackDirectLength(), 111141.548, 1 );

info.latitude = 46;
info.longitude = 101;

gpsDigitizing.gpsStateChanged( info );
gpsDigitizing.addVertex();
QCOMPARE( spy.count(), 3 );
QGSCOMPARENEAR( gpsDigitizing.totalTrackLength(), 188604.338, 1 );
QGSCOMPARENEAR( gpsDigitizing.trackDirectLength(), 135869.0912, 1 );

gpsDigitizing.resetTrack();
QCOMPARE( spy.count(), 4 );
}


QGSTEST_MAIN( TestQgsGpsIntegration )
#include "testqgsgpsintegration.moc"

0 comments on commit 32db68b

Please sign in to comment.