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).
This commit is contained in:
Peter Petrik 2019-03-15 08:42:28 +01:00 committed by GitHub
parent 95930ed68c
commit 37faa0d883
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1029 additions and 61 deletions

View File

@ -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

View File

@ -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 *
************************************************************************/

View File

@ -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

View File

@ -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
)

View File

@ -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;
}

View File

@ -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>" )

View File

@ -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

View File

@ -0,0 +1,94 @@
/***************************************************************************
qgsmeshtimeformatdialog.cpp
---------------------------
begin : March 2019
copyright : (C) 2019 by Peter Petrik
email : zilolv at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsmeshtimeformatdialog.h"
#include "qgsgui.h"
#include "qgsmeshtimesettings.h"
QgsMeshTimeFormatDialog::QgsMeshTimeFormatDialog( QgsMeshLayer *meshLayer, QWidget *parent, Qt::WindowFlags f )
: QDialog( parent, f ),
mLayer( meshLayer )
{
setupUi( this );
QgsGui::enableAutoGeometryRestore( this );
if ( !meshLayer )
return;
loadSettings();
connect( mUseTimeComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, &QgsMeshTimeFormatDialog::saveSettings );
connect( mReferenceDateTimeEdit, &QDateTimeEdit::timeChanged, this, &QgsMeshTimeFormatDialog::saveSettings );
connect( mAbsoluteTimeFormatComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, &QgsMeshTimeFormatDialog::saveSettings ); connect( mUseTimeComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, &QgsMeshTimeFormatDialog::saveSettings );
connect( mRelativeTimeFormatComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, &QgsMeshTimeFormatDialog::saveSettings );
connect( mOffsetHoursSpinBox, qgis::overload<double>::of( &QDoubleSpinBox::valueChanged ), this, &QgsMeshTimeFormatDialog::saveSettings );
}
void QgsMeshTimeFormatDialog::loadSettings()
{
const QgsMeshTimeSettings settings = mLayer->timeSettings();
enableGroups( settings.useAbsoluteTime() ) ;
if ( settings.useAbsoluteTime() )
{
mUseTimeComboBox->setCurrentIndex( 0 );
}
else
{
mUseTimeComboBox->setCurrentIndex( 1 );
}
mReferenceDateTimeEdit->setDateTime( settings.absoluteTimeReferenceTime() );
mReferenceDateTimeEdit->setDisplayFormat( settings.absoluteTimeFormat() );
int index = mAbsoluteTimeFormatComboBox->findText( settings.absoluteTimeFormat() );
if ( index < 0 )
{
index = mAbsoluteTimeFormatComboBox->count();
mAbsoluteTimeFormatComboBox->addItem( settings.absoluteTimeFormat() );
}
mAbsoluteTimeFormatComboBox->setCurrentIndex( index );
index = mRelativeTimeFormatComboBox->findText( settings.relativeTimeFormat() );
if ( index < 0 )
{
index = mRelativeTimeFormatComboBox->count();
mRelativeTimeFormatComboBox->addItem( settings.relativeTimeFormat() );
}
mRelativeTimeFormatComboBox->setCurrentIndex( index );
mOffsetHoursSpinBox->setValue( settings.relativeTimeOffsetHours() );
}
void QgsMeshTimeFormatDialog::saveSettings()
{
QgsMeshTimeSettings settings;
settings.setUseAbsoluteTime( mUseTimeComboBox->currentIndex() == 0 );
settings.setAbsoluteTimeReferenceTime( mReferenceDateTimeEdit->dateTime() );
settings.setAbsoluteTimeFormat( mAbsoluteTimeFormatComboBox->currentText() );
settings.setRelativeTimeOffsetHours( mOffsetHoursSpinBox->value() );
settings.setRelativeTimeFormat( mRelativeTimeFormatComboBox->currentText() );
enableGroups( settings.useAbsoluteTime() ) ;
mLayer->setTimeSettings( settings );
}
void QgsMeshTimeFormatDialog::enableGroups( bool useAbsoluteTime )
{
mAbsoluteTimeGroupBox->setEnabled( useAbsoluteTime );
mRelativeTimeGroupBox->setEnabled( ! useAbsoluteTime );
}
QgsMeshTimeFormatDialog::~QgsMeshTimeFormatDialog() = default;

View File

@ -0,0 +1,51 @@
/***************************************************************************
qgsmeshtimeformatdialog.h
-------------------------
begin : March 2019
copyright : (C) 2019 by Peter Petrik
email : zilolv at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSMESHTIMEFORMATDIALOG_H
#define QGSMESHTIMEFORMATDIALOG_H
#include "ui_qgsmeshtimeformatdialog.h"
#include "qgsmeshcalculator.h"
#include "qgshelp.h"
#include "qgis_app.h"
//! A dialog to enter a mesh calculation expression
class APP_EXPORT QgsMeshTimeFormatDialog: public QDialog, private Ui::QgsMeshTimeFormatDialog
{
Q_OBJECT
public:
/**
* Constructor for raster calculator dialog
* \param meshLayer main mesh layer, will be used for default extent and projection
* \param parent widget
* \param f window flags
*/
QgsMeshTimeFormatDialog( QgsMeshLayer *meshLayer = nullptr, QWidget *parent = nullptr, Qt::WindowFlags f = nullptr );
~QgsMeshTimeFormatDialog();
private slots:
private:
void loadSettings();
void saveSettings();
void enableGroups( bool useAbsoluteTime );
QgsMeshLayer *mLayer;
};
#endif // QGSMESHTIMEFORMATDIALOG_H

