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 );
73 if ( ! mRasterLayer->
isValid() )
82 gboxNoDataValue->setEnabled(
false );
83 gboxCustomTransparency->setEnabled(
false );
86 cboxTransparencyBand->setShowNotSetOption(
true, tr(
"None" ) );
87 cboxTransparencyBand->setLayer( mRasterLayer );
91 cboxTransparencyBand->setBand( renderer->
alphaBand() );
100 lblSrcNoDataValue->setText( tr(
"not defined" ) );
107 mSrcNoDataValueCheckBox->setEnabled( enableSrcNoData );
108 lblSrcNoDataValue->setEnabled( enableSrcNoData );
111 QgsDebugMsg( QStringLiteral(
"noDataRangeList.size = %1" ).arg( noDataRangeList.size() ) );
112 if ( !noDataRangeList.isEmpty() )
118 leNoDataValue->insert( QString() );
121 populateTransparencyTable( mRasterLayer->
renderer() );
124 void QgsRasterTransparencyWidget::transparencyCellTextEdited(
const QString &text )
127 QgsDebugMsg( QStringLiteral(
"text = %1" ).arg( text ) );
133 int nBands = renderer->
usesBands().size();
136 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( sender() );
137 if ( !lineEdit )
return;
140 for (
int r = 0; r < tableTransparency->rowCount(); r++ )
142 for (
int c = 0;
c < tableTransparency->columnCount();
c++ )
144 if ( tableTransparency->cellWidget( r,
c ) == sender() )
151 if ( row != -1 )
break;
153 QgsDebugMsg( QStringLiteral(
"row = %1 column =%2" ).arg( row ).arg( column ) );
157 QLineEdit *toLineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, 1 ) );
158 if ( !toLineEdit )
return;
159 bool toChanged = mTransparencyToEdited.value( row );
160 QgsDebugMsg( QStringLiteral(
"toChanged = %1" ).arg( toChanged ) );
163 toLineEdit->setText( lineEdit->text() );
166 else if ( column == 1 )
168 setTransparencyToEdited( row );
174 void QgsRasterTransparencyWidget::pbnAddValuesFromDisplay_clicked()
176 if ( mMapCanvas && mPixelSelectorTool )
182 void QgsRasterTransparencyWidget::pbnAddValuesManually_clicked()
190 tableTransparency->insertRow( tableTransparency->rowCount() );
195 for (
int i = 0; i < n; i++ )
197 setTransparencyCell( tableTransparency->rowCount() - 1, i, std::numeric_limits<double>::quiet_NaN() );
200 setTransparencyCell( tableTransparency->rowCount() - 1, n, 100 );
202 tableTransparency->resizeColumnsToContents();
203 tableTransparency->resizeRowsToContents();
206 void QgsRasterTransparencyWidget::pbnDefaultValues_clicked()
216 setupTransparencyTable( nBands );
218 tableTransparency->resizeColumnsToContents();
219 tableTransparency->resizeRowsToContents();
223 void QgsRasterTransparencyWidget::pbnExportTransparentPixelValues_clicked()
226 QString myLastDir = myQSettings.
value( QStringLiteral(
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
227 QString myFileName = QFileDialog::getSaveFileName(
this, tr(
"Save Pixel Values as File" ), myLastDir, tr(
"Textfile" ) +
" (*.txt)" );
228 if ( !myFileName.isEmpty() )
230 if ( !myFileName.endsWith( QLatin1String(
".txt" ), Qt::CaseInsensitive ) )
232 myFileName = myFileName +
".txt";
235 QFile myOutputFile( myFileName );
236 if ( myOutputFile.open( QFile::WriteOnly | QIODevice::Truncate ) )
238 QTextStream myOutputStream( &myOutputFile );
239 myOutputStream <<
"# " << tr(
"QGIS Generated Transparent Pixel Value Export File" ) <<
'\n';
240 if ( rasterIsMultiBandColor() )
242 myOutputStream <<
"#\n#\n# " << tr(
"Red" ) <<
"\t" << tr(
"Green" ) <<
"\t" << tr(
"Blue" ) <<
"\t" << tr(
"Percent Transparent" );
243 for (
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
245 myOutputStream <<
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) <<
"\t" 246 << QString::number( transparencyCellValue( myTableRunner, 1 ) ) <<
"\t" 247 << QString::number( transparencyCellValue( myTableRunner, 2 ) ) <<
"\t" 248 << QString::number( transparencyCellValue( myTableRunner, 3 ) );
253 myOutputStream <<
"#\n#\n# " << tr(
"Value" ) <<
"\t" << tr(
"Percent Transparent" );
255 for (
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
257 myOutputStream <<
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) <<
"\t" 258 << QString::number( transparencyCellValue( myTableRunner, 1 ) ) <<
"\t" 259 << QString::number( transparencyCellValue( myTableRunner, 2 ) );
265 QMessageBox::warning(
this, tr(
"Save Pixel Values as File" ), tr(
"Write access denied. Adjust the file permissions and try again.\n\n" ) );
270 void QgsRasterTransparencyWidget::pbnImportTransparentPixelValues_clicked()
272 int myLineCounter = 0;
273 bool myImportError =
false;
276 QString myLastDir = myQSettings.
value( QStringLiteral(
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
277 QString myFileName = QFileDialog::getOpenFileName(
this, tr(
"Load Pixel Values from File" ), myLastDir, tr(
"Textfile" ) +
" (*.txt)" );
278 QFile myInputFile( myFileName );
279 if ( myInputFile.open( QFile::ReadOnly ) )
281 QTextStream myInputStream( &myInputFile );
283 if ( rasterIsMultiBandColor() )
285 for (
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
287 tableTransparency->removeRow( myTableRunner );
290 while ( !myInputStream.atEnd() )
293 myInputLine = myInputStream.readLine();
294 if ( !myInputLine.isEmpty() )
296 if ( !myInputLine.simplified().startsWith(
'#' ) )
298 QStringList myTokens = myInputLine.split( QRegExp(
"\\s+" ), QString::SkipEmptyParts );
299 if ( myTokens.count() != 4 )
301 myImportError =
true;
302 myBadLines = myBadLines + QString::number( myLineCounter ) +
":\t[" + myInputLine +
"]\n";
306 tableTransparency->insertRow( tableTransparency->rowCount() );
307 for (
int col = 0; col < 4; col++ )
309 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
318 for (
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
320 tableTransparency->removeRow( myTableRunner );
323 while ( !myInputStream.atEnd() )
326 myInputLine = myInputStream.readLine();
327 if ( !myInputLine.isEmpty() )
329 if ( !myInputLine.simplified().startsWith(
'#' ) )
331 QStringList myTokens = myInputLine.split( QRegExp(
"\\s+" ), QString::SkipEmptyParts );
332 if ( myTokens.count() != 3 && myTokens.count() != 2 )
334 myImportError =
true;
335 myBadLines = myBadLines + QString::number( myLineCounter ) +
":\t[" + myInputLine +
"]\n";
339 if ( myTokens.count() == 2 )
341 myTokens.insert( 1, myTokens[0] );
343 tableTransparency->insertRow( tableTransparency->rowCount() );
344 for (
int col = 0; col < 3; col++ )
346 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
356 QMessageBox::warning(
this, tr(
"Load Pixel Values from File" ), tr(
"The following lines contained errors\n\n%1" ).arg( myBadLines ) );
359 else if ( !myFileName.isEmpty() )
361 QMessageBox::warning(
this, tr(
"Load Pixel Values from File" ), tr(
"Read access denied. Adjust the file permissions and try again.\n\n" ) );
363 tableTransparency->resizeColumnsToContents();
364 tableTransparency->resizeRowsToContents();
368 void QgsRasterTransparencyWidget::pbnRemoveSelectedRow_clicked()
370 if ( 0 < tableTransparency->rowCount() )
372 tableTransparency->removeRow( tableTransparency->currentRow() );
377 bool QgsRasterTransparencyWidget::rasterIsMultiBandColor()
386 if (
"" != leNoDataValue->text() )
388 bool myDoubleOk =
false;
389 double myNoDataValue = leNoDataValue->text().toDouble( &myDoubleOk );
393 myNoDataRangeList << myNoDataRange;
404 if ( rasterRenderer )
406 rasterRenderer->
setAlphaBand( cboxTransparencyBand->currentBand() );
410 if ( tableTransparency->columnCount() == 4 )
413 QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
414 myTransparentThreeValuePixelList.reserve( tableTransparency->rowCount() );
415 for (
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
417 myTransparentPixel.
red = transparencyCellValue( myListRunner, 0 );
418 myTransparentPixel.
green = transparencyCellValue( myListRunner, 1 );
419 myTransparentPixel.
blue = transparencyCellValue( myListRunner, 2 );
421 myTransparentThreeValuePixelList.append( myTransparentPixel );
425 else if ( tableTransparency->columnCount() == 3 )
428 QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
429 myTransparentSingleValuePixelList.reserve( tableTransparency->rowCount() );
430 for (
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
432 myTransparentPixel.
min = transparencyCellValue( myListRunner, 0 );
433 myTransparentPixel.
max = transparencyCellValue( myListRunner, 1 );
436 myTransparentSingleValuePixelList.append( myTransparentPixel );
444 rasterRenderer->
setOpacity( mOpacityWidget->opacity() );
448 void QgsRasterTransparencyWidget::pixelSelected(
const QgsPointXY &canvasPoint )
457 if ( mMapCanvas && mPixelSelectorTool )
466 int myWidth = mMapCanvas->
extent().
width() / mapUnitsPerPixel;
467 int myHeight = mMapCanvas->
extent().
height() / mapUnitsPerPixel;
471 QList<int> bands = renderer->
usesBands();
473 QList<double> values;
474 for (
int i = 0; i < bands.size(); ++i )
476 int bandNo = bands.value( i );
477 if ( myPixelMap.count( bandNo ) == 1 )
479 if ( myPixelMap.value( bandNo ).isNull() )
483 double value = myPixelMap.value( bandNo ).toDouble();
484 QgsDebugMsg( QStringLiteral(
"value = %1" ).arg( value, 0,
'g', 17 ) );
485 values.append( value );
488 if ( bands.size() == 1 )
491 values.insert( 1, values.value( 0 ) );
493 tableTransparency->insertRow( tableTransparency->rowCount() );
494 for (
int i = 0; i < values.size(); i++ )
496 setTransparencyCell( tableTransparency->rowCount() - 1, i, values.value( i ) );
498 setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
501 tableTransparency->resizeColumnsToContents();
502 tableTransparency->resizeRowsToContents();
505 void QgsRasterTransparencyWidget::populateTransparencyTable(
QgsRasterRenderer *renderer )
517 int nBands = renderer->
usesBands().size();
518 setupTransparencyTable( nBands );
521 if ( !rasterTransparency )
529 for (
int i = 0; i < pixelList.size(); ++i )
531 tableTransparency->insertRow( i );
532 setTransparencyCell( i, 0, pixelList[i].min );
533 setTransparencyCell( i, 1, pixelList[i].max );
534 setTransparencyCell( i, 2, pixelList[i].percentTransparent );
536 if ( pixelList[i].min != pixelList[i].max )
538 setTransparencyToEdited( i );
542 else if ( nBands == 3 )
545 for (
int i = 0; i < pixelList.size(); ++i )
547 tableTransparency->insertRow( i );
548 setTransparencyCell( i, 0, pixelList[i].red );
549 setTransparencyCell( i, 1, pixelList[i].green );
550 setTransparencyCell( i, 2, pixelList[i].blue );
551 setTransparencyCell( i, 3, pixelList[i].percentTransparent );
555 tableTransparency->resizeColumnsToContents();
556 tableTransparency->resizeRowsToContents();
560 void QgsRasterTransparencyWidget::setupTransparencyTable(
int nBands )
562 tableTransparency->clear();
563 tableTransparency->setColumnCount( 0 );
564 tableTransparency->setRowCount( 0 );
565 mTransparencyToEdited.clear();
569 tableTransparency->setColumnCount( 4 );
570 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Red" ) ) );
571 tableTransparency->setHorizontalHeaderItem( 1,
new QTableWidgetItem( tr(
"Green" ) ) );
572 tableTransparency->setHorizontalHeaderItem( 2,
new QTableWidgetItem( tr(
"Blue" ) ) );
573 tableTransparency->setHorizontalHeaderItem( 3,
new QTableWidgetItem( tr(
"Percent Transparent" ) ) );
577 tableTransparency->setColumnCount( 3 );
580 if ( QgsRasterLayer::PalettedColor != mRasterLayer->drawingStyle() &&
581 QgsRasterLayer::PalettedSingleBandGray != mRasterLayer->drawingStyle() &&
582 QgsRasterLayer::PalettedSingleBandPseudoColor != mRasterLayer->drawingStyle() &&
583 QgsRasterLayer::PalettedMultiBandColor != mRasterLayer->drawingStyle() )
585 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Gray" ) ) );
589 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Indexed Value" ) ) );
592 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"From" ) ) );
593 tableTransparency->setHorizontalHeaderItem( 1,
new QTableWidgetItem( tr(
"To" ) ) );
594 tableTransparency->setHorizontalHeaderItem( 2,
new QTableWidgetItem( tr(
"Percent Transparent" ) ) );
598 void QgsRasterTransparencyWidget::setTransparencyCell(
int row,
int column,
double value )
600 QgsDebugMsg( QStringLiteral(
"value = %1" ).arg( value, 0,
'g', 17 ) );
602 if ( !provider )
return;
605 if ( !renderer )
return;
606 int nBands = renderer->
usesBands().size();
608 QLineEdit *lineEdit =
new QLineEdit();
609 lineEdit->setFrame(
false );
611 lineEdit->setContentsMargins( 1, 1, 1, 1 );
613 if ( column == tableTransparency->columnCount() - 1 )
617 lineEdit->setValidator(
new QIntValidator(
nullptr ) );
618 lineEdit->setText( QString::number( static_cast<int>( value ) ) );
628 lineEdit->setValidator(
new QDoubleValidator(
nullptr ) );
629 if ( !std::isnan( value ) )
635 lineEdit->setValidator(
new QIntValidator(
nullptr ) );
636 if ( !std::isnan( value ) )
638 valueString = QString::number( static_cast<int>( value ) );
642 lineEdit->setText( valueString );
645 tableTransparency->setCellWidget( row, column, lineEdit );
646 adjustTransparencyCellWidth( row, column );
648 if ( nBands == 1 && ( column == 0 || column == 1 ) )
650 connect( lineEdit, &QLineEdit::textEdited,
this, &QgsRasterTransparencyWidget::transparencyCellTextEdited );
652 tableTransparency->resizeColumnsToContents();
656 void QgsRasterTransparencyWidget::adjustTransparencyCellWidth(
int row,
int column )
658 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
659 if ( !lineEdit )
return;
661 int width = std::max( lineEdit->fontMetrics().width( lineEdit->text() ) + 10, 100 );
662 width = std::max( width, tableTransparency->columnWidth( column ) );
664 lineEdit->setFixedWidth( width );
667 void QgsRasterTransparencyWidget::setTransparencyToEdited(
int row )
669 if ( row >= mTransparencyToEdited.size() )
671 mTransparencyToEdited.resize( row + 1 );
673 mTransparencyToEdited[row] =
true;
676 double QgsRasterTransparencyWidget::transparencyCellValue(
int row,
int column )
678 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
679 if ( !lineEdit || lineEdit->text().isEmpty() )
681 std::numeric_limits<double>::quiet_NaN();
683 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
Thirty two bit floating point (float)
bool isValid() const
Returns the status of the layer.
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 layer's data provider, it may be null.
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)
This signal is 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.