37 #include "qgsnative.h"
70 #include <QDesktopServices>
71 #include <QTableWidgetItem>
72 #include <QHeaderView>
73 #include <QTextStream>
75 #include <QFileDialog>
76 #include <QMessageBox>
78 #include <QLinearGradient>
79 #include <QPainterPath>
81 #include <QColorDialog>
83 #include <QMouseEvent>
92 , TRSTRING_NOT_SET( tr(
"Not Set" ) )
93 , mDefaultStandardDeviation( 0 )
94 , mDefaultRedBand( 0 )
95 , mDefaultGreenBand( 0 )
96 , mDefaultBlueBand( 0 )
98 , mGradientHeight( 0.0 )
99 , mGradientWidth( 0.0 )
100 , mMapCanvas( canvas )
101 , mMetadataFilled( false )
103 mGrayMinimumMaximumEstimated =
true;
104 mRGBMinimumMaximumEstimated =
true;
107 connect( mLayerOrigNameLineEd, &QLineEdit::textEdited,
this, &QgsRasterLayerProperties::mLayerOrigNameLineEd_textEdited );
108 connect( buttonBuildPyramids, &QPushButton::clicked,
this, &QgsRasterLayerProperties::buttonBuildPyramids_clicked );
109 connect( pbnAddValuesFromDisplay, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnAddValuesFromDisplay_clicked );
110 connect( pbnAddValuesManually, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnAddValuesManually_clicked );
112 connect( pbnDefaultValues, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnDefaultValues_clicked );
113 connect( pbnExportTransparentPixelValues, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnExportTransparentPixelValues_clicked );
114 connect( pbnImportTransparentPixelValues, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnImportTransparentPixelValues_clicked );
115 connect( pbnRemoveSelectedRow, &QToolButton::clicked,
this, &QgsRasterLayerProperties::pbnRemoveSelectedRow_clicked );
116 connect( mRenderTypeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged );
117 connect( mResetColorRenderingBtn, &QToolButton::clicked,
this, &QgsRasterLayerProperties::mResetColorRenderingBtn_clicked );
122 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsRasterLayerProperties::showHelp );
124 connect( mSetEndAsStartStaticButton, &QPushButton::clicked,
this, &QgsRasterLayerProperties::setEndAsStartStaticButton_clicked );
125 connect( mProjectTemporalRange, &QRadioButton::toggled,
this, &QgsRasterLayerProperties::passProjectTemporalRange_toggled );
126 connect( mStaticTemporalRange, &QRadioButton::toggled,
this, &QgsRasterLayerProperties::staticTemporalRange_toggled );
128 connect( mStaticTemporalRange, &QRadioButton::toggled, mStaticWmstFrame, &QWidget::setEnabled );
129 connect( mReferenceTime, &QCheckBox::toggled, mWmstReferenceTimeFrame, &QWidget::setEnabled );
134 mBtnStyle =
new QPushButton( tr(
"Style" ) );
135 QMenu *menuStyle =
new QMenu(
this );
136 menuStyle->addAction( tr(
"Load Style…" ),
this, &QgsRasterLayerProperties::loadStyle_clicked );
137 menuStyle->addAction( tr(
"Save Style…" ),
this, &QgsRasterLayerProperties::saveStyleAs_clicked );
138 menuStyle->addSeparator();
139 menuStyle->addAction( tr(
"Save as Default" ),
this, &QgsRasterLayerProperties::saveDefaultStyle_clicked );
140 menuStyle->addAction( tr(
"Restore Default" ),
this, &QgsRasterLayerProperties::loadDefaultStyle_clicked );
141 mBtnStyle->setMenu( menuStyle );
142 connect( menuStyle, &QMenu::aboutToShow,
this, &QgsRasterLayerProperties::aboutToShowStyleMenu );
143 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
145 mBtnMetadata =
new QPushButton( tr(
"Metadata" ),
this );
146 QMenu *menuMetadata =
new QMenu(
this );
147 mActionLoadMetadata = menuMetadata->addAction( tr(
"Load Metadata…" ),
this, &QgsRasterLayerProperties::loadMetadata );
148 mActionSaveMetadataAs = menuMetadata->addAction( tr(
"Save Metadata…" ),
this, &QgsRasterLayerProperties::saveMetadataAs );
149 menuMetadata->addSeparator();
150 menuMetadata->addAction( tr(
"Save as Default" ),
this, &QgsRasterLayerProperties::saveDefaultMetadata );
151 menuMetadata->addAction( tr(
"Restore Default" ),
this, &QgsRasterLayerProperties::loadDefaultMetadata );
152 mBtnMetadata->setMenu( menuMetadata );
153 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
157 connect(
this, &QDialog::accepted,
this, &QgsRasterLayerProperties::apply );
158 connect(
this, &QDialog::rejected,
this, &QgsRasterLayerProperties::onCancel );
160 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked,
this, &QgsRasterLayerProperties::apply );
163 connect( mSliderBrightness, &QAbstractSlider::valueChanged, mBrightnessSpinBox, &QSpinBox::setValue );
164 connect( mBrightnessSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ), mSliderBrightness, &QAbstractSlider::setValue );
166 connect( mSliderContrast, &QAbstractSlider::valueChanged, mContrastSpinBox, &QSpinBox::setValue );
167 connect( mContrastSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ), mSliderContrast, &QAbstractSlider::setValue );
170 connect( sliderSaturation, &QAbstractSlider::valueChanged, spinBoxSaturation, &QSpinBox::setValue );
171 connect( spinBoxSaturation,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ), sliderSaturation, &QAbstractSlider::setValue );
174 connect( sliderColorizeStrength, &QAbstractSlider::valueChanged, spinColorizeStrength, &QSpinBox::setValue );
175 connect( spinColorizeStrength,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ), sliderColorizeStrength, &QAbstractSlider::setValue );
178 connect( comboGrayscale,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsRasterLayerProperties::toggleSaturationControls );
181 connect( mColorizeCheck, &QAbstractButton::toggled,
this, &QgsRasterLayerProperties::toggleColorizeControls );
184 connect( lbxPyramidResolutions, &QListWidget::itemSelectionChanged,
this, &QgsRasterLayerProperties::toggleBuildPyramidsButton );
186 connect( mRefreshLayerCheckBox, &QCheckBox::toggled, mRefreshLayerIntervalSpinBox, &QDoubleSpinBox::setEnabled );
189 mScaleRangeWidget->setMapCanvas( mMapCanvas );
193 leNoDataValue->setValidator(
new QDoubleValidator( -std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), 1000,
this ) );
208 mPixelSelectorTool = qgis::make_unique<QgsMapToolEmitPoint>( canvas );
214 pbnAddValuesFromDisplay->setEnabled(
false );
228 cboResamplingMethod->clear();
231 for ( QPair<QString, QString> method : constProviderType )
233 cboResamplingMethod->addItem( method.second, method.first );
237 QString prefix = provider->
name() +
"/driverOptions/_pyramids/";
239 QString defaultMethod = mySettings.
value( prefix +
"resampling",
"AVERAGE" ).toString();
240 int idx = cboResamplingMethod->findData( defaultMethod );
242 cboResamplingMethod->setCurrentIndex( idx );
247 QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;
249 for ( myRasterPyramidIterator = myPyramidList.begin();
250 myRasterPyramidIterator != myPyramidList.end();
251 ++myRasterPyramidIterator )
253 if ( myRasterPyramidIterator->exists )
255 lbxPyramidResolutions->addItem(
new QListWidgetItem( myPyramidPixmap,
256 QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral(
" x " ) +
257 QString::number( myRasterPyramidIterator->yDim ) ) );
261 lbxPyramidResolutions->addItem(
new QListWidgetItem( myNoPyramidPixmap,
262 QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral(
" x " ) +
263 QString::number( myRasterPyramidIterator->yDim ) ) );
270 mOptsPage_Pyramids->setEnabled(
false );
279 mOptsPage_Histogram->setEnabled(
false );
282 QVBoxLayout *layout =
new QVBoxLayout( metadataFrame );
283 layout->setMargin( 0 );
285 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
287 layout->addWidget( mMetadataWidget );
288 metadataFrame->setLayout( layout );
290 QVBoxLayout *temporalLayout =
new QVBoxLayout( temporalFrame );
291 temporalLayout->setContentsMargins( 0, 0, 0, 0 );
293 temporalLayout->addWidget( mTemporalWidget );
295 setSourceStaticTimeState();
301 mPostgresRasterTemporalGroup->setEnabled(
true );
302 mPostgresRasterTemporalGroup->setVisible(
true );
303 mPostgresRasterTemporalGroup->setChecked(
false );
305 mPostgresRasterTemporalFieldComboBox->setFields( fields );
306 mPostgresRasterTemporalFieldComboBox->setFilters( QgsFieldProxyModel::Filter::Date |
307 QgsFieldProxyModel::Filter::DateTime |
308 QgsFieldProxyModel::Filter::String );
309 mPostgresRasterTemporalFieldComboBox->setAllowEmptyFieldName(
true );
312 mPostgresRasterDefaultTime->setEnabled( ! fieldName.isEmpty() );
314 mPostgresRasterDefaultTime->setAllowNull(
true );
315 mPostgresRasterDefaultTime->setEmpty();
319 const int fieldIdx { mRasterLayer->
dataProvider()->
uri().
param( QStringLiteral(
"temporalFieldIndex" ) ).toInt( &ok ) };
320 if ( ok && fields.exists( fieldIdx ) )
322 mPostgresRasterTemporalGroup->setChecked(
true );
323 mPostgresRasterTemporalFieldComboBox->setField( fields.field( fieldIdx ).name() );
326 const QDateTime defaultDateTime { QDateTime::fromString( mRasterLayer->
dataProvider()->
uri().
param( QStringLiteral(
"temporalDefaultTime" ) ), Qt::DateFormat::ISODate ) };
327 if ( defaultDateTime.isValid() )
329 mPostgresRasterDefaultTime->setDateTime( defaultDateTime );
337 mPostgresRasterTemporalGroup->setEnabled(
false );
338 mPostgresRasterTemporalGroup->setVisible(
false );
343 mCrsSelector->setCrs( mRasterLayer->
crs() );
346 QString pyramidFormat( QStringLiteral(
"<h2>%1</h2><p>%2 %3 %4</p><b><font color='red'><p>%5</p><p>%6</p>" ) );
347 QString pyramidHeader = tr(
"Description" );
348 QString pyramidSentence1 = tr(
"Large resolution raster layers can slow navigation in QGIS." );
349 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." );
350 QString pyramidSentence3 = tr(
"You must have write access in the directory where the original data is stored to build pyramids." );
351 QString pyramidSentence4 = tr(
"Please note that building internal pyramids may alter the original data file and once created they cannot be removed!" );
352 QString pyramidSentence5 = tr(
"Please note that building internal pyramids could corrupt your image - always make a backup of your data first!" );
354 tePyramidDescription->setHtml( pyramidFormat.arg( pyramidHeader,
359 pyramidSentence5 ) );
362 mResamplingGroupBox->setSaveCheckedState(
true );
364 mZoomedInResamplingComboBox->insertItem( 0, tr(
"Nearest neighbour" ) );
365 mZoomedInResamplingComboBox->insertItem( 1, tr(
"Bilinear" ) );
366 mZoomedInResamplingComboBox->insertItem( 2, tr(
"Cubic" ) );
367 mZoomedOutResamplingComboBox->insertItem( 0, tr(
"Nearest neighbour" ) );
368 mZoomedOutResamplingComboBox->insertItem( 1, tr(
"Average" ) );
372 if ( resampleFilter )
375 if ( zoomedInResampler )
377 if ( zoomedInResampler->
type() == QLatin1String(
"bilinear" ) )
379 mZoomedInResamplingComboBox->setCurrentIndex( 1 );
381 else if ( zoomedInResampler->
type() == QLatin1String(
"cubic" ) )
383 mZoomedInResamplingComboBox->setCurrentIndex( 2 );
388 mZoomedInResamplingComboBox->setCurrentIndex( 0 );
392 if ( zoomedOutResampler )
394 if ( zoomedOutResampler->
type() == QLatin1String(
"bilinear" ) )
396 mZoomedOutResamplingComboBox->setCurrentIndex( 1 );
401 mZoomedOutResamplingComboBox->setCurrentIndex( 0 );
403 mMaximumOversamplingSpinBox->setValue( resampleFilter->
maxOversampling() );
406 btnColorizeColor->setColorDialogTitle( tr(
"Select Color" ) );
407 btnColorizeColor->setContext( QStringLiteral(
"symbology" ) );
412 if ( hueSaturationFilter )
414 sliderSaturation->setValue( hueSaturationFilter->
saturation() );
415 comboGrayscale->setCurrentIndex( (
int ) hueSaturationFilter->
grayscaleMode() );
418 toggleSaturationControls(
static_cast<int>( hueSaturationFilter->
grayscaleMode() ) );
421 mColorizeCheck->setChecked( hueSaturationFilter->
colorizeOn() );
422 btnColorizeColor->setColor( hueSaturationFilter->
colorizeColor() );
423 toggleColorizeControls( hueSaturationFilter->
colorizeOn() );
424 sliderColorizeStrength->setValue( hueSaturationFilter->
colorizeStrength() );
428 mBlendModeComboBox->setBlendMode( mRasterLayer->
blendMode() );
433 cboxTransparencyBand->setShowNotSetOption(
true, tr(
"None" ) );
434 cboxTransparencyBand->setLayer( mRasterLayer );
443 cboxTransparencyBand->setCurrentIndex( cboxTransparencyBand->findData( renderer->
alphaBand() ) );
450 mHistogramWidget =
nullptr;
451 if ( mOptsPage_Histogram->isEnabled() )
454 mHistogramStackedWidget->addWidget( mHistogramWidget );
467 mDisableRenderTypeComboBoxCurrentIndexChanged =
true;
469 for (
const QString &name : constRenderersList )
480 mDisableRenderTypeComboBoxCurrentIndexChanged =
false;
485 QString rendererType = renderer->
type();
486 widgetIndex = mRenderTypeComboBox->findData( rendererType );
487 if ( widgetIndex != -1 )
489 mDisableRenderTypeComboBoxCurrentIndexChanged =
true;
490 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
491 mDisableRenderTypeComboBoxCurrentIndexChanged =
false;
494 if ( rendererType == QLatin1String(
"singlebandcolordata" ) && mRenderTypeComboBox->count() == 1 )
497 QSizePolicy sizep = mBandRenderingGrpBx->sizePolicy();
498 sizep.setVerticalStretch( 0 );
499 sizep.setVerticalPolicy( QSizePolicy::Maximum );
500 mBandRenderingGrpBx->setSizePolicy( sizep );
501 mBandRenderingGrpBx->updateGeometry();
504 if ( mRasterLayer->
providerType() != QStringLiteral(
"wms" ) )
506 mWMSPrintGroupBox->hide();
507 mPublishDataSourceUrlCheckBox->hide();
508 mBackgroundLayerCheckBox->hide();
515 #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
516 const int horizontalDpi = qApp->desktop()->screen()->logicalDpiX();
518 const int horizontalDpi = logicalDpiX();
522 if ( horizontalDpi > 96 )
524 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
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 );
533 mRenderTypeComboBox_currentIndexChanged( widgetIndex );
541 if ( !settings.
contains( QStringLiteral(
"/Windows/RasterLayerProperties/tab" ) ) )
543 settings.
setValue( QStringLiteral(
"Windows/RasterLayerProperties/tab" ),
549 QString title = tr(
"Layer Properties — %1" ).arg( lyr->
name() );
557 mOptsPage_Information->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#information-properties" ) );
558 mOptsPage_Source->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#source-properties" ) );
559 mOptsPage_Style->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#symbology-properties" ) );
560 mOptsPage_Transparency->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#transparency-properties" ) );
562 if ( mOptsPage_Histogram )
563 mOptsPage_Histogram->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#histogram-properties" ) );
565 mOptsPage_Rendering->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#rendering-properties" ) );
567 if ( mOptsPage_Pyramids )
568 mOptsPage_Pyramids->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#pyramids-properties" ) );
570 mOptsPage_Metadata->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#metadata-properties" ) );
571 mOptsPage_Legend->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#legend-properties" ) );
572 mOptsPage_Server->setProperty(
"helpPage", QStringLiteral(
"working_with_raster/raster_properties.html#server-properties" ) );
575 void QgsRasterLayerProperties::setupTransparencyTable(
int nBands )
577 tableTransparency->clear();
578 tableTransparency->setColumnCount( 0 );
579 tableTransparency->setRowCount( 0 );
580 mTransparencyToEdited.clear();
584 tableTransparency->setColumnCount( 4 );
585 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Red" ) ) );
586 tableTransparency->setHorizontalHeaderItem( 1,
new QTableWidgetItem( tr(
"Green" ) ) );
587 tableTransparency->setHorizontalHeaderItem( 2,
new QTableWidgetItem( tr(
"Blue" ) ) );
588 tableTransparency->setHorizontalHeaderItem( 3,
new QTableWidgetItem( tr(
"Percent Transparent" ) ) );
592 tableTransparency->setColumnCount( 3 );
595 if ( QgsRasterLayer::PalettedColor != mRasterLayer->drawingStyle() &&
596 QgsRasterLayer::PalettedSingleBandGray != mRasterLayer->drawingStyle() &&
597 QgsRasterLayer::PalettedSingleBandPseudoColor != mRasterLayer->drawingStyle() &&
598 QgsRasterLayer::PalettedMultiBandColor != mRasterLayer->drawingStyle() )
600 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Gray" ) ) );
604 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"Indexed Value" ) ) );
607 tableTransparency->setHorizontalHeaderItem( 0,
new QTableWidgetItem( tr(
"From" ) ) );
608 tableTransparency->setHorizontalHeaderItem( 1,
new QTableWidgetItem( tr(
"To" ) ) );
609 tableTransparency->setHorizontalHeaderItem( 2,
new QTableWidgetItem( tr(
"Percent Transparent" ) ) );
612 tableTransparency->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
613 tableTransparency->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
616 void QgsRasterLayerProperties::populateTransparencyTable(
QgsRasterRenderer *renderer )
628 int nBands = renderer->
usesBands().size();
629 setupTransparencyTable( nBands );
632 if ( !rasterTransparency )
640 for (
int i = 0; i < pixelList.size(); ++i )
642 tableTransparency->insertRow( i );
643 setTransparencyCell( i, 0, pixelList[i].min );
644 setTransparencyCell( i, 1, pixelList[i].max );
645 setTransparencyCell( i, 2, pixelList[i].percentTransparent );
647 if ( pixelList[i].min != pixelList[i].max )
649 setTransparencyToEdited( i );
653 else if ( nBands == 3 )
656 for (
int i = 0; i < pixelList.size(); ++i )
658 tableTransparency->insertRow( i );
659 setTransparencyCell( i, 0, pixelList[i].red );
660 setTransparencyCell( i, 1, pixelList[i].green );
661 setTransparencyCell( i, 2, pixelList[i].blue );
662 setTransparencyCell( i, 3, pixelList[i].percentTransparent );
666 tableTransparency->resizeColumnsToContents();
667 tableTransparency->resizeRowsToContents();
670 void QgsRasterLayerProperties::setRendererWidget(
const QString &rendererName )
683 opacity = oldRenderer->
opacity();
692 QgsDebugMsg( QStringLiteral(
"renderer has widgetCreateFunction" ) );
695 if ( oldWidget && ( !oldRenderer || rendererName != oldRenderer->
type() ) )
697 if ( rendererName == QLatin1String(
"singlebandgray" ) )
700 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
702 else if ( rendererName == QLatin1String(
"multibandcolor" ) )
705 whileBlocking( mRasterLayer )->setDefaultContrastEnhancement();
713 mRendererStackedWidget->addWidget( mRendererWidget );
719 QList<int> oldBands = oldRenderer->
usesBands();
720 QList<int> newBands = newRenderer->
usesBands();
721 if ( oldBands != newBands )
723 populateTransparencyTable( newRenderer );
731 const int widgetIndex = mRenderTypeComboBox->findData( rendererName );
732 if ( widgetIndex != -1 )
734 mDisableRenderTypeComboBoxCurrentIndexChanged =
true;
735 mRenderTypeComboBox->setCurrentIndex( widgetIndex );
736 mDisableRenderTypeComboBoxCurrentIndexChanged =
false;
739 if ( mRendererWidget != oldWidget )
742 if ( mHistogramWidget )
757 void QgsRasterLayerProperties::sync()
768 gboxNoDataValue->setEnabled(
false );
769 gboxCustomTransparency->setEnabled(
false );
770 mOptionsStackedWidget->setCurrentWidget( mOptsPage_Server );
776 if ( mOptsPage_Pyramids )
778 delete mOptsPage_Pyramids;
779 mOptsPage_Pyramids =
nullptr;
785 if ( mOptsPage_Histogram )
787 delete mOptsPage_Histogram;
788 mOptsPage_Histogram =
nullptr;
789 delete mHistogramWidget;
790 mHistogramWidget =
nullptr;
794 QgsDebugMsg( QStringLiteral(
"populate transparency tab" ) );
801 if ( brightnessFilter )
803 mSliderBrightness->setValue( brightnessFilter->
brightness() );
804 mSliderContrast->setValue( brightnessFilter->
contrast() );
818 cboxTransparencyBand->setBand( renderer->
alphaBand() );
830 lblSrcNoDataValue->setText( tr(
"not defined" ) );
837 mSrcNoDataValueCheckBox->setEnabled( enableSrcNoData );
838 lblSrcNoDataValue->setEnabled( enableSrcNoData );
841 QgsDebugMsg( QStringLiteral(
"noDataRangeList.size = %1" ).arg( noDataRangeList.size() ) );
842 if ( !noDataRangeList.isEmpty() )
848 leNoDataValue->insert( QString() );
855 populateTransparencyTable( mRasterLayer->
renderer() );
857 QgsDebugMsg( QStringLiteral(
"populate colormap tab" ) );
862 QgsDebugMsg( QStringLiteral(
"populate general tab" ) );
868 mLayerOrigNameLineEd->setText( mRasterLayer->
name() );
869 leDisplayName->setText( mRasterLayer->
name() );
872 QPixmap thumbnail = QPixmap::fromImage( mRasterLayer->
previewAsImage( pixmapThumbnail->size() ) );
873 pixmapThumbnail->setPixmap( thumbnail );
879 pixmapLegend->setPixmap( mRasterLayer->legendAsPixmap() );
880 pixmapLegend->setScaledContents(
true );
881 pixmapLegend->repaint();
884 pixmapPalette->setPixmap( mRasterLayer->
paletteAsPixmap( mRasterLayer->bandNumber( mRasterLayer->grayBandName() ) ) );
885 pixmapPalette->setScaledContents(
true );
886 pixmapPalette->repaint();
889 QgsDebugMsg( QStringLiteral(
"populate metadata tab" ) );
894 updateInformationContent();
897 mLayerShortNameLineEdit->setText( mRasterLayer->
shortName() );
900 mLayerShortNameLineEdit->setValidator( shortNameValidator );
903 mLayerTitleLineEdit->setText( mRasterLayer->
title() );
904 mLayerAbstractTextEdit->setPlainText( mRasterLayer->
abstract() );
905 mLayerKeywordListLineEdit->setText( mRasterLayer->
keywordList() );
906 mLayerDataUrlLineEdit->setText( mRasterLayer->
dataUrl() );
907 mLayerDataUrlFormatComboBox->setCurrentIndex(
908 mLayerDataUrlFormatComboBox->findText(
914 mLayerAttributionLineEdit->setText( mRasterLayer->
attribution() );
915 mLayerAttributionUrlLineEdit->setText( mRasterLayer->
attributionUrl() );
916 mLayerMetadataUrlLineEdit->setText( mRasterLayer->
metadataUrl() );
917 mLayerMetadataUrlTypeComboBox->setCurrentIndex(
918 mLayerMetadataUrlTypeComboBox->findText(
922 mLayerMetadataUrlFormatComboBox->setCurrentIndex(
923 mLayerMetadataUrlFormatComboBox->findText(
928 mLayerLegendUrlLineEdit->setText( mRasterLayer->
legendUrl() );
929 mLayerLegendUrlFormatComboBox->setCurrentIndex( mLayerLegendUrlFormatComboBox->findText( mRasterLayer->
legendUrlFormat() ) );
932 QVariant wmsPrintLayer = mRasterLayer->
customProperty( QStringLiteral(
"WMSPrintLayer" ) );
933 if ( wmsPrintLayer.isValid() )
935 mWMSPrintLayerLineEdit->setText( wmsPrintLayer.toString() );
938 QVariant wmsPublishDataSourceUrl = mRasterLayer->
customProperty( QStringLiteral(
"WMSPublishDataSourceUrl" ),
false );
939 mPublishDataSourceUrlCheckBox->setChecked( wmsPublishDataSourceUrl.toBool() );
941 QVariant wmsBackgroundLayer = mRasterLayer->
customProperty( QStringLiteral(
"WMSBackgroundLayer" ),
false );
942 mBackgroundLayerCheckBox->setChecked( wmsBackgroundLayer.toBool() );
944 mLegendConfigEmbeddedWidget->setLayer( mRasterLayer );
949 void QgsRasterLayerProperties::apply()
953 if ( !mRasterLayer->
isValid() )
959 mLegendConfigEmbeddedWidget->applyToLayer();
961 QgsDebugMsg( QStringLiteral(
"apply processing symbology tab" ) );
972 QgsDebugMsg( QStringLiteral(
"processing transparency tab" ) );
979 if (
"" != leNoDataValue->text() )
981 bool myDoubleOk =
false;
982 double myNoDataValue = leNoDataValue->text().toDouble( &myDoubleOk );
986 myNoDataRangeList << myNoDataRange;
989 for (
int bandNo = 1; bandNo <= mRasterLayer->
dataProvider()->bandCount(); bandNo++ )
997 if ( rendererWidget )
1005 mMetadataFilled =
false;
1009 if ( rasterRenderer )
1011 rasterRenderer->
setAlphaBand( cboxTransparencyBand->currentBand() );
1015 if ( tableTransparency->columnCount() == 4 )
1018 QList<QgsRasterTransparency::TransparentThreeValuePixel> myTransparentThreeValuePixelList;
1019 for (
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
1021 myTransparentPixel.
red = transparencyCellValue( myListRunner, 0 );
1022 myTransparentPixel.
green = transparencyCellValue( myListRunner, 1 );
1023 myTransparentPixel.
blue = transparencyCellValue( myListRunner, 2 );
1025 myTransparentThreeValuePixelList.append( myTransparentPixel );
1029 else if ( tableTransparency->columnCount() == 3 )
1032 QList<QgsRasterTransparency::TransparentSingleValuePixel> myTransparentSingleValuePixelList;
1033 for (
int myListRunner = 0; myListRunner < tableTransparency->rowCount(); myListRunner++ )
1035 myTransparentPixel.
min = transparencyCellValue( myListRunner, 0 );
1036 myTransparentPixel.
max = transparencyCellValue( myListRunner, 1 );
1039 myTransparentSingleValuePixelList.append( myTransparentPixel );
1047 rasterRenderer->
setOpacity( mOpacityWidget->opacity() );
1050 QgsDebugMsg( QStringLiteral(
"processing general tab" ) );
1054 mRasterLayer->
setName( mLayerOrigNameLineEd->text() );
1070 if ( resampleFilter )
1073 QString zoomedInResamplingMethod = mZoomedInResamplingComboBox->currentText();
1074 if ( zoomedInResamplingMethod == tr(
"Bilinear" ) )
1078 else if ( zoomedInResamplingMethod == tr(
"Cubic" ) )
1087 QString zoomedOutResamplingMethod = mZoomedOutResamplingComboBox->currentText();
1088 if ( zoomedOutResamplingMethod == tr(
"Average" ) )
1100 if ( hueSaturationFilter )
1102 hueSaturationFilter->
setSaturation( sliderSaturation->value() );
1104 hueSaturationFilter->
setColorizeOn( mColorizeCheck->checkState() );
1110 mRasterLayer->
setBlendMode( mBlendModeComboBox->blendMode() );
1112 updateSourceStaticTime();
1118 if ( mPostgresRasterTemporalGroup->isEnabled() &&
1119 mPostgresRasterTemporalGroup->isChecked() &&
1120 ! mPostgresRasterTemporalFieldComboBox->currentField().isEmpty() )
1122 const QString originaUri { uri.
uri() };
1124 uri.removeParam( QStringLiteral(
"temporalFieldIndex" ) );
1125 uri.removeParam( QStringLiteral(
"temporalDefaultTime" ) );
1126 if ( fieldIdx >= 0 )
1128 uri.setParam( QStringLiteral(
"temporalFieldIndex" ), QString::number( fieldIdx ) );
1129 if ( mPostgresRasterDefaultTime->dateTime().isValid() )
1131 QDateTime defaultDateTime { mPostgresRasterDefaultTime->dateTime() };
1132 const QTime defaultTime { defaultDateTime.time() };
1134 defaultDateTime.setTime( { defaultTime.hour(), defaultTime.minute(), 0 } );
1135 uri.setParam( QStringLiteral(
"temporalDefaultTime" ), defaultDateTime.toString( Qt::DateFormat::ISODate ) );
1137 if ( uri.uri( ) != originaUri )
1141 else if ( uri.hasParam( QStringLiteral(
"temporalFieldIndex" ) ) )
1143 uri.removeParam( QStringLiteral(
"temporalFieldIndex" ) );
1144 uri.removeParam( QStringLiteral(
"temporalDefaultTime" ) );
1152 mRasterLayer->
setCrs( mCrsSelector->crs() );
1155 QPixmap thumbnail = QPixmap::fromImage( mRasterLayer->
previewAsImage( pixmapThumbnail->size() ) );
1156 pixmapThumbnail->setPixmap( thumbnail );
1158 if ( mRasterLayer->
shortName() != mLayerShortNameLineEdit->text() )
1159 mMetadataFilled =
false;
1160 mRasterLayer->
setShortName( mLayerShortNameLineEdit->text() );
1162 if ( mRasterLayer->
title() != mLayerTitleLineEdit->text() )
1163 mMetadataFilled =
false;
1164 mRasterLayer->
setTitle( mLayerTitleLineEdit->text() );
1166 if ( mRasterLayer->
abstract() != mLayerAbstractTextEdit->toPlainText() )
1167 mMetadataFilled =
false;
1168 mRasterLayer->
setAbstract( mLayerAbstractTextEdit->toPlainText() );
1170 if ( mRasterLayer->
keywordList() != mLayerKeywordListLineEdit->text() )
1171 mMetadataFilled =
false;
1172 mRasterLayer->
setKeywordList( mLayerKeywordListLineEdit->text() );
1174 if ( mRasterLayer->
dataUrl() != mLayerDataUrlLineEdit->text() )
1175 mMetadataFilled =
false;
1176 mRasterLayer->
setDataUrl( mLayerDataUrlLineEdit->text() );
1178 if ( mRasterLayer->
dataUrlFormat() != mLayerDataUrlFormatComboBox->currentText() )
1179 mMetadataFilled =
false;
1180 mRasterLayer->
setDataUrlFormat( mLayerDataUrlFormatComboBox->currentText() );
1183 if ( mRasterLayer->
attribution() != mLayerAttributionLineEdit->text() )
1184 mMetadataFilled =
false;
1185 mRasterLayer->
setAttribution( mLayerAttributionLineEdit->text() );
1187 if ( mRasterLayer->
attributionUrl() != mLayerAttributionUrlLineEdit->text() )
1188 mMetadataFilled =
false;
1191 if ( mRasterLayer->
metadataUrl() != mLayerMetadataUrlLineEdit->text() )
1192 mMetadataFilled =
false;
1193 mRasterLayer->
setMetadataUrl( mLayerMetadataUrlLineEdit->text() );
1195 if ( mRasterLayer->
metadataUrlType() != mLayerMetadataUrlTypeComboBox->currentText() )
1196 mMetadataFilled =
false;
1199 if ( mRasterLayer->
metadataUrlFormat() != mLayerMetadataUrlFormatComboBox->currentText() )
1200 mMetadataFilled =
false;
1203 if ( mRasterLayer->
legendUrl() != mLayerLegendUrlLineEdit->text() )
1204 mMetadataFilled =
false;
1205 mRasterLayer->
setLegendUrl( mLayerLegendUrlLineEdit->text() );
1207 if ( mRasterLayer->
legendUrlFormat() != mLayerLegendUrlFormatComboBox->currentText() )
1208 mMetadataFilled =
false;
1211 if ( !mWMSPrintLayerLineEdit->text().isEmpty() )
1213 mRasterLayer->
setCustomProperty( QStringLiteral(
"WMSPrintLayer" ), mWMSPrintLayerLineEdit->text() );
1216 mRasterLayer->
setCustomProperty(
"WMSPublishDataSourceUrl", mPublishDataSourceUrlCheckBox->isChecked() );
1217 mRasterLayer->
setCustomProperty(
"WMSBackgroundLayer", mBackgroundLayerCheckBox->isChecked() );
1229 void QgsRasterLayerProperties::updateSourceStaticTime()
1235 QVariantMap uri = currentUri;
1237 if ( mWmstGroup->isVisibleTo(
this ) )
1238 uri[ QStringLiteral(
"allowTemporalUpdates" ) ] = mWmstGroup->isChecked();
1241 if ( mWmstGroup->isEnabled() &&
1245 bool enableTime = !mDisableTime->isChecked();
1247 uri[ QStringLiteral(
"enableTime" ) ] = enableTime;
1249 mFetchModeComboBox->currentData().toInt() ) );
1254 if ( mStaticTemporalRange->isChecked() )
1256 QString time = mStartStaticDateTimeEdit->dateTime().toString( Qt::ISODateWithMs ) +
'/' +
1257 mEndStaticDateTimeEdit->dateTime().toString( Qt::ISODateWithMs );
1258 uri[ QStringLiteral(
"time" ) ] = time;
1259 uri[ QStringLiteral(
"temporalSource" ) ] = QLatin1String(
"provider" );
1262 if ( mProjectTemporalRange->isChecked() )
1264 QgsDateTimeRange range;
1268 if ( range.begin().isValid() && range.end().isValid() )
1270 QString time = range.begin().toString( Qt::ISODateWithMs ) +
'/' +
1271 range.end().toString( Qt::ISODateWithMs );
1273 uri[ QStringLiteral(
"time" ) ] = time;
1274 uri[ QStringLiteral(
"temporalSource" ) ] = QLatin1String(
"project" );
1279 if ( mReferenceTime->isChecked() )
1281 QString referenceTime = mReferenceDateTimeEdit->dateTime().toString( Qt::ISODateWithMs );
1282 uri[ QStringLiteral(
"referenceTime" ) ] = referenceTime;
1286 if ( uri.contains( QStringLiteral(
"referenceTime" ) ) )
1287 uri.remove( QStringLiteral(
"referenceTime" ) );
1291 if ( currentUri != uri )
1295 void QgsRasterLayerProperties::setSourceStaticTimeState()
1307 mStartStaticDateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
1308 mEndStaticDateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
1309 mReferenceDateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
1312 if ( availableProviderRange.begin().isValid() && availableProviderRange.end().isValid() )
1314 mStartStaticDateTimeEdit->setDateTimeRange( availableProviderRange.begin(),
1315 availableProviderRange.end() );
1316 mStartStaticDateTimeEdit->setDateTime( availableProviderRange.begin() );
1317 mEndStaticDateTimeEdit->setDateTimeRange( availableProviderRange.begin(),
1318 availableProviderRange.end() );
1319 mEndStaticDateTimeEdit->setDateTime( availableProviderRange.end() );
1321 if ( availableReferenceRange.begin().isValid() && availableReferenceRange.end().isValid() )
1323 mReferenceDateTimeEdit->setDateTimeRange( availableReferenceRange.begin(),
1324 availableReferenceRange.end() );
1325 mReferenceDateTimeEdit->setDateTime( availableReferenceRange.begin() );
1328 const QString time = uri.value( QStringLiteral(
"time" ) ).toString();
1329 if ( !time.isEmpty() )
1331 QStringList parts = time.split(
'/' );
1332 mStartStaticDateTimeEdit->setDateTime( QDateTime::fromString( parts.at( 0 ), Qt::ISODateWithMs ) );
1333 mEndStaticDateTimeEdit->setDateTime( QDateTime::fromString( parts.at( 1 ), Qt::ISODateWithMs ) );
1336 const QString referenceTimeExtent = uri.value( QStringLiteral(
"referenceTimeDimensionExtent" ) ).toString();
1338 mReferenceTime->setEnabled( !referenceTimeExtent.isEmpty() );
1339 mReferenceDateTimeEdit->setVisible( !referenceTimeExtent.isEmpty() );
1341 QString referenceTimeLabelText = referenceTimeExtent.isEmpty() ?
1342 tr(
"There is no reference time in the layer's capabilities." ) : QString();
1343 mReferenceTimeLabel->setText( referenceTimeLabelText );
1345 const QString referenceTime = uri.value( QStringLiteral(
"referenceTime" ) ).toString();
1347 mReferenceTime->setChecked( !referenceTime.isEmpty() );
1349 if ( !referenceTime.isEmpty() && !referenceTimeExtent.isEmpty() )
1351 mReferenceDateTimeEdit->setDateTime( QDateTime::fromString( referenceTime, Qt::ISODateWithMs ) );
1359 mFetchModeComboBox->setCurrentIndex( mFetchModeComboBox->findData( qobject_cast< QgsRasterLayerTemporalProperties * >( mRasterLayer->
temporalProperties() )->intervalHandlingMethod() ) );
1361 const QString temporalSource = uri.value( QStringLiteral(
"temporalSource" ) ).toString();
1362 bool enableTime = uri.value( QStringLiteral(
"enableTime" ),
true ).toBool();
1364 if ( temporalSource == QLatin1String(
"provider" ) )
1365 mStaticTemporalRange->setChecked( !time.isEmpty() );
1366 else if ( temporalSource == QLatin1String(
"project" ) )
1367 mProjectTemporalRange->setChecked( !time.isEmpty() );
1369 mDisableTime->setChecked( !enableTime );
1374 mWmstOptionsLabel->setText( tr(
"The static temporal options below are disabled because the layer "
1375 "temporal properties are active, to enable them disable temporal properties "
1376 "in the temporal tab. " ) );
1377 QgsDateTimeRange range;
1381 if ( !range.begin().isValid() || !range.end().isValid() )
1383 mProjectTemporalRange->setEnabled(
false );
1384 mProjectTemporalRangeLabel->setText( tr(
"The option below is disabled because the project temporal range "
1385 "is not valid, update the project temporal range in the project properties "
1386 "with valid values in order to use it here." ) );
1389 mWmstGroup->setChecked( uri.contains( QStringLiteral(
"allowTemporalUpdates" ) ) &&
1390 uri.value( QStringLiteral(
"allowTemporalUpdates" ),
true ).toBool() );
1394 void QgsRasterLayerProperties::staticTemporalRange_toggled(
bool checked )
1402 void QgsRasterLayerProperties::passProjectTemporalRange_toggled(
bool checked )
1406 QgsDateTimeRange range;
1410 if ( range.begin().isValid() && range.end().isValid() )
1411 mLabel->setText( tr(
"Project temporal range is set from %1 to %2" ).arg(
1412 range.begin().toString(
"yyyy-MM-dd HH:mm:ss" ),
1413 range.end().toString(
"yyyy-MM-dd HH:mm:ss" )
1416 mLabel->setText( tr(
"Project temporal range is not valid, can't use it here" ) );
1420 void QgsRasterLayerProperties::temporalPropertiesChange()
1425 mWmstOptionsLabel->setText( tr(
"The static temporal options below are disabled because the layer "
1426 "temporal properties are active, to enable them disable temporal properties "
1427 "in the temporal tab. " ) );
1429 mWmstOptionsLabel->clear();
1432 void QgsRasterLayerProperties::mLayerOrigNameLineEd_textEdited(
const QString &text )
1437 void QgsRasterLayerProperties::buttonBuildPyramids_clicked()
1449 for (
int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
1451 QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
1453 myPyramidList[myCounterInt].build = myItem->isSelected() || myPyramidList[myCounterInt].exists;
1457 QString prefix = provider->
name() +
"/driverOptions/_pyramids/";
1459 QString resamplingMethod( cboResamplingMethod->currentData().toString() );
1460 mySettings.
setValue( prefix +
"resampling", resamplingMethod );
1467 QApplication::setOverrideCursor( Qt::WaitCursor );
1474 QApplication::restoreOverrideCursor();
1475 mPyramidProgress->setValue( 0 );
1476 buttonBuildPyramids->setEnabled(
false );
1477 if ( !res.isNull() )
1479 if ( res == QLatin1String(
"CANCELED" ) )
1483 else if ( res == QLatin1String(
"ERROR_WRITE_ACCESS" ) )
1485 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1486 tr(
"Write access denied. Adjust the file permissions and try again." ) );
1488 else if ( res == QLatin1String(
"ERROR_WRITE_FORMAT" ) )
1490 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1491 tr(
"The file was not writable. Some formats do not "
1492 "support pyramid overviews. Consult the GDAL documentation if in doubt." ) );
1494 else if ( res == QLatin1String(
"FAILED_NOT_SUPPORTED" ) )
1496 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1497 tr(
"Building pyramid overviews is not supported on this type of raster." ) );
1499 else if ( res == QLatin1String(
"ERROR_JPEG_COMPRESSION" ) )
1501 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1502 tr(
"Building internal pyramid overviews is not supported on raster layers with JPEG compression and your current libtiff library." ) );
1504 else if ( res == QLatin1String(
"ERROR_VIRTUAL" ) )
1506 QMessageBox::warning(
this, tr(
"Building Pyramids" ),
1507 tr(
"Building pyramid overviews is not supported on this type of raster." ) );
1515 lbxPyramidResolutions->clear();
1521 QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;
1522 for ( myRasterPyramidIterator = myPyramidList.begin();
1523 myRasterPyramidIterator != myPyramidList.end();
1524 ++myRasterPyramidIterator )
1526 if ( myRasterPyramidIterator->exists )
1528 lbxPyramidResolutions->addItem(
new QListWidgetItem( myPyramidPixmap,
1529 QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral(
" x " ) +
1530 QString::number( myRasterPyramidIterator->yDim ) ) );
1534 lbxPyramidResolutions->addItem(
new QListWidgetItem( myNoPyramidPixmap,
1535 QString::number( myRasterPyramidIterator->xDim ) + QStringLiteral(
" x " ) +
1536 QString::number( myRasterPyramidIterator->yDim ) ) );
1545 updateInformationContent();
1548 void QgsRasterLayerProperties::urlClicked(
const QUrl &url )
1550 QFileInfo file( url.toLocalFile() );
1551 if ( file.exists() && !file.isDir() )
1554 QDesktopServices::openUrl( url );
1557 void QgsRasterLayerProperties::mRenderTypeComboBox_currentIndexChanged(
int index )
1559 if ( index < 0 || mDisableRenderTypeComboBoxCurrentIndexChanged || ! mRasterLayer->renderer() )
1564 QString rendererName = mRenderTypeComboBox->itemData( index ).toString();
1565 setRendererWidget( rendererName );
1568 void QgsRasterLayerProperties::pbnAddValuesFromDisplay_clicked()
1570 if ( mMapCanvas && mPixelSelectorTool )
1579 mMapCanvas->window()->raise();
1580 mMapCanvas->window()->activateWindow();
1581 mMapCanvas->window()->setFocus();
1582 mMapCanvas->
setMapTool( mPixelSelectorTool.get() );
1587 void QgsRasterLayerProperties::pbnAddValuesManually_clicked()
1595 tableTransparency->insertRow( tableTransparency->rowCount() );
1600 for (
int i = 0; i < n; i++ )
1602 setTransparencyCell( tableTransparency->rowCount() - 1, i, std::numeric_limits<double>::quiet_NaN() );
1605 setTransparencyCell( tableTransparency->rowCount() - 1, n, 100 );
1607 tableTransparency->resizeColumnsToContents();
1608 tableTransparency->resizeRowsToContents();
1618 void QgsRasterLayerProperties::pbnDefaultValues_clicked()
1620 if ( !mRendererWidget )
1634 setupTransparencyTable( nBands );
1636 tableTransparency->resizeColumnsToContents();
1637 tableTransparency->resizeRowsToContents();
1640 void QgsRasterLayerProperties::setTransparencyCell(
int row,
int column,
double value )
1642 QgsDebugMsg( QStringLiteral(
"value = %1" ).arg( value, 0,
'g', 17 ) );
1644 if ( !provider )
return;
1647 if ( !renderer )
return;
1648 int nBands = renderer->
usesBands().size();
1650 QLineEdit *lineEdit =
new QLineEdit();
1651 lineEdit->setFrame(
false );
1653 lineEdit->setContentsMargins( 1, 1, 1, 1 );
1655 if ( column == tableTransparency->columnCount() - 1 )
1659 lineEdit->setValidator(
new QIntValidator(
nullptr ) );
1660 lineEdit->setText( QString::number(
static_cast<int>( value ) ) );
1665 QString valueString;
1670 lineEdit->setValidator(
new QDoubleValidator(
nullptr ) );
1671 if ( !std::isnan( value ) )
1677 lineEdit->setValidator(
new QIntValidator(
nullptr ) );
1678 if ( !std::isnan( value ) )
1680 valueString = QString::number(
static_cast<int>( value ) );
1684 lineEdit->setText( valueString );
1686 tableTransparency->setCellWidget( row, column, lineEdit );
1687 adjustTransparencyCellWidth( row, column );
1689 if ( nBands == 1 && ( column == 0 || column == 1 ) )
1691 connect( lineEdit, &QLineEdit::textEdited,
this, &QgsRasterLayerProperties::transparencyCellTextEdited );
1693 tableTransparency->resizeColumnsToContents();
1696 void QgsRasterLayerProperties::setTransparencyCellValue(
int row,
int column,
double value )
1698 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
1699 if ( !lineEdit )
return;
1701 lineEdit->adjustSize();
1702 adjustTransparencyCellWidth( row, column );
1703 tableTransparency->resizeColumnsToContents();
1706 double QgsRasterLayerProperties::transparencyCellValue(
int row,
int column )
1708 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
1709 if ( !lineEdit || lineEdit->text().isEmpty() )
1711 return std::numeric_limits<double>::quiet_NaN();
1713 return lineEdit->text().toDouble();
1716 void QgsRasterLayerProperties::adjustTransparencyCellWidth(
int row,
int column )
1718 QLineEdit *lineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, column ) );
1719 if ( !lineEdit )
return;
1721 int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
1722 width = std::max( width, tableTransparency->columnWidth( column ) );
1724 lineEdit->setFixedWidth( width );
1727 void QgsRasterLayerProperties::pbnExportTransparentPixelValues_clicked()
1730 QString myLastDir = myQSettings.
value( QStringLiteral(
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
1731 QString myFileName = QFileDialog::getSaveFileName(
this, tr(
"Save File" ), myLastDir, tr(
"Textfile" ) +
" (*.txt)" );
1732 if ( !myFileName.isEmpty() )
1734 if ( !myFileName.endsWith( QLatin1String(
".txt" ), Qt::CaseInsensitive ) )
1736 myFileName = myFileName +
".txt";
1739 QFile myOutputFile( myFileName );
1740 if ( myOutputFile.open( QFile::WriteOnly | QIODevice::Truncate ) )
1742 QTextStream myOutputStream( &myOutputFile );
1743 myOutputStream <<
"# " << tr(
"QGIS Generated Transparent Pixel Value Export File" ) <<
'\n';
1744 if ( rasterIsMultiBandColor() )
1746 myOutputStream <<
"#\n#\n# " << tr(
"Red" ) <<
"\t" << tr(
"Green" ) <<
"\t" << tr(
"Blue" ) <<
"\t" << tr(
"Percent Transparent" );
1747 for (
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
1749 myOutputStream <<
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) <<
"\t"
1750 << QString::number( transparencyCellValue( myTableRunner, 1 ) ) <<
"\t"
1751 << QString::number( transparencyCellValue( myTableRunner, 2 ) ) <<
"\t"
1752 << QString::number( transparencyCellValue( myTableRunner, 3 ) );
1757 myOutputStream <<
"#\n#\n# " << tr(
"Value" ) <<
"\t" << tr(
"Percent Transparent" );
1759 for (
int myTableRunner = 0; myTableRunner < tableTransparency->rowCount(); myTableRunner++ )
1761 myOutputStream <<
'\n' << QString::number( transparencyCellValue( myTableRunner, 0 ) ) <<
"\t"
1762 << QString::number( transparencyCellValue( myTableRunner, 1 ) ) <<
"\t"
1763 << QString::number( transparencyCellValue( myTableRunner, 2 ) );
1769 QMessageBox::warning(
this, tr(
"Export Transparent Pixels" ), tr(
"Write access denied. Adjust the file permissions and try again.\n\n" ) );
1774 void QgsRasterLayerProperties::transparencyCellTextEdited(
const QString &text )
1777 QgsDebugMsg( QStringLiteral(
"text = %1" ).arg( text ) );
1783 int nBands = renderer->
usesBands().size();
1786 QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
1787 if ( !lineEdit )
return;
1790 for (
int r = 0; r < tableTransparency->rowCount(); r++ )
1792 for (
int c = 0;
c < tableTransparency->columnCount();
c++ )
1794 if ( tableTransparency->cellWidget( r,
c ) == sender() )
1801 if ( row != -1 )
break;
1803 QgsDebugMsg( QStringLiteral(
"row = %1 column =%2" ).arg( row ).arg( column ) );
1807 QLineEdit *toLineEdit =
dynamic_cast<QLineEdit *
>( tableTransparency->cellWidget( row, 1 ) );
1808 if ( !toLineEdit )
return;
1809 bool toChanged = mTransparencyToEdited.value( row );
1810 QgsDebugMsg( QStringLiteral(
"toChanged = %1" ).arg( toChanged ) );
1813 toLineEdit->setText( lineEdit->text() );
1816 else if ( column == 1 )
1818 setTransparencyToEdited( row );
1823 void QgsRasterLayerProperties::aboutToShowStyleMenu()
1827 QMenu *m = qobject_cast<QMenu *>( sender() );
1835 void QgsRasterLayerProperties::syncToLayer()
1840 setRendererWidget( renderer->
type() );
1846 void QgsRasterLayerProperties::setTransparencyToEdited(
int row )
1848 if ( row >= mTransparencyToEdited.size() )
1850 mTransparencyToEdited.resize( row + 1 );
1852 mTransparencyToEdited[row] =
true;
1859 bool isMetadataPanel = ( index ==
mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
1860 mBtnStyle->setVisible( ! isMetadataPanel );
1861 mBtnMetadata->setVisible( isMetadataPanel );
1863 if ( !mHistogramWidget )
1875 if ( index ==
mOptStackedWidget->indexOf( mOptsPage_Information ) || !mMetadataFilled )
1878 updateInformationContent();
1882 void QgsRasterLayerProperties::setEndAsStartStaticButton_clicked()
1884 mEndStaticDateTimeEdit->setDateTime( mStartStaticDateTimeEdit->dateTime() );
1887 void QgsRasterLayerProperties::pbnImportTransparentPixelValues_clicked()
1889 int myLineCounter = 0;
1890 bool myImportError =
false;
1893 QString myLastDir = myQSettings.
value( QStringLiteral(
"lastRasterFileFilterDir" ), QDir::homePath() ).toString();
1894 QString myFileName = QFileDialog::getOpenFileName(
this, tr(
"Open file" ), myLastDir, tr(
"Textfile" ) +
" (*.txt)" );
1895 QFile myInputFile( myFileName );
1896 if ( myInputFile.open( QFile::ReadOnly ) )
1898 QTextStream myInputStream( &myInputFile );
1899 QString myInputLine;
1900 if ( rasterIsMultiBandColor() )
1902 for (
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
1904 tableTransparency->removeRow( myTableRunner );
1907 while ( !myInputStream.atEnd() )
1910 myInputLine = myInputStream.readLine();
1911 if ( !myInputLine.isEmpty() )
1913 if ( !myInputLine.simplified().startsWith(
'#' ) )
1915 QStringList myTokens = myInputLine.split( QRegExp(
"\\s+" ), QString::SkipEmptyParts );
1916 if ( myTokens.count() != 4 )
1918 myImportError =
true;
1919 myBadLines = myBadLines + QString::number( myLineCounter ) +
":\t[" + myInputLine +
"]\n";
1923 tableTransparency->insertRow( tableTransparency->rowCount() );
1924 for (
int col = 0; col < 4; col++ )
1926 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
1935 for (
int myTableRunner = tableTransparency->rowCount() - 1; myTableRunner >= 0; myTableRunner-- )
1937 tableTransparency->removeRow( myTableRunner );
1940 while ( !myInputStream.atEnd() )
1943 myInputLine = myInputStream.readLine();
1944 if ( !myInputLine.isEmpty() )
1946 if ( !myInputLine.simplified().startsWith(
'#' ) )
1948 QStringList myTokens = myInputLine.split( QRegExp(
"\\s+" ), QString::SkipEmptyParts );
1949 if ( myTokens.count() != 3 && myTokens.count() != 2 )
1951 myImportError =
true;
1952 myBadLines = myBadLines + QString::number( myLineCounter ) +
":\t[" + myInputLine +
"]\n";
1956 if ( myTokens.count() == 2 )
1958 myTokens.insert( 1, myTokens[0] );
1960 tableTransparency->insertRow( tableTransparency->rowCount() );
1961 for (
int col = 0; col < 3; col++ )
1963 setTransparencyCell( tableTransparency->rowCount() - 1, col, myTokens[col].toDouble() );
1971 if ( myImportError )
1973 QMessageBox::warning(
this, tr(
"Import Transparent Pixels" ), tr(
"The following lines contained errors\n\n%1" ).arg( myBadLines ) );
1976 else if ( !myFileName.isEmpty() )
1978 QMessageBox::warning(
this, tr(
"Import Transparent Pixels" ), tr(
"Read access denied. Adjust the file permissions and try again.\n\n" ) );
1980 tableTransparency->resizeColumnsToContents();
1981 tableTransparency->resizeRowsToContents();
1984 void QgsRasterLayerProperties::pbnRemoveSelectedRow_clicked()
1986 if ( 0 < tableTransparency->rowCount() )
1988 tableTransparency->removeRow( tableTransparency->currentRow() );
1992 void QgsRasterLayerProperties::pixelSelected(
const QgsPointXY &canvasPoint,
const Qt::MouseButton &btn )
2002 if ( mMapCanvas && mPixelSelectorTool )
2011 int myWidth = mMapCanvas->
extent().
width() / mapUnitsPerPixel;
2012 int myHeight = mMapCanvas->
extent().
height() / mapUnitsPerPixel;
2016 QList<int> bands = renderer->
usesBands();
2018 QList<double> values;
2019 for (
int i = 0; i < bands.size(); ++i )
2021 int bandNo = bands.value( i );
2022 if ( myPixelMap.count( bandNo ) == 1 )
2024 if ( myPixelMap.value( bandNo ).isNull() )
2028 double value = myPixelMap.value( bandNo ).toDouble();
2029 QgsDebugMsg( QStringLiteral(
"value = %1" ).arg( value, 0,
'g', 17 ) );
2030 values.append( value );
2033 if ( bands.size() == 1 )
2036 values.insert( 1, values.value( 0 ) );
2038 tableTransparency->insertRow( tableTransparency->rowCount() );
2039 for (
int i = 0; i < values.size(); i++ )
2041 setTransparencyCell( tableTransparency->rowCount() - 1, i, values.value( i ) );
2043 setTransparencyCell( tableTransparency->rowCount() - 1, tableTransparency->columnCount() - 1, 100 );
2047 tableTransparency->resizeColumnsToContents();
2048 tableTransparency->resizeRowsToContents();
2051 void QgsRasterLayerProperties::toggleSaturationControls(
int grayscaleMode )
2054 if ( grayscaleMode == 0 )
2056 sliderSaturation->setEnabled(
true );
2057 spinBoxSaturation->setEnabled(
true );
2061 sliderSaturation->setEnabled(
false );
2062 spinBoxSaturation->setEnabled(
false );
2066 void QgsRasterLayerProperties::toggleColorizeControls(
bool colorizeEnabled )
2069 btnColorizeColor->setEnabled( colorizeEnabled );
2070 sliderColorizeStrength->setEnabled( colorizeEnabled );
2071 spinColorizeStrength->setEnabled( colorizeEnabled );
2075 QLinearGradient QgsRasterLayerProperties::redGradient()
2079 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2080 myGradient.setColorAt( 0.0, QColor( 242, 14, 25, 190 ) );
2081 myGradient.setColorAt( 0.5, QColor( 175, 29, 37, 190 ) );
2082 myGradient.setColorAt( 1.0, QColor( 114, 17, 22, 190 ) );
2085 QLinearGradient QgsRasterLayerProperties::greenGradient()
2089 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2090 myGradient.setColorAt( 0.0, QColor( 48, 168, 5, 190 ) );
2091 myGradient.setColorAt( 0.8, QColor( 36, 122, 4, 190 ) );
2092 myGradient.setColorAt( 1.0, QColor( 21, 71, 2, 190 ) );
2095 QLinearGradient QgsRasterLayerProperties::blueGradient()
2099 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2100 myGradient.setColorAt( 0.0, QColor( 30, 0, 106, 190 ) );
2101 myGradient.setColorAt( 0.2, QColor( 30, 72, 128, 190 ) );
2102 myGradient.setColorAt( 1.0, QColor( 30, 223, 196, 190 ) );
2105 QLinearGradient QgsRasterLayerProperties::grayGradient()
2109 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2110 myGradient.setColorAt( 0.0, QColor( 5, 5, 5, 190 ) );
2111 myGradient.setColorAt( 0.8, QColor( 122, 122, 122, 190 ) );
2112 myGradient.setColorAt( 1.0, QColor( 220, 220, 220, 190 ) );
2115 QLinearGradient QgsRasterLayerProperties::highlightGradient()
2119 QLinearGradient myGradient = QLinearGradient( mGradientWidth, 0, mGradientWidth, mGradientHeight );
2120 myGradient.setColorAt( 1.0, QColor( 255, 255, 255, 50 ) );
2121 myGradient.setColorAt( 0.5, QColor( 255, 255, 255, 100 ) );
2122 myGradient.setColorAt( 0.0, QColor( 255, 255, 255, 150 ) );
2133 void QgsRasterLayerProperties::loadDefaultStyle_clicked()
2135 bool defaultLoadedFlag =
false;
2138 if ( defaultLoadedFlag )
2145 QMessageBox::information(
this,
2146 tr(
"Default Style" ),
2152 void QgsRasterLayerProperties::saveDefaultStyle_clicked()
2158 bool defaultSavedFlag =
false;
2162 if ( !defaultSavedFlag )
2165 QMessageBox::information(
this,
2166 tr(
"Default Style" ),
2173 void QgsRasterLayerProperties::loadStyle_clicked()
2176 QString lastUsedDir = settings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
2178 QString fileName = QFileDialog::getOpenFileName(
2180 tr(
"Load layer properties from style file" ),
2182 tr(
"QGIS Layer Style File" ) +
" (*.qml)" );
2183 if ( fileName.isEmpty() )
2187 if ( !fileName.endsWith( QLatin1String(
".qml" ), Qt::CaseInsensitive ) )
2188 fileName += QLatin1String(
".qml" );
2192 bool defaultLoadedFlag =
false;
2193 QString message = mRasterLayer->
loadNamedStyle( fileName, defaultLoadedFlag );
2194 if ( defaultLoadedFlag )
2196 settings.
setValue( QStringLiteral(
"style/lastStyleDir" ), QFileInfo( fileName ).absolutePath() );
2201 QMessageBox::information(
this, tr(
"Save Style" ), message );
2206 void QgsRasterLayerProperties::saveStyleAs_clicked()
2209 QString lastUsedDir = settings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
2211 QString selectedFilter;
2212 QString outputFileName = QFileDialog::getSaveFileName(
2214 tr(
"Save layer properties as style file" ),
2216 tr(
"QGIS Layer Style File" ) +
" (*.qml)" +
";;" + tr(
"Styled Layer Descriptor" ) +
" (*.sld)",
2218 if ( outputFileName.isEmpty() )
2223 if ( selectedFilter.contains( QStringLiteral(
".qml" ), Qt::CaseInsensitive ) )
2226 type = StyleType::QML;
2231 type = StyleType::SLD;
2237 bool defaultLoadedFlag =
false;
2243 message = mRasterLayer->
saveNamedStyle( outputFileName, defaultLoadedFlag );
2248 message = mRasterLayer->
saveSldStyle( outputFileName, defaultLoadedFlag );
2252 if ( defaultLoadedFlag )
2254 settings.
setValue( QStringLiteral(
"style/lastStyleDir" ), QFileInfo( outputFileName ).absolutePath() );
2258 QMessageBox::information(
this, tr(
"Save Style" ), message );
2261 void QgsRasterLayerProperties::restoreWindowModality()
2276 void QgsRasterLayerProperties::loadMetadata()
2279 QString myLastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
2281 QString myFileName = QFileDialog::getOpenFileName(
this, tr(
"Load layer metadata from metadata file" ), myLastUsedDir,
2282 tr(
"QGIS Layer Metadata File" ) +
" (*.qmd)" );
2283 if ( myFileName.isNull() )
2289 bool defaultLoadedFlag =
false;
2293 if ( defaultLoadedFlag )
2300 QMessageBox::warning(
this, tr(
"Load Metadata" ), myMessage );
2303 QFileInfo myFI( myFileName );
2304 QString myPath = myFI.path();
2305 myQSettings.
setValue( QStringLiteral(
"style/lastStyleDir" ), myPath );
2310 void QgsRasterLayerProperties::saveMetadataAs()
2313 QString myLastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
2315 QString myOutputFileName = QFileDialog::getSaveFileName(
this, tr(
"Save Layer Metadata as QMD" ),
2316 myLastUsedDir, tr(
"QMD File" ) +
" (*.qmd)" );
2317 if ( myOutputFileName.isNull() )
2330 bool defaultLoadedFlag =
false;
2331 QString message = mRasterLayer->
saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
2332 if ( defaultLoadedFlag )
2333 myQSettings.
setValue( QStringLiteral(
"style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
2335 QMessageBox::information(
this, tr(
"Save Metadata" ), message );
2338 void QgsRasterLayerProperties::saveDefaultMetadata()
2342 bool defaultSavedFlag =
false;
2344 if ( !defaultSavedFlag )
2346 QMessageBox::warning(
this, tr(
"Default Metadata" ), errorMsg );
2350 void QgsRasterLayerProperties::loadDefaultMetadata()
2352 bool defaultLoadedFlag =
false;
2355 if ( defaultLoadedFlag )
2361 QMessageBox::information(
this, tr(
"Default Metadata" ), myMessage );
2366 void QgsRasterLayerProperties::toggleBuildPyramidsButton()
2368 if ( lbxPyramidResolutions->selectedItems().empty() )
2370 buttonBuildPyramids->setEnabled(
false );
2374 buttonBuildPyramids->setEnabled(
true );
2378 void QgsRasterLayerProperties::mResetColorRenderingBtn_clicked()
2380 mBlendModeComboBox->setBlendMode( QPainter::CompositionMode_SourceOver );
2381 mSliderBrightness->setValue( 0 );
2382 mSliderContrast->setValue( 0 );
2383 sliderSaturation->setValue( 0 );
2385 mColorizeCheck->setChecked(
false );
2386 sliderColorizeStrength->setValue( 100 );
2389 bool QgsRasterLayerProperties::rasterIsMultiBandColor()
2394 void QgsRasterLayerProperties::updateInformationContent()
2398 const QString html { mRasterLayer->
htmlMetadata().replace( QStringLiteral(
"<head>" ), QStringLiteral( R
"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
2399 mMetadataViewer->setHtml( html );
2400 mMetadataFilled = true;
2403 void QgsRasterLayerProperties::onCancel()
2409 QDomDocument doc( QStringLiteral(
"qgis" ) );
2410 int errorLine, errorColumn;
2411 doc.setContent( mOldStyle.
xmlData(),
false, &myMessage, &errorLine, &errorColumn );
2417 void QgsRasterLayerProperties::showHelp()
2419 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property(
"helpPage" );
2421 if ( helpPage.isValid() )
2427 QgsHelp::openHelp( QStringLiteral(
"working_with_raster/raster_properties.html" ) );