View File

@ -484,6 +484,7 @@ SET(QGIS_CORE_SRCS
mesh/qgsmeshspatialindex.cpp
mesh/qgsmeshvectorrenderer.cpp
mesh/qgstriangularmesh.cpp
mesh/qgsmeshtimesettings.cpp
geometry/qgsabstractgeometry.cpp
geometry/qgsbox3d.cpp
@ -1117,6 +1118,7 @@ SET(QGIS_CORE_HDRS
mesh/qgsmeshspatialindex.h
mesh/qgsmeshvectorrenderer.h
mesh/qgstriangularmesh.h
mesh/qgsmeshtimesettings.h
scalebar/qgsdoubleboxscalebarrenderer.h
scalebar/qgsnumericscalebarrenderer.h

View File

@ -27,13 +27,13 @@
#include "qgsmeshlayer.h"
#include "qgsmeshlayerrenderer.h"
#include "qgsmeshlayerutils.h"
#include "qgsmeshtimesettings.h"
#include "qgspainting.h"
#include "qgsproviderregistry.h"
#include "qgsreadwritecontext.h"
#include "qgsstyle.h"
#include "qgstriangularmesh.h"
QgsMeshLayer::QgsMeshLayer( const QString &meshLayerPath,
const QString &baseName,
const QString &providerKey,
@ -144,6 +144,22 @@ void QgsMeshLayer::setRendererSettings( const QgsMeshRendererSettings &settings
triggerRepaint();
}
QgsMeshTimeSettings QgsMeshLayer::timeSettings() const
{
return mTimeSettings;
}
void QgsMeshLayer::setTimeSettings( const QgsMeshTimeSettings &settings )
{
mTimeSettings = settings;
emit timeSettingsChanged();
}
QString QgsMeshLayer::formatTime( double hours )
{
return QgsMeshLayerUtils::formatTime( hours, mTimeSettings );
}
QgsMeshDatasetValue QgsMeshLayer::datasetValue( const QgsMeshDatasetIndex &index, const QgsPointXY &point ) const
{
QgsMeshDatasetValue value;
@ -281,6 +297,10 @@ bool QgsMeshLayer::readSymbology( const QDomNode &node, QString &errorMessage,
if ( !elemRendererSettings.isNull() )
mRendererSettings.readXml( elemRendererSettings );
QDomElement elemTimeSettings = elem.firstChildElement( "mesh-time-settings" );
if ( !elemTimeSettings.isNull() )
mTimeSettings.readXml( elemTimeSettings, context );
// get and set the blend mode if it exists
QDomNode blendModeNode = node.namedItem( QStringLiteral( "blendMode" ) );
if ( !blendModeNode.isNull() )
@ -305,6 +325,9 @@ bool QgsMeshLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &e
QDomElement elemRendererSettings = mRendererSettings.writeXml( doc );
elem.appendChild( elemRendererSettings );
QDomElement elemTimeSettings = mTimeSettings.writeXml( doc, context );
elem.appendChild( elemTimeSettings );
// add blend mode node
QDomElement blendModeElement = doc.createElement( QStringLiteral( "blendMode" ) );
QDomText blendModeText = doc.createTextNode( QString::number( QgsPainting::getBlendModeEnum( blendMode() ) ) );

View File

@ -24,6 +24,7 @@
#include "qgsmaplayer.h"
#include "qgsmeshdataprovider.h"
#include "qgsmeshrenderersettings.h"
#include "qgsmeshtimesettings.h"
class QgsMapLayerRenderer;
struct QgsMeshLayerRendererCache;
@ -178,6 +179,28 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
//! Sets new renderer settings
void setRendererSettings( const QgsMeshRendererSettings &settings );
/**
* Returns time format settings
*
* \since QGIS 3.8
*/
QgsMeshTimeSettings timeSettings() const;
/**
* Sets time format settings
*
* \since QGIS 3.8
*/
void setTimeSettings( const QgsMeshTimeSettings &settings );
/**
* Returns (date) time in hours formatted to human readable form
* \param hours time in double in hours
* \returns formatted time string
* \since QGIS 3.8
*/
QString formatTime( double hours );
/**
* Interpolates the value on the given point from given dataset.
*
@ -211,6 +234,13 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
*/
void activeVectorDatasetChanged( const QgsMeshDatasetIndex &index );
/**
* Emitted when time format is changed
*
* \since QGIS 3.8
*/
void timeSettingsChanged( );
private: // Private methods
/**
@ -252,6 +282,9 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
//! Renderer configuration
QgsMeshRendererSettings mRendererSettings;
//! Time format configuration
QgsMeshTimeSettings mTimeSettings;
};
#endif //QGSMESHLAYER_H

View File

@ -16,8 +16,11 @@
***************************************************************************/
#include "qgsmeshlayerutils.h"
#include "qgsmeshtimesettings.h"
#include <limits>
#include <QTime>
#include <QDateTime>
///@cond PRIVATE
@ -127,4 +130,93 @@ QgsRectangle QgsMeshLayerUtils::triangleBoundingBox( const QgsPointXY &p1, const
return bbox;
}
QString QgsMeshLayerUtils::formatTime( double hours, const QgsMeshTimeSettings &settings )
{
QString ret;
if ( settings.useAbsoluteTime() )
{
QString format( settings.absoluteTimeFormat() );
QDateTime dateTime( settings.absoluteTimeReferenceTime() );
int seconds = static_cast<int>( hours * 3600.0 );
dateTime = dateTime.addSecs( seconds );
ret = dateTime.toString( format );
if ( ret.isEmpty() ) // error
ret = dateTime.toString();
}
else
{
QString format( settings.relativeTimeFormat() );
format = format.trimmed();
hours = hours + settings.relativeTimeOffsetHours();
int totalHours = static_cast<int>( hours );
if ( format == QStringLiteral( "hh:mm:ss.zzz" ) )
{
int ms = static_cast<int>( hours * 3600.0 * 1000 );
int seconds = ms / 1000;
int z = ms % 1000;
int m = seconds / 60;
int s = seconds % 60;
int h = m / 60;
m = m % 60;
ret = QStringLiteral( "%1:%2:%3.%4" ).
arg( h, 2, 10, QLatin1Char( '0' ) ).
arg( m, 2, 10, QLatin1Char( '0' ) ).
arg( s, 2, 10, QLatin1Char( '0' ) ).
arg( z, 3, 10, QLatin1Char( '0' ) );
}
else if ( format == QStringLiteral( "hh:mm:ss" ) )
{
int seconds = static_cast<int>( hours * 3600.0 );
int m = seconds / 60;
int s = seconds % 60;
int h = m / 60;
m = m % 60;
ret = QStringLiteral( "%1:%2:%3" ).
arg( h, 2, 10, QLatin1Char( '0' ) ).
arg( m, 2, 10, QLatin1Char( '0' ) ).
arg( s, 2, 10, QLatin1Char( '0' ) );
}
else if ( format == QStringLiteral( "d hh:mm:ss" ) )
{
int seconds = static_cast<int>( hours * 3600.0 );
int m = seconds / 60;
int s = seconds % 60;
int h = m / 60;
m = m % 60;
int d = totalHours / 24;
h = totalHours % 24;
ret = QStringLiteral( "%1 d %2:%3:%4" ).
arg( d ).
arg( h, 2, 10, QLatin1Char( '0' ) ).
arg( m, 2, 10, QLatin1Char( '0' ) ).
arg( s, 2, 10, QLatin1Char( '0' ) );
}
else if ( format == QStringLiteral( "d hh" ) )
{
int d = totalHours / 24;
int h = totalHours % 24;
ret = QStringLiteral( "%1 d %2" ).
arg( d ).
arg( h );
}
else if ( format == QStringLiteral( "d" ) )
{
int d = totalHours / 24;
ret = QStringLiteral( "%1" ).arg( d );
}
else if ( format == QStringLiteral( "ss" ) )
{
int seconds = static_cast<int>( hours * 3600.0 );
ret = QStringLiteral( "%1" ).arg( seconds );
}
else // "hh"
{
ret = QStringLiteral( "%1" ).arg( hours );
}
}
return ret;
}
///@endcond

View File

@ -30,6 +30,8 @@
///@cond PRIVATE
class QgsMeshTimeSettings;
/**
* \ingroup core
* Misc utility functions used for mesh layer support
@ -101,6 +103,11 @@ class CORE_EXPORT QgsMeshLayerUtils
* \returns bounding box of the triangle
*/
static QgsRectangle triangleBoundingBox( const QgsPointXY &p1, const QgsPointXY &p2, const QgsPointXY &p3 );
/**
* Formats hours in human readable string based on settings
*/
static QString formatTime( double hours, const QgsMeshTimeSettings &settings );
};
///@endcond

View File

@ -0,0 +1,105 @@
/***************************************************************************
qgsmeshtimesettings.cpp
-- ---------------------
begin : March 2019
copyright : (C) 2019 by Peter Petrik
email : zilolv at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsmeshtimesettings.h"
QgsMeshTimeSettings::QgsMeshTimeSettings() = default;
QgsMeshTimeSettings::QgsMeshTimeSettings( double relativeTimeOffsetHours, const QString &relativeTimeFormat )
: mUseAbsoluteTime( false )
, mRelativeTimeOffsetHours( relativeTimeOffsetHours )
, mRelativeTimeFormat( relativeTimeFormat )
{}
QgsMeshTimeSettings::QgsMeshTimeSettings( const QDateTime &absoluteTimeReferenceTime, const QString &absoluteTimeFormat )
: mUseAbsoluteTime( true )
, mAbsoluteTimeReferenceTime( absoluteTimeReferenceTime )
, mAbsoluteTimeFormat( absoluteTimeFormat )
{}
QDomElement QgsMeshTimeSettings::writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const
{
Q_UNUSED( context );
QDomElement elem = doc.createElement( QStringLiteral( "mesh-time-settings" ) );
elem.setAttribute( QStringLiteral( "use-absolute-time" ), mUseAbsoluteTime ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
elem.setAttribute( QStringLiteral( "relative-time-offset-hours" ), mRelativeTimeOffsetHours );
elem.setAttribute( QStringLiteral( "relative-time-format" ), mRelativeTimeFormat );
elem.setAttribute( QStringLiteral( "absolute-time-reference-time" ), mAbsoluteTimeReferenceTime.toString() );
elem.setAttribute( QStringLiteral( "absolute-time-format" ), mAbsoluteTimeFormat );
return elem;
}
void QgsMeshTimeSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
{
Q_UNUSED( context );
mUseAbsoluteTime = elem.attribute( QStringLiteral( "use-absolute-time" ) ).toInt(); //bool
mRelativeTimeOffsetHours = elem.attribute( QStringLiteral( "relative-time-offset-hours" ) ).toDouble();
mRelativeTimeFormat = elem.attribute( QStringLiteral( "relative-time-format" ) );
mAbsoluteTimeReferenceTime = QDateTime::fromString( elem.attribute( QStringLiteral( "absolute-time-reference-time" ) ) );
mAbsoluteTimeFormat = elem.attribute( QStringLiteral( "absolute-time-format" ) );
}
bool QgsMeshTimeSettings::useAbsoluteTime() const
{
return mUseAbsoluteTime;
}
void QgsMeshTimeSettings::setUseAbsoluteTime( bool useAbsoluteTime )
{
mUseAbsoluteTime = useAbsoluteTime;
}
double QgsMeshTimeSettings::relativeTimeOffsetHours() const
{
return mRelativeTimeOffsetHours;
}
void QgsMeshTimeSettings::setRelativeTimeOffsetHours( double relativeTimeOffsetHours )
{
mRelativeTimeOffsetHours = relativeTimeOffsetHours;
}
QString QgsMeshTimeSettings::relativeTimeFormat() const
{
return mRelativeTimeFormat;
}
void QgsMeshTimeSettings::setRelativeTimeFormat( const QString &relativeTimeFormat )
{
mRelativeTimeFormat = relativeTimeFormat;
}
QDateTime QgsMeshTimeSettings::absoluteTimeReferenceTime() const
{
return mAbsoluteTimeReferenceTime;
}
void QgsMeshTimeSettings::setAbsoluteTimeReferenceTime( const QDateTime &absoluteTimeReferenceTime )
{
mAbsoluteTimeReferenceTime = absoluteTimeReferenceTime;
}
QString QgsMeshTimeSettings::absoluteTimeFormat() const
{
return mAbsoluteTimeFormat;
}
void QgsMeshTimeSettings::setAbsoluteTimeFormat( const QString &absoluteTimeFormat )
{
mAbsoluteTimeFormat = absoluteTimeFormat;
}

View File

@ -0,0 +1,87 @@
/***************************************************************************
qgsmeshtimesettings.h
---------------------
begin : March 2019
copyright : (C) 2019 by Peter Petrik
email : zilolv at gmail dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSMESHTIMESETTINGS_H
#define QGSMESHTIMESETTINGS_H
#include <QDateTime>
#include <QDomDocument>
#include "qgis_core.h"
#include "qgis.h"
#include "qgsreadwritecontext.h"
/**
* \ingroup core
*
* Represents a mesh time settings for mesh datasets
*
* \since QGIS 3.8
*/
class CORE_EXPORT QgsMeshTimeSettings
{
public:
//! Default constructor for relative time formate and 0 offset
QgsMeshTimeSettings();
//! Constructs relative time format settings with defined offset in hours
QgsMeshTimeSettings( double relativeTimeOffsetHours, const QString &relativeTimeFormat );
//! Constructs absolute time format settings with defined reference time
QgsMeshTimeSettings( const QDateTime &absoluteTimeReferenceTime, const QString &absoluteTimeFormat );
//! Writes configuration to a new DOM element
QDomElement writeXml( QDomDocument &doc, const QgsReadWriteContext &context ) const;
//! Reads configuration from the given DOM element
void readXml( const QDomElement &elem, const QgsReadWriteContext &context );
//! Returns whether to use absolute time format
bool useAbsoluteTime() const;
//! Sets use absolute time flag
void setUseAbsoluteTime( bool useAbsoluteTime );
//! Returns number of offset hours for relative time formatting
double relativeTimeOffsetHours() const;
//! Sets number of offset hours for relative time formatting
void setRelativeTimeOffsetHours( double relativeTimeOffsetHours );
//! Returns format used for relative time
QString relativeTimeFormat() const;
//! Sets format used for relative time
void setRelativeTimeFormat( const QString &relativeTimeFormat );
//! Returns reference time used for absolute time format
QDateTime absoluteTimeReferenceTime() const;
//! Sets reference time used for absolute time format
void setAbsoluteTimeReferenceTime( const QDateTime &absoluteTimeReferenceTime );
//! Returns format used for absolute time
QString absoluteTimeFormat() const;
//! Sets format used for absolute time
void setAbsoluteTimeFormat( const QString &absoluteTimeFormat );
private:
bool mUseAbsoluteTime = false;
double mRelativeTimeOffsetHours = 0;
QString mRelativeTimeFormat = QStringLiteral( "d hh:mm:ss" );
QDateTime mAbsoluteTimeReferenceTime;
QString mAbsoluteTimeFormat = QStringLiteral( "dd.MM.yyyy hh:mm:ss" );
};
Q_DECLARE_METATYPE( QgsMeshTimeSettings );
#endif // QGSMESHTIMESETTINGS_H

View File

@ -3,13 +3,13 @@
<class>QgsMeshRendererActiveDatasetWidgetBase</class>
<widget class="QWidget" name="QgsMeshRendererActiveDatasetWidgetBase">
<property name="enabled">
<bool>false</bool>
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>286</width>
<width>292</width>
<height>337</height>
</rect>
</property>
@ -36,30 +36,17 @@
</item>
<item>
<layout class="QGridLayout" name="mTimeLayout">
<item row="0" column="0" colspan="6">
<widget class="QSlider" name="mDatasetSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QToolButton" name="mLastDatasetButton">
<property name="text">
<string>&gt;|</string>
</property>
<property name="autoRaise">
<item row="2" column="0" colspan="2">
<widget class="QComboBox" name="mTimeComboBox">
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</property>
</widget>
</item>
<item row="1" column="4">
<item row="2" column="5">
<widget class="QToolButton" name="mNextDatasetButton">
<property name="text">
<string>&gt;</string>
@ -69,7 +56,7 @@
</property>
</widget>
</item>
<item row="1" column="3">
<item row="2" column="4">
<widget class="QToolButton" name="mPreviousDatasetButton">
<property name="text">
<string>&lt;</string>
@ -79,7 +66,17 @@
</property>
</widget>
</item>
<item row="1" column="2">
<item row="2" column="6">
<widget class="QToolButton" name="mLastDatasetButton">
<property name="text">
<string>&gt;|</string>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QToolButton" name="mFirstDatasetButton">
<property name="text">
<string>|&lt;</string>
@ -89,13 +86,33 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QComboBox" name="mTimeComboBox">
<property name="editable">
<item row="2" column="2">
<widget class="QToolButton" name="mTimeFormatButton">
<property name="toolTip">
<string>Time Format Options</string>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="icon">
<iconset resource="../../../images/images.qrc">
<normaloff>:/images/themes/default/console/iconSettingsConsole.svg</normaloff>:/images/themes/default/console/iconSettingsConsole.svg</iconset>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::NoInsert</enum>
</widget>
</item>
<item row="1" column="0" colspan="7">
<widget class="QSlider" name="mDatasetSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
</item>
@ -135,6 +152,8 @@
<header>mesh/qgsmeshdatasetgrouptreeview.h</header>
</customwidget>
</customwidgets>
<resources/>
<resources>
<include location="../../../images/images.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,254 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsMeshTimeFormatDialog</class>
<widget class="QDialog" name="QgsMeshTimeFormatDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>271</width>
<height>382</height>
</rect>
</property>
<property name="windowTitle">
<string>Time Display Options</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QComboBox" name="mUseTimeComboBox">
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>Use absolute time</string>
</property>
</item>
<item>
<property name="text">
<string>Use relative time</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QGroupBox" name="mAbsoluteTimeGroupBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Use absolute time </string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="refLabel">
<property name="text">
<string>Reference date/time</string>
</property>
</widget>
</item>
<item>
<widget class="QDateTimeEdit" name="mReferenceDateTimeEdit">
<property name="dateTime">
<datetime>
<hour>0</hour>
<minute>0</minute>
<second>0</second>
<year>2019</year>
<month>1</month>
<day>1</day>
</datetime>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Date/time Format</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mAbsoluteTimeFormatComboBox">
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>dd.MM.yyyy hh:mm:ss</string>
</property>
</item>
<item>
<property name="text">
<string>dd.MM.yyyy hh:mm</string>
</property>
</item>
<item>
<property name="text">
<string>dd.MM.yyyy hh</string>
</property>
</item>
<item>
<property name="text">
<string>dd.MM.yyyy</string>
</property>
</item>
<item>
<property name="text">
<string>dd/MM/yyyy hh:mm:ss</string>
</property>
</item>
<item>
<property name="text">
<string>dd/MM/yyyy hh:mm</string>
</property>
</item>
<item>
<property name="text">
<string>dd/MM/yyyy hh</string>
</property>
</item>
<item>
<property name="text">
<string>dd/MM/yyyy</string>
</property>
</item>
<item>
<property name="text">
<string>MM/dd/yyyy hh:mm:ss</string>
</property>
</item>
<item>
<property name="text">
<string>MM/dd/yyyy hh:mm</string>
</property>
</item>
<item>
<property name="text">
<string>MM/dd/yyyy hh</string>
</property>
</item>
<item>
<property name="text">
<string>MM/dd/yyyy</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="mRelativeTimeGroupBox">
<property name="title">
<string>Use relative time</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Offset by</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="mOffsetHoursSpinBox">
<property name="suffix">
<string> hours</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-100000.000000000000000</double>
</property>
<property name="maximum">
<double>100000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Time Format</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mRelativeTimeFormatComboBox">
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>hh:mm:ss</string>
</property>
</item>
<item>
<property name="text">
<string>hh:mm:ss.zzz</string>
</property>
</item>
<item>
<property name="text">
<string>hh</string>
</property>
</item>
<item>
<property name="text">
<string>d hh:mm:ss</string>
</property>
</item>
<item>
<property name="text">
<string>d hh</string>
</property>
</item>
<item>
<property name="text">
<string>d</string>
</property>
</item>
<item>
<property name="text">
<string>ss</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
<slots>
<slot>shaftLengthMethodChanged()</slot>
<slot>apply()</slot>
</slots>
</ui>

View File

@ -26,6 +26,7 @@
#include "qgsproviderregistry.h"
#include "qgsproject.h"
#include "qgstriangularmesh.h"
#include "qgsmeshlayerutils.h"
/**
* \ingroup UnitTests
@ -60,6 +61,9 @@ class TestQgsMeshLayer : public QObject
void test_read_face_vector_dataset();
void test_read_vertex_scalar_dataset_with_inactive_face();
void test_extent();
void test_time_format_data();
void test_time_format();
};
QString TestQgsMeshLayer::readFile( const QString &fname ) const
@ -426,5 +430,68 @@ void TestQgsMeshLayer::test_write_read_project()
QVERIFY( layers.size() == 2 );
}
void TestQgsMeshLayer::test_time_format_data()
{
QTest::addColumn<QgsMeshTimeSettings>( "settings" );
QTest::addColumn<double>( "hours" );
QTest::addColumn<QString>( "expectedTime" );
QTest::newRow( "rel1" ) << QgsMeshTimeSettings( 0, "hh:mm:ss.zzz" ) << 0.0 << QString( "00:00:00.000" );
QTest::newRow( "rel2" ) << QgsMeshTimeSettings( 0, "hh:mm:ss" ) << 0.0 << QString( "00:00:00" );
QTest::newRow( "rel3" ) << QgsMeshTimeSettings( 0, "d hh:mm:ss" ) << 0.0 << QString( "0 d 00:00:00" );
QTest::newRow( "rel4" ) << QgsMeshTimeSettings( 0, "d hh" ) << 0.0 << QString( "0 d 0" );
QTest::newRow( "rel5" ) << QgsMeshTimeSettings( 0, "d" ) << 0.0 << QString( "0" );
QTest::newRow( "rel6" ) << QgsMeshTimeSettings( 0, "hh" ) << 0.0 << QString( "0" );
QTest::newRow( "rel7" ) << QgsMeshTimeSettings( 0, "ss" ) << 0.0 << QString( "0" );
QTest::newRow( "rel8" ) << QgsMeshTimeSettings( 0, "some-invalid-format" ) << 0.0 << QString( "0" );
QTest::newRow( "rel9" ) << QgsMeshTimeSettings( 100.11111, "hh:mm:ss.zzz" ) << 0.0 << QString( "100:06:39.996" );
QTest::newRow( "rel10" ) << QgsMeshTimeSettings( 0, "hh:mm:ss.zzz" ) << 100.11111 << QString( "100:06:39.996" );
QTest::newRow( "rel11" ) << QgsMeshTimeSettings( 0, "hh:mm:ss" ) << 100.11111 << QString( "100:06:39" );
QTest::newRow( "rel12" ) << QgsMeshTimeSettings( 0, "d hh:mm:ss" ) << 100.11111 << QString( "4 d 04:06:39" );
QTest::newRow( "rel13" ) << QgsMeshTimeSettings( 0, "d hh" ) << 100.11111 << QString( "4 d 4" );
QTest::newRow( "rel14" ) << QgsMeshTimeSettings( 0, "d" ) << 100.11111 << QString( "4" );
QTest::newRow( "rel15" ) << QgsMeshTimeSettings( 0, "hh" ) << 100.11111 << QString( "100.111" );
QTest::newRow( "rel16" ) << QgsMeshTimeSettings( 0, "ss" ) << 100.11111 << QString( "360399" );
QTest::newRow( "rel17" ) << QgsMeshTimeSettings( 0, "some-invalid-format" ) << 100.11111 << QString( "100.111" );
QDateTime dt = QDateTime::fromString( "2019-03-21 11:01:02", "yyyy-MM-dd HH:mm:ss" );
QTest::newRow( "abs1" ) << QgsMeshTimeSettings( dt, "dd.MM.yyyy hh:mm:ss" ) << 0.0 << QString( "21.03.2019 11:01:02" );
QTest::newRow( "abs2" ) << QgsMeshTimeSettings( dt, "dd.MM.yyyy hh:mm" ) << 0.0 << QString( "21.03.2019 11:01" );
QTest::newRow( "abs3" ) << QgsMeshTimeSettings( dt, "dd.MM.yyyy hh" ) << 0.0 << QString( "21.03.2019 11" );
QTest::newRow( "abs4" ) << QgsMeshTimeSettings( dt, "dd.MM.yyyy" ) << 0.0 << QString( "21.03.2019" );
QTest::newRow( "abs5" ) << QgsMeshTimeSettings( dt, "dd/MM/yyyy hh:mm:ss" ) << 0.0 << QString( "21/03/2019 11:01:02" );
QTest::newRow( "abs6" ) << QgsMeshTimeSettings( dt, "dd/MM/yyyy hh:mm" ) << 0.0 << QString( "21/03/2019 11:01" );
QTest::newRow( "abs7" ) << QgsMeshTimeSettings( dt, "dd/MM/yyyy hh" ) << 0.0 << QString( "21/03/2019 11" );
QTest::newRow( "abs8" ) << QgsMeshTimeSettings( dt, "dd/MM/yyyy" ) << 0.0 << QString( "21/03/2019" );
QTest::newRow( "abs9" ) << QgsMeshTimeSettings( dt, "MM/dd/yyyy hh:mm:ss" ) << 0.0 << QString( "03/21/2019 11:01:02" );
QTest::newRow( "abs10" ) << QgsMeshTimeSettings( dt, "MM/dd/yyyy hh:mm" ) << 0.0 << QString( "03/21/2019 11:01" );
QTest::newRow( "abs11" ) << QgsMeshTimeSettings( dt, "MM/dd/yyyy hh" ) << 0.0 << QString( "03/21/2019 11" );
QTest::newRow( "abs12" ) << QgsMeshTimeSettings( dt, "MM/dd/yyyy" ) << 0.0 << QString( "03/21/2019" );
QTest::newRow( "abs13" ) << QgsMeshTimeSettings( dt, "dd.MM.yyyy hh:mm:ss" ) << 100.11111 << QString( "25.03.2019 15:07:41" );
QTest::newRow( "abs14" ) << QgsMeshTimeSettings( dt, "dd.MM.yyyy hh:mm" ) << 100.11111 << QString( "25.03.2019 15:07" );
QTest::newRow( "abs15" ) << QgsMeshTimeSettings( dt, "dd.MM.yyyy hh" ) << 100.11111 << QString( "25.03.2019 15" );
QTest::newRow( "abs16" ) << QgsMeshTimeSettings( dt, "dd.MM.yyyy" ) << 100.11111 << QString( "25.03.2019" );
QTest::newRow( "abs17" ) << QgsMeshTimeSettings( dt, "dd/MM/yyyy hh:mm:ss" ) << 100.11111 << QString( "25/03/2019 15:07:41" );
QTest::newRow( "abs18" ) << QgsMeshTimeSettings( dt, "dd/MM/yyyy hh:mm" ) << 100.11111 << QString( "25/03/2019 15:07" );
QTest::newRow( "abs19" ) << QgsMeshTimeSettings( dt, "dd/MM/yyyy hh" ) << 100.11111 << QString( "25/03/2019 15" );
QTest::newRow( "abs20" ) << QgsMeshTimeSettings( dt, "dd/MM/yyyy" ) << 100.11111 << QString( "25/03/2019" );
QTest::newRow( "abs21" ) << QgsMeshTimeSettings( dt, "MM/dd/yyyy hh:mm:ss" ) << 100.11111 << QString( "03/25/2019 15:07:41" );
QTest::newRow( "abs22" ) << QgsMeshTimeSettings( dt, "MM/dd/yyyy hh:mm" ) << 100.11111 << QString( "03/25/2019 15:07" );
QTest::newRow( "abs23" ) << QgsMeshTimeSettings( dt, "MM/dd/yyyy hh" ) << 100.11111 << QString( "03/25/2019 15" );
QTest::newRow( "abs24" ) << QgsMeshTimeSettings( dt, "MM/dd/yyyy" ) << 100.11111 << QString( "03/25/2019" );
}
void TestQgsMeshLayer::test_time_format()
{
QFETCH( QgsMeshTimeSettings, settings );
QFETCH( double, hours );
QFETCH( QString, expectedTime );
QString time = QgsMeshLayerUtils::formatTime( hours, settings );
QCOMPARE( time, expectedTime );
}
QGSTEST_MAIN( TestQgsMeshLayer )
#include "testqgsmeshlayer.moc"