Skip to content

Commit

Permalink
Tracking tweaks (#3351)
Browse files Browse the repository at this point in the history
* Add also a tracking layer when a new project is created

* Show tracking elapsed time instead of time when tracking started + fix time formatting
  • Loading branch information
wonder-sk committed Apr 19, 2024
1 parent 3a80e93 commit 048a353
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 14 deletions.
17 changes: 17 additions & 0 deletions app/position/tracking/positiontrackingmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
PositionTrackingManager::PositionTrackingManager( QObject *parent )
: QObject( parent )
{
connect( &mElapsedTimeTextTimer, &QTimer::timeout, this, &PositionTrackingManager::elapsedTimeTextChanged );
}

void PositionTrackingManager::addPoint( const QgsPoint &position )
Expand Down Expand Up @@ -208,6 +209,8 @@ void PositionTrackingManager::setup()
{
emit trackedGeometryChanged( mTrackedGeometry );
}

mElapsedTimeTextTimer.start( 1000 );
}

AbstractTrackingBackend *PositionTrackingManager::constructTrackingBackend( QgsProject *project, PositionKit *positionKit )
Expand Down Expand Up @@ -348,6 +351,20 @@ QDateTime PositionTrackingManager::startTime() const
return mTrackingStartTime;
}

QString PositionTrackingManager::elapsedTimeText() const
{
if ( !mIsTrackingPosition )
return QString();

qint64 totalSecs = mTrackingStartTime.secsTo( QDateTime::currentDateTime() );
int hours = totalSecs / 3600;
totalSecs = totalSecs % 3600;
int minutes = totalSecs / 60;
int seconds = totalSecs % 60;

return QString( "%1:%2:%3" ).arg( hours, 2, 10, QChar( '0' ) ).arg( minutes, 2, 10, QChar( '0' ) ).arg( seconds, 2, 10, QChar( '0' ) );
}

bool PositionTrackingManager::isTrackingPosition() const
{
return mIsTrackingPosition;
Expand Down
10 changes: 10 additions & 0 deletions app/position/tracking/positiontrackingmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <QObject>
#include <qglobal.h>
#include <QQmlEngine>
#include <QTimer>

#include "abstracttrackingbackend.h"

Expand All @@ -33,6 +34,7 @@ class PositionTrackingManager : public QObject
Q_PROPERTY( QDateTime startTime READ startTime NOTIFY startTimeChanged )
Q_PROPERTY( QgsGeometry trackedGeometry READ trackedGeometry NOTIFY trackedGeometryChanged )
Q_PROPERTY( bool isTrackingPosition READ isTrackingPosition NOTIFY isTrackingPositionChanged )
Q_PROPERTY( QString elapsedTimeText READ elapsedTimeText NOTIFY elapsedTimeTextChanged )

// properties to be set from QML
Q_PROPERTY( QgsProject *qgsProject READ qgsProject WRITE setQgsProject NOTIFY qgsProjectChanged )
Expand Down Expand Up @@ -73,6 +75,9 @@ class PositionTrackingManager : public QObject

QDateTime startTime() const;

//! How long we have been tracking, formatted as a text (empty if not tracking)
QString elapsedTimeText() const;

bool isTrackingPosition() const;

public slots:
Expand All @@ -99,6 +104,8 @@ class PositionTrackingManager : public QObject

void abort();

void elapsedTimeTextChanged();

private:
void setLayerId( QString newLayerId );
void setup();
Expand All @@ -114,6 +121,9 @@ class PositionTrackingManager : public QObject
QDateTime mTrackingStartTime;
QgsFeature mTrackedFeature;
bool mIsTrackingPosition = false;

// timer to make sure we are periodically updating tracking elapsed time
QTimer mElapsedTimeTextTimer;
};

#endif // POSITIONTRACKINGMANAGER_H
82 changes: 78 additions & 4 deletions app/projectwizard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#include "qgsdatetimefieldformatter.h"
#include "qgsmarkersymbollayer.h"
#include "qgis.h"
#include "qgslinesymbol.h"
#include "qgssymbollayer.h"
#include "qgssymbollayerutils.h"
#include "qgssymbol.h"
#include "qgsmarkersymbol.h"
#include "qgssinglesymbolrenderer.h"
Expand Down Expand Up @@ -86,6 +88,72 @@ QgsVectorLayer *ProjectWizard::createGpkgLayer( QString const &projectDir, QList
return l;
}

