27 #include <QFileDialog>    28 #include <QMessageBox>    30 #include <QTextStream>    36   if ( role == Qt::EditRole )
    56   else if ( ok1 || ok2 )
    63     return text( column ) < other.
text( column );
    69     , mMinMaxWidget( nullptr )
    76   mColormapTreeWidget->setColumnWidth( ColorColumn, 50 );
    82   QgsDebugMsg( 
"defaultPalette = " + defaultPalette );
    83   mColorRampComboBox->setCurrentIndex( mColorRampComboBox->findText( defaultPalette ) );
    84   connect( mButtonEditRamp, SIGNAL( clicked() ), mColorRampComboBox, SLOT( editSourceRamp() ) );
   107   mMinMaxContainerWidget->setLayout( layout );
   109   connect( mMinMaxWidget, SIGNAL( load( 
int, 
double, 
double, 
int ) ),
   110            this, SLOT( 
loadMinMax( 
int, 
double, 
double, 
int ) ) );
   115   for ( 
int i = 1; i <= nBands; ++i ) 
   124   mClassificationModeComboBox->addItem( 
tr( 
"Continuous" ), 
Continuous );
   125   mClassificationModeComboBox->addItem( 
tr( 
"Equal interval" ), 
EqualInterval );
   126   mClassificationModeComboBox->addItem( 
tr( 
"Quantile" ), 
Quantile );
   128   mNumberOfEntriesSpinBox->setValue( 5 ); 
   133   if ( mMinLineEdit->text().isEmpty() || mMaxLineEdit->text().isEmpty() )
   135     mMinMaxWidget->
load();
   138   on_mClassificationModeComboBox_currentIndexChanged( 0 );
   140   resetClassifyButton();
   142   connect( mClassificationModeComboBox, SIGNAL( currentIndexChanged( 
int ) ), 
this, SLOT( on_mClassifyButton_clicked() ) );
   143   connect( mMinLineEdit, SIGNAL( textChanged( 
QString ) ), 
this, SLOT( on_mClassifyButton_clicked() ) );
   144   connect( mMaxLineEdit, SIGNAL( textChanged( 
QString ) ), 
this, SLOT( on_mClassifyButton_clicked() ) );
   145   connect( mColorRampComboBox, SIGNAL( sourceRampEdited() ), 
this, SLOT( on_mClassifyButton_clicked() ) );
   146   connect( mColorRampComboBox, SIGNAL( currentIndexChanged( 
int ) ), 
this, SLOT( on_mClassifyButton_clicked() ) );
   147   connect( mInvertCheckBox, SIGNAL( stateChanged( 
int ) ), 
this, SLOT( on_mClassifyButton_clicked() ) );
   148   connect( mNumberOfEntriesSpinBox, SIGNAL( valueChanged( 
int ) ), 
this, SLOT( on_mClassifyButton_clicked() ) );
   149   connect( mBandComboBox, SIGNAL( currentIndexChanged( 
int ) ), 
this, SLOT( on_mClassifyButton_clicked() ) );
   161   colorRampShader->
setClip( mClipCheckBox->isChecked() );
   165   int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
   167   for ( 
int i = 0; i < topLevelItemCount; ++i )
   169     currentItem = mColormapTreeWidget->topLevelItem( i );
   177     newColorRampItem.
label = currentItem->
text( LabelColumn );
   178     colorRampItems.
append( newColorRampItem );
   181   qSort( colorRampItems );
   188   int bandNumber = mBandComboBox->itemData( mBandComboBox->currentIndex() ).toInt();
   207 void QgsSingleBandPseudoColorRendererWidget::autoLabel()
   211   QString unit = mUnitLineEdit->text();
   213   int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
   215   for ( 
int i = 0; i < topLevelItemCount; ++i )
   217     currentItem = mColormapTreeWidget->topLevelItem( i );
   219     if ( !currentItem || currentItem->
text( ValueColumn ).
isEmpty() )
   228         label = 
"<= " + currentItem->
text( ValueColumn ) + unit;
   230       else if ( currentItem->
text( ValueColumn ).
toDouble() == std::numeric_limits<double>::infinity() )
   232         label = 
"> " + mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + unit;
   236         label = mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + 
" - " + currentItem->
text( ValueColumn ) + unit;
   241       label = currentItem->
text( ValueColumn ) + unit;
   246       currentItem->
