16 #include <QDoubleValidator>    17 #include <QIntValidator>    19 #include <QTextStream>    20 #include <QMessageBox>    21 #include <QFileDialog>    40   , TRSTRING_NOT_SET( tr( 
"Not Set" ) )
    41   , mRasterLayer( layer )
    42   , mMapCanvas( canvas )
    45   connect( pbnAddValuesFromDisplay, &QToolButton::clicked, 
this, &QgsRasterTransparencyWidget::pbnAddValuesFromDisplay_clicked );
    46   connect( pbnAddValuesManually, &QToolButton::clicked, 
this, &QgsRasterTransparencyWidget::pbnAddValuesManually_clicked );
    47   connect( pbnDefaultValues, &QToolButton::clicked, 
this, &QgsRasterTransparencyWidget::pbnDefaultValues_clicked );
    48   connect( pbnExportTransparentPixelValues, &QToolButton::clicked, 
this, &QgsRasterTransparencyWidget::pbnExportTransparentPixelValues_clicked );
    49   connect( pbnImportTransparentPixelValues, &QToolButton::clicked, 
this, &QgsRasterTransparencyWidget::pbnImportTransparentPixelValues_clicked );
    50   connect( pbnRemoveSelectedRow, &QToolButton::clicked, 
this, &QgsRasterTransparencyWidget::pbnRemoveSelectedRow_clicked );
    59   mPixelSelectorTool = 
nullptr;
    67     pbnAddValuesFromDisplay->setEnabled( 
false );
    80       gboxNoDataValue->setEnabled( 
false );
    81       gboxCustomTransparency->setEnabled( 
false );
    84     cboxTransparencyBand->setShowNotSetOption( 
true, tr( 
"None" ) );
    85     cboxTransparencyBand->setLayer( mRasterLayer );
    89     cboxTransparencyBand->setBand( renderer->
alphaBand() );
    98     lblSrcNoDataValue->setText( tr( 
"not defined" ) );
   105   mSrcNoDataValueCheckBox->setEnabled( enableSrcNoData );
   106   lblSrcNoDataValue->setEnabled( enableSrcNoData );
   109   QgsDebugMsg( QStringLiteral( 
"noDataRangeList.size = %1" ).arg( noDataRangeList.size() ) );
   110   if ( !noDataRangeList.isEmpty() )
   116     leNoDataValue->insert( QString() );
   119   populateTransparencyTable( mRasterLayer->
renderer() );
   122 void QgsRasterTransparencyWidget::transparencyCellTextEdited( 
const QString &text )
   125   QgsDebugMsg( QStringLiteral( 
"text = %1" ).arg( text ) );
   131   int nBands = renderer->
usesBands().size();
   134     QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
   135     if ( !lineEdit ) 
return;
   138     for ( 
int r = 0; r < tableTransparency->rowCount(); r++ )
   140       for ( 
int c = 0; 
c < tableTransparency->columnCount(); 
c++ )
   142         if ( tableTransparency->cellWidget( r, 
c ) == sender() )
   149       if ( row != -1 ) 
break;
   151     QgsDebugMsg( QStringLiteral( 
"row = %1 column =%2" ).arg( row ).arg( column ) );
   155       QLineEdit *toLineEdit = 
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, 1 ) );
   156       if ( !toLineEdit ) 
return;
   157       bool toChanged = mTransparencyToEdited.value( row );
   158       QgsDebugMsg( QStringLiteral( 
"toChanged = %1" ).arg( toChanged ) );
   161         toLineEdit->setText( lineEdit->text() );
   164     else if ( column == 1 )
   166       setTransparencyToEdited( row );
   172 void QgsRasterTransparencyWidget::pbnAddValuesFromDisplay_clicked()
   174   if ( mMapCanvas && mPixelSelectorTool )
   180 void QgsRasterTransparencyWidget::pbnAddValuesManually_clicked()
   188   tableTransparency->insertRow( tableTransparency->rowCount() );
   193   for ( 
int i = 0; i < n; i++ )
   195     setTransparencyCell( tableTransparency->rowCount() - 1, i, std::numeric_limits<double>::quiet_NaN() );
   198   setTransparencyCell( tableTransparency->rowCount() - 1, n, 100 );
   200   tableTransparency->resizeColumnsToContents();
   201   tableTransparency->resizeRowsToContents();
   204 void QgsRasterTransparencyWidget::pbnDefaultValues_clicked()
   214   setupTransparencyTable( nBands );
   216   tableTransparency->resizeColumnsToContents(); 
   217   tableTransparency->resizeRowsToContents();
   221 void QgsRasterTransparencyWidget::pbnExportTransparentPixelValues_clicked()
   224   QString myLastDir = myQSettings.
