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