setText( LabelColumn, label );
   253 void QgsSingleBandPseudoColorRendererWidget::setUnitFromLabels()
   259   int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
   261   for ( 
int i = 0; i < topLevelItemCount; ++i )
   263     currentItem = mColormapTreeWidget->topLevelItem( i );
   265     if ( !currentItem || currentItem->
text( ValueColumn ).
isEmpty() )
   274         label = 
"<= " + currentItem->
text( ValueColumn );
   276       else if ( currentItem->
text( ValueColumn ).
toDouble() == std::numeric_limits<double>::infinity() )
   278         label = 
"> " + mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn );
   282         label = mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + 
" - " + currentItem->
text( ValueColumn );
   287       label = currentItem->
text( ValueColumn );
   300   for ( 
int i = 0; i < suffixes.
count(); ++i )
   302     int n = allSuffixes.
count( suffixes[i] );
   312     mUnitLineEdit->setText( unit );
   317 void QgsSingleBandPseudoColorRendererWidget::on_mAddEntryButton_clicked()
   320   newItem->
setText( ValueColumn, 
"0" );
   323   newItem->
setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
   325            this, SLOT( mColormapTreeWidget_itemEdited( 
QTreeWidgetItem*, 
int ) ) );
   326   mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder );
   331 void QgsSingleBandPseudoColorRendererWidget::on_mDeleteEntryButton_clicked()
   341 void QgsSingleBandPseudoColorRendererWidget::on_mNumberOfEntriesSpinBox_valueChanged()
   345 void QgsSingleBandPseudoColorRendererWidget::on_mClassifyButton_clicked()
   347   int bandComboIndex = mBandComboBox->currentIndex();
   363   double min = lineEditValue( mMinLineEdit );
   364   double max = lineEditValue( mMaxLineEdit );
   366   if ( qIsNaN( min ) || qIsNaN( max ) )
   373   if ( mClassificationModeComboBox->itemData( mClassificationModeComboBox->currentIndex() ).toInt() == 
Continuous )
   375     if ( colorRamp.data() )
   377       numberOfEntries = colorRamp->count();
   378       entryValues.
reserve( numberOfEntries );
   381         double intervalDiff = max - 
min;
   385         if ( colorGradientRamp != NULL && colorGradientRamp->
isDiscrete() )
   393           intervalDiff *= ( numberOfEntries - 1 ) / ( 
double )numberOfEntries;
   397         for ( 
int i = 1; i < numberOfEntries; ++i )
   399           double value = colorRamp->
value( i );
   400           entryValues.
push_back( min + value * intervalDiff );
   402         entryValues.
push_back( std::numeric_limits<double>::infinity() );
   406         for ( 
int i = 0; i < numberOfEntries; ++i )
   408           if ( mInvertCheckBox->isChecked() )
   410             double value = 1.0 - colorRamp->value( numberOfEntries - i - 1 );
   411             entryValues.
push_back( min + value * ( max - min ) );
   415             double value = colorRamp->value( i );
   416             entryValues.
push_back( min + value * ( max - min ) );
   421       for ( 
int i = 0; i < numberOfEntries; ++i )
   423         int idx = mInvertCheckBox->isChecked() ? numberOfEntries - i - 1 : i;
   424         entryColors.
push_back( colorRamp->color( colorRamp->value( idx ) ) );
   430     numberOfEntries = mNumberOfEntriesSpinBox->value();
   431     if ( numberOfEntries < 2 )
   434     if ( mClassificationModeComboBox->itemData( mClassificationModeComboBox->currentIndex() ).toInt() == 
Quantile )
   436       int bandNr = mBandComboBox->itemData( bandComboIndex ).toInt();
   439       double cut1 = std::numeric_limits<double>::quiet_NaN();
   440       double cut2 = std::numeric_limits<double>::quiet_NaN();
   448       entryValues.
reserve( numberOfEntries );
   451         double intervalDiff = 1.0 / ( numberOfEntries );
   452         for ( 
int i = 1; i < numberOfEntries; ++i )
   457         entryValues.
push_back( std::numeric_limits<double>::infinity() );
   461         double intervalDiff = 1.0 / ( numberOfEntries - 1 );
   462         for ( 
int i = 0; i < numberOfEntries; ++i )
   471       entryValues.
reserve( numberOfEntries );
   477         double intervalDiff = ( max - 
min ) / ( numberOfEntries );
   479         for ( 
int i = 1; i < numberOfEntries; ++i )
   481           entryValues.
push_back( min + i * intervalDiff );
   483         entryValues.
push_back( std::numeric_limits<double>::infinity() );
   488         double intervalDiff = ( max - 
min ) / ( numberOfEntries - 1 );
   490         for ( 
int i = 0; i < numberOfEntries; ++i )
   492           entryValues.
