Show a read only table of band ranges in dialog when in dynamic range

per band mode
This commit is contained in:
Nyall Dawson 2024-03-21 15:19:30 +10:00 committed by Martin Dobias
parent 69c87d1478
commit d51d2a8841
3 changed files with 362 additions and 147 deletions

View File

@ -74,6 +74,10 @@ QgsRasterElevationPropertiesWidget::QgsRasterElevationPropertiesWidget( QgsRaste
mBandElevationTable->setItemDelegateForColumn( 1, tableDelegate );
mBandElevationTable->setItemDelegateForColumn( 2, tableDelegate );
mDynamicRangePerBandModel = new QgsRasterBandDynamicElevationRangeModel( this );
mBandDynamicElevationTable->verticalHeader()->setVisible( false );
mBandDynamicElevationTable->setModel( mDynamicRangePerBandModel );
QMenu *calculateFixedRangePerBandMenu = new QMenu( mCalculateFixedRangePerBandButton );
mCalculateFixedRangePerBandButton->setMenu( calculateFixedRangePerBandMenu );
mCalculateFixedRangePerBandButton->setPopupMode( QToolButton::InstantPopup );
@ -115,6 +119,16 @@ QgsRasterElevationPropertiesWidget::QgsRasterElevationPropertiesWidget( QgsRaste
onChanged();
} );
connect( mLowerExpressionWidget, qOverload< const QString &, bool >( &QgsFieldExpressionWidget::fieldChanged ), this, [this]( const QString & expression, bool isValid )
{
if ( isValid )
mDynamicRangePerBandModel->setLowerExpression( expression );
} );
connect( mUpperExpressionWidget, qOverload< const QString &, bool >( &QgsFieldExpressionWidget::fieldChanged ), this, [this]( const QString & expression, bool isValid )
{
if ( isValid )
mDynamicRangePerBandModel->setUpperExpression( expression );
} );
setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#elevation-properties" ) );
}
@ -181,6 +195,11 @@ void QgsRasterElevationPropertiesWidget::syncToLayer( QgsMapLayer *layer )
mBandElevationTable->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
mBandElevationTable->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch );
mDynamicRangePerBandModel->setLayer( mLayer );
mBandDynamicElevationTable->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
mBandDynamicElevationTable->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
mBandDynamicElevationTable->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch );
if ( QgsApplication::rasterRendererRegistry()->rendererCapabilities( mLayer->renderer()->type() ) & Qgis::RasterRendererCapability::UsesMultipleBands )
{
mWidgetFixedRangePerBand->hide();
@ -204,6 +223,9 @@ void QgsRasterElevationPropertiesWidget::syncToLayer( QgsMapLayer *layer )
mUpperExpressionWidget->setExpression(
props->dataDefinedProperties().property( QgsMapLayerElevationProperties::Property::RasterPerBandUpperElevation ).asExpression() );
mDynamicRangePerBandModel->setLowerExpression( mLowerExpressionWidget->expression() );
mDynamicRangePerBandModel->setUpperExpression( mUpperExpressionWidget->expression() );
QList<QPair<QString, QVariant> > bandChoices;
for ( int band = 1; band <= mLayer->bandCount(); ++band )
{
@ -601,6 +623,171 @@ void QgsRasterBandFixedElevationRangeModel::setLayerData( QgsRasterLayer *layer,
endResetModel();
}
//
// QgsRasterBandDynamicElevationRangeModel
//
QgsRasterBandDynamicElevationRangeModel::QgsRasterBandDynamicElevationRangeModel( QObject *parent )
: QAbstractItemModel( parent )
{
}
int QgsRasterBandDynamicElevationRangeModel::columnCount( const QModelIndex & ) const
{
return 3;
}
int QgsRasterBandDynamicElevationRangeModel::rowCount( const QModelIndex &parent ) const
{
if ( parent.isValid() || !mLayer )
return 0;
return mLayer->bandCount();
}
QModelIndex QgsRasterBandDynamicElevationRangeModel::index( int row, int column, const QModelIndex &parent ) const
{
if ( hasIndex( row, column, parent ) )
{
return createIndex( row, column, row );
}
return QModelIndex();
}
QModelIndex QgsRasterBandDynamicElevationRangeModel::parent( const QModelIndex &child ) const
{
Q_UNUSED( child )
return QModelIndex();
}
Qt::ItemFlags QgsRasterBandDynamicElevationRangeModel::flags( const QModelIndex &index ) const
{
if ( !index.isValid() || !mLayer )
return Qt::ItemFlags();
if ( index.row() < 0 || index.row() >= mLayer->bandCount() || index.column() < 0 || index.column() >= columnCount() )
return Qt::ItemFlags();
switch ( index.column() )
{
case 0:
case 1:
case 2:
return Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable;;
default:
break;
}
return Qt::ItemFlags();
}
QVariant QgsRasterBandDynamicElevationRangeModel::data( const QModelIndex &index, int role ) const
{
if ( !index.isValid() || !mLayer )
return QVariant();
if ( index.row() < 0 || index.row() >= mLayer->bandCount() || index.column() < 0 || index.column() >= columnCount() )
return QVariant();
const int band = index.row() + 1;
switch ( role )
{
case Qt::DisplayRole:
case Qt::EditRole:
case Qt::ToolTipRole:
{
switch ( index.column() )
{
case 0:
return mLayer->dataProvider() ? QVariant( mLayer->dataProvider()->displayBandName( band ) ) : QVariant( band );
case 1:
case 2:
{
const QString expressionString = index.column() == 1 ? mLowerExpression : mUpperExpression;
QgsExpression expression( expressionString );
QgsExpressionContext context;
context.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( mLayer ) );
QgsExpressionContextScope *bandScope = new QgsExpressionContextScope();
bandScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "band" ), band, true, false, tr( "Band number" ) ) );
bandScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "band_name" ), ( mLayer && mLayer->dataProvider() ) ? mLayer->dataProvider()->displayBandName( band ) : QString(), true, false, tr( "Band name" ) ) );
bandScope->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "band_description" ), ( mLayer && mLayer->dataProvider() ) ? mLayer->dataProvider()->bandDescription( band ) : QString(), true, false, tr( "Band description" ) ) );
context.appendScope( bandScope );
return expression.evaluate( &context );
}
default:
break;
}
break;
}
case Qt::TextAlignmentRole:
{
switch ( index.column() )
{
case 0:
return static_cast<Qt::Alignment::Int>( Qt::AlignLeft | Qt::AlignVCenter );
case 1:
case 2:
return static_cast<Qt::Alignment::Int>( Qt::AlignRight | Qt::AlignVCenter );
default:
break;
}
break;
}
default:
break;
}
return QVariant();
}
QVariant QgsRasterBandDynamicElevationRangeModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
if ( role == Qt::DisplayRole && orientation == Qt::Horizontal )
{
switch ( section )
{
case 0:
return tr( "Band" );
case 1:
return tr( "Lower" );
case 2:
return tr( "Upper" );
default:
break;
}
}
return QAbstractItemModel::headerData( section, orientation, role );
}
void QgsRasterBandDynamicElevationRangeModel::setLayer( QgsRasterLayer *layer )
{
beginResetModel();
mLayer = layer;
endResetModel();
}
void QgsRasterBandDynamicElevationRangeModel::setLowerExpression( const QString &expression )
{
mLowerExpression = expression;
emit dataChanged( index( 0, 1 ), index( rowCount() - 1, 1 ) );
}
void QgsRasterBandDynamicElevationRangeModel::setUpperExpression( const QString &expression )
{
mUpperExpression = expression;
emit dataChanged( index( 0, 2 ), index( rowCount() - 1, 2 ) );
}
//
// QgsFixedElevationRangeDelegate
//