static QgsVectorLayer *createTrackingLayer( const QString &trackingGpkgPath )
{
// based on the code in https://github.com/MerginMaps/qgis-plugin/blob/master/Mergin/utils.py
// (create_tracking_layer(), setup_tracking_layer(), set_tracking_layer_flags())

QgsFields fields;
fields.append( QgsField( "tracking_start_time", QVariant::DateTime ) );
fields.append( QgsField( "tracking_end_time", QVariant::DateTime ) );
fields.append( QgsField( "total_distance", QVariant::Double ) );
fields.append( QgsField( "tracked_by", QVariant::String ) );

QgsVectorFileWriter::SaveVectorOptions options;
options.driverName = "GPKG";
options.layerName = "tracking_layer";

QgsVectorFileWriter *writer = QgsVectorFileWriter::create(
trackingGpkgPath,
fields,
Qgis::WkbType::LineStringZM,
QgsCoordinateReferenceSystem( "EPSG:4326" ),
QgsCoordinateTransformContext(),
options );
delete writer;

QgsVectorLayer *layer = new QgsVectorLayer( trackingGpkgPath, "tracking_layer", "ogr" );

int idx = layer->fields().indexFromName( "fid" );
QgsEditorWidgetSetup cfg( "Hidden", QVariantMap() );
layer->setEditorWidgetSetup( idx, cfg );

idx = layer->fields().indexFromName( "tracking_start_time" );
QgsDefaultValue start_time_default;
start_time_default.setExpression( "@tracking_start_time" );
layer->setDefaultValueDefinition( idx, start_time_default );

idx = layer->fields().indexFromName( "tracking_end_time" );
QgsDefaultValue end_time_default;
end_time_default.setExpression( "@tracking_end_time" );
layer->setDefaultValueDefinition( idx, end_time_default );

idx = layer->fields().indexFromName( "total_distance" );
QgsDefaultValue distance_default;
distance_default.setExpression( "round($length, 2)" );
layer->setDefaultValueDefinition( idx, distance_default );

idx = layer->fields().indexFromName( "tracked_by" );
QgsDefaultValue user_default;
user_default.setExpression( "@mergin_username" );
layer->setDefaultValueDefinition( idx, user_default );

QVariantMap symbolProps;
symbolProps["capstyle"] = "square";
symbolProps["joinstyle"] = "bevel";
symbolProps["line_style"] = "solid";
symbolProps["line_width"] = "0.35";
symbolProps["line_width_unit"] = "MM";
symbolProps["line_color"] = QgsSymbolLayerUtils::encodeColor( QColor( "#FFA500" ) );

layer->setRenderer( new QgsSingleSymbolRenderer( QgsLineSymbol::createSimple( symbolProps ) ) );

layer->setReadOnly( false );
layer->setFlags( QgsMapLayer::Identifiable | QgsMapLayer::Searchable | QgsMapLayer::Removable );

return layer;
}

void ProjectWizard::createProject( QString const &projectName, FieldsModel *fieldsModel )
{
if ( !CoreUtils::isValidName( projectName ) )
Expand All @@ -95,9 +163,9 @@ void ProjectWizard::createProject( QString const &projectName, FieldsModel *fiel
}

QString projectDir = CoreUtils::createUniqueProjectDirectory( mDataDir, projectName );
QString projectFilepath( QString( "%1/%2.%3" ).arg( projectDir ).arg( projectName ).arg( "qgz" ) );
QString gpkgName( QStringLiteral( "data" ) );
QString projectGpkgPath( QString( "%1/%2.%3" ).arg( projectDir ).arg( gpkgName ).arg( "gpkg" ) );
QString projectFilepath( QString( "%1/%2.qgz" ).arg( projectDir ).arg( projectName ) );
QString projectGpkgPath( QString( "%1/data.gpkg" ).arg( projectDir ) );
QString trackingGpkgPath( QString( "%1/tracking_layer.gpkg" ).arg( projectDir ) );

QgsProject project;

Expand All @@ -115,8 +183,14 @@ void ProjectWizard::createProject( QString const &projectName, FieldsModel *fiel
metadata.setRights( QStringList() << QStringLiteral( "漏 OpenMapTiles 漏 OpenStreetMap contributors" ) );
bgLayer->setMetadata( metadata );
QgsVectorLayer *layer = createGpkgLayer( projectDir, fieldsModel->fields() );

QgsVectorLayer *trackingLayer = createTrackingLayer( trackingGpkgPath );
project.writeEntry( "Mergin", "PositionTracking/Enabled", true );
project.writeEntry( "Mergin", "PositionTracking/TrackingLayer", trackingLayer->id() );
project.writeEntry( "Mergin", "PositionTracking/UpdateFrequency", 0 ); // 0 means often (1 = normal, 2 = occasional)

QList<QgsMapLayer *> layers;
layers << layer << bgLayer;
layers << layer << trackingLayer << bgLayer;
project.addMapLayers( layers );

// Configurate mapSettings
Expand Down
2 changes: 1 addition & 1 deletion app/qml/dialogs/MMPositionTrackingDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ MMComponents.MMDrawerDialog {
MMComponents.MMText {
width: parent.width

text: qsTr("Started at")
text: qsTr("Tracking time")
horizontalAlignment: Text.AlignRight
font: __style.p6
color: __style.nightColor
Expand Down
5 changes: 1 addition & 4 deletions app/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -550,10 +550,7 @@ ApplicationWindow {
function getStartingTime() {
if ( map.isTrackingPosition )
{
let date = map.trackingManager?.startTime
if ( date ) {
return date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds()
}
return map.trackingManager?.elapsedTimeText
}
return qsTr( "not tracking" )
}
Expand Down
6 changes: 1 addition & 5 deletions app/qml/map/MMMapController.qml
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,7 @@ Item {

text: {
if (visible) {
// TODO make some merge with main.qml:trackingPrivate.getStartingTime()
let date = root.trackingManager?.startTime
if ( date ) {
return date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds()
}
return root.trackingManager?.elapsedTimeText
}
else
return ""
Expand Down

1 comment on commit 048a353

@inputapp-bot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS - version 24.04.600011 just submitted!

Please sign in to comment.