19#include "moc_qgsrasterlayertemporalpropertieswidget.cpp"
40 mFixedRangeLowerExpression = QStringLiteral(
"make_datetime(%1,1,1,0,0,0) + make_interval(days:=@band)" ).arg( QDate::currentDate().year() );
41 mFixedRangeUpperExpression = QStringLiteral(
"make_datetime(%1,1,1,23,59,59) + make_interval(days:=@band)" ).arg( QDate::currentDate().year() );
43 mExtraWidgetLayout =
new QVBoxLayout();
44 mExtraWidgetLayout->setContentsMargins( 0, 0, 0, 0 );
45 mExtraWidgetLayout->addStretch();
46 mExtraWidgetContainer->setLayout( mExtraWidgetLayout );
73 mScaleUnitComboBox->setCurrentIndex( mScaleUnitComboBox->findData(
static_cast< int >(
Qgis::TemporalUnit::Days ) ) );
77 mFixedRangePerBandModel =
new QgsRasterBandFixedTemporalRangeModel(
this );
78 mBandRangesTable->verticalHeader()->setVisible(
false );
79 mBandRangesTable->setModel( mFixedRangePerBandModel );
80 QgsFixedTemporalRangeDelegate *tableDelegate =
new QgsFixedTemporalRangeDelegate( mBandRangesTable );
81 mBandRangesTable->setItemDelegateForColumn( 1, tableDelegate );
82 mBandRangesTable->setItemDelegateForColumn( 2, tableDelegate );
84 connect( mModeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, &QgsRasterLayerTemporalPropertiesWidget::modeChanged );
86 connect( mTemporalGroupBox, &QGroupBox::toggled,
this, &QgsRasterLayerTemporalPropertiesWidget::temporalGroupBoxChecked );
88 mStartTemporalDateTimeEdit->setDisplayFormat( QStringLiteral(
"yyyy-MM-dd HH:mm:ss" ) );
89 mEndTemporalDateTimeEdit->setDisplayFormat( QStringLiteral(
"yyyy-MM-dd HH:mm:ss" ) );
90 mOffsetDateTimeEdit->setDisplayFormat( QStringLiteral(
"yyyy-MM-dd HH:mm:ss" ) );
92 QMenu *calculateFixedRangePerBandMenu =
new QMenu( mCalculateFixedRangePerBandButton );
93 mCalculateFixedRangePerBandButton->setMenu( calculateFixedRangePerBandMenu );
94 mCalculateFixedRangePerBandButton->setPopupMode( QToolButton::InstantPopup );
95 QAction *calculateLowerAction =
new QAction(
"Calculate Beginning by Expression…", calculateFixedRangePerBandMenu );
96 calculateFixedRangePerBandMenu->addAction( calculateLowerAction );
97 connect( calculateLowerAction, &QAction::triggered,
this, [
this]
99 calculateRangeByExpression(
false );
101 QAction *calculateUpperAction =
new QAction(
"Calculate End by Expression…", calculateFixedRangePerBandMenu );
102 calculateFixedRangePerBandMenu->addAction( calculateUpperAction );
103 connect( calculateUpperAction, &QAction::triggered,
this, [
this]
105 calculateRangeByExpression(
true );
119 temporalProperties->
setBandNumber( mBandComboBox->currentBand() );
122 mEndTemporalDateTimeEdit->dateTime() );
141 mModeComboBox->setCurrentIndex( mModeComboBox->findData( QVariant::fromValue( temporalProperties->
mode() ) ) );
142 switch ( temporalProperties->
mode() )
145 mStackedWidget->setCurrentWidget( mPageAutomatic );
148 mStackedWidget->setCurrentWidget( mPageFixedRange );
151 mStackedWidget->setCurrentWidget( mPageRedrawOnly );
154 mStackedWidget->setCurrentWidget( mPageFixedRangePerBand );
157 mStackedWidget->setCurrentWidget( mPageRepresentsTemporalValues );
161 mBandComboBox->setLayer( mLayer );
162 mBandComboBox->setBand( temporalProperties->
bandNumber() );
167 mFixedRangePerBandModel->setLayerData( mLayer, temporalProperties->
fixedRangePerBand() );
168 mBandRangesTable->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
169 mBandRangesTable->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
170 mBandRangesTable->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch );
177 mTemporalGroupBox->setChecked( temporalProperties->
isActive() );
181 widget->syncToLayer( mLayer );
187 mExtraWidgets << widget;
188 mExtraWidgetLayout->insertWidget( mExtraWidgetLayout->count() - 1, widget );
191void QgsRasterLayerTemporalPropertiesWidget::temporalGroupBoxChecked(
bool checked )
195 widget->emit dynamicTemporalControlToggled( checked );
199void QgsRasterLayerTemporalPropertiesWidget::modeChanged()
201 if ( mModeComboBox->currentData().isValid() )
206 mStackedWidget->setCurrentWidget( mPageAutomatic );
209 mStackedWidget->setCurrentWidget( mPageFixedRange );
212 mStackedWidget->setCurrentWidget( mPageRedrawOnly );
215 mStackedWidget->setCurrentWidget( mPageFixedRangePerBand );
218 mStackedWidget->setCurrentWidget( mPageRepresentsTemporalValues );
224void QgsRasterLayerTemporalPropertiesWidget::calculateRangeByExpression(
bool isUpper )
233 expressionContext.
setHighlightedVariables( { QStringLiteral(
"band" ), QStringLiteral(
"band_name" ), QStringLiteral(
"band_description" )} );
236 dlg.
setExpectedOutputFormat( !isUpper ? tr(
"Temporal range start date / time" ) : tr(
"Temporal range end date / time" ) );
238 QList<QPair<QString, QVariant> > bandChoices;
239 for (
int band = 1; band <= mLayer->
bandCount(); ++band )
245 return createExpressionContextForBand( value.toInt() );
256 exp.prepare( &expressionContext );
257 for (
int band = 1; band <= mLayer->
bandCount(); ++band )
259 bandScope->
setVariable( QStringLiteral(
"band" ), band );
263 const QVariant res = exp.evaluate( &expressionContext );
264 mFixedRangePerBandModel->setData( mFixedRangePerBandModel->index( band - 1, isUpper ? 2 : 1 ), res, Qt::EditRole );
269QgsExpressionContext QgsRasterLayerTemporalPropertiesWidget::createExpressionContextForBand(
int band )
const
278 context.
setHighlightedVariables( { QStringLiteral(
"band" ), QStringLiteral(
"band_name" ), QStringLiteral(
"band_description" )} );
288QgsRasterBandFixedTemporalRangeModel::QgsRasterBandFixedTemporalRangeModel( QObject *parent )
289 : QAbstractItemModel( parent )
294int QgsRasterBandFixedTemporalRangeModel::columnCount(
const QModelIndex & )
const
299int QgsRasterBandFixedTemporalRangeModel::rowCount(
const QModelIndex &parent )
const
301 if ( parent.isValid() )
306QModelIndex QgsRasterBandFixedTemporalRangeModel::index(
int row,
int column,
const QModelIndex &parent )
const
308 if ( hasIndex( row, column, parent ) )
310 return createIndex( row, column, row );
313 return QModelIndex();
316QModelIndex QgsRasterBandFixedTemporalRangeModel::parent(
const QModelIndex &child )
const
319 return QModelIndex();
322Qt::ItemFlags QgsRasterBandFixedTemporalRangeModel::flags(
const QModelIndex &index )
const
324 if ( !index.isValid() )
325 return Qt::ItemFlags();
327 if ( index.row() < 0 || index.row() >= mBandCount || index.column() < 0 || index.column() >= columnCount() )
328 return Qt::ItemFlags();
330 switch ( index.column() )
333 return Qt::ItemFlag::ItemIsEnabled;
336 return Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsEditable | Qt::ItemFlag::ItemIsSelectable;
341 return Qt::ItemFlags();
344QVariant QgsRasterBandFixedTemporalRangeModel::data(
const QModelIndex &index,
int role )
const
346 if ( !index.isValid() )
349 if ( index.row() < 0 || index.row() >= mBandCount || index.column() < 0 || index.column() >= columnCount() )
352 const int band = index.row() + 1;
357 case Qt::DisplayRole:
359 case Qt::ToolTipRole:
361 switch ( index.column() )
364 return mBandNames.value( band, QString::number( band ) );
367 return range.
begin().isValid() ? range.
begin() : QVariant();
370 return range.
end().isValid() ? range.
end() : QVariant();
378 case Qt::TextAlignmentRole:
380 switch ( index.column() )
383 return static_cast<Qt::Alignment::Int
>( Qt::AlignLeft | Qt::AlignVCenter );
387 return static_cast<Qt::Alignment::Int
>( Qt::AlignRight | Qt::AlignVCenter );
400QVariant QgsRasterBandFixedTemporalRangeModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
402 if ( role == Qt::DisplayRole && orientation == Qt::Horizontal )
409 return tr(
"Begin" );
416 return QAbstractItemModel::headerData( section, orientation, role );
419bool QgsRasterBandFixedTemporalRangeModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
421 if ( !index.isValid() )
424 if ( index.row() > mBandCount || index.row() < 0 )
427 const int band = index.row() + 1;
434 const QDateTime newValue = value.toDateTime();
435 if ( !newValue.isValid() )
438 switch ( index.column() )
443 emit dataChanged( index, index, QVector<int>() << role );
449 emit dataChanged( index, index, QVector<int>() << role );
465void QgsRasterBandFixedTemporalRangeModel::setLayerData(
QgsRasterLayer *layer,
const QMap<int, QgsDateTimeRange> &ranges )
473 for (
int band = 1; band <= mBandCount; ++band )
485QgsFixedTemporalRangeDelegate::QgsFixedTemporalRangeDelegate( QObject *parent )
486 : QStyledItemDelegate( parent )
491QWidget *QgsFixedTemporalRangeDelegate::createEditor( QWidget *parent,
const QStyleOptionViewItem &,
const QModelIndex & )
const
498void QgsFixedTemporalRangeDelegate::setModelData( QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index )
const
500 if (
QgsDateTimeEdit *dateTimeEdit = qobject_cast< QgsDateTimeEdit * >( editor ) )
502 model->setData( index, dateTimeEdit->dateTime() );
TemporalUnit
Temporal units.
@ Milliseconds
Milliseconds.
RasterTemporalMode
Raster layer temporal modes.
@ RepresentsTemporalValues
Pixel values represent an datetime.
@ 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.
@ 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").
A representation of the interval between two datetime values.
double originalDuration() const
Returns the original interval duration.
Qgis::TemporalUnit originalUnit() const
Returns the original interval temporal unit.
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.
QDateTime temporalRepresentationOffset() const
Returns the temporal offset, which is a fixed datetime which should be added to individual pixel valu...
void setTemporalRepresentationOffset(const QDateTime &offset)
Sets the temporal offset, which is a fixed datetime which should be added to individual pixel values ...
const QgsInterval & temporalRepresentationScale() const
Returns the scale, which is an interval factor which should be applied to individual pixel values fro...
Qgis::RasterTemporalMode mode() const
Returns the temporal properties mode.
void setTemporalRepresentationScale(const QgsInterval &scale)
Sets the scale, which is an interval factor which should be applied to individual pixel values from t...
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.
int bandNumber() const
Returns the band number from which temporal values should be taken.
const QgsDateTimeRange & fixedTemporalRange() const
Returns the fixed temporal range for the layer.
void setBandNumber(int number)
Sets the band number from which temporal values should be taken.
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.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
Single variable definition for use within a QgsExpressionContextScope.