Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[raster][temporal] Add a brand new temporal mode: pixel value as temporal datetime #57035

Merged
merged 6 commits into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion python/PyQt6/core/auto_additions/qgis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions python/PyQt6/core/auto_generated/qgis.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,7 @@ The development version
TemporalRangeFromDataProvider,
RedrawLayerOnly,
FixedRangePerBand,
RepresentsTemporalValues,
};

enum class TemporalIntervalMatchMethod /BaseType=IntEnum/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,88 @@ 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 bandNumber() const;
%Docstring
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:`setBandNumber`

.. versionadded:: 3.38
%End

void setBandNumber( int number );
%Docstring
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:`bandNumber`

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

const QgsInterval &temporalRepresentationScale() const;
%Docstring
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 :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues.

.. seealso:: :py:func:`setTemporalRepresentationScale`

.. versionadded:: 3.38
%End

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.

.. note::

This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues.

.. seealso:: :py:func:`temporalRepresentationScale`

.. versionadded:: 3.38
%End

Expand Down
5 changes: 4 additions & 1 deletion python/core/auto_additions/qgis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions python/core/auto_generated/qgis.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,7 @@ The development version
TemporalRangeFromDataProvider,
RedrawLayerOnly,
FixedRangePerBand,
RepresentsTemporalValues,
};

enum class TemporalIntervalMatchMethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,88 @@ 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 bandNumber() const;
%Docstring
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:`setBandNumber`

.. versionadded:: 3.38
%End

void setBandNumber( int number );
%Docstring
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:`bandNumber`

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

const QgsInterval &temporalRepresentationScale() const;
%Docstring
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 :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues.

.. seealso:: :py:func:`setTemporalRepresentationScale`

.. versionadded:: 3.38
%End

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.

.. note::

This is only considered when :py:func:`~QgsRasterLayerTemporalProperties.mode` is :py:class:`Qgis`.RasterTemporalMode.RepresentsTemporalValues.

.. seealso:: :py:func:`temporalRepresentationScale`

.. versionadded:: 3.38
%End

Expand Down
1 change: 1 addition & 0 deletions src/core/qgis.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 )

Expand Down
26 changes: 26 additions & 0 deletions src/core/raster/qgsrasterlayerrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include "qgsapplication.h"
#include "qgsrastertransparency.h"
#include "qgsrasterlayerutils.h"
#include "qgsinterval.h"
#include "qgsunittypes.h"

#include <QElapsedTimer>
#include <QPointer>
Expand Down Expand Up @@ -301,6 +303,30 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender
case Qgis::RasterTemporalMode::FixedRangePerBand:
break;

case Qgis::RasterTemporalMode::RepresentsTemporalValues:
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;
if ( const QgsRasterTransparency *rendererTransparency = mPipe->renderer()->rasterTransparency() )
transparency = std::make_unique< QgsRasterTransparency >( *rendererTransparency );
else
transparency = std::make_unique< QgsRasterTransparency >();

QVector<QgsRasterTransparency::TransparentSingleValuePixel> transparentPixels = transparency->transparentSingleValuePixelList();

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<double>::lowest(), adjustedLower, 0, true, !rendererContext.zRange().includeLower() ) );
transparentPixels.append( QgsRasterTransparency::TransparentSingleValuePixel( adjustedUpper, std::numeric_limits<double>::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() )
Expand Down
Loading
Loading