QGIS API Documentation 3.43.0-Master (3ee7834ace6)
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
6 email : tim@linfiniti.com
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 "moc_qgsrasterlayerproperties.cpp"
46#include "qgsrasterpyramid.h"
47#include "qgsrasterrange.h"
48#include "qgsrasterrenderer.h"
56#include "qgssettings.h"
58#include "qgsmaplayerlegend.h"
59#include "qgsfileutils.h"
60#include "qgswebview.h"
61#include "qgsvectorlayer.h"
62#include "qgsdoublevalidator.h"
64#include "qgsprojectutils.h"
68#include "qgsmaptip.h"
69#include "qgswebframe.h"
70#include "qgsexpressionfinder.h"
73#if WITH_QTWEBKIT
74#include <QWebElement>
75#endif
76#include "qgshelp.h"
77
78#include <QDesktopServices>
79#include <QTableWidgetItem>
80#include <QHeaderView>
81#include <QTextStream>
82#include <QFile>
83#include <QFileDialog>
84#include <QMessageBox>
85#include <QPainter>
86#include <QLinearGradient>
87#include <QPainterPath>
88#include <QPolygonF>
89#include <QColorDialog>
90#include <QList>
91#include <QMouseEvent>
92#include <QVector>
93#include <QUrl>
94#include <QMenu>
95#include <QScreen>
96#include <QRegularExpressionValidator>
97#include <QRegularExpression>
98
99QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl )
100 : QgsLayerPropertiesDialog( lyr, canvas, QStringLiteral( "RasterLayerProperties" ), parent, fl )
101 // Constant that signals property not used.
102 , TRSTRING_NOT_SET( tr( "Not Set" ) )
103 , mDefaultStandardDeviation( 0 )
104 , mDefaultRedBand( 0 )
105 , mDefaultGreenBand( 0 )
106 , mDefaultBlueBand( 0 )
107 , mRasterLayer( qobject_cast<QgsRasterLayer *>( lyr ) )
108 , mGradientHeight( 0.0 )
109 , mGradientWidth( 0.0 )
110 , mMetadataFilled( false )
111{
112 mGrayMinimumMaximumEstimated = true;
113 mRGBMinimumMaximumEstimated = true;
114
115 setupUi( this );
116
117 mMetadataViewer = new QgsWebView( this );
118 mOptsPage_Information->layout()->addWidget( mMetadataViewer );
119
120 mRasterTransparencyWidget = new QgsRasterTransparencyWidget( mRasterLayer, canvas, this );
121
122 transparencyScrollArea->setWidget( mRasterTransparencyWidget );
123
124 mLabelingWidget = new QgsRasterLabelingWidget( mRasterLayer, canvas, this );
125 QVBoxLayout *vl = new QVBoxLayout();
126 vl->setContentsMargins( 0, 0, 0, 0 );
127 vl->addWidget( mLabelingWidget );
128 mOptsPage_Labeling->setLayout( vl );
129
130 connect( buttonBuildPyramids, &QPushButton::clicked, this, &QgsRasterLayerProperties::buttonBuildPyramids_clicked );
131 connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsRasterLayerProperties::mCrsSelector_crsChanged );
132 connect( mRenderTypeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged );
133 connect( mResetColorRenderingBtn, &QToolButton::clicked, this, &QgsRasterLayerProperties::mResetColorRenderingBtn_clicked );
134 // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
135 // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
136 // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
137 initOptionsBase( false );
138 connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerProperties::showHelp );
139
140 mSourceGroupBox->hide();
141
142 mBtnStyle = new QPushButton( tr( "Style" ) );
143 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
144
145 connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsRasterLayerProperties::syncToLayer );
146
147 connect( this, &QDialog::accepted, this, &QgsRasterLayerProperties::apply );
148 connect( this, &QDialog::rejected, this, &QgsRasterLayerProperties::rollback );
149
150 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsRasterLayerProperties::apply );
151
152 cbxPyramidsFormat->addItem( tr( "External" ), QVariant::fromValue( Qgis::RasterPyramidFormat::GeoTiff ) );
153 cbxPyramidsFormat->addItem( tr( "Internal (if possible)" ), QVariant::fromValue( Qgis::RasterPyramidFormat::Internal ) );
154 cbxPyramidsFormat->addItem( tr( "External (Erdas Imagine)" ), QVariant::fromValue( Qgis::RasterPyramidFormat::Erdas ) );
155
156 // brightness/contrast controls
157 connect( mSliderBrightness, &QAbstractSlider::valueChanged, mBrightnessSpinBox, &QSpinBox::setValue );
158 connect( mBrightnessSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), mSliderBrightness, &QAbstractSlider::setValue );
159 mBrightnessSpinBox->setClearValue( 0 );
160
161 connect( mSliderContrast, &QAbstractSlider::valueChanged, mContrastSpinBox, &QSpinBox::setValue );
162 connect( mContrastSpinBox, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), mSliderContrast, &QAbstractSlider::setValue );
163 mContrastSpinBox->setClearValue( 0 );
164
165 // gamma correction controls
166 connect( mSliderGamma, &QAbstractSlider::valueChanged, this, &QgsRasterLayerProperties::updateGammaSpinBox );
167 connect( mGammaSpinBox, static_cast<void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsRasterLayerProperties::updateGammaSlider );
168 mGammaSpinBox->setClearValue( 1.0 );
169
170 // Connect saturation slider and spin box
171 connect( sliderSaturation, &QAbstractSlider::valueChanged, spinBoxSaturation, &QSpinBox::setValue );
172 connect( spinBoxSaturation, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), sliderSaturation, &QAbstractSlider::setValue );
173 spinBoxSaturation->setClearValue( 0 );
174
175 // Connect colorize strength slider and spin box
176 connect( sliderColorizeStrength, &QAbstractSlider::valueChanged, spinColorizeStrength, &QSpinBox::setValue );
177 connect( spinColorizeStrength, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ), sliderColorizeStrength, &QAbstractSlider::setValue );
178 spinColorizeStrength->setClearValue( 100 );
179
180 // enable or disable saturation slider and spin box depending on grayscale combo choice
181 connect( comboGrayscale, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRasterLayerProperties::toggleSaturationControls );
182
183 // enable or disable colorize colorbutton with colorize checkbox
184 connect( mColorizeCheck, &QAbstractButton::toggled, this, &QgsRasterLayerProperties::toggleColorizeControls );
185
186 // enable or disable Build Pyramids button depending on selection in pyramid list
187 connect( lbxPyramidResolutions, &QListWidget::itemSelectionChanged, this, &QgsRasterLayerProperties::toggleBuildPyramidsButton );
188
189 mRefreshSettingsWidget->setLayer( mRasterLayer );
190 mMapLayerServerPropertiesWidget->setHasWfsTitle( false );
191 mMapLayerServerPropertiesWidget->setServerProperties( mRasterLayer->serverProperties() );
192
193 // set up the scale based layer visibility stuff....
194 mScaleRangeWidget->setMapCanvas( mCanvas );
195 chkUseScaleDependentRendering->setChecked( lyr->hasScaleBasedVisibility() );
196 mScaleRangeWidget->setScaleRange( lyr->minimumScale(), lyr->maximumScale() );
197
198 // build GUI components
199 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
200 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
201
202 initMapTipPreview();
203
204 if ( !mRasterLayer )
205 {
206 return;
207 }
208
209 connect( mEnableMapTips, &QAbstractButton::toggled, mHtmlMapTipGroupBox, &QWidget::setEnabled );
210 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
211
212 updateRasterAttributeTableOptionsPage();
213
214 connect( mRasterLayer, &QgsRasterLayer::rendererChanged, this, &QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage );
215
216 connect( mCreateRasterAttributeTableButton, &QPushButton::clicked, this, [=] {
217 if ( mRasterLayer->canCreateRasterAttributeTable() )
218 {
219 // Create the attribute table from the renderer
220 QgsCreateRasterAttributeTableDialog dlg { mRasterLayer };
221 dlg.setOpenWhenDoneVisible( false );
222 if ( dlg.exec() == QDialog::Accepted )
223 {
224 updateRasterAttributeTableOptionsPage();
225 }
226 }
227 } );
228
229 connect( mLoadRasterAttributeTableFromFileButton, &QPushButton::clicked, this, [=] {
230 // Load the attribute table from a VAT.DBF file
231 QgsLoadRasterAttributeTableDialog dlg { mRasterLayer };
232 dlg.setOpenWhenDoneVisible( false );
233 if ( dlg.exec() == QDialog::Accepted )
234 {
235 updateRasterAttributeTableOptionsPage();
236 }
237 } );
238
239 mBackupCrs = mRasterLayer->crs();
240
241 // Handles window modality raising canvas
242 if ( mCanvas && mRasterTransparencyWidget->pixelSelectorTool() )
243 {
244 connect( mRasterTransparencyWidget->pixelSelectorTool(), &QgsMapToolEmitPoint::deactivated, this, [=] {
245 hide();
246 setModal( true );
247 show();
248 raise();
249 activateWindow();
250 } );
251
252 connect( mRasterTransparencyWidget->pbnAddValuesFromDisplay, &QPushButton::clicked, this, [=] {
253 hide();
254 setModal( false );
255
256 // Transfer focus to the canvas to use the selector tool
257 mCanvas->window()->raise();
258 mCanvas->window()->activateWindow();
259 mCanvas->window()->setFocus();
260 } );
261 }
262
263 if ( mCanvas )
264 {
265 mContext = mCanvas->createExpressionContext();
266 }
267 else
268 {
273 }
274
275 // Initialize with layer center
276 mContext << QgsExpressionContextUtils::mapLayerPositionScope( mRasterLayer->extent().center() );
277 mContext << QgsExpressionContextUtils::layerScope( mRasterLayer );
278
279 connect( mInsertExpressionButton, &QAbstractButton::clicked, this, [=] {
280 // Get the linear indexes if the start and end of the selection
281 int selectionStart = mMapTipWidget->selectionStart();
282 int selectionEnd = mMapTipWidget->selectionEnd();
283 QString expression = QgsExpressionFinder::findAndSelectActiveExpression( mMapTipWidget );
284 QgsExpressionBuilderDialog exprDlg( nullptr, expression, this, QStringLiteral( "generic" ), mContext );
285
286 exprDlg.setWindowTitle( tr( "Insert Expression" ) );
287 if ( exprDlg.exec() == QDialog::Accepted && !exprDlg.expressionText().trimmed().isEmpty() )
288 mMapTipWidget->insertText( "[%" + exprDlg.expressionText().trimmed() + "%]" );
289 else // Restore the selection
290 mMapTipWidget->setLinearSelection( selectionStart, selectionEnd );
291 } );
292
293 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
294
295 // Only do pyramids if dealing directly with GDAL.
296 if ( provider && ( provider->capabilities() & Qgis::RasterInterfaceCapability::BuildPyramids || provider->providerCapabilities() & Qgis::RasterProviderCapability::BuildPyramids ) )
297 {
298 // initialize resampling methods
299 cboResamplingMethod->clear();
300
301 const auto constProviderType = QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() );
302 for ( const QPair<QString, QString> &method : std::as_const( constProviderType ) )
303 {
304 cboResamplingMethod->addItem( method.second, method.first );
305 }
306
307 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
308 QString prefix = provider->name() + "/driverOptions/_pyramids/";
309 QgsSettings mySettings;
310 QString defaultMethod = mySettings.value( prefix + "resampling", "AVERAGE" ).toString();
311 int idx = cboResamplingMethod->findData( defaultMethod );
312 if ( idx >= 0 )
313 cboResamplingMethod->setCurrentIndex( idx );
314
315
316 // build pyramid list
317 const QList<QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
318
319 for ( const QgsRasterPyramid &pyramid : myPyramidList )
320 {
321 if ( pyramid.getExists() )
322 {
323 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap, QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) + QString::number( pyramid.getYDim() ) ) );
324 }
325 else
326 {
327 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap, QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) + QString::number( pyramid.getYDim() ) ) );
328 }
329 }
330 }
331 else
332 {
333 // disable Pyramids tab completely
334 mOptsPage_Pyramids->setEnabled( false );
335 }
336
337 // We can calculate histogram for all data sources but estimated only if
338 // size is unknown - could also be enabled if well supported (estimated histogram
339 // and let user know that it is estimated)
340 if ( !provider || !( provider->capabilities() & Qgis::RasterInterfaceCapability::Size ) )
341 {
342 // disable Histogram tab completely
343 mOptsPage_Histogram->setEnabled( false );
344 }
345
346 QVBoxLayout *layout = new QVBoxLayout( metadataFrame );
347 layout->setContentsMargins( 0, 0, 0, 0 );
348 mMetadataWidget = new QgsMetadataWidget( this, mRasterLayer );
349 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
350 mMetadataWidget->setMapCanvas( mCanvas );
351 layout->addWidget( mMetadataWidget );
352 metadataFrame->setLayout( layout );
353
354 QVBoxLayout *temporalLayout = new QVBoxLayout( temporalFrame );
355 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
356 mTemporalWidget = new QgsRasterLayerTemporalPropertiesWidget( this, mRasterLayer );
357 temporalLayout->addWidget( mTemporalWidget );
358
359 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().toWkt( Qgis::CrsWktVariant::Preferred ), 2 );
360 QgsDebugMsgLevel( "Setting crs to " + mRasterLayer->crs().userFriendlyIdentifier(), 2 );
361 mCrsSelector->setCrs( mRasterLayer->crs() );
362
363 // Set text for pyramid info box
364 QString pyramidFormat( QStringLiteral( "<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
365 QString pyramidHeader = tr( "Description" );
366 QString pyramidSentence1 = tr( "Large resolution raster layers can slow navigation in QGIS." );
367 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." );
368 QString pyramidSentence3 = tr( "You must have write access in the directory where the original data is stored to build pyramids." );
369 QString pyramidSentence4 = tr( "Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
370 QString pyramidSentence5 = tr( "Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
371
372 tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader, pyramidSentence1, pyramidSentence2, pyramidSentence3, pyramidSentence4, pyramidSentence5 ) );
373
374 //resampling
375 mResamplingGroupBox->setSaveCheckedState( true );
376 mResamplingUtils.initWidgets( mRasterLayer, mZoomedInResamplingComboBox, mZoomedOutResamplingComboBox, mMaximumOversamplingSpinBox, mCbEarlyResampling );
377 mResamplingUtils.refreshWidgetsFromLayer();
378
379 const QgsRasterRenderer *renderer = mRasterLayer->renderer();
380
381 btnColorizeColor->setColorDialogTitle( tr( "Select Color" ) );
382 btnColorizeColor->setContext( QStringLiteral( "symbology" ) );
383
384 // Hue and saturation color control
385 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
386 //set hue and saturation controls to current values
387 if ( hueSaturationFilter )
388 {
389 sliderSaturation->setValue( hueSaturationFilter->saturation() );
390 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
391
392 // Set initial state of saturation controls based on grayscale mode choice
393 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
394
395 // Set initial state of colorize controls
396 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
397 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
398 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
399 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
400 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
401 }
402
403 //blend mode
404 mBlendModeComboBox->setShowClippingModes( QgsProjectUtils::layerIsContainedInGroupLayer( QgsProject::instance(), mRasterLayer ) );
405 mBlendModeComboBox->setBlendMode( mRasterLayer->blendMode() );
406
407 //transparency band
408 if ( provider )
409 {
410 mRasterTransparencyWidget->cboxTransparencyBand->setShowNotSetOption( true, tr( "None" ) );
411 mRasterTransparencyWidget->cboxTransparencyBand->setLayer( mRasterLayer );
412
413// Alpha band is set in sync()
414#if 0
415 if ( renderer )
416 {
417 QgsDebugMsgLevel( QStringLiteral( "alphaBand = %1" ).arg( renderer->alphaBand() ), 2 );
418 if ( renderer->alphaBand() > 0 )
419 {
420 cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->alphaBand() ) );
421 }
422 }
423#endif
424 }
425
426 // create histogram widget
427 mHistogramWidget = nullptr;
428 if ( mOptsPage_Histogram->isEnabled() )
429 {
430 mHistogramWidget = new QgsRasterHistogramWidget( mRasterLayer, mOptsPage_Histogram );
431 mHistogramStackedWidget->addWidget( mHistogramWidget );
432 }
433
434 //insert renderer widgets into registry
442
443 //fill available renderers into combo box
445 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
446 const auto constRenderersList = QgsApplication::rasterRendererRegistry()->renderersList();
447 for ( const QString &name : constRenderersList )
448 {
449 if ( QgsApplication::rasterRendererRegistry()->rendererData( name, entry ) )
450 {
451 if ( ( mRasterLayer->rasterType() != Qgis::RasterLayerType::SingleBandColorData && entry.name != QLatin1String( "singlebandcolordata" ) ) || ( mRasterLayer->rasterType() == Qgis::RasterLayerType::SingleBandColorData && entry.name == QLatin1String( "singlebandcolordata" ) ) )
452 {
453 mRenderTypeComboBox->addItem( entry.visibleName, entry.name );
454 }
455 }
456 }
457 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
458
459 int widgetIndex = 0;
460 if ( renderer )
461 {
462 QString rendererType = renderer->type();
463 widgetIndex = mRenderTypeComboBox->findData( rendererType );
464 if ( widgetIndex != -1 )
465 {
466 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
467 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
468 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
469 }
470
471 if ( rendererType == QLatin1String( "singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
472 {
473 // no band rendering options for singlebandcolordata, so minimize group box
474 QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
475 sizep.setVerticalStretch( 0 );
476 sizep.setVerticalPolicy( QSizePolicy::Maximum );
477 mBandRenderingGrpBx->setSizePolicy( sizep );
478 mBandRenderingGrpBx->updateGeometry();
479 }
480
481 if ( mRasterLayer->providerType() != QLatin1String( "wms" ) )
482 {
483 mWMSPrintGroupBox->hide();
484 mPublishDataSourceUrlCheckBox->hide();
485 mBackgroundLayerCheckBox->hide();
486 }
487 }
488
489#ifdef WITH_QTWEBKIT
490 // Setup information tab
491
492 const int horizontalDpi = logicalDpiX();
493
494 // Adjust zoom: text is ok, but HTML seems rather big at least on Linux/KDE
495 if ( horizontalDpi > 96 )
496 {
497 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
498 }
499 mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
500 connect( mMetadataViewer->page(), &QWebPage::linkClicked, this, &QgsRasterLayerProperties::openUrl );
501 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
502 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
503
504#endif
505
506 initializeDataDefinedButton( mRasterTransparencyWidget->mOpacityDDBtn, QgsRasterPipe::Property::RendererOpacity );
507
508 mRenderTypeComboBox_currentIndexChanged( widgetIndex );
509
510 setMetadataWidget( mMetadataWidget, mOptsPage_Metadata );
511
512 QMenu *menuStyle = new QMenu( this );
513 menuStyle->addAction( tr( "Load Style…" ), this, &QgsRasterLayerProperties::loadStyle );
514 menuStyle->addAction( tr( "Save Style…" ), this, &QgsRasterLayerProperties::saveStyleAs );
515 menuStyle->addSeparator();
516 menuStyle->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveStyleAsDefault );
517 menuStyle->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultStyle );
518 mBtnStyle->setMenu( menuStyle );
519 connect( menuStyle, &QMenu::aboutToShow, this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
520
521 mBtnMetadata = new QPushButton( tr( "Metadata" ), this );
522 QMenu *menuMetadata = new QMenu( this );
523 mActionLoadMetadata = menuMetadata->addAction( tr( "Load Metadata…" ), this, &QgsRasterLayerProperties::loadMetadataFromFile );
524 mActionSaveMetadataAs = menuMetadata->addAction( tr( "Save Metadata…" ), this, &QgsRasterLayerProperties::saveMetadataToFile );
525 menuMetadata->addSeparator();
526 menuMetadata->addAction( tr( "Save as Default" ), this, &QgsRasterLayerProperties::saveMetadataAsDefault );
527 menuMetadata->addAction( tr( "Restore Default" ), this, &QgsRasterLayerProperties::loadDefaultMetadata );
528 mBtnMetadata->setMenu( menuMetadata );
529 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
530
531 // update based on lyr's current state
532 sync();
533
534 QgsSettings settings;
535 // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often
536 // this will be read by restoreOptionsBaseUi()
537 if ( !settings.contains( QStringLiteral( "/Windows/RasterLayerProperties/tab" ) ) )
538 {
539 settings.setValue( QStringLiteral( "Windows/RasterLayerProperties/tab" ), mOptStackedWidget->indexOf( mOptsPage_Style ) );
540 }
541
542 mResetColorRenderingBtn->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionUndo.svg" ) ) );
543
544 optionsStackedWidget_CurrentChanged( mOptionsStackedWidget->currentIndex() );
545
546 //Add help page references
547 mOptsPage_Information->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#information-properties" ) );
548 mOptsPage_Source->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#source-properties" ) );
549 mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#symbology-properties" ) );
550 mOptsPage_Transparency->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#transparency-properties" ) );
551
552 if ( mOptsPage_Histogram )
553 mOptsPage_Histogram->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#histogram-properties" ) );
554
555 mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#rendering-properties" ) );
556 mOptsPage_Temporal->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#temporal-properties" ) );
557
558 if ( mOptsPage_Pyramids )
559 mOptsPage_Pyramids->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#pyramids-properties" ) );
560
561 if ( mOptsPage_Display )
562 mOptsPage_Display->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#display-properties" ) );
563
564 mOptsPage_Metadata->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#metadata-properties" ) );
565 mOptsPage_Legend->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#legend-properties" ) );
566 mOptsPage_Server->setProperty( "helpPage", QStringLiteral( "working_with_raster/raster_properties.html#server-properties" ) );
567
568 initialize();
569}
570
572{
573 if ( !factory->supportsLayer( mRasterLayer ) || !factory->supportLayerPropertiesDialog() )
574 {
575 return;
576 }
577
578 QgsMapLayerConfigWidget *page = factory->createWidget( mRasterLayer, nullptr, false, this );
579 switch ( factory->parentPage() )
580 {
582 {
583 mConfigWidgets << page;
584
585 const QString beforePage = factory->layerPropertiesPagePositionHint();
586 if ( beforePage.isEmpty() )
587 addPage( factory->title(), factory->title(), factory->icon(), page );
588 else
589 insertPage( factory->title(), factory->title(), factory->icon(), page, beforePage );
590 break;
591 }
592
594 mTemporalWidget->addWidget( page );
595 break;
596 }
597}
598
603
604void QgsRasterLayerProperties::updateRasterAttributeTableOptionsPage()
605{
606 if ( mRasterAttributeTableWidget )
607 {
608 mOptsPage_RasterAttributeTable->layout()->removeWidget( mRasterAttributeTableWidget );
609 mRasterAttributeTableWidget = nullptr;
610 }
611
612 // Setup raster attribute table
613 if ( mRasterLayer->attributeTableCount() > 0 )
614 {
615 mRasterAttributeTableWidget = new QgsRasterAttributeTableWidget( this, mRasterLayer );
616 mOptsPage_RasterAttributeTable->layout()->addWidget( mRasterAttributeTableWidget );
617 // When the renderer changes we need to sync the style options page
618 connect( mRasterAttributeTableWidget, &QgsRasterAttributeTableWidget::rendererChanged, this, &QgsRasterLayerProperties::syncToLayer );
619 mNoRasterAttributeTableWidget->hide();
620 }
621 else
622 {
623 mNoRasterAttributeTableWidget->show();
624 mCreateRasterAttributeTableButton->setEnabled( mRasterLayer->canCreateRasterAttributeTable() );
625 }
626}
627
628void QgsRasterLayerProperties::setRendererWidget( const QString &rendererName )
629{
630 QgsDebugMsgLevel( "rendererName = " + rendererName, 3 );
631 QgsRasterRendererWidget *oldWidget = mRendererWidget;
632 QgsRasterRenderer *oldRenderer = mRasterLayer->renderer();
633
634 int alphaBand = -1;
635 double opacity = 1;
636 QColor nodataColor;
637 const QList<int> oldBands = oldRenderer ? oldRenderer->usesBands() : QList<int>();
638 if ( oldRenderer )
639 {
640 // Retain alpha band and opacity when switching renderer
641 alphaBand = oldRenderer->alphaBand();
642 opacity = oldRenderer->opacity();
643 nodataColor = oldRenderer->nodataColor();
644 }
645
646 QgsRasterRendererRegistryEntry rendererEntry;
647 if ( QgsApplication::rasterRendererRegistry()->rendererData( rendererName, rendererEntry ) )
648 {
649 if ( rendererEntry.widgetCreateFunction ) //single band color data renderer e.g. has no widget
650 {
651 QgsDebugMsgLevel( QStringLiteral( "renderer has widgetCreateFunction" ), 3 );
652 // Current canvas extent (used to calc min/max) in layer CRS
654 if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->type() ) )
655 {
656 if ( rendererName == QLatin1String( "singlebandgray" ) )
657 {
658 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::SingleBandGray, mRasterLayer->dataProvider() ) );
659 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
660 }
661 else if ( rendererName == QLatin1String( "multibandcolor" ) )
662 {
663 whileBlocking( mRasterLayer )->setRenderer( QgsApplication::rasterRendererRegistry()->defaultRendererForDrawingStyle( Qgis::RasterDrawingStyle::MultiBandColor, mRasterLayer->dataProvider() ) );
664 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
665 }
666 }
667 mRasterLayer->renderer()->setAlphaBand( alphaBand );
668 mRasterLayer->renderer()->setOpacity( opacity );
669 mRasterLayer->renderer()->setNodataColor( nodataColor );
670 mRendererWidget = rendererEntry.widgetCreateFunction( mRasterLayer, myExtent );
671 mRendererWidget->setMapCanvas( mCanvas );
672 mRendererStackedWidget->addWidget( mRendererWidget );
673 if ( oldWidget )
674 {
675 //compare used bands in new and old renderer and reset transparency dialog if different
676 std::unique_ptr<QgsRasterRenderer> newRenderer;
677 newRenderer.reset( mRendererWidget->renderer() );
678 const QList<int> newBands = newRenderer->usesBands();
679 if ( oldBands != newBands )
680 {
681 mRasterTransparencyWidget->syncToLayer();
682 }
683 }
684 }
685 }
686
687 const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
688 if ( widgetIndex != -1 )
689 {
690 mDisableRenderTypeComboBoxCurrentIndexChanged = true;
691 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
692 mDisableRenderTypeComboBoxCurrentIndexChanged = false;
693 }
694
695 if ( mRendererWidget != oldWidget )
696 delete oldWidget;
697
698 if ( mHistogramWidget )
699 {
700 mHistogramWidget->setRendererWidget( rendererName, mRendererWidget );
701 }
702}
703
704void QgsRasterLayerProperties::sync()
705{
706 QgsSettings myQSettings;
707
708 if ( !mSourceWidget )
709 {
710 mSourceWidget = QgsGui::sourceWidgetProviderRegistry()->createWidget( mRasterLayer );
711 if ( mSourceWidget )
712 {
713 QHBoxLayout *layout = new QHBoxLayout();
714 layout->addWidget( mSourceWidget );
715 mSourceGroupBox->setLayout( layout );
716 if ( !mSourceWidget->groupTitle().isEmpty() )
717 mSourceGroupBox->setTitle( mSourceWidget->groupTitle() );
718 mSourceGroupBox->show();
719
720 connect( mSourceWidget, &QgsProviderSourceWidget::validChanged, this, [=]( bool isValid ) {
721 buttonBox->button( QDialogButtonBox::Apply )->setEnabled( isValid );
722 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
723 } );
724 }
725 }
726
727 if ( mSourceWidget )
728 {
729 mSourceWidget->setMapCanvas( mCanvas );
730 mSourceWidget->setSourceUri( mRasterLayer->source() );
731 }
732
733 const QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
734 if ( !provider )
735 return;
736
737 mRasterTransparencyWidget->syncToLayer();
738 mLabelingWidget->syncToLayer( mRasterLayer );
739
740 if ( provider->dataType( 1 ) == Qgis::DataType::ARGB32
742 {
743 mRasterTransparencyWidget->gboxNoDataValue->setEnabled( false );
744 mRasterTransparencyWidget->gboxCustomTransparency->setEnabled( false );
745 mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
746 }
747
748 // TODO: Wouldn't it be better to just removeWidget() the tabs than delete them? [LS]
751 {
752 if ( mOptsPage_Pyramids )
753 {
754 delete mOptsPage_Pyramids;
755 mOptsPage_Pyramids = nullptr;
756 }
757 }
758
760 {
761 if ( mOptsPage_Histogram )
762 {
763 delete mOptsPage_Histogram;
764 mOptsPage_Histogram = nullptr;
765 delete mHistogramWidget;
766 mHistogramWidget = nullptr;
767 }
768 }
769
770 QgsDebugMsgLevel( QStringLiteral( "populate transparency tab" ), 3 );
771
772 /*
773 * Style tab
774 */
775
776 //set brightness, contrast and gamma
777 QgsBrightnessContrastFilter *brightnessFilter = mRasterLayer->brightnessFilter();
778 if ( brightnessFilter )
779 {
780 mSliderBrightness->setValue( brightnessFilter->brightness() );
781 mSliderContrast->setValue( brightnessFilter->contrast() );
782 mGammaSpinBox->setValue( brightnessFilter->gamma() );
783 }
784
785 // Hue and saturation color control
786 const QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
787 //set hue and saturation controls to current values
788 if ( hueSaturationFilter )
789 {
790 sliderSaturation->setValue( hueSaturationFilter->saturation() );
791 comboGrayscale->setCurrentIndex( ( int ) hueSaturationFilter->grayscaleMode() );
792
793 // Set state of saturation controls based on grayscale mode choice
794 toggleSaturationControls( static_cast<int>( hueSaturationFilter->grayscaleMode() ) );
795
796 // Set state of colorize controls
797 mColorizeCheck->setChecked( hueSaturationFilter->colorizeOn() );
798 btnColorizeColor->setColor( hueSaturationFilter->colorizeColor() );
799 toggleColorizeControls( hueSaturationFilter->colorizeOn() );
800 sliderColorizeStrength->setValue( hueSaturationFilter->colorizeStrength() );
801 mInvertColorsCheck->setChecked( hueSaturationFilter->invertColors() );
802 }
803
804 // Resampling
805 mResamplingUtils.refreshWidgetsFromLayer();
806
807 mRefreshSettingsWidget->syncToLayer();
808 mMapLayerServerPropertiesWidget->sync();
809
810 QgsDebugMsgLevel( QStringLiteral( "populate general tab" ), 3 );
811 /*
812 * General Tab
813 */
814
815 mLayerOrigNameLineEd->setText( mRasterLayer->name() );
816
817 QgsDebugMsgLevel( QStringLiteral( "populate metadata tab" ), 2 );
818 /*
819 * Metadata Tab
820 */
821 //populate the metadata tab's text browser widget with gdal metadata info
822 updateInformationContent();
823
824 mEnableMapTips->setChecked( mRasterLayer->mapTipsEnabled() );
825 mMapTipWidget->setText( mRasterLayer->mapTipTemplate() );
826
827 //WMS print layer
828 QVariant wmsPrintLayer = mRasterLayer->customProperty( QStringLiteral( "WMSPrintLayer" ) );
829 if ( wmsPrintLayer.isValid() )
830 {
831 mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
832 }
833
834 QVariant wmsPublishDataSourceUrl = mRasterLayer->customProperty( QStringLiteral( "WMSPublishDataSourceUrl" ), false );
835 mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
836
837 QVariant wmsBackgroundLayer = mRasterLayer->customProperty( QStringLiteral( "WMSBackgroundLayer" ), false );
838 mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
839
840 mLegendPlaceholderWidget->setLastPathSettingsKey( QStringLiteral( "lastLegendPlaceholderDir" ) );
841 mLegendPlaceholderWidget->setSource( mRasterLayer->legendPlaceholderImage() );
842 mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
843
844 mTemporalWidget->syncToLayer();
845
846 mPropertyCollection = mRasterLayer->pipe()->dataDefinedProperties();
847 updateDataDefinedButtons();
848
849 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
850 {
851 page->syncToLayer( mRasterLayer );
852 }
853}
854
856{
857 if ( mSourceWidget )
858 {
859 const QString newSource = mSourceWidget->sourceUri();
860 if ( newSource != mRasterLayer->source() )
861 {
862 mRasterLayer->setDataSource( newSource, mRasterLayer->name(), mRasterLayer->providerType(), QgsDataProvider::ProviderOptions() );
863 }
864 }
865
866 // Do nothing on "bad" layers
867 if ( !mRasterLayer->isValid() )
868 return;
869
870 // apply all plugin dialogs
871 for ( QgsMapLayerConfigWidget *page : std::as_const( mConfigWidgets ) )
872 {
873 page->apply();
874 }
875
876
877 /*
878 * Legend Tab
879 */
880 mRasterLayer->setLegendPlaceholderImage( mLegendPlaceholderWidget->source() );
881 mLegendConfigEmbeddedWidget->applyToLayer();
882
883 QgsDebugMsgLevel( QStringLiteral( "apply processing symbology tab" ), 3 );
884 /*
885 * Symbology Tab
886 */
887
888 //set whether the layer histogram should be inverted
889 //mRasterLayer->setInvertHistogram( cboxInvertColorMap->isChecked() );
890
891 mRasterLayer->brightnessFilter()->setBrightness( mSliderBrightness->value() );
892 mRasterLayer->brightnessFilter()->setContrast( mSliderContrast->value() );
893 mRasterLayer->brightnessFilter()->setGamma( mGammaSpinBox->value() );
894
895 QgsDebugMsgLevel( QStringLiteral( "processing transparency tab" ), 3 );
896 /*
897 * Transparent Pixel Tab
898 */
899
900 mRasterTransparencyWidget->applyToRasterProvider( mRasterLayer->dataProvider() );
901
902 //set renderer from widget
903 QgsRasterRendererWidget *rendererWidget = dynamic_cast<QgsRasterRendererWidget *>( mRendererStackedWidget->currentWidget() );
904 if ( rendererWidget )
905 {
906 rendererWidget->doComputations();
907
908 mRasterLayer->setRenderer( rendererWidget->renderer() );
909 }
910
911 mBackupCrs = mRasterLayer->crs();
912 mMetadataWidget->acceptMetadata();
913 mMetadataFilled = false;
914
915 //transparency settings
916 QgsRasterRenderer *rasterRenderer = mRasterLayer->renderer();
917 mRasterTransparencyWidget->applyToRasterRenderer( rasterRenderer );
918
919 mLabelingWidget->apply();
920
921 if ( rasterRenderer )
922 {
923 // Sync the layer styling widget
924 mRasterLayer->emitStyleChanged();
925 }
926
927 QgsDebugMsgLevel( QStringLiteral( "processing general tab" ), 3 );
928 /*
929 * General Tab
930 */
931 mRasterLayer->setName( mLayerOrigNameLineEd->text() );
932
933 // set up the scale based layer visibility stuff....
934 mRasterLayer->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
935 mRasterLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
936 mRasterLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
937
938 mRefreshSettingsWidget->saveToLayer();
939 if ( mMapLayerServerPropertiesWidget->save() )
940 mMetadataFilled = true;
941
942 //update the legend pixmap
943 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
944 // pixmapLegend->setScaledContents( true );
945 // pixmapLegend->repaint();
946
947 mResamplingUtils.refreshLayerFromWidgets();
948
949 // Hue and saturation controls
950 QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
951 if ( hueSaturationFilter )
952 {
953 hueSaturationFilter->setSaturation( sliderSaturation->value() );
954 hueSaturationFilter->setGrayscaleMode( ( QgsHueSaturationFilter::GrayscaleMode ) comboGrayscale->currentIndex() );
955 hueSaturationFilter->setColorizeOn( mColorizeCheck->checkState() );
956 hueSaturationFilter->setColorizeColor( btnColorizeColor->color() );
957 hueSaturationFilter->setColorizeStrength( sliderColorizeStrength->value() );
958 hueSaturationFilter->setInvertColors( mInvertColorsCheck->isChecked() );
959 }
960
961 //set the blend mode for the layer
962 mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );
963
964 // Update temporal properties
965 mTemporalWidget->saveTemporalProperties();
966
967 mRasterLayer->setCrs( mCrsSelector->crs() );
968
969 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
970 {
971 mRasterLayer->setCustomProperty( QStringLiteral( "WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
972 }
973
974 mRasterLayer->setCustomProperty( "WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
975 mRasterLayer->setCustomProperty( "WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
976
977 mRasterLayer->pipe()->setDataDefinedProperties( mPropertyCollection );
978
979 mRasterLayer->setMapTipsEnabled( mEnableMapTips->isChecked() );
980 mRasterLayer->setMapTipTemplate( mMapTipWidget->text() );
981
982 // Force a redraw of the legend
983 mRasterLayer->setLegend( QgsMapLayerLegend::defaultRasterLegend( mRasterLayer ) );
984
985 //make sure the layer is redrawn
986 mRasterLayer->triggerRepaint();
987
988 // notify the project we've made a change
990}
991
992void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
993{
994 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
995
996 auto feedback = std::make_unique<QgsRasterBlockFeedback>();
997
998 connect( feedback.get(), &QgsRasterBlockFeedback::progressChanged, mPyramidProgress, &QProgressBar::setValue );
999 //
1000 // Go through the list marking any files that are selected in the listview
1001 // as true so that we can generate pyramids for them.
1002 //
1003 QList<QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
1004 for ( int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1005 {
1006 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1007 //mark to be pyramided
1008 myPyramidList[myCounterInt].setBuild( myItem->isSelected() || myPyramidList[myCounterInt].getExists() );
1009 }
1010
1011 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
1012 QString prefix = provider->name() + "/driverOptions/_pyramids/";
1013 QgsSettings mySettings;
1014 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1015 mySettings.setValue( prefix + "resampling", resamplingMethod );
1016
1017 //
1018 // Ask raster layer to build the pyramids
1019 //
1020
1021 // let the user know we're going to possibly be taking a while
1022 QApplication::setOverrideCursor( Qt::WaitCursor );
1023 QString res = provider->buildPyramids(
1024 myPyramidList,
1025 resamplingMethod,
1026 cbxPyramidsFormat->currentData().value<Qgis::RasterPyramidFormat>(),
1027 QStringList(),
1028 feedback.get()
1029 );
1030 QApplication::restoreOverrideCursor();
1031 mPyramidProgress->setValue( 0 );
1032 buttonBuildPyramids->setEnabled( false );
1033 if ( !res.isNull() )
1034 {
1035 if ( res == QLatin1String( "CANCELED" ) )
1036 {
1037 // user canceled
1038 }
1039 else if ( res == QLatin1String( "ERROR_WRITE_ACCESS" ) )
1040 {
1041 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "Write access denied. Adjust the file permissions and try again." ) );
1042 }
1043 else if ( res == QLatin1String( "ERROR_WRITE_FORMAT" ) )
1044 {
1045 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "The file was not writable. Some formats do not "
1046 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1047 }
1048 else if ( res == QLatin1String( "FAILED_NOT_SUPPORTED" ) )
1049 {
1050 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "Building pyramid overviews is not supported on this type of raster." ) );
1051 }
1052 else if ( res == QLatin1String( "ERROR_JPEG_COMPRESSION" ) )
1053 {
1054 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1055 }
1056 else if ( res == QLatin1String( "ERROR_VIRTUAL" ) )
1057 {
1058 QMessageBox::warning( this, tr( "Building Pyramids" ), tr( "Building pyramid overviews is not supported on this type of raster." ) );
1059 }
1060 }
1061
1062 //
1063 // repopulate the pyramids list
1064 //
1065 lbxPyramidResolutions->clear();
1066 // Need to rebuild list as some or all pyramids may have failed to build
1067 myPyramidList = provider->buildPyramidList();
1068 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
1069 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
1070
1071 for ( const QgsRasterPyramid &pyramid : std::as_const( myPyramidList ) )
1072 {
1073 if ( pyramid.getExists() )
1074 {
1075 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap, QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) + QString::number( pyramid.getYDim() ) ) );
1076 }
1077 else
1078 {
1079 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap, QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) + QString::number( pyramid.getYDim() ) ) );
1080 }
1081 }
1082 //update the legend pixmap
1083 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1084 // pixmapLegend->setScaledContents( true );
1085 // pixmapLegend->repaint();
1086
1087 //populate the metadata tab's text browser widget with gdal metadata info
1088 updateInformationContent();
1089}
1090
1091void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( int index )
1092{
1093 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || !mRasterLayer->renderer() )
1094 {
1095 return;
1096 }
1097
1098 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1099 setRendererWidget( rendererName );
1100}
1101
1102void QgsRasterLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
1103{
1104 QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mCanvas, tr( "Select Transformation" ) );
1105 mRasterLayer->setCrs( crs );
1106 mMetadataWidget->crsChanged();
1107}
1108
1109void QgsRasterLayerProperties::aboutToShowStyleMenu()
1110{
1111 // this should be unified with QgsVectorLayerProperties::aboutToShowStyleMenu()
1112
1113 QMenu *m = qobject_cast<QMenu *>( sender() );
1114
1116 // re-add style manager actions!
1117 m->addSeparator();
1119}
1120
1121void QgsRasterLayerProperties::syncToLayer()
1122{
1123 QgsRasterRenderer *renderer = mRasterLayer->renderer();
1124 if ( renderer )
1125 {
1126 setRendererWidget( renderer->type() );
1127 }
1128 sync();
1129 mRasterLayer->triggerRepaint();
1130}
1131
1133{
1135
1136 if ( !mHistogramWidget )
1137 return;
1138
1139 if ( index == mOptStackedWidget->indexOf( mOptsPage_Histogram ) )
1140 {
1141 mHistogramWidget->setActive( true );
1142 }
1143 else
1144 {
1145 mHistogramWidget->setActive( false );
1146 }
1147
1148 if ( index == mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1149 {
1150 //set the metadata contents (which can be expensive)
1151 updateInformationContent();
1152 }
1153}
1154
1155void QgsRasterLayerProperties::initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsRasterPipe::Property key )
1156{
1157 button->blockSignals( true );
1158 button->init( static_cast<int>( key ), mPropertyCollection, QgsRasterPipe::propertyDefinitions(), nullptr );
1159 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsRasterLayerProperties::updateProperty );
1160 button->registerExpressionContextGenerator( this );
1161 button->blockSignals( false );
1162}
1163
1164void QgsRasterLayerProperties::updateDataDefinedButtons()
1165{
1166 const auto propertyOverrideButtons { findChildren<QgsPropertyOverrideButton *>() };
1167 for ( QgsPropertyOverrideButton *button : propertyOverrideButtons )
1168 {
1169 updateDataDefinedButton( button );
1170 }
1171}
1172
1173void QgsRasterLayerProperties::updateDataDefinedButton( QgsPropertyOverrideButton *button )
1174{
1175 if ( !button )
1176 return;
1177
1178 if ( button->propertyKey() < 0 )
1179 return;
1180
1181 QgsRasterPipe::Property key = static_cast<QgsRasterPipe::Property>( button->propertyKey() );
1182 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
1183}
1184
1185void QgsRasterLayerProperties::updateProperty()
1186{
1187 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1188 QgsRasterPipe::Property key = static_cast<QgsRasterPipe::Property>( button->propertyKey() );
1189 mPropertyCollection.setProperty( key, button->toProperty() );
1190}
1191
1192void QgsRasterLayerProperties::toggleSaturationControls( int grayscaleMode )
1193{
1194 // Enable or disable saturation controls based on choice of grayscale mode
1195 if ( grayscaleMode == 0 )
1196 {
1197 sliderSaturation->setEnabled( true );
1198 spinBoxSaturation->setEnabled( true );
1199 }
1200 else
1201 {
1202 sliderSaturation->setEnabled( false );
1203 spinBoxSaturation->setEnabled( false );
1204 }
1205}
1206
1207void QgsRasterLayerProperties::toggleColorizeControls( bool colorizeEnabled )
1208{
1209 // Enable or disable colorize controls based on checkbox
1210 btnColorizeColor->setEnabled( colorizeEnabled );
1211 sliderColorizeStrength->setEnabled( colorizeEnabled );
1212 spinColorizeStrength->setEnabled( colorizeEnabled );
1213}
1214
1215
1216QLinearGradient QgsRasterLayerProperties::redGradient()
1217{
1218 //define a gradient
1219 // TODO change this to actual polygon dims
1220 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1221 myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
1222 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
1223 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
1224 return myGradient;
1225}
1226QLinearGradient QgsRasterLayerProperties::greenGradient()
1227{
1228 //define a gradient
1229 // TODO change this to actual polygon dims
1230 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1231 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
1232 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
1233 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
1234 return myGradient;
1235}
1236QLinearGradient QgsRasterLayerProperties::blueGradient()
1237{
1238 //define a gradient
1239 // TODO change this to actual polygon dims
1240 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1241 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
1242 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
1243 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
1244 return myGradient;
1245}
1246QLinearGradient QgsRasterLayerProperties::grayGradient()
1247{
1248 //define a gradient
1249 // TODO change this to actual polygon dims
1250 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1251 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
1252 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
1253 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
1254 return myGradient;
1255}
1256QLinearGradient QgsRasterLayerProperties::highlightGradient()
1257{
1258 //define another gradient for the highlight
1259 // TODO change this to actual polygon dims
1260 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1261 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
1262 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
1263 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
1264 return myGradient;
1265}
1266
1267//
1268//
1269// Next four methods for saving and restoring qml style state
1270//
1271//
1272
1277
1278void QgsRasterLayerProperties::restoreWindowModality()
1279{
1280 hide();
1281 setModal( true );
1282 show();
1283 raise();
1284 activateWindow();
1285}
1286
1287void QgsRasterLayerProperties::toggleBuildPyramidsButton()
1288{
1289 if ( lbxPyramidResolutions->selectedItems().empty() )
1290 {
1291 buttonBuildPyramids->setEnabled( false );
1292 }
1293 else
1294 {
1295 buttonBuildPyramids->setEnabled( true );
1296 }
1297}
1298
1299void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
1300{
1301 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
1302 mSliderBrightness->setValue( 0 );
1303 mSliderContrast->setValue( 0 );
1304 mGammaSpinBox->setValue( 1.0 );
1305 sliderSaturation->setValue( 0 );
1306 comboGrayscale->setCurrentIndex( ( int ) QgsHueSaturationFilter::GrayscaleOff );
1307 mColorizeCheck->setChecked( false );
1308 sliderColorizeStrength->setValue( 100 );
1309 mInvertColorsCheck->setChecked( false );
1310}
1311
1312bool QgsRasterLayerProperties::rasterIsMultiBandColor()
1313{
1314 return mRasterLayer && nullptr != dynamic_cast<QgsMultiBandColorRenderer *>( mRasterLayer->renderer() );
1315}
1316
1317void QgsRasterLayerProperties::updateInformationContent()
1318{
1320 // Inject the stylesheet
1321 const QString html { mRasterLayer->htmlMetadata().replace( QLatin1String( "<head>" ), QStringLiteral( R"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
1322 mMetadataViewer->setHtml( html );
1323 mMetadataFilled = true;
1324}
1325
1327{
1328 // Give the user a chance to save the raster attribute table edits.
1329 if ( mRasterAttributeTableWidget && mRasterAttributeTableWidget->isDirty() )
1330 {
1331 mRasterAttributeTableWidget->setEditable( false, false );
1332 }
1334
1335 if ( mBackupCrs != mRasterLayer->crs() )
1336 mRasterLayer->setCrs( mBackupCrs );
1337}
1338
1339void QgsRasterLayerProperties::showHelp()
1340{
1341 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
1342
1343 if ( helpPage.isValid() )
1344 {
1345 QgsHelp::openHelp( helpPage.toString() );
1346 }
1347 else
1348 {
1349 QgsHelp::openHelp( QStringLiteral( "working_with_raster/raster_properties.html" ) );
1350 }
1351}
1352
1353void QgsRasterLayerProperties::updateGammaSpinBox( int value )
1354{
1355 whileBlocking( mGammaSpinBox )->setValue( value / 100.0 );
1356}
1357
1358void QgsRasterLayerProperties::updateGammaSlider( double value )
1359{
1360 whileBlocking( mSliderGamma )->setValue( value * 100 );
1361}
1362
1363
1364bool QgsRasterLayerProperties::eventFilter( QObject *obj, QEvent *ev )
1365{
1366 // If the map tip preview container is resized, resize the map tip
1367 if ( obj == mMapTipPreviewContainer && ev->type() == QEvent::Resize )
1368 {
1369 resizeMapTip();
1370 }
1371 return QgsOptionsDialogBase::eventFilter( obj, ev );
1372}
1373
1374void QgsRasterLayerProperties::initMapTipPreview()
1375{
1376 // HTML editor and preview are in a splitter. By default, the editor takes 2/3 of the space
1377 mMapTipSplitter->setSizes( { 400, 200 } );
1378 // Event filter is used to resize the map tip when the container is resized
1379 mMapTipPreviewContainer->installEventFilter( this );
1380
1381 // Note: there's quite a bit of overlap between this and the code in QgsMapTip::showMapTip
1382 // Create the WebView
1383 mMapTipPreview = new QgsWebView( mMapTipPreviewContainer );
1384
1385#if WITH_QTWEBKIT
1386 mMapTipPreview->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks ); //Handle link clicks by yourself
1387 mMapTipPreview->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
1388 connect( mMapTipPreview, &QWebView::loadFinished, this, &QgsRasterLayerProperties::resizeMapTip );
1389#endif
1390
1391 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
1392 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
1393 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
1394
1395 // Disable scrollbars, avoid random resizing issues
1396 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
1397 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
1398
1399
1400 // Update the map tip preview when the expression or the map tip template changes
1401 connect( mMapTipWidget, &QgsCodeEditorHTML::textChanged, this, &QgsRasterLayerProperties::updateMapTipPreview );
1402}
1403
1404void QgsRasterLayerProperties::updateMapTipPreview()
1405{
1406 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1407 const QString htmlContent = QgsMapTip::rasterMapTipPreviewText( mRasterLayer, mCanvas, mMapTipWidget->text() );
1408 mMapTipPreview->setHtml( htmlContent );
1409}
1410
1411void QgsRasterLayerProperties::resizeMapTip()
1412{
1413 // Ensure the map tip is not bigger than the container
1414 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1415#if WITH_QTWEBKIT
1416 // Get the content size
1417 const QWebElement container = mMapTipPreview->page()->mainFrame()->findFirstElement(
1418 QStringLiteral( "#QgsWebViewContainer" )
1419 );
1420 const int width = container.geometry().width();
1421 const int height = container.geometry().height();
1422 mMapTipPreview->resize( width, height );
1423
1424 // Move the map tip to the center of the container
1425 mMapTipPreview->move( ( mMapTipPreviewContainer->width() - mMapTipPreview->width() ) / 2, ( mMapTipPreviewContainer->height() - mMapTipPreview->height() ) / 2 );
1426
1427#else
1428 mMapTipPreview->adjustSize();
1429#endif
1430}
@ BuildPyramids
Supports building of pyramids (overviews) (since QGIS 3.38 – this is a replacement for RasterInterfac...
@ SingleBandColorData
Single band containing color data.
RasterPyramidFormat
Raster pyramid formats.
Definition qgis.h:4627
@ 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...
@ BuildPyramids
Supports building of pyramids (overviews) (Deprecated since QGIS 3.38 – use RasterProviderCapability:...
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
@ 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.
@ 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.
@ WebBrowser
StyleSheet for embedded browsers (QtWebKit), supports full standard CSS.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
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...
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:120
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.
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.
virtual void syncToLayer(QgsMapLayer *layer)
Reset to original (vector layer) values.
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:76
QString name
Definition qgsmaplayer.h:80
QString source() const
Returns the source for the layer.
Q_INVOKABLE QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
QString providerType() const
Returns the provider type (provider key) for this 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:83
QString legendPlaceholderImage() const
Returns path to the placeholder image or an empty string if a generated legend is shown.
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
void setDataSource(const QString &dataSource, const QString &baseName=QString(), const QString &provider=QString(), bool loadDefaultStyleFlag=false)
Updates the data source of the layer.
void triggerRepaint(bool deferredUpdate=false)
Will advise the map canvas (and any other interested party) that this layer requires to be repainted.
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
void rendererChanged()
Signal emitted when renderer is changed.
void setScaleBasedVisibility(bool enabled)
Sets whether scale based visibility is enabled for the layer.
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.
void setLegendPlaceholderImage(const QString &imgPath)
Set placeholder image for legend.
void setMapTipsEnabled(bool enabled)
Enable or disable map tips for this layer.
double minimumScale() const
Returns the minimum map scale (i.e.
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
void setMapTipTemplate(const QString &mapTipTemplate)
The mapTip is a pretty, html representation for feature information.
bool mapTipsEnabled
Definition qgsmaplayer.h:90
void setLegend(QgsMapLayerLegend *legend)
Assign a legend controller to the map layer.
double maximumScale() const
Returns the maximum map scale (i.e.
QString mapTipTemplate
Definition qgsmaplayer.h:89
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
The QgsMapSettings class contains configuration for rendering of the map.
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.
void deactivated()
Emitted when 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.
void setDirty(bool b=true)
Flag the project as dirty (modified).
void crsChanged(const QgsCoordinateReferenceSystem &crs)
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.
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 dataType(int bandNo) const override=0
Returns data type for the band specified by number.
virtual Qgis::RasterProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
static QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns a list of pyramid resampling method name and label pairs for given provider.
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.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
Master widget for configuration of labeling of a raster layer.
void apply() override
Saves the labeling configuration and immediately updates the map canvas to reflect the changes.
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.
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.
@ 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.
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 setNodataColor(const QColor &color)
Sets the color to use for shading nodata pixels.
static QgsRasterRendererWidget * create(QgsRasterLayer *layer, const QgsRectangle &extent)
Widget creation function (use by the renderer registry)
Widget to control a layers transparency and related options.
void applyToRasterRenderer(QgsRasterRenderer *renderer) SIP_SKIP
Applies widget settings to a raster renderer.
void syncToLayer()
Sync the widget state to the layer set for the widget.
void applyToRasterProvider(QgsRasterDataProvider *provider) SIP_SKIP
Applies widget settings to a raster provider.
A rectangle specified with double values.
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
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6123
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:41
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.
Registry for raster renderer entries.
QgsRasterRendererWidgetCreateFunc widgetCreateFunction