push_back( min + i * intervalDiff );
   497     if ( !colorRamp.data() )
   501       if ( numberOfEntries != 0 )
   503         colorDiff = ( int )( 255 / numberOfEntries );
   506       entryColors.
reserve( numberOfEntries );
   507       for ( 
int i = 0; i < numberOfEntries; ++i )
   510         int idx = mInvertCheckBox->isChecked() ? numberOfEntries - i - 1 : i;
   511         currentColor.
setRgb( colorDiff*idx, 0, 255 - colorDiff * idx );
   517       entryColors.
reserve( numberOfEntries );
   518       for ( 
int i = 0; i < numberOfEntries; ++i )
   520         int idx = mInvertCheckBox->isChecked() ? numberOfEntries - i - 1 : i;
   521         entryColors.
push_back( colorRamp->color((( 
double ) idx ) / ( numberOfEntries - 1 ) ) );
   526   mColormapTreeWidget->clear();
   532   double maxabs = log10( qMax( qAbs( max ), qAbs( min ) ) );
   533   int nDecimals = qRound( qMax( 3.0 + maxabs - log10( max - min ), maxabs <= 15.0 ? maxabs + 0.49 : 0.0 ) );
   535   for ( ; value_it != entryValues.
end(); ++value_it, ++color_it )
   541     newItem->
setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
   543              this, SLOT( mColormapTreeWidget_itemEdited( 
QTreeWidgetItem*, 
int ) ) );
   549 void QgsSingleBandPseudoColorRendererWidget::on_mClassificationModeComboBox_currentIndexChanged( 
int index )
   551   Mode mode = 
static_cast< Mode >( mClassificationModeComboBox->itemData( index ).toInt() );
   552   mNumberOfEntriesSpinBox->setEnabled( mode != 
Continuous );
   553   mMinLineEdit->setEnabled( mode != 
Quantile );
   554   mMaxLineEdit->setEnabled( mode != 
Quantile );
   557 void QgsSingleBandPseudoColorRendererWidget::on_mColorRampComboBox_currentIndexChanged( 
int index )
   561   settings.
setValue( 
"/Raster/defaultPalette", mColorRampComboBox->currentText() );
   567   bool enableContinuous = ( ramp->
count() > 0 );
   568   mClassificationModeComboBox->setEnabled( enableContinuous );
   569   if ( !enableContinuous )
   571     mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( 
EqualInterval ) );
   577   mColormapTreeWidget->clear();
   579   for ( ; it != colorRampItems.
constEnd(); ++it )
   584     newItem->
setText( LabelColumn, it->label );
   585     newItem->
setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
   587              this, SLOT( mColormapTreeWidget_itemEdited( 
QTreeWidgetItem*, 
int ) ) );
   592 void QgsSingleBandPseudoColorRendererWidget::on_mLoadFromBandButton_clicked()
   599   int bandIndex = mBandComboBox->itemData( mBandComboBox->currentIndex() ).toInt();
   603   if ( !colorRampList.
isEmpty() )
   605     populateColormapTreeWidget( colorRampList );
   610     QMessageBox::warning( 
this, 
tr( 
"Load Color Map" ), 
tr( 
"The color map for band %1 has no entries" ).arg( bandIndex ) );
   615 void QgsSingleBandPseudoColorRendererWidget::on_mLoadFromFileButton_clicked()
   618   bool importError = 
false;
   623   QFile inputFile( fileName );
   624   if ( inputFile.
open( QFile::ReadOnly ) )
   627     mColormapTreeWidget->clear();
   635     while ( !inputStream.
atEnd() )
   643           if ( inputLine.
contains( 
"INTERPOLATION", Qt::CaseInsensitive ) )
   645             inputStringComponents = inputLine.
split( 
':' );
   646             if ( inputStringComponents.
size() == 2 )
   648               if ( inputStringComponents[1].trimmed().toUpper().compare( 
"INTERPOLATED", Qt::CaseInsensitive ) == 0 )
   652               else if ( inputStringComponents[1].trimmed().toUpper().compare( 
"DISCRETE", Qt::CaseInsensitive ) == 0 )
   664               badLines = badLines + 
QString::number( lineCounter ) + 
":\t[" + inputLine + 
"]\n";
   669             inputStringComponents = inputLine.
split( 
',' );
   670             if ( inputStringComponents.
size() == 6 )
   673                   QColor::fromRgb( inputStringComponents[1].toInt(), inputStringComponents[2].toInt(),
   674                                    inputStringComponents[3].toInt(), inputStringComponents[4].toInt() ),
   675                   inputStringComponents[5] );
   681               badLines = badLines + 
