Skip to content

Commit

Permalink
[feature] Add a "redraw layer only" temporal mode for raster layers
Browse files Browse the repository at this point in the history
Just like the equivalent setting for vector layers, this option
causes a raster layer to be redrawn on each new animation frame. It's
useful when the layer uses time-based expression values (e.g. data
defined renderer opacity, to fade/in out a raster layer)
  • Loading branch information
nyalldawson committed Jun 25, 2021
1 parent bcca0ba commit 2d48973
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 11 deletions.
Expand Up @@ -39,6 +39,7 @@ The ``enabled`` argument specifies whether the temporal properties are initially
{
ModeFixedTemporalRange,
ModeTemporalRangeFromDataProvider,
ModeRedrawLayerOnly,
};

TemporalMode mode() const;
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgsrasterlayerrenderer.cpp
Expand Up @@ -262,6 +262,7 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender
switch ( temporalProperties->mode() )
{
case QgsRasterLayerTemporalProperties::ModeFixedTemporalRange:
case QgsRasterLayerTemporalProperties::ModeRedrawLayerOnly:
break;

case QgsRasterLayerTemporalProperties::ModeTemporalRangeFromDataProvider:
Expand Down
7 changes: 7 additions & 0 deletions src/core/raster/qgsrasterlayertemporalproperties.cpp
Expand Up @@ -35,6 +35,7 @@ bool QgsRasterLayerTemporalProperties::isVisibleInTemporalRange( const QgsDateTi
return range.isInfinite() || mFixedRange.isInfinite() || mFixedRange.overlaps( range );

case ModeTemporalRangeFromDataProvider:
case ModeRedrawLayerOnly:
return true;
}
return true;
Expand All @@ -53,6 +54,9 @@ QgsDateTimeRange QgsRasterLayerTemporalProperties::calculateTemporalExtent( QgsM

case QgsRasterLayerTemporalProperties::ModeTemporalRangeFromDataProvider:
return rasterLayer->dataProvider()->temporalCapabilities()->availableTemporalRange();

case QgsRasterLayerTemporalProperties::ModeRedrawLayerOnly:
break;
}

return QgsDateTimeRange();
Expand All @@ -74,6 +78,9 @@ QList<QgsDateTimeRange> QgsRasterLayerTemporalProperties::allTemporalRanges( Qgs
QList< QgsDateTimeRange > ranges = rasterLayer->dataProvider()->temporalCapabilities()->allAvailableTemporalRanges();
return ranges.empty() ? QList< QgsDateTimeRange > { rasterLayer->dataProvider()->temporalCapabilities()->availableTemporalRange() } : ranges;
}

case QgsRasterLayerTemporalProperties::ModeRedrawLayerOnly:
break;
}

return {};
Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgsrasterlayertemporalproperties.h
Expand Up @@ -56,6 +56,7 @@ class CORE_EXPORT QgsRasterLayerTemporalProperties : public QgsMapLayerTemporalP
{
ModeFixedTemporalRange = 0, //!< Mode when temporal properties have fixed start and end datetimes.
ModeTemporalRangeFromDataProvider = 1, //!< Mode when raster layer delegates temporal range handling to the dataprovider.
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)
};

