also use color ramp shader widget for pseudo color renderer (#7358)

This commit is contained in:
Peter Petrik 2018-07-06 03:23:29 +02:00 committed by Mathieu Pellerin
parent a261a668a0
commit 4f8c9e18ab
8 changed files with 202 additions and 1095 deletions

View File

@ -32,24 +32,44 @@ The other mode is used to style mesh layer contours (scalar datasets)
Creates new color ramp shader widget
%End
void initForUseWithRasterLayer();
void initializeForUseWithRasterLayer();
%Docstring
Allows quantile classification mode for raster layers
%End
void setRasterBand( QgsRasterDataProvider *dp, int band, const QgsRectangle &extent );
void setRasterDataProvider( QgsRasterDataProvider *dp );
%Docstring
Associates raster with the widget
Associates raster with the widget, only when used for raster layer
%End
void setMinMaxAndClassify( double min, double max );
void setRasterBand( int band );
%Docstring
Sets raster band, only when used for raster layer
%End
void setExtent( const QgsRectangle &extent );
%Docstring
Sets extent, only when used for raster layer
%End
void setMinimumMaximumAndClassify( double minimum, double maximum );
%Docstring
Sets min max and classify color tree
%End
void setMinMax( double min, double max );
void setMinimumMaximum( double minimum, double maximum );
%Docstring
Sets min max
%End
double minimum() const;
%Docstring
Gets min value
%End
double maximum() const;
%Docstring
Gets max value
%End
QgsColorRampShader shader() const;
@ -63,7 +83,7 @@ Sets widget state from the color ramp shader
%End
signals:
void minMaxChangedFromTree( double min, double max );
void minimumMaximumChangedFromTree( double minimum, double maximum );
%Docstring
Color ramp tree has changed
%End
@ -85,7 +105,7 @@ Classification mode changed
Executes the single band pseudo raster classification
%End
void loadMinMaxFromTree();
void loadMinimumMaximumFromTree();
%Docstring
Loads min and max values from color ramp tree
%End

View File

@ -12,6 +12,11 @@
class QgsSingleBandPseudoColorRendererWidget: QgsRasterRendererWidget
{
%Docstring
Single band pseudo color renderer widget consists of a color ramp shader widget,
a raster min max widget and a band selector.
%End
%TypeHeaderCode
#include "qgssinglebandpseudocolorrendererwidget.h"
@ -19,46 +24,46 @@ class QgsSingleBandPseudoColorRendererWidget: QgsRasterRendererWidget
public:
QgsSingleBandPseudoColorRendererWidget( QgsRasterLayer *layer, const QgsRectangle &extent = QgsRectangle() );
%Docstring
Creates new raster renderer widget
%End
static QgsRasterRendererWidget *create( QgsRasterLayer *layer, const QgsRectangle &extent ) /Factory/;
%Docstring
Creates new raster renderer widget
%End
virtual QgsRasterRenderer *renderer();
QgsColorRampShader *shaderFunction() const /Factory/;
%Docstring
Returns shader function used in the renderer. Caller takes ownership and deletes it.
%End
virtual void setMapCanvas( QgsMapCanvas *canvas );
virtual void doComputations();
virtual QgsRasterMinMaxWidget *minMaxWidget();
int currentBand() const;
%Docstring
Returns the current raster band number
%End
void setFromRenderer( const QgsRasterRenderer *r );
%Docstring
Set state of the widget from renderer settings
%End
public slots:
void classify();
%Docstring
Executes the single band pseudo raster classficiation
%End
void loadMinMax( int bandNo, double min, double max );
%Docstring
called when new min/max values are loaded
%End
void loadMinMaxFromTree();
void loadMinMaxFromTree( double min, double max );
%Docstring
called when the color ramp tree has changed
%End
};
/************************************************************************
* This file has been generated automatically from *
* *

View File

@ -79,14 +79,14 @@ void QgsMeshRendererScalarSettingsWidget::minMaxChanged()
{
double min = lineEditValue( mScalarMinLineEdit );
double max = lineEditValue( mScalarMaxLineEdit );
mScalarColorRampShaderWidget->setMinMax( min, max );
mScalarColorRampShaderWidget->setMinimumMaximum( min, max );
}
void QgsMeshRendererScalarSettingsWidget::minMaxEdited()
{
double min = lineEditValue( mScalarMinLineEdit );
double max = lineEditValue( mScalarMaxLineEdit );
mScalarColorRampShaderWidget->setMinMaxAndClassify( min, max );
mScalarColorRampShaderWidget->setMinimumMaximumAndClassify( min, max );
}
void QgsMeshRendererScalarSettingsWidget::recalculateMinMaxButtonClicked()
@ -95,7 +95,7 @@ void QgsMeshRendererScalarSettingsWidget::recalculateMinMaxButtonClicked()
calcMinMax( mActiveDataset, min, max );
whileBlocking( mScalarMinLineEdit )->setText( QString::number( min ) );
whileBlocking( mScalarMaxLineEdit )->setText( QString::number( max ) );
mScalarColorRampShaderWidget->setMinMaxAndClassify( min, max );
mScalarColorRampShaderWidget->setMinimumMaximumAndClassify( min, max );
}
void QgsMeshRendererScalarSettingsWidget::setActiveDataset( int activeDataset )

View File

@ -90,22 +90,32 @@ QgsColorRampShaderWidget::QgsColorRampShaderWidget( QWidget *parent )
connect( mClassifyButton, &QPushButton::clicked, this, &QgsColorRampShaderWidget::applyColorRamp );
connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsColorRampShaderWidget::applyColorRamp );
connect( mNumberOfEntriesSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsColorRampShaderWidget::classify );
connect( mClipCheckBox, &QAbstractButton::toggled, this, &QgsColorRampShaderWidget::widgetChanged );
}
void QgsColorRampShaderWidget::initForUseWithRasterLayer()
void QgsColorRampShaderWidget::initializeForUseWithRasterLayer()
{
Q_ASSERT( mClassificationModeComboBox->findData( QgsColorRampShader::Quantile < 0 ) );
mClassificationModeComboBox->addItem( tr( "Quantile" ), QgsColorRampShader::Quantile );
mLoadFromBandButton->setVisible( bool( mRasterDataProvider ) ); // only for raster version
}
void QgsColorRampShaderWidget::setRasterBand( QgsRasterDataProvider *dp,
int band,
const QgsRectangle &extent )
void QgsColorRampShaderWidget::setRasterDataProvider( QgsRasterDataProvider *dp )
{
mRasterDataProvider = dp;
loadMinimumMaximumFromTree();
}
void QgsColorRampShaderWidget::setRasterBand( int band )
{
mBand = band;
loadMinimumMaximumFromTree();
}
void QgsColorRampShaderWidget::setExtent( const QgsRectangle &extent )
{
mExtent = extent;
loadMinimumMaximumFromTree();
}
QgsColorRampShader QgsColorRampShaderWidget::shader() const
@ -265,7 +275,7 @@ void QgsColorRampShaderWidget::mAddEntryButton_clicked()
mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder );
autoLabel();
loadMinMaxFromTree();
loadMinimumMaximumFromTree();
emit widgetChanged();
}
@ -283,7 +293,7 @@ void QgsColorRampShaderWidget::mDeleteEntryButton_clicked()
delete item;
}
loadMinMaxFromTree();
loadMinimumMaximumFromTree();
emit widgetChanged();
}
@ -400,7 +410,7 @@ void QgsColorRampShaderWidget::mLoadFromBandButton_clicked()
QMessageBox::warning( this, tr( "Load Color Map" ), tr( "The color map for band %1 has no entries." ).arg( mBand ) );
}
loadMinMaxFromTree();
loadMinimumMaximumFromTree();
emit widgetChanged();
}
@ -492,7 +502,7 @@ void QgsColorRampShaderWidget::mLoadFromFileButton_clicked()
QMessageBox::warning( this, tr( "Load Color Map from File" ), tr( "Read access denied. Adjust the file permissions and try again.\n\n" ) );
}
loadMinMaxFromTree();
loadMinimumMaximumFromTree();
emit widgetChanged();
}
@ -577,7 +587,7 @@ void QgsColorRampShaderWidget::mColormapTreeWidget_itemDoubleClicked( QTreeWidge
if ( newColor.isValid() )
{
item->setBackground( ColorColumn, QBrush( newColor ) );
loadMinMaxFromTree();
loadMinimumMaximumFromTree();
emit widgetChanged();
}
}
@ -601,7 +611,7 @@ void QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited( QTreeWidgetItem *
mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder );
autoLabel();
loadMinMaxFromTree();
loadMinimumMaximumFromTree();
emit widgetChanged();
}
@ -678,25 +688,35 @@ void QgsColorRampShaderWidget::mColorInterpolationComboBox_currentIndexChanged(
emit widgetChanged();
}
void QgsColorRampShaderWidget::setMinMaxAndClassify( double min, double max )
void QgsColorRampShaderWidget::setMinimumMaximumAndClassify( double min, double max )
{
if ( !qgsDoubleNear( mMin, min ) || !qgsDoubleNear( mMax, max ) )
{
mMin = min;
mMax = max;
setMinimumMaximum( min, max );
classify();
}
}
void QgsColorRampShaderWidget::setMinMax( double min, double max )
void QgsColorRampShaderWidget::setMinimumMaximum( double min, double max )
{
mMin = min;
mMax = max;
resetClassifyButton();
}
void QgsColorRampShaderWidget::loadMinMaxFromTree()
double QgsColorRampShaderWidget::minimum() const
{
return mMin;
}
double QgsColorRampShaderWidget::maximum() const
{
return mMax;
}
void QgsColorRampShaderWidget::loadMinimumMaximumFromTree()
{
QTreeWidgetItem *item = mColormapTreeWidget->topLevelItem( 0 );
if ( !item )
@ -712,7 +732,7 @@ void QgsColorRampShaderWidget::loadMinMaxFromTree()
{
mMin = min;
mMax = max;
emit minMaxChangedFromTree( min, max );
emit minimumMaximumChangedFromTree( min, max );
}
}
@ -744,7 +764,7 @@ void QgsColorRampShaderWidget::changeColor()
item->setBackground( ColorColumn, QBrush( newColor ) );
}
loadMinMaxFromTree();
loadMinimumMaximumFromTree();
emit widgetChanged();
}
}
@ -772,7 +792,7 @@ void QgsColorRampShaderWidget::changeOpacity()
item->setBackground( ColorColumn, QBrush( newColor ) );
}
loadMinMaxFromTree();
loadMinimumMaximumFromTree();
emit widgetChanged();
}
}

View File

@ -49,16 +49,28 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo
QgsColorRampShaderWidget( QWidget *parent = nullptr );
//! Allows quantile classification mode for raster layers
void initForUseWithRasterLayer();
void initializeForUseWithRasterLayer();
//! Associates raster with the widget
void setRasterBand( QgsRasterDataProvider *dp, int band, const QgsRectangle &extent );
//! Associates raster with the widget, only when used for raster layer
void setRasterDataProvider( QgsRasterDataProvider *dp );
//! Sets raster band, only when used for raster layer
void setRasterBand( int band );
//! Sets extent, only when used for raster layer
void setExtent( const QgsRectangle &extent );
//! Sets min max and classify color tree
void setMinMaxAndClassify( double min, double max );
void setMinimumMaximumAndClassify( double minimum, double maximum );
//! Sets min max
void setMinMax( double min, double max );
void setMinimumMaximum( double minimum, double maximum );
//! Gets min value
double minimum() const;
//! Gets max value
double maximum() const;
//! Returns shared function used in the renderer
QgsColorRampShader shader() const;
@ -68,7 +80,7 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo
signals:
//! Color ramp tree has changed
void minMaxChangedFromTree( double min, double max );
void minimumMaximumChangedFromTree( double minimum, double maximum );
//! Widget changed
void widgetChanged();
@ -84,7 +96,7 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo
void classify();
//! Loads min and max values from color ramp tree
void loadMinMaxFromTree();
void loadMinimumMaximumFromTree();
protected:
//! Populates color ramp tree from ramp items
@ -101,8 +113,8 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo
/**
* Generate labels from the values in the color map.
* Skip labels which were manually edited (black text).
* Text of generated labels is made gray
* Skip labels which were manually edited (black text).
* Text of generated labels is made gray
*/
void autoLabel();

View File

@ -23,6 +23,7 @@
#include "qgsrasterminmaxwidget.h"
#include "qgstreewidgetitem.h"
#include "qgssettings.h"
#include "qgsmapcanvas.h"
// for color ramps - todo add rasterStyle and refactor raster vs. vector ramps
#include "qgsstyle.h"
@ -47,32 +48,12 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
setupUi( this );
connect( mAddEntryButton, &QPushButton::clicked, this, &QgsSingleBandPseudoColorRendererWidget::mAddEntryButton_clicked );
connect( mDeleteEntryButton, &QPushButton::clicked, this, &QgsSingleBandPseudoColorRendererWidget::mDeleteEntryButton_clicked );
connect( mLoadFromBandButton, &QPushButton::clicked, this, &QgsSingleBandPseudoColorRendererWidget::mLoadFromBandButton_clicked );
connect( mLoadFromFileButton, &QPushButton::clicked, this, &QgsSingleBandPseudoColorRendererWidget::mLoadFromFileButton_clicked );
connect( mExportToFileButton, &QPushButton::clicked, this, &QgsSingleBandPseudoColorRendererWidget::mExportToFileButton_clicked );
connect( mUnitLineEdit, &QLineEdit::textEdited, this, &QgsSingleBandPseudoColorRendererWidget::mUnitLineEdit_textEdited );
connect( mColormapTreeWidget, &QTreeWidget::itemDoubleClicked, this, &QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemDoubleClicked );
connect( mColorInterpolationComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSingleBandPseudoColorRendererWidget::mColorInterpolationComboBox_currentIndexChanged );
mColorRampShaderWidget->initializeForUseWithRasterLayer();
connect( mMinLineEdit, &QLineEdit::textChanged, this, &QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textChanged );
connect( mMaxLineEdit, &QLineEdit::textChanged, this, &QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textChanged );
connect( mMinLineEdit, &QLineEdit::textEdited, this, &QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textEdited );
connect( mMaxLineEdit, &QLineEdit::textEdited, this, &QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textEdited );
connect( mClassificationModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSingleBandPseudoColorRendererWidget::mClassificationModeComboBox_currentIndexChanged );
contextMenu = new QMenu( tr( "Options" ), this );
contextMenu->addAction( tr( "Change Color…" ), this, SLOT( changeColor() ) );
contextMenu->addAction( tr( "Change Opacity…" ), this, SLOT( changeOpacity() ) );
mColormapTreeWidget->setColumnWidth( ColorColumn, 50 );
mColormapTreeWidget->setContextMenuPolicy( Qt::CustomContextMenu );
mColormapTreeWidget->setSelectionMode( QAbstractItemView::ExtendedSelection );
connect( mColormapTreeWidget, &QTreeView::customContextMenuRequested, this, [ = ]( QPoint ) { contextMenu->exec( QCursor::pos() ); }
);
QString defaultPalette = settings.value( QStringLiteral( "Raster/defaultPalette" ), "" ).toString();
btnColorRamp->setColorRampFromName( defaultPalette );
if ( !mRasterLayer )
{
@ -98,20 +79,9 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
mMinMaxContainerWidget->setLayout( layout );
layout->addWidget( mMinMaxWidget );
mColorRampShaderWidget->setRasterDataProvider( provider );
mBandComboBox->setLayer( mRasterLayer );
mColorInterpolationComboBox->addItem( tr( "Discrete" ), QgsColorRampShader::Discrete );
mColorInterpolationComboBox->addItem( tr( "Linear" ), QgsColorRampShader::Interpolated );
mColorInterpolationComboBox->addItem( tr( "Exact" ), QgsColorRampShader::Exact );
mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Interpolated ) );
mClassificationModeComboBox->addItem( tr( "Continuous" ), QgsColorRampShader::Continuous );
mClassificationModeComboBox->addItem( tr( "Equal Interval" ), QgsColorRampShader::EqualInterval );
mClassificationModeComboBox->addItem( tr( "Quantile" ), QgsColorRampShader::Quantile );
mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( QgsColorRampShader::Continuous ) );
mNumberOfEntriesSpinBox->setValue( 5 ); // some default
setFromRenderer( layer->renderer() );
connect( mMinMaxWidget, &QgsRasterMinMaxWidget::widgetChanged, this, &QgsSingleBandPseudoColorRendererWidget::widgetChanged );
@ -129,58 +99,22 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget(
mMinMaxWidget->doComputations();
}
mClassificationModeComboBox_currentIndexChanged( 0 );
whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
resetClassifyButton();
connect( mClassificationModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsSingleBandPseudoColorRendererWidget::classify );
connect( mClassifyButton, &QPushButton::clicked, this, &QgsSingleBandPseudoColorRendererWidget::applyColorRamp );
connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsSingleBandPseudoColorRendererWidget::applyColorRamp );
connect( mNumberOfEntriesSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsSingleBandPseudoColorRendererWidget::classify );
connect( mBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsSingleBandPseudoColorRendererWidget::classify );
connect( mBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsSingleBandPseudoColorRendererWidget::bandChanged );
connect( mClipCheckBox, &QAbstractButton::toggled, this, &QgsRasterRendererWidget::widgetChanged );
}
QgsColorRampShader *QgsSingleBandPseudoColorRendererWidget::shaderFunction() const
{
QgsColorRampShader *colorRampShader = new QgsColorRampShader( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
colorRampShader->setColorRampType( static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ) );
colorRampShader->setClassificationMode( static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) );
colorRampShader->setClip( mClipCheckBox->isChecked() );
//iterate through mColormapTreeWidget and set colormap info of layer
QList<QgsColorRampShader::ColorRampItem> colorRampItems;
int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
QTreeWidgetItem *currentItem = nullptr;
for ( int i = 0; i < topLevelItemCount; ++i )
{
currentItem = mColormapTreeWidget->topLevelItem( i );
if ( !currentItem )
{
continue;
}
QgsColorRampShader::ColorRampItem newColorRampItem;
newColorRampItem.value = currentItem->text( ValueColumn ).toDouble();
newColorRampItem.color = currentItem->background( ColorColumn ).color();
newColorRampItem.label = currentItem->text( LabelColumn );
colorRampItems.append( newColorRampItem );
}
// sort the shader items
std::sort( colorRampItems.begin(), colorRampItems.end() );
colorRampShader->setColorRampItemList( colorRampItems );
if ( !btnColorRamp->isNull() )
{
colorRampShader->setSourceColorRamp( btnColorRamp->colorRamp() );
}
return colorRampShader;
connect( mColorRampShaderWidget, &QgsColorRampShaderWidget::minimumMaximumChangedFromTree, this, &QgsSingleBandPseudoColorRendererWidget::loadMinMaxFromTree );
connect( mColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsSingleBandPseudoColorRendererWidget::widgetChanged );
}
QgsRasterRenderer *QgsSingleBandPseudoColorRendererWidget::renderer()
{
QgsRasterShader *rasterShader = new QgsRasterShader();
rasterShader->setRasterShaderFunction( shaderFunction() );
mColorRampShaderWidget->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
mColorRampShaderWidget->setExtent( mMinMaxWidget->extent() );
QgsColorRampShader *fcn = new QgsColorRampShader( mColorRampShaderWidget->shader() );
rasterShader->setRasterShaderFunction( fcn );
int bandNumber = mBandComboBox->currentBand();
QgsSingleBandPseudoColorRenderer *renderer = new QgsSingleBandPseudoColorRenderer( mRasterLayer->dataProvider(), bandNumber, rasterShader );
@ -195,6 +129,8 @@ void QgsSingleBandPseudoColorRendererWidget::doComputations()
mMinMaxWidget->doComputations();
}
QgsRasterMinMaxWidget *QgsSingleBandPseudoColorRendererWidget::minMaxWidget() { return mMinMaxWidget; }
int QgsSingleBandPseudoColorRendererWidget::currentBand() const
{
return mBandComboBox->currentBand();
@ -204,239 +140,7 @@ void QgsSingleBandPseudoColorRendererWidget::setMapCanvas( QgsMapCanvas *canvas
{
QgsRasterRendererWidget::setMapCanvas( canvas );
mMinMaxWidget->setMapCanvas( canvas );
}
void QgsSingleBandPseudoColorRendererWidget::autoLabel()
{
QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() );
bool discrete = interpolation == QgsColorRampShader::Discrete;
QString unit = mUnitLineEdit->text();
QString label;
int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
QTreeWidgetItem *currentItem = nullptr;
for ( int i = 0; i < topLevelItemCount; ++i )
{
currentItem = mColormapTreeWidget->topLevelItem( i );
//If the item is null or does not have a pixel values set, skip
if ( !currentItem || currentItem->text( ValueColumn ).isEmpty() )
{
continue;
}
if ( discrete )
{
if ( i == 0 )
{
label = "<= " + currentItem->text( ValueColumn ) + unit;
}
else if ( currentItem->text( ValueColumn ).toDouble() == std::numeric_limits<double>::infinity() )
{
label = "> " + mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + unit;
}
else
{
label = mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + " - " + currentItem->text( ValueColumn ) + unit;
}
}
else
{
label = currentItem->text( ValueColumn ) + unit;
}
if ( currentItem->text( LabelColumn ).isEmpty() || currentItem->text( LabelColumn ) == label || currentItem->foreground( LabelColumn ).color() == QColor( Qt::gray ) )
{
currentItem->setText( LabelColumn, label );
currentItem->setForeground( LabelColumn, QBrush( QColor( Qt::gray ) ) );
}
}
}
void QgsSingleBandPseudoColorRendererWidget::setUnitFromLabels()
{
QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() );
bool discrete = interpolation == QgsColorRampShader::Discrete;
QStringList allSuffixes;
QString label;
int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
QTreeWidgetItem *currentItem = nullptr;
for ( int i = 0; i < topLevelItemCount; ++i )
{
currentItem = mColormapTreeWidget->topLevelItem( i );
//If the item is null or does not have a pixel values set, skip
if ( !currentItem || currentItem->text( ValueColumn ).isEmpty() )
{
continue;
}
if ( discrete )
{
if ( i == 0 )
{
label = "<= " + currentItem->text( ValueColumn );
}
else if ( currentItem->text( ValueColumn ).toDouble() == std::numeric_limits<double>::infinity() )
{
label = "> " + mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn );
}
else
{
label = mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + " - " + currentItem->text( ValueColumn );
}
}
else
{
label = currentItem->text( ValueColumn );
}
if ( currentItem->text( LabelColumn ).startsWith( label ) )
{
allSuffixes.append( currentItem->text( LabelColumn ).mid( label.length() ) );
}
}
// find most common suffix
QStringList suffixes = QStringList( allSuffixes );
suffixes.removeDuplicates();
int max = 0;
QString unit;
for ( int i = 0; i < suffixes.count(); ++i )
{
int n = allSuffixes.count( suffixes[i] );
if ( n > max )
{
max = n;
unit = suffixes[i];
}
}
// Set this suffix as unit if at least used twice
if ( max >= 2 )
{
mUnitLineEdit->setText( unit );
}
autoLabel();
}
void QgsSingleBandPseudoColorRendererWidget::mAddEntryButton_clicked()
{
QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget );
newItem->setText( ValueColumn, QStringLiteral( "0" ) );
newItem->setBackground( ColorColumn, QBrush( QColor( Qt::magenta ) ) );
newItem->setText( LabelColumn, QString() );
newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
connect( newItem, &QgsTreeWidgetItemObject::itemEdited,
this, &QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemEdited );
mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder );
autoLabel();
loadMinMaxFromTree();
emit widgetChanged();
}
void QgsSingleBandPseudoColorRendererWidget::mDeleteEntryButton_clicked()
{
QList<QTreeWidgetItem *> itemList;
itemList = mColormapTreeWidget->selectedItems();
if ( itemList.isEmpty() )
{
return;
}
Q_FOREACH ( QTreeWidgetItem *item, itemList )
{
delete item;
}
loadMinMaxFromTree();
emit widgetChanged();
}
void QgsSingleBandPseudoColorRendererWidget::classify()
{
std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
if ( !ramp || std::isnan( lineEditValue( mMinLineEdit ) ) || std::isnan( lineEditValue( mMaxLineEdit ) ) )
{
return;
}
std::unique_ptr<QgsSingleBandPseudoColorRenderer> pr( new QgsSingleBandPseudoColorRenderer( mRasterLayer->dataProvider(), mBandComboBox->currentBand(), nullptr ) );
pr->setClassificationMin( lineEditValue( mMinLineEdit ) );
pr->setClassificationMax( lineEditValue( mMaxLineEdit ) );
pr->createShader( ramp.release(), static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ), static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ), mNumberOfEntriesSpinBox->value(), mClipCheckBox->isChecked(), minMaxWidget()->extent() );
const QgsRasterShader *rasterShader = pr->shader();
if ( rasterShader )
{
const QgsColorRampShader *colorRampShader = dynamic_cast<const QgsColorRampShader *>( rasterShader->rasterShaderFunction() );
if ( colorRampShader )
{
mColormapTreeWidget->clear();
const QList<QgsColorRampShader::ColorRampItem> colorRampItemList = colorRampShader->colorRampItemList();
for ( const QgsColorRampShader::ColorRampItem &item : colorRampItemList )
{
QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget );
newItem->setText( ValueColumn, QString::number( item.value, 'g', 15 ) );
newItem->setBackground( ColorColumn, QBrush( item.color ) );
newItem->setText( LabelColumn, item.label );
newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
connect( newItem, &QgsTreeWidgetItemObject::itemEdited,
this, &QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemEdited );
}
mClipCheckBox->setChecked( colorRampShader->clip() );
}
}
autoLabel();
emit widgetChanged();
}
void QgsSingleBandPseudoColorRendererWidget::mClassificationModeComboBox_currentIndexChanged( int index )
{
QgsColorRampShader::ClassificationMode mode = static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->itemData( index ).toInt() );
mNumberOfEntriesSpinBox->setEnabled( mode != QgsColorRampShader::Continuous );
mMinLineEdit->setEnabled( mode != QgsColorRampShader::Quantile );
mMaxLineEdit->setEnabled( mode != QgsColorRampShader::Quantile );
}
void QgsSingleBandPseudoColorRendererWidget::applyColorRamp()
{
std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() );
if ( !ramp )
{
return;
}
if ( !btnColorRamp->colorRampName().isEmpty() )
{
// Remember last used color ramp
QgsSettings settings;
settings.setValue( QStringLiteral( "Raster/defaultPalette" ), btnColorRamp->colorRampName() );
}
bool enableContinuous = ( ramp->count() > 0 );
mClassificationModeComboBox->setEnabled( enableContinuous );
if ( !enableContinuous )
{
mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( QgsColorRampShader::EqualInterval ) );
}
classify();
}
void QgsSingleBandPseudoColorRendererWidget::populateColormapTreeWidget( const QList<QgsColorRampShader::ColorRampItem> &colorRampItems )
{
mColormapTreeWidget->clear();
QList<QgsColorRampShader::ColorRampItem>::const_iterator it = colorRampItems.constBegin();
for ( ; it != colorRampItems.constEnd(); ++it )
{
QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget );
newItem->setText( ValueColumn, QString::number( it->value, 'g', 15 ) );
newItem->setBackground( ColorColumn, QBrush( it->color ) );
newItem->setText( LabelColumn, it->label );
newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
connect( newItem, &QgsTreeWidgetItemObject::itemEdited,
this, &QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemEdited );
}
setUnitFromLabels();
mColorRampShaderWidget->setExtent( mMinMaxWidget->extent() );
}
void QgsSingleBandPseudoColorRendererWidget::mLoadFromBandButton_clicked()
@ -447,232 +151,10 @@ void QgsSingleBandPseudoColorRendererWidget::mLoadFromBandButton_clicked()
}
int bandIndex = mBandComboBox->currentBand();
QList<QgsColorRampShader::ColorRampItem> colorRampList = mRasterLayer->dataProvider()->colorTable( bandIndex );
if ( !colorRampList.isEmpty() )
{
populateColormapTreeWidget( colorRampList );
mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Interpolated ) );
}
else
{
QMessageBox::warning( this, tr( "Load Color Map" ), tr( "The color map for band %1 has no entries." ).arg( bandIndex ) );
}
loadMinMaxFromTree();
mColorRampShaderWidget->setRasterBand( bandIndex );
emit widgetChanged();
}
void QgsSingleBandPseudoColorRendererWidget::mLoadFromFileButton_clicked()
{
int lineCounter = 0;
bool importError = false;
QString badLines;
QgsSettings settings;
QString lastDir = settings.value( QStringLiteral( "lastColorMapDir" ), QDir::homePath() ).toString();
QString fileName = QFileDialog::getOpenFileName( this, tr( "Load Color Map from File" ), lastDir, tr( "Textfile (*.txt)" ) );
QFile inputFile( fileName );
if ( inputFile.open( QFile::ReadOnly ) )
{
//clear the current tree
mColormapTreeWidget->clear();
QTextStream inputStream( &inputFile );
QString inputLine;
QStringList inputStringComponents;
QList<QgsColorRampShader::ColorRampItem> colorRampItems;
//read through the input looking for valid data
while ( !inputStream.atEnd() )
{
lineCounter++;
inputLine = inputStream.readLine();
if ( !inputLine.isEmpty() )
{
if ( !inputLine.simplified().startsWith( '#' ) )
{
if ( inputLine.contains( QLatin1String( "INTERPOLATION" ), Qt::CaseInsensitive ) )
{
inputStringComponents = inputLine.split( ':' );
if ( inputStringComponents.size() == 2 )
{
if ( inputStringComponents[1].trimmed().toUpper().compare( QLatin1String( "INTERPOLATED" ), Qt::CaseInsensitive ) == 0 )
{
mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Interpolated ) );
}
else if ( inputStringComponents[1].trimmed().toUpper().compare( QLatin1String( "DISCRETE" ), Qt::CaseInsensitive ) == 0 )
{
mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Discrete ) );
}
else
{
mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Exact ) );
}
}
else
{
importError = true;
badLines = badLines + QString::number( lineCounter ) + ":\t[" + inputLine + "]\n";
}
}
else
{
inputStringComponents = inputLine.split( ',' );
if ( inputStringComponents.size() == 6 )
{
QgsColorRampShader::ColorRampItem currentItem( inputStringComponents[0].toDouble(),
QColor::fromRgb( inputStringComponents[1].toInt(), inputStringComponents[2].toInt(),
inputStringComponents[3].toInt(), inputStringComponents[4].toInt() ),
inputStringComponents[5] );
colorRampItems.push_back( currentItem );
}
else
{
importError = true;
badLines = badLines + QString::number( lineCounter ) + ":\t[" + inputLine + "]\n";
}
}
}
}
lineCounter++;
}
populateColormapTreeWidget( colorRampItems );
QFileInfo fileInfo( fileName );
settings.setValue( QStringLiteral( "lastColorMapDir" ), fileInfo.absoluteDir().absolutePath() );
if ( importError )
{
QMessageBox::warning( this, tr( "Load Color Map from File" ), tr( "The following lines contained errors\n\n" ) + badLines );
}
}
else if ( !fileName.isEmpty() )
{
QMessageBox::warning( this, tr( "Load Color Map from File" ), tr( "Read access denied. Adjust the file permissions and try again.\n\n" ) );
}
loadMinMaxFromTree();
emit widgetChanged();
}
void QgsSingleBandPseudoColorRendererWidget::mExportToFileButton_clicked()
{
QgsSettings settings;
QString lastDir = settings.value( QStringLiteral( "lastColorMapDir" ), QDir::homePath() ).toString();
QString fileName = QFileDialog::getSaveFileName( this, tr( "Save Color Map as File" ), lastDir, tr( "Textfile (*.txt)" ) );
if ( !fileName.isEmpty() )
{
if ( !fileName.endsWith( QLatin1String( ".txt" ), Qt::CaseInsensitive ) )
{
fileName = fileName + ".txt";
}
QFile outputFile( fileName );
if ( outputFile.open( QFile::WriteOnly | QIODevice::Truncate ) )
{
QTextStream outputStream( &outputFile );
outputStream << "# " << tr( "QGIS Generated Color Map Export File" ) << '\n';
outputStream << "INTERPOLATION:";
QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() );
switch ( interpolation )
{
case QgsColorRampShader::Interpolated:
outputStream << "INTERPOLATED\n";
break;
case QgsColorRampShader::Discrete:
outputStream << "DISCRETE\n";
break;
case QgsColorRampShader::Exact:
outputStream << "EXACT\n";
break;
}
int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
QTreeWidgetItem *currentItem = nullptr;
QColor color;
for ( int i = 0; i < topLevelItemCount; ++i )
{
currentItem = mColormapTreeWidget->topLevelItem( i );
if ( !currentItem )
{
continue;
}
color = currentItem->background( ColorColumn ).color();
outputStream << currentItem->text( ValueColumn ).toDouble() << ',';
outputStream << color.red() << ',' << color.green() << ',' << color.blue() << ',' << color.alpha() << ',';
if ( currentItem->text( LabelColumn ).isEmpty() )
{
outputStream << "Color entry " << i + 1 << '\n';
}
else
{
outputStream << currentItem->text( LabelColumn ) << '\n';
}
}
outputStream.flush();
outputFile.close();
QFileInfo fileInfo( fileName );
settings.setValue( QStringLiteral( "lastColorMapDir" ), fileInfo.absoluteDir().absolutePath() );
}
else
{
QMessageBox::warning( this, tr( "Save Color Map as File" ), tr( "Write access denied. Adjust the file permissions and try again.\n\n" ) );
}
}
}
void QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, int column )
{
if ( !item )
{
return;
}
if ( column == ColorColumn )
{
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
QColor newColor = QgsColorDialog::getColor( item->background( column ).color(), this, QStringLiteral( "Change Color" ), true );
if ( newColor.isValid() )
{
item->setBackground( ColorColumn, QBrush( newColor ) );
loadMinMaxFromTree();
emit widgetChanged();
}
}
else
{
if ( column == LabelColumn )
{
// Set text color to default black, which signifies a manually edited label
item->setForeground( LabelColumn, QBrush() );
}
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
}
}
void QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemEdited( QTreeWidgetItem *item, int column )
{
Q_UNUSED( item );
if ( column == ValueColumn )
{
mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder );
autoLabel();
loadMinMaxFromTree();
emit widgetChanged();
}
else if ( column == LabelColumn )
{
// call autoLabel to fill when empty or gray out when same as autoLabel
autoLabel();
emit widgetChanged();
}
}
void QgsSingleBandPseudoColorRendererWidget::setFromRenderer( const QgsRasterRenderer *r )
{
const QgsSingleBandPseudoColorRenderer *pr = dynamic_cast<const QgsSingleBandPseudoColorRenderer *>( r );
@ -687,36 +169,7 @@ void QgsSingleBandPseudoColorRendererWidget::setFromRenderer( const QgsRasterRen
const QgsColorRampShader *colorRampShader = dynamic_cast<const QgsColorRampShader *>( rasterShader->rasterShaderFunction() );
if ( colorRampShader )
{
if ( colorRampShader->sourceColorRamp() )
{
btnColorRamp->setColorRamp( colorRampShader->sourceColorRamp() );
}
else
{
QgsSettings settings;
QString defaultPalette = settings.value( QStringLiteral( "/Raster/defaultPalette" ), "Spectral" ).toString();
btnColorRamp->setColorRampFromName( defaultPalette );
}
mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( colorRampShader->colorRampType() ) );
const QList<QgsColorRampShader::ColorRampItem> colorRampItemList = colorRampShader->colorRampItemList();
QList<QgsColorRampShader::ColorRampItem>::const_iterator it = colorRampItemList.constBegin();
for ( ; it != colorRampItemList.end(); ++it )
{
QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget );
newItem->setText( ValueColumn, QString::number( it->value, 'g', 15 ) );
newItem->setBackground( ColorColumn, QBrush( it->color ) );
newItem->setText( LabelColumn, it->label );
newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
connect( newItem, &QgsTreeWidgetItemObject::itemEdited,
this, &QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemEdited );
}
setUnitFromLabels();
mClipCheckBox->setChecked( colorRampShader->clip() );
mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( colorRampShader->classificationMode() ) );
mNumberOfEntriesSpinBox->setValue( colorRampShader->colorRampItemList().count() ); // some default
mColorRampShaderWidget->setFromShader( *colorRampShader );
}
}
setLineEditValue( mMinLineEdit, pr->classificationMin() );
@ -735,38 +188,8 @@ void QgsSingleBandPseudoColorRendererWidget::bandChanged()
QList<int> bands;
bands.append( mBandComboBox->currentBand() );
mMinMaxWidget->setBands( bands );
}
void QgsSingleBandPseudoColorRendererWidget::mColorInterpolationComboBox_currentIndexChanged( int index )
{
QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->itemData( index ).toInt() );
mClipCheckBox->setEnabled( interpolation == QgsColorRampShader::Interpolated );
QString valueLabel;
QString valueToolTip;
switch ( interpolation )
{
case QgsColorRampShader::Interpolated:
valueLabel = tr( "Value" );
valueToolTip = tr( "Value for color stop" );
break;
case QgsColorRampShader::Discrete:
valueLabel = tr( "Value <=" );
valueToolTip = tr( "Maximum value for class" );
break;
case QgsColorRampShader::Exact:
valueLabel = tr( "Value =" );
valueToolTip = tr( "Value for color" );
break;
}
QTreeWidgetItem *header = mColormapTreeWidget->headerItem();
header->setText( ValueColumn, valueLabel );
header->setToolTip( ValueColumn, valueToolTip );
autoLabel();
emit widgetChanged();
mColorRampShaderWidget->setRasterBand( mBandComboBox->currentBand() );
mColorRampShaderWidget->classify();
}
void QgsSingleBandPseudoColorRendererWidget::loadMinMax( int bandNo, double min, double max )
@ -797,27 +220,21 @@ void QgsSingleBandPseudoColorRendererWidget::loadMinMax( int bandNo, double min,
if ( oldMin != min || oldMax != max )
{
classify();
mColorRampShaderWidget->setRasterBand( bandNo );
mColorRampShaderWidget->setMinimumMaximum( min, max );
mColorRampShaderWidget->classify();
}
}
void QgsSingleBandPseudoColorRendererWidget::loadMinMaxFromTree()
void QgsSingleBandPseudoColorRendererWidget::loadMinMaxFromTree( double min, double max )
{
QTreeWidgetItem *item = mColormapTreeWidget->topLevelItem( 0 );
if ( !item )
{
return;
}
double min = item->text( ValueColumn ).toDouble();
item = mColormapTreeWidget->topLevelItem( mColormapTreeWidget->topLevelItemCount() - 1 );
double max = item->text( ValueColumn ).toDouble();
whileBlocking( mMinLineEdit )->setText( QString::number( min ) );
whileBlocking( mMaxLineEdit )->setText( QString::number( max ) );
minMaxModified();
}
void QgsSingleBandPseudoColorRendererWidget::setLineEditValue( QLineEdit *lineEdit, double value )
{
QString s;
@ -838,81 +255,29 @@ double QgsSingleBandPseudoColorRendererWidget::lineEditValue( const QLineEdit *l
return lineEdit->text().toDouble();
}
void QgsSingleBandPseudoColorRendererWidget::resetClassifyButton()
{
mClassifyButton->setEnabled( true );
double min = lineEditValue( mMinLineEdit );
double max = lineEditValue( mMaxLineEdit );
if ( std::isnan( min ) || std::isnan( max ) || min >= max )
{
mClassifyButton->setEnabled( false );
}
}
void QgsSingleBandPseudoColorRendererWidget::changeColor()
{
QList<QTreeWidgetItem *> itemList;
itemList = mColormapTreeWidget->selectedItems();
if ( itemList.isEmpty() )
{
return;
}
QTreeWidgetItem *firstItem = itemList.first();
QColor newColor = QgsColorDialog::getColor( firstItem->background( ColorColumn ).color(), this, QStringLiteral( "Change Color" ), true );
if ( newColor.isValid() )
{
Q_FOREACH ( QTreeWidgetItem *item, itemList )
{
item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
item->setBackground( ColorColumn, QBrush( newColor ) );
}
loadMinMaxFromTree();
emit widgetChanged();
}
}
void QgsSingleBandPseudoColorRendererWidget::changeOpacity()
{
QList<QTreeWidgetItem *> itemList;
itemList = mColormapTreeWidget->selectedItems();
if ( itemList.isEmpty() )
{
return;
}
QTreeWidgetItem *firstItem = itemList.first();
bool ok;
double oldOpacity = firstItem->background( ColorColumn ).color().alpha() / 255 * 100;
double opacity = QInputDialog::getDouble( this, tr( "Opacity" ), tr( "Change color opacity [%]" ), oldOpacity, 0.0, 100.0, 0, &ok );
if ( ok )
{
int newOpacity = opacity / 100 * 255;
Q_FOREACH ( QTreeWidgetItem *item, itemList )
{
QColor newColor = item->background( ColorColumn ).color();
newColor.setAlpha( newOpacity );
item->setBackground( ColorColumn, QBrush( newColor ) );
}
loadMinMaxFromTree();
emit widgetChanged();
}
}
void QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textEdited( const QString & )
{
minMaxModified();
classify();
whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
}
void QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textEdited( const QString & )
{
minMaxModified();
classify();
whileBlocking( mColorRampShaderWidget )->setMinimumMaximumAndClassify( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
}
void QgsSingleBandPseudoColorRendererWidget::mMinLineEdit_textChanged( const QString & )
{
whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
}
void QgsSingleBandPseudoColorRendererWidget::mMaxLineEdit_textChanged( const QString & )
{
whileBlocking( mColorRampShaderWidget )->setMinimumMaximum( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) );
}
void QgsSingleBandPseudoColorRendererWidget::minMaxModified()
{
mMinMaxWidget->userHasSetManualMinMaxValues();

View File

@ -30,6 +30,10 @@ class QgsRasterMinMaxWidget;
/**
* \ingroup gui
* \class QgsSingleBandPseudoColorRendererWidget
*
* Single band pseudo color renderer widget consists of a color ramp shader widget,
* a raster min max widget and a band selector.
*
*/
class GUI_EXPORT QgsSingleBandPseudoColorRendererWidget: public QgsRasterRendererWidget, private Ui::QgsSingleBandPseudoColorRendererWidgetBase
{
@ -38,87 +42,45 @@ class GUI_EXPORT QgsSingleBandPseudoColorRendererWidget: public QgsRasterRendere
public:
//! Creates new raster renderer widget
QgsSingleBandPseudoColorRendererWidget( QgsRasterLayer *layer, const QgsRectangle &extent = QgsRectangle() );
//! Creates new raster renderer widget
static QgsRasterRendererWidget *create( QgsRasterLayer *layer, const QgsRectangle &extent ) SIP_FACTORY { return new QgsSingleBandPseudoColorRendererWidget( layer, extent ); }
QgsRasterRenderer *renderer() override;
//! Returns shader function used in the renderer. Caller takes ownership and deletes it.
QgsColorRampShader *shaderFunction() const SIP_FACTORY;
QgsRasterRenderer *renderer() override;
void setMapCanvas( QgsMapCanvas *canvas ) override;
void doComputations() override;
QgsRasterMinMaxWidget *minMaxWidget() override { return mMinMaxWidget; }
QgsRasterMinMaxWidget *minMaxWidget() override;
//! Returns the current raster band number
int currentBand() const;
//! Set state of the widget from renderer settings
void setFromRenderer( const QgsRasterRenderer *r );
public slots:
/**
* Executes the single band pseudo raster classficiation
*/
void classify();
//! called when new min/max values are loaded
void loadMinMax( int bandNo, double min, double max );
//! called when the color ramp tree has changed
void loadMinMaxFromTree();
private:
enum Column
{
ValueColumn = 0,
ColorColumn = 1,
LabelColumn = 2,
};
void populateColormapTreeWidget( const QList<QgsColorRampShader::ColorRampItem> &colorRampItems );
/**
* Generate labels from the values in the color map.
* Skip labels which were manually edited (black text).
* Text of generated labels is made gray
*/
void autoLabel();
//! Extract the unit out of the current labels and set the unit field.
void setUnitFromLabels();
QMenu *contextMenu = nullptr;
void loadMinMaxFromTree( double min, double max );
private slots:
void applyColorRamp();
void mAddEntryButton_clicked();
void mDeleteEntryButton_clicked();
void mLoadFromBandButton_clicked();
void mLoadFromFileButton_clicked();
void mExportToFileButton_clicked();
void mUnitLineEdit_textEdited( const QString &text ) { Q_UNUSED( text ); autoLabel(); }
void mColormapTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, int column );
void mColormapTreeWidget_itemEdited( QTreeWidgetItem *item, int column );
void bandChanged();
void mColorInterpolationComboBox_currentIndexChanged( int index );
void mMinLineEdit_textChanged( const QString & ) { resetClassifyButton(); }
void mMaxLineEdit_textChanged( const QString & ) { resetClassifyButton(); }
void mMinLineEdit_textChanged( const QString & );
void mMaxLineEdit_textChanged( const QString & );
void mMinLineEdit_textEdited( const QString &text );
void mMaxLineEdit_textEdited( const QString &text );
void mClassificationModeComboBox_currentIndexChanged( int index );
void changeColor();
void changeOpacity();
private:
void setLineEditValue( QLineEdit *lineEdit, double value );
double lineEditValue( const QLineEdit *lineEdit ) const;
void resetClassifyButton();
QgsRasterMinMaxWidget *mMinMaxWidget = nullptr;
int mMinMaxOrigin;
void minMaxModified();
};
#endif // QGSSINGLEBANDCOLORRENDERERWIDGET_H

View File

@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>3</number>
</property>
@ -26,286 +26,57 @@
<property name="bottomMargin">
<number>3</number>
</property>
<item row="6" column="0" colspan="5">
<widget class="QTreeWidget" name="mColormapTreeWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>250</height>
</size>
</property>
<attribute name="headerDefaultSectionSize">
<number>70</number>
</attribute>
<attribute name="headerMinimumSectionSize">
<number>10</number>
</attribute>
<attribute name="headerStretchLastSection">
<bool>true</bool>
</attribute>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
<column>
<property name="text">
<string>Color</string>
</property>
</column>
<column>
<property name="text">
<string>Label</string>
</property>
</column>
</widget>
</item>
<item row="4" column="1" colspan="4">
<widget class="QgsColorRampButton" name="btnColorRamp">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="mColorInterpolationLabel_2">
<property name="text">
<string>Color ramp</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLineEdit" name="mMaxLineEdit"/>
</item>
<item row="1" column="1">
<widget class="QLabel" name="mMinLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="4">
<widget class="QComboBox" name="mColorInterpolationComboBox"/>
</item>
<item row="0" column="1" colspan="4">
<widget class="QgsRasterBandComboBox" name="mBandComboBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mBandLabel">
<property name="text">
<string>Band</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="mMaxLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Max</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="mColorInterpolationLabel">
<property name="text">
<string>Interpolation</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="mClassifyButton">
<property name="text">
<string>Classify</string>
</property>
</widget>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="QLineEdit" name="mMinLineEdit"/>
</item>
<item>
<widget class="QPushButton" name="mAddEntryButton">
<property name="toolTip">
<string>Add values manually</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyAdd.svg</normaloff>:/images/themes/default/symbologyAdd.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mDeleteEntryButton">
<property name="toolTip">
<string>Remove selected row(s)</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/symbologyRemove.svg</normaloff>:/images/themes/default/symbologyRemove.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mLoadFromBandButton">
<property name="toolTip">
<string>Load color map from band</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionReload.svg</normaloff>:/images/themes/default/mActionReload.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mLoadFromFileButton">
<property name="toolTip">
<string>Load color map from file</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionFileOpen.svg</normaloff>:/images/themes/default/mActionFileOpen.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mExportToFileButton">
<property name="toolTip">
<string>Export color map to file</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mActionFileSaveAs.svg</normaloff>:/images/themes/default/mActionFileSaveAs.svg</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>48</width>
<height>28</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="mMinLineEdit"/>
</item>
<item row="9" column="0" colspan="5">
<widget class="QCheckBox" name="mClipCheckBox">
<property name="toolTip">
<string>If checked, any pixels with a value out of range will not be rendered</string>
</property>
<property name="text">
<string>Clip out of range values</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="mClassificationModeLabel">
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mClassificationModeComboBox"/>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="mNumberOfEntriesLabel">
<property name="text">
<string>Classes</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="mNumberOfEntriesSpinBox">
<item row="1" column="0">
<widget class="QLabel" name="mMinLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>255</number>
</property>
<property name="value">
<number>5</number>
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mBandLabel">
<property name="text">
<string>Band</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="mMaxLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Max</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="mMaxLineEdit"/>
</item>
<item row="0" column="1" colspan="3">
<widget class="QgsRasterBandComboBox" name="mBandComboBox"/>
</item>
</layout>
</item>
<item row="5" column="1" colspan="4">
<widget class="QLineEdit" name="mUnitLineEdit">
<property name="toolTip">
<string>Unit suffix</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="5">
<item>
<widget class="QWidget" name="mMinMaxContainerWidget" native="true"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="mUnitLabel">
<property name="text">
<string>Label unit
suffix</string>
</property>
</widget>
<item>
<widget class="QgsColorRampShaderWidget" name="mColorRampShaderWidget" native="true"/>
</item>
</layout>
</widget>
@ -316,60 +87,12 @@ suffix</string>
<header>raster/qgsrasterbandcombobox.h</header>
</customwidget>
<customwidget>
<class>QgsColorRampButton</class>
<extends>QToolButton</extends>
<header>qgscolorrampbutton.h</header>
<class>QgsColorRampShaderWidget</class>
<extends>QWidget</extends>
<header>raster/qgscolorrampshaderwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>mBandComboBox</tabstop>
<tabstop>mMinLineEdit</tabstop>
<tabstop>mMaxLineEdit</tabstop>
<tabstop>mColorInterpolationComboBox</tabstop>
<tabstop>btnColorRamp</tabstop>
<tabstop>mUnitLineEdit</tabstop>
<tabstop>mColormapTreeWidget</tabstop>
<tabstop>mClassificationModeComboBox</tabstop>
<tabstop>mNumberOfEntriesSpinBox</tabstop>
<tabstop>mClassifyButton</tabstop>
<tabstop>mAddEntryButton</tabstop>
<tabstop>mDeleteEntryButton</tabstop>
<tabstop>mLoadFromBandButton</tabstop>
<tabstop>mLoadFromFileButton</tabstop>
<tabstop>mExportToFileButton</tabstop>
<tabstop>mClipCheckBox</tabstop>
</tabstops>
<resources>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
</resources>
<resources/>
<connections/>
</ui>