From 8c4914db35f52c60ec17c71c254264e5fb84dbe6 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Wed, 3 Apr 2024 20:26:44 +0700 Subject: [PATCH 1/6] [raster][temporal] Add a brand new temporal mode: pixel value as temporal datetime --- python/PyQt6/core/auto_additions/qgis.py | 5 +- python/PyQt6/core/auto_generated/qgis.sip.in | 1 + .../qgsrasterlayertemporalproperties.sip.in | 124 ++++++++++++++++++ python/core/auto_additions/qgis.py | 5 +- python/core/auto_generated/qgis.sip.in | 1 + .../qgsrasterlayertemporalproperties.sip.in | 124 ++++++++++++++++++ src/core/qgis.h | 1 + src/core/raster/qgsrasterlayerrenderer.cpp | 25 ++++ .../qgsrasterlayertemporalproperties.cpp | 80 +++++++++++ .../raster/qgsrasterlayertemporalproperties.h | 89 +++++++++++++ src/core/raster/qgsrasterlayerutils.cpp | 21 ++- ...qgsrasterlayertemporalpropertieswidget.cpp | 43 ++++++ ...rasterlayertemporalpropertieswidgetbase.ui | 108 +++++++++++++++ .../test_qgsrasterlayertemporalproperties.py | 39 ++++++ 14 files changed, 662 insertions(+), 4 deletions(-) diff --git a/python/PyQt6/core/auto_additions/qgis.py b/python/PyQt6/core/auto_additions/qgis.py index 02cb7d44a228..b5c63e785fd6 100644 --- a/python/PyQt6/core/auto_additions/qgis.py +++ b/python/PyQt6/core/auto_additions/qgis.py @@ -2116,7 +2116,10 @@ QgsRasterLayerTemporalProperties.FixedRangePerBand = Qgis.RasterTemporalMode.FixedRangePerBand QgsRasterLayerTemporalProperties.FixedRangePerBand.is_monkey_patched = True QgsRasterLayerTemporalProperties.FixedRangePerBand.__doc__ = "Layer has a fixed temporal range per band (since QGIS 3.38)" -Qgis.RasterTemporalMode.__doc__ = "Raster layer temporal modes\n\n.. versionadded:: 3.22\n\n" + '* ``ModeFixedTemporalRange``: ' + Qgis.RasterTemporalMode.FixedTemporalRange.__doc__ + '\n' + '* ``ModeTemporalRangeFromDataProvider``: ' + Qgis.RasterTemporalMode.TemporalRangeFromDataProvider.__doc__ + '\n' + '* ``ModeRedrawLayerOnly``: ' + Qgis.RasterTemporalMode.RedrawLayerOnly.__doc__ + '\n' + '* ``FixedRangePerBand``: ' + Qgis.RasterTemporalMode.FixedRangePerBand.__doc__ +QgsRasterLayerTemporalProperties.RepresentsTemporalValues = Qgis.RasterTemporalMode.RepresentsTemporalValues +QgsRasterLayerTemporalProperties.RepresentsTemporalValues.is_monkey_patched = True +QgsRasterLayerTemporalProperties.RepresentsTemporalValues.__doc__ = "Pixel values represent an datetime" +Qgis.RasterTemporalMode.__doc__ = "Raster layer temporal modes\n\n.. versionadded:: 3.22\n\n" + '* ``ModeFixedTemporalRange``: ' + Qgis.RasterTemporalMode.FixedTemporalRange.__doc__ + '\n' + '* ``ModeTemporalRangeFromDataProvider``: ' + Qgis.RasterTemporalMode.TemporalRangeFromDataProvider.__doc__ + '\n' + '* ``ModeRedrawLayerOnly``: ' + Qgis.RasterTemporalMode.RedrawLayerOnly.__doc__ + '\n' + '* ``FixedRangePerBand``: ' + Qgis.RasterTemporalMode.FixedRangePerBand.__doc__ + '\n' + '* ``RepresentsTemporalValues``: ' + Qgis.RasterTemporalMode.RepresentsTemporalValues.__doc__ # -- Qgis.RasterTemporalMode.baseClass = Qgis QgsRasterDataProviderTemporalCapabilities.IntervalHandlingMethod = Qgis.TemporalIntervalMatchMethod diff --git a/python/PyQt6/core/auto_generated/qgis.sip.in b/python/PyQt6/core/auto_generated/qgis.sip.in index 38b07fa1399c..5b9871da60e9 100644 --- a/python/PyQt6/core/auto_generated/qgis.sip.in +++ b/python/PyQt6/core/auto_generated/qgis.sip.in @@ -1258,6 +1258,7 @@ The development version TemporalRangeFromDataProvider, RedrawLayerOnly, FixedRangePerBand, + RepresentsTemporalValues, }; enum class TemporalIntervalMatchMethod /BaseType=IntEnum/ diff --git a/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 62d35f120e7b..65e50c481bb0 100644 --- a/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -139,6 +139,130 @@ Returns the band corresponding to the specified ``range``. %Docstring Returns a filtered list of bands which match the specified ``range``. +.. versionadded:: 3.38 +%End + + int temporalRepresentationBandNumber() const; +%Docstring +Returns the band number from which the temporal values should be taken. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`setTemporalRepresentationBandNumber` + +.. versionadded:: 3.38 +%End + + void setTemporalRepresentationBandNumber( int number ); +%Docstring +Sets the band number from which the temporal values should be taken. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`temporalRepresentationBandNumber` + +.. versionadded:: 3.38 +%End + + QDateTime temporalRepresentationOffset() const; +%Docstring +Returns the temporal offset, which is a fixed datetime which should be added to individual pixel values +from the layer. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`setTemporalRepresentationOffset` + +.. versionadded:: 3.38 +%End + + void setTemporalRepresentationOffset( const QDateTime &offset ); +%Docstring +Sets the temporal offset, which is a fixed datetime which should be added to individual pixel values +from the layer. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`temporalRepresentationOffset` + +.. versionadded:: 3.38 +%End + + double temporalRepresentationScale() const; +%Docstring +Returns the scale, which is a duration factor which should be applied to individual pixel +values from the layer. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`setTemporalRepresentationScale` + +.. seealso:: :py:func:`temporalRepresentationScaleUnit` + +.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` + +.. versionadded:: 3.38 +%End + + void setTemporalRepresentationScale( double scale ); +%Docstring +Sets the scale, which is a duration factor which should be applied to individual pixel +values from the layer. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`temporalRepresentationScale` + +.. seealso:: :py:func:`temporalRepresentationScaleUnit` + +.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` + +.. versionadded:: 3.38 +%End + + Qgis::TemporalUnit temporalRepresentationScaleUnit() const; +%Docstring +Returns the scale's temporal unit type. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` + +.. seealso:: :py:func:`temporalRepresentationScale` + +.. seealso:: :py:func:`setTemporalRepresentationScale` + +.. versionadded:: 3.38 +%End + + void setTemporalRepresentationScaleUnit( Qgis::TemporalUnit unit ); +%Docstring +Sets the scale's temporal unit type. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`temporalRepresentationScaleUnit` + +.. seealso:: :py:func:`temporalRepresentationScale` + +.. seealso:: :py:func:`setTemporalRepresentationScale` + .. versionadded:: 3.38 %End diff --git a/python/core/auto_additions/qgis.py b/python/core/auto_additions/qgis.py index 4918dd1f3f26..5a2b2539999a 100644 --- a/python/core/auto_additions/qgis.py +++ b/python/core/auto_additions/qgis.py @@ -2077,7 +2077,10 @@ QgsRasterLayerTemporalProperties.FixedRangePerBand = Qgis.RasterTemporalMode.FixedRangePerBand QgsRasterLayerTemporalProperties.FixedRangePerBand.is_monkey_patched = True QgsRasterLayerTemporalProperties.FixedRangePerBand.__doc__ = "Layer has a fixed temporal range per band (since QGIS 3.38)" -Qgis.RasterTemporalMode.__doc__ = "Raster layer temporal modes\n\n.. versionadded:: 3.22\n\n" + '* ``ModeFixedTemporalRange``: ' + Qgis.RasterTemporalMode.FixedTemporalRange.__doc__ + '\n' + '* ``ModeTemporalRangeFromDataProvider``: ' + Qgis.RasterTemporalMode.TemporalRangeFromDataProvider.__doc__ + '\n' + '* ``ModeRedrawLayerOnly``: ' + Qgis.RasterTemporalMode.RedrawLayerOnly.__doc__ + '\n' + '* ``FixedRangePerBand``: ' + Qgis.RasterTemporalMode.FixedRangePerBand.__doc__ +QgsRasterLayerTemporalProperties.RepresentsTemporalValues = Qgis.RasterTemporalMode.RepresentsTemporalValues +QgsRasterLayerTemporalProperties.RepresentsTemporalValues.is_monkey_patched = True +QgsRasterLayerTemporalProperties.RepresentsTemporalValues.__doc__ = "Pixel values represent an datetime" +Qgis.RasterTemporalMode.__doc__ = "Raster layer temporal modes\n\n.. versionadded:: 3.22\n\n" + '* ``ModeFixedTemporalRange``: ' + Qgis.RasterTemporalMode.FixedTemporalRange.__doc__ + '\n' + '* ``ModeTemporalRangeFromDataProvider``: ' + Qgis.RasterTemporalMode.TemporalRangeFromDataProvider.__doc__ + '\n' + '* ``ModeRedrawLayerOnly``: ' + Qgis.RasterTemporalMode.RedrawLayerOnly.__doc__ + '\n' + '* ``FixedRangePerBand``: ' + Qgis.RasterTemporalMode.FixedRangePerBand.__doc__ + '\n' + '* ``RepresentsTemporalValues``: ' + Qgis.RasterTemporalMode.RepresentsTemporalValues.__doc__ # -- Qgis.RasterTemporalMode.baseClass = Qgis QgsRasterDataProviderTemporalCapabilities.IntervalHandlingMethod = Qgis.TemporalIntervalMatchMethod diff --git a/python/core/auto_generated/qgis.sip.in b/python/core/auto_generated/qgis.sip.in index 965636863fe2..6df2b9c00282 100644 --- a/python/core/auto_generated/qgis.sip.in +++ b/python/core/auto_generated/qgis.sip.in @@ -1258,6 +1258,7 @@ The development version TemporalRangeFromDataProvider, RedrawLayerOnly, FixedRangePerBand, + RepresentsTemporalValues, }; enum class TemporalIntervalMatchMethod diff --git a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 62d35f120e7b..65e50c481bb0 100644 --- a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -139,6 +139,130 @@ Returns the band corresponding to the specified ``range``. %Docstring Returns a filtered list of bands which match the specified ``range``. +.. versionadded:: 3.38 +%End + + int temporalRepresentationBandNumber() const; +%Docstring +Returns the band number from which the temporal values should be taken. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`setTemporalRepresentationBandNumber` + +.. versionadded:: 3.38 +%End + + void setTemporalRepresentationBandNumber( int number ); +%Docstring +Sets the band number from which the temporal values should be taken. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`temporalRepresentationBandNumber` + +.. versionadded:: 3.38 +%End + + QDateTime temporalRepresentationOffset() const; +%Docstring +Returns the temporal offset, which is a fixed datetime which should be added to individual pixel values +from the layer. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`setTemporalRepresentationOffset` + +.. versionadded:: 3.38 +%End + + void setTemporalRepresentationOffset( const QDateTime &offset ); +%Docstring +Sets the temporal offset, which is a fixed datetime which should be added to individual pixel values +from the layer. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`temporalRepresentationOffset` + +.. versionadded:: 3.38 +%End + + double temporalRepresentationScale() const; +%Docstring +Returns the scale, which is a duration factor which should be applied to individual pixel +values from the layer. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`setTemporalRepresentationScale` + +.. seealso:: :py:func:`temporalRepresentationScaleUnit` + +.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` + +.. versionadded:: 3.38 +%End + + void setTemporalRepresentationScale( double scale ); +%Docstring +Sets the scale, which is a duration factor which should be applied to individual pixel +values from the layer. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`temporalRepresentationScale` + +.. seealso:: :py:func:`temporalRepresentationScaleUnit` + +.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` + +.. versionadded:: 3.38 +%End + + Qgis::TemporalUnit temporalRepresentationScaleUnit() const; +%Docstring +Returns the scale's temporal unit type. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` + +.. seealso:: :py:func:`temporalRepresentationScale` + +.. seealso:: :py:func:`setTemporalRepresentationScale` + +.. versionadded:: 3.38 +%End + + void setTemporalRepresentationScaleUnit( Qgis::TemporalUnit unit ); +%Docstring +Sets the scale's temporal unit type. + +.. note:: + + This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. + +.. seealso:: :py:func:`temporalRepresentationScaleUnit` + +.. seealso:: :py:func:`temporalRepresentationScale` + +.. seealso:: :py:func:`setTemporalRepresentationScale` + .. versionadded:: 3.38 %End diff --git a/src/core/qgis.h b/src/core/qgis.h index 56a599e59dcb..c5b0d0eb0eee 100644 --- a/src/core/qgis.h +++ b/src/core/qgis.h @@ -2145,6 +2145,7 @@ class CORE_EXPORT Qgis TemporalRangeFromDataProvider SIP_MONKEYPATCH_COMPAT_NAME( ModeTemporalRangeFromDataProvider ) = 1, //!< Mode when raster layer delegates temporal range handling to the dataprovider. RedrawLayerOnly SIP_MONKEYPATCH_COMPAT_NAME( ModeRedrawLayerOnly ) = 2, //!< Redraw the layer when temporal range changes, but don't apply any filtering. Useful when raster symbology expressions depend on the time range. (since QGIS 3.22) FixedRangePerBand = 3, //!< Layer has a fixed temporal range per band (since QGIS 3.38) + RepresentsTemporalValues = 4, //!< Pixel values represent an datetime }; Q_ENUM( RasterTemporalMode ) diff --git a/src/core/raster/qgsrasterlayerrenderer.cpp b/src/core/raster/qgsrasterlayerrenderer.cpp index 472a457aaf8e..6ad73dac0663 100644 --- a/src/core/raster/qgsrasterlayerrenderer.cpp +++ b/src/core/raster/qgsrasterlayerrenderer.cpp @@ -35,6 +35,7 @@ #include "qgsapplication.h" #include "qgsrastertransparency.h" #include "qgsrasterlayerutils.h" +#include "qgsunittypes.h" #include #include @@ -301,6 +302,30 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender case Qgis::RasterTemporalMode::FixedRangePerBand: break; + case Qgis::RasterTemporalMode::RepresentsTemporalValues: + if ( mPipe->renderer()->usesBands().contains( temporalProperties->temporalRepresentationBandNumber() ) ) + { + // if layer has elevation settings and we are only rendering a temporal range => we need to filter pixels by temporal values + std::unique_ptr< QgsRasterTransparency > transparency; + if ( const QgsRasterTransparency *rendererTransparency = mPipe->renderer()->rasterTransparency() ) + transparency = std::make_unique< QgsRasterTransparency >( *rendererTransparency ); + else + transparency = std::make_unique< QgsRasterTransparency >(); + + QVector transparentPixels = transparency->transparentSingleValuePixelList(); + + const qint64 msecsLower = temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().begin() ); + const qint64 msecsUpper = temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().end() ); + const double adjustedLower = msecsLower * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, temporalProperties->temporalRepresentationScaleUnit() ) / temporalProperties->temporalRepresentationScale(); + const double adjustedUpper = msecsUpper * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, temporalProperties->temporalRepresentationScaleUnit() ) / temporalProperties->temporalRepresentationScale(); + transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( std::numeric_limits::lowest(), adjustedLower, 0, true, !rendererContext.zRange().includeLower() ) ); + transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( adjustedUpper, std::numeric_limits::max(), 0, !rendererContext.zRange().includeUpper(), true ) ); + + transparency->setTransparentSingleValuePixelList( transparentPixels ); + mPipe->renderer()->setRasterTransparency( transparency.release() ); + } + break; + case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider: // in this mode we need to pass on the desired render temporal range to the data provider if ( QgsRasterDataProviderTemporalCapabilities *temporalCapabilities = mPipe->provider()->temporalCapabilities() ) diff --git a/src/core/raster/qgsrasterlayertemporalproperties.cpp b/src/core/raster/qgsrasterlayertemporalproperties.cpp index 4cde844e5272..564c37cc4484 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.cpp +++ b/src/core/raster/qgsrasterlayertemporalproperties.cpp @@ -44,6 +44,7 @@ bool QgsRasterLayerTemporalProperties::isVisibleInTemporalRange( const QgsDateTi return false; } + case Qgis::RasterTemporalMode::RepresentsTemporalValues: case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider: case Qgis::RasterTemporalMode::RedrawLayerOnly: return true; @@ -95,6 +96,7 @@ QgsDateTimeRange QgsRasterLayerTemporalProperties::calculateTemporalExtent( QgsM return QgsDateTimeRange( begin, end, includeBeginning, includeEnd ); } + case Qgis::RasterTemporalMode::RepresentsTemporalValues: case Qgis::RasterTemporalMode::RedrawLayerOnly: break; } @@ -131,6 +133,7 @@ QList QgsRasterLayerTemporalProperties::allTemporalRanges( Qgs return ranges.empty() ? QList< QgsDateTimeRange > { rasterLayer->dataProvider()->temporalCapabilities()->availableTemporalRange() } : ranges; } + case Qgis::RasterTemporalMode::RepresentsTemporalValues: case Qgis::RasterTemporalMode::RedrawLayerOnly: break; } @@ -160,6 +163,7 @@ QgsTemporalProperty::Flags QgsRasterLayerTemporalProperties::flags() const case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider: case Qgis::RasterTemporalMode::RedrawLayerOnly: case Qgis::RasterTemporalMode::FixedRangePerBand: + case Qgis::RasterTemporalMode::RepresentsTemporalValues: return QgsTemporalProperty::Flags(); } BUILTIN_UNREACHABLE @@ -230,6 +234,9 @@ int QgsRasterLayerTemporalProperties::bandForTemporalRange( QgsRasterLayer *, co } return currentMatchingBand; } + + case Qgis::RasterTemporalMode::RepresentsTemporalValues: + return mTemporalRepresentationBandNumber; } BUILTIN_UNREACHABLE } @@ -265,10 +272,65 @@ QList QgsRasterLayerTemporalProperties::filteredBandsForTemporalRange( QgsR } return res; } + + case Qgis::RasterTemporalMode::RepresentsTemporalValues: + return QList() << mTemporalRepresentationBandNumber; } BUILTIN_UNREACHABLE } +int QgsRasterLayerTemporalProperties::temporalRepresentationBandNumber() const +{ + return mTemporalRepresentationBandNumber; +} + +void QgsRasterLayerTemporalProperties::setTemporalRepresentationBandNumber( int number ) +{ + if ( mTemporalRepresentationBandNumber == number ) + return; + + mTemporalRepresentationBandNumber = number; +} + +QDateTime QgsRasterLayerTemporalProperties::temporalRepresentationOffset() const +{ + return mTemporalRepresentationOffset; +} + +void QgsRasterLayerTemporalProperties::setTemporalRepresentationOffset( const QDateTime &offset ) +{ + if ( mTemporalRepresentationOffset == offset ) + return; + + mTemporalRepresentationOffset = offset; +} + +double QgsRasterLayerTemporalProperties::temporalRepresentationScale() const +{ + return mTemporalRepresentationScale; +} + +void QgsRasterLayerTemporalProperties::setTemporalRepresentationScale( double scale ) +{ + if ( mTemporalRepresentationScale == scale ) + return; + + mTemporalRepresentationScale = scale; +} + +Qgis::TemporalUnit QgsRasterLayerTemporalProperties::temporalRepresentationScaleUnit() const +{ + return mTemporalRepresentationScaleUnit; +} + +void QgsRasterLayerTemporalProperties::setTemporalRepresentationScaleUnit( Qgis::TemporalUnit unit ) +{ + if ( mTemporalRepresentationScaleUnit == unit ) + return; + + mTemporalRepresentationScaleUnit = unit; +} + bool QgsRasterLayerTemporalProperties::readXml( const QDomElement &element, const QgsReadWriteContext &context ) { Q_UNUSED( context ) @@ -316,6 +378,15 @@ bool QgsRasterLayerTemporalProperties::readXml( const QDomElement &element, cons break; } + case Qgis::RasterTemporalMode::RepresentsTemporalValues: + { + mTemporalRepresentationBandNumber = temporalNode.attribute( QStringLiteral( "temporalRepresentationBandNumber" ), QStringLiteral( "1" ) ).toInt(); + mTemporalRepresentationOffset = QDateTime::fromString( temporalNode.attribute( QStringLiteral( "temporalRepresentationOffset" ) ), Qt::ISODate ); + mTemporalRepresentationScale = temporalNode.attribute( QStringLiteral( "temporalRepresentationScale" ), QStringLiteral( "1" ) ).toDouble(); + mTemporalRepresentationScaleUnit = static_cast< Qgis::TemporalUnit >( temporalNode.attribute( QStringLiteral( "temporalRepresentationScaleUnit" ), QStringLiteral( "4" ) ).toInt() ); + break; + } + case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider: case Qgis::RasterTemporalMode::RedrawLayerOnly: break; @@ -373,6 +444,15 @@ QDomElement QgsRasterLayerTemporalProperties::writeXml( QDomElement &element, QD break; } + case Qgis::RasterTemporalMode::RepresentsTemporalValues: + { + temporalElement.setAttribute( QStringLiteral( "temporalRepresentationBandNumber" ), QString::number( mTemporalRepresentationBandNumber ) ); + temporalElement.setAttribute( QStringLiteral( "temporalRepresentationOffset" ), mTemporalRepresentationOffset.toString( Qt::ISODate ) ); + temporalElement.setAttribute( QStringLiteral( "temporalRepresentationScale" ), QString::number( mTemporalRepresentationScale ) ); + temporalElement.setAttribute( QStringLiteral( "temporalRepresentationScaleUnit" ), QString::number( static_cast< int >( mTemporalRepresentationScaleUnit ) ) ); + break; + } + case Qgis::RasterTemporalMode::RedrawLayerOnly: case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider: break; diff --git a/src/core/raster/qgsrasterlayertemporalproperties.h b/src/core/raster/qgsrasterlayertemporalproperties.h index aa2fabf15b92..b6aa967e37f2 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.h +++ b/src/core/raster/qgsrasterlayertemporalproperties.h @@ -144,6 +144,90 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP */ QList< int > filteredBandsForTemporalRange( QgsRasterLayer *layer, const QgsDateTimeRange &range ) const; + /** + * Returns the band number from which the temporal values should be taken. + * + * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. + * \see setTemporalRepresentationBandNumber() + * \since QGIS 3.38 + */ + int temporalRepresentationBandNumber() const; + + /** + * Sets the band number from which the temporal values should be taken. + * + * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. + * \see temporalRepresentationBandNumber() + * \since QGIS 3.38 + */ + void setTemporalRepresentationBandNumber( int number ); + + /** + * Returns the temporal offset, which is a fixed datetime which should be added to individual pixel values + * from the layer. + * + * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. + * \see setTemporalRepresentationOffset() + * \since QGIS 3.38 + */ + QDateTime temporalRepresentationOffset() const; + + /** + * Sets the temporal offset, which is a fixed datetime which should be added to individual pixel values + * from the layer. + * + * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. + * \see temporalRepresentationOffset() + * \since QGIS 3.38 + */ + void setTemporalRepresentationOffset( const QDateTime &offset ); + + /** + * Returns the scale, which is a duration factor which should be applied to individual pixel + * values from the layer. + * + * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. + * \see setTemporalRepresentationScale() + * \see temporalRepresentationScaleUnit() + * \see setTemporalRepresentationScaleUnit() + * \since QGIS 3.38 + */ + double temporalRepresentationScale() const; + + /** + * Sets the scale, which is a duration factor which should be applied to individual pixel + * values from the layer. + * + * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. + * \see temporalRepresentationScale() + * \see temporalRepresentationScaleUnit() + * \see setTemporalRepresentationScaleUnit() + * \since QGIS 3.38 + */ + void setTemporalRepresentationScale( double scale ); + + /** + * Returns the scale's temporal unit type. + * + * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. + * \see setTemporalRepresentationScaleUnit() + * \see temporalRepresentationScale() + * \see setTemporalRepresentationScale() + * \since QGIS 3.38 + */ + Qgis::TemporalUnit temporalRepresentationScaleUnit() const; + + /** + * Sets the scale's temporal unit type. + * + * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. + * \see temporalRepresentationScaleUnit() + * \see temporalRepresentationScale() + * \see setTemporalRepresentationScale() + * \since QGIS 3.38 + */ + void setTemporalRepresentationScaleUnit( Qgis::TemporalUnit unit ); + QDomElement writeXml( QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context ) override; bool readXml( const QDomElement &element, const QgsReadWriteContext &context ) override; @@ -162,6 +246,11 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP QgsDateTimeRange mFixedRange; QMap< int, QgsDateTimeRange > mRangePerBand; + + int mTemporalRepresentationBandNumber = 1; + QDateTime mTemporalRepresentationOffset; + double mTemporalRepresentationScale = 1.0; + Qgis::TemporalUnit mTemporalRepresentationScaleUnit = Qgis::TemporalUnit::Days; }; #endif // QGSRASTERLAYERTEMPORALPROPERTIES_H diff --git a/src/core/raster/qgsrasterlayerutils.cpp b/src/core/raster/qgsrasterlayerutils.cpp index 3dc8b536cc98..f5437c9fbc80 100644 --- a/src/core/raster/qgsrasterlayerutils.cpp +++ b/src/core/raster/qgsrasterlayerutils.cpp @@ -58,8 +58,25 @@ int QgsRasterLayerUtils::renderedBandForElevationAndTemporalRange( // both elevation and temporal properties enabled // first find bands matching the temporal range - const QList< int > temporalBands = temporalProperties->filteredBandsForTemporalRange( - layer, temporalRange ); + QList< int > temporalBands; + switch ( temporalProperties->mode() ) + { + case Qgis::RasterTemporalMode::RedrawLayerOnly: + case Qgis::RasterTemporalMode::TemporalRangeFromDataProvider: + case Qgis::RasterTemporalMode::FixedTemporalRange: + case Qgis::RasterTemporalMode::FixedRangePerBand: + { + temporalBands << temporalProperties->filteredBandsForTemporalRange( layer, temporalRange ); + break; + } + + case Qgis::RasterTemporalMode::RepresentsTemporalValues: + { + temporalBands << temporalProperties->temporalRepresentationBandNumber(); + break; + } + } + if ( temporalBands.empty() ) { matched = false; diff --git a/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp b/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp index 05f6ff1b006f..f8c3feb1d9eb 100644 --- a/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp +++ b/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp @@ -23,6 +23,8 @@ #include "qgsdatetimeedit.h" #include "qgsexpressionbuilderdialog.h" #include "qgsexpressioncontextutils.h" +#include "qgsunittypes.h" + #include #include @@ -48,8 +50,27 @@ QgsRasterLayerTemporalPropertiesWidget::QgsRasterLayerTemporalPropertiesWidget( } mModeComboBox->addItem( tr( "Fixed Time Range" ), QVariant::fromValue( Qgis::RasterTemporalMode::FixedTemporalRange ) ); mModeComboBox->addItem( tr( "Fixed Time Range Per Band" ), QVariant::fromValue( Qgis::RasterTemporalMode::FixedRangePerBand ) ); + mModeComboBox->addItem( tr( "Represents Temporal Values" ), QVariant::fromValue( Qgis::RasterTemporalMode::RepresentsTemporalValues ) ); mModeComboBox->addItem( tr( "Redraw Layer Only" ), QVariant::fromValue( Qgis::RasterTemporalMode::RedrawLayerOnly ) ); + for ( const Qgis::TemporalUnit unit : + { + Qgis::TemporalUnit::Milliseconds, + Qgis::TemporalUnit::Seconds, + Qgis::TemporalUnit::Minutes, + Qgis::TemporalUnit::Hours, + Qgis::TemporalUnit::Days, + Qgis::TemporalUnit::Weeks, + Qgis::TemporalUnit::Months, + Qgis::TemporalUnit::Years, + Qgis::TemporalUnit::Decades, + Qgis::TemporalUnit::Centuries, + } ) + { + mScaleUnitComboBox->addItem( QgsUnitTypes::toString( unit ), static_cast< int >( unit ) ); + } + mScaleUnitComboBox->setCurrentIndex( mScaleUnitComboBox->findData( static_cast< int >( Qgis::TemporalUnit::Days ) ) ); + mStackedWidget->setSizeMode( QgsStackedWidget::SizeMode::CurrentPageOnly ); mFixedRangePerBandModel = new QgsRasterBandFixedTemporalRangeModel( this ); @@ -65,6 +86,7 @@ QgsRasterLayerTemporalPropertiesWidget::QgsRasterLayerTemporalPropertiesWidget( mStartTemporalDateTimeEdit->setDisplayFormat( QStringLiteral( "yyyy-MM-dd HH:mm:ss" ) ); mEndTemporalDateTimeEdit->setDisplayFormat( QStringLiteral( "yyyy-MM-dd HH:mm:ss" ) ); + mOffsetDateTimeEdit->setDisplayFormat( QStringLiteral( "yyyy-MM-dd HH:mm:ss" ) ); QMenu *calculateFixedRangePerBandMenu = new QMenu( mCalculateFixedRangePerBandButton ); mCalculateFixedRangePerBandButton->setMenu( calculateFixedRangePerBandMenu ); @@ -100,6 +122,13 @@ void QgsRasterLayerTemporalPropertiesWidget::saveTemporalProperties() temporalProperties->setFixedRangePerBand( mFixedRangePerBandModel->rangeData() ); + temporalProperties->setTemporalRepresentationOffset( mOffsetDateTimeEdit->dateTime() ); + + temporalProperties->setTemporalRepresentationScale( mScaleSpinBox->value() ); + temporalProperties->setTemporalRepresentationScaleUnit( static_cast< Qgis::TemporalUnit >( mScaleUnitComboBox->currentData().toInt() ) ); + + temporalProperties->setTemporalRepresentationBandNumber( mBandComboBox->currentBand() ); + for ( QgsMapLayerConfigWidget *widget : std::as_const( mExtraWidgets ) ) { widget->apply(); @@ -124,6 +153,9 @@ void QgsRasterLayerTemporalPropertiesWidget::syncToLayer() case Qgis::RasterTemporalMode::FixedRangePerBand: mStackedWidget->setCurrentWidget( mPageFixedRangePerBand ); break; + case Qgis::RasterTemporalMode::RepresentsTemporalValues: + mStackedWidget->setCurrentWidget( mPageRepresentsTemporalValues ); + break; } mStartTemporalDateTimeEdit->setDateTime( temporalProperties->fixedTemporalRange().begin() ); @@ -134,6 +166,14 @@ void QgsRasterLayerTemporalPropertiesWidget::syncToLayer() mBandRangesTable->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch ); mBandRangesTable->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch ); + mOffsetDateTimeEdit->setDateTime( temporalProperties->temporalRepresentationOffset() ); + + mScaleSpinBox->setValue( temporalProperties->temporalRepresentationScale() ); + mScaleUnitComboBox->setCurrentIndex( mScaleUnitComboBox->findData( static_cast< int >( temporalProperties->temporalRepresentationScaleUnit() ) ) ); + + mBandComboBox->setLayer( mLayer ); + mBandComboBox->setBand( temporalProperties->temporalRepresentationBandNumber() ); + mTemporalGroupBox->setChecked( temporalProperties->isActive() ); for ( QgsMapLayerConfigWidget *widget : std::as_const( mExtraWidgets ) ) @@ -174,6 +214,9 @@ void QgsRasterLayerTemporalPropertiesWidget::modeChanged() case Qgis::RasterTemporalMode::FixedRangePerBand: mStackedWidget->setCurrentWidget( mPageFixedRangePerBand ); break; + case Qgis::RasterTemporalMode::RepresentsTemporalValues: + mStackedWidget->setCurrentWidget( mPageRepresentsTemporalValues ); + break; } } } diff --git a/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui b/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui index fed537432da6..75aa4926c1ff 100644 --- a/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui +++ b/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui @@ -272,6 +272,114 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti + + + + 0 + 0 + + + + + + + Scale + + + + + + + Offset + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 6 + + + 0.000000000000000 + + + 99999999999.000000000000000 + + + 1.000000000000000 + + + + + + + false + + + + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-weight:600;">The pixel values in the layer represent a temporal value. </span></p><p> The offset is used to define the starting datetime while scaling identifies the scale – e.g. 1 day or 1 week - of each pixel value.</p></body></html> + + + true + + + + + + + M/d/yyyy h:mm AP + + + Qt::UTC + + + + + + + + + + Band + + + + + diff --git a/tests/src/python/test_qgsrasterlayertemporalproperties.py b/tests/src/python/test_qgsrasterlayertemporalproperties.py index 90cc2dfaa96c..e16af427eed1 100644 --- a/tests/src/python/test_qgsrasterlayertemporalproperties.py +++ b/tests/src/python/test_qgsrasterlayertemporalproperties.py @@ -273,6 +273,45 @@ def test_basic_fixed_range_per_band(self): includeBeginning=False, includeEnd=True)}) + def test_basic_represents_temporal_value(self): + """ + Basic tests for the class using the RepresentsTemporalValue mode + """ + props = QgsRasterLayerTemporalProperties(None) + props.setMode(Qgis.RasterTemporalMode.RepresentsTemporalValues) + self.assertEqual(props.mode(), + Qgis.RasterTemporalMode.RepresentsTemporalValues) + self.assertEqual(props.temporalRepresentationScale(), 1) + self.assertEqual(props.temporalRepresentationScaleUnit(), Qgis.TemporalUnit.Days) + self.assertEqual(props.temporalRepresentationOffset(), QDateTime()) + self.assertEqual(props.temporalRepresentationBandNumber(), 1) + self.assertFalse(props.isActive()) + + props.setTemporalRepresentationScale(2.5) + props.setTemporalRepresentationScaleUnit(Qgis.TemporalUnit.Weeks) + props.setTemporalRepresentationOffset(QDateTime(QDate(2024, 1, 1), QTime(0, 0, 0))) + props.setTemporalRepresentationBandNumber(2) + props.setIsActive(True) + self.assertEqual(props.temporalRepresentationScale(), 2.5) + self.assertEqual(props.temporalRepresentationScaleUnit(), Qgis.TemporalUnit.Weeks) + self.assertEqual(props.temporalRepresentationOffset(), QDateTime(QDate(2024, 1, 1), QTime(0, 0, 0))) + self.assertEqual(props.temporalRepresentationBandNumber(), 2) + self.assertTrue(props.isActive()) + + doc = QDomDocument("testdoc") + elem = doc.createElement('test') + props.writeXml(elem, doc, QgsReadWriteContext()) + + props2 = QgsRasterLayerTemporalProperties(None) + props2.readXml(elem, QgsReadWriteContext()) + self.assertEqual(props2.mode(), + Qgis.RasterTemporalMode.RepresentsTemporalValues) + self.assertEqual(props2.temporalRepresentationScale(), 2.5) + self.assertEqual(props2.temporalRepresentationScaleUnit(), Qgis.TemporalUnit.Weeks) + self.assertEqual(props2.temporalRepresentationOffset(), QDateTime(QDate(2024, 1, 1), QTime(0, 0, 0))) + self.assertEqual(props2.temporalRepresentationBandNumber(), 2) + self.assertTrue(props2.isActive()) + if __name__ == '__main__': unittest.main() From 545325cb81393bb784bfd40776bfa6be7a588126 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Thu, 4 Apr 2024 09:38:48 +0700 Subject: [PATCH 2/6] [ui] Fix vertical spacing issues with raster layer properties dialog's temporal panel --- ...rasterlayertemporalpropertieswidgetbase.ui | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui b/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui index 75aa4926c1ff..7e2855573185 100644 --- a/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui +++ b/src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui @@ -157,6 +157,19 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti + + + + Qt::Vertical + + + + 40 + 20 + + + + @@ -207,7 +220,7 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti - + @@ -217,7 +230,7 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti - + @@ -233,7 +246,7 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti - + 0 @@ -270,6 +283,19 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti + + + + Qt::Vertical + + + + 40 + 20 + + + + @@ -378,6 +404,19 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti + + + + Qt::Vertical + + + + 40 + 20 + + + + From 58ac7221f43e5b8ef3d20c0b45d18949e95b2c62 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Thu, 4 Apr 2024 14:00:23 +0700 Subject: [PATCH 3/6] Make clang-tidy happy --- src/core/raster/qgsrasterlayerrenderer.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/raster/qgsrasterlayerrenderer.cpp b/src/core/raster/qgsrasterlayerrenderer.cpp index 6ad73dac0663..0e5c45024298 100644 --- a/src/core/raster/qgsrasterlayerrenderer.cpp +++ b/src/core/raster/qgsrasterlayerrenderer.cpp @@ -314,10 +314,8 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender QVector transparentPixels = transparency->transparentSingleValuePixelList(); - const qint64 msecsLower = temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().begin() ); - const qint64 msecsUpper = temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().end() ); - const double adjustedLower = msecsLower * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, temporalProperties->temporalRepresentationScaleUnit() ) / temporalProperties->temporalRepresentationScale(); - const double adjustedUpper = msecsUpper * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, temporalProperties->temporalRepresentationScaleUnit() ) / temporalProperties->temporalRepresentationScale(); + const double adjustedLower = static_cast< double >( temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().begin() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, temporalProperties->temporalRepresentationScaleUnit() ) / temporalProperties->temporalRepresentationScale(); + const double adjustedUpper = static_cast< double >( temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().end() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, temporalProperties->temporalRepresentationScaleUnit() ) / temporalProperties->temporalRepresentationScale(); transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( std::numeric_limits::lowest(), adjustedLower, 0, true, !rendererContext.zRange().includeLower() ) ); transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( adjustedUpper, std::numeric_limits::max(), 0, !rendererContext.zRange().includeUpper(), true ) ); From 2ba2abeb89505f37c3538f6798175544b3efcecd Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Sat, 6 Apr 2024 10:41:37 +0700 Subject: [PATCH 4/6] Address review --- .../qgsrasterlayertemporalproperties.sip.in | 62 +++--------------- .../qgsrasterlayertemporalproperties.sip.in | 62 +++--------------- src/core/raster/qgsrasterlayerrenderer.cpp | 8 ++- .../qgsrasterlayertemporalproperties.cpp | 44 +++++-------- .../raster/qgsrasterlayertemporalproperties.h | 53 ++++----------- src/core/raster/qgsrasterlayerutils.cpp | 2 +- ...qgsrasterlayertemporalpropertieswidget.cpp | 17 +++-- .../src/python/test_qgsrasterlayerrenderer.py | 52 +++++++++++++++ .../test_qgsrasterlayertemporalproperties.py | 34 ++++++---- ...cted_represents_temporal_values_filter.png | Bin 0 -> 471523 bytes ...d_represents_temporal_values_no_filter.png | Bin 0 -> 471523 bytes 11 files changed, 138 insertions(+), 196 deletions(-) create mode 100644 tests/testdata/control_images/rasterlayerrenderer/expected_represents_temporal_values_filter/expected_represents_temporal_values_filter.png create mode 100644 tests/testdata/control_images/rasterlayerrenderer/expected_represents_temporal_values_no_filter/expected_represents_temporal_values_no_filter.png diff --git a/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 65e50c481bb0..606ace7eefd5 100644 --- a/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -142,28 +142,28 @@ Returns a filtered list of bands which match the specified ``range``. .. versionadded:: 3.38 %End - int temporalRepresentationBandNumber() const; + int bandNumber() const; %Docstring -Returns the band number from which the temporal values should be taken. +Returns the band number from which temporal values should be taken. .. note:: This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. -.. seealso:: :py:func:`setTemporalRepresentationBandNumber` +.. seealso:: :py:func:`setBandNumber` .. versionadded:: 3.38 %End - void setTemporalRepresentationBandNumber( int number ); + void setBandNumber( int number ); %Docstring -Sets the band number from which the temporal values should be taken. +Sets the band number from which temporal values should be taken. .. note:: This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. -.. seealso:: :py:func:`temporalRepresentationBandNumber` +.. seealso:: :py:func:`bandNumber` .. versionadded:: 3.38 %End @@ -196,9 +196,9 @@ from the layer. .. versionadded:: 3.38 %End - double temporalRepresentationScale() const; + QgsInterval temporalRepresentationScale() const; %Docstring -Returns the scale, which is a duration factor which should be applied to individual pixel +Returns the scale, which is an interval factor which should be applied to individual pixel values from the layer. .. note:: @@ -207,16 +207,12 @@ values from the layer. .. seealso:: :py:func:`setTemporalRepresentationScale` -.. seealso:: :py:func:`temporalRepresentationScaleUnit` - -.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` - .. versionadded:: 3.38 %End - void setTemporalRepresentationScale( double scale ); + void setTemporalRepresentationScale( QgsInterval scale ); %Docstring -Sets the scale, which is a duration factor which should be applied to individual pixel +Sets the scale, which is an interval factor which should be applied to individual pixel values from the layer. .. note:: @@ -225,44 +221,6 @@ values from the layer. .. seealso:: :py:func:`temporalRepresentationScale` -.. seealso:: :py:func:`temporalRepresentationScaleUnit` - -.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` - -.. versionadded:: 3.38 -%End - - Qgis::TemporalUnit temporalRepresentationScaleUnit() const; -%Docstring -Returns the scale's temporal unit type. - -.. note:: - - This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. - -.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` - -.. seealso:: :py:func:`temporalRepresentationScale` - -.. seealso:: :py:func:`setTemporalRepresentationScale` - -.. versionadded:: 3.38 -%End - - void setTemporalRepresentationScaleUnit( Qgis::TemporalUnit unit ); -%Docstring -Sets the scale's temporal unit type. - -.. note:: - - This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. - -.. seealso:: :py:func:`temporalRepresentationScaleUnit` - -.. seealso:: :py:func:`temporalRepresentationScale` - -.. seealso:: :py:func:`setTemporalRepresentationScale` - .. versionadded:: 3.38 %End diff --git a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 65e50c481bb0..606ace7eefd5 100644 --- a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -142,28 +142,28 @@ Returns a filtered list of bands which match the specified ``range``. .. versionadded:: 3.38 %End - int temporalRepresentationBandNumber() const; + int bandNumber() const; %Docstring -Returns the band number from which the temporal values should be taken. +Returns the band number from which temporal values should be taken. .. note:: This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. -.. seealso:: :py:func:`setTemporalRepresentationBandNumber` +.. seealso:: :py:func:`setBandNumber` .. versionadded:: 3.38 %End - void setTemporalRepresentationBandNumber( int number ); + void setBandNumber( int number ); %Docstring -Sets the band number from which the temporal values should be taken. +Sets the band number from which temporal values should be taken. .. note:: This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. -.. seealso:: :py:func:`temporalRepresentationBandNumber` +.. seealso:: :py:func:`bandNumber` .. versionadded:: 3.38 %End @@ -196,9 +196,9 @@ from the layer. .. versionadded:: 3.38 %End - double temporalRepresentationScale() const; + QgsInterval temporalRepresentationScale() const; %Docstring -Returns the scale, which is a duration factor which should be applied to individual pixel +Returns the scale, which is an interval factor which should be applied to individual pixel values from the layer. .. note:: @@ -207,16 +207,12 @@ values from the layer. .. seealso:: :py:func:`setTemporalRepresentationScale` -.. seealso:: :py:func:`temporalRepresentationScaleUnit` - -.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` - .. versionadded:: 3.38 %End - void setTemporalRepresentationScale( double scale ); + void setTemporalRepresentationScale( QgsInterval scale ); %Docstring -Sets the scale, which is a duration factor which should be applied to individual pixel +Sets the scale, which is an interval factor which should be applied to individual pixel values from the layer. .. note:: @@ -225,44 +221,6 @@ values from the layer. .. seealso:: :py:func:`temporalRepresentationScale` -.. seealso:: :py:func:`temporalRepresentationScaleUnit` - -.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` - -.. versionadded:: 3.38 -%End - - Qgis::TemporalUnit temporalRepresentationScaleUnit() const; -%Docstring -Returns the scale's temporal unit type. - -.. note:: - - This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. - -.. seealso:: :py:func:`setTemporalRepresentationScaleUnit` - -.. seealso:: :py:func:`temporalRepresentationScale` - -.. seealso:: :py:func:`setTemporalRepresentationScale` - -.. versionadded:: 3.38 -%End - - void setTemporalRepresentationScaleUnit( Qgis::TemporalUnit unit ); -%Docstring -Sets the scale's temporal unit type. - -.. note:: - - This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues. - -.. seealso:: :py:func:`temporalRepresentationScaleUnit` - -.. seealso:: :py:func:`temporalRepresentationScale` - -.. seealso:: :py:func:`setTemporalRepresentationScale` - .. versionadded:: 3.38 %End diff --git a/src/core/raster/qgsrasterlayerrenderer.cpp b/src/core/raster/qgsrasterlayerrenderer.cpp index 0e5c45024298..7d3a16b27602 100644 --- a/src/core/raster/qgsrasterlayerrenderer.cpp +++ b/src/core/raster/qgsrasterlayerrenderer.cpp @@ -35,6 +35,7 @@ #include "qgsapplication.h" #include "qgsrastertransparency.h" #include "qgsrasterlayerutils.h" +#include "qgsinterval.h" #include "qgsunittypes.h" #include @@ -303,7 +304,7 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender break; case Qgis::RasterTemporalMode::RepresentsTemporalValues: - if ( mPipe->renderer()->usesBands().contains( temporalProperties->temporalRepresentationBandNumber() ) ) + if ( mPipe->renderer()->usesBands().contains( temporalProperties->bandNumber() ) ) { // if layer has elevation settings and we are only rendering a temporal range => we need to filter pixels by temporal values std::unique_ptr< QgsRasterTransparency > transparency; @@ -314,8 +315,9 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender QVector transparentPixels = transparency->transparentSingleValuePixelList(); - const double adjustedLower = static_cast< double >( temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().begin() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, temporalProperties->temporalRepresentationScaleUnit() ) / temporalProperties->temporalRepresentationScale(); - const double adjustedUpper = static_cast< double >( temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().end() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, temporalProperties->temporalRepresentationScaleUnit() ) / temporalProperties->temporalRepresentationScale(); + const QgsInterval scale = temporalProperties->temporalRepresentationScale(); + const double adjustedLower = static_cast< double >( temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().begin() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, scale.originalUnit() ) / scale.originalDuration(); + const double adjustedUpper = static_cast< double >( temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().end() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, scale.originalUnit() ) / scale.originalDuration(); transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( std::numeric_limits::lowest(), adjustedLower, 0, true, !rendererContext.zRange().includeLower() ) ); transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( adjustedUpper, std::numeric_limits::max(), 0, !rendererContext.zRange().includeUpper(), true ) ); diff --git a/src/core/raster/qgsrasterlayertemporalproperties.cpp b/src/core/raster/qgsrasterlayertemporalproperties.cpp index 564c37cc4484..0aef20cfe852 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.cpp +++ b/src/core/raster/qgsrasterlayertemporalproperties.cpp @@ -22,6 +22,7 @@ QgsRasterLayerTemporalProperties::QgsRasterLayerTemporalProperties( QObject *parent, bool enabled ) : QgsMapLayerTemporalProperties( parent, enabled ) { + mTemporalRepresentationScale.setDays( 1.0 ); } bool QgsRasterLayerTemporalProperties::isVisibleInTemporalRange( const QgsDateTimeRange &range ) const @@ -236,7 +237,7 @@ int QgsRasterLayerTemporalProperties::bandForTemporalRange( QgsRasterLayer *, co } case Qgis::RasterTemporalMode::RepresentsTemporalValues: - return mTemporalRepresentationBandNumber; + return mBandNumber; } BUILTIN_UNREACHABLE } @@ -274,22 +275,22 @@ QList QgsRasterLayerTemporalProperties::filteredBandsForTemporalRange( QgsR } case Qgis::RasterTemporalMode::RepresentsTemporalValues: - return QList() << mTemporalRepresentationBandNumber; + return QList() << mBandNumber; } BUILTIN_UNREACHABLE } -int QgsRasterLayerTemporalProperties::temporalRepresentationBandNumber() const +int QgsRasterLayerTemporalProperties::bandNumber() const { - return mTemporalRepresentationBandNumber; + return mBandNumber; } -void QgsRasterLayerTemporalProperties::setTemporalRepresentationBandNumber( int number ) +void QgsRasterLayerTemporalProperties::setBandNumber( int number ) { - if ( mTemporalRepresentationBandNumber == number ) + if ( mBandNumber == number ) return; - mTemporalRepresentationBandNumber = number; + mBandNumber = number; } QDateTime QgsRasterLayerTemporalProperties::temporalRepresentationOffset() const @@ -305,12 +306,12 @@ void QgsRasterLayerTemporalProperties::setTemporalRepresentationOffset( const QD mTemporalRepresentationOffset = offset; } -double QgsRasterLayerTemporalProperties::temporalRepresentationScale() const +QgsInterval QgsRasterLayerTemporalProperties::temporalRepresentationScale() const { return mTemporalRepresentationScale; } -void QgsRasterLayerTemporalProperties::setTemporalRepresentationScale( double scale ) +void QgsRasterLayerTemporalProperties::setTemporalRepresentationScale( QgsInterval scale ) { if ( mTemporalRepresentationScale == scale ) return; @@ -318,19 +319,6 @@ void QgsRasterLayerTemporalProperties::setTemporalRepresentationScale( double sc mTemporalRepresentationScale = scale; } -Qgis::TemporalUnit QgsRasterLayerTemporalProperties::temporalRepresentationScaleUnit() const -{ - return mTemporalRepresentationScaleUnit; -} - -void QgsRasterLayerTemporalProperties::setTemporalRepresentationScaleUnit( Qgis::TemporalUnit unit ) -{ - if ( mTemporalRepresentationScaleUnit == unit ) - return; - - mTemporalRepresentationScaleUnit = unit; -} - bool QgsRasterLayerTemporalProperties::readXml( const QDomElement &element, const QgsReadWriteContext &context ) { Q_UNUSED( context ) @@ -341,6 +329,7 @@ bool QgsRasterLayerTemporalProperties::readXml( const QDomElement &element, cons setIsActive( temporalNode.attribute( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt() ); mMode = static_cast< Qgis::RasterTemporalMode >( temporalNode.attribute( QStringLiteral( "mode" ), QStringLiteral( "0" ) ). toInt() ); + mBandNumber = temporalNode.attribute( QStringLiteral( "bandNumber" ), QStringLiteral( "1" ) ).toInt(); mIntervalHandlingMethod = static_cast< Qgis::TemporalIntervalMatchMethod >( temporalNode.attribute( QStringLiteral( "fetchMode" ), QStringLiteral( "0" ) ). toInt() ); switch ( mMode ) @@ -380,10 +369,9 @@ bool QgsRasterLayerTemporalProperties::readXml( const QDomElement &element, cons case Qgis::RasterTemporalMode::RepresentsTemporalValues: { - mTemporalRepresentationBandNumber = temporalNode.attribute( QStringLiteral( "temporalRepresentationBandNumber" ), QStringLiteral( "1" ) ).toInt(); mTemporalRepresentationOffset = QDateTime::fromString( temporalNode.attribute( QStringLiteral( "temporalRepresentationOffset" ) ), Qt::ISODate ); - mTemporalRepresentationScale = temporalNode.attribute( QStringLiteral( "temporalRepresentationScale" ), QStringLiteral( "1" ) ).toDouble(); - mTemporalRepresentationScaleUnit = static_cast< Qgis::TemporalUnit >( temporalNode.attribute( QStringLiteral( "temporalRepresentationScaleUnit" ), QStringLiteral( "4" ) ).toInt() ); + mTemporalRepresentationScale = QgsInterval( temporalNode.attribute( QStringLiteral( "temporalRepresentationScale" ), QStringLiteral( "1" ) ).toDouble(), + static_cast< Qgis::TemporalUnit >( temporalNode.attribute( QStringLiteral( "temporalRepresentationScaleUnit" ), QStringLiteral( "4" ) ).toInt() ) ); break; } @@ -404,6 +392,7 @@ QDomElement QgsRasterLayerTemporalProperties::writeXml( QDomElement &element, QD QDomElement temporalElement = document.createElement( QStringLiteral( "temporal" ) ); temporalElement.setAttribute( QStringLiteral( "enabled" ), isActive() ? QStringLiteral( "1" ) : QStringLiteral( "0" ) ); temporalElement.setAttribute( QStringLiteral( "mode" ), QString::number( static_cast< int >( mMode ) ) ); + temporalElement.setAttribute( QStringLiteral( "bandNumber" ), QString::number( mBandNumber ) ); temporalElement.setAttribute( QStringLiteral( "fetchMode" ), QString::number( static_cast< int >( mIntervalHandlingMethod ) ) ); switch ( mMode ) @@ -446,10 +435,9 @@ QDomElement QgsRasterLayerTemporalProperties::writeXml( QDomElement &element, QD case Qgis::RasterTemporalMode::RepresentsTemporalValues: { - temporalElement.setAttribute( QStringLiteral( "temporalRepresentationBandNumber" ), QString::number( mTemporalRepresentationBandNumber ) ); temporalElement.setAttribute( QStringLiteral( "temporalRepresentationOffset" ), mTemporalRepresentationOffset.toString( Qt::ISODate ) ); - temporalElement.setAttribute( QStringLiteral( "temporalRepresentationScale" ), QString::number( mTemporalRepresentationScale ) ); - temporalElement.setAttribute( QStringLiteral( "temporalRepresentationScaleUnit" ), QString::number( static_cast< int >( mTemporalRepresentationScaleUnit ) ) ); + temporalElement.setAttribute( QStringLiteral( "temporalRepresentationScale" ), QString::number( mTemporalRepresentationScale.originalDuration() ) ); + temporalElement.setAttribute( QStringLiteral( "temporalRepresentationScaleUnit" ), QString::number( static_cast< int >( mTemporalRepresentationScale.originalUnit() ) ) ); break; } diff --git a/src/core/raster/qgsrasterlayertemporalproperties.h b/src/core/raster/qgsrasterlayertemporalproperties.h index b6aa967e37f2..166e1081a86b 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.h +++ b/src/core/raster/qgsrasterlayertemporalproperties.h @@ -22,6 +22,7 @@ #include "qgis_core.h" #include "qgis_sip.h" #include "qgis.h" +#include "qgsinterval.h" #include "qgsrange.h" #include "qgsmaplayertemporalproperties.h" @@ -145,22 +146,22 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP QList< int > filteredBandsForTemporalRange( QgsRasterLayer *layer, const QgsDateTimeRange &range ) const; /** - * Returns the band number from which the temporal values should be taken. + * Returns the band number from which temporal values should be taken. * * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. - * \see setTemporalRepresentationBandNumber() + * \see setBandNumber() * \since QGIS 3.38 */ - int temporalRepresentationBandNumber() const; + int bandNumber() const; /** - * Sets the band number from which the temporal values should be taken. + * Sets the band number from which temporal values should be taken. * * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. - * \see temporalRepresentationBandNumber() + * \see bandNumber() * \since QGIS 3.38 */ - void setTemporalRepresentationBandNumber( int number ); + void setBandNumber( int number ); /** * Returns the temporal offset, which is a fixed datetime which should be added to individual pixel values @@ -183,50 +184,24 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP void setTemporalRepresentationOffset( const QDateTime &offset ); /** - * Returns the scale, which is a duration factor which should be applied to individual pixel + * Returns the scale, which is an interval factor which should be applied to individual pixel * values from the layer. * * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. * \see setTemporalRepresentationScale() - * \see temporalRepresentationScaleUnit() - * \see setTemporalRepresentationScaleUnit() * \since QGIS 3.38 */ - double temporalRepresentationScale() const; + QgsInterval temporalRepresentationScale() const; /** - * Sets the scale, which is a duration factor which should be applied to individual pixel + * Sets the scale, which is an interval factor which should be applied to individual pixel * values from the layer. * * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. * \see temporalRepresentationScale() - * \see temporalRepresentationScaleUnit() - * \see setTemporalRepresentationScaleUnit() * \since QGIS 3.38 */ - void setTemporalRepresentationScale( double scale ); - - /** - * Returns the scale's temporal unit type. - * - * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. - * \see setTemporalRepresentationScaleUnit() - * \see temporalRepresentationScale() - * \see setTemporalRepresentationScale() - * \since QGIS 3.38 - */ - Qgis::TemporalUnit temporalRepresentationScaleUnit() const; - - /** - * Sets the scale's temporal unit type. - * - * \note This is only considered when mode() is Qgis::RasterTemporalMode::RepresentsTemporalValues. - * \see temporalRepresentationScaleUnit() - * \see temporalRepresentationScale() - * \see setTemporalRepresentationScale() - * \since QGIS 3.38 - */ - void setTemporalRepresentationScaleUnit( Qgis::TemporalUnit unit ); + void setTemporalRepresentationScale( QgsInterval scale ); QDomElement writeXml( QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context ) override; @@ -247,10 +222,10 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP QMap< int, QgsDateTimeRange > mRangePerBand; - int mTemporalRepresentationBandNumber = 1; + int mBandNumber = 1; + QDateTime mTemporalRepresentationOffset; - double mTemporalRepresentationScale = 1.0; - Qgis::TemporalUnit mTemporalRepresentationScaleUnit = Qgis::TemporalUnit::Days; + QgsInterval mTemporalRepresentationScale; }; #endif // QGSRASTERLAYERTEMPORALPROPERTIES_H diff --git a/src/core/raster/qgsrasterlayerutils.cpp b/src/core/raster/qgsrasterlayerutils.cpp index f5437c9fbc80..2ffd4d62845b 100644 --- a/src/core/raster/qgsrasterlayerutils.cpp +++ b/src/core/raster/qgsrasterlayerutils.cpp @@ -72,7 +72,7 @@ int QgsRasterLayerUtils::renderedBandForElevationAndTemporalRange( case Qgis::RasterTemporalMode::RepresentsTemporalValues: { - temporalBands << temporalProperties->temporalRepresentationBandNumber(); + temporalBands << temporalProperties->bandNumber(); break; } } diff --git a/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp b/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp index f8c3feb1d9eb..0e63cad44d50 100644 --- a/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp +++ b/src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp @@ -115,6 +115,7 @@ void QgsRasterLayerTemporalPropertiesWidget::saveTemporalProperties() QgsRasterLayerTemporalProperties *temporalProperties = qobject_cast< QgsRasterLayerTemporalProperties * >( mLayer->temporalProperties() ); temporalProperties->setMode( mModeComboBox->currentData().value< Qgis::RasterTemporalMode >() ); + temporalProperties->setBandNumber( mBandComboBox->currentBand() ); const QgsDateTimeRange normalRange = QgsDateTimeRange( mStartTemporalDateTimeEdit->dateTime(), mEndTemporalDateTimeEdit->dateTime() ); @@ -124,10 +125,8 @@ void QgsRasterLayerTemporalPropertiesWidget::saveTemporalProperties() temporalProperties->setTemporalRepresentationOffset( mOffsetDateTimeEdit->dateTime() ); - temporalProperties->setTemporalRepresentationScale( mScaleSpinBox->value() ); - temporalProperties->setTemporalRepresentationScaleUnit( static_cast< Qgis::TemporalUnit >( mScaleUnitComboBox->currentData().toInt() ) ); - - temporalProperties->setTemporalRepresentationBandNumber( mBandComboBox->currentBand() ); + const QgsInterval scale( mScaleSpinBox->value(), static_cast< Qgis::TemporalUnit >( mScaleUnitComboBox->currentData().toInt() ) ); + temporalProperties->setTemporalRepresentationScale( scale ); for ( QgsMapLayerConfigWidget *widget : std::as_const( mExtraWidgets ) ) { @@ -158,6 +157,9 @@ void QgsRasterLayerTemporalPropertiesWidget::syncToLayer() break; } + mBandComboBox->setLayer( mLayer ); + mBandComboBox->setBand( temporalProperties->bandNumber() ); + mStartTemporalDateTimeEdit->setDateTime( temporalProperties->fixedTemporalRange().begin() ); mEndTemporalDateTimeEdit->setDateTime( temporalProperties->fixedTemporalRange().end() ); @@ -168,11 +170,8 @@ void QgsRasterLayerTemporalPropertiesWidget::syncToLayer() mOffsetDateTimeEdit->setDateTime( temporalProperties->temporalRepresentationOffset() ); - mScaleSpinBox->setValue( temporalProperties->temporalRepresentationScale() ); - mScaleUnitComboBox->setCurrentIndex( mScaleUnitComboBox->findData( static_cast< int >( temporalProperties->temporalRepresentationScaleUnit() ) ) ); - - mBandComboBox->setLayer( mLayer ); - mBandComboBox->setBand( temporalProperties->temporalRepresentationBandNumber() ); + mScaleSpinBox->setValue( temporalProperties->temporalRepresentationScale().originalDuration() ); + mScaleUnitComboBox->setCurrentIndex( mScaleUnitComboBox->findData( static_cast< int >( temporalProperties->temporalRepresentationScale().originalUnit() ) ) ); mTemporalGroupBox->setChecked( temporalProperties->isActive() ); diff --git a/tests/src/python/test_qgsrasterlayerrenderer.py b/tests/src/python/test_qgsrasterlayerrenderer.py index 727a55affca5..222e7c6303a2 100644 --- a/tests/src/python/test_qgsrasterlayerrenderer.py +++ b/tests/src/python/test_qgsrasterlayerrenderer.py @@ -21,6 +21,7 @@ Qgis, QgsCoordinateReferenceSystem, QgsGeometry, + QgsInterval, QgsMapClippingRegion, QgsMapSettings, QgsRasterLayer, @@ -517,6 +518,57 @@ def test_render_fixed_range_per_band_with_temporal_range_filter(self): map_settings) ) + def test_render_represents_temporal_values(self): + """ + Test rendering a raster with its temporal properties' mode set + to represents temporal values + """ + raster_layer = QgsRasterLayer(os.path.join(TEST_DATA_DIR, 'scaleoffset.tif')) + self.assertTrue(raster_layer.isValid()) + + renderer = QgsSingleBandGrayRenderer(raster_layer.dataProvider(), 1) + raster_layer.setRenderer(renderer) + + # set layer as temporal enabled + raster_layer.temporalProperties().setIsActive(True) + raster_layer.temporalProperties().setMode( + Qgis.RasterTemporalMode.RepresentsTemporalValues + ) + raster_layer.temporalProperties().setBandNumber(1) + raster_layer.temporalProperties().setTemporalRepresentationOffset(QDateTime(QDate(2024, 1, 1), QTime(0, 0, 0))) + raster_layer.temporalProperties().setTemporalRepresentationScale(QgsInterval(1, Qgis.TemporalUnit.Days)) + + map_settings = QgsMapSettings() + map_settings.setOutputSize(QSize(400, 400)) + map_settings.setOutputDpi(96) + map_settings.setDestinationCrs(raster_layer.crs()) + map_settings.setExtent(raster_layer.extent()) + map_settings.setLayers([raster_layer]) + + # no filter on map settings + map_settings.setIsTemporal(False) + self.assertTrue( + self.render_map_settings_check( + 'No temporal range filter on map settings on represents temporal values mode', + 'represents_temporal_values_no_filter', + map_settings) + ) + + # map settings matches part of the overall range + map_settings.setIsTemporal(True) + map_settings.setTemporalRange(QgsDateTimeRange( + QDateTime(QDate(2024, 1, 1), + QTime(0, 0, 0)), + QDateTime(QDate(2024, 1, 5), + QTime(23, 59, 59)) + )) + self.assertTrue( + self.render_map_settings_check( + 'Temporal range filter on map settings on represents temporal values mode', + 'represents_temporal_values_filter', + map_settings) + ) + if __name__ == '__main__': unittest.main() diff --git a/tests/src/python/test_qgsrasterlayertemporalproperties.py b/tests/src/python/test_qgsrasterlayertemporalproperties.py index e16af427eed1..ac5588cd903c 100644 --- a/tests/src/python/test_qgsrasterlayertemporalproperties.py +++ b/tests/src/python/test_qgsrasterlayertemporalproperties.py @@ -16,6 +16,7 @@ from qgis.PyQt.QtXml import QDomDocument from qgis.core import ( Qgis, + QgsInterval, QgsRasterLayerTemporalProperties, QgsReadWriteContext, QgsDateTimeRange @@ -281,23 +282,33 @@ def test_basic_represents_temporal_value(self): props.setMode(Qgis.RasterTemporalMode.RepresentsTemporalValues) self.assertEqual(props.mode(), Qgis.RasterTemporalMode.RepresentsTemporalValues) - self.assertEqual(props.temporalRepresentationScale(), 1) - self.assertEqual(props.temporalRepresentationScaleUnit(), Qgis.TemporalUnit.Days) + self.assertEqual(props.bandNumber(), 1) + self.assertEqual(props.temporalRepresentationScale(), QgsInterval(1, Qgis.TemporalUnit.Days)) self.assertEqual(props.temporalRepresentationOffset(), QDateTime()) - self.assertEqual(props.temporalRepresentationBandNumber(), 1) self.assertFalse(props.isActive()) - props.setTemporalRepresentationScale(2.5) - props.setTemporalRepresentationScaleUnit(Qgis.TemporalUnit.Weeks) + props.setBandNumber(2) + props.setTemporalRepresentationScale(QgsInterval(2.5, Qgis.TemporalUnit.Weeks)) props.setTemporalRepresentationOffset(QDateTime(QDate(2024, 1, 1), QTime(0, 0, 0))) - props.setTemporalRepresentationBandNumber(2) props.setIsActive(True) - self.assertEqual(props.temporalRepresentationScale(), 2.5) - self.assertEqual(props.temporalRepresentationScaleUnit(), Qgis.TemporalUnit.Weeks) + self.assertEqual(props.bandNumber(), 2) + self.assertEqual(props.temporalRepresentationScale(), QgsInterval(2.5, Qgis.TemporalUnit.Weeks)) self.assertEqual(props.temporalRepresentationOffset(), QDateTime(QDate(2024, 1, 1), QTime(0, 0, 0))) - self.assertEqual(props.temporalRepresentationBandNumber(), 2) self.assertTrue(props.isActive()) + self.assertEqual(props.bandForTemporalRange(None, QgsDateTimeRange( + QDateTime(QDate(2023, 5, 3), + QTime(12, 13, 14)), + QDateTime(QDate(2023, 5, 4), + QTime(12, 13, 14)) + )), 2) + self.assertEqual(props.filteredBandsForTemporalRange(None, QgsDateTimeRange( + QDateTime(QDate(2023, 5, 3), + QTime(12, 13, 14)), + QDateTime(QDate(2023, 5, 4), + QTime(12, 13, 14)) + )), [2]) + doc = QDomDocument("testdoc") elem = doc.createElement('test') props.writeXml(elem, doc, QgsReadWriteContext()) @@ -306,10 +317,9 @@ def test_basic_represents_temporal_value(self): props2.readXml(elem, QgsReadWriteContext()) self.assertEqual(props2.mode(), Qgis.RasterTemporalMode.RepresentsTemporalValues) - self.assertEqual(props2.temporalRepresentationScale(), 2.5) - self.assertEqual(props2.temporalRepresentationScaleUnit(), Qgis.TemporalUnit.Weeks) + self.assertEqual(props.bandNumber(), 2) + self.assertEqual(props2.temporalRepresentationScale(), QgsInterval(2.5, Qgis.TemporalUnit.Weeks)) self.assertEqual(props2.temporalRepresentationOffset(), QDateTime(QDate(2024, 1, 1), QTime(0, 0, 0))) - self.assertEqual(props2.temporalRepresentationBandNumber(), 2) self.assertTrue(props2.isActive()) diff --git a/tests/testdata/control_images/rasterlayerrenderer/expected_represents_temporal_values_filter/expected_represents_temporal_values_filter.png b/tests/testdata/control_images/rasterlayerrenderer/expected_represents_temporal_values_filter/expected_represents_temporal_values_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..ebd0fd00bcdfdc84baf630bf9f033c1083269f7b GIT binary patch literal 471523 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 Yb{stQyubbS)rxzsy>8>sHJ`ipe}~ZQK>z>% literal 0 HcmV?d00001 From 975ab2babe41f46bb22f678bf09b53d9e713f43a Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Sat, 6 Apr 2024 12:35:03 +0700 Subject: [PATCH 5/6] Optimize a bit --- .../raster/qgsrasterlayertemporalproperties.sip.in | 4 ++-- .../raster/qgsrasterlayertemporalproperties.sip.in | 4 ++-- src/core/raster/qgsrasterlayerrenderer.cpp | 7 ++++--- src/core/raster/qgsrasterlayertemporalproperties.cpp | 4 ++-- src/core/raster/qgsrasterlayertemporalproperties.h | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 606ace7eefd5..623c5230738f 100644 --- a/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -168,7 +168,7 @@ Sets the band number from which temporal values should be taken. .. versionadded:: 3.38 %End - QDateTime temporalRepresentationOffset() const; + const QDateTime temporalRepresentationOffset() const; %Docstring Returns the temporal offset, which is a fixed datetime which should be added to individual pixel values from the layer. @@ -196,7 +196,7 @@ from the layer. .. versionadded:: 3.38 %End - QgsInterval temporalRepresentationScale() const; + const QgsInterval temporalRepresentationScale() const; %Docstring Returns the scale, which is an interval factor which should be applied to individual pixel values from the layer. diff --git a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 606ace7eefd5..623c5230738f 100644 --- a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -168,7 +168,7 @@ Sets the band number from which temporal values should be taken. .. versionadded:: 3.38 %End - QDateTime temporalRepresentationOffset() const; + const QDateTime temporalRepresentationOffset() const; %Docstring Returns the temporal offset, which is a fixed datetime which should be added to individual pixel values from the layer. @@ -196,7 +196,7 @@ from the layer. .. versionadded:: 3.38 %End - QgsInterval temporalRepresentationScale() const; + const QgsInterval temporalRepresentationScale() const; %Docstring Returns the scale, which is an interval factor which should be applied to individual pixel values from the layer. diff --git a/src/core/raster/qgsrasterlayerrenderer.cpp b/src/core/raster/qgsrasterlayerrenderer.cpp index 7d3a16b27602..3a9e8f824678 100644 --- a/src/core/raster/qgsrasterlayerrenderer.cpp +++ b/src/core/raster/qgsrasterlayerrenderer.cpp @@ -315,9 +315,10 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender QVector transparentPixels = transparency->transparentSingleValuePixelList(); - const QgsInterval scale = temporalProperties->temporalRepresentationScale(); - const double adjustedLower = static_cast< double >( temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().begin() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, scale.originalUnit() ) / scale.originalDuration(); - const double adjustedUpper = static_cast< double >( temporalProperties->temporalRepresentationOffset().msecsTo( rendererContext.temporalRange().end() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, scale.originalUnit() ) / scale.originalDuration(); + const QDateTime &offset = temporalProperties->temporalRepresentationOffset(); + const QgsInterval &scale = temporalProperties->temporalRepresentationScale(); + const double adjustedLower = static_cast< double >( offset.msecsTo( rendererContext.temporalRange().begin() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, scale.originalUnit() ) / scale.originalDuration(); + const double adjustedUpper = static_cast< double >( offset.msecsTo( rendererContext.temporalRange().end() ) ) * QgsUnitTypes::fromUnitToUnitFactor( Qgis::TemporalUnit::Milliseconds, scale.originalUnit() ) / scale.originalDuration(); transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( std::numeric_limits::lowest(), adjustedLower, 0, true, !rendererContext.zRange().includeLower() ) ); transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( adjustedUpper, std::numeric_limits::max(), 0, !rendererContext.zRange().includeUpper(), true ) ); diff --git a/src/core/raster/qgsrasterlayertemporalproperties.cpp b/src/core/raster/qgsrasterlayertemporalproperties.cpp index 0aef20cfe852..2e96313df230 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.cpp +++ b/src/core/raster/qgsrasterlayertemporalproperties.cpp @@ -293,7 +293,7 @@ void QgsRasterLayerTemporalProperties::setBandNumber( int number ) mBandNumber = number; } -QDateTime QgsRasterLayerTemporalProperties::temporalRepresentationOffset() const +const QDateTime QgsRasterLayerTemporalProperties::temporalRepresentationOffset() const { return mTemporalRepresentationOffset; } @@ -306,7 +306,7 @@ void QgsRasterLayerTemporalProperties::setTemporalRepresentationOffset( const QD mTemporalRepresentationOffset = offset; } -QgsInterval QgsRasterLayerTemporalProperties::temporalRepresentationScale() const +const QgsInterval QgsRasterLayerTemporalProperties::temporalRepresentationScale() const { return mTemporalRepresentationScale; } diff --git a/src/core/raster/qgsrasterlayertemporalproperties.h b/src/core/raster/qgsrasterlayertemporalproperties.h index 166e1081a86b..9a3013fdf4d2 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.h +++ b/src/core/raster/qgsrasterlayertemporalproperties.h @@ -171,7 +171,7 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP * \see setTemporalRepresentationOffset() * \since QGIS 3.38 */ - QDateTime temporalRepresentationOffset() const; + const QDateTime temporalRepresentationOffset() const; /** * Sets the temporal offset, which is a fixed datetime which should be added to individual pixel values @@ -191,7 +191,7 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP * \see setTemporalRepresentationScale() * \since QGIS 3.38 */ - QgsInterval temporalRepresentationScale() const; + const QgsInterval temporalRepresentationScale() const; /** * Sets the scale, which is an interval factor which should be applied to individual pixel From 97414bf2521fd49dd29c88ca7d3b5a54ec81c426 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Sun, 7 Apr 2024 11:33:18 +0700 Subject: [PATCH 6/6] More review addressed --- .../raster/qgsrasterlayertemporalproperties.sip.in | 6 +++--- .../raster/qgsrasterlayertemporalproperties.sip.in | 6 +++--- src/core/raster/qgsrasterlayertemporalproperties.cpp | 6 +++--- src/core/raster/qgsrasterlayertemporalproperties.h | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 623c5230738f..4d9e5a0728e3 100644 --- a/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/PyQt6/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -168,7 +168,7 @@ Sets the band number from which temporal values should be taken. .. versionadded:: 3.38 %End - const QDateTime temporalRepresentationOffset() const; + QDateTime temporalRepresentationOffset() const; %Docstring Returns the temporal offset, which is a fixed datetime which should be added to individual pixel values from the layer. @@ -196,7 +196,7 @@ from the layer. .. versionadded:: 3.38 %End - const QgsInterval temporalRepresentationScale() const; + const QgsInterval &temporalRepresentationScale() const; %Docstring Returns the scale, which is an interval factor which should be applied to individual pixel values from the layer. @@ -210,7 +210,7 @@ values from the layer. .. versionadded:: 3.38 %End - void setTemporalRepresentationScale( QgsInterval scale ); + void setTemporalRepresentationScale( const QgsInterval &scale ); %Docstring Sets the scale, which is an interval factor which should be applied to individual pixel values from the layer. diff --git a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in index 623c5230738f..4d9e5a0728e3 100644 --- a/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in +++ b/python/core/auto_generated/raster/qgsrasterlayertemporalproperties.sip.in @@ -168,7 +168,7 @@ Sets the band number from which temporal values should be taken. .. versionadded:: 3.38 %End - const QDateTime temporalRepresentationOffset() const; + QDateTime temporalRepresentationOffset() const; %Docstring Returns the temporal offset, which is a fixed datetime which should be added to individual pixel values from the layer. @@ -196,7 +196,7 @@ from the layer. .. versionadded:: 3.38 %End - const QgsInterval temporalRepresentationScale() const; + const QgsInterval &temporalRepresentationScale() const; %Docstring Returns the scale, which is an interval factor which should be applied to individual pixel values from the layer. @@ -210,7 +210,7 @@ values from the layer. .. versionadded:: 3.38 %End - void setTemporalRepresentationScale( QgsInterval scale ); + void setTemporalRepresentationScale( const QgsInterval &scale ); %Docstring Sets the scale, which is an interval factor which should be applied to individual pixel values from the layer. diff --git a/src/core/raster/qgsrasterlayertemporalproperties.cpp b/src/core/raster/qgsrasterlayertemporalproperties.cpp index 2e96313df230..659ab8aee834 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.cpp +++ b/src/core/raster/qgsrasterlayertemporalproperties.cpp @@ -293,7 +293,7 @@ void QgsRasterLayerTemporalProperties::setBandNumber( int number ) mBandNumber = number; } -const QDateTime QgsRasterLayerTemporalProperties::temporalRepresentationOffset() const +QDateTime QgsRasterLayerTemporalProperties::temporalRepresentationOffset() const { return mTemporalRepresentationOffset; } @@ -306,12 +306,12 @@ void QgsRasterLayerTemporalProperties::setTemporalRepresentationOffset( const QD mTemporalRepresentationOffset = offset; } -const QgsInterval QgsRasterLayerTemporalProperties::temporalRepresentationScale() const +const QgsInterval &QgsRasterLayerTemporalProperties::temporalRepresentationScale() const { return mTemporalRepresentationScale; } -void QgsRasterLayerTemporalProperties::setTemporalRepresentationScale( QgsInterval scale ) +void QgsRasterLayerTemporalProperties::setTemporalRepresentationScale( const QgsInterval &scale ) { if ( mTemporalRepresentationScale == scale ) return; diff --git a/src/core/raster/qgsrasterlayertemporalproperties.h b/src/core/raster/qgsrasterlayertemporalproperties.h index 9a3013fdf4d2..f4cff37b4b82 100644 --- a/src/core/raster/qgsrasterlayertemporalproperties.h +++ b/src/core/raster/qgsrasterlayertemporalproperties.h @@ -171,7 +171,7 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP * \see setTemporalRepresentationOffset() * \since QGIS 3.38 */ - const QDateTime temporalRepresentationOffset() const; + QDateTime temporalRepresentationOffset() const; /** * Sets the temporal offset, which is a fixed datetime which should be added to individual pixel values @@ -191,7 +191,7 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP * \see setTemporalRepresentationScale() * \since QGIS 3.38 */ - const QgsInterval temporalRepresentationScale() const; + const QgsInterval &temporalRepresentationScale() const; /** * Sets the scale, which is an interval factor which should be applied to individual pixel @@ -201,7 +201,7 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP * \see temporalRepresentationScale() * \since QGIS 3.38 */ - void setTemporalRepresentationScale( QgsInterval scale ); + void setTemporalRepresentationScale( const QgsInterval &scale ); QDomElement writeXml( QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context ) override;