37 mFixedRangeLowerExpression = QStringLiteral(
"make_datetime(%1,1,1,0,0,0) + make_interval(days:=@band)" ).arg( QDate::currentDate().year() );
38 mFixedRangeUpperExpression = QStringLiteral(
"make_datetime(%1,1,1,23,59,59) + make_interval(days:=@band)" ).arg( QDate::currentDate().year() );
40 mExtraWidgetLayout =
new QVBoxLayout();
41 mExtraWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
42 mExtraWidgetLayout->addStretch();
43 mExtraWidgetContainer->setLayout( mExtraWidgetLayout );
55 mFixedRangePerBandModel =
new QgsRasterBandFixedTemporalRangeModel(
this );
56 mBandRangesTable->verticalHeader()->setVisible(
false );
57 mBandRangesTable->setModel( mFixedRangePerBandModel );
58 QgsFixedTemporalRangeDelegate *tableDelegate =
new QgsFixedTemporalRangeDelegate( mBandRangesTable );
59 mBandRangesTable->setItemDelegateForColumn( 1, tableDelegate );
60 mBandRangesTable->setItemDelegateForColumn( 2, tableDelegate );
62 connect( mModeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsRasterLayerTemporalPropertiesWidget::modeChanged );
64 connect( mTemporalGroupBox, &QGroupBox::toggled,
this, &QgsRasterLayerTemporalPropertiesWidget::temporalGroupBoxChecked );
66 mStartTemporalDateTimeEdit->setDisplayFormat( QStringLiteral(
"yyyy-MM-dd HH:mm:ss" ) );
67 mEndTemporalDateTimeEdit->setDisplayFormat( QStringLiteral(
"yyyy-MM-dd HH:mm:ss" ) );
69 QMenu *calculateFixedRangePerBandMenu =
new QMenu( mCalculateFixedRangePerBandButton );
70 mCalculateFixedRangePerBandButton->setMenu( calculateFixedRangePerBandMenu );
71 mCalculateFixedRangePerBandButton->setPopupMode( QToolButton::InstantPopup );
72 QAction *calculateLowerAction =
new QAction(
"Calculate Beginning by Expression…", calculateFixedRangePerBandMenu );
73 calculateFixedRangePerBandMenu->addAction( calculateLowerAction );
74 connect( calculateLowerAction, &QAction::triggered,
this, [
this]
76 calculateRangeByExpression(
false );
78 QAction *calculateUpperAction =
new QAction(
"Calculate End by Expression…", calculateFixedRangePerBandMenu );
79 calculateFixedRangePerBandMenu->addAction( calculateUpperAction );
80 connect( calculateUpperAction, &QAction::triggered,
this, [
this]
82 calculateRangeByExpression(
true );
98 mEndTemporalDateTimeEdit->dateTime() );
112 mModeComboBox->setCurrentIndex( mModeComboBox->findData( QVariant::fromValue( temporalProperties->
mode() ) ) );
113 switch ( temporalProperties->
mode() )
116 mStackedWidget->setCurrentWidget( mPageAutomatic );
119 mStackedWidget->setCurrentWidget( mPageFixedRange );
122 mStackedWidget->setCurrentWidget( mPageRedrawOnly );
125 mStackedWidget->setCurrentWidget( mPageFixedRangePerBand );
132 mFixedRangePerBandModel->setLayerData( mLayer, temporalProperties->
fixedRangePerBand() );
133 mBandRangesTable->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
134 mBandRangesTable->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
135 mBandRangesTable->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch );
137 mTemporalGroupBox->setChecked( temporalProperties->
isActive() );
141 widget->syncToLayer( mLayer );
147 mExtraWidgets << widget;
148 mExtraWidgetLayout->insertWidget( mExtraWidgetLayout->count() - 1, widget );
151void QgsRasterLayerTemporalPropertiesWidget::temporalGroupBoxChecked(
bool checked )
155 widget->emit dynamicTemporalControlToggled( checked );
159void QgsRasterLayerTemporalPropertiesWidget::modeChanged()
161 if ( mModeComboBox->currentData().isValid() )
166 mStackedWidget->setCurrentWidget( mPageAutomatic );
169 mStackedWidget->setCurrentWidget( mPageFixedRange );
172 mStackedWidget->setCurrentWidget( mPageRedrawOnly );
175 mStackedWidget->setCurrentWidget( mPageFixedRangePerBand );
181void QgsRasterLayerTemporalPropertiesWidget::calculateRangeByExpression(
bool isUpper )
190 expressionContext.
setHighlightedVariables( { QStringLiteral(
"band" ), QStringLiteral(
"band_name" ), QStringLiteral(
"band_description" )} );
193 dlg.
setExpectedOutputFormat( !isUpper ? tr(
"Temporal range start date / time" ) : tr(
"Temporal range end date / time" ) );
195 QList<QPair<QString, QVariant> > bandChoices;
196 for (
int band = 1; band <= mLayer->
bandCount(); ++band )
202 return createExpressionContextForBand( value.toInt() );
213 exp.prepare( &expressionContext );
214 for (
int band = 1; band <= mLayer->
bandCount(); ++band )
216 bandScope->
setVariable( QStringLiteral(
"band" ), band );
220 const QVariant res = exp.evaluate( &expressionContext );
221 mFixedRangePerBandModel->setData( mFixedRangePerBandModel->index( band - 1, isUpper ? 2 : 1 ), res, Qt::EditRole );
226QgsExpressionContext QgsRasterLayerTemporalPropertiesWidget::createExpressionContextForBand(
int band )
const
235 context.
setHighlightedVariables( { QStringLiteral(
"band" ), QStringLiteral(
"band_name" ), QStringLiteral(
"band_description" )} );
245QgsRasterBandFixedTemporalRangeModel::QgsRasterBandFixedTemporalRangeModel( QObject *parent )
246 : QAbstractItemModel( parent )
251int QgsRasterBandFixedTemporalRangeModel::columnCount(
const QModelIndex & )
const
256int QgsRasterBandFixedTemporalRangeModel::rowCount(
const QModelIndex &parent )
const
258 if ( parent.isValid() )
263QModelIndex QgsRasterBandFixedTemporalRangeModel::index(
int row,
int column,
const QModelIndex &parent )
const
265 if ( hasIndex( row, column, parent ) )
267 return createIndex( row, column, row );
270 return QModelIndex();
273QModelIndex QgsRasterBandFixedTemporalRangeModel::parent(
const QModelIndex &child )
const
276 return QModelIndex();
279Qt::ItemFlags QgsRasterBandFixedTemporalRangeModel::flags(
const QModelIndex &index )
const
281 if ( !index.isValid() )
282 return Qt::ItemFlags();
284 if ( index.row() < 0 || index.row() >= mBandCount || index.column() < 0 || index.column() >= columnCount() )
285 return Qt::ItemFlags();
287 switch ( index.column() )
290 return Qt::ItemFlag::ItemIsEnabled;
293 return Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsEditable | Qt::ItemFlag::ItemIsSelectable;
298 return Qt::ItemFlags();
301QVariant QgsRasterBandFixedTemporalRangeModel::data(
const QModelIndex &index,
int role )
const
303 if ( !index.isValid() )
306 if ( index.row() < 0 || index.row() >= mBandCount || index.column() < 0 || index.column() >= columnCount() )
309 const int band = index.row() + 1;
314 case Qt::DisplayRole:
316 case Qt::ToolTipRole:
318 switch ( index.column() )
321 return mBandNames.value( band, QString::number( band ) );
324 return range.
begin().isValid() ? range.
begin() : QVariant();
327 return range.
end().isValid() ? range.
end() : QVariant();
335 case Qt::TextAlignmentRole:
337 switch ( index.column() )
340 return static_cast<Qt::Alignment::Int
>( Qt::AlignLeft | Qt::AlignVCenter );
344 return static_cast<Qt::Alignment::Int
>( Qt::AlignRight | Qt::AlignVCenter );
357QVariant QgsRasterBandFixedTemporalRangeModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
359 if ( role == Qt::DisplayRole && orientation == Qt::Horizontal )
366 return tr(
"Begin" );
373 return QAbstractItemModel::headerData( section, orientation, role );
376bool QgsRasterBandFixedTemporalRangeModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
378 if ( !index.isValid() )
381 if ( index.row() > mBandCount || index.row() < 0 )
384 const int band = index.row() + 1;
391 const QDateTime newValue = value.toDateTime();
392 if ( !newValue.isValid() )
395 switch ( index.column() )
400 emit dataChanged( index, index, QVector<int>() << role );
406 emit dataChanged( index, index, QVector<int>() << role );
422void QgsRasterBandFixedTemporalRangeModel::setLayerData(
QgsRasterLayer *layer,
const QMap<int, QgsDateTimeRange> &ranges )
430 for (
int band = 1; band <= mBandCount; ++band )
442QgsFixedTemporalRangeDelegate::QgsFixedTemporalRangeDelegate( QObject *parent )
443 : QStyledItemDelegate( parent )
448QWidget *QgsFixedTemporalRangeDelegate::createEditor( QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex & )
const
455void QgsFixedTemporalRangeDelegate::setModelData( QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index )
const
457 if (
QgsDateTimeEdit *dateTimeEdit = qobject_cast< QgsDateTimeEdit * >( editor ) )
459 model->setData( index, dateTimeEdit->dateTime() );
RasterTemporalMode
Raster layer temporal modes.
@ RedrawLayerOnly
Redraw the layer when temporal range changes, but don't apply any filtering. Useful when raster symbo...
@ FixedRangePerBand
Layer has a fixed temporal range per band (since QGIS 3.38)
@ TemporalRangeFromDataProvider
Mode when raster layer delegates temporal range handling to the dataprovider.
@ FixedTemporalRange
Mode when temporal properties have fixed start and end datetimes.
bool hasTemporalCapabilities() const
Returns true if the provider has temporal capabilities available.
The QgsDateTimeEdit class is a QDateTimeEdit with the capability of setting/reading null date/times.
void setAllowNull(bool allowNull)
Determines if the widget allows setting null date/time.
A generic dialog for building expression strings.
void setExpectedOutputFormat(const QString &expected)
Set the expected format string, which is shown in the dialog.
QgsExpressionBuilderWidget * expressionBuilder()
The builder widget that is used by the dialog.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsRasterDataProviderTemporalCapabilities * temporalCapabilities() override
Returns the provider's temporal capabilities.
virtual QString bandDescription(int bandNumber)
Returns the description for band bandNumber, or an empty string if the band is not valid or has not d...
QString displayBandName(int bandNumber) const
Generates a friendly, descriptive name for the specified bandNumber.
Implementation of map layer temporal properties for raster layers.
Qgis::RasterTemporalMode mode() const
Returns the temporal properties mode.
void setMode(Qgis::RasterTemporalMode mode)
Sets the temporal properties mode.
void setFixedTemporalRange(const QgsDateTimeRange &range)
Sets a temporal range to apply to the whole layer.
void setFixedRangePerBand(const QMap< int, QgsDateTimeRange > &ranges)
Sets the fixed temporal range for each band.
QMap< int, QgsDateTimeRange > fixedRangePerBand() const
Returns the fixed temporal range for each band.
const QgsDateTimeRange & fixedTemporalRange() const
Returns the fixed temporal range for the layer.
Represents a raster layer.
int bandCount() const
Returns the number of bands in this layer.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
bool isActive() const
Returns true if the temporal property is active.
void setIsActive(bool active)
Sets whether the temporal property is active.
T begin() const
Returns the beginning of the range.
T end() const
Returns the upper bound of the range.
bool includeEnd() const
Returns true if the end is inclusive, or false if the end is exclusive.
bool includeBeginning() const
Returns true if the beginning is inclusive, or false if the beginning is exclusive.
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
Single variable definition for use within a QgsExpressionContextScope.