View File

@ -52,6 +52,30 @@ class QgsRasterBandFixedElevationRangeModel : public QAbstractItemModel
QMap<int, QgsDoubleRange > mRanges;
};
class QgsRasterBandDynamicElevationRangeModel : public QAbstractItemModel
{
Q_OBJECT
public:
QgsRasterBandDynamicElevationRangeModel( QObject *parent );
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const override;
QModelIndex parent( const QModelIndex &child ) const override;
Qt::ItemFlags flags( const QModelIndex &index ) const override;
QVariant data( const QModelIndex &index, int role ) const override;
QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
void setLayer( QgsRasterLayer *layer );
void setLowerExpression( const QString &expression );
void setUpperExpression( const QString &expression );
private:
QPointer< QgsRasterLayer > mLayer;
QString mLowerExpression;
QString mUpperExpression;
};
class QgsFixedElevationRangeDelegate : public QStyledItemDelegate
{
Q_OBJECT
@ -92,6 +116,7 @@ class QgsRasterElevationPropertiesWidget : public QgsMapLayerConfigWidget, publi
QgsRasterLayer *mLayer = nullptr;
bool mBlockUpdates = false;
QgsRasterBandFixedElevationRangeModel *mFixedRangePerBandModel = nullptr;
QgsRasterBandDynamicElevationRangeModel *mDynamicRangePerBandModel = nullptr;
QString mFixedRangeLowerExpression = QStringLiteral( "@band" );
QString mFixedRangeUpperExpression = QStringLiteral( "@band" );

View File

@ -32,133 +32,6 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="mProfileChartGroupBox">
<property name="title">
<string>Profile Chart Appearance</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,2">
<item row="1" column="0" colspan="2">
<widget class="QgsStackedWidget" name="mSymbologyStackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="mPageLine">
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1,2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Line style</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QgsSymbolButton" name="mLineStyleButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="mPageFill">
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QgsSymbolButton" name="mFillStyleButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Limit</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Fill style</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsDoubleSpinBox" name="mElevationLimitSpinBox">
<property name="decimals">
<number>6</number>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Style</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mStyleComboBox"/>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mModeComboBox"/>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
@ -172,13 +45,6 @@
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Configuration</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QgsStackedWidget" name="mStackedWidget">
<property name="sizePolicy">
@ -476,13 +342,6 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Upper</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsFieldExpressionWidget" name="mLowerExpressionWidget" native="true">
<property name="sizePolicy">
@ -519,13 +378,163 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Upper</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QTableView" name="mBandDynamicElevationTable"/>
</item>
</layout>
</widget>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mModeComboBox"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="mProfileChartGroupBox">
<property name="title">
<string>Profile Chart Appearance</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="1,2">
<item row="1" column="0" colspan="2">
<widget class="QgsStackedWidget" name="mSymbologyStackedWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="mPageLine">
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1,2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Line style</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QgsSymbolButton" name="mLineStyleButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="mPageFill">
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QgsSymbolButton" name="mFillStyleButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Limit</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Fill style</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsDoubleSpinBox" name="mElevationLimitSpinBox">
<property name="decimals">
<number>6</number>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Style</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mStyleComboBox"/>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Configuration</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsStackedWidget</class>
<extends>QStackedWidget</extends>
<header>qgsstackedwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
@ -541,12 +550,6 @@
<extends>QComboBox</extends>
<header>qgsrasterbandcombobox.h</header>
</customwidget>
<customwidget>
<class>QgsStackedWidget</class>
<extends>QStackedWidget</extends>
<header>qgsstackedwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsFieldExpressionWidget</class>
<extends>QWidget</extends>