Skip to content
Permalink
Browse files

Add option to format time in mesh layer (#9452)

[feature] [mesh] #20731 add option to format time in mesh layer

There is new settings dialog that can be opened by button next to time slider. User can set reference time and time format (e.g. 2019-03-21 22:01:11).
  • Loading branch information
PeterPetrik committed Mar 15, 2019
1 parent 95930ed commit 37faa0d883ae2bba3f795a7cc66898cc24b76c7a
@@ -139,6 +139,31 @@ Returns renderer settings
void setRendererSettings( const QgsMeshRendererSettings &settings );
%Docstring
Sets new renderer settings
%End

QgsMeshTimeSettings timeSettings() const;
%Docstring
Returns time format settings

.. versionadded:: 3.8
%End

void setTimeSettings( const QgsMeshTimeSettings &settings );
%Docstring
Sets time format settings

.. versionadded:: 3.8
%End

QString formatTime( double hours );
%Docstring
Returns (date) time in hours formatted to human readable form

:param hours: time in double in hours

:return: formatted time string

.. versionadded:: 3.8
%End

QgsMeshDatasetValue datasetValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point ) const;
@@ -176,6 +201,13 @@ Emitted when active scalar dataset is changed
Emitted when active vector dataset is changed

.. versionadded:: 3.4
%End

void timeSettingsChanged( );
%Docstring
Emitted when time format is changed

.. versionadded:: 3.8
%End

private: // Private methods
@@ -0,0 +1,102 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/mesh/qgsmeshtimesettings.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsMeshTimeSettings
{
%Docstring

Represents a mesh time settings for mesh datasets

.. versionadded:: 3.8
%End

%TypeHeaderCode
#include "qgsmeshtimesettings.h"
%End
public:
QgsMeshTimeSettings();
%Docstring
Default constructor for relative time formate and 0 offset
%End
QgsMeshTimeSettings( double relativeTimeOffsetHours, const QString &relativeTimeFormat );
%Docstring
Constructs relative time format settings with defined offset in hours
%End
QgsMeshTimeSettings( const QDateTime &absoluteTimeReferenceTime, const QString &absoluteTimeFormat );
%Docstring
Constructs absolute time format settings with defined reference time
%End

QDomElement writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const;
%Docstring
Writes configuration to a new DOM element
%End
void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
%Docstring
Reads configuration from the given DOM element
%End

bool useAbsoluteTime() const;
%Docstring
Returns whether to use absolute time format
%End
void setUseAbsoluteTime( bool useAbsoluteTime );
%Docstring
Sets use absolute time flag
%End

double relativeTimeOffsetHours() const;
%Docstring
Returns number of offset hours for relative time formatting
%End
void setRelativeTimeOffsetHours( double relativeTimeOffsetHours );
%Docstring
Sets number of offset hours for relative time formatting
%End

QString relativeTimeFormat() const;
%Docstring
Returns format used for relative time
%End
void setRelativeTimeFormat( const QString &relativeTimeFormat );
%Docstring
Sets format used for relative time
%End

QDateTime absoluteTimeReferenceTime() const;
%Docstring
Returns reference time used for absolute time format
%End
void setAbsoluteTimeReferenceTime( const QDateTime &absoluteTimeReferenceTime );
%Docstring
Sets reference time used for absolute time format
%End

QString absoluteTimeFormat() const;
%Docstring
Returns format used for absolute time
%End
void setAbsoluteTimeFormat( const QString &absoluteTimeFormat );
%Docstring
Sets format used for absolute time
%End

};