/**
Expand Down
8 changes: 8 additions & 0 deletions src/gui/raster/qgsrasterlayertemporalpropertieswidget.cpp
Expand Up @@ -39,6 +39,7 @@ QgsRasterLayerTemporalPropertiesWidget::QgsRasterLayerTemporalPropertiesWidget(
connect( mModeFixedRangeRadio, &QRadioButton::toggled, mFixedTimeRangeFrame, &QWidget::setEnabled );

connect( mTemporalGroupBox, &QGroupBox::toggled, this, &QgsRasterLayerTemporalPropertiesWidget::temporalGroupBoxChecked );
connect( mModeRedrawLayer, &QRadioButton::toggled, mLabelRedrawLayer, &QWidget::setEnabled );

mStartTemporalDateTimeEdit->setDisplayFormat( QStringLiteral( "yyyy-MM-dd HH:mm:ss" ) );
mEndTemporalDateTimeEdit->setDisplayFormat( QStringLiteral( "yyyy-MM-dd HH:mm:ss" ) );
Expand Down Expand Up @@ -66,6 +67,8 @@ void QgsRasterLayerTemporalPropertiesWidget::saveTemporalProperties()
temporalProperties->setMode( QgsRasterLayerTemporalProperties::ModeTemporalRangeFromDataProvider );
else if ( mModeFixedRangeRadio->isChecked() )
temporalProperties->setMode( QgsRasterLayerTemporalProperties::ModeFixedTemporalRange );
else if ( mModeRedrawLayer->isChecked() )
temporalProperties->setMode( QgsRasterLayerTemporalProperties::ModeRedrawLayerOnly );
temporalProperties->setFixedTemporalRange( normalRange );

for ( QgsMapLayerConfigWidget *widget : std::as_const( mExtraWidgets ) )
Expand All @@ -85,13 +88,18 @@ void QgsRasterLayerTemporalPropertiesWidget::syncToLayer()
case QgsRasterLayerTemporalProperties::ModeFixedTemporalRange:
mModeFixedRangeRadio->setChecked( true );
break;
case QgsRasterLayerTemporalProperties::ModeRedrawLayerOnly:
mModeRedrawLayer->setChecked( true );
break;
}

mStartTemporalDateTimeEdit->setDateTime( temporalProperties->fixedTemporalRange().begin() );
mEndTemporalDateTimeEdit->setDateTime( temporalProperties->fixedTemporalRange().end() );

mTemporalGroupBox->setChecked( temporalProperties->isActive() );

mLabelRedrawLayer->setEnabled( mModeRedrawLayer->isChecked() );

for ( QgsMapLayerConfigWidget *widget : std::as_const( mExtraWidgets ) )
{
widget->syncToLayer( mLayer );
Expand Down
63 changes: 52 additions & 11 deletions src/ui/raster/qgsrasterlayertemporalpropertieswidgetbase.ui
Expand Up @@ -49,10 +49,10 @@
<x>0</x>
<y>0</y>
<width>577</width>
<height>413</height>
<height>663</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="0,1">
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0">
<property name="leftMargin">
<number>0</number>
</property>
Expand All @@ -65,9 +65,6 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QWidget" name="mExtraWidgetContainer" native="true"/>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="mTemporalGroupBox">
<property name="enabled">
Expand All @@ -87,13 +84,10 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="2" column="0" colspan="2">
<widget class="QRadioButton" name="mModeFixedRangeRadio">
<item row="4" column="0" colspan="2">
<widget class="QRadioButton" name="mModeRedrawLayer">
<property name="text">
<string>Fixed time range (only show this layer if animation time is within this range)</string>
</property>
<property name="checked">
<bool>false</bool>
<string>Redraw layer only</string>
</property>
</widget>
</item>
Expand Down Expand Up @@ -125,6 +119,9 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti
<number>0</number>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,2,0,3">
<property name="leftMargin">
<number>20</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
Expand Down Expand Up @@ -181,9 +178,53 @@ background: white;QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::ti
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QRadioButton" name="mModeFixedRangeRadio">
<property name="text">
<string>Fixed time range (only show this layer if animation time is within this range)</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>20</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="mLabelRedrawLayer">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;The layer will automatically be redrawn whenever the temporal range is changed, but no time based filtering will be applied to the layer.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This configuration is useful when the layer has renderer settings which vary based on the temporal range. For instance, when it is using time-dependent data-defined renderer expressions.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QWidget" name="mExtraWidgetContainer" native="true"/>
</item>
</layout>
</widget>
</widget>
Expand Down

0 comments on commit 2d48973

Please sign in to comment.