QString::number( lineCounter ) + 
":\t[" + inputLine + 
"]\n";
   688     populateColormapTreeWidget( colorRampItems );
   698   else if ( !fileName.
isEmpty() )
   700     QMessageBox::warning( 
this, 
tr( 
"Read access denied" ), 
tr( 
"Read access denied. Adjust the file permissions and try again.\n\n" ) );
   705 void QgsSingleBandPseudoColorRendererWidget::on_mExportToFileButton_clicked()
   712     if ( !fileName.
endsWith( 
".txt", Qt::CaseInsensitive ) )
   714       fileName = fileName + 
".txt";
   717     QFile outputFile( fileName );
   718     if ( outputFile.
open( QFile::WriteOnly ) )
   721       outputStream << 
"# " << 
tr( 
"QGIS Generated Color Map Export File" ) << 
'\n';
   722       outputStream << 
"INTERPOLATION:";
   724       switch ( interpolation )
   727           outputStream << 
"INTERPOLATED\n";
   730           outputStream << 
"DISCRETE\n";
   733           outputStream << 
"EXACT\n";
   737       int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();
   740       for ( 
int i = 0; i < topLevelItemCount; ++i )
   742         currentItem = mColormapTreeWidget->topLevelItem( i );
   748         outputStream << currentItem->
text( ValueColumn ).
toDouble() << 
',';
   749         outputStream << color.
red() << 
',' << color.
green() << 
',' << color.
blue() << 
',' << color.
alpha() << 
',';
   752           outputStream << 
"Color entry " << i + 1 << 
'\n';
   756           outputStream << currentItem->
text( LabelColumn ) << 
'\n';
   759       outputStream.
flush();
   767       QMessageBox::warning( 
this, 
tr( 
"Write access denied" ), 
tr( 
"Write access denied. Adjust the file permissions and try again.\n\n" ) );
   772 void QgsSingleBandPseudoColorRendererWidget::on_mColormapTreeWidget_itemDoubleClicked( 
QTreeWidgetItem* item, 
int column )
   779   if ( column == ColorColumn )
   781     item->
setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
   791     if ( column == LabelColumn )
   796     item->
setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
   801 void QgsSingleBandPseudoColorRendererWidget::mColormapTreeWidget_itemEdited( 
QTreeWidgetItem* item, 
int column )
   805   if ( column == ValueColumn )
   807     mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder );
   811   else if ( column == LabelColumn )
   823     mBandComboBox->setCurrentIndex( mBandComboBox->findData( pr->
band() ) );
   829       if ( colorRampShader )
   831         mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( colorRampShader->
colorRampType() ) );
   835         for ( ; it != colorRampItemList.
end(); ++it )
   840           newItem->
setText( LabelColumn, it->label );
   841           newItem->
setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
   843                    this, SLOT( mColormapTreeWidget_itemEdited( 
QTreeWidgetItem*, 
int ) ) );
   846         mClipCheckBox->setChecked( colorRampShader->
clip() );
   856 void QgsSingleBandPseudoColorRendererWidget::on_mBandComboBox_currentIndexChanged( 
int index )
   859   bands.
append( mBandComboBox->itemData( index ).toInt() );
   863 void QgsSingleBandPseudoColorRendererWidget::on_mColorInterpolationComboBox_currentIndexChanged( 
int index )
   871   switch ( interpolation )
   874       valueLabel = 
tr( 
"Value" );
   875       valueToolTip = 
tr( 
"Value for color stop" );
   878       valueLabel = 
tr( 
"Value <=" );
   879       valueToolTip = 
tr( 
"Maximum value for class" );
   882       valueLabel = 
tr( 
"Value =" );
   883       valueToolTip = 
tr( 
"Value for color" );
   888   header->
setText( ValueColumn, valueLabel );
   889   header->
setToolTip( ValueColumn, valueToolTip );
   897   Q_UNUSED( theBandNo );
   898   QgsDebugMsg( 
QString( 
"theBandNo = %1 theMin = %2 theMax = %3" ).arg( theBandNo ).arg( theMin ).arg( theMax ) );
   900   if ( qIsNaN( theMin ) )
   902     mMinLineEdit->clear();
   909   if ( qIsNaN( theMax ) )
   911     mMaxLineEdit->clear();
   918   mMinMaxOrigin = theOrigin;
   922 void QgsSingleBandPseudoColorRendererWidget::showMinMaxOrigin()
   927 void QgsSingleBandPseudoColorRendererWidget::setLineEditValue( 
QLineEdit * theLineEdit, 
double theValue )
   930   if ( !qIsNaN( theValue ) )
   937 double QgsSingleBandPseudoColorRendererWidget::lineEditValue( 
const QLineEdit * theLineEdit )
 const   939   if ( theLineEdit->
text().isEmpty() )
   941     return std::numeric_limits<double>::quiet_NaN();
   944   return theLineEdit->
