From bbb1e7cf9daf070cf53eec74294fca3b9c776595 Mon Sep 17 00:00:00 2001 From: Samweli Date: Wed, 11 Mar 2020 08:15:35 +0100 Subject: [PATCH] updates on temporal animation logic --- .../qgstemporalcontroller.sip.in | 4 +- .../qgstemporalnavigationobject.sip.in | 21 ++--- ...terdataprovidertemporalcapabilities.sip.in | 67 +++++++++++++- .../qgsrasterlayertemporalproperties.sip.in | 31 +++++++ python/gui/auto_generated/qgsmapcanvas.sip.in | 3 +- .../qgstemporalcontrollerdockwidget.sip.in | 12 ++- src/app/qgisapp.cpp | 4 +- src/app/qgsprojectproperties.cpp | 7 +- src/core/qgsmaplayertemporalproperties.h | 4 +- src/core/qgstemporalcontroller.cpp | 3 +- src/core/qgstemporalcontroller.h | 4 +- src/core/qgstemporalnavigationobject.cpp | 40 +++++---- src/core/qgstemporalnavigationobject.h | 29 ++++--- ...rasterdataprovidertemporalcapabilities.cpp | 36 ++++++++ ...gsrasterdataprovidertemporalcapabilities.h | 87 ++++++++++++++++++- src/core/raster/qgsrasterlayer.cpp | 37 ++++++++ src/core/raster/qgsrasterlayer.h | 7 ++ src/core/raster/qgsrasterlayerrenderer.cpp | 16 ++++ .../qgsrasterlayertemporalproperties.cpp | 43 ++++++++- .../raster/qgsrasterlayertemporalproperties.h | 44 ++++++++-- src/gui/qgsmapcanvas.cpp | 11 +-- src/gui/qgsmapcanvas.h | 9 +- src/gui/qgstemporalcontrollerdockwidget.cpp | 73 +++++++--------- src/gui/qgstemporalcontrollerdockwidget.h | 31 ++++--- src/gui/qgstemporalmapsettingsdialog.cpp | 3 - src/gui/qgstemporalmapsettingswidget.cpp | 4 - src/gui/qgstemporalmapsettingswidget.h | 2 +- ...qgsrasterlayertemporalpropertieswidget.cpp | 72 +++++++-------- .../qgsrasterlayertemporalpropertieswidget.h | 27 ------ src/providers/wms/qgswmsprovider.cpp | 10 +++ src/ui/qgsprojectpropertiesbase.ui | 16 ++-- src/ui/qgstemporalcontrollerdockwidgetbase.ui | 8 +- ...rasterlayertemporalpropertieswidgetbase.ui | 34 +++++++- tests/src/app/testqgsprojectproperties.cpp | 24 ++--- 34 files changed, 589 insertions(+), 234 deletions(-) diff --git a/python/core/auto_generated/qgstemporalcontroller.sip.in b/python/core/auto_generated/qgstemporalcontroller.sip.in index 0e95058ccf47..d51f7dcfed54 100644 --- a/python/core/auto_generated/qgstemporalcontroller.sip.in +++ b/python/core/auto_generated/qgstemporalcontroller.sip.in @@ -24,13 +24,11 @@ updates of the objects temporal range. %End public: - QgsTemporalController(); + QgsTemporalController( QObject *parent = 0 ); %Docstring Constructor for QgsTemporalController. %End - virtual ~QgsTemporalController(); - signals: void updateTemporalRange( const QgsDateTimeRange &range ); diff --git a/python/core/auto_generated/qgstemporalnavigationobject.sip.in b/python/core/auto_generated/qgstemporalnavigationobject.sip.in index af546a061f61..a84a8f852e29 100644 --- a/python/core/auto_generated/qgstemporalnavigationobject.sip.in +++ b/python/core/auto_generated/qgstemporalnavigationobject.sip.in @@ -12,7 +12,7 @@ -class QgsTemporalNavigationObject : QObject +class QgsTemporalNavigationObject : QgsTemporalController { %Docstring The QgsTemporalNavigationObject class @@ -123,7 +123,8 @@ Returns the total number of frames for the navigation. void play(); %Docstring -Plays the temporal navigation +Starts playing the temporal navigation from its current frame, +using the direction specified by playBackMode() %End void pause(); @@ -133,12 +134,12 @@ Stops the temporal navigation. void forward(); %Docstring -Forward the temporal navigation up till the end of frames. +Starts the animation playing in a forward direction up till the end of frames. %End void backward(); %Docstring -Decrement the temporal navigation till the end of frames. +Starts the animation playing in a reverse direction until the beginning of the time range. %End void next(); @@ -159,18 +160,6 @@ Rewind the temporal navigation to start of the temporal extent. void skipToEnd(); %Docstring Skips the temporal navigation to end of the temporal extent. -%End - - void timerTimeout(); -%Docstring -Handles logic when the temporal navigation timer emit a timeout signal. -%End - - signals: - - void updateTemporalRange( QgsDateTimeRange temporalRange ); -%Docstring -Emitted when navigation range changes. %End }; diff --git a/python/core/auto_generated/raster/qgsrasterdataprovidertemporalcapabilities.sip.in b/python/core/auto_generated/raster/qgsrasterdataprovidertemporalcapabilities.sip.in index 87828b1bb8a5..03d2fc0b5bef 100644 --- a/python/core/auto_generated/raster/qgsrasterdataprovidertemporalcapabilities.sip.in +++ b/python/core/auto_generated/raster/qgsrasterdataprovidertemporalcapabilities.sip.in @@ -9,7 +9,6 @@ - class QgsRasterDataProviderTemporalCapabilities : QgsDataProviderTemporalCapabilities { %Docstring @@ -36,6 +35,72 @@ The ``enabled`` argument specifies whether the data provider has temporal capabi virtual ~QgsRasterDataProviderTemporalCapabilities(); + enum TemporalMode + { + ModeFixedTemporalRange, + ModeTemporalRangeFromDataProvider + }; + + TemporalMode mode() const; +%Docstring +Returns the temporal mode. + +.. seealso:: :py:func:`setMode` +%End + + void setMode( TemporalMode mode ); +%Docstring +Sets the temporal ``mode``. + +.. seealso:: :py:func:`mode` +%End + + enum FetchMode + { + Earliest, + Latest, + Range + }; + + FetchMode fetchMode() const; +%Docstring +Returns the temporal capabilities fetch mode. + +.. seealso:: :py:func:`setFetchMode` +%End + + void setFetchMode( FetchMode mode ); +%Docstring +Sets the temporal properties fetch ``mode``. + +.. seealso:: :py:func:`fetchMode` +%End + + enum TimeInterval + { + Seconds, + Minutes, + Hours, + Days, + Months, + Years, + None + }; + + TimeInterval timeInterval() const; +%Docstring +Returns the temporal interval. + +.. seealso:: :py:func:`setTimeInterval` +%End + + void setTimeInterval( TimeInterval interval ); +%Docstring +Sets the temporal time ``interval``. + +.. seealso:: :py:func:`timeInterval` +%End + void setFixedTemporalRange( const QgsDateTimeRange &range ); %Docstring Sets the fixed datetime ``range`` for the temporal properties. diff --git a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 67d34866901e..1da49ec46b1b 100644 --- a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -50,6 +50,27 @@ Returns the temporal properties mode. Sets the temporal properties ``mode``. .. seealso:: :py:func:`mode` +%End + + enum FetchMode + { + Earliest, + Latest, + Range + }; + + FetchMode fetchMode() const; +%Docstring +Returns the temporal properties fetch mode. + +.. seealso:: :py:func:`setFetchMode` +%End + + void setFetchMode( FetchMode mode ); +%Docstring +Sets the temporal properties fetch ``mode``. + +.. seealso:: :py:func:`fetchMode` %End void setFixedTemporalRange( const QgsDateTimeRange &range ); @@ -164,6 +185,16 @@ Returns the current active reference datetime range for these temporal propertie virtual bool readXml( const QDomElement &element, const QgsReadWriteContext &context ); + TemporalMode indexToMode( int index ); +%Docstring +Returns the temporal mode given index +%End + + FetchMode indexToFetchMode( int index ); +%Docstring +Returns the temporal fetch mode given index +%End + }; /************************************************************************ diff --git a/python/gui/auto_generated/qgsmapcanvas.sip.in b/python/gui/auto_generated/qgsmapcanvas.sip.in index 284c082d6da5..0ab7f1ab185a 100644 --- a/python/gui/auto_generated/qgsmapcanvas.sip.in +++ b/python/gui/auto_generated/qgsmapcanvas.sip.in @@ -18,6 +18,7 @@ + class QgsMapCanvas : QGraphicsView { %Docstring @@ -72,7 +73,7 @@ Gets access to properties used for map rendering .. versionadded:: 2.4 %End - void setTemporalController( QgsTemporalNavigationObject *controller ); + void setTemporalController( QgsTemporalController *controller ); %Docstring Sets the temporal controller, this controller will be used to update the canvas temporal range. diff --git a/python/gui/auto_generated/qgstemporalcontrollerdockwidget.sip.in b/python/gui/auto_generated/qgstemporalcontrollerdockwidget.sip.in index e13226202abe..9e5e57980d2f 100644 --- a/python/gui/auto_generated/qgstemporalcontrollerdockwidget.sip.in +++ b/python/gui/auto_generated/qgstemporalcontrollerdockwidget.sip.in @@ -31,11 +31,21 @@ Constructor for QgsTemporalControllerDockWidget ~QgsTemporalControllerDockWidget(); - QgsTemporalNavigationObject *temporalController(); + QgsTemporalController *temporalController(); %Docstring Returns the temporal controller object used by this object in navigation. %End + enum TimeUnit + { + Seconds, + Minutes, + Hours, + Days, + Months, + Years + }; + }; /************************************************************************ diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 4d4049eff019..088027aa062c 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -1153,8 +1153,8 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh mBrowserWidget->setObjectName( QStringLiteral( "Browser" ) ); mBrowserWidget->setMessageBar( mInfoBar ); - mTemporalControllerWidget = new QgsTemporalControllerDockWidget( tr( "Temporal VCR" ), this ); - mTemporalControllerWidget->setObjectName( QStringLiteral( "Temporal VCR" ) ); + mTemporalControllerWidget = new QgsTemporalControllerDockWidget( tr( "Temporal Controller" ), this ); + mTemporalControllerWidget->setObjectName( QStringLiteral( "Temporal Controller" ) ); addDockWidget( Qt::BottomDockWidgetArea, mTemporalControllerWidget ); mTemporalControllerWidget->hide(); diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index 35075485bcf0..5c42796350b0 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -2540,9 +2540,10 @@ void QgsProjectProperties::calculateFromLayersButton_clicked() mStartDateTimeEdit->setDateTime( minDate ); mEndDateTimeEdit->setDateTime( maxDate ); - mCurrentRangeLabel->setText( tr( "Current range: %1 to %2" ).arg( - mStartDateTimeEdit->dateTime().toString( "yyyy-MM-dd hh:mm:ss" ), - mEndDateTimeEdit->dateTime().toString( "yyyy-MM-dd hh:mm:ss" ) ) ); + QLocale locale; + mCurrentRangeLabel->setText( tr( "Current selected range: %1 to %2" ).arg( + mStartDateTimeEdit->dateTime().toString( locale.dateTimeFormat() ), + mEndDateTimeEdit->dateTime().toString( locale.dateTimeFormat() ) ) ); } QListWidgetItem *QgsProjectProperties::addScaleToScaleList( const QString &newScale ) diff --git a/src/core/qgsmaplayertemporalproperties.h b/src/core/qgsmaplayertemporalproperties.h index 6ca92810516d..33de95a1d341 100644 --- a/src/core/qgsmaplayertemporalproperties.h +++ b/src/core/qgsmaplayertemporalproperties.h @@ -70,8 +70,8 @@ class CORE_EXPORT QgsMapLayerTemporalProperties : public QgsTemporalProperty */ enum TemporalSource { - Layer, //! Defined from layer . - Project//! Defined from project time settings; + Layer = 0, //! Defined from layer . + Project = 1//! Defined from project time settings; }; /** diff --git a/src/core/qgstemporalcontroller.cpp b/src/core/qgstemporalcontroller.cpp index 0a6220ecf63c..bb80f7042396 100644 --- a/src/core/qgstemporalcontroller.cpp +++ b/src/core/qgstemporalcontroller.cpp @@ -17,6 +17,7 @@ #include "qgstemporalcontroller.h" -QgsTemporalController::QgsTemporalController( ) +QgsTemporalController::QgsTemporalController( QObject *parent ) + : QObject( parent ) { } diff --git a/src/core/qgstemporalcontroller.h b/src/core/qgstemporalcontroller.h index ee97d4477aac..e550c927ea43 100644 --- a/src/core/qgstemporalcontroller.h +++ b/src/core/qgstemporalcontroller.h @@ -42,9 +42,7 @@ class CORE_EXPORT QgsTemporalController : public QObject * Constructor for QgsTemporalController. * */ - QgsTemporalController(); - - virtual ~QgsTemporalController() = default; + QgsTemporalController( QObject *parent = nullptr ); signals: diff --git a/src/core/qgstemporalnavigationobject.cpp b/src/core/qgstemporalnavigationobject.cpp index ab83df743a25..03a683f473f3 100644 --- a/src/core/qgstemporalnavigationobject.cpp +++ b/src/core/qgstemporalnavigationobject.cpp @@ -19,44 +19,54 @@ #include "qgis.h" QgsTemporalNavigationObject::QgsTemporalNavigationObject( QObject *parent ) - : QObject( parent ) + : QgsTemporalController( parent ) { mNewFrameTimer = new QTimer( this ); connect( mNewFrameTimer, &QTimer::timeout, - this, qgis::overload<>::of( &QgsTemporalNavigationObject::timerTimeout ) ); + this, &QgsTemporalNavigationObject::timerTimeout ); } void QgsTemporalNavigationObject::timerTimeout() { - if ( mPlayBackMode == PlaybackMode::Forward ) - forward(); - if ( mPlayBackMode == PlaybackMode::Reverse ) - backward(); - return; + switch ( mPlayBackMode ) + { + case PlaybackMode::Forward: + forward(); + break; + + case PlaybackMode::Reverse: + backward(); + break; + + case PlaybackMode::Idle: + pause(); + break; + } } QgsDateTimeRange QgsTemporalNavigationObject::dateTimeRangeForFrameNumber( long long frame ) const { QDateTime start = mTemporalExtents.begin(); - long long pastFrame = frame - 1; - if ( pastFrame < 0 ) - pastFrame = 0; + if ( frame < 0 ) + frame = 0; + long long nextFrame = frame + 1; - QDateTime begin = start.addSecs( pastFrame * mFrameDuration.seconds() ); - QDateTime end = start.addSecs( frame * mFrameDuration.seconds() ); + QDateTime begin = start.addSecs( frame * mFrameDuration.seconds() ); + QDateTime end = start.addSecs( nextFrame * mFrameDuration.seconds() ); if ( end <= mTemporalExtents.end() ) return QgsDateTimeRange( begin, end ); - return mTemporalExtents; + return QgsDateTimeRange( begin, mTemporalExtents.end() ); } void QgsTemporalNavigationObject::setTemporalExtents( QgsDateTimeRange temporalExtents ) { mTemporalExtents = temporalExtents; + setCurrentFrameNumber( 0 ); } QgsDateTimeRange QgsTemporalNavigationObject::temporalExtents() const @@ -68,10 +78,7 @@ void QgsTemporalNavigationObject::setCurrentFrameNumber( long long frameNumber ) { if ( frameNumber < 0 || frameNumber >= totalFrameCount() ) - { - pause(); return; - } if ( mCurrentFrameNumber != frameNumber ) { @@ -89,6 +96,7 @@ long long QgsTemporalNavigationObject::currentFrameNumber() const void QgsTemporalNavigationObject::setFrameDuration( QgsInterval frameDuration ) { mFrameDuration = frameDuration; + setCurrentFrameNumber( 0 ); } QgsInterval QgsTemporalNavigationObject::frameDuration() const diff --git a/src/core/qgstemporalnavigationobject.h b/src/core/qgstemporalnavigationobject.h index 003d52e8d0e0..21ff6d7eeafb 100644 --- a/src/core/qgstemporalnavigationobject.h +++ b/src/core/qgstemporalnavigationobject.h @@ -22,6 +22,7 @@ #include "qgis_core.h" #include "qgsrange.h" #include "qgsinterval.h" +#include "qgstemporalcontroller.h" #include #include @@ -34,7 +35,7 @@ class QgsMapLayer; * * \since QGIS 3.14 */ -class CORE_EXPORT QgsTemporalNavigationObject : public QObject +class CORE_EXPORT QgsTemporalNavigationObject : public QgsTemporalController { Q_OBJECT @@ -49,9 +50,9 @@ class CORE_EXPORT QgsTemporalNavigationObject : public QObject //! Represents the current playback mode enum PlaybackMode { - Forward, //! When the forward button is clicked. - Reverse, //! When the back button is clicked. - Idle, //! When navigation is idle. + Forward, //! Animation is playing forward. + Reverse, //! Animation is playing in reverse. + Idle, //! Animation is paused. }; /** @@ -140,16 +141,19 @@ class CORE_EXPORT QgsTemporalNavigationObject : public QObject public slots: - //! Plays the temporal navigation + /** + * Starts playing the temporal navigation from its current frame, + * using the direction specified by playBackMode() + */ void play(); //! Stops the temporal navigation. void pause(); - //! Forward the temporal navigation up till the end of frames. + //! Starts the animation playing in a forward direction up till the end of frames. void forward(); - //! Decrement the temporal navigation till the end of frames. + //! Starts the animation playing in a reverse direction until the beginning of the time range. void backward(); //! Forward the temporal navigation by one frame. @@ -164,14 +168,11 @@ class CORE_EXPORT QgsTemporalNavigationObject : public QObject //! Skips the temporal navigation to end of the temporal extent. void skipToEnd(); + private slots: + //! Handles logic when the temporal navigation timer emit a timeout signal. void timerTimeout(); - signals: - - //! Emitted when navigation range changes. - void updateTemporalRange( QgsDateTimeRange temporalRange ); - private: //! The controller temporal navigation extent range. @@ -184,10 +185,10 @@ class CORE_EXPORT QgsTemporalNavigationObject : public QObject QgsInterval mFrameDuration; //! Member for frame rate - double mFramesPerSecond; + double mFramesPerSecond = 1; //! Timer to set navigation time interval - QTimer *mNewFrameTimer; + QTimer *mNewFrameTimer = nullptr; //! Navigation playback mode member PlaybackMode mPlayBackMode = Idle; diff --git a/src/core/raster/qgsrasterdataprovidertemporalcapabilities.cpp b/src/core/raster/qgsrasterdataprovidertemporalcapabilities.cpp index 4a90f685163d..89fb6423c5ba 100644 --- a/src/core/raster/qgsrasterdataprovidertemporalcapabilities.cpp +++ b/src/core/raster/qgsrasterdataprovidertemporalcapabilities.cpp @@ -89,3 +89,39 @@ bool QgsRasterDataProviderTemporalCapabilities::isReferenceEnable() const { return mReferenceEnable; } + +QgsRasterDataProviderTemporalCapabilities::TemporalMode QgsRasterDataProviderTemporalCapabilities::mode() const +{ + return mMode; +} + +void QgsRasterDataProviderTemporalCapabilities::setMode( TemporalMode mode ) +{ + if ( mMode == mode ) + return; + mMode = mode; +} + +QgsRasterDataProviderTemporalCapabilities::FetchMode QgsRasterDataProviderTemporalCapabilities::fetchMode() const +{ + return mFetchMode; +} + +void QgsRasterDataProviderTemporalCapabilities::setFetchMode( FetchMode mode ) +{ + if ( mFetchMode == mode ) + return; + mFetchMode = mode; +} + +QgsRasterDataProviderTemporalCapabilities::TimeInterval QgsRasterDataProviderTemporalCapabilities::timeInterval() const +{ + return mTimeInteval; +} + +void QgsRasterDataProviderTemporalCapabilities::setTimeInterval( TimeInterval interval ) +{ + if ( mTimeInteval == interval ) + return; + mTimeInteval = interval; +} diff --git a/src/core/raster/qgsrasterdataprovidertemporalcapabilities.h b/src/core/raster/qgsrasterdataprovidertemporalcapabilities.h index cffa77bb9401..58288c76cd5f 100644 --- a/src/core/raster/qgsrasterdataprovidertemporalcapabilities.h +++ b/src/core/raster/qgsrasterdataprovidertemporalcapabilities.h @@ -23,8 +23,6 @@ #include "qgsrange.h" #include "qgsdataprovidertemporalcapabilities.h" -#include - /** * \class QgsRasterDataProviderTemporalCapabilities * \ingroup core @@ -49,6 +47,80 @@ class CORE_EXPORT QgsRasterDataProviderTemporalCapabilities : public QgsDataProv virtual ~QgsRasterDataProviderTemporalCapabilities() = default; + /** + * Mode of the temporal capabilities + **/ + enum TemporalMode + { + ModeFixedTemporalRange = 0, //! Mode when temporal capabilities have fixed start and end datetimes. + ModeTemporalRangeFromDataProvider = 1 //! Mode when temporal capabilities provides the temporal range . + }; + + /** + * Returns the temporal mode. + * + *\see setMode() + **/ + TemporalMode mode() const; + + /** + * Sets the temporal \a mode. + * + *\see mode() + **/ + void setMode( TemporalMode mode ); + + /** + * Mode to used to fetch the data from provider. This is applicable for wms based layers. + * + **/ + enum FetchMode + { + Earliest = 0, //! Use the start datetime in the temporal range. + Latest = 1, //! Use the end datetime in the temporal range. + Range = 2 //! Use the datetimes in temporal range as range. + }; + + /** + * Returns the temporal capabilities fetch mode. + * + *\see setFetchMode() + **/ + FetchMode fetchMode() const; + + /** + * Sets the temporal properties fetch \a mode. + * + *\see fetchMode() + **/ + void setFetchMode( FetchMode mode ); + + //! Stores the capabilities time interval duration in the temporal ranges. + enum TimeInterval + { + Seconds = 0, //! For seconds + Minutes = 1, //! For minutes + Hours = 2, //! For hours + Days = 3, //! For days + Months = 4, //! For months + Years = 5, //! For years + None = 6 //! if there is no time interval + }; + + /** + * Returns the temporal interval. + * + *\see setTimeInterval() + **/ + TimeInterval timeInterval() const; + + /** + * Sets the temporal time \a interval. + * + *\see timeInterval() + **/ + void setTimeInterval( TimeInterval interval ); + /** * Sets the fixed datetime \a range for the temporal properties. * @@ -151,8 +223,6 @@ class CORE_EXPORT QgsRasterDataProviderTemporalCapabilities : public QgsDataProv bool isReferenceEnable() const; private: - //! Represents current active datetime range member. - QgsDateTimeRange mRange; /** * Represents fixed data provider datetime range. @@ -189,6 +259,15 @@ class CORE_EXPORT QgsRasterDataProviderTemporalCapabilities : public QgsDataProv //! If reference range has been enabled to be used in these properties bool mReferenceEnable = false; + //! Data fetch mode. + FetchMode mFetchMode = Earliest; + + //! Temporal capabilities mode. + TemporalMode mMode = ModeTemporalRangeFromDataProvider; + + //! Member for time interval. + TimeInterval mTimeInteval = None; + }; #endif // QGSRASTERDATAPROVIDERTEMPORALCAPABILITIES_H diff --git a/src/core/raster/qgsrasterlayer.cpp b/src/core/raster/qgsrasterlayer.cpp index d28a351aa643..b41b29c5dd34 100644 --- a/src/core/raster/qgsrasterlayer.cpp +++ b/src/core/raster/qgsrasterlayer.cpp @@ -866,6 +866,10 @@ void QgsRasterLayer::setDataSource( const QString &dataSource, const QString &ba setDataProvider( provider, options ); + if ( mDataProvider ) + setDefaultsFromDataProviderTemporalCapabilities( + mDataProvider->temporalCapabilities() ); + if ( mValid ) { // load default style @@ -958,6 +962,39 @@ QgsRasterLayerTemporalProperties *QgsRasterLayer::temporalProperties() return mTemporalProperties; } +void QgsRasterLayer::setDefaultsFromDataProviderTemporalCapabilities( + QgsRasterDataProviderTemporalCapabilities *temporalCapabilities ) +{ + + mTemporalProperties->setFixedTemporalRange( temporalCapabilities->fixedTemporalRange() ); + mTemporalProperties->setFixedReferenceTemporalRange( temporalCapabilities->fixedReferenceTemporalRange() ); + switch ( temporalCapabilities->mode() ) + { + case QgsRasterDataProviderTemporalCapabilities::ModeTemporalRangeFromDataProvider: + mTemporalProperties->setMode( QgsRasterLayerTemporalProperties::ModeTemporalRangeFromDataProvider ); + break; + + case QgsRasterDataProviderTemporalCapabilities::ModeFixedTemporalRange: + mTemporalProperties->setMode( QgsRasterLayerTemporalProperties::ModeFixedTemporalRange ); + break; + } + + switch ( temporalCapabilities->fetchMode() ) + { + case QgsRasterDataProviderTemporalCapabilities::Earliest: + mTemporalProperties->setFetchMode( QgsRasterLayerTemporalProperties::Earliest ); + break; + + case QgsRasterDataProviderTemporalCapabilities::Latest: + mTemporalProperties->setFetchMode( QgsRasterLayerTemporalProperties::Latest ); + break; + + case QgsRasterDataProviderTemporalCapabilities::Range: + mTemporalProperties->setFetchMode( QgsRasterLayerTemporalProperties::Range ); + break; + } +} + void QgsRasterLayer::setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm algorithm, QgsRasterMinMaxOrigin::Limits limits, const QgsRectangle &extent, int sampleSize, bool generateLookupTableFlag ) { setContrastEnhancement( algorithm, diff --git a/src/core/raster/qgsrasterlayer.h b/src/core/raster/qgsrasterlayer.h index c1eb65c5299c..311d1a29c1bb 100644 --- a/src/core/raster/qgsrasterlayer.h +++ b/src/core/raster/qgsrasterlayer.h @@ -502,6 +502,13 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer bool generateLookupTableFlag, QgsRasterRenderer *rasterRenderer ); + /** + * Sets the defaults capabilities from the provider temporal capabilities + * into layer's temporal properties. + */ + void setDefaultsFromDataProviderTemporalCapabilities( + QgsRasterDataProviderTemporalCapabilities *temporalCapabilities ); + //! Refresh renderer void refreshRenderer( QgsRasterRenderer *rasterRenderer, const QgsRectangle &extent ); diff --git a/src/core/raster/qgsrasterlayerrenderer.cpp b/src/core/raster/qgsrasterlayerrenderer.cpp index a4d11aa5e9f3..f86394f525f2 100644 --- a/src/core/raster/qgsrasterlayerrenderer.cpp +++ b/src/core/raster/qgsrasterlayerrenderer.cpp @@ -241,6 +241,22 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender { mPipe->provider()->temporalCapabilities()->setRequestedTemporalRange( rendererContext.temporalRange() ); mPipe->provider()->temporalCapabilities()->setRequestedReferenceTemporalRange( layer->temporalProperties()->referenceTemporalRange() ); + + switch ( layer->temporalProperties()->fetchMode() ) + { + case QgsRasterLayerTemporalProperties::Earliest: + mPipe->provider()->temporalCapabilities()->setFetchMode( + QgsRasterDataProviderTemporalCapabilities::Earliest ); + break; + case QgsRasterLayerTemporalProperties::Latest: + mPipe->provider()->temporalCapabilities()->setFetchMode( + QgsRasterDataProviderTemporalCapabilities::Latest ); + break; + case QgsRasterLayerTemporalProperties::Range: + mPipe->provider()->temporalCapabilities()->setFetchMode( + QgsRasterDataProviderTemporalCapabilities::Range ); + break; + } } break; } diff --git a/src/core/raster/qgsrasterlayertemporalproperties.cpp b/src/core/raster/qgsrasterlayertemporalproperties.cpp index 6bc939729f16..a6dbf9415dd8 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.cpp +++ b/src/core/raster/qgsrasterlayertemporalproperties.cpp @@ -34,6 +34,18 @@ void QgsRasterLayerTemporalProperties::setMode( QgsRasterLayerTemporalProperties mMode = mode; } +QgsRasterLayerTemporalProperties::FetchMode QgsRasterLayerTemporalProperties::fetchMode() const +{ + return mFetchMode; +} + +void QgsRasterLayerTemporalProperties::setFetchMode( FetchMode mode ) +{ + if ( mFetchMode == mode ) + return; + mFetchMode = mode; +} + void QgsRasterLayerTemporalProperties::setFixedTemporalRange( const QgsDateTimeRange &range ) { mFixedRange = range; @@ -94,6 +106,16 @@ bool QgsRasterLayerTemporalProperties::readXml( const QDomElement &element, cons TemporalMode mode = indexToMode( temporalNode.toElement().attribute( QStringLiteral( "mode" ), QStringLiteral( "0" ) ). toInt() ); setMode( mode ); + FetchMode fetchMode = indexToFetchMode( temporalNode.toElement().attribute( QStringLiteral( "fetchMode" ), QStringLiteral( "0" ) ). toInt() ); + setFetchMode( fetchMode ); + + int sourceIndex = temporalNode.toElement().attribute( QStringLiteral( "source" ), QStringLiteral( "0" ) ).toInt(); + + if ( sourceIndex == 0 ) + setTemporalSource( TemporalSource::Layer ); + else + setTemporalSource( TemporalSource::Project ); + for ( QString rangeString : { "fixedRange", "fixedReferenceRange", "normalRange", "referenceRange" } ) { QDomNode rangeElement = temporalNode.namedItem( rangeString ); @@ -126,6 +148,8 @@ QDomElement QgsRasterLayerTemporalProperties::writeXml( QDomElement &element, QD QDomElement temporalElement = document.createElement( QStringLiteral( "temporal" ) ); temporalElement.setAttribute( QStringLiteral( "mode" ), QString::number( mMode ) ); + temporalElement.setAttribute( QStringLiteral( "source" ), QString::number( temporalSource() ) ); + temporalElement.setAttribute( QStringLiteral( "fetchMode" ), QString::number( fetchMode() ) ); for ( QString rangeString : { "fixedRange", "fixedReferenceRange", "normalRange", "referenceRange" } ) { @@ -161,9 +185,9 @@ QDomElement QgsRasterLayerTemporalProperties::writeXml( QDomElement &element, QD return element; } -QgsRasterLayerTemporalProperties::TemporalMode QgsRasterLayerTemporalProperties::indexToMode( int number ) +QgsRasterLayerTemporalProperties::TemporalMode QgsRasterLayerTemporalProperties::indexToMode( int index ) { - switch ( number ) + switch ( index ) { case 0: return TemporalMode::ModeFixedTemporalRange; @@ -173,3 +197,18 @@ QgsRasterLayerTemporalProperties::TemporalMode QgsRasterLayerTemporalProperties: return TemporalMode::ModeFixedTemporalRange; } } + +QgsRasterLayerTemporalProperties::FetchMode QgsRasterLayerTemporalProperties::indexToFetchMode( int index ) +{ + switch ( index ) + { + case 0: + return Earliest; + case 1: + return Latest; + case 2: + return Range; + default: + return Earliest; + } +} diff --git a/src/core/raster/qgsrasterlayertemporalproperties.h b/src/core/raster/qgsrasterlayertemporalproperties.h index 5d12aedc63ff..bd37e1c330d0 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.h +++ b/src/core/raster/qgsrasterlayertemporalproperties.h @@ -69,6 +69,31 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP **/ void setMode( TemporalMode mode ); + /** + * Mode to used to fetch the data from provider. This is applicable for wms based layers. + * + **/ + enum FetchMode + { + Earliest = 0, //! Use the start datetime in the temporal range. + Latest = 1, //! Use the end datetime in the temporal range. + Range = 2 //! Use the datetimes in temporal range as range. + }; + + /** + * Returns the temporal properties fetch mode. + * + *\see setFetchMode() + **/ + FetchMode fetchMode() const; + + /** + * Sets the temporal properties fetch \a mode. + * + *\see fetchMode() + **/ + void setFetchMode( FetchMode mode ); + /** * Sets a temporal \a range to apply to the whole layer. All bands from * the raster layer will be rendered whenever the current datetime range of @@ -161,10 +186,23 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP bool readXml( const QDomElement &element, const QgsReadWriteContext &context ) override; + /** + * Returns the temporal mode given index + **/ + TemporalMode indexToMode( int index ); + + /** + * Returns the temporal fetch mode given index + **/ + FetchMode indexToFetchMode( int index ); + private: //! Temporal layer mode. - TemporalMode mMode = TemporalMode::ModeFixedTemporalRange; + TemporalMode mMode = ModeFixedTemporalRange; + + //! Temporal layer data fetch mode. + FetchMode mFetchMode = Range; //! Represents fixed temporal range. QgsDateTimeRange mFixedRange; @@ -180,10 +218,6 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP //! Represents current active datetime range member. QgsDateTimeRange mRange; - /** - * Returns the temporal mode given index - **/ - TemporalMode indexToMode( int index ); }; #endif // QGSRASTERLAYERTEMPORALPROPERTIES_H diff --git a/src/gui/qgsmapcanvas.cpp b/src/gui/qgsmapcanvas.cpp index 8a13bc5d829c..55bfd4170ca0 100644 --- a/src/gui/qgsmapcanvas.cpp +++ b/src/gui/qgsmapcanvas.cpp @@ -76,6 +76,7 @@ email : sherman at mrcc.com #include "qgsreferencedgeometry.h" #include "qgsprojectviewsettings.h" #include "qgsmaplayertemporalproperties.h" +#include "qgstemporalcontroller.h" /** * \ingroup gui @@ -416,11 +417,11 @@ void QgsMapCanvas::setDestinationCrs( const QgsCoordinateReferenceSystem &crs ) emit destinationCrsChanged(); } -void QgsMapCanvas::setTemporalController( QgsTemporalNavigationObject *controller ) +void QgsMapCanvas::setTemporalController( QgsTemporalController *controller ) { mController = controller; - connect( mController, &QgsTemporalNavigationObject::updateTemporalRange, this, &QgsMapCanvas::setTemporalRange ); + connect( mController, &QgsTemporalController::updateTemporalRange, this, &QgsMapCanvas::setTemporalRange ); } void QgsMapCanvas::setMapSettingsFlags( QgsMapSettings::Flags flags ) @@ -2472,12 +2473,6 @@ const QgsLabelingEngineSettings &QgsMapCanvas::labelingEngineSettings() const return mSettings.labelingEngineSettings(); } -void QgsMapCanvas::updateTemporalRange( const QgsDateTimeRange &range ) -{ - mSettings.setTemporalRange( range ); - autoRefreshTriggered(); -} - void QgsMapCanvas::startPreviewJobs() { stopPreviewJobs(); //just in case still running diff --git a/src/gui/qgsmapcanvas.h b/src/gui/qgsmapcanvas.h index 18b83b0749dc..8df22fb32af2 100644 --- a/src/gui/qgsmapcanvas.h +++ b/src/gui/qgsmapcanvas.h @@ -27,7 +27,6 @@ #include "qgsgeometry.h" #include "qgscustomdrophandler.h" #include "qgstemporalrangeobject.h" -#include "qgstemporalnavigationobject.h" #include #include @@ -69,6 +68,8 @@ class QgsRubberBand; class QgsMapCanvasAnnotationItem; class QgsReferencedRectangle; +class QgsTemporalController; + /** * \ingroup gui * Map canvas is a class for displaying all GIS data types on a canvas. @@ -130,7 +131,7 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView * * \since QGIS 3.14 */ - void setTemporalController( QgsTemporalNavigationObject *controller ); + void setTemporalController( QgsTemporalController *controller ); /** * sets destination coordinate reference system @@ -1010,8 +1011,6 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView void startPreviewJob( int number ); - void updateTemporalRange( const QgsDateTimeRange &range ); - private: //! encompases all map settings necessary for map rendering @@ -1024,7 +1023,7 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView * Temporal controller for tracking update of temporal objects * which relates with canvas */ - QgsTemporalNavigationObject *mController = nullptr; + QgsTemporalController *mController = nullptr; //! Flag indicating if the map canvas is frozen. bool mFrozen = false; diff --git a/src/gui/qgstemporalcontrollerdockwidget.cpp b/src/gui/qgstemporalcontrollerdockwidget.cpp index 7e473d33c42a..b3369d7be8c2 100644 --- a/src/gui/qgstemporalcontrollerdockwidget.cpp +++ b/src/gui/qgstemporalcontrollerdockwidget.cpp @@ -31,7 +31,6 @@ QgsTemporalControllerDockWidget::QgsTemporalControllerDockWidget( const QString setWindowTitle( name ); mNavigationObject = new QgsTemporalNavigationObject( this ); - settingsDialog(); connect( mForwardButton, &QPushButton::clicked, this, &QgsTemporalControllerDockWidget::forwardButton_clicked ); connect( mBackButton, &QPushButton::clicked, this, &QgsTemporalControllerDockWidget::backButton_clicked ); @@ -41,24 +40,18 @@ QgsTemporalControllerDockWidget::QgsTemporalControllerDockWidget( const QString connect( mStartDateTime, &QDateTimeEdit::dateTimeChanged, this, &QgsTemporalControllerDockWidget::updateTemporalExtent ); connect( mEndDateTime, &QDateTimeEdit::dateTimeChanged, this, &QgsTemporalControllerDockWidget::updateTemporalExtent ); - connect( mSpinBox, qgis::overload::of( &QSpinBox::valueChanged ), this, &QgsTemporalControllerDockWidget::updateFrameDuration ); + connect( mSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsTemporalControllerDockWidget::updateFrameDuration ); connect( mTimeStepsComboBox, qgis::overload::of( &QComboBox::currentIndexChanged ), this, &QgsTemporalControllerDockWidget::updateFrameDuration ); connect( mSlider, &QSlider::valueChanged, this, &QgsTemporalControllerDockWidget::timeSlider_valueChanged ); connect( mNavigationObject, &QgsTemporalNavigationObject::updateTemporalRange, this, &QgsTemporalControllerDockWidget::updateSlider ); - connect( mSettingsDialog->mapSettingsWidget(), &QgsTemporalMapSettingsWidget::frameRateChanged, this, &QgsTemporalControllerDockWidget::updateFrameRate ); - connect( mSettings, &QPushButton::clicked, this, &QgsTemporalControllerDockWidget::settings_clicked ); connect( mSetToProjectTimeButton, &QPushButton::clicked, this, &QgsTemporalControllerDockWidget::setDatesToProjectTime ); init(); } -QgsTemporalControllerDockWidget::~QgsTemporalControllerDockWidget() -{ -} - void QgsTemporalControllerDockWidget::init() { QgsDateTimeRange range; @@ -78,41 +71,37 @@ void QgsTemporalControllerDockWidget::init() mSetToProjectTimeButton->setToolTip( tr( "Set to project time" ) ); - QStringList listSteps = ( QStringList() << tr( "Seconds" ) << tr( "Minutes" ) << tr( "Hours" ) - << tr( "Days" ) << - tr( "Months" ) << ( "Years" ) ); + mTimeStepsComboBox->addItem( tr( "Seconds" ), QgsTemporalControllerDockWidget::Seconds ); + mTimeStepsComboBox->addItem( tr( "Minutes" ), QgsTemporalControllerDockWidget::Minutes ); + mTimeStepsComboBox->addItem( tr( "Hours" ), QgsTemporalControllerDockWidget::Hours ); + mTimeStepsComboBox->addItem( tr( "Days" ), QgsTemporalControllerDockWidget::Days ); + mTimeStepsComboBox->addItem( tr( "Months" ), QgsTemporalControllerDockWidget::Months ); + mTimeStepsComboBox->addItem( tr( "Years" ), QgsTemporalControllerDockWidget::Years ); - mTimeStepsComboBox->addItems( listSteps ); - mTimeStepsComboBox->setCurrentIndex( 2 ); + mTimeStepsComboBox->setCurrentIndex( mTimeStepsComboBox->findData( + QgsTemporalControllerDockWidget::Hours ) ); - mSpinBox->setMinimum( 1 ); + mSpinBox->setMinimum( 0.0000001 ); mSpinBox->setSingleStep( 1 ); mSpinBox->setValue( 1 ); mSpinBox->setEnabled( true ); - updateFrameRate(); updateTemporalExtent(); updateFrameDuration(); } -void QgsTemporalControllerDockWidget::updateFrameRate() -{ - if ( mSettingsDialog && mSettingsDialog->mapSettingsWidget() ) - mNavigationObject->setFramesPerSeconds( - mSettingsDialog->mapSettingsWidget()->frameRateValue() ); -} - void QgsTemporalControllerDockWidget::updateTemporalExtent() { - QgsDateTimeRange temporaExtent = QgsDateTimeRange( mStartDateTime->dateTime(), - mEndDateTime->dateTime() ); - mNavigationObject->setTemporalExtents( temporaExtent ); + QgsDateTimeRange temporalExtent = QgsDateTimeRange( mStartDateTime->dateTime(), + mEndDateTime->dateTime() ); + mNavigationObject->setTemporalExtents( temporalExtent ); mSlider->setRange( 0, mNavigationObject->totalFrameCount() - 1 ); + mSlider->setValue( 0 ); } void QgsTemporalControllerDockWidget::updateFrameDuration() { - mNavigationObject->setFrameDuration( interval( mTimeStepsComboBox->currentText(), + mNavigationObject->setFrameDuration( interval( mTimeStepsComboBox->currentData().toInt(), mSpinBox->value() ) ); mSlider->setRange( 0, mNavigationObject->totalFrameCount() - 1 ); } @@ -131,19 +120,23 @@ void QgsTemporalControllerDockWidget::updateRangeLabel( const QgsDateTimeRange & range.end().toString( locale.dateTimeFormat() ) ) ); } -QgsTemporalNavigationObject *QgsTemporalControllerDockWidget::temporalController() +QgsTemporalController *QgsTemporalControllerDockWidget::temporalController() { return mNavigationObject; } -void QgsTemporalControllerDockWidget::settingsDialog() -{ - mSettingsDialog = new QgsTemporalMapSettingsDialog( this ); -} - void QgsTemporalControllerDockWidget::settings_clicked() { - mSettingsDialog->setVisible( !mSettingsDialog->isVisible() ); + + QgsTemporalMapSettingsDialog *dialog = new QgsTemporalMapSettingsDialog( this ); + dialog->setAttribute( Qt::WA_DeleteOnClose ); + dialog->setVisible( true ); + + connect( dialog->mapSettingsWidget(), &QgsTemporalMapSettingsWidget::frameRateChanged, this, [ this, dialog ]() + { + mNavigationObject->setFramesPerSeconds( dialog->mapSettingsWidget()->frameRateValue() ); + mSlider->setValue( 0 ); + } ); } void QgsTemporalControllerDockWidget::timeSlider_valueChanged( int value ) @@ -151,31 +144,31 @@ void QgsTemporalControllerDockWidget::timeSlider_valueChanged( int value ) mNavigationObject->setCurrentFrameNumber( value ); } -QgsInterval QgsTemporalControllerDockWidget::interval( QString time, int value ) +QgsInterval QgsTemporalControllerDockWidget::interval( int time, double value ) { QgsInterval interval; - if ( time == QString( "Seconds" ) ) + if ( time == QgsTemporalControllerDockWidget::Seconds ) { interval.setSeconds( value ); } - if ( time == QString( "Minutes" ) ) + if ( time == QgsTemporalControllerDockWidget::Minutes ) { interval.setMinutes( value ); } - if ( time == QString( "Hours" ) ) + if ( time == QgsTemporalControllerDockWidget::Hours ) { interval.setHours( value ); } - if ( time == QString( "Days" ) ) + if ( time == QgsTemporalControllerDockWidget::Days ) { interval.setDays( value ); } - if ( time == QString( "Months" ) ) + if ( time == QgsTemporalControllerDockWidget::Months ) { interval.setMonths( value ); } - if ( time == QString( "Years" ) ) + if ( time == QgsTemporalControllerDockWidget::Years ) { interval.setYears( value ); } diff --git a/src/gui/qgstemporalcontrollerdockwidget.h b/src/gui/qgstemporalcontrollerdockwidget.h index 67fdd33768c1..b9c6277bbd1a 100644 --- a/src/gui/qgstemporalcontrollerdockwidget.h +++ b/src/gui/qgstemporalcontrollerdockwidget.h @@ -29,6 +29,7 @@ class QgsMapLayer; class QgsTemporalNavigationObject; class QgsTemporalMapSettingsWidget; class QgsTemporalMapSettingsDialog; +class QgsTemporalController; /** * \ingroup gui @@ -47,12 +48,23 @@ class GUI_EXPORT QgsTemporalControllerDockWidget : public QgsDockWidget, private */ QgsTemporalControllerDockWidget( const QString &name, QWidget *parent = nullptr ); - ~QgsTemporalControllerDockWidget() override; + ~QgsTemporalControllerDockWidget() = default; /** * Returns the temporal controller object used by this object in navigation. */ - QgsTemporalNavigationObject *temporalController(); + QgsTemporalController *temporalController(); + + //! Stores the used time unit in the animation frame duration. + enum TimeUnit + { + Seconds = 0, //! For seconds + Minutes = 1, //! For minutes + Hours = 2, //! For hours + Days = 3, //! For days + Months = 4, //! For months + Years = 5 //! For years + }; private: @@ -71,23 +83,15 @@ class GUI_EXPORT QgsTemporalControllerDockWidget : public QgsDockWidget, private **/ void setDateInputsEnable( bool enabled ); - /** - * Sets the controller settings dialog - **/ - void settingsDialog(); - /** * Returns the time interval using the passed \a value and \a time * to determine the interval duration. */ - QgsInterval interval( QString time, int value ); + QgsInterval interval( int time, double value ); //! Handles all non gui navigation logic QgsTemporalNavigationObject *mNavigationObject = nullptr; - //! Dialog for temporal map settings - QgsTemporalMapSettingsDialog *mSettingsDialog = nullptr; - private slots: /** @@ -146,11 +150,6 @@ class GUI_EXPORT QgsTemporalControllerDockWidget : public QgsDockWidget, private **/ void updateRangeLabel( const QgsDateTimeRange &range ); - /** - * Updates the frames per seconds value for the navigation object. - **/ - void updateFrameRate(); - /** * Updates the navigation temporal extent. **/ diff --git a/src/gui/qgstemporalmapsettingsdialog.cpp b/src/gui/qgstemporalmapsettingsdialog.cpp index 4e8e7e8082a4..cf860d48cd0e 100644 --- a/src/gui/qgstemporalmapsettingsdialog.cpp +++ b/src/gui/qgstemporalmapsettingsdialog.cpp @@ -30,12 +30,9 @@ QgsTemporalMapSettingsDialog::QgsTemporalMapSettingsDialog( QWidget *parent, Qt: QVBoxLayout *layout = new QVBoxLayout(); mTemporalMapSettingsWidget = new QgsTemporalMapSettingsWidget( this ); layout->addWidget( mTemporalMapSettingsWidget ); - setLayout( layout ); setWindowTitle( tr( "Temporal Map Settings" ) ); mTemporalMapSettingsWidget->setFrameRateValue( 1 ); - - hide(); } void QgsTemporalMapSettingsDialog::apply() diff --git a/src/gui/qgstemporalmapsettingswidget.cpp b/src/gui/qgstemporalmapsettingswidget.cpp index 336e470d17f0..7504e24a2bf2 100644 --- a/src/gui/qgstemporalmapsettingswidget.cpp +++ b/src/gui/qgstemporalmapsettingswidget.cpp @@ -27,10 +27,6 @@ QgsTemporalMapSettingsWidget::QgsTemporalMapSettingsWidget( QWidget *parent ) connect( mFrameSpinBox, qgis::overload::of( &QDoubleSpinBox::valueChanged ), this, &QgsTemporalMapSettingsWidget::frameRateChange ); } -QgsTemporalMapSettingsWidget::~QgsTemporalMapSettingsWidget() -{ -} - double QgsTemporalMapSettingsWidget::frameRateValue() { return mFrameSpinBox->value(); diff --git a/src/gui/qgstemporalmapsettingswidget.h b/src/gui/qgstemporalmapsettingswidget.h index 94d32a412def..eba4278c10af 100644 --- a/src/gui/qgstemporalmapsettingswidget.h +++ b/src/gui/qgstemporalmapsettingswidget.h @@ -40,7 +40,7 @@ class GUI_EXPORT QgsTemporalMapSettingsWidget : public QWidget, private Ui::QgsT */ QgsTemporalMapSettingsWidget( QWidget *parent = nullptr ); - ~QgsTemporalMapSettingsWidget() override; + ~QgsTemporalMapSettingsWidget() = default; /** * Returns the value of frame rate from widget input diff --git a/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp b/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp index a34b6ea85e5b..7b5a8fe2e599 100644 --- a/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp +++ b/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp @@ -40,6 +40,19 @@ void QgsRasterLayerTemporalPropertiesWidget::init() setDateTimeInputsLimit(); setDateTimeInputsLocale(); + mFetchModeComboBox->addItem( tr( "Earliest" ), QgsRasterLayerTemporalProperties::Earliest ); + mFetchModeComboBox->addItem( tr( "Latest" ), QgsRasterLayerTemporalProperties::Latest ); + mFetchModeComboBox->addItem( tr( "Range" ), QgsRasterLayerTemporalProperties::Range ); + + QgsRasterLayerTemporalProperties *temporalProperties = qobject_cast( + mLayer->temporalProperties() ); + if ( temporalProperties ) + mFetchModeComboBox->setCurrentIndex( mFetchModeComboBox->findData( + temporalProperties->fetchMode() ) ); + else + mFetchModeComboBox->setCurrentIndex( mFetchModeComboBox->findData( + QgsRasterLayerTemporalProperties::Earliest ) ); + updateRangeLabel( mRangeLabel ); } @@ -58,7 +71,8 @@ void QgsRasterLayerTemporalPropertiesWidget::setInputWidgetState( TemporalDimens mSetEndAsStartReferenceButton->setEnabled( enabled ); } - if ( mSource == TemporalRangeSource::Project ) + if ( mLayer->temporalProperties()->temporalSource() == + QgsMapLayerTemporalProperties::TemporalSource::Project ) mProjectRadioButton->setChecked( true ); } @@ -133,7 +147,8 @@ void QgsRasterLayerTemporalPropertiesWidget::setDateTimeInputsLimit() void QgsRasterLayerTemporalPropertiesWidget::updateRangeLabel( QLabel *label ) { QLocale locale; - if ( mSource == TemporalRangeSource::Layer ) + if ( mLayer->temporalProperties()->temporalSource() == + QgsMapLayerTemporalProperties::TemporalSource::Layer ) { if ( mLayer->type() == QgsMapLayerType::RasterLayer ) { @@ -148,7 +163,8 @@ void QgsRasterLayerTemporalPropertiesWidget::updateRangeLabel( QLabel *label ) label->setText( tr( "Layer temporal range is not set" ) ); } } - else if ( mSource == TemporalRangeSource::Project ) + else if ( mLayer->temporalProperties()->temporalSource() == + QgsMapLayerTemporalProperties::TemporalSource::Project ) { QgsDateTimeRange range = QgsProject::instance()->timeSettings()->temporalRange(); @@ -161,12 +177,9 @@ void QgsRasterLayerTemporalPropertiesWidget::updateRangeLabel( QLabel *label ) } } - void QgsRasterLayerTemporalPropertiesWidget::setEndAsStartNormalButton_clicked() { mEndTemporalDateTimeEdit->setDateTime( mStartTemporalDateTimeEdit->dateTime() ); - // Update current selection label - setTemporalRangeSource( TemporalRangeSource::Layer ); updateRangeLabel( mRangeLabel ); } @@ -177,26 +190,20 @@ void QgsRasterLayerTemporalPropertiesWidget::setEndAsStartReferenceButton_clicke void QgsRasterLayerTemporalPropertiesWidget::layerRadioButton_clicked() { - if ( mLayerRadioButton->isChecked() ) - { - setInputWidgetState( TemporalDimension::NormalTemporal, true ); - setTemporalRangeSource( TemporalRangeSource::Layer ); - updateRangeLabel( mRangeLabel ); - mProjectRadioButton->setChecked( false ); - } - else - setInputWidgetState( TemporalDimension::NormalTemporal, false ); + setInputWidgetState( TemporalDimension::NormalTemporal, true ); + mLayer->temporalProperties()->setTemporalSource( + QgsMapLayerTemporalProperties::TemporalSource::Layer ); + updateRangeLabel( mRangeLabel ); + mLayerRadioButton->setChecked( true ); + mProjectRadioButton->setChecked( false ); } void QgsRasterLayerTemporalPropertiesWidget::projectRadioButton_clicked() { - if ( mProjectRadioButton->isChecked() ) - { - mLayerRadioButton->setChecked( false ); - setInputWidgetState( TemporalDimension::NormalTemporal, false ); - setTemporalRangeSource( TemporalRangeSource::Project ); - updateRangeLabel( mRangeLabel ); - } + setInputWidgetState( TemporalDimension::NormalTemporal, false ); + mLayer->temporalProperties()->setTemporalSource( + QgsMapLayerTemporalProperties::TemporalSource::Project ); + updateRangeLabel( mRangeLabel ); } void QgsRasterLayerTemporalPropertiesWidget::referenceCheckBox_clicked() @@ -207,8 +214,6 @@ void QgsRasterLayerTemporalPropertiesWidget::referenceCheckBox_clicked() setInputWidgetState( TemporalDimension::BiTemporal, false ); } - - void QgsRasterLayerTemporalPropertiesWidget::saveTemporalProperties() { if ( mLayerRadioButton->isChecked() ) @@ -224,6 +229,9 @@ void QgsRasterLayerTemporalPropertiesWidget::saveTemporalProperties() rasterLayer->temporalProperties()->setTemporalRange( normalRange ); rasterLayer->temporalProperties()->setTemporalSource( QgsMapLayerTemporalProperties::TemporalSource::Layer ); + int fetchModeIndex = mFetchModeComboBox->currentData().toInt(); + rasterLayer->temporalProperties()->setFetchMode( + rasterLayer->temporalProperties()->indexToFetchMode( fetchModeIndex ) ); if ( mReferenceCheckBox->isChecked() ) { @@ -253,6 +261,10 @@ void QgsRasterLayerTemporalPropertiesWidget::saveTemporalProperties() rasterLayer->temporalProperties()->setTemporalRange( projectRange ); rasterLayer->temporalProperties()->setTemporalSource( QgsMapLayerTemporalProperties::TemporalSource::Project ); + int fetchModeIndex = mFetchModeComboBox->currentData().toInt(); + rasterLayer->temporalProperties()->setFetchMode( + rasterLayer->temporalProperties()->indexToFetchMode( fetchModeIndex ) ); + if ( mReferenceCheckBox->isChecked() ) { QgsDateTimeRange referenceRange = QgsDateTimeRange( mStartReferenceDateTimeEdit->dateTime(), @@ -263,15 +275,3 @@ void QgsRasterLayerTemporalPropertiesWidget::saveTemporalProperties() } } } - -void QgsRasterLayerTemporalPropertiesWidget::setTemporalRangeSource( QgsRasterLayerTemporalPropertiesWidget::TemporalRangeSource source ) -{ - if ( mSource == source ) - return; - mSource = source; -} - -QgsRasterLayerTemporalPropertiesWidget::TemporalRangeSource QgsRasterLayerTemporalPropertiesWidget::temporalRangeSource() const -{ - return mSource; -} diff --git a/src/gui/raster/qgsrasterlayertemporalpropertieswidget.h b/src/gui/raster/qgsrasterlayertemporalpropertieswidget.h index 224574c257e6..90fc233e4f28 100644 --- a/src/gui/raster/qgsrasterlayertemporalpropertieswidget.h +++ b/src/gui/raster/qgsrasterlayertemporalpropertieswidget.h @@ -73,33 +73,6 @@ class GUI_EXPORT QgsRasterLayerTemporalPropertiesWidget : public QWidget, privat BiTemporal }; - /** - * Source where the temporal range will be taken from to update the layers - * temporal range. - */ - enum TemporalRangeSource - { - Layer, //! When current temporal range is from layer properties. - Project //! Using Project time settings temporal range - }; - - /** - * Sets the properties temporal range input source, it can be from layer or project. - * - * \see temporalRangeSource() - */ - void setTemporalRangeSource( TemporalRangeSource source ); - - /** - * Returns the temporal range source. - * - * \see setTemporalRangeSource() - */ - TemporalRangeSource temporalRangeSource() const; - - - TemporalRangeSource mSource = Layer; - private slots: /** diff --git a/src/providers/wms/qgswmsprovider.cpp b/src/providers/wms/qgswmsprovider.cpp index 7a497b3b33dc..6e85e7b8afe5 100644 --- a/src/providers/wms/qgswmsprovider.cpp +++ b/src/providers/wms/qgswmsprovider.cpp @@ -158,6 +158,11 @@ QgsWmsProvider::QgsWmsProvider( QString const &uri, const ProviderOptions &optio temporalCapabilities()->setHasTemporalCapabilities( true ); temporalCapabilities()->setFixedTemporalRange( mSettings.mFixedRange ); + temporalCapabilities()->setMode( + QgsRasterDataProviderTemporalCapabilities::ModeTemporalRangeFromDataProvider ); + temporalCapabilities()->setFetchMode( + QgsRasterDataProviderTemporalCapabilities::Earliest ); + if ( mSettings.mIsBiTemporal ) { temporalCapabilities()->setFixedReferenceTemporalRange( mSettings.mFixedReferenceRange ); @@ -1082,6 +1087,11 @@ void QgsWmsProvider::addWmstParameters( QUrlQuery &query ) QgsDateTimeRange range = temporalCapabilities()->requestedTemporalRange(); QString format = "yyyy-MM-ddThh:mm:ssZ"; + if ( temporalCapabilities()->fetchMode() == QgsRasterDataProviderTemporalCapabilities::Earliest ) + range = QgsDateTimeRange( range.begin(), range.begin() ); + else if ( temporalCapabilities()->fetchMode() == QgsRasterDataProviderTemporalCapabilities::Latest ) + range = QgsDateTimeRange( range.end(), range.end() ); + if ( !temporalCapabilities()->isTimeEnabled() ) format = "yyyy-MM-dd"; diff --git a/src/ui/qgsprojectpropertiesbase.ui b/src/ui/qgsprojectpropertiesbase.ui index b6842d5aa901..6f58008867e9 100644 --- a/src/ui/qgsprojectpropertiesbase.ui +++ b/src/ui/qgsprojectpropertiesbase.ui @@ -2905,6 +2905,9 @@ M/d/yyyy h:mm AP + + Qt::UTC + @@ -2919,6 +2922,9 @@ M/d/yyyy h:mm AP + + Qt::UTC + @@ -3007,6 +3013,11 @@
qgsscrollarea.h
1 + + QgsDateTimeEdit + QDateTimeEdit +
qgsdatetimeedit.h
+
QgsColorButton QToolButton @@ -3024,11 +3035,6 @@
qgsopacitywidget.h
1
- - QgsDateTimeEdit - QDateTimeEdit -
qgsdatetimeedit.h
-
QgsColorSchemeList QWidget diff --git a/src/ui/qgstemporalcontrollerdockwidgetbase.ui b/src/ui/qgstemporalcontrollerdockwidgetbase.ui index ef5c3208ad7b..d1b490cb087d 100644 --- a/src/ui/qgstemporalcontrollerdockwidgetbase.ui +++ b/src/ui/qgstemporalcontrollerdockwidgetbase.ui @@ -115,7 +115,7 @@
- + @@ -139,6 +139,9 @@ M/d/yyyy h:mm AP + + Qt::UTC + @@ -153,6 +156,9 @@ M/d/yyyy h:mm AP + + Qt::UTC + diff --git a/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui b/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui index c9d24f6e09e8..7de305880a3e 100644 --- a/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui +++ b/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui @@ -104,7 +104,7 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti M/d/yyyy h:mm AP - Qt::LocalTime + Qt::UTC @@ -127,6 +127,9 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti M/d/yyyy h:mm AP + + Qt::UTC + @@ -138,6 +141,33 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti + + + + Fetch mode + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -309,4 +339,4 @@ p, li { white-space: pre-wrap; } - \ No newline at end of file + diff --git a/tests/src/app/testqgsprojectproperties.cpp b/tests/src/app/testqgsprojectproperties.cpp index 162f5dbf3b31..9ffc9fb5b50b 100644 --- a/tests/src/app/testqgsprojectproperties.cpp +++ b/tests/src/app/testqgsprojectproperties.cpp @@ -256,15 +256,15 @@ void TestQgsProjectProperties::testBearingFormat() void TestQgsProjectProperties::testTimeSettings() { QgsProject::instance()->clear(); - QgsDateTimeRange range = QgsDateTimeRange( QDateTime( QDate( 2020, 1, 1 ) ), - QDateTime( QDate( 2020, 12, 31 ) ) ); + QgsDateTimeRange range = QgsDateTimeRange( QDateTime( QDate( 2020, 1, 1 ), QTime(), Qt::UTC ), + QDateTime( QDate( 2020, 12, 31 ), QTime(), Qt::UTC ) ); QgsProject::instance()->timeSettings()->setTemporalRange( range ); + QgsDateTimeRange projectRange = QgsProject::instance()->timeSettings()->temporalRange(); std::unique_ptr< QgsProjectProperties > projectProperties = qgis::make_unique< QgsProjectProperties >( mQgisApp->mapCanvas() ); - projectProperties->apply(); - QCOMPARE( QgsProject::instance()->timeSettings()->temporalRange(), range ); + QCOMPARE( projectRange, range ); // Test setting Project temporal range using temporal layers @@ -272,12 +272,12 @@ void TestQgsProjectProperties::testTimeSettings() QgsRasterLayer *secondLayer = new QgsRasterLayer( "", "secondLayer", "wms" ); QgsRasterLayer *thirdLayer = new QgsRasterLayer( "", "thirdLayer", "wms" ); - QgsDateTimeRange firstRange = QgsDateTimeRange( QDateTime( QDate( 2020, 1, 1 ) ), - QDateTime( QDate( 2020, 3, 31 ) ) ); - QgsDateTimeRange secondRange = QgsDateTimeRange( QDateTime( QDate( 2020, 4, 1 ) ), - QDateTime( QDate( 2020, 7, 31 ) ) ); - QgsDateTimeRange thirdRange = QgsDateTimeRange( QDateTime( QDate( 2019, 1, 1 ) ), - QDateTime( QDate( 2020, 2, 28 ) ) ); + QgsDateTimeRange firstRange = QgsDateTimeRange( QDateTime( QDate( 2020, 1, 1 ), QTime(), Qt::UTC ), + QDateTime( QDate( 2020, 3, 31 ), QTime(), Qt::UTC ) ); + QgsDateTimeRange secondRange = QgsDateTimeRange( QDateTime( QDate( 2020, 4, 1 ), QTime(), Qt::UTC ), + QDateTime( QDate( 2020, 7, 31 ), QTime(), Qt::UTC ) ); + QgsDateTimeRange thirdRange = QgsDateTimeRange( QDateTime( QDate( 2019, 1, 1 ), QTime(), Qt::UTC ), + QDateTime( QDate( 2020, 2, 28 ), QTime(), Qt::UTC ) ); firstLayer->temporalProperties()->setTemporalRange( firstRange ); secondLayer->temporalProperties()->setTemporalRange( secondRange ); @@ -289,9 +289,9 @@ void TestQgsProjectProperties::testTimeSettings() projectProperties->apply(); QgsDateTimeRange expectedRange = QgsDateTimeRange( thirdRange.begin(), secondRange.end() ); + QgsDateTimeRange secondProjectRange = QgsProject::instance()->timeSettings()->temporalRange(); - QCOMPARE( QgsProject::instance()->timeSettings()->temporalRange(), expectedRange ); - + QCOMPARE( secondProjectRange, expectedRange ); } QGSTEST_MAIN( TestQgsProjectProperties )