Skip to content

Commit

Permalink
Add API to allow storage of GPS component information in recorded
Browse files Browse the repository at this point in the history
track/point geometry m values
  • Loading branch information
nyalldawson committed Dec 8, 2022
1 parent 59332bb commit 2cecb3f
Show file tree
Hide file tree
Showing 7 changed files with 324 additions and 7 deletions.
7 changes: 7 additions & 0 deletions python/core/auto_generated/gps/qgsgpslogger.sip.in
Expand Up @@ -27,6 +27,8 @@ from incoming GPS location points.
%End
public:



QgsGpsLogger( QgsGpsConnection *connection, QObject *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsGpsLogger with the specified ``parent`` object.
Expand Down Expand Up @@ -122,6 +124,11 @@ handling.
double lastElevation() const;
%Docstring
Returns the last recorded elevation the device.
%End

double lastMValue() const;
%Docstring
Returns the last recorded value corresponding to the QgsGpsLogger.settingsGpsMValueComponent setting.
%End

void resetTrack();
Expand Down
4 changes: 2 additions & 2 deletions src/app/gps/qgsappgpslogging.cpp
Expand Up @@ -334,7 +334,7 @@ bool QgsAppGpsLogging::createOrUpdateLogDatabase()

const Qgis::VectorExportResult result = ogrMetadata->createEmptyLayer( mGpkgLogFile,
pointFields,
QgsWkbTypes::PointZ,
QgsGpsLogger::settingsGpsStoreAttributeInMValues.value() ? QgsWkbTypes::PointZM : QgsWkbTypes::PointZ,
QgsCoordinateReferenceSystem( "EPSG:4326" ),
false, unusedMap, error, &options );
if ( result != Qgis::VectorExportResult::Success )
Expand Down Expand Up @@ -374,7 +374,7 @@ bool QgsAppGpsLogging::createOrUpdateLogDatabase()

const Qgis::VectorExportResult result = ogrMetadata->createEmptyLayer( mGpkgLogFile,
tracksFields,
QgsWkbTypes::LineStringZ,
QgsGpsLogger::settingsGpsStoreAttributeInMValues.value() ? QgsWkbTypes::LineStringZM : QgsWkbTypes::LineStringZ,
QgsCoordinateReferenceSystem( "EPSG:4326" ),
false, unusedMap, error, &options );
if ( result != Qgis::VectorExportResult::Success )
Expand Down
58 changes: 56 additions & 2 deletions src/core/gps/qgsgpslogger.cpp
Expand Up @@ -110,6 +110,7 @@ QgsGeometry QgsGpsLogger::currentGeometry( QgsWkbTypes::Type type, QString &erro
}

const bool is3D = QgsWkbTypes::hasZ( type );
const bool isMeasure = QgsWkbTypes::hasM( type );
switch ( geometryType )
{
case QgsWkbTypes::PointGeometry:
Expand All @@ -122,6 +123,9 @@ QgsGeometry QgsGpsLogger::currentGeometry( QgsWkbTypes::Type type, QString &erro
else
g = QgsGeometry::fromPointXY( pointXYWgs84 );

if ( isMeasure )
g.get()->addMValue( lastMValue() );

if ( QgsWkbTypes::isMultiType( type ) )
g.convertToMultiType();

Expand All @@ -134,8 +138,10 @@ QgsGeometry QgsGpsLogger::currentGeometry( QgsWkbTypes::Type type, QString &erro
QgsGeometry g;

std::unique_ptr<QgsLineString> ringWgs84( new QgsLineString( captureListWgs84 ) );
if ( ! is3D )
if ( !is3D )
ringWgs84->dropZValue();
if ( !isMeasure )
ringWgs84->dropMValue();

if ( geometryType == QgsWkbTypes::LineGeometry )
{
Expand Down Expand Up @@ -174,6 +180,11 @@ double QgsGpsLogger::lastElevation() const
return mLastElevation;
}

double QgsGpsLogger::lastMValue() const
{
return mLastMValue;
}

void QgsGpsLogger::resetTrack()
{
mBlockGpsStateChanged++;
Expand Down Expand Up @@ -201,6 +212,9 @@ void QgsGpsLogger::updateGpsSettings()
mTimeStampSpec = QgsGpsConnection::settingsGpsTimeStampSpecification.value();
mTimeZone = QgsGpsConnection::settingsGpsTimeStampTimeZone.value();
mOffsetFromUtc = static_cast< int >( QgsGpsConnection::settingsGpsTimeStampOffsetFromUtc.value() );

mStoreAttributeInMValues = settingsGpsStoreAttributeInMValues.value();
mMValueComponent = settingsGpsMValueComponent.value();
}
else
{
Expand Down Expand Up @@ -328,6 +342,41 @@ void QgsGpsLogger::gpsStateChanged( const QgsGpsInformation &info )
{
mLastTime = info.utcDateTime;
}

switch ( mMValueComponent )
{
case Qgis::GpsInformationComponent::Altitude:
case Qgis::GpsInformationComponent::GroundSpeed:
case Qgis::GpsInformationComponent::Bearing:
case Qgis::GpsInformationComponent::Pdop:
case Qgis::GpsInformationComponent::Hdop:
case Qgis::GpsInformationComponent::Vdop:
case Qgis::GpsInformationComponent::HorizontalAccuracy:
case Qgis::GpsInformationComponent::VerticalAccuracy:
case Qgis::GpsInformationComponent::HvAccuracy:
case Qgis::GpsInformationComponent::SatellitesUsed:
case Qgis::GpsInformationComponent::GeoidalSeparation:
case Qgis::GpsInformationComponent::EllipsoidAltitude:
{
const QVariant value = info.componentValue( mMValueComponent );
mLastMValue = value.isValid() ? info.componentValue( mMValueComponent ).toDouble() : std::numeric_limits< double >::quiet_NaN();
break;
}

case Qgis::GpsInformationComponent::Timestamp:
mLastMValue = info.utcDateTime.toMSecsSinceEpoch();
break;

case Qgis::GpsInformationComponent::Location:
case Qgis::GpsInformationComponent::TotalTrackLength:
case Qgis::GpsInformationComponent::TrackDistanceFromStart:
case Qgis::GpsInformationComponent::TrackStartTime:
case Qgis::GpsInformationComponent::TrackEndTime:
case Qgis::GpsInformationComponent::TrackDistanceSinceLastPoint:
case Qgis::GpsInformationComponent::TrackTimeSinceLastPoint:
// not possible
break;
}
}
else
{
Expand Down Expand Up @@ -368,7 +417,12 @@ void QgsGpsLogger::gpsStateChanged( const QgsGpsInformation &info )

void QgsGpsLogger::addTrackVertex()
{
const QgsPoint pointWgs84 = QgsPoint( mLastGpsPositionWgs84.x(), mLastGpsPositionWgs84.y(), mLastElevation );
QgsPoint pointWgs84 = QgsPoint( mLastGpsPositionWgs84.x(), mLastGpsPositionWgs84.y(), mLastElevation );

if ( mStoreAttributeInMValues )
{
pointWgs84.addMValue( mLastMValue );
}

const bool trackWasEmpty = mCaptureListWgs84.empty();
mCaptureListWgs84.push_back( pointWgs84 );
Expand Down
16 changes: 16 additions & 0 deletions src/core/gps/qgsgpslogger.h
Expand Up @@ -23,6 +23,8 @@
#include "qgsdistancearea.h"
#include "qgscoordinatetransformcontext.h"
#include "qgswkbtypes.h"
#include "qgssettingsentryimpl.h"
#include "qgssettingsentryenumflag.h"

#include <QObject>
#include <QPointer>
Expand Down Expand Up @@ -50,6 +52,12 @@ class CORE_EXPORT QgsGpsLogger : public QObject

public:

//! Settings entry for whether storing GPS attributes as geometry M values should be enabled
static const inline QgsSettingsEntryBool settingsGpsStoreAttributeInMValues = QgsSettingsEntryBool( QStringLiteral( "store-attribute-in-m-values" ), QgsSettings::Prefix::GPS, false, QStringLiteral( "Whether GPS attributes should be stored in geometry m values" ) ) SIP_SKIP;

//! Settings entry dictating which GPS attribute should be stored in geometry M values
static const inline QgsSettingsEntryEnumFlag<Qgis::GpsInformationComponent> settingsGpsMValueComponent = QgsSettingsEntryEnumFlag<Qgis::GpsInformationComponent>( QStringLiteral( "m-value-attribute" ), QgsSettings::Prefix::GPS, Qgis::GpsInformationComponent::Timestamp, QStringLiteral( "Which GPS attribute should be stored in geometry m values" ) ) SIP_SKIP;

/**
* Constructor for QgsGpsLogger with the specified \a parent object.
*
Expand Down Expand Up @@ -147,6 +155,11 @@ class CORE_EXPORT QgsGpsLogger : public QObject
*/
double lastElevation() const;

/**
* Returns the last recorded value corresponding to the QgsGpsLogger::settingsGpsMValueComponent setting.
*/
double lastMValue() const;

/**
* Resets the current track, discarding all recorded points.
*/
Expand Down Expand Up @@ -272,6 +285,9 @@ class CORE_EXPORT QgsGpsLogger : public QObject
int mOffsetFromUtc = 0;

bool mAutomaticallyAddTrackVertices = true;
bool mStoreAttributeInMValues = false;
Qgis::GpsInformationComponent mMValueComponent = Qgis::GpsInformationComponent::Timestamp;
double mLastMValue = std::numeric_limits<double>::quiet_NaN();

friend class TestQgsGpsIntegration;

Expand Down
20 changes: 19 additions & 1 deletion src/core/gps/qgsvectorlayergpslogger.cpp
Expand Up @@ -107,6 +107,15 @@ void QgsVectorLayerGpsLogger::endCurrentTrack()
QgsDebugMsg( QStringLiteral( "Error transforming GPS track" ) );
}

if ( geometry.constGet()->is3D() && !QgsWkbTypes::hasZ( mTracksLayer->wkbType() ) )
{
geometry.get()->dropZValue();
}
if ( geometry.constGet()->isMeasure() && !QgsWkbTypes::hasM( mTracksLayer->wkbType() ) )
{
geometry.get()->dropMValue();
}

QgsAttributeMap attributes;

for ( auto it = mDestinationFields.constBegin(); it != mDestinationFields.constEnd(); ++it )
Expand Down Expand Up @@ -186,7 +195,16 @@ void QgsVectorLayerGpsLogger::gpsStateChanged( const QgsGpsInformation &info )
{
// record point
const QgsPointXY newPosition = lastPosition();
QgsGeometry geometry( new QgsPoint( newPosition.x(), newPosition.y(), lastElevation() ) );
QgsGeometry geometry( new QgsPoint( newPosition.x(), newPosition.y(), lastElevation(), lastMValue() ) );

if ( geometry.constGet()->is3D() && !QgsWkbTypes::hasZ( mPointsLayer->wkbType() ) )
{
geometry.get()->dropZValue();
}
if ( geometry.constGet()->isMeasure() && !QgsWkbTypes::hasM( mPointsLayer->wkbType() ) )
{
geometry.get()->dropMValue();
}

try
{
Expand Down
4 changes: 4 additions & 0 deletions src/core/settings/qgssettingsregistrycore.cpp
Expand Up @@ -29,6 +29,7 @@
#include "qgsogrdbconnection.h"
#include "qgsfontmanager.h"
#include "qgsgpsconnection.h"
#include "qgsgpslogger.h"

QgsSettingsRegistryCore::QgsSettingsRegistryCore()
: QgsSettingsRegistry()
Expand Down Expand Up @@ -129,6 +130,9 @@ QgsSettingsRegistryCore::QgsSettingsRegistryCore()
addSettingsEntry( &QgsGpsConnection::settingsGpsTimeStampSpecification );
addSettingsEntry( &QgsGpsConnection::settingsGpsTimeStampTimeZone );
addSettingsEntry( &QgsGpsConnection::settingsGpsTimeStampOffsetFromUtc );

addSettingsEntry( &QgsGpsLogger::settingsGpsStoreAttributeInMValues );
addSettingsEntry( &QgsGpsLogger::settingsGpsMValueComponent );
}

QgsSettingsRegistryCore::~QgsSettingsRegistryCore()
Expand Down

0 comments on commit 2cecb3f

Please sign in to comment.