text().toDouble();
   947 void QgsSingleBandPseudoColorRendererWidget::resetClassifyButton()
   949   mClassifyButton->setEnabled( 
true );
   950   double min = lineEditValue( mMinLineEdit );
   951   double max = lineEditValue( mMaxLineEdit );
   952   if ( qIsNaN( min ) || qIsNaN( max ) || min >= max )
   954     mClassifyButton->setEnabled( 
false );
 
Assigns the color of the exact matching value in the color ramp item list. 
virtual int bandCount() const =0
Get number of bands. 
A rectangle specified with double values. 
double classificationMin() const
Interface for all raster shaders. 
void setContentsMargins(int left, int top, int right, int bottom)
QgsColorRampShader::ColorRamp_TYPE colorRampType() const
Get the color ramp type. 
QString readLine(qint64 maxlen)
void push_back(const T &value)
void setText(const QString &)
A ramp shader will color a raster pixel based on a list of values ranges in a ramp. 
virtual QList< QgsColorRampShader::ColorRampItem > colorTable(int bandNo) const
This class provides qgis with the ability to render raster datasets onto the mapcanvas. 
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
void setClassificationMinMaxOrigin(int origin)
QString simplified() const
QList< QgsColorRampShader::ColorRampItem > colorRampItemList() const
Get the custom colormap. 
bool isDiscrete() const
Returns true if the gradient is using discrete interpolation, rather than smoothly interpolating betw...
void setColorRampItemList(const QList< QgsColorRampShader::ColorRampItem > &theList)
Set custom colormap. 
QgsRasterRenderer * renderer() const
void setClip(bool clip)
Sets whether the shader should not render values out of range. 
void setRgb(int r, int g, int b, int a)
double toDouble(bool *ok) const
QgsRasterShader * shader()
QString tr(const char *sourceText, const char *disambiguation, int n)
void setClassificationMax(double max)
Map canvas is a class for displaying all GIS data types on a canvas. 
int classificationMinMaxOrigin() const
const QColor & color() const
void setValue(const QString &key, const QVariant &value)
QString number(int n, int base)
int count(const T &value) const
void append(const T &value)
QgsRasterShaderFunction * rasterShaderFunction()
double classificationMax() const
static QgsStyleV2 * defaultStyle()
return default application-wide style 
static QString minMaxOriginLabel(int theOrigin)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
Raster renderer pipe for single band pseudocolor. 
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
void setRasterShaderFunction(QgsRasterShaderFunction *)
A public method that allows the user to set their own shader function. 
void setColorRampType(QgsColorRampShader::ColorRamp_TYPE theColorRampType)
Set the color ramp type. 
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QVariant value(const QString &key, const QVariant &defaultValue) const
virtual int count() const =0
Returns number of defined colors, or -1 if undefined. 
static QColor getColor(const QColor &initialColor, QWidget *parent, const QString &title=QString(), const bool allowAlpha=false)
Return a color selection from a color dialog. 
void setClassificationMin(double min)
QString mid(int position, int n) const
QString absolutePath() const
Interpolates the color between two class breaks linearly. 
Assigns the color of the higher class for every pixel between two class breaks. 
void setText(int column, const QString &text)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
bool clip() const
Returns whether the shader will clip values which are out of range. 
void push_back(const T &value)
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
QgsRasterDataProvider * dataProvider()
Returns the data provider. 
virtual double value(int index) const override
Returns relative value between [0,1] of color at specified index. 
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
const_iterator constEnd() const
const_iterator constBegin() const
virtual void cumulativeCut(int theBandNo, double theLowerCount, double theUpperCount, double &theLowerValue, double &theUpperValue, const QgsRectangle &theExtent=QgsRectangle(), int theSampleSize=0)
Find values for cumulative pixel count cut. 
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Abstract base class for color ramps. 
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
QString text(int column) const
ColorRamp_TYPE
Supported methods for color interpolation. 
Raster renderer pipe that applies colors to a raster. 
int band() const
Returns the band used by the renderer. 
Base class for raster data providers.