QGIS API Documentation 3.36.0-Maidenhead (09951dc0acf)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 "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
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 {
999 QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
1000 for ( int myListRunner = 0; myListRunner < mRasterTransparencyWidget->tableTransparency->rowCount(); myListRunner++ )
1001 {
1002 myTransparentPixel.red = transparencyCellValue( myListRunner, 0 );
1003 myTransparentPixel.green = transparencyCellValue( myListRunner, 1 );
1004 myTransparentPixel.blue = transparencyCellValue( myListRunner, 2 );
1005 myTransparentPixel.percentTransparent = transparencyCellValue( myListRunner, 3 );
1006 myTransparentThreeValuePixelList.append( myTransparentPixel );
1007 }
1008 rasterTransparency->setTransparentThreeValuePixelList( myTransparentThreeValuePixelList );
1009 }
1010 else if ( mRasterTransparencyWidget->tableTransparency->columnCount() == 3 )
1011 {
1013 QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
1014 for ( int myListRunner = 0; myListRunner < mRasterTransparencyWidget->tableTransparency->rowCount(); myListRunner++ )
1015 {
1016 myTransparentPixel.min = transparencyCellValue( myListRunner, 0 );
1017 myTransparentPixel.max = transparencyCellValue( myListRunner, 1 );
1018 myTransparentPixel.percentTransparent = transparencyCellValue( myListRunner, 2 );
1019
1020 myTransparentSingleValuePixelList.append( myTransparentPixel );
1021 }
1022 rasterTransparency->setTransparentSingleValuePixelList( myTransparentSingleValuePixelList );
1023 }
1024
1025 rasterRenderer->setRasterTransparency( rasterTransparency );
1026
1027 // Sync the layer styling widget
1028 mRasterLayer->emitStyleChanged();
1029
1030 //set global transparency
1031 rasterRenderer->setOpacity( mRasterTransparencyWidget->mOpacityWidget->opacity() );
1032 }
1033
1034 QgsDebugMsgLevel( QStringLiteral( "processing general tab" ), 3 );
1035 /*
1036 * General Tab
1037 */
1038 mRasterLayer->setName( mLayerOrigNameLineEd->text() );
1039
1040 // set up the scale based layer visibility stuff....
1041 mRasterLayer->setScaleBasedVisibility( chkUseScaleDependentRendering->isChecked() );
1042 mRasterLayer->setMinimumScale( mScaleRangeWidget->minimumScale() );
1043 mRasterLayer->setMaximumScale( mScaleRangeWidget->maximumScale() );
1044
1045 mRefreshSettingsWidget->saveToLayer();
1046
1047 //update the legend pixmap
1048 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1049 // pixmapLegend->setScaledContents( true );
1050 // pixmapLegend->repaint();
1051
1052 mResamplingUtils.refreshLayerFromWidgets();
1053
1054 // Hue and saturation controls
1055 QgsHueSaturationFilter *hueSaturationFilter = mRasterLayer->hueSaturationFilter();
1056 if ( hueSaturationFilter )
1057 {
1058 hueSaturationFilter->setSaturation( sliderSaturation->value() );
1059 hueSaturationFilter->setGrayscaleMode( ( QgsHueSaturationFilter::GrayscaleMode ) comboGrayscale->currentIndex() );
1060 hueSaturationFilter->setColorizeOn( mColorizeCheck->checkState() );
1061 hueSaturationFilter->setColorizeColor( btnColorizeColor->color() );
1062 hueSaturationFilter->setColorizeStrength( sliderColorizeStrength->value() );
1063 hueSaturationFilter->setInvertColors( mInvertColorsCheck->isChecked() );
1064 }
1065
1066 //set the blend mode for the layer
1067 mRasterLayer->setBlendMode( mBlendModeComboBox->blendMode() );
1068
1069 // Update temporal properties
1070 mTemporalWidget->saveTemporalProperties();
1071
1072 mRasterLayer->setCrs( mCrsSelector->crs() );
1073
1074 if ( mRasterLayer->shortName() != mLayerShortNameLineEdit->text() )
1075 mMetadataFilled = false;
1076 mRasterLayer->setShortName( mLayerShortNameLineEdit->text() );
1077
1078 if ( mRasterLayer->title() != mLayerTitleLineEdit->text() )
1079 mMetadataFilled = false;
1080 mRasterLayer->setTitle( mLayerTitleLineEdit->text() );
1081
1082 if ( mRasterLayer->abstract() != mLayerAbstractTextEdit->toPlainText() )
1083 mMetadataFilled = false;
1084 mRasterLayer->setAbstract( mLayerAbstractTextEdit->toPlainText() );
1085
1086 if ( mRasterLayer->keywordList() != mLayerKeywordListLineEdit->text() )
1087 mMetadataFilled = false;
1088 mRasterLayer->setKeywordList( mLayerKeywordListLineEdit->text() );
1089
1090 if ( mRasterLayer->dataUrl() != mLayerDataUrlLineEdit->text() )
1091 mMetadataFilled = false;
1092 mRasterLayer->setDataUrl( mLayerDataUrlLineEdit->text() );
1093
1094 if ( mRasterLayer->dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
1095 mMetadataFilled = false;
1096 mRasterLayer->setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
1097
1098 //layer attribution
1099 if ( mRasterLayer->attribution() != mLayerAttributionLineEdit->text() )
1100 mMetadataFilled = false;
1101 mRasterLayer->setAttribution( mLayerAttributionLineEdit->text() );
1102
1103 if ( mRasterLayer->attributionUrl() != mLayerAttributionUrlLineEdit->text() )
1104 mMetadataFilled = false;
1105 mRasterLayer->setAttributionUrl( mLayerAttributionUrlLineEdit->text() );
1106
1107 // Metadata URL
1108 QList<QgsMapLayerServerProperties::MetadataUrl> metaUrls;
1109 for ( int row = 0; row < mMetadataUrlModel->rowCount() ; row++ )
1110 {
1112 metaUrl.url = mMetadataUrlModel->item( row, 0 )->text();
1113 metaUrl.type = mMetadataUrlModel->item( row, 1 )->text();
1114 metaUrl.format = mMetadataUrlModel->item( row, 2 )->text();
1115 metaUrls.append( metaUrl );
1116 mMetadataFilled = false;
1117 }
1118 mRasterLayer->serverProperties()->setMetadataUrls( metaUrls );
1119
1120 if ( mRasterLayer->legendUrl() != mLayerLegendUrlLineEdit->text() )
1121 mMetadataFilled = false;
1122 mRasterLayer->setLegendUrl( mLayerLegendUrlLineEdit->text() );
1123
1124 if ( mRasterLayer->legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
1125 mMetadataFilled = false;
1126 mRasterLayer->setLegendUrlFormat( mLayerLegendUrlFormatComboBox->currentText() );
1127
1128 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
1129 {
1130 mRasterLayer->setCustomProperty( QStringLiteral( "WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
1131 }
1132
1133 mRasterLayer->setCustomProperty( "WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
1134 mRasterLayer->setCustomProperty( "WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
1135
1136 mRasterLayer->pipe()->setDataDefinedProperties( mPropertyCollection );
1137
1138 mRasterLayer->setMapTipsEnabled( mEnableMapTips->isChecked() );
1139 mRasterLayer->setMapTipTemplate( mMapTipWidget->text() );
1140
1141 // Force a redraw of the legend
1142 mRasterLayer->setLegend( QgsMapLayerLegend::defaultRasterLegend( mRasterLayer ) );
1143
1144 //make sure the layer is redrawn
1145 mRasterLayer->triggerRepaint();
1146
1147 // notify the project we've made a change
1148 QgsProject::instance()->setDirty( true );
1149}
1150
1151void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
1152{
1153 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1154
1155 std::unique_ptr< QgsRasterBlockFeedback > feedback( new QgsRasterBlockFeedback() );
1156
1157 connect( feedback.get(), &QgsRasterBlockFeedback::progressChanged, mPyramidProgress, &QProgressBar::setValue );
1158 //
1159 // Go through the list marking any files that are selected in the listview
1160 // as true so that we can generate pyramids for them.
1161 //
1162 QList< QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
1163 for ( int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1164 {
1165 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1166 //mark to be pyramided
1167 myPyramidList[myCounterInt].setBuild( myItem->isSelected() || myPyramidList[myCounterInt].getExists() );
1168 }
1169
1170 // keep it in sync with qgsrasterpyramidsoptionwidget.cpp
1171 QString prefix = provider->name() + "/driverOptions/_pyramids/";
1172 QgsSettings mySettings;
1173 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1174 mySettings.setValue( prefix + "resampling", resamplingMethod );
1175
1176 //
1177 // Ask raster layer to build the pyramids
1178 //
1179
1180 // let the user know we're going to possibly be taking a while
1181 QApplication::setOverrideCursor( Qt::WaitCursor );
1182 QString res = provider->buildPyramids(
1183 myPyramidList,
1184 resamplingMethod,
1185 cbxPyramidsFormat->currentData().value< Qgis::RasterPyramidFormat >(),
1186 QStringList(),
1187 feedback.get() );
1188 QApplication::restoreOverrideCursor();
1189 mPyramidProgress->setValue( 0 );
1190 buttonBuildPyramids->setEnabled( false );
1191 if ( !res.isNull() )
1192 {
1193 if ( res == QLatin1String( "CANCELED" ) )
1194 {
1195 // user canceled
1196 }
1197 else if ( res == QLatin1String( "ERROR_WRITE_ACCESS" ) )
1198 {
1199 QMessageBox::warning( this, tr( "Building Pyramids" ),
1200 tr( "Write access denied. Adjust the file permissions and try again." ) );
1201 }
1202 else if ( res == QLatin1String( "ERROR_WRITE_FORMAT" ) )
1203 {
1204 QMessageBox::warning( this, tr( "Building Pyramids" ),
1205 tr( "The file was not writable. Some formats do not "
1206 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1207 }
1208 else if ( res == QLatin1String( "FAILED_NOT_SUPPORTED" ) )
1209 {
1210 QMessageBox::warning( this, tr( "Building Pyramids" ),
1211 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1212 }
1213 else if ( res == QLatin1String( "ERROR_JPEG_COMPRESSION" ) )
1214 {
1215 QMessageBox::warning( this, tr( "Building Pyramids" ),
1216 tr( "Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1217 }
1218 else if ( res == QLatin1String( "ERROR_VIRTUAL" ) )
1219 {
1220 QMessageBox::warning( this, tr( "Building Pyramids" ),
1221 tr( "Building pyramid overviews is not supported on this type of raster." ) );
1222 }
1223
1224 }
1225
1226 //
1227 // repopulate the pyramids list
1228 //
1229 lbxPyramidResolutions->clear();
1230 // Need to rebuild list as some or all pyramids may have failed to build
1231 myPyramidList = provider->buildPyramidList();
1232 QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.svg" ) );
1233 QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.svg" ) );
1234
1235 for ( const QgsRasterPyramid &pyramid : std::as_const( myPyramidList ) )
1236 {
1237 if ( pyramid.getExists() )
1238 {
1239 lbxPyramidResolutions->addItem( new QListWidgetItem( myPyramidPixmap,
1240 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1241 QString::number( pyramid.getYDim() ) ) );
1242 }
1243 else
1244 {
1245 lbxPyramidResolutions->addItem( new QListWidgetItem( myNoPyramidPixmap,
1246 QString::number( pyramid.getXDim() ) + QStringLiteral( " x " ) +
1247 QString::number( pyramid.getYDim() ) ) );
1248 }
1249 }
1250 //update the legend pixmap
1251 // pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
1252 // pixmapLegend->setScaledContents( true );
1253 // pixmapLegend->repaint();
1254
1255 //populate the metadata tab's text browser widget with gdal metadata info
1256 updateInformationContent();
1257}
1258
1259void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged( int index )
1260{
1261 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
1262 {
1263 return;
1264 }
1265
1266 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1267 setRendererWidget( rendererName );
1268}
1269
1270void QgsRasterLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs )
1271{
1272 QgsDatumTransformDialog::run( crs, QgsProject::instance()->crs(), this, mCanvas, tr( "Select Transformation" ) );
1273 mRasterLayer->setCrs( crs );
1274 mMetadataWidget->crsChanged();
1275}
1276
1277void QgsRasterLayerProperties::setTransparencyCell( int row, int column, double value )
1278{
1279 QgsDebugMsgLevel( QStringLiteral( "value = %1" ).arg( value, 0, 'g', 17 ), 3 );
1280 QgsRasterDataProvider *provider = mRasterLayer->dataProvider();
1281 if ( !provider ) return;
1282
1283 QgsRasterRenderer *renderer = mRendererWidget->renderer();
1284 if ( !renderer ) return;
1285 int nBands = renderer->usesBands().size();
1286
1287 QLineEdit *lineEdit = new QLineEdit();
1288 lineEdit->setFrame( false ); // frame looks bad in table
1289 // Without margins row selection is not displayed (important for delete row)
1290 lineEdit->setContentsMargins( 1, 1, 1, 1 );
1291
1292 if ( column == mRasterTransparencyWidget->tableTransparency->columnCount() - 1 )
1293 {
1294 // transparency
1295 // Who needs transparency as floating point?
1296 lineEdit->setValidator( new QIntValidator( nullptr ) );
1297 lineEdit->setText( QString::number( static_cast<int>( value ) ) );
1298 }
1299 else
1300 {
1301 // value
1302 QString valueString;
1303 switch ( provider->sourceDataType( 1 ) )
1304 {
1307 lineEdit->setValidator( new QgsDoubleValidator( nullptr ) );
1308 if ( !std::isnan( value ) )
1309 {
1310 double v = QgsRasterBlock::printValue( value ).toDouble();
1311 valueString = QLocale().toString( v, 'g' ) ;
1312 }
1313 break;
1314 default:
1315 lineEdit->setValidator( new QIntValidator( nullptr ) );
1316 if ( !std::isnan( value ) )
1317 {
1318 valueString = QLocale().toString( static_cast<int>( value ) );
1319 }
1320 break;
1321 }
1322 lineEdit->setText( valueString );
1323 }
1324 mRasterTransparencyWidget->tableTransparency->setCellWidget( row, column, lineEdit );
1325 adjustTransparencyCellWidth( row, column );
1326
1327 if ( nBands == 1 && ( column == 0 || column == 1 ) )
1328 {
1329 connect( lineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerProperties::transparencyCellTextEdited );
1330 }
1331 mRasterTransparencyWidget->tableTransparency->resizeColumnsToContents();
1332}
1333
1334void QgsRasterLayerProperties::setTransparencyCellValue( int row, int column, double value )
1335{
1336 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1337 if ( !lineEdit ) return;
1338 double v = QgsRasterBlock::printValue( value ).toDouble();
1339 lineEdit->setText( QLocale().toString( v, 'g' ) );
1340 lineEdit->adjustSize();
1341 adjustTransparencyCellWidth( row, column );
1342 mRasterTransparencyWidget->tableTransparency->resizeColumnsToContents();
1343}
1344
1345double QgsRasterLayerProperties::transparencyCellValue( int row, int column )
1346{
1347 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1348 if ( !lineEdit || lineEdit->text().isEmpty() )
1349 {
1350 return std::numeric_limits<double>::quiet_NaN();
1351 }
1352 return QLocale().toDouble( lineEdit->text() );
1353}
1354
1355void QgsRasterLayerProperties::adjustTransparencyCellWidth( int row, int column )
1356{
1357 QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, column ) );
1358 if ( !lineEdit ) return;
1359
1360 int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
1361 width = std::max( width, mRasterTransparencyWidget->tableTransparency->columnWidth( column ) );
1362
1363 lineEdit->setFixedWidth( width );
1364}
1365
1366void QgsRasterLayerProperties::transparencyCellTextEdited( const QString &text )
1367{
1368 Q_UNUSED( text )
1369 QgsDebugMsgLevel( QStringLiteral( "text = %1" ).arg( text ), 3 );
1370 QgsRasterRenderer *renderer = mRendererWidget->renderer();
1371 if ( !renderer )
1372 {
1373 return;
1374 }
1375 int nBands = renderer->usesBands().size();
1376 if ( nBands == 1 )
1377 {
1378 QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
1379 if ( !lineEdit ) return;
1380 int row = -1;
1381 int column = -1;
1382 for ( int r = 0; r < mRasterTransparencyWidget->tableTransparency->rowCount(); r++ )
1383 {
1384 for ( int c = 0; c < mRasterTransparencyWidget->tableTransparency->columnCount(); c++ )
1385 {
1386 if ( mRasterTransparencyWidget->tableTransparency->cellWidget( r, c ) == sender() )
1387 {
1388 row = r;
1389 column = c;
1390 break;
1391 }
1392 }
1393 if ( row != -1 ) break;
1394 }
1395 QgsDebugMsgLevel( QStringLiteral( "row = %1 column =%2" ).arg( row ).arg( column ), 3 );
1396
1397 if ( column == 0 )
1398 {
1399 QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mRasterTransparencyWidget->tableTransparency->cellWidget( row, 1 ) );
1400 if ( !toLineEdit ) return;
1401 bool toChanged = mTransparencyToEdited.value( row );
1402 QgsDebugMsgLevel( QStringLiteral( "toChanged = %1" ).arg( toChanged ), 3 );
1403 if ( !toChanged )
1404 {
1405 toLineEdit->setText( lineEdit->text() );
1406 }
1407 }
1408 else if ( column == 1 )
1409 {
1410 setTransparencyToEdited( row );
1411 }
1412 }
1413}
1414
1415void QgsRasterLayerProperties::aboutToShowStyleMenu()
1416{
1417 // this should be unified with QgsVectorLayerProperties::aboutToShowStyleMenu()
1418
1419 QMenu *m = qobject_cast<QMenu *>( sender() );
1420
1422 // re-add style manager actions!
1423 m->addSeparator();
1425}
1426
1427void QgsRasterLayerProperties::syncToLayer()
1428{
1429 QgsRasterRenderer *renderer = mRasterLayer->renderer();
1430 if ( renderer )
1431 {
1432 setRendererWidget( renderer->type() );
1433 }
1434 sync();
1435 mRasterLayer->triggerRepaint();
1436}
1437
1438void QgsRasterLayerProperties::setTransparencyToEdited( int row )
1439{
1440 if ( row >= mTransparencyToEdited.size() )
1441 {
1442 mTransparencyToEdited.resize( row + 1 );
1443 }
1444 mTransparencyToEdited[row] = true;
1445}
1446
1448{
1450
1451 if ( !mHistogramWidget )
1452 return;
1453
1454 if ( index == mOptStackedWidget->indexOf( mOptsPage_Histogram ) )
1455 {
1456 mHistogramWidget->setActive( true );
1457 }
1458 else
1459 {
1460 mHistogramWidget->setActive( false );
1461 }
1462
1463 if ( index == mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1464 {
1465 //set the metadata contents (which can be expensive)
1466 updateInformationContent();
1467 }
1468}
1469
1470void QgsRasterLayerProperties::initializeDataDefinedButton( QgsPropertyOverrideButton *button, QgsRasterPipe::Property key )
1471{
1472 button->blockSignals( true );
1473 button->init( static_cast< int >( key ), mPropertyCollection, QgsRasterPipe::propertyDefinitions(), nullptr );
1474 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsRasterLayerProperties::updateProperty );
1475 button->registerExpressionContextGenerator( this );
1476 button->blockSignals( false );
1477}
1478
1479void QgsRasterLayerProperties::updateDataDefinedButtons()
1480{
1481 const auto propertyOverrideButtons { findChildren< QgsPropertyOverrideButton * >() };
1482 for ( QgsPropertyOverrideButton *button : propertyOverrideButtons )
1483 {
1484 updateDataDefinedButton( button );
1485 }
1486}
1487
1488void QgsRasterLayerProperties::updateDataDefinedButton( QgsPropertyOverrideButton *button )
1489{
1490 if ( !button )
1491 return;
1492
1493 if ( button->propertyKey() < 0 )
1494 return;
1495
1496 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1497 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
1498}
1499
1500void QgsRasterLayerProperties::updateProperty()
1501{
1502 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1503 QgsRasterPipe::Property key = static_cast< QgsRasterPipe::Property >( button->propertyKey() );
1504 mPropertyCollection.setProperty( key, button->toProperty() );
1505}
1506
1507void QgsRasterLayerProperties::toggleSaturationControls( int grayscaleMode )
1508{
1509 // Enable or disable saturation controls based on choice of grayscale mode
1510 if ( grayscaleMode == 0 )
1511 {
1512 sliderSaturation->setEnabled( true );
1513 spinBoxSaturation->setEnabled( true );
1514 }
1515 else
1516 {
1517 sliderSaturation->setEnabled( false );
1518 spinBoxSaturation->setEnabled( false );
1519 }
1520}
1521
1522void QgsRasterLayerProperties::toggleColorizeControls( bool colorizeEnabled )
1523{
1524 // Enable or disable colorize controls based on checkbox
1525 btnColorizeColor->setEnabled( colorizeEnabled );
1526 sliderColorizeStrength->setEnabled( colorizeEnabled );
1527 spinColorizeStrength->setEnabled( colorizeEnabled );
1528}
1529
1530
1531QLinearGradient QgsRasterLayerProperties::redGradient()
1532{
1533 //define a gradient
1534 // TODO change this to actual polygon dims
1535 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1536 myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
1537 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
1538 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
1539 return myGradient;
1540}
1541QLinearGradient QgsRasterLayerProperties::greenGradient()
1542{
1543 //define a gradient
1544 // TODO change this to actual polygon dims
1545 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1546 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
1547 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
1548 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
1549 return myGradient;
1550}
1551QLinearGradient QgsRasterLayerProperties::blueGradient()
1552{
1553 //define a gradient
1554 // TODO change this to actual polygon dims
1555 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1556 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
1557 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
1558 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
1559 return myGradient;
1560}
1561QLinearGradient QgsRasterLayerProperties::grayGradient()
1562{
1563 //define a gradient
1564 // TODO change this to actual polygon dims
1565 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1566 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
1567 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
1568 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
1569 return myGradient;
1570}
1571QLinearGradient QgsRasterLayerProperties::highlightGradient()
1572{
1573 //define another gradient for the highlight
1574 // TODO change this to actual polygon dims
1575 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
1576 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
1577 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
1578 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
1579 return myGradient;
1580}
1581
1582void QgsRasterLayerProperties::addMetadataUrl()
1583{
1584 const int row = mMetadataUrlModel->rowCount();
1585 mMetadataUrlModel->setItem( row, 0, new QStandardItem( QLatin1String() ) );
1586 mMetadataUrlModel->setItem( row, 1, new QStandardItem( QLatin1String() ) );
1587 mMetadataUrlModel->setItem( row, 2, new QStandardItem( QLatin1String() ) );
1588}
1589
1590void QgsRasterLayerProperties::removeSelectedMetadataUrl()
1591{
1592 const QModelIndexList selectedRows = tableViewMetadataUrl->selectionModel()->selectedRows();
1593 if ( selectedRows.empty() )
1594 return;
1595 mMetadataUrlModel->removeRow( selectedRows[0].row() );
1596}
1597
1598
1599//
1600//
1601// Next four methods for saving and restoring qml style state
1602//
1603//
1604
1609
1610void QgsRasterLayerProperties::restoreWindowModality()
1611{
1612 hide();
1613 setModal( true );
1614 show();
1615 raise();
1616 activateWindow();
1617}
1618
1619void QgsRasterLayerProperties::toggleBuildPyramidsButton()
1620{
1621 if ( lbxPyramidResolutions->selectedItems().empty() )
1622 {
1623 buttonBuildPyramids->setEnabled( false );
1624 }
1625 else
1626 {
1627 buttonBuildPyramids->setEnabled( true );
1628 }
1629}
1630
1631void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
1632{
1633 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
1634 mSliderBrightness->setValue( 0 );
1635 mSliderContrast->setValue( 0 );
1636 mGammaSpinBox->setValue( 1.0 );
1637 sliderSaturation->setValue( 0 );
1638 comboGrayscale->setCurrentIndex( ( int ) QgsHueSaturationFilter::GrayscaleOff );
1639 mColorizeCheck->setChecked( false );
1640 sliderColorizeStrength->setValue( 100 );
1641 mInvertColorsCheck->setChecked( false );
1642}
1643
1644bool QgsRasterLayerProperties::rasterIsMultiBandColor()
1645{
1646 return mRasterLayer && nullptr != dynamic_cast<QgsMultiBandColorRenderer *>( mRasterLayer->renderer() );
1647}
1648
1649void QgsRasterLayerProperties::updateInformationContent()
1650{
1652 // Inject the stylesheet
1653 const QString html { mRasterLayer->htmlMetadata().replace( QLatin1String( "<head>" ), QStringLiteral( R"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
1654 mMetadataViewer->setHtml( html );
1655 mMetadataFilled = true;
1656}
1657
1659{
1660 // Give the user a chance to save the raster attribute table edits.
1661 if ( mRasterAttributeTableWidget && mRasterAttributeTableWidget->isDirty() )
1662 {
1663 mRasterAttributeTableWidget->setEditable( false, false );
1664 }
1666
1667 if ( mBackupCrs != mRasterLayer->crs() )
1668 mRasterLayer->setCrs( mBackupCrs );
1669}
1670
1671void QgsRasterLayerProperties::showHelp()
1672{
1673 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property( "helpPage" );
1674
1675 if ( helpPage.isValid() )
1676 {
1677 QgsHelp::openHelp( helpPage.toString() );
1678 }
1679 else
1680 {
1681 QgsHelp::openHelp( QStringLiteral( "working_with_raster/raster_properties.html" ) );
1682 }
1683}
1684
1685void QgsRasterLayerProperties::updateGammaSpinBox( int value )
1686{
1687 whileBlocking( mGammaSpinBox )->setValue( value / 100.0 );
1688}
1689
1690void QgsRasterLayerProperties::updateGammaSlider( double value )
1691{
1692 whileBlocking( mSliderGamma )->setValue( value * 100 );
1693}
1694
1695
1696bool QgsRasterLayerProperties::eventFilter( QObject *obj, QEvent *ev )
1697{
1698 // If the map tip preview container is resized, resize the map tip
1699 if ( obj == mMapTipPreviewContainer && ev->type() == QEvent::Resize )
1700 {
1701 resizeMapTip();
1702 }
1703 return QgsOptionsDialogBase::eventFilter( obj, ev );
1704}
1705
1706void QgsRasterLayerProperties::initMapTipPreview()
1707{
1708 // HTML editor and preview are in a splitter. By default, the editor takes 2/3 of the space
1709 mMapTipSplitter->setSizes( { 400, 200 } );
1710 // Event filter is used to resize the map tip when the container is resized
1711 mMapTipPreviewContainer->installEventFilter( this );
1712
1713 // Note: there's quite a bit of overlap between this and the code in QgsMapTip::showMapTip
1714 // Create the WebView
1715 mMapTipPreview = new QgsWebView( mMapTipPreviewContainer );
1716
1717#if WITH_QTWEBKIT
1718 mMapTipPreview->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );//Handle link clicks by yourself
1719 mMapTipPreview->setContextMenuPolicy( Qt::NoContextMenu ); //No context menu is allowed if you don't need it
1720 connect( mMapTipPreview, &QWebView::loadFinished, this, &QgsRasterLayerProperties::resizeMapTip );
1721#endif
1722
1723 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
1724 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
1725 mMapTipPreview->page()->settings()->setAttribute( QWebSettings::LocalStorageEnabled, true );
1726
1727 // Disable scrollbars, avoid random resizing issues
1728 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
1729 mMapTipPreview->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
1730
1731
1732 // Update the map tip preview when the expression or the map tip template changes
1733 connect( mMapTipWidget, &QgsCodeEditorHTML::textChanged, this, &QgsRasterLayerProperties::updateMapTipPreview );
1734}
1735
1736void QgsRasterLayerProperties::updateMapTipPreview()
1737{
1738 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1739 const QString htmlContent = QgsMapTip::rasterMapTipPreviewText( mRasterLayer, mCanvas, mMapTipWidget->text() );
1740 mMapTipPreview->setHtml( htmlContent );
1741}
1742
1743void QgsRasterLayerProperties::resizeMapTip()
1744{
1745 // Ensure the map tip is not bigger than the container
1746 mMapTipPreview->setMaximumSize( mMapTipPreviewContainer->width(), mMapTipPreviewContainer->height() );
1747#if WITH_QTWEBKIT
1748 // Get the content size
1749 const QWebElement container = mMapTipPreview->page()->mainFrame()->findFirstElement(
1750 QStringLiteral( "#QgsWebViewContainer" ) );
1751 const int width = container.geometry().width();
1752 const int height = container.geometry().height();
1753 mMapTipPreview->resize( width, height );
1754
1755 // Move the map tip to the center of the container
1756 mMapTipPreview->move( ( mMapTipPreviewContainer->width() - mMapTipPreview->width() ) / 2,
1757 ( mMapTipPreviewContainer->height() - mMapTipPreview->height() ) / 2 );
1758
1759#else
1760 mMapTipPreview->adjustSize();
1761#endif
1762}
@ SingleBandColorData
Single band containing color data.
RasterPyramidFormat
Raster pyramid formats.
Definition qgis.h:3919
@ 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.
@ WebBrowser
StyleSheet for Qt GUI widgets (based on QLabel or QTextBrowser), supports basic CSS and Qt extensions...
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:38
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.
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.
QString name
Definition qgsmaplayer.h:78
QString legendUrlFormat() const
Returns the format for a URL based layer legend.
void setAbstract(const QString &abstract)
Sets the abstract of the layer used by QGIS Server in GetCapabilities request.
QString source() const
Returns the source for the layer.
void setLegendUrl(const QString &legendUrl)
Sets the URL for the layer's legend.
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.
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
QString attribution() const
Returns the attribution of the layer used by QGIS Server in GetCapabilities request.
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.
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.
QString dataUrlFormat() const
Returns the DataUrl format of the layer used by QGIS Server in GetCapabilities request.
void setDataUrl(const QString &dataUrl)
Sets the DataUrl of the layer used by QGIS Server in GetCapabilities request.
void setKeywordList(const QString &keywords)
Sets the keyword list of the layer used by QGIS Server in GetCapabilities request.
void setAttribution(const QString &attrib)
Sets the attribution of the layer used by QGIS Server in GetCapabilities request.
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.
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.
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.
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.
QString attributionUrl() const
Returns the attribution URL of the layer used by QGIS Server in GetCapabilities request.
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.
void setLegendUrlFormat(const QString &legendUrlFormat)
Sets the format for a URL based layer legend.
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.
QString mapTipTemplate
Definition qgsmaplayer.h:85
void setTitle(const QString &title)
Sets the title of the layer used by QGIS Server in GetCapabilities request.
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.
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.
void setDirty(bool b=true)
Flag the project as dirty (modified).
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.
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 syncToLayer()
Updates the widget state to match the current layer state.
void saveTemporalProperties()
Save widget temporal properties inputs.
void addWidget(QgsMapLayerConfigWidget *widget SIP_TRANSFER)
Adds a child widget to the properties widget.
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.
@ 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)
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 QList< QgsRasterTransparency::TransparentSingleValuePixel > &newList)
Sets the transparent single value pixel list, replacing the whole existing list.
void setTransparentThreeValuePixelList(const QList< QgsRasterTransparency::TransparentThreeValuePixel > &newList)
Sets the transparent three value pixel list, replacing the whole existing list.
A rectangle specified with double values.
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:5048
#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
QString format
Format specification of online resource.