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