/************************************************************************
* This file has been generated automatically from *
* *
* src/core/mesh/qgsmeshtimesettings.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -241,6 +241,7 @@
%Include auto_generated/mesh/qgsmeshlayerinterpolator.sip
%Include auto_generated/mesh/qgsmeshrenderersettings.sip
%Include auto_generated/mesh/qgsmeshspatialindex.sip
%Include auto_generated/mesh/qgsmeshtimesettings.sip
%Include auto_generated/scalebar/qgsdoubleboxscalebarrenderer.sip
%Include auto_generated/scalebar/qgsnumericscalebarrenderer.sip
%Include auto_generated/scalebar/qgsscalebarsettings.sip
@@ -244,6 +244,7 @@ SET(QGIS_APP_SRCS
mesh/qgsmeshrendereractivedatasetwidget.cpp
mesh/qgsmeshdatasetgrouptreeview.cpp
mesh/qgsmeshcalculatordialog.cpp
mesh/qgsmeshtimeformatdialog.cpp
)

SET (QGIS_APP_MOC_HDRS
@@ -470,6 +471,7 @@ SET (QGIS_APP_MOC_HDRS
mesh/qgsmeshrendereractivedatasetwidget.h
mesh/qgsmeshdatasetgrouptreeview.h
mesh/qgsmeshcalculatordialog.h
mesh/qgsmeshtimeformatdialog.h
)


@@ -26,7 +26,6 @@
#include "qgsmaplayerproxymodel.h"
#include "qgswkbtypes.h"
#include "qgsfeatureiterator.h"
#include "qgsmeshrendereractivedatasetwidget.h"

#include "cpl_string.h"
#include "gdal.h"
@@ -527,8 +526,7 @@ void QgsMeshCalculatorDialog::repopulateTimeCombos()
{
const QgsMeshDatasetMetadata meta = dp->datasetMetadata( QgsMeshDatasetIndex( groupIndex, datasetIndex ) );
const double time = meta.time();

const QString timestr = QgsMeshRendererActiveDatasetWidget::formatTime( time ); // the format is "HH:mm:ss"
const QString timestr = layer->formatTime( time );

times[timestr] = time;
}
@@ -21,6 +21,7 @@
#include "qgsmeshlayer.h"
#include "qgsmessagelog.h"
#include "qgsmeshrenderersettings.h"
#include "qgsmeshtimeformatdialog.h"

QgsMeshRendererActiveDatasetWidget::QgsMeshRendererActiveDatasetWidget( QWidget *parent )
: QWidget( parent )
@@ -30,6 +31,7 @@ QgsMeshRendererActiveDatasetWidget::QgsMeshRendererActiveDatasetWidget( QWidget
connect( mTimeComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, &QgsMeshRendererActiveDatasetWidget::onActiveTimeChanged );
connect( mDatasetSlider, &QSlider::valueChanged, mTimeComboBox, &QComboBox::setCurrentIndex );

connect( mTimeFormatButton, &QToolButton::clicked, this, &QgsMeshRendererActiveDatasetWidget::onTimeSettingsClicked );
connect( mFirstDatasetButton, &QToolButton::clicked, this, &QgsMeshRendererActiveDatasetWidget::onFirstTimeClicked );
connect( mPreviousDatasetButton, &QToolButton::clicked, this, &QgsMeshRendererActiveDatasetWidget::onPreviousTimeClicked );
connect( mNextDatasetButton, &QToolButton::clicked, this, &QgsMeshRendererActiveDatasetWidget::onNextTimeClicked );
@@ -45,6 +47,12 @@ void QgsMeshRendererActiveDatasetWidget::setLayer( QgsMeshLayer *layer )
{
mMeshLayer = layer;
mDatasetGroupTreeView->setLayer( layer );
setTimeRange();

if ( layer )
{
connect( mMeshLayer, &QgsMeshLayer::timeSettingsChanged, this, &QgsMeshRendererActiveDatasetWidget::setTimeRange );
}
}

int QgsMeshRendererActiveDatasetWidget::activeScalarDatasetGroup() const
@@ -102,7 +110,7 @@ void QgsMeshRendererActiveDatasetWidget::setTimeRange()
QgsMeshDatasetIndex index( groupWithMaximumDatasets, i );
QgsMeshDatasetMetadata meta = mMeshLayer->dataProvider()->datasetMetadata( index );
double time = meta.time();
mTimeComboBox->addItem( formatTime( time ), time );
mTimeComboBox->addItem( mMeshLayer->formatTime( time ), time );
}
}
mTimeComboBox->blockSignals( false );
@@ -111,6 +119,7 @@ void QgsMeshRendererActiveDatasetWidget::setTimeRange()
bool isTimeVarying = datasetCount > 1;
mTimeComboBox->setEnabled( isTimeVarying );
mDatasetSlider->setEnabled( isTimeVarying );
mTimeFormatButton->setEnabled( isTimeVarying );
mFirstDatasetButton->setEnabled( isTimeVarying );
mPreviousDatasetButton->setEnabled( isTimeVarying );
mNextDatasetButton->setEnabled( isTimeVarying );
@@ -123,7 +132,6 @@ void QgsMeshRendererActiveDatasetWidget::onActiveScalarGroupChanged( int groupIn
return;

mActiveScalarDatasetGroup = groupIndex;

// keep the same timestep if possible
onActiveTimeChanged( mTimeComboBox->currentIndex() );
emit activeScalarGroupChanged( mActiveScalarDatasetGroup );
@@ -176,6 +184,15 @@ void QgsMeshRendererActiveDatasetWidget::onActiveTimeChanged( int value )
}
}

void QgsMeshRendererActiveDatasetWidget::onTimeSettingsClicked()
{
if ( !mMeshLayer )
return;
QgsMeshTimeFormatDialog dlg( mMeshLayer );
dlg.setModal( true );
dlg.exec();
}

void QgsMeshRendererActiveDatasetWidget::onFirstTimeClicked()
{
mTimeComboBox->setCurrentIndex( 0 );
@@ -249,21 +266,6 @@ void QgsMeshRendererActiveDatasetWidget::updateMetadata()
mActiveDatasetMetadata->setText( msg );
}

QString QgsMeshRendererActiveDatasetWidget::formatTime( double hours )
{
// time should be in hours
int seconds = static_cast<int>( qgsRound( hours * 3600.0, 0 ) );
int days = static_cast<int>( floor( hours / 24.0 ) );
QTime t = QTime( 0, 0 ).addSecs( seconds );
if ( days > 0 )
{
return QStringLiteral( "%1 d %2" ).arg( days ).arg( t.toString() ); // the format is "d HH:mm:ss
}
else
{
return t.toString(); // the format is "HH:mm:ss"
}
}

QString QgsMeshRendererActiveDatasetWidget::metadata( QgsMeshDatasetIndex datasetIndex )
{
@@ -276,9 +278,11 @@ QString QgsMeshRendererActiveDatasetWidget::metadata( QgsMeshDatasetIndex datase
.arg( tr( "Is valid" ) )
.arg( meta.isValid() ? tr( "Yes" ) : tr( "No" ) );

msg += QStringLiteral( "<tr><td>%1</td><td>%2</td></tr>" )
const double time = meta.time();
msg += QStringLiteral( "<tr><td>%1</td><td>%2 (%3)</td></tr>" )
.arg( tr( "Time" ) )
.arg( meta.time() );
.arg( mMeshLayer->formatTime( time ) )
.arg( time );

const QgsMeshDatasetGroupMetadata gmeta = mMeshLayer->dataProvider()->datasetGroupMetadata( datasetIndex );
msg += QStringLiteral( "<tr><td>%1</td><td>%2</td></tr>" )
@@ -61,13 +61,6 @@ class APP_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui
//! Synchronizes widgets state with associated mesh layer
void syncToLayer();

/**
* Formats time to human readable string
* \param hours time in double in hours
* \returns formatted time string
*/
static QString formatTime( double hours );

signals:

//! Emitted when the current scalar group gets changed
@@ -83,6 +76,7 @@ class APP_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui
void onActiveScalarGroupChanged( int groupIndex );
void onActiveVectorGroupChanged( int groupIndex );
void onActiveTimeChanged( int value );
void onTimeSettingsClicked();
void onFirstTimeClicked();
void onPreviousTimeClicked();
void onNextTimeClicked();
@@ -91,8 +85,9 @@ class APP_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui
QString metadata( QgsMeshDatasetIndex datasetIndex );

private:
//! Loop through all dataset groups and find the maximum number of datasets
//! Loops through all dataset groups and finds the maximum number of datasets
void setTimeRange();

void updateMetadata();

QgsMeshLayer *mMeshLayer = nullptr; // not owned

0 comments on commit 37faa0d

Please sign in to comment.
You can’t perform that action at this time.