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