value( QStringLiteral( 
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
   225   QString myFileName = QFileDialog::getSaveFileName( 
this, tr( 
"Save Pixel Values as File" ), myLastDir, tr( 
"Textfile" ) + 
" (*.txt)" );
   226   if ( !myFileName.isEmpty() )
   228     if ( !myFileName.endsWith( QLatin1String( 
".txt" ), Qt::CaseInsensitive ) )
   230       myFileName = myFileName + 
".txt";
   233     QFile myOutputFile( myFileName );
   234     if ( myOutputFile.open( QFile::WriteOnly | QIODevice::Truncate ) )
   236       QTextStream myOutputStream( &myOutputFile );
   237       myOutputStream << 
"# " << tr( 
"QGIS Generated Transparent Pixel Value Export File" ) << 
'\n';
   238       if ( rasterIsMultiBandColor() )
   240         myOutputStream << 
"#\n#\n# " << tr( 
"Red" ) << 
"\t" << tr( 
"Green" ) << 
"\t" << tr( 
"Blue" ) << 
"\t" << tr( 
"Percent Transparent" );
   241         for ( 
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
   243           myOutputStream << 
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) << 
"\t"   244                          << QString::number( transparencyCellValue( myTableRunner, 1 ) ) << 
"\t"   245                          << QString::number( transparencyCellValue( myTableRunner, 2 ) ) << 
"\t"   246                          << QString::number( transparencyCellValue( myTableRunner, 3 ) );
   251         myOutputStream << 
"#\n#\n# " << tr( 
"Value" ) << 
"\t" << tr( 
"Percent Transparent" );
   253         for ( 
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
   255           myOutputStream << 
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) << 
"\t"   256                          << QString::number( transparencyCellValue( myTableRunner, 1 ) ) << 
"\t"   257                          << QString::number( transparencyCellValue( myTableRunner, 2 ) );
   263       QMessageBox::warning( 
this, tr( 
"Save Pixel Values as File" ), tr( 
"Write access denied. Adjust the file permissions and try again.\n\n" ) );
   268 void QgsRasterTransparencyWidget::pbnImportTransparentPixelValues_clicked()
   270   int myLineCounter = 0;
   271   bool myImportError = 
false;
   274   QString myLastDir = myQSettings.
value( QStringLiteral( 
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
   275   QString myFileName = QFileDialog::getOpenFileName( 
this, tr( 
"Load Pixel Values from File" ), myLastDir, tr( 
"Textfile" ) + 
" (*.txt)" );
   276   QFile myInputFile( myFileName );
   277   if ( myInputFile.open( QFile::ReadOnly ) )
   279     QTextStream myInputStream( &myInputFile );
   281     if ( rasterIsMultiBandColor() )
   283       for ( 
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
   285         tableTransparency->removeRow( myTableRunner );
   288       while ( !myInputStream.atEnd() )
   291         myInputLine = myInputStream.readLine();
   292         if ( !myInputLine.isEmpty() )
   294           if ( !myInputLine.simplified().startsWith( 
'#' ) )
   296             QStringList myTokens = myInputLine.split( QRegExp( 
"\\s+" ), QString::SkipEmptyParts );
   297             if ( myTokens.count() != 4 )
   299               myImportError = 
true;
   300               myBadLines = myBadLines + QString::number( myLineCounter ) + 
":\t[" + myInputLine + 
"]\n";
   304               tableTransparency->insertRow( tableTransparency->rowCount() );
   305               for ( 
int col = 0; col < 4; col++ )
   307                 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
   316       for ( 
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
   318         tableTransparency->removeRow( myTableRunner );
   321       while ( !myInputStream.atEnd() )
   324         myInputLine = myInputStream.readLine();
   325         if ( !myInputLine.isEmpty() )
   327           if ( !myInputLine.simplified().startsWith( 
'#' ) )
   329             QStringList myTokens = myInputLine.split( QRegExp( 
"\\s+" ), QString::SkipEmptyParts );
   330             if ( myTokens.count() != 3 && myTokens.count() != 2 ) 
   332               myImportError = 
true;
   333               myBadLines = myBadLines + QString::number( myLineCounter ) + 
":\t[" + myInputLine + 
"]\n";
   337               if ( myTokens.count() == 2 )
   339                 myTokens.insert( 1, myTokens[0] ); 
   341               tableTransparency->insertRow( tableTransparency->rowCount() );
   342               for ( 
int col = 0; col < 3; col++ )
   344                 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
   354       QMessageBox::warning( 
this, tr( 
"Load Pixel Values from File" ), tr( 
"The following lines contained errors\n\n%1" ).arg( myBadLines ) );
   357   else if ( !myFileName.isEmpty() )
   359     QMessageBox::warning( 
this, tr( 
"Load Pixel Values from File" ), tr( 
"Read access denied. Adjust the file permissions and try again.\n\n" ) );
   361   tableTransparency->resizeColumnsToContents();
   362   tableTransparency->resizeRowsToContents();
   366 void QgsRasterTransparencyWidget::pbnRemoveSelectedRow_clicked()
   368   if ( 0 < tableTransparency->rowCount() )
   370     tableTransparency->removeRow( tableTransparency->currentRow() );
   375 bool QgsRasterTransparencyWidget::rasterIsMultiBandColor()
   384   if ( 
"" != leNoDataValue->text() )
   386     bool myDoubleOk = 
false;
   387     double myNoDataValue = leNoDataValue->text().toDouble( &myDoubleOk );
   391       myNoDataRangeList << myNoDataRange;
   402   if ( rasterRenderer )
   404     rasterRenderer->
setAlphaBand( cboxTransparencyBand->currentBand() );
   408     if ( tableTransparency->columnCount() == 4 )
   411       QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
   412       myTransparentThreeValuePixelList.reserve( tableTransparency->rowCount() );
   413       for ( 
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
   415         myTransparentPixel.
red = transparencyCellValue( myListRunner, 0 );
   416         myTransparentPixel.
green = transparencyCellValue( myListRunner, 1 );
   417         myTransparentPixel.
blue = transparencyCellValue( myListRunner, 2 );
   419         myTransparentThreeValuePixelList.append( myTransparentPixel );
   423     else if ( tableTransparency->columnCount() == 3 )
   426       QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
   427       myTransparentSingleValuePixelList.reserve( tableTransparency->rowCount() );
   428       for ( 
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
   430         myTransparentPixel.
min = transparencyCellValue( myListRunner, 0 );
   431         myTransparentPixel.
max = transparencyCellValue( myListRunner, 1 );
   434         myTransparentSingleValuePixelList.append( myTransparentPixel );
   442     rasterRenderer->
setOpacity( mOpacityWidget->opacity() );
   446 void QgsRasterTransparencyWidget::pixelSelected( 
const QgsPointXY &canvasPoint )
   455   if ( mMapCanvas && mPixelSelectorTool )
   464     int myWidth = mMapCanvas->
extent().
width() / mapUnitsPerPixel;
   465     int myHeight = mMapCanvas->
extent().
height() / mapUnitsPerPixel;
   469     QList<int> bands = renderer->
usesBands();
   471     QList<double> values;
   472     for ( 
int i = 0; i < bands.size(); ++i )
   474       int bandNo = bands.value( i );
   475       if ( myPixelMap.count( bandNo ) == 1 )
   477         if ( myPixelMap.value( bandNo ).isNull() )
   481         double value = myPixelMap.value( bandNo ).toDouble();
   482         QgsDebugMsg( QStringLiteral( 
"value = %1" ).arg( value, 0, 
'g', 17 ) );
   483         values.append( value );
   486     if ( bands.size() == 1 )
   489       values.insert( 1, values.value( 0 ) );
   491     tableTransparency->insertRow( tableTransparency->rowCount() );
   492     for ( 
int i = 0; i < values.size(); i++ )
   494       setTransparencyCell( tableTransparency->rowCount() - 1, i, values.value( i ) );
   496     setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
   499   tableTransparency->resizeColumnsToContents();
   500   tableTransparency->resizeRowsToContents();
   503 void QgsRasterTransparencyWidget::populateTransparencyTable( 
QgsRasterRenderer *renderer )
   515   int nBands = renderer->
usesBands().size();
   516   setupTransparencyTable( nBands );
   519   if ( !rasterTransparency )
   527     for ( 
int i = 0; i < pixelList.size(); ++i )
   529       tableTransparency->insertRow( i );
   530       setTransparencyCell( i, 0, pixelList[i].min );
   531       setTransparencyCell( i, 1, pixelList[i].max );
   532       setTransparencyCell( i, 2, pixelList[i].percentTransparent );
   534       if ( pixelList[i].min != pixelList[i].max )
   536         setTransparencyToEdited( i );
   540   else if ( nBands == 3 )
   543     for ( 
int i = 0; i < pixelList.size(); ++i )
   545       tableTransparency->insertRow( i );
   546       setTransparencyCell( i, 0, pixelList[i].red );
   547       setTransparencyCell( i, 1, pixelList[i].green );
   548       setTransparencyCell( i, 2, pixelList[i].blue );
   549       setTransparencyCell( i, 3, pixelList[i].percentTransparent );
   553   tableTransparency->resizeColumnsToContents();
   554   tableTransparency->resizeRowsToContents();
   558 void QgsRasterTransparencyWidget::setupTransparencyTable( 
int nBands )
   560   tableTransparency->clear();
   561   tableTransparency->setColumnCount( 0 );
   562   tableTransparency->setRowCount( 0 );
   563   mTransparencyToEdited.clear();
   567     tableTransparency->setColumnCount( 4 );
   568     tableTransparency->setHorizontalHeaderItem( 0, 
new QTableWidgetItem( tr( 
"Red" ) ) );
   569     tableTransparency->setHorizontalHeaderItem( 1, 
new QTableWidgetItem( tr( 
"Green" ) ) );
   570     tableTransparency->setHorizontalHeaderItem( 2, 
new QTableWidgetItem( tr( 
"Blue" ) ) );
   571     tableTransparency->setHorizontalHeaderItem( 3, 
new QTableWidgetItem( tr( 
"Percent Transparent" ) ) );
   575     tableTransparency->setColumnCount( 3 );
   578     if ( QgsRasterLayer::PalettedColor != mRasterLayer->drawingStyle() &&
   579          QgsRasterLayer::PalettedSingleBandGray != mRasterLayer->drawingStyle() &&
   580          QgsRasterLayer::PalettedSingleBandPseudoColor != mRasterLayer->drawingStyle() &&
   581          QgsRasterLayer::PalettedMultiBandColor != mRasterLayer->drawingStyle() )
   583       tableTransparency->setHorizontalHeaderItem( 0, 
new QTableWidgetItem( tr( 
"Gray" ) ) );
   587       tableTransparency->setHorizontalHeaderItem( 0, 
new QTableWidgetItem( tr( 
"Indexed Value" ) ) );
   590     tableTransparency->setHorizontalHeaderItem( 0, 
new QTableWidgetItem( tr( 
"From" ) ) );
   591     tableTransparency->setHorizontalHeaderItem( 1, 
new QTableWidgetItem( tr( 
"To" ) ) );
   592     tableTransparency->setHorizontalHeaderItem( 2, 
new QTableWidgetItem( tr( 
"Percent Transparent" ) ) );
   596 void QgsRasterTransparencyWidget::setTransparencyCell( 
int row, 
int column, 
double value )
   598   QgsDebugMsg( QStringLiteral( 
"value = %1" ).arg( value, 0, 
'g', 17 ) );
   600   if ( !provider ) 
return;
   603   if ( !renderer ) 
return;
   604   int nBands = renderer->
usesBands().size();
   606   QLineEdit *lineEdit = 
new QLineEdit();
   607   lineEdit->setFrame( 
false ); 
   609   lineEdit->setContentsMargins( 1, 1, 1, 1 );
   611   if ( column == tableTransparency->columnCount() - 1 )
   615     lineEdit->setValidator( 
new QIntValidator( 
nullptr ) );
   616     lineEdit->setText( QString::number( static_cast<int>( value ) ) );
   626         lineEdit->setValidator( 
new QDoubleValidator( 
nullptr ) );
   627         if ( !std::isnan( value ) )
   633         lineEdit->setValidator( 
new QIntValidator( 
nullptr ) );
   634         if ( !std::isnan( value ) )
   636           valueString = QString::number( static_cast<int>( value ) );
   640     lineEdit->setText( valueString );
   643   tableTransparency->setCellWidget( row, column, lineEdit );
   644   adjustTransparencyCellWidth( row, column );
   646   if ( nBands == 1 && ( column == 0 || column == 1 ) )
   648     connect( lineEdit, &QLineEdit::textEdited, 
this, &QgsRasterTransparencyWidget::transparencyCellTextEdited );
   650   tableTransparency->resizeColumnsToContents();
   654 void QgsRasterTransparencyWidget::adjustTransparencyCellWidth( 
int row, 
int column )
   656   QLineEdit *lineEdit = 
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
   657   if ( !lineEdit ) 
return;
   659   int width = std::max( lineEdit->fontMetrics().width( lineEdit->text() ) + 10, 100 );
   660   width = std::max( width, tableTransparency->columnWidth( column ) );
   662   lineEdit->setFixedWidth( width );
   665 void QgsRasterTransparencyWidget::setTransparencyToEdited( 
int row )
   667   if ( row >= mTransparencyToEdited.size() )
   669     mTransparencyToEdited.resize( row + 1 );
   671   mTransparencyToEdited[row] = 
true;
   674 double QgsRasterTransparencyWidget::transparencyCellValue( 
int row, 
int column )
   676   QLineEdit *lineEdit = 
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
   677   if ( !lineEdit || lineEdit->text().isEmpty() )
   679     std::numeric_limits<double>::quiet_NaN();
   681   return lineEdit->text().toDouble();
 void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool. 
 
virtual int bandCount() const =0
Gets number of bands. 
 
A rectangle specified with double values. 
 
static QString printValue(double value)
Print double value with all necessary significant digits. 
 
virtual void setUseSourceNoDataValue(int bandNo, bool use)
Sets the source nodata value usage. 
 
void setTransparentThreeValuePixelList(const QList< QgsRasterTransparency::TransparentThreeValuePixel > &newList)
Sets the transparent three value pixel list, replacing the whole existing list. 
 
This class is a composition of two QSettings instances: 
 
virtual QList< int > usesBands() const
Returns a list of band numbers used by the renderer. 
 
double opacity() const
Returns the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1...
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key. 
 
This class provides qgis with the ability to render raster datasets onto the mapcanvas. 
 
A class to represent a 2D point. 
 
Qgis::DataType sourceDataType(int bandNo) const override=0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
 
Raster values range container. 
 
QgsRasterRenderer * renderer() const
Returns the raster's renderer. 
 
Thirty two bit floating point (float) 
 
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value. 
 
Map canvas is a class for displaying all GIS data types on a canvas. 
 
const QgsRasterTransparency * rasterTransparency() const
 
Sixty four bit floating point (double) 
 
The QgsMapSettings class contains configuration for rendering of the map. 
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied. 
 
QgsRasterDataProvider * dataProvider() override
Returns the source data provider. 
 
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas. 
 
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas. 
 
double percentTransparent
 
double width() const
Returns the width of the rectangle. 
 
void bandChanged(int band)
Emitted when the currently selected band changes. 
 
QgsRectangle extent() const
Returns the current zoom extent of the map canvas. 
 
void setAlphaBand(int band)
 
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value. 
 
QList< QgsRasterTransparency::TransparentSingleValuePixel > transparentSingleValuePixelList() const
Returns the transparent single value pixel list. 
 
QMap< int, QVariant > results() const
Returns the identify results. 
 
void setTransparentSingleValuePixelList(const QList< QgsRasterTransparency::TransparentSingleValuePixel > &newList)
Sets the transparent single value pixel list, replacing the whole existing list. 
 
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering. 
 
QList< QgsRasterRange > QgsRasterRangeList
 
virtual QgsRasterIdentifyResult identify(const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Identify raster value(s) found on the point position. 
 
Renderer for multiband images with the color components. 
 
virtual QgsRasterRangeList userNoDataValues(int bandNo) const
Returns a list of user no data value ranges. 
 
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
 
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1...
 
virtual bool useSourceNoDataValue(int bandNo) const
Returns the source nodata value usage. 
 
QList< QgsRasterTransparency::TransparentThreeValuePixel > transparentThreeValuePixelList() const
Returns the transparent three value pixel list. 
 
virtual void setUserNoDataValue(int bandNo, const QgsRasterRangeList &noData)
 
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS 
 
void setRasterTransparency(QgsRasterTransparency *t)
 
double percentTransparent
 
Raster renderer pipe that applies colors to a raster. 
 
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number. 
 
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32. 
 
double height() const
Returns the height of the rectangle. 
 
Base class for raster data providers.