void QgsRendererRasterPropertiesWidget::setRendererWidget( const QString &rendererName ) { QgsDebugMsg( "rendererName = " + rendererName ); QgsRasterRendererWidget* oldWidget = mRendererWidget; QgsRasterRendererRegistryEntry rendererEntry; if ( QgsRasterRendererRegistry::instance()->rendererData( rendererName, rendererEntry ) ) { if ( rendererEntry.widgetCreateFunction ) //single band color data renderer e.g. has no widget { QgsDebugMsg( "renderer has widgetCreateFunction" ); // Current canvas extent (used to calc min/max) in layer CRS QgsRectangle myExtent = mMapCanvas->mapSettings().outputExtentToLayerExtent( mRasterLayer, mMapCanvas->extent() ); mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent ); mRendererWidget->setMapCanvas( mMapCanvas ); connect( mRendererWidget, SIGNAL( widgetChanged() ), this, SIGNAL( widgetChanged() ) ); stackedWidget->addWidget( mRendererWidget ); stackedWidget->setCurrentWidget( mRendererWidget ); if ( oldWidget ) { //compare used bands in new and old renderer and reset transparency dialog if different QgsRasterRenderer* oldRenderer = oldWidget->renderer(); QgsRasterRenderer* newRenderer = mRendererWidget->renderer(); QList<int> oldBands = oldRenderer->usesBands(); QList<int> newBands = newRenderer->usesBands(); // if ( oldBands != newBands ) // { // populateTransparencyTable( newRenderer ); // } delete oldRenderer; delete newRenderer; } } } if ( mRendererWidget != oldWidget ) delete oldWidget; int widgetIndex = cboRenderers->findData( rendererName ); if ( widgetIndex != -1 ) { whileBlocking( cboRenderers )->setCurrentIndex( widgetIndex ); } }
void QgsRasterTransparencyWidget::setTransparencyCell( int row, int column, double value ) { QgsDebugMsg( QStringLiteral( "value = %1" ).arg( value, 0, 'g', 17 ) ); QgsRasterDataProvider *provider = mRasterLayer->dataProvider(); if ( !provider ) return; QgsRasterRenderer *renderer = mRasterLayer->renderer(); if ( !renderer ) return; int nBands = renderer->usesBands().size(); QLineEdit *lineEdit = new QLineEdit(); lineEdit->setFrame( false ); // frame looks bad in table // Without margins row selection is not displayed (important for delete row) lineEdit->setContentsMargins( 1, 1, 1, 1 ); if ( column == tableTransparency->columnCount() - 1 ) { // transparency // Who needs transparency as floating point? lineEdit->setValidator( new QIntValidator( nullptr ) ); lineEdit->setText( QString::number( static_cast<int>( value ) ) ); } else { // value QString valueString; switch ( provider->sourceDataType( 1 ) ) { case Qgis::Float32: case Qgis::Float64: lineEdit->setValidator( new QDoubleValidator( nullptr ) ); if ( !std::isnan( value ) ) { valueString = QgsRasterBlock::printValue( value ); } break; default: lineEdit->setValidator( new QIntValidator( nullptr ) ); if ( !std::isnan( value ) ) { valueString = QString::number( static_cast<int>( value ) ); } break; } lineEdit->setText( valueString ); connect( lineEdit, &QLineEdit::textEdited, this, &QgsPanelWidget::widgetChanged ); } tableTransparency->setCellWidget( row, column, lineEdit ); adjustTransparencyCellWidth( row, column ); if ( nBands == 1 && ( column == 0 || column == 1 ) ) { connect( lineEdit, &QLineEdit::textEdited, this, &QgsRasterTransparencyWidget::transparencyCellTextEdited ); } tableTransparency->resizeColumnsToContents(); emit widgetChanged(); }
void QgsRasterTransparencyWidget::pixelSelected( const QgsPointXY &canvasPoint ) { QgsRasterRenderer *renderer = mRasterLayer->renderer(); if ( !renderer ) { return; } //Get the pixel values and add a new entry to the transparency table if ( mMapCanvas && mPixelSelectorTool ) { mMapCanvas->unsetMapTool( mPixelSelectorTool ); const QgsMapSettings &ms = mMapCanvas->mapSettings(); QgsPointXY myPoint = ms.mapToLayerCoordinates( mRasterLayer, canvasPoint ); QgsRectangle myExtent = ms.mapToLayerCoordinates( mRasterLayer, mMapCanvas->extent() ); double mapUnitsPerPixel = mMapCanvas->mapUnitsPerPixel(); int myWidth = mMapCanvas->extent().width() / mapUnitsPerPixel; int myHeight = mMapCanvas->extent().height() / mapUnitsPerPixel; QMap<int, QVariant> myPixelMap = mRasterLayer->dataProvider()->identify( myPoint, QgsRaster::IdentifyFormatValue, myExtent, myWidth, myHeight ).results(); QList<int> bands = renderer->usesBands(); QList<double> values; for ( int i = 0; i < bands.size(); ++i ) { int bandNo = bands.value( i ); if ( myPixelMap.count( bandNo ) == 1 ) { if ( myPixelMap.value( bandNo ).isNull() ) { return; // Don't add nodata, transparent anyway } double value = myPixelMap.value( bandNo ).toDouble(); QgsDebugMsg( QStringLiteral( "value = %1" ).arg( value, 0, 'g', 17 ) ); values.append( value ); } } if ( bands.size() == 1 ) { // Set 'to' values.insert( 1, values.value( 0 ) ); } tableTransparency->insertRow( tableTransparency->rowCount() ); for ( int i = 0; i < values.size(); i++ ) { setTransparencyCell( tableTransparency->rowCount() - 1, i, values.value( i ) ); } setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 ); } tableTransparency->resizeColumnsToContents(); tableTransparency->resizeRowsToContents(); }
void QgsRasterTransparencyWidget::transparencyCellTextEdited( const QString &text ) { Q_UNUSED( text ) QgsDebugMsg( QStringLiteral( "text = %1" ).arg( text ) ); QgsRasterRenderer *renderer = mRasterLayer->renderer(); if ( !renderer ) { return; } int nBands = renderer->usesBands().size(); if ( nBands == 1 ) { QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( sender() ); if ( !lineEdit ) return; int row = -1; int column = -1; for ( int r = 0; r < tableTransparency->rowCount(); r++ ) { for ( int c = 0; c < tableTransparency->columnCount(); c++ ) { if ( tableTransparency->cellWidget( r, c ) == sender() ) { row = r; column = c; break; } } if ( row != -1 ) break; } QgsDebugMsg( QStringLiteral( "row = %1 column =%2" ).arg( row ).arg( column ) ); if ( column == 0 ) { QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( tableTransparency->cellWidget( row, 1 ) ); if ( !toLineEdit ) return; bool toChanged = mTransparencyToEdited.value( row ); QgsDebugMsg( QStringLiteral( "toChanged = %1" ).arg( toChanged ) ); if ( !toChanged ) { toLineEdit->setText( lineEdit->text() ); } } else if ( column == 1 ) { setTransparencyToEdited( row ); } } emit widgetChanged(); }
void QgsRasterTransparencyWidget::pbnDefaultValues_clicked() { QgsRasterRenderer *r = mRasterLayer->renderer(); if ( !r ) { return; } int nBands = r->usesBands().size(); setupTransparencyTable( nBands ); tableTransparency->resizeColumnsToContents(); // works only with values tableTransparency->resizeRowsToContents(); }
void QgsRasterTransparencyWidget::pbnAddValuesManually_clicked() { QgsRasterRenderer *renderer = mRasterLayer->renderer(); if ( !renderer ) { return; } tableTransparency->insertRow( tableTransparency->rowCount() ); int n = renderer->usesBands().size(); if ( n == 1 ) n++; for ( int i = 0; i < n; i++ ) { setTransparencyCell( tableTransparency->rowCount() - 1, i, std::numeric_limits<double>::quiet_NaN() ); } setTransparencyCell( tableTransparency->rowCount() - 1, n, 100 ); tableTransparency->resizeColumnsToContents(); tableTransparency->resizeRowsToContents(); }
QgsRasterRenderer* QgsRasterRendererRegistry::defaultRendererForDrawingStyle( QgsRaster::DrawingStyle theDrawingStyle, QgsRasterDataProvider* provider ) const { if ( !provider || provider->bandCount() < 1 ) { return nullptr; } QgsRasterRenderer* renderer = nullptr; switch ( theDrawingStyle ) { case QgsRaster::PalettedColor: { int grayBand = 1; //reasonable default QList<QgsColorRampShader::ColorRampItem> colorEntries = provider->colorTable( grayBand ); //go through list and take maximum value (it could be that entries don't start at 0 or indices are not contiguous) int colorArraySize = 0; QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = colorEntries.constBegin(); for ( ; colorIt != colorEntries.constEnd(); ++colorIt ) { if ( colorIt->value > colorArraySize ) { colorArraySize = ( int )( colorIt->value ); } } colorArraySize += 1; //usually starts at 0 QColor* colorArray = new QColor[ colorArraySize ]; colorIt = colorEntries.constBegin(); QVector<QString> labels; for ( ; colorIt != colorEntries.constEnd(); ++colorIt ) { int idx = ( int )( colorIt->value ); colorArray[idx] = colorIt->color; if ( !colorIt->label.isEmpty() ) { if ( labels.size() <= idx ) labels.resize( idx + 1 ); labels[idx] = colorIt->label; } } renderer = new QgsPalettedRasterRenderer( provider, grayBand, colorArray, colorArraySize, labels ); } break; case QgsRaster::MultiBandSingleBandGray: case QgsRaster::SingleBandGray: { int grayBand = 1; renderer = new QgsSingleBandGrayRenderer( provider, grayBand ); QgsContrastEnhancement* ce = new QgsContrastEnhancement(( QGis::DataType )( provider->dataType( grayBand ) ) ); // Default contrast enhancement is set from QgsRasterLayer, it has already setContrastEnhancementAlgorithm(). Default enhancement must only be set if default style was not loaded (to avoid stats calculation). (( QgsSingleBandGrayRenderer* )renderer )->setContrastEnhancement( ce ); break; } case QgsRaster::SingleBandPseudoColor: { int bandNo = 1; double minValue = 0; double maxValue = 0; // TODO: avoid calculating statistics if not necessary (default style loaded) minMaxValuesForBand( bandNo, provider, minValue, maxValue ); QgsRasterShader* shader = new QgsRasterShader( minValue, maxValue ); renderer = new QgsSingleBandPseudoColorRenderer( provider, bandNo, shader ); break; } case QgsRaster::MultiBandColor: { QSettings s; int redBand = s.value( "/Raster/defaultRedBand", 1 ).toInt(); if ( redBand < 0 || redBand > provider->bandCount() ) { redBand = -1; } int greenBand = s.value( "/Raster/defaultGreenBand", 2 ).toInt(); if ( greenBand < 0 || greenBand > provider->bandCount() ) { greenBand = -1; } int blueBand = s.value( "/Raster/defaultBlueBand", 3 ).toInt(); if ( blueBand < 0 || blueBand > provider->bandCount() ) { blueBand = -1; } renderer = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand ); break; } case QgsRaster::SingleBandColorDataStyle: { renderer = new QgsSingleBandColorDataRenderer( provider, 1 ); break; } default: return nullptr; } QgsRasterTransparency* tr = new QgsRasterTransparency(); //renderer takes ownership int bandCount = renderer->usesBands().size(); if ( bandCount == 1 ) { QList<QgsRasterTransparency::TransparentSingleValuePixel> transparentSingleList; tr->setTransparentSingleValuePixelList( transparentSingleList ); } else if ( bandCount == 3 ) { QList<QgsRasterTransparency::TransparentThreeValuePixel> transparentThreeValueList; tr->setTransparentThreeValuePixelList( transparentThreeValueList ); } renderer->setRasterTransparency( tr ); return renderer; }
void QgsRendererRasterPropertiesWidget::setRendererWidget( const QString &rendererName ) { QgsDebugMsg( "rendererName = " + rendererName ); QgsRasterRendererWidget *oldWidget = mRendererWidget; QgsRasterRenderer *oldRenderer = mRasterLayer->renderer(); int alphaBand = -1; double opacity = 1; if ( oldRenderer ) { // Retain alpha band and opacity when switching renderer alphaBand = oldRenderer->alphaBand(); opacity = oldRenderer->opacity(); } QgsRasterRendererRegistryEntry rendererEntry; if ( QgsApplication::rasterRendererRegistry()->rendererData( rendererName, rendererEntry ) ) { if ( rendererEntry.widgetCreateFunction ) // Single band color data renderer e.g. has no widget { QgsDebugMsg( QStringLiteral( "renderer has widgetCreateFunction" ) ); // Current canvas extent (used to calc min/max) in layer CRS QgsRectangle myExtent = mMapCanvas->mapSettings().outputExtentToLayerExtent( mRasterLayer, mMapCanvas->extent() ); if ( oldWidget ) { if ( rendererName == QLatin1String( "singlebandgray" ) ) { whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( QgsRaster::SingleBandGray, mRasterLayer->dataProvider() ) ); whileBlocking( mRasterLayer )->setDefaultContrastEnhancement(); } else if ( rendererName == QLatin1String( "multibandcolor" ) ) { whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( QgsRaster::MultiBandColor, mRasterLayer->dataProvider() ) ); whileBlocking( mRasterLayer )->setDefaultContrastEnhancement(); } } mRasterLayer->renderer()->setAlphaBand( alphaBand ); mRasterLayer->renderer()->setOpacity( opacity ); mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent ); mRendererWidget->setMapCanvas( mMapCanvas ); connect( mRendererWidget, &QgsRasterRendererWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); stackedWidget->addWidget( mRendererWidget ); stackedWidget->setCurrentWidget( mRendererWidget ); if ( oldWidget ) { // Compare used bands in new and old renderer and reset transparency dialog if different QgsRasterRenderer *oldRenderer = oldWidget->renderer(); QgsRasterRenderer *newRenderer = mRendererWidget->renderer(); #if 0 QList<int> oldBands = oldRenderer->usesBands(); QList<int> newBands = newRenderer->usesBands(); if ( oldBands != newBands ) { populateTransparencyTable( newRenderer ); } #endif delete oldRenderer; delete newRenderer; } } } if ( mRendererWidget != oldWidget ) delete oldWidget; int widgetIndex = cboRenderers->findData( rendererName ); if ( widgetIndex != -1 ) { whileBlocking( cboRenderers )->setCurrentIndex( widgetIndex ); } }
QgsRasterRenderer *QgsRasterRendererRegistry::defaultRendererForDrawingStyle( QgsRaster::DrawingStyle drawingStyle, QgsRasterDataProvider *provider ) const { if ( !provider || provider->bandCount() < 1 ) { return nullptr; } QgsRasterRenderer *renderer = nullptr; switch ( drawingStyle ) { case QgsRaster::PalettedColor: { int grayBand = 1; //reasonable default QgsPalettedRasterRenderer::ClassData classes = QgsPalettedRasterRenderer::colorTableToClassData( provider->colorTable( grayBand ) ); renderer = new QgsPalettedRasterRenderer( provider, grayBand, classes ); } break; case QgsRaster::MultiBandSingleBandGray: case QgsRaster::SingleBandGray: { int grayBand = 1; renderer = new QgsSingleBandGrayRenderer( provider, grayBand ); QgsContrastEnhancement *ce = new QgsContrastEnhancement( ( Qgis::DataType )( provider->dataType( grayBand ) ) ); // Default contrast enhancement is set from QgsRasterLayer, it has already setContrastEnhancementAlgorithm(). Default enhancement must only be set if default style was not loaded (to avoid stats calculation). ( ( QgsSingleBandGrayRenderer * )renderer )->setContrastEnhancement( ce ); break; } case QgsRaster::SingleBandPseudoColor: { int bandNo = 1; double minValue = 0; double maxValue = 0; // TODO: avoid calculating statistics if not necessary (default style loaded) minMaxValuesForBand( bandNo, provider, minValue, maxValue ); QgsRasterShader *shader = new QgsRasterShader( minValue, maxValue ); renderer = new QgsSingleBandPseudoColorRenderer( provider, bandNo, shader ); break; } case QgsRaster::MultiBandColor: { QgsSettings s; int redBand = s.value( QStringLiteral( "/Raster/defaultRedBand" ), 1 ).toInt(); if ( redBand < 0 || redBand > provider->bandCount() ) { redBand = -1; } int greenBand = s.value( QStringLiteral( "/Raster/defaultGreenBand" ), 2 ).toInt(); if ( greenBand < 0 || greenBand > provider->bandCount() ) { greenBand = -1; } int blueBand = s.value( QStringLiteral( "/Raster/defaultBlueBand" ), 3 ).toInt(); if ( blueBand < 0 || blueBand > provider->bandCount() ) { blueBand = -1; } renderer = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand ); break; } case QgsRaster::SingleBandColorDataStyle: { renderer = new QgsSingleBandColorDataRenderer( provider, 1 ); break; } default: return nullptr; } QgsRasterTransparency *tr = new QgsRasterTransparency(); //renderer takes ownership int bandCount = renderer->usesBands().size(); if ( bandCount == 1 ) { QList<QgsRasterTransparency::TransparentSingleValuePixel> transparentSingleList; tr->setTransparentSingleValuePixelList( transparentSingleList ); } else if ( bandCount == 3 ) { QList<QgsRasterTransparency::TransparentThreeValuePixel> transparentThreeValueList; tr->setTransparentThreeValuePixelList( transparentThreeValueList ); } renderer->setRasterTransparency( tr ); return renderer; }