QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsrasterlayerproperties.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrasterlayerproperties.cpp - description
3 -------------------
4 begin : 1/1/2004
5 copyright : (C) 2004 Tim Sutton
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include <limits>
19#include <typeinfo>
20
21#include "qgsgui.h"
22#include "qgsapplication.h"
25#include "qgslogger.h"
27#include "qgsmapcanvas.h"
30#include "qgsmaptoolemitpoint.h"
31#include "qgsmetadatawidget.h"
38#include "qgsproject.h"
43#include "qgsrasterlayer.h"
45#include "qgsrasterpyramid.h"
46#include "qgsrasterrange.h"
47#include "qgsrasterrenderer.h"
54#include "qgssettings.h"
56#include "qgsmaplayerlegend.h"
57#include "qgsfileutils.h"
58#include "qgswebview.h"
59#include "qgsvectorlayer.h"
60#include "qgsdoublevalidator.h"
62#include "qgsprojectutils.h"
66#include "qgsmaptip.h"
67#include "qgswebframe.h"
68#include "qgsexpressionfinder.h"
70#if WITH_QTWEBKIT
71#include <QWebElement>
72#endif
73#include "qgshelp.h"
74
75#include <QDesktopServices>
76#include <QTableWidgetItem>
77#include <QHeaderView>
78#include <QTextStream>
79#include <QFile>
80#include <QFileDialog>
81#include <QMessageBox>
82#include <QPainter>
83#include <QLinearGradient>
84#include <QPainterPath>
85#include <QPolygonF>
86#include <QColorDialog>
87#include <QList>
88#include <QMouseEvent>
89#include <QVector>
90#include <QUrl>
91#include <QMenu>
92#include <QScreen>
93#include <QRegularExpressionValidator>
94#include <QRegularExpression>
95
96QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl )
97 : QgsLayerPropertiesDialog( lyr, canvas, QStringLiteral( "RasterLayerProperties" ), parent, fl )
98 // Constant that signals property not used.
99 , TRSTRING_NOT_SET( tr( "Not Set" ) )
100 , mDefaultStandardDeviation( 0 )
101 , mDefaultRedBand( 0 )
102 , mDefaultGreenBand( 0 )
103 , mDefaultBlueBand( 0 )
104 , mRasterLayer( qobject_cast<QgsRasterLayer *>( lyr ) )
105 , mGradientHeight( 0.0 )
106 , mGradientWidth( 0.0 )
107 , mMetadataFilled( false )
108{
109 mGrayMinimumMaximumEstimated = true;
110 mRGBMinimumMaximumEstimated = true;
111
112 setupUi( this );
113
114 mMetadataViewer = new QgsWebView( this );
115 mOptsPage_Information->layout()->addWidget( mMetadataViewer );
116
117 mRasterTransparencyWidget = new QgsRasterTransparencyWidget( mRasterLayer, canvas, this );
118
119 transparencyScrollArea->setWidget( mRasterTransparencyWidget );
120
121 connect( buttonBuildPyramids, &QPushButton::clicked, this, &QgsRasterLayerProperties::buttonBuildPyramids_clicked );
122 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsRasterLayerProperties::mCrsSelector_crsChanged );
123 connect( mRenderTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged );
124 connect( mResetColorRenderingBtn, &QToolButton::clicked, this, &QgsRasterLayerProperties::mResetColorRenderingBtn_clicked );
125 connect( buttonRemoveMetadataUrl, &QPushButton::clicked, this, &QgsRasterLayerProperties::removeSelectedMetadataUrl );
126 connect( buttonAddMetadataUrl, &QPushButton::clicked, this, &QgsRasterLayerProperties::addMetadataUrl );
127 // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
128 // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
129 // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
130 initOptionsBase( false );
131 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerProperties::showHelp );
132
133 mSourceGroupBox->hide();
134
135 mBtnStyle = new QPushButton( tr( "Style" ) );
136 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
137
138 connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsRasterLayerProperties::syncToLayer );
139
140 connect( this, &QDialog::accepted, this, &QgsRasterLayerProperties::apply );
141 connect( this, &QDialog::rejected, this, &QgsRasterLayerProperties::rollback );
142
143 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsRasterLayerProperties::apply );
144
145 cbxPyramidsFormat->addItem( tr( "External" ), QVariant::fromValue( Qgis::RasterPyramidFormat::GeoTiff ) );
146 cbxPyramidsFormat->addItem( tr( "Internal (if possible)" ), QVariant::fromValue( Qgis::RasterPyramidFormat::Internal ) );
147 cbxPyramidsFormat->addItem( tr( "External (Erdas Imagine)" ), QVariant::fromValue( Qgis::RasterPyramidFormat::Erdas ) );
148
149 // brightness/contrast controls
150 connect( mSliderBrightness, &QAbstractSlider::valueChanged, mBrightnessSpinBox, &QSpinBox::setValue );
151 connect( mBrightnessSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mSliderBrightness, &QAbstractSlider::setValue );
152 mBrightnessSpinBox->setClearValue( 0 );
153
154 connect( mSliderContrast, &QAbstractSlider::valueChanged, mContrastSpinBox, &QSpinBox::setValue );
155 connect( mContrastSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mSliderContrast, &QAbstractSlider::setValue );
156 mContrastSpinBox->setClearValue( 0 );
157
158 // gamma correction controls
159 connect( mSliderGamma, &QAbstractSlider::valueChanged, this, &QgsRasterLayerProperties::updateGammaSpinBox );
160 connect( mGammaSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsRasterLayerProperties::updateGammaSlider );
161 mGammaSpinBox->setClearValue( 1.0 );
162
163 // Connect saturation slider and spin box
164 connect( sliderSaturation, &QAbstractSlider::valueChanged, spinBoxSaturation, &QSpinBox::setValue );
165 connect( spinBoxSaturation, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), sliderSaturation, &QAbstractSlider::setValue );
166 spinBoxSaturation->setClearValue( 0 );
167
168 // Connect colorize strength slider and spin box
169 connect( sliderColorizeStrength, &QAbstractSlider::valueChanged, spinColorizeStrength, &QSpinBox::setValue );
170 connect( spinColorizeStrength, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), sliderColorizeStrength, &QAbstractSlider::setValue );
171 spinColorizeStrength->setClearValue( 100 );
172
173 // enable or disable saturation slider and spin box depending on grayscale combo choice
174 connect( comboGrayscale, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::toggleSaturationControls );
175
176 // enable or disable colorize colorbutton with colorize checkbox
177 connect( mColorizeCheck, &QAbstractButton::toggled, this, &QgsRasterLayerProperties::toggleColorizeControls );
178
179 // enable or disable Build Pyramids button depending on selection in pyramid list
180 connect( lbxPyramidResolutions, &QListWidget::itemSelectionChanged, this, &QgsRasterLayerProperties::toggleBuildPyramidsButton );
181
182 mRefreshSettingsWidget->setLayer( mRasterLayer );
183
184 // set up the scale based layer visibility stuff....
185 mScaleRangeWidget->setMapCanvas( mCanvas );
186 chkUseScaleDependentRendering->setChecked( lyr->hasScaleBasedVisibility() );
187 mScaleRangeWidget->setScaleRange( lyr->minimumScale(), lyr->maximumScale() );
188
189 // Setup the layer metadata URL
190 tableViewMetadataUrl->setSelectionMode( QAbstractItemView::SingleSelection );
191 tableViewMetadataUrl->setSelectionBehavior( QAbstractItemView::SelectRows );
192 tableViewMetadataUrl->horizontalHeader()->setStretchLastSection( true );
193 tableViewMetadataUrl->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
194
195 mMetadataUrlModel = new QStandardItemModel( tableViewMetadataUrl );
196 mMetadataUrlModel->clear();
197 mMetadataUrlModel->setColumnCount( 3 );
198 QStringList metadataUrlHeaders;
199 metadataUrlHeaders << tr( "URL" ) << tr( "Type" ) << tr( "Format" );
200 mMetadataUrlModel->setHorizontalHeaderLabels( metadataUrlHeaders );
201 tableViewMetadataUrl->setModel( mMetadataUrlModel );
202 tableViewMetadataUrl->setItemDelegate( new MetadataUrlItemDelegate( this ) );
203
204 // build GUI components
205 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
206 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
207
208 mRasterTransparencyWidget->pbnAddValuesManually->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyAdd.svg" ) ) );
209 mRasterTransparencyWidget->pbnAddValuesFromDisplay->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionContextHelp.png" ) ) );
210 mRasterTransparencyWidget->pbnRemoveSelectedRow->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyRemove.svg" ) ) );
211 mRasterTransparencyWidget->pbnDefaultValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionOpenTable.svg" ) ) );
212 mRasterTransparencyWidget->pbnImportTransparentPixelValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileOpen.svg" ) ) );
213 mRasterTransparencyWidget->pbnExportTransparentPixelValues->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileSave.svg" ) ) );
214 initMapTipPreview();
215
216 if ( !mRasterLayer )
217 {
218 return;
219 }
220
221 connect( mEnableMapTips, &QAbstractButton::toggled, mHtmlMapTipGroupBox, &QWidget::setEnabled );
222 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
223
224 updateRasterAttributeTableOptionsPage();
225
226 connect( mRasterLayer, &QgsRasterLayer::rendererChanged, this, &QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage );
227
228 connect( mCreateRasterAttributeTableButton, &QPushButton::clicked, this, [ = ]
229 {
230 if ( mRasterLayer->canCreateRasterAttributeTable() )
231 {
232 // Create the attribute table from the renderer
233 QgsCreateRasterAttributeTableDialog dlg { mRasterLayer };
234 dlg.setOpenWhenDoneVisible( false );
235 if ( dlg.exec() == QDialog::Accepted )
236 {
237 updateRasterAttributeTableOptionsPage();
238 }
239 }
240 } );
241
242 connect( mLoadRasterAttributeTableFromFileButton, &QPushButton::clicked, this, [ = ]
243 {
244 // Load the attribute table from a VAT.DBF file
245 QgsLoadRasterAttributeTableDialog dlg { mRasterLayer };
246 dlg.setOpenWhenDoneVisible( false );
247 if ( dlg.exec() == QDialog::Accepted )
248 {
249 updateRasterAttributeTableOptionsPage();
250 }
251 } );
252
253 mBackupCrs = mRasterLayer->crs();
254
255 // Handles window modality raising canvas
256 if ( mCanvas && mRasterTransparencyWidget->pixelSelectorTool() )
257 {
258
259 connect( mRasterTransparencyWidget->pixelSelectorTool(), &QgsMapToolEmitPoint::deactivated, this, [ = ]
260 {
261 hide();
262 setModal( true );
263 show();
264 raise();
265 activateWindow();
266 } );
267
268 connect( mRasterTransparencyWidget->pbnAddValuesFromDisplay, &QPushButton::clicked, this, [ = ]
269 {
270 hide();
271 setModal( false );
272
273 // Transfer focus to the canvas to use the selector tool
274 mCanvas->window()->raise();
275 mCanvas->window()->activateWindow();
276 mCanvas->window()->setFocus();
277 } );
278 }
279
283
284 if ( mCanvas )
285 {
286 mContext << QgsExpressionContextUtils::mapSettingsScope( mCanvas->mapSettings() );
287 // Initialize with layer center
288 mContext << QgsExpressionContextUtils::mapLayerPositionScope( mRasterLayer->extent().center() );
289 }
290
291 mContext << QgsExpressionContextUtils::layerScope( mRasterLayer );
292
293 connect( mInsertExpressionButton, &QAbstractButton::clicked, this, [ = ]
294 {
295 // Get the linear indexes if the start and end of the selection
296 int selectionStart = mMapTipWidget->selectionStart();
297 int selectionEnd = mMapTipWidget->selectionEnd();
298 QString expression = QgsExpressionFinder::findAndSelectActiveExpression( mMapTipWidget );
299 QgsExpressionBuilderDialog exprDlg( nullptr, expression, this, QStringLiteral( "generic" ), mContext );
300
301 exprDlg.setWindowTitle( tr( "Insert Expression" ) );
302 if ( exprDlg.exec() == QDialog::Accepted && !exprDlg.expressionText().trimmed().isEmpty() )
303 mMapTipWidget->insertText( "[%" + exprDlg.expressionText().trimmed() + "%]" );
304 else // Restore the selection
305 mMapTipWidget->setLinearSelection( selectionStart, selectionEnd );
306 } );
307
308 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
309
310 // Only do pyramids if dealing directly with GDAL.
311 if ( provider && provider->capabilities() & QgsRasterDataProvider::BuildPyramids )
312 {
313 // initialize resampling methods
314 cboResamplingMethod->clear();
315
316 const auto constProviderType = QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() );
317 for ( const QPair<QString, QString> &method : std::as_const( constProviderType ) )
318 {
319 cboResamplingMethod->addItem( method.second, method.first );
320 }
321
322 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
323 QString prefix = provider->name() + "/driverOptions/_pyramids/";
324 QgsSettings mySettings;
325 QString defaultMethod = mySettings.value( prefix + "resampling", "AVERAGE" ).toString();
326 int idx = cboResamplingMethod->findData( defaultMethod );
327 if ( idx >= 0 )
328 cboResamplingMethod->setCurrentIndex( idx );
329
330
331 // build pyramid list
332 const QList< QgsRasterPyramid > myPyramidList = provider->buildPyramidList();
333
334 for ( const QgsRasterPyramid &pyramid : myPyramidList )
335 {
336 if ( pyramid.getExists() )
337 {
338 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
339 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
340 QString::number( pyramid.getYDim() ) ) );
341 }
342 else
343 {
344 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
345 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
346 QString::number( pyramid.getYDim() ) ) );
347 }
348 }
349 }
350 else
351 {
352 // disable Pyramids tab completely
353 mOptsPage_Pyramids->setEnabled( false );
354 }
355
356 // We can calculate histogram for all data sources but estimated only if
357 // size is unknown - could also be enabled if well supported (estimated histogram
358 // and let user know that it is estimated)
359 if ( !provider || !( provider->capabilities() & QgsRasterDataProvider::Size ) )
360 {
361 // disable Histogram tab completely
362 mOptsPage_Histogram->setEnabled( false );
363 }
364
365 QVBoxLayout *layout = new QVBoxLayout( metadataFrame );
366 layout->setContentsMargins( 0, 0, 0, 0 );
367 mMetadataWidget = new QgsMetadataWidget( this, mRasterLayer );
368 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
369 mMetadataWidget->setMapCanvas( mCanvas );
370 layout->addWidget( mMetadataWidget );
371 metadataFrame->setLayout( layout );
372
373 QVBoxLayout *temporalLayout = new QVBoxLayout( temporalFrame );
374 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
375 mTemporalWidget = new QgsRasterLayerTemporalPropertiesWidget( this, mRasterLayer );
376 temporalLayout->addWidget( mTemporalWidget );
377
378 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().toWkt( Qgis::CrsWktVariant::Preferred ), 2 );
379 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().userFriendlyIdentifier(), 2 );
380 mCrsSelector->setCrs( mRasterLayer->crs() );
381
382 // Set text for pyramid info box
383 QString pyramidFormat( QStringLiteral( "<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
384 QString pyramidHeader = tr( "Description" );
385 QString pyramidSentence1 = tr( "Large resolution raster layers can slow navigation in QGIS." );
386 QString pyramidSentence2 = tr( "By creating lower resolution copies of the data (pyramids) performance can be considerably improved as QGIS selects the most suitable resolution to use depending on the level of zoom." );
387 QString pyramidSentence3 = tr( "You must have write access in the directory where the original data is stored to build pyramids." );
388 QString pyramidSentence4 = tr( "Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
389 QString pyramidSentence5 = tr( "Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
390
391 tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader,
392 pyramidSentence1,
393 pyramidSentence2,
394 pyramidSentence3,
395 pyramidSentence4,
396 pyramidSentence5 ) );
397
398 //resampling
399 mResamplingGroupBox->setSaveCheckedState( true );
400 mResamplingUtils.initWidgets( mRasterLayer, mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox, mMaximumOversamplingSpinBox, mCbEarlyResampling );
401 mResamplingUtils.refreshWidgetsFromLayer();
402
403 const QgsRasterRenderer *renderer = mRasterLayer->renderer();
404
405 btnColorizeColor->setColorDialogTitle( tr( "Select Color" ) );
406 btnColorizeColor->setContext( QStringLiteral( "symbology" ) );
407
408 // Hue and saturation color control
409 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
410 //set hue and saturation controls to current values
411 if ( hueSaturationFilter )
412 {
413 sliderSaturation->setValue( hueSaturationFilter->saturation() );
414 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
415
416 // Set initial state of saturation controls based on grayscale mode choice
417 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
418
419 // Set initial state of colorize controls
420 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
421 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
422 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
423 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
424 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
425 }
426
427 //blend mode
428 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mRasterLayer ) );
429 mBlendModeComboBox->setBlendMode( mRasterLayer->blendMode() );
430
431 //transparency band
432 if ( provider )
433 {
434 mRasterTransparencyWidget->cboxTransparencyBand->setShowNotSetOption( true, tr( "None" ) );
435 mRasterTransparencyWidget->cboxTransparencyBand->setLayer( mRasterLayer );
436
437// Alpha band is set in sync()
438#if 0
439 if ( renderer )
440 {
441 QgsDebugMsgLevel( QStringLiteral( "alphaBand = %1" ).arg( renderer->alphaBand() ), 2 );
442 if ( renderer->alphaBand() > 0 )
443 {
444 cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->alphaBand() ) );
445 }
446 }
447#endif
448 }
449
450 // create histogram widget
451 mHistogramWidget = nullptr;
452 if ( mOptsPage_Histogram->isEnabled() )
453 {
454 mHistogramWidget = new QgsRasterHistogramWidget( mRasterLayer, mOptsPage_Histogram );
455 mHistogramStackedWidget->addWidget( mHistogramWidget );
456 }
457
458 //insert renderer widgets into registry
465
466 //fill available renderers into combo box
468 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
469 const auto constRenderersList = QgsApplication::rasterRendererRegistry()->renderersList();
470 for ( const QString &name : constRenderersList )
471 {
472 if ( QgsApplication::rasterRendererRegistry()->rendererData( name, entry ) )
473 {
474 if ( ( mRasterLayer->rasterType() != Qgis::RasterLayerType::SingleBandColorData && entry.name != QLatin1String( "singlebandcolordata" ) ) ||
475 ( mRasterLayer->rasterType() == Qgis::RasterLayerType::SingleBandColorData && entry.name == QLatin1String( "singlebandcolordata" ) ) )
476 {
477 mRenderTypeComboBox->addItem( entry.visibleName, entry.name );
478 }
479 }
480 }
481 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
482
483 int widgetIndex = 0;
484 if ( renderer )
485 {
486 QString rendererType = renderer->type();
487 widgetIndex = mRenderTypeComboBox->findData( rendererType );
488 if ( widgetIndex != -1 )
489 {
490 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
491 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
492 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
493 }
494
495 if ( rendererType == QLatin1String( "singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
496 {
497 // no band rendering options for singlebandcolordata, so minimize group box
498 QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
499 sizep.setVerticalStretch( 0 );
500 sizep.setVerticalPolicy( QSizePolicy::Maximum );
501 mBandRenderingGrpBx->setSizePolicy( sizep );
502 mBandRenderingGrpBx->updateGeometry();
503 }
504
505 if ( mRasterLayer->providerType() != QLatin1String( "wms" ) )
506 {
507 mWMSPrintGroupBox->hide();
508 mPublishDataSourceUrlCheckBox->hide();
509 mBackgroundLayerCheckBox->hide();
510 }
511 }
512
513#ifdef WITH_QTWEBKIT
514 // Setup information tab
515
516 const int horizontalDpi = logicalDpiX();
517
518 // Adjust zoom: text is ok, but HTML seems rather big at least on Linux/KDE
519 if ( horizontalDpi > 96 )
520 {
521 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
522 }
523 mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
524 connect( mMetadataViewer->page(), &QWebPage::linkClicked, this, &QgsRasterLayerProperties::openUrl );
525 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
526 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
527
528#endif
529
530 initializeDataDefinedButton( mRasterTransparencyWidget->mOpacityDDBtn, QgsRasterPipe::Property::RendererOpacity );
531
532 mRenderTypeComboBox_currentIndexChanged( widgetIndex );
533
534 setMetadataWidget( mMetadataWidget, mOptsPage_Metadata );
535
536 QMenu *menuStyle = new QMenu( this );
537 menuStyle->addAction( tr( "Load Style…" ), this, &QgsRasterLayerProperties::loadStyle );
538 menuStyle->addAction( tr( "Save Style…" ), this, &QgsRasterLayerProperties::saveStyleAs );
539 menuStyle->addSeparator();
540 menuStyle->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveStyleAsDefault );
541 menuStyle->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultStyle );
542 mBtnStyle->setMenu( menuStyle );
543 connect( menuStyle, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
544
545 mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
546 QMenu *menuMetadata = new QMenu( this );
547 mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsRasterLayerProperties::loadMetadataFromFile );
548 mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsRasterLayerProperties::saveMetadataToFile );
549 menuMetadata->addSeparator();
550 menuMetadata->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveMetadataAsDefault );
551 menuMetadata->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultMetadata );
552 mBtnMetadata->setMenu( menuMetadata );
553 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
554
555 // update based on lyr's current state
556 sync();
557
558 QgsSettings settings;
559 // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often
560 // this will be read by restoreOptionsBaseUi()
561 if ( !settings.contains( QStringLiteral( "/Windows/RasterLayerProperties/tab" ) ) )
562 {
563 settings.setValue( QStringLiteral( "Windows/RasterLayerProperties/tab" ),
564 mOptStackedWidget->indexOf( mOptsPage_Style ) );
565 }
566
567 mResetColorRenderingBtn->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUndo.svg" ) ) );
568
569 optionsStackedWidget_CurrentChanged( mOptionsStackedWidget->currentIndex() );
570
571 //Add help page references
572 mOptsPage_Information->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#information-properties" ) );
573 mOptsPage_Source->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#source-properties" ) );
574 mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#symbology-properties" ) );
575 mOptsPage_Transparency->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#transparency-properties" ) );
576
577 if ( mOptsPage_Histogram )
578 mOptsPage_Histogram->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#histogram-properties" ) );
579
580 mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#rendering-properties" ) );
581 mOptsPage_Temporal->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#temporal-properties" ) );
582
583 if ( mOptsPage_Pyramids )
584 mOptsPage_Pyramids->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#pyramids-properties" ) );
585
586 if ( mOptsPage_Display )
587 mOptsPage_Display->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#display-properties" ) );
588
589 mOptsPage_Metadata->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#metadata-properties" ) );
590 mOptsPage_Legend->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#legend-properties" ) );
591 mOptsPage_Server->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#server-properties" ) );
592
593 initialize();
594}
595
597{
598 if ( !factory->supportsLayer( mRasterLayer ) || !factory->supportLayerPropertiesDialog() )
599 {
600 return;
601 }
602
603 QgsMapLayerConfigWidget *page = factory->createWidget( mRasterLayer, nullptr, false, this );
604 switch ( factory->parentPage() )
605 {
607 {
608 mConfigWidgets << page;
609
610 const QString beforePage = factory->layerPropertiesPagePositionHint();
611 if ( beforePage.isEmpty() )
612 addPage( factory->title(), factory->title(), factory->icon(), page );
613 else
614 insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage );
615 break;
616 }
617
619 mTemporalWidget->addWidget( page );
620 break;
621 }
622}
623
625{
626 return mContext;
627}
628
629void QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage( )
630{
631 if ( mRasterAttributeTableWidget )
632 {
633 mOptsPage_RasterAttributeTable->layout()->removeWidget( mRasterAttributeTableWidget );
634 mRasterAttributeTableWidget = nullptr;
635 }
636
637 // Setup raster attribute table
638 if ( mRasterLayer->attributeTableCount() > 0 )
639 {
640 mRasterAttributeTableWidget = new QgsRasterAttributeTableWidget( this, mRasterLayer );
641 mOptsPage_RasterAttributeTable->layout()->addWidget( mRasterAttributeTableWidget );
642 // When the renderer changes we need to sync the style options page
643 connect( mRasterAttributeTableWidget, &QgsRasterAttributeTableWidget::rendererChanged, this, &QgsRasterLayerProperties::syncToLayer );
644 mNoRasterAttributeTableWidget->hide();
645 }
646 else
647 {
648 mNoRasterAttributeTableWidget->show();
649 mCreateRasterAttributeTableButton->setEnabled( mRasterLayer->canCreateRasterAttributeTable() );
650 }
651}
652
653void QgsRasterLayerProperties::setRendererWidget( const QString &rendererName )
654{
655 QgsDebugMsgLevel( "rendererName = " + rendererName, 3 );
656 QgsRasterRendererWidget *oldWidget = mRendererWidget;
657 QgsRasterRenderer *oldRenderer = mRasterLayer->renderer();
658
659 int alphaBand = -1;
660 double opacity = 1;
661 QColor nodataColor;
662 const QList<int> oldBands = oldRenderer ? oldRenderer->usesBands() : QList<int>();
663 if ( oldRenderer )
664 {
665 // Retain alpha band and opacity when switching renderer
666 alphaBand = oldRenderer->alphaBand();
667 opacity = oldRenderer->opacity();
668 nodataColor = oldRenderer->nodataColor();
669 }
670
671 QgsRasterRendererRegistryEntry rendererEntry;
672 if ( QgsApplication::rasterRendererRegistry()->rendererData( rendererName, rendererEntry ) )
673 {
674 if ( rendererEntry.widgetCreateFunction ) //single band color data renderer e.g. has no widget
675 {
676 QgsDebugMsgLevel( QStringLiteral( "renderer has widgetCreateFunction" ), 3 );
677 // Current canvas extent (used to calc min/max) in layer CRS
679 if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->type() ) )
680 {
681 if ( rendererName == QLatin1String( "singlebandgray" ) )
682 {
683 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::SingleBandGray, mRasterLayer->dataProvider() ) );
684 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
685 }
686 else if ( rendererName == QLatin1String( "multibandcolor" ) )
687 {
688 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::MultiBandColor, mRasterLayer->dataProvider() ) );
689 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
690 }
691 }
692 mRasterLayer->renderer()->setAlphaBand( alphaBand );
693 mRasterLayer->renderer()->setOpacity( opacity );
694 mRasterLayer->renderer()->setNodataColor( nodataColor );
695 mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent );
696 mRendererWidget->setMapCanvas( mCanvas );
697 mRendererStackedWidget->addWidget( mRendererWidget );
698 if ( oldWidget )
699 {
700 //compare used bands in new and old renderer and reset transparency dialog if different
701 std::unique_ptr<QgsRasterRenderer> newRenderer;
702 newRenderer.reset( mRendererWidget->renderer() );
703 const QList<int> newBands = newRenderer->usesBands();
704 if ( oldBands != newBands )
705 {
706 mRasterTransparencyWidget->syncToLayer();
707 }
708 }
709 }
710 }
711
712 const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
713 if ( widgetIndex != -1 )
714 {
715 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
716 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
717 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
718 }
719
720 if ( mRendererWidget != oldWidget )
721 delete oldWidget;
722
723 if ( mHistogramWidget )
724 {
725 mHistogramWidget->setRendererWidget( rendererName, mRendererWidget );
726 }
727}
728
729void QgsRasterLayerProperties::sync()
730{
731 QgsSettings myQSettings;
732
733 if ( !mSourceWidget )
734 {
735 mSourceWidget = QgsGui::sourceWidgetProviderRegistry()->createWidget( mRasterLayer );
736 if ( mSourceWidget )
737 {
738 QHBoxLayout *layout = new QHBoxLayout();
739 layout->addWidget( mSourceWidget );
740 mSourceGroupBox->setLayout( layout );
741 if ( !mSourceWidget->groupTitle().isEmpty() )
742 mSourceGroupBox->setTitle( mSourceWidget->groupTitle() );
743 mSourceGroupBox->show();
744
745 connect( mSourceWidget, &QgsProviderSourceWidget::validChanged, this, [ = ]( bool isValid )
746 {
747 buttonBox->button( QDialogButtonBox::Apply )->setEnabled( isValid );
748 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
749 } );
750 }
751 }
752
753 if ( mSourceWidget )
754 {
755 mSourceWidget->setMapCanvas( mCanvas );
756 mSourceWidget->setSourceUri( mRasterLayer->source() );
757 }
758
759 const QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
760 if ( !provider )
761 return;
762
763 mRasterTransparencyWidget->syncToLayer();
764
765 if ( provider->dataType( 1 ) == Qgis::DataType::ARGB32
767 {
768 mRasterTransparencyWidget->gboxNoDataValue->setEnabled( false );
769 mRasterTransparencyWidget->gboxCustomTransparency->setEnabled( false );
770 mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
771 }
772
773 // TODO: Wouldn't it be better to just removeWidget() the tabs than delete them? [LS]
774 if ( !( provider->capabilities() & QgsRasterDataProvider::BuildPyramids ) )
775 {
776 if ( mOptsPage_Pyramids )
777 {
778 delete mOptsPage_Pyramids;
779 mOptsPage_Pyramids = nullptr;
780 }
781 }
782
783 if ( !( provider->capabilities() & QgsRasterDataProvider::Size ) )
784 {
785 if ( mOptsPage_Histogram )
786 {
787 delete mOptsPage_Histogram;
788 mOptsPage_Histogram = nullptr;
789 delete mHistogramWidget;
790 mHistogramWidget = nullptr;
791 }
792 }
793
794 QgsDebugMsgLevel( QStringLiteral( "populate transparency tab" ), 3 );
795
796 /*
797 * Style tab
798 */
799
800 //set brightness, contrast and gamma
801 QgsBrightnessContrastFilter *brightnessFilter = mRasterLayer->brightnessFilter();
802 if ( brightnessFilter )
803 {
804 mSliderBrightness->setValue( brightnessFilter->brightness() );
805 mSliderContrast->setValue( brightnessFilter->contrast() );
806 mGammaSpinBox->setValue( brightnessFilter->gamma() );
807 }
808
809 // Hue and saturation color control
810 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
811 //set hue and saturation controls to current values
812 if ( hueSaturationFilter )
813 {
814 sliderSaturation->setValue( hueSaturationFilter->saturation() );
815 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
816
817 // Set state of saturation controls based on grayscale mode choice
818 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
819
820 // Set state of colorize controls
821 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
822 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
823 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
824 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
825 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
826 }
827
828 mRefreshSettingsWidget->syncToLayer();
829
830 QgsDebugMsgLevel( QStringLiteral( "populate general tab" ), 3 );
831 /*
832 * General Tab
833 */
834
835 mLayerOrigNameLineEd->setText( mRasterLayer->name() );
836
837 QgsDebugMsgLevel( QStringLiteral( "populate metadata tab" ), 2 );
838 /*
839 * Metadata Tab
840 */
841 //populate the metadata tab's text browser widget with gdal metadata info
842 updateInformationContent();
843
844 // WMS Name as layer short name
845 mLayerShortNameLineEdit->setText( mRasterLayer->shortName() );
846 // WMS Name validator
847 QValidator *shortNameValidator = new QRegularExpressionValidator( QgsApplication::shortNameRegularExpression(), this );
848 mLayerShortNameLineEdit->setValidator( shortNameValidator );
849
850 //layer title and abstract
851 mLayerTitleLineEdit->setText( mRasterLayer->title() );
852 mLayerAbstractTextEdit->setPlainText( mRasterLayer->abstract() );
853 mLayerKeywordListLineEdit->setText( mRasterLayer->keywordList() );
854 mLayerDataUrlLineEdit->setText( mRasterLayer->dataUrl() );
855 mLayerDataUrlFormatComboBox->setCurrentIndex(
856 mLayerDataUrlFormatComboBox->findText(
857 mRasterLayer->dataUrlFormat()
858 )
859 );
860
861 //layer attribution
862 mLayerAttributionLineEdit->setText( mRasterLayer->attribution() );
863 mLayerAttributionUrlLineEdit->setText( mRasterLayer->attributionUrl() );
864
865 // layer metadata url
866 const QList<QgsMapLayerServerProperties::MetadataUrl> &metaUrls = mRasterLayer->serverProperties()->metadataUrls();
867 for ( const QgsMapLayerServerProperties::MetadataUrl &metaUrl : metaUrls )
868 {
869 const int row = mMetadataUrlModel->rowCount();
870 mMetadataUrlModel->setItem( row, 0, new QStandardItem( metaUrl.url ) );
871 mMetadataUrlModel->setItem( row, 1, new QStandardItem( metaUrl.type ) );
872 mMetadataUrlModel->setItem( row, 2, new QStandardItem( metaUrl.format ) );
873 }
874
875 // layer legend url
876 mLayerLegendUrlLineEdit->setText( mRasterLayer->legendUrl() );
877 mLayerLegendUrlFormatComboBox->setCurrentIndex( mLayerLegendUrlFormatComboBox->findText( mRasterLayer->legendUrlFormat() ) );
878
879 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
880 mMapTipWidget->setText( mRasterLayer->mapTipTemplate() );
881
882 //WMS print layer
883 QVariant wmsPrintLayer = mRasterLayer->customProperty( QStringLiteral( "WMSPrintLayer" ) );
884 if ( wmsPrintLayer.isValid() )
885 {
886 mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
887 }
888
889 QVariant wmsPublishDataSourceUrl = mRasterLayer->customProperty( QStringLiteral( "WMSPublishDataSourceUrl" ), false );
890 mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
891
892 QVariant wmsBackgroundLayer = mRasterLayer->customProperty( QStringLiteral( "WMSBackgroundLayer" ), false );
893 mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
894
895 mLegendPlaceholderWidget->setLastPathSettingsKey( QStringLiteral( "lastLegendPlaceholderDir" ) );
896 mLegendPlaceholderWidget->setSource( mRasterLayer->legendPlaceholderImage() );
897 mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
898
899 mTemporalWidget->syncToLayer();
900
901 mPropertyCollection = mRasterLayer->pipe()->dataDefinedProperties();
902 updateDataDefinedButtons();
903
904 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
905 {
906 page->syncToLayer( mRasterLayer );
907 }
908
909}
910
912{
913 if ( mSourceWidget )
914 {
915 const QString newSource = mSourceWidget->sourceUri();
916 if ( newSource != mRasterLayer->source() )
917 {
918 mRasterLayer->setDataSource( newSource, mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
919 }
920 }
921
922 // Do nothing on "bad" layers
923 if ( !mRasterLayer->isValid() )
924 return;
925
926 // apply all plugin dialogs
927 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
928 {
929 page->apply();
930 }
931
932
933 /*
934 * Legend Tab
935 */
936 mRasterLayer->setLegendPlaceholderImage( mLegendPlaceholderWidget->source() );
937 mLegendConfigEmbeddedWidget->applyToLayer();
938
939 QgsDebugMsgLevel( QStringLiteral( "apply processing symbology tab" ), 3 );
940 /*
941 * Symbology Tab
942 */
943
944 //set whether the layer histogram should be inverted
945 //mRasterLayer->setInvertHistogram( cboxInvertColorMap->isChecked() );
946
947 mRasterLayer->brightnessFilter()->setBrightness( mSliderBrightness->value() );
948 mRasterLayer->brightnessFilter()->setContrast( mSliderContrast->value() );
949 mRasterLayer->brightnessFilter()->setGamma( mGammaSpinBox->value() );
950
951 QgsDebugMsgLevel( QStringLiteral( "processing transparency tab" ), 3 );
952 /*
953 * Transparent Pixel Tab
954 */
955
956 //set NoDataValue
957 QgsRasterRangeList myNoDataRangeList;
958 if ( "" != mRasterTransparencyWidget->leNoDataValue->text() )
959 {
960 bool myDoubleOk = false;
961 double myNoDataValue = QgsDoubleValidator::toDouble( mRasterTransparencyWidget->leNoDataValue->text(), &myDoubleOk );
962 if ( myDoubleOk )
963 {
964 QgsRasterRange myNoDataRange( myNoDataValue, myNoDataValue );
965 myNoDataRangeList << myNoDataRange;
966 }
967 }
968 for ( int bandNo = 1; bandNo <= mRasterLayer->dataProvider()->bandCount(); bandNo++ )
969 {
970 mRasterLayer->dataProvider()->setUserNoDataValue( bandNo, myNoDataRangeList );
971 mRasterLayer->dataProvider()->setUseSourceNoDataValue( bandNo, mRasterTransparencyWidget->mSrcNoDataValueCheckBox->isChecked() );
972 }
973
974 //set renderer from widget
975 QgsRasterRendererWidget *rendererWidget = dynamic_cast<QgsRasterRendererWidget *>( mRendererStackedWidget->currentWidget() );
976 if ( rendererWidget )
977 {
978 rendererWidget->doComputations();
979
980 mRasterLayer->setRenderer( rendererWidget->renderer() );
981 }
982
983 mBackupCrs = mRasterLayer->crs();
984 mMetadataWidget->acceptMetadata();
985 mMetadataFilled = false;
986
987 //transparency settings
988 QgsRasterRenderer *rasterRenderer = mRasterLayer->renderer();
989 if ( rasterRenderer )
990 {
991 rasterRenderer->setAlphaBand( mRasterTransparencyWidget->cboxTransparencyBand->currentBand() );
992 rasterRenderer->setNodataColor( mRasterTransparencyWidget->mNodataColorButton->color() );
993
994 //Walk through each row in table and test value. If not valid set to 0.0 and continue building transparency list
995 QgsRasterTransparency *rasterTransparency = new QgsRasterTransparency();
996 if ( mRasterTransparencyWidget->tableTransparency->columnCount() == 4 )
997 {
998 QVector<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
999 for ( int myListRunner = 0; myListRunner < mRasterTransparencyWidget->tableTransparency->rowCount(); myListRunner++ )
1000 {
1001 const double red = transparencyCellValue( myListRunner, 0 );
1002 const double green = transparencyCellValue( myListRunner, 1 );
1003 const double blue = transparencyCellValue( myListRunner, 2 );
1004 const double opacity = 1.0 - transparencyCellValue( myListRunner, 3 ) / 100.0;
1005 myTransparentThreeValuePixelList.append(
1006 QgsRasterTransparency::TransparentThreeValuePixel( red, green, blue, opacity )
1007 );
1008 }
1009 rasterTransparency->setTransparentThreeValuePixelList( myTransparentThreeValuePixelList );
1010 }
1011 else if ( mRasterTransparencyWidget->tableTransparency->columnCount() == 3 )
1012 {
1013 QVector<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
1014 for ( int myListRunner = 0; myListRunner < mRasterTransparencyWidget->tableTransparency->rowCount(); myListRunner++ )
1015 {
1016 const double min = transparencyCellValue( myListRunner, 0 );
1017 const double max = transparencyCellValue( myListRunner, 1 );
1018 const double opacity = 1.0 - transparencyCellValue( myListRunner, 2 ) / 100.0;
1019
1020 myTransparentSingleValuePixelList.append(
1022 );
1023 }
1024 rasterTransparency->setTransparentSingleValuePixelList( myTransparentSingleValuePixelList );
1025 }
1026
1027 rasterRenderer->setRasterTransparency( rasterTransparency );
1028
1029 // Sync the layer styling widget
1030 mRasterLayer->emitStyleChanged();
1031
1032 //set global transparency
1033 rasterRenderer->setOpacity( mRasterTransparencyWidget->mOpacityWidget->opacity() );
1034 }
1035
1036 QgsDebugMsgLevel( QStringLiteral( "processing general tab" ), 3 );
1037 /*
1038 * General Tab
1039 */
1040 mRasterLayer->setName( mLayerOrigNameLineEd->text() );
1041
1042 // set up the scale based layer visibility stuff....
1043 mRasterLayer->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
1044 mRasterLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
1045 mRasterLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
1046
1047 mRefreshSettingsWidget->saveToLayer();
1048
1049 //update the legend pixmap
1050 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1051 // pixmapLegend->setScaledContents( true );
1052 // pixmapLegend->repaint();
1053
1054 mResamplingUtils.refreshLayerFromWidgets();
1055
1056 // Hue and saturation controls
1057 QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
1058 if ( hueSaturationFilter )
1059 {
1060 hueSaturationFilter->setSaturation( sliderSaturation->value() );
1061 hueSaturationFilter->setGrayscaleMode( ( QgsHueSaturationFilter::GrayscaleMode ) comboGrayscale->currentIndex() );
1062 hueSaturationFilter->setColorizeOn( mColorizeCheck->checkState() );
1063 hueSaturationFilter->setColorizeColor( btnColorizeColor->color() );
1064 hueSaturationFilter->setColorizeStrength( sliderColorizeStrength->value() );
1065 hueSaturationFilter->setInvertColors( mInvertColorsCheck->isChecked() );
1066 }
1067
1068 //set the blend mode for the layer
1069 mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );
1070
1071 // Update temporal properties
1072 mTemporalWidget->saveTemporalProperties();
1073
1074 mRasterLayer->setCrs( mCrsSelector->crs() );
1075
1076 if ( mRasterLayer->shortName() != mLayerShortNameLineEdit->text() )
1077 mMetadataFilled = false;
1078 mRasterLayer->setShortName( mLayerShortNameLineEdit->text() );
1079
1080 if ( mRasterLayer->title() != mLayerTitleLineEdit->text() )
1081 mMetadataFilled = false;
1082 mRasterLayer->setTitle( mLayerTitleLineEdit->text() );
1083
1084 if ( mRasterLayer->abstract() != mLayerAbstractTextEdit->toPlainText() )
1085 mMetadataFilled = false;
1086 mRasterLayer->setAbstract( mLayerAbstractTextEdit->toPlainText() );
1087
1088 if ( mRasterLayer->keywordList() != mLayerKeywordListLineEdit->text() )
1089 mMetadataFilled = false;
1090 mRasterLayer->setKeywordList( mLayerKeywordListLineEdit->text() );
1091
1092 if ( mRasterLayer->dataUrl() != mLayerDataUrlLineEdit->text() )
1093 mMetadataFilled = false;
1094 mRasterLayer->setDataUrl( mLayerDataUrlLineEdit->text() );
1095
1096 if ( mRasterLayer->dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
1097 mMetadataFilled = false;
1098 mRasterLayer->setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
1099
1100 //layer attribution
1101 if ( mRasterLayer->attribution() != mLayerAttributionLineEdit->text() )
1102 mMetadataFilled = false;
1103 mRasterLayer->setAttribution( mLayerAttributionLineEdit->text() );
1104
1105 if ( mRasterLayer->attributionUrl() != mLayerAttributionUrlLineEdit->text() )
1106 mMetadataFilled = false;
1107 mRasterLayer->setAttributionUrl( mLayerAttributionUrlLineEdit->text() );
1108
1109 // Metadata URL
1110 QList<QgsMapLayerServerProperties::MetadataUrl> metaUrls;
1111 for ( int row = 0; row < mMetadataUrlModel->rowCount() ; row++ )
1112 {
1114 metaUrl.url = mMetadataUrlModel->item( row, 0 )->text();
1115 metaUrl.type = mMetadataUrlModel->item( row, 1 )->text();
1116 metaUrl.format = mMetadataUrlModel->item( row, 2 )->text();
1117 metaUrls.append( metaUrl );
1118 mMetadataFilled = false;
1119 }
1120 mRasterLayer->serverProperties()->setMetadataUrls( metaUrls );
1121
1122 if ( mRasterLayer->legendUrl() != mLayerLegendUrlLineEdit->text() )
1123 mMetadataFilled = false;
1124 mRasterLayer->setLegendUrl( mLayerLegendUrlLineEdit->text() );
1125
1126 if ( mRasterLayer->legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
1127 mMetadataFilled = false;
1128 mRasterLayer->setLegendUrlFormat( mLayerLegendUrlFormatComboBox->currentText() );
1129
1130 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
1131 {
1132 mRasterLayer->setCustomProperty( QStringLiteral( "WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
1133 }
1134
1135 mRasterLayer->setCustomProperty( "WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
1136 mRasterLayer->setCustomProperty( "WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
1137
1138 mRasterLayer->pipe()->setDataDefinedProperties( mPropertyCollection );
1139
1140 mRasterLayer->setMapTipsEnabled( mEnableMapTips->isChecked() );
1141 mRasterLayer->setMapTipTemplate( mMapTipWidget->text() );
1142
1143 // Force a redraw of the legend
1144 mRasterLayer->setLegend( QgsMapLayerLegend::defaultRasterLegend( mRasterLayer ) );
1145
1146 //make sure the layer is redrawn
1147 mRasterLayer->triggerRepaint();
1148
1149 // notify the project we've made a change
1150 QgsProject::instance()->setDirty( true );
1151}
1152
1153void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
1154{
1155 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1156
1157 std::unique_ptr< QgsRasterBlockFeedback > feedback( new QgsRasterBlockFeedback() );
1158
1159 connect( feedback.get(), &QgsRasterBlockFeedback::progressChanged, mPyramidProgress, &QProgressBar::setValue );
1160 //
1161 // Go through the list marking any files that are selected in the listview
1162 // as true so that we can generate pyramids for them.
1163 //
1164 QList< QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
1165 for ( int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1166 {
1167 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1168 //mark to be pyramided
1169 myPyramidList[myCounterInt].setBuild( myItem->isSelected() || myPyramidList[myCounterInt].getExists() );
1170 }
1171
1172 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
1173 QString prefix = provider->name() + "/driverOptions/_pyramids/";
1174 QgsSettings mySettings;
1175 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1176 mySettings.setValue( prefix + "resampling", resamplingMethod );
1177
1178 //
1179 // Ask raster layer to build the pyramids
1180 //
1181
1182 // let the user know we're going to possibly be taking a while
1183 QApplication::setOverrideCursor( Qt::WaitCursor );
1184 QString res = provider->buildPyramids(
1185 myPyramidList,
1186 resamplingMethod,
1187 cbxPyramidsFormat->currentData().value< Qgis::RasterPyramidFormat >(),
1188 QStringList(),
1189 feedback.get() );
1190 QApplication::restoreOverrideCursor();
1191 mPyramidProgress->setValue( 0 );
1192 buttonBuildPyramids->setEnabled( false );
1193 if ( !res.isNull() )
1194 {
1195 if ( res == QLatin1String( "CANCELED" ) )
1196 {
1197 // user canceled
1198 }
1199 else if ( res == QLatin1String( "ERROR_WRITE_ACCESS" ) )
1200 {
1201 QMessageBox::warning( this, tr( "Building Pyramids" ),
1202 tr( "Write access denied. Adjust the file permissions and try again." ) );
1203 }
1204 else if ( res == QLatin1String( "ERROR_WRITE_FORMAT" ) )
1205 {
1206 QMessageBox::warning( this, tr( "Building Pyramids" ),
1207 tr( "The file was not writable. Some formats do not "
1208 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1209 }
1210 else if ( res == QLatin1String( "FAILED_NOT_SUPPORTED" ) )
1211 {
1212 QMessageBox::warning( this, tr( "Building Pyramids" ),
1213 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1214 }
1215 else if ( res == QLatin1String( "ERROR_JPEG_COMPRESSION" ) )
1216 {
1217 QMessageBox::warning( this, tr( "Building Pyramids" ),
1218 tr( "Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1219 }
1220 else if ( res == QLatin1String( "ERROR_VIRTUAL" ) )
1221 {
1222 QMessageBox::warning( this, tr( "Building Pyramids" ),
1223 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1224 }
1225
1226 }
1227
1228 //
1229 // repopulate the pyramids list
1230 //
1231 lbxPyramidResolutions->clear();
1232 // Need to rebuild list as some or all pyramids may have failed to build
1233 myPyramidList = provider->buildPyramidList();
1234 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
1235 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
1236
1237 for ( const QgsRasterPyramid &pyramid : std::as_const( myPyramidList ) )
1238 {
1239 if ( pyramid.getExists() )
1240 {
1241 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
1242 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1243 QString::number( pyramid.getYDim() ) ) );
1244 }
1245 else
1246 {
1247 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
1248 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1249 QString::number( pyramid.getYDim() ) ) );
1250 }
1251 }
1252 //update the legend pixmap
1253 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1254 // pixmapLegend->setScaledContents( true );
1255 // pixmapLegend->repaint();
1256
1257 //populate the metadata tab's text browser widget with gdal metadata info
1258 updateInformationContent();
1259}
1260
1261void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( int index )
1262{
1263 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
1264 {
1265 return;
1266 }
1267
1268 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1269 setRendererWidget( rendererName );
1270}
1271
1272void QgsRasterLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
1273{
1274 QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mCanvas, tr( "Select Transformation" ) );
1275 mRasterLayer->setCrs( crs );
1276 mMetadataWidget->crsChanged();
1277}
1278
1279void QgsRasterLayerProperties::setTransparencyCell( int row, int column, double value )
1280{
1281 QgsDebugMsgLevel( QStringLiteral( "value = %1" ).arg( value, 0, 'g', 17 ), 3 );
1282 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1283 if ( !provider ) return;
1284
1285 QgsRasterRenderer *renderer = mRendererWidget->renderer();
1286 if ( !renderer ) return;
1287 int nBands = renderer->usesBands().size();
1288
1289 QLineEdit *lineEdit = new QLineEdit();
1290 lineEdit->setFrame( false ); // frame looks bad in table
1291 // Without margins row selection is not displayed (important for delete row)
1292 lineEdit->setContentsMargins( 1, 1, 1, 1 );
1293
1294 if ( column == mRasterTransparencyWidget->tableTransparency->columnCount() - 1 )
1295 {
1296 // transparency
1297 // Who needs transparency as floating point?
1298 lineEdit->setValidator( new QIntValidator( nullptr ) );
1299 lineEdit->setText( QString::number( static_cast<int>( value ) ) );
1300 }
1301 else
1302 {
1303 // value
1304 QString valueString;
1305 switch ( provider->sourceDataType( 1 ) )
1306 {
1309 lineEdit->setValidator( new QgsDoubleValidator( nullptr ) );
1310 if ( !std::isnan( value ) )
1311 {
1312 double v = QgsRasterBlock::printValue( value ).toDouble();
1313 valueString = QLocale().toString( v, 'g' ) ;
1314 }
1315 break;
1316 default:
1317 lineEdit->setValidator( new QIntValidator( nullptr ) );
1318 if ( !std::isnan( value ) )
1319 {
1320 valueString = QLocale().toString( static_cast<int>( value ) );
1321 }
1322 break;
1323 }
1324 lineEdit->setText( valueString );
1325 }
1326 mRasterTransparencyWidget->tableTransparency->setCellWidget( row, column, lineEdit );
1327 adjustTransparencyCellWidth( row, column );
1328
1329 if ( nBands == 1 && ( column == 0 || column == 1 ) )
1330 {
1331 connect( lineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerProperties::transparencyCellTextEdited );
1332 }
1333 mRasterTransparencyWidget->tableTransparency->resizeColumnsToContents();
1334}
1335
1336void QgsRasterLayerProperties::setTransparencyCellValue( int row, int column, double value )
1337{
1338 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1339 if ( !lineEdit ) return;
1340 double v = QgsRasterBlock::printValue( value ).toDouble();
1341 lineEdit->setText( QLocale().toString( v, 'g' ) );
1342 lineEdit->adjustSize();
1343 adjustTransparencyCellWidth( row, column );
1344 mRasterTransparencyWidget->tableTransparency->resizeColumnsToContents();
1345}
1346
1347double QgsRasterLayerProperties::transparencyCellValue( int row, int column )
1348{
1349 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1350 if ( !lineEdit || lineEdit->text().isEmpty() )
1351 {
1352 return std::numeric_limits<double>::quiet_NaN();
1353 }
1354 return QLocale().toDouble( lineEdit->text() );
1355}
1356
1357void QgsRasterLayerProperties::adjustTransparencyCellWidth( int row, int column )
1358{
1359 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1360 if ( !lineEdit ) return;
1361
1362 int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
1363 width = std::max( width, mRasterTransparencyWidget->tableTransparency->columnWidth( column ) );
1364
1365 lineEdit->setFixedWidth( width );
1366}
1367
1368void QgsRasterLayerProperties::transparencyCellTextEdited( const QString &text )
1369{
1370 Q_UNUSED( text )
1371 QgsDebugMsgLevel( QStringLiteral( "text = %1" ).arg( text ), 3 );
1372 QgsRasterRenderer *renderer = mRendererWidget->renderer();
1373 if ( !renderer )
1374 {
1375 return;
1376 }
1377 int nBands = renderer->usesBands().size();
1378 if ( nBands == 1 )
1379 {
1380 QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
1381 if ( !lineEdit ) return;
1382 int row = -1;
1383 int column = -1;
1384 for ( int r = 0; r < mRasterTransparencyWidget->tableTransparency->rowCount(); r++ )
1385 {
1386 for ( int c = 0; c < mRasterTransparencyWidget->tableTransparency->columnCount(); c++ )
1387 {
1388 if ( mRasterTransparencyWidget->tableTransparency->cellWidget( r, c ) == sender() )
1389 {
1390 row = r;
1391 column = c;
1392 break;
1393 }
1394 }
1395 if ( row != -1 ) break;
1396 }
1397 QgsDebugMsgLevel( QStringLiteral( "row = %1 column =%2" ).arg( row ).arg( column ), 3 );
1398
1399 if ( column == 0 )
1400 {
1401 QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, 1 ) );
1402 if ( !toLineEdit ) return;
1403 bool toChanged = mTransparencyToEdited.value( row );
1404 QgsDebugMsgLevel( QStringLiteral( "toChanged = %1" ).arg( toChanged ), 3 );
1405 if ( !toChanged )
1406 {
1407 toLineEdit->setText( lineEdit->text() );
1408 }
1409 }
1410 else if ( column == 1 )
1411 {
1412 setTransparencyToEdited( row );
1413 }
1414 }
1415}
1416
1417void QgsRasterLayerProperties::aboutToShowStyleMenu()
1418{
1419 // this should be unified with QgsVectorLayerProperties::aboutToShowStyleMenu()
1420
1421 QMenu *m = qobject_cast<QMenu *>( sender() );
1422
1424 // re-add style manager actions!
1425 m->addSeparator();
1427}
1428
1429void QgsRasterLayerProperties::syncToLayer()
1430{
1431 QgsRasterRenderer *renderer = mRasterLayer->renderer();
1432 if ( renderer )
1433 {
1434 setRendererWidget( renderer->type() );
1435 }
1436 sync();
1437 mRasterLayer->triggerRepaint();
1438}
1439
1440void QgsRasterLayerProperties::setTransparencyToEdited( int row )
1441{
1442 if ( row >= mTransparencyToEdited.size() )
1443 {
1444 mTransparencyToEdited.resize( row + 1 );
1445 }
1446 mTransparencyToEdited[row] = true;
1447}
1448
1450{
1452
1453 if ( !mHistogramWidget )
1454 return;
1455
1456 if ( index == mOptStackedWidget->indexOf( mOptsPage_Histogram ) )
1457 {
1458 mHistogramWidget->setActive( true );
1459 }
1460 else
1461 {
1462 mHistogramWidget->setActive( false );
1463 }
1464
1465 if ( index == mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1466 {
1467 //set the metadata contents (which can be expensive)
1468 updateInformationContent();
1469 }
1470}
1471
1472void QgsRasterLayerProperties::initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsRasterPipe::Property key )
1473{
1474 button->blockSignals( true );
1475 button->init( static_cast< int >( key ), mPropertyCollection, QgsRasterPipe::propertyDefinitions(), nullptr );
1476 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsRasterLayerProperties::updateProperty );
1477 button->registerExpressionContextGenerator( this );
1478 button->blockSignals( false );
1479}
1480
1481void QgsRasterLayerProperties::updateDataDefinedButtons()
1482{
1483 const auto propertyOverrideButtons { findChildren< QgsPropertyOverrideButton * >() };
1484 for ( QgsPropertyOverrideButton *button : propertyOverrideButtons )
1485 {
1486 updateDataDefinedButton( button );
1487 }
1488}
1489
1490void QgsRasterLayerProperties::updateDataDefinedButton( QgsPropertyOverrideButton *button )
1491{
1492 if ( !button )
1493 return;
1494
1495 if ( button->propertyKey() < 0 )
1496 return;
1497
1498 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1499 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
1500}
1501
1502void QgsRasterLayerProperties::updateProperty()
1503{
1504 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1505 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1506 mPropertyCollection.setProperty( key, button->toProperty() );
1507}
1508
1509void QgsRasterLayerProperties::toggleSaturationControls( int grayscaleMode )
1510{
1511 // Enable or disable saturation controls based on choice of grayscale mode
1512 if ( grayscaleMode == 0 )
1513 {
1514 sliderSaturation->setEnabled( true );
1515 spinBoxSaturation->setEnabled( true );
1516 }
1517 else
1518 {
1519 sliderSaturation->setEnabled( false );
1520 spinBoxSaturation->setEnabled( false );
1521 }
1522}
1523
1524void QgsRasterLayerProperties::toggleColorizeControls( bool colorizeEnabled )
1525{
1526 // Enable or disable colorize controls based on checkbox
1527 btnColorizeColor->setEnabled( colorizeEnabled );
1528 sliderColorizeStrength->setEnabled( colorizeEnabled );
1529 spinColorizeStrength->setEnabled( colorizeEnabled );
1530}
1531
1532
1533QLinearGradient QgsRasterLayerProperties::redGradient()
1534{
1535 //define a gradient
1536 // TODO change this to actual polygon dims
1537 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1538 myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
1539 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
1540 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
1541 return myGradient;
1542}
1543QLinearGradient QgsRasterLayerProperties::greenGradient()
1544{
1545 //define a gradient
1546 // TODO change this to actual polygon dims
1547 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1548 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
1549 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
1550 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
1551 return myGradient;
1552}
1553QLinearGradient QgsRasterLayerProperties::blueGradient()
1554{
1555 //define a gradient
1556 // TODO change this to actual polygon dims
1557 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1558 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
1559 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
1560 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
1561 return myGradient;
1562}
1563QLinearGradient QgsRasterLayerProperties::grayGradient()
1564{
1565 //define a gradient
1566 // TODO change this to actual polygon dims
1567 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1568 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
1569 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
1570 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
1571 return myGradient;
1572}
1573QLinearGradient QgsRasterLayerProperties::highlightGradient()
1574{
1575 //define another gradient for the highlight
1576 // TODO change this to actual polygon dims
1577 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1578 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
1579 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
1580 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
1581 return myGradient;
1582}
1583
1584void QgsRasterLayerProperties::addMetadataUrl()
1585{
1586 const int row = mMetadataUrlModel->rowCount();
1587 mMetadataUrlModel->setItem( row, 0, new QStandardItem( QLatin1String() ) );
1588 mMetadataUrlModel->setItem( row, 1, new QStandardItem( QLatin1String() ) );
1589 mMetadataUrlModel->setItem( row, 2, new QStandardItem( QLatin1String() ) );
1590}
1591
1592void QgsRasterLayerProperties::removeSelectedMetadataUrl()
1593{
1594 const QModelIndexList selectedRows = tableViewMetadataUrl->selectionModel()->selectedRows();
1595 if ( selectedRows.empty() )
1596 return;
1597 mMetadataUrlModel->removeRow( selectedRows[0].row() );
1598}
1599
1600
1601//
1602//
1603// Next four methods for saving and restoring qml style state
1604//
1605//
1606
1608{
1610}
1611
1612void QgsRasterLayerProperties::restoreWindowModality()
1613{
1614 hide();
1615 setModal( true );
1616 show();
1617 raise();
1618 activateWindow();
1619}
1620
1621void QgsRasterLayerProperties::toggleBuildPyramidsButton()
1622{
1623 if ( lbxPyramidResolutions->selectedItems().empty() )
1624 {
1625 buttonBuildPyramids->setEnabled( false );
1626 }
1627 else
1628 {
1629 buttonBuildPyramids->setEnabled( true );
1630 }
1631}
1632
1633void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
1634{
1635 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
1636 mSliderBrightness->setValue( 0 );
1637 mSliderContrast->setValue( 0 );
1638 mGammaSpinBox->setValue( 1.0 );
1639 sliderSaturation->setValue( 0 );
1640 comboGrayscale->setCurrentIndex( ( int ) QgsHueSaturationFilter::GrayscaleOff );
1641 mColorizeCheck->setChecked( false );
1642 sliderColorizeStrength->setValue( 100 );
1643 mInvertColorsCheck->setChecked( false );
1644}
1645
1646bool QgsRasterLayerProperties::rasterIsMultiBandColor()
1647{
1648 return mRasterLayer && nullptr != dynamic_cast<QgsMultiBandColorRenderer *>( mRasterLayer->renderer() );
1649}
1650
1651void QgsRasterLayerProperties::updateInformationContent()
1652{
1653 const QString myStyle = QgsApplication::reportStyleSheet( QgsApplication::StyleSheetType::WebBrowser );
1654 // Inject the stylesheet
1655 const QString html { mRasterLayer->htmlMetadata().replace( QLatin1String( "<head>" ), QStringLiteral( R"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
1656 mMetadataViewer->setHtml( html );
1657 mMetadataFilled = true;
1658}
1659
1661{
1662 // Give the user a chance to save the raster attribute table edits.
1663 if ( mRasterAttributeTableWidget && mRasterAttributeTableWidget->isDirty() )
1664 {
1665 mRasterAttributeTableWidget->setEditable( false, false );
1666 }
1668
1669 if ( mBackupCrs != mRasterLayer->crs() )
1670 mRasterLayer->setCrs( mBackupCrs );
1671}
1672
1673void QgsRasterLayerProperties::showHelp()
1674{
1675 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
1676
1677 if ( helpPage.isValid() )
1678 {
1679 QgsHelp::openHelp( helpPage.toString() );
1680 }
1681 else
1682 {
1683 QgsHelp::openHelp( QStringLiteral( "working_with_raster/raster_properties.html" ) );
1684 }
1685}
1686
1687void QgsRasterLayerProperties::updateGammaSpinBox( int value )
1688{
1689 whileBlocking( mGammaSpinBox )->setValue( value / 100.0 );
1690}
1691
1692void QgsRasterLayerProperties::updateGammaSlider( double value )
1693{
1694 whileBlocking( mSliderGamma )->setValue( value * 100 );
1695}
1696
1697
1698bool QgsRasterLayerProperties::eventFilter( QObject *obj, QEvent *ev )
1699{
1700 // If the map tip preview container is resized, resize the map tip
1701 if ( obj == mMapTipPreviewContainer && ev->type() == QEvent::Resize )
1702 {
1703 resizeMapTip();
1704 }
1705 return QgsOptionsDialogBase::eventFilter( obj, ev );
1706}
1707
1708void QgsRasterLayerProperties::initMapTipPreview()
1709{
1710 // HTML editor and preview are in a splitter. By default, the editor takes 2/3 of the space
1711 mMapTipSplitter->setSizes( { 400, 200 } );
1712 // Event filter is used to resize the map tip when the container is resized
1713 mMapTipPreviewContainer->installEventFilter( this );
1714
1715 // Note: there's quite a bit of overlap between this and the code in QgsMapTip::showMapTip
1716 // Create the WebView
1717 mMapTipPreview = new QgsWebView( mMapTipPreviewContainer );
1718
1719#if WITH_QTWEBKIT
1720 mMapTipPreview->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );//Handle link clicks by yourself
1721 mMapTipPreview->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
1722 connect( mMapTipPreview, &QWebView::loadFinished, this, &QgsRasterLayerProperties::resizeMapTip );
1723#endif
1724
1725 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
1726 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
1727 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
1728
1729 // Disable scrollbars, avoid random resizing issues
1730 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
1731 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
1732
1733
1734 // Update the map tip preview when the expression or the map tip template changes
1735 connect( mMapTipWidget, &QgsCodeEditorHTML::textChanged, this, &QgsRasterLayerProperties::updateMapTipPreview );
1736}
1737
1738void QgsRasterLayerProperties::updateMapTipPreview()
1739{
1740 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1741 const QString htmlContent = QgsMapTip::rasterMapTipPreviewText( mRasterLayer, mCanvas, mMapTipWidget->text() );
1742 mMapTipPreview->setHtml( htmlContent );
1743}
1744
1745void QgsRasterLayerProperties::resizeMapTip()
1746{
1747 // Ensure the map tip is not bigger than the container
1748 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1749#if WITH_QTWEBKIT
1750 // Get the content size
1751 const QWebElement container = mMapTipPreview->page()->mainFrame()->findFirstElement(
1752 QStringLiteral( "#QgsWebViewContainer" ) );
1753 const int width = container.geometry().width();
1754 const int height = container.geometry().height();
1755 mMapTipPreview->resize( width, height );
1756
1757 // Move the map tip to the center of the container
1758 mMapTipPreview->move( ( mMapTipPreviewContainer->width() - mMapTipPreview->width() ) / 2,
1759 ( mMapTipPreviewContainer->height() - mMapTipPreview->height() ) / 2 );
1760
1761#else
1762 mMapTipPreview->adjustSize();
1763#endif
1764}
@ SingleBandColorData
Single band containing color data.
RasterPyramidFormat
Raster pyramid formats.
Definition: qgis.h:3981
@ GeoTiff
Geotiff .ovr (external)
@ Erdas
Erdas Image .aux (external)
@ SingleBandGray
A single band image drawn as a range of gray colors.
@ MultiBandColor
A layer containing 2 or more bands, mapped to RGB color space. In the case of a multiband with only t...
@ Float32
Thirty two bit floating point (float)
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
@ Float64
Sixty four bit floating point (double)
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
static QString reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
static QgsRasterRendererRegistry * rasterRendererRegistry()
Returns the application's raster renderer registry, used for managing raster layer renderers.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QRegularExpression shortNameRegularExpression()
Returns the short name regular expression for line edit validator.
Brightness/contrast and gamma correction filter pipe for rasters.
int contrast() const
Returns current contrast level.
int brightness() const
Returns current brightness level.
double gamma() const
Returns current gamma value.
void setGamma(double gamma)
Set gamma value.
void setContrast(int contrast)
Set contrast level.
void setBrightness(int brightness)
Set brightness level.
This class represents a coordinate reference system (CRS).
virtual QString name() const =0
Returns a provider name.
static bool run(const QgsCoordinateReferenceSystem &sourceCrs=QgsCoordinateReferenceSystem(), const QgsCoordinateReferenceSystem &destinationCrs=QgsCoordinateReferenceSystem(), QWidget *parent=nullptr, QgsMapCanvas *mapCanvas=nullptr, const QString &windowTitle=QString())
Runs the dialog (if required) prompting for the desired transform to use from sourceCrs to destinatio...
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
A generic dialog for building expression strings.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapLayerPositionScope(const QgsPointXY &position)
Sets the expression context variables which are available for expressions triggered by moving the mou...
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QString findAndSelectActiveExpression(QgsCodeEditor *editor, const QString &pattern=QString())
Find the expression under the cursor in the given editor and select it.
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
static QgsProviderSourceWidgetProviderRegistry * sourceWidgetProviderRegistry()
Returns the registry of provider source widget providers.
Definition: qgsgui.cpp:114
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:39
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Factory method to create the renderer for this type.
Color and saturation filter pipe for rasters.
void setColorizeOn(bool colorizeOn)
void setSaturation(int saturation)
bool invertColors() const
Returns true if the filter inverts colors.
void setGrayscaleMode(QgsHueSaturationFilter::GrayscaleMode grayscaleMode)
void setInvertColors(bool invertColors)
Sets whether the filter will invert colors.
QgsHueSaturationFilter::GrayscaleMode grayscaleMode() const
void setColorizeColor(const QColor &colorizeColor)
void setColorizeStrength(int colorizeStrength)
Base class for "layer properties" dialogs, containing common utilities for handling functionality in ...
QPushButton * mBtnStyle
Style button.
void saveMetadataToFile()
Allows the user to save the layer's metadata as a file.
virtual void rollback()
Rolls back changes made to the layer.
void optionsStackedWidget_CurrentChanged(int index) override
void saveStyleAsDefault()
Saves the current layer style as the default for the layer.
QList< QgsMapLayerConfigWidget * > mConfigWidgets
Layer config widgets.
void loadDefaultStyle()
Reloads the default style for the layer.
void saveStyleAs()
Saves a style when appriate button is pressed.
void loadStyle()
Triggers a dialog to load a saved style.
QgsMapCanvas * mCanvas
Associated map canvas.
void loadDefaultMetadata()
Reloads the default layer metadata for the layer.
void loadMetadataFromFile()
Allows the user to load layer metadata from a file.
void saveMetadataAsDefault()
Saves the current layer metadata as the default for the layer.
void openUrl(const QUrl &url)
Handles opening a url from the dialog.
The QgsLoadRasterAttributeTableDialog dialog let the user select a VAT.DBF file and associate the res...
void setOpenWhenDoneVisible(bool visible)
Sets the visibility of the "Open newly created raster attribute table" option to visible,...
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:93
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Factory class for creating custom map layer property pages.
virtual bool supportsLayer(QgsMapLayer *layer) const
Check if the layer is supported for this widget.
virtual QIcon icon() const
The icon that will be shown in the UI for the panel.
virtual QgsMapLayerConfigWidget * createWidget(QgsMapLayer *layer, QgsMapCanvas *canvas, bool dockWidget=true, QWidget *parent=nullptr) const =0
Factory function to create the widget on demand as needed by the dock.
virtual ParentPage parentPage() const
Returns the associated parent page, for factories which create sub-components of a standard page.
virtual QString title() const
The title of the panel.
virtual bool supportLayerPropertiesDialog() const
Flag if widget is supported for use in layer properties dialog.
@ Temporal
Factory creates sub-components of the temporal properties page (only supported for raster layer tempo...
@ NoParent
Factory creates pages itself, not sub-components.
virtual QString layerPropertiesPagePositionHint() const
Returns a tab name hinting at where this page should be inserted into the layer properties tab list.
A panel widget that can be shown in the map style dock.
static QgsMapLayerLegend * defaultRasterLegend(QgsRasterLayer *rl)
Create new legend implementation for raster layer.
void removesExtraMenuSeparators(QMenu *m)
removes extra separators from the menu
void addStyleManagerActions(QMenu *m, QgsMapLayer *layer)
adds actions to the menu in accordance to the layer
static QgsMapLayerStyleGuiUtils * instance()
returns a singleton instance of this class
void currentStyleChanged(const QString &currentName)
Emitted when the current style has been changed.
Base class for all map layer types.
Definition: qgsmaplayer.h:75
void setShortName(const QString &shortName)
Sets the short name of the layer used by QGIS Server to identify the layer.
Definition: qgsmaplayer.h:290
QString name
Definition: qgsmaplayer.h:78
QString legendUrlFormat() const
Returns the format for a URL based layer legend.
Definition: qgsmaplayer.h:1412
void setAbstract(const QString &abstract)
Sets the abstract of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:319
QString source() const
Returns the source for the layer.
void setLegendUrl(const QString &legendUrl)
Sets the URL for the layer's legend.
Definition: qgsmaplayer.h:1397
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
void setMinimumScale(double scale)
Sets the minimum map scale (i.e.
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:81
QString legendPlaceholderImage() const
Returns path to the placeholder image or an empty string if a generated legend is shown.
Definition: qgsmaplayer.h:1640
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
Definition: qgsmaplayer.h:422
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:397
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
void setAttributionUrl(const QString &attribUrl)
Sets the attribution URL of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:405
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
QString abstract() const
Returns the abstract of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:327
QString dataUrlFormat() const
Returns the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:378
void setDataUrl(const QString &dataUrl)
Sets the DataUrl of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:352
void setKeywordList(const QString &keywords)
Sets the keyword list of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:334
void setAttribution(const QString &attrib)
Sets the attribution of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:388
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
void setDataUrlFormat(const QString &dataUrlFormat)
Sets the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:369
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
void rendererChanged()
Signal emitted when renderer is changed.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:312
void setScaleBasedVisibility(bool enabled)
Sets whether scale based visibility is enabled for the layer.
QString dataUrl() const
Returns the DataUrl of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:361
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
void emitStyleChanged()
Triggers an emission of the styleChanged() signal.
void setName(const QString &name)
Set the display name of the layer.
bool isValid
Definition: qgsmaplayer.h:83
void setLegendPlaceholderImage(const QString &imgPath)
Set placeholder image for legend.
Definition: qgsmaplayer.h:1647
void setMapTipsEnabled(bool enabled)
Enable or disable map tips for this layer.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:414
void setDataSource(const QString &dataSource, const QString &baseName, const QString &provider, bool loadDefaultStyleFlag=false)
Updates the data source of the layer.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
QString legendUrl() const
Returns the URL for the layer's legend.
Definition: qgsmaplayer.h:1402
void setLegendUrlFormat(const QString &legendUrlFormat)
Sets the format for a URL based layer legend.
Definition: qgsmaplayer.h:1407
void setMapTipTemplate(const QString &mapTipTemplate)
The mapTip is a pretty, html representation for feature information.
bool mapTipsEnabled
Definition: qgsmaplayer.h:86
void setLegend(QgsMapLayerLegend *legend)
Assign a legend controller to the map layer.
double maximumScale() const
Returns the maximum map scale (i.e.
QString keywordList() const
Returns the keyword list of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:342
QString mapTipTemplate
Definition: qgsmaplayer.h:85
void setTitle(const QString &title)
Sets the title of the layer used by QGIS Server in GetCapabilities request.
Definition: qgsmaplayer.h:304
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
QgsRectangle outputExtentToLayerExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from output CRS to layer's CRS
static QString rasterMapTipPreviewText(QgsMapLayer *layer, QgsMapCanvas *mapCanvas, const QString &mapTemplate)
Returns the html that would be displayed in a maptip for a given layer.
Definition: qgsmaptip.cpp:492
void deactivated()
signal emitted once the map tool is deactivated
A wizard to edit metadata on a map layer.
void acceptMetadata()
Saves the metadata to the layer.
void crsChanged()
If the CRS is updated.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Renderer for multiband images with the color components.
void addPage(const QString &title, const QString &tooltip, const QIcon &icon, QWidget *widget, const QStringList &path=QStringList(), const QString &key=QString())
Adds a new page to the dialog pages.
QStackedWidget * mOptStackedWidget
void initOptionsBase(bool restoreUi=true, const QString &title=QString())
Set up the base ui connections for vertical tabs.
void insertPage(const QString &title, const QString &tooltip, const QIcon &icon, QWidget *widget, const QString &before, const QStringList &path=QStringList(), const QString &key=QString())
Inserts a new page into the dialog pages.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
static bool layerIsContainedInGroupLayer(QgsProject *project, QgsMapLayer *layer)
Returns true if the specified layer is a child layer from any QgsGroupLayer in the given project.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:481
void setDirty(bool b=true)
Flag the project as dirty (modified).
Definition: qgsproject.cpp:599
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
A button for controlling property overrides which may apply to a widget.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void changed()
Emitted when property definition changes.
void init(int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer=nullptr, bool auxiliaryStorageEnabled=false)
Initialize a newly constructed property button (useful if button was included in a UI layout).
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
int propertyKey() const
Returns the property key linked to the button.
QgsProviderSourceWidget * createWidget(QgsMapLayer *layer, QWidget *parent=nullptr)
Creates a new widget to configure the source of the specified layer.
virtual QString groupTitle() const
Returns an optional group title for the source settings, for use in layer properties dialogs.
void validChanged(bool isValid)
Emitted whenever the validation status of the widget changes.
virtual QString sourceUri() const =0
Returns the source URI as currently defined by the widget.
virtual void setMapCanvas(QgsMapCanvas *mapCanvas)
Sets a map canvas associated with the widget.
virtual void setSourceUri(const QString &uri)=0
Sets the source uri to show in the widget.
The QgsRasterAttributeTableWidget class provides an attribute table for rasters and methods to edit t...
void rendererChanged()
This signal is emitted after a successful classify operation which changed the raster renderer.
bool isDirty() const
Returns true if the associated raster attribute table is dirty.
bool setEditable(bool editable, bool allowCancel=true)
Set the editable state, it may trigger save changes if the attribute table has unsave changes.
Feedback object tailored for raster block reading.
static QString printValue(double value)
Print double value with all necessary significant digits.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Widget creation function (mainly for the use by the renderer registry)
Base class for raster data providers.
virtual QString buildPyramids(const QList< QgsRasterPyramid > &pyramidList, const QString &resamplingMethod="NEAREST", Qgis::RasterPyramidFormat format=Qgis::RasterPyramidFormat::GeoTiff, const QStringList &configOptions=QStringList(), QgsRasterBlockFeedback *feedback=nullptr)
Creates pyramid overviews.
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...
virtual void setUseSourceNoDataValue(int bandNo, bool use)
Sets the source nodata value usage.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
static QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns a list of pyramid resampling method name and label pairs for given provider.
virtual void setUserNoDataValue(int bandNo, const QgsRasterRangeList &noData)
virtual QList< QgsRasterPyramid > buildPyramidList(const QList< int > &overviewList=QList< int >())
Returns the raster layers pyramid list.
void setRendererWidget(const QString &name, QgsRasterRendererWidget *rendererWidget=nullptr)
Sets the renderer widget (or just its name if there is no widget)
void setActive(bool activeFlag)
Activate the histogram widget.
@ BuildPyramids
Supports building of pyramids (overviews)
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
Q_DECL_DEPRECATED void saveDefaultStyle()
Saves the default style when appropriate button is pressed.
QgsRasterLayerProperties(QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent=nullptr, Qt::WindowFlags=QgsGuiUtils::ModalDialogFlags)
Constructor.
bool eventFilter(QObject *obj, QEvent *ev) override
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void optionsStackedWidget_CurrentChanged(int index) FINAL
void addPropertiesPageFactory(const QgsMapLayerConfigWidgetFactory *factory) FINAL
Adds properties page from a factory.
A widget for configuring the temporal properties for a raster layer.
void addWidget(QgsMapLayerConfigWidget *widget)
Adds a child widget to the properties widget.
void syncToLayer()
Updates the widget state to match the current layer state.
void saveTemporalProperties()
Save widget temporal properties inputs.
Represents a raster layer.
QString htmlMetadata() const override
Obtain a formatted HTML string containing assorted metadata for this layer.
bool canCreateRasterAttributeTable()
Returns true if the raster renderer is suitable for creation of a raster attribute table.
int attributeTableCount() const
Returns the number of attribute tables for the raster by counting the number of bands that have an as...
QgsRasterPipe * pipe()
Returns the raster pipe.
QgsBrightnessContrastFilter * brightnessFilter() const
Returns the raster's brightness/contrast filter.
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
QString providerType() const
[ data provider interface ] Which provider is being used for this Raster Layer?
void setRenderer(QgsRasterRenderer *renderer)
Sets the raster's renderer.
QgsHueSaturationFilter * hueSaturationFilter() const
Returns the raster's hue/saturation filter.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the pipe's property collection, used for data defined overrides.
Property
Data definable properties.
Definition: qgsrasterpipe.h:60
@ RendererOpacity
Raster renderer global opacity.
static QgsPropertiesDefinition propertyDefinitions()
Returns the definitions for data defined properties available for use in raster pipes.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the pipe's property collection, used for data defined overrides.
This struct is used to store pyramid info for the raster layer.
Raster values range container.
void insertWidgetFunction(const QString &rendererName, QgsRasterRendererWidgetCreateFunc func)
Sets the widget creation function for a renderer.
QStringList renderersList() const
Returns a list of the names of registered renderers.
Abstract base class for widgets which configure a QgsRasterRenderer.
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
virtual void doComputations()
Load programmatically with current values.
virtual QgsRasterRenderer * renderer()=0
Creates a new renderer, using the properties defined in the widget.
Raster renderer pipe that applies colors to a raster.
QColor nodataColor() const
Returns the color to use for shading nodata pixels.
virtual QString type() const
Returns a unique string representation of the renderer type.
double opacity() const
Returns the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
virtual QList< int > usesBands() const
Returns a list of band numbers used by the renderer.
void setAlphaBand(int band)
void setOpacity(double opacity)
Sets the opacity for the renderer, where opacity is a value between 0 (totally transparent) and 1....
void setRasterTransparency(QgsRasterTransparency *t)
void setNodataColor(const QColor &color)
Sets the color to use for shading nodata pixels.
Widget to control a layers transparency and related options.
void syncToLayer()
Sync the widget state to the layer set for the widget.
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
void setTransparentSingleValuePixelList(const QVector< QgsRasterTransparency::TransparentSingleValuePixel > &newList)
Sets the transparent single value pixel list, replacing the whole existing list.
void setTransparentThreeValuePixelList(const QVector< QgsRasterTransparency::TransparentThreeValuePixel > &newList)
Sets the transparent three value pixel list, replacing the whole existing list.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
void setMetadataUrls(const QList< QgsServerMetadataUrlProperties::MetadataUrl > &metaUrls)
Sets a the list of metadata URL for the layer.
QList< QgsServerMetadataUrlProperties::MetadataUrl > metadataUrls() const
Returns a list of metadataUrl resources associated for the layer.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Creates new raster renderer widget.
The QgsWebView class is a collection of stubs to mimic the API of QWebView on systems where the real ...
Definition: qgswebview.h:66
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
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:5111
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QList< QgsRasterRange > QgsRasterRangeList
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.
Registry for raster renderer entries.
QgsRasterRendererWidgetCreateFunc widgetCreateFunction
Defines the transparency for a range of single-band pixel values.
Defines the transparency for a RGB pixel value.
QString format
Format specification of online resource.