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 );
52 mNodataColorButton->setShowNoColor(
true );
53 mNodataColorButton->setColorDialogTitle( tr(
"Select No Data Color" ) );
62 mPixelSelectorTool =
nullptr;
70 pbnAddValuesFromDisplay->setEnabled(
false );
83 gboxNoDataValue->setEnabled(
false );
84 gboxCustomTransparency->setEnabled(
false );
87 cboxTransparencyBand->setShowNotSetOption(
true, tr(
"None" ) );
88 cboxTransparencyBand->setLayer( mRasterLayer );
92 cboxTransparencyBand->setBand( renderer->
alphaBand() );
101 lblSrcNoDataValue->setText( tr(
"not defined" ) );
108 mSrcNoDataValueCheckBox->setEnabled( enableSrcNoData );
109 lblSrcNoDataValue->setEnabled( enableSrcNoData );
114 mNodataColorButton->setColor( renderer->
nodataColor() );
116 mNodataColorButton->setToNull();
120 QgsDebugMsg( QStringLiteral(
"noDataRangeList.size = %1" ).arg( noDataRangeList.size() ) );
121 if ( !noDataRangeList.isEmpty() )
127 leNoDataValue->setText( QString() );
130 populateTransparencyTable( mRasterLayer->
renderer() );
133 void QgsRasterTransparencyWidget::transparencyCellTextEdited(
const QString &text )
136 QgsDebugMsg( QStringLiteral(
"text = %1" ).arg( text ) );
142 int nBands = renderer->
usesBands().size();
145 QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
146 if ( !lineEdit )
return;
149 for (
int r = 0; r < tableTransparency->rowCount(); r++ )
151 for (
int c = 0;
c < tableTransparency->columnCount();
c++ )
153 if ( tableTransparency->cellWidget( r,
c ) == sender() )
160 if ( row != -1 )
break;
162 QgsDebugMsg( QStringLiteral(
"row = %1 column =%2" ).arg( row ).arg( column ) );
166 QLineEdit *toLineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, 1 ) );
167 if ( !toLineEdit )
return;
168 bool toChanged = mTransparencyToEdited.value( row );
169 QgsDebugMsg( QStringLiteral(
"toChanged = %1" ).arg( toChanged ) );
172 toLineEdit->setText( lineEdit->text() );
175 else if ( column == 1 )
177 setTransparencyToEdited( row );
183 void QgsRasterTransparencyWidget::pbnAddValuesFromDisplay_clicked()
185 if ( mMapCanvas && mPixelSelectorTool )
191 void QgsRasterTransparencyWidget::pbnAddValuesManually_clicked()
199 tableTransparency->insertRow( tableTransparency->rowCount() );
204 for (
int i = 0; i < n; i++ )
206 setTransparencyCell( tableTransparency->rowCount() - 1, i, std::numeric_limits<double>::quiet_NaN() );
209 setTransparencyCell( tableTransparency->rowCount() - 1, n, 100 );
211 tableTransparency->resizeColumnsToContents();
212 tableTransparency->resizeRowsToContents();
215 void QgsRasterTransparencyWidget::pbnDefaultValues_clicked()
225 setupTransparencyTable( nBands );
227 tableTransparency->resizeColumnsToContents();
228 tableTransparency->resizeRowsToContents();
232 void QgsRasterTransparencyWidget::pbnExportTransparentPixelValues_clicked()
235 QString myLastDir = myQSettings.
value( QStringLiteral(
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
236 QString myFileName = QFileDialog::getSaveFileName(
this, tr(
"Save Pixel Values as File" ), myLastDir, tr(
"Textfile" ) +
" (*.txt)" );
237 if ( !myFileName.isEmpty() )
239 if ( !myFileName.endsWith( QLatin1String(
".txt" ), Qt::CaseInsensitive ) )
241 myFileName = myFileName +
".txt";
244 QFile myOutputFile( myFileName );
245 if ( myOutputFile.open( QFile::WriteOnly | QIODevice::Truncate ) )
247 QTextStream myOutputStream( &myOutputFile );
248 myOutputStream <<
"# " << tr(
"QGIS Generated Transparent Pixel Value Export File" ) <<
'\n';
249 if ( rasterIsMultiBandColor() )
251 myOutputStream <<
"#\n#\n# " << tr(
"Red" ) <<
"\t" << tr(
"Green" ) <<
"\t" << tr(
"Blue" ) <<
"\t" << tr(
"Percent Transparent" );
252 for (
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
254 myOutputStream <<
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) <<
"\t" 255 << QString::number( transparencyCellValue( myTableRunner, 1 ) ) <<
"\t" 256 << QString::number( transparencyCellValue( myTableRunner, 2 ) ) <<
"\t" 257 << QString::number( transparencyCellValue( myTableRunner, 3 ) );
262 myOutputStream <<
"#\n#\n# " << tr(
"Value" ) <<
"\t" << tr(
"Percent Transparent" );
264 for (
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
266 myOutputStream <<
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) <<
"\t" 267 << QString::number( transparencyCellValue( myTableRunner, 1 ) ) <<
"\t" 268 << QString::number( transparencyCellValue( myTableRunner, 2 ) );
274 QMessageBox::warning(
this, tr(
"Save Pixel Values as File" ), tr(
"Write access denied. Adjust the file permissions and try again.\n\n" ) );
279 void QgsRasterTransparencyWidget::pbnImportTransparentPixelValues_clicked()
281 int myLineCounter = 0;
282 bool myImportError =
false;
285 QString myLastDir = myQSettings.
value( QStringLiteral(
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
286 QString myFileName = QFileDialog::getOpenFileName(
this, tr(
"Load Pixel Values from File" ), myLastDir, tr(
"Textfile" ) +
" (*.txt)" );
287 QFile myInputFile( myFileName );
288 if ( myInputFile.open( QFile::ReadOnly ) )
290 QTextStream myInputStream( &myInputFile );
292 if ( rasterIsMultiBandColor() )
294 for (
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
296 tableTransparency->removeRow( myTableRunner );
299 while ( !myInputStream.atEnd() )
302 myInputLine = myInputStream.readLine();
303 if ( !myInputLine.isEmpty() )
305 if ( !myInputLine.simplified().startsWith(
'#' ) )
307 QStringList myTokens = myInputLine.split( QRegExp(
"\\s+" ), QString::SkipEmptyParts );
308 if ( myTokens.count() != 4 )
310 myImportError =
true;
311 myBadLines = myBadLines + QString::number( myLineCounter ) +
":\t[" + myInputLine +
"]\n";
315 tableTransparency->insertRow( tableTransparency->rowCount() );
316 for (
int col = 0; col < 4; col++ )
318 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
327 for (
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
329 tableTransparency->removeRow( myTableRunner );
332 while ( !myInputStream.atEnd() )
335 myInputLine = myInputStream.readLine();
336 if ( !myInputLine.isEmpty() )
338 if ( !myInputLine.simplified().startsWith(
'#' ) )
340 QStringList myTokens = myInputLine.split( QRegExp(
"\\s+" ), QString::SkipEmptyParts );
341 if ( myTokens.count() != 3 && myTokens.count() != 2 )
343 myImportError =
true;
344 myBadLines = myBadLines + QString::number( myLineCounter ) +
":\t[" + myInputLine +
"]\n";
348 if ( myTokens.count() == 2 )
350 myTokens.insert( 1, myTokens[0] );
352 tableTransparency->insertRow( tableTransparency->rowCount() );
353 for (
int col = 0; col < 3; col++ )
355 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
365 QMessageBox::warning(
this, tr(
"Load Pixel Values from File" ), tr(
"The following lines contained errors\n\n%1" ).arg( myBadLines ) );
368 else if ( !myFileName.isEmpty() )
370 QMessageBox::warning(
this, tr(
"Load Pixel Values from File" ), tr(
"Read access denied. Adjust the file permissions and try again.\n\n" ) );
372 tableTransparency->resizeColumnsToContents();
373 tableTransparency->resizeRowsToContents();
377 void QgsRasterTransparencyWidget::pbnRemoveSelectedRow_clicked()
379 if ( 0 < tableTransparency->rowCount() )
381 tableTransparency->removeRow( tableTransparency->currentRow() );
386 bool QgsRasterTransparencyWidget::rasterIsMultiBandColor()
395 if (
"" != leNoDataValue->text() )
397 bool myDoubleOk =
false;
398 double myNoDataValue = leNoDataValue->text().toDouble( &myDoubleOk );
402 myNoDataRangeList << myNoDataRange;
413 if ( rasterRenderer )
415 rasterRenderer->
setAlphaBand( cboxTransparencyBand->currentBand() );
420 if ( tableTransparency->columnCount() == 4 )
423 QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
424 myTransparentThreeValuePixelList.reserve( tableTransparency->rowCount() );
425 for (
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
427 myTransparentPixel.
red = transparencyCellValue( myListRunner, 0 );
428 myTransparentPixel.
green = transparencyCellValue( myListRunner, 1 );
429 myTransparentPixel.
blue = transparencyCellValue( myListRunner, 2 );
431 myTransparentThreeValuePixelList.append( myTransparentPixel );
435 else if ( tableTransparency->columnCount() == 3 )
438 QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
439 myTransparentSingleValuePixelList.reserve( tableTransparency->rowCount() );
440 for (
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
442 myTransparentPixel.
min = transparencyCellValue( myListRunner, 0 );
443 myTransparentPixel.
max = transparencyCellValue( myListRunner, 1 );
446 myTransparentSingleValuePixelList.append( myTransparentPixel );
454 rasterRenderer->
setOpacity( mOpacityWidget->opacity() );
458 void QgsRasterTransparencyWidget::pixelSelected(
const QgsPointXY &canvasPoint )
467 if ( mMapCanvas && mPixelSelectorTool )
476 int myWidth = mMapCanvas->
extent().
width() / mapUnitsPerPixel;
477 int myHeight = mMapCanvas->
extent().
height() / mapUnitsPerPixel;
481 QList<int> bands = renderer->
usesBands();
483 QList<double> values;
484 for (
int i = 0; i < bands.size(); ++i )
486 int bandNo = bands.value( i );
487 if ( myPixelMap.count( bandNo ) == 1 )
489 if ( myPixelMap.value( bandNo ).isNull() )
493 double value = myPixelMap.value( bandNo ).toDouble();
494 QgsDebugMsg( QStringLiteral(
"value = %1" ).arg( value, 0,
'g', 17 ) );
495 values.append( value );
498 if ( bands.size() == 1 )
501 values.insert( 1, values.value( 0 ) );
503 tableTransparency->insertRow( tableTransparency->rowCount() );
504 for (
int i = 0; i < values.size(); i++ )
506 setTransparencyCell( tableTransparency->rowCount() - 1, i, values.value( i ) );
508 setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
511 tableTransparency->resizeColumnsToContents();
512 tableTransparency->resizeRowsToContents();
515 void QgsRasterTransparencyWidget::populateTransparencyTable(
QgsRasterRenderer *renderer )
527 int nBands = renderer->
usesBands().size();
528 setupTransparencyTable( nBands );
531 if ( !rasterTransparency )
539 for (
int i = 0; i < pixelList.size(); ++i )
541 tableTransparency->insertRow( i );
542 setTransparencyCell( i, 0, pixelList[i].min );
543 setTransparencyCell( i, 1, pixelList[i].max );
544 setTransparencyCell( i, 2, pixelList[i].percentTransparent );
546 if ( pixelList[i].min != pixelList[i].max )
548 setTransparencyToEdited( i );
552 else if ( nBands == 3 )
555 for (
int i = 0; i < pixelList.size(); ++i )
557 tableTransparency->insertRow( i );
558 setTransparencyCell( i, 0, pixelList[i].red );
559 setTransparencyCell( i, 1, pixelList[i].green );
560 setTransparencyCell( i, 2, pixelList[i].blue );
561 setTransparencyCell( i, 3, pixelList[i].percentTransparent );
565 tableTransparency->resizeColumnsToContents();
566 tableTransparency->resizeRowsToContents();
570 void QgsRasterTransparencyWidget::setupTransparencyTable(
int nBands )
572 tableTransparency->clear();
573 tableTransparency->setColumnCount( 0 );
574 tableTransparency->setRowCount( 0 );
575 mTransparencyToEdited.clear();
579 tableTransparency->setColumnCount( 4 );
580 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Red" ) ) );
581 tableTransparency->setHorizontalHeaderItem( 1,
new QTableWidgetItem( tr(
"Green" ) ) );
582 tableTransparency->setHorizontalHeaderItem( 2,
new QTableWidgetItem( tr(
"Blue" ) ) );
583 tableTransparency->setHorizontalHeaderItem( 3,
new QTableWidgetItem( tr(
"Percent Transparent" ) ) );
587 tableTransparency->setColumnCount( 3 );
590 if ( QgsRasterLayer::PalettedColor != mRasterLayer->drawingStyle() &&
591 QgsRasterLayer::PalettedSingleBandGray != mRasterLayer->drawingStyle() &&
592 QgsRasterLayer::PalettedSingleBandPseudoColor != mRasterLayer->drawingStyle() &&
593 QgsRasterLayer::PalettedMultiBandColor != mRasterLayer->drawingStyle() )
595 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Gray" ) ) );
599 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Indexed Value" ) ) );
602 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"From" ) ) );
603 tableTransparency->setHorizontalHeaderItem( 1,
new QTableWidgetItem( tr(
"To" ) ) );
604 tableTransparency->setHorizontalHeaderItem( 2,
new QTableWidgetItem( tr(
"Percent Transparent" ) ) );
608 void QgsRasterTransparencyWidget::setTransparencyCell(
int row,
int column,
double value )
610 QgsDebugMsg( QStringLiteral(
"value = %1" ).arg( value, 0,
'g', 17 ) );
612 if ( !provider )
return;
615 if ( !renderer )
return;
616 int nBands = renderer->
usesBands().size();
618 QLineEdit *lineEdit =
new QLineEdit();
619 lineEdit->setFrame(
false );
621 lineEdit->setContentsMargins( 1, 1, 1, 1 );
623 if ( column == tableTransparency->columnCount() - 1 )
627 lineEdit->setValidator(
new QIntValidator(
nullptr ) );
628 lineEdit->setText( QString::number( static_cast<int>( value ) ) );
638 lineEdit->setValidator(
new QDoubleValidator(
nullptr ) );
639 if ( !std::isnan( value ) )
645 lineEdit->setValidator(
new QIntValidator(
nullptr ) );
646 if ( !std::isnan( value ) )
648 valueString = QString::number( static_cast<int>( value ) );
652 lineEdit->setText( valueString );
655 tableTransparency->setCellWidget( row, column, lineEdit );
656 adjustTransparencyCellWidth( row, column );
658 if ( nBands == 1 && ( column == 0 || column == 1 ) )
660 connect( lineEdit, &QLineEdit::textEdited,
this, &QgsRasterTransparencyWidget::transparencyCellTextEdited );
662 tableTransparency->resizeColumnsToContents();
666 void QgsRasterTransparencyWidget::adjustTransparencyCellWidth(
int row,
int column )
668 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
669 if ( !lineEdit )
return;
671 int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
672 width = std::max( width, tableTransparency->columnWidth( column ) );
674 lineEdit->setFixedWidth( width );
677 void QgsRasterTransparencyWidget::setTransparencyToEdited(
int row )
679 if ( row >= mTransparencyToEdited.size() )
681 mTransparencyToEdited.resize( row + 1 );
683 mTransparencyToEdited[row] =
true;
686 double QgsRasterTransparencyWidget::transparencyCellValue(
int row,
int column )
688 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
689 if ( !lineEdit || lineEdit->text().isEmpty() )
691 std::numeric_limits<double>::quiet_NaN();
693 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:
QColor nodataColor() const
Returns the color to use for shading nodata pixels.
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.
Represents a raster layer.
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.
void setNodataColor(const QColor &color)
Sets the color to use for shading nodata pixels.
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.