QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
qgscreaterasterattributetabledialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscreaterasterattributetabledialog.cpp - QgsCreateRasterAttributeTableDialog
3
4 ---------------------
5 begin : 13.10.2022
6 copyright : (C) 2022 by Alessandro Pasotti
7 email : elpaso at itopen dot it
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
17#include "moc_qgscreaterasterattributetabledialog.cpp"
18#include "qgsrasterlayer.h"
19#include "qgsmessagebar.h"
20#include "qgsgui.h"
21#include <QMessageBox>
22
24 : QDialog( parent )
25 , mRasterLayer( rasterLayer )
26{
27 Q_ASSERT( mRasterLayer );
28 Q_ASSERT( mRasterLayer->canCreateRasterAttributeTable() );
29
30 setupUi( this );
31
32 // Apparently, some drivers (HFA) ignore Min/Max fields and set them to generic,
33 // for this reason we disable the native support for thematic RATs (later in the loop)
34 bool nativeRatSupported { mRasterLayer->dataProvider()->providerCapabilities().testFlag( Qgis::RasterProviderCapability::NativeRasterAttributeTable ) };
35
36 connect( mNativeRadioButton, &QRadioButton::toggled, this, &QgsCreateRasterAttributeTableDialog::updateButtons );
37 connect( mDbfRadioButton, &QRadioButton::toggled, this, &QgsCreateRasterAttributeTableDialog::updateButtons );
38
39
40 // Check for existing RATs
41 QStringList existingRatsInfo;
42 if ( mRasterLayer->attributeTableCount() > 0 )
43 {
44 for ( int bandNo = 1; bandNo <= mRasterLayer->bandCount(); ++bandNo )
45 {
46 if ( QgsRasterAttributeTable *rat = mRasterLayer->attributeTable( bandNo ) )
47 {
48 // disable the native support for thematic RATs
49 if ( nativeRatSupported && rat->type() != Qgis::RasterAttributeTableType::Athematic )
50 {
51 nativeRatSupported = false;
52 existingRatsInfo.push_back( tr( "The data provider supports attribute table storage but some drivers do not support 'thematic' types, for this reason the option is disabled." ) );
53 }
54 if ( !rat->filePath().isEmpty() )
55 {
56 existingRatsInfo.push_back( tr( "Raster band %1 already has an associated attribute table at %2." ).arg( QString::number( bandNo ), rat->filePath() ) );
57 }
58 else
59 {
60 existingRatsInfo.push_back( tr( "Raster band %1 already has an associated attribute table." ).arg( bandNo ) );
61 }
62 }
63 }
64 }
65
66 if ( !existingRatsInfo.isEmpty() )
67 {
68 mCreateInfoLabel->setText( mCreateInfoLabel->text().append( QStringLiteral( "<br><ul><li>" ) + existingRatsInfo.join( QLatin1String( "</li><li>" ) ) ).append( QStringLiteral( "</ul>" ) ) );
69 mCreateInfoLabel->adjustSize();
70 mCreateInfoLabel->show();
71 }
72
73 if ( !nativeRatSupported )
74 {
75 mNativeRadioButton->setEnabled( false );
76 mDbfRadioButton->setChecked( true );
77 }
78 else
79 {
80 mDbfPathWidget->setFilter( QStringLiteral( "VAT DBF Files (*.vat.dbf)" ) );
81 if ( QFile::exists( mRasterLayer->dataProvider()->dataSourceUri() ) )
82 {
83 mDbfPathWidget->setFilePath( mRasterLayer->dataProvider()->dataSourceUri() + ".vat.dbf" );
84 }
85 }
86
87 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
88 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
89
90 updateButtons();
91
93}
94
96{
97 return mDbfPathWidget->filePath();
98}
99
101{
102 return mDbfRadioButton->isChecked();
103}
104
106{
107 return mOpenRat->isChecked();
108}
109
111{
112 mMessageBar = bar;
113}
114
116{
117 if ( !visible )
118 {
119 mOpenRat->setChecked( false );
120 }
121
122 mOpenRat->setVisible( visible );
123}
124
126{
127 QString errorMessage;
128 int bandNumber { 0 };
129 QgsRasterAttributeTable *rat { QgsRasterAttributeTable::createFromRaster( mRasterLayer, &bandNumber ) };
130 bool success { false };
131
132 if ( !rat )
133 {
134 notify( tr( "Error Creating Raster Attribute Table" ), tr( "The raster attribute table could not be created." ), Qgis::MessageLevel::Critical );
135 }
136 else
137 {
138 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, rat );
139
140 // Save it
141 const bool storageIsFile { saveToFile() };
142 if ( storageIsFile )
143 {
144 const QString destinationPath { filePath() };
145 if ( !QFile::exists( destinationPath ) || QMessageBox::warning( nullptr, tr( "Confirm Overwrite" ), tr( "Are you sure you want to overwrite the existing attribute table at '%1'?" ).arg( destinationPath ), QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == QMessageBox::Yes )
146 {
147 success = rat->writeToFile( destinationPath, &errorMessage );
148 if ( !success )
149 {
150 notify( tr( "Error Saving Raster Attribute Table" ), errorMessage, Qgis::MessageLevel::Critical );
151 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
152 }
153 }
154 }
155 else
156 {
157 success = mRasterLayer->dataProvider()->writeNativeAttributeTable( &errorMessage ); //#spellok
158 if ( !success )
159 {
160 notify( tr( "Error Saving Raster Attribute Table" ), errorMessage, Qgis::MessageLevel::Critical );
161 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
162 }
163 }
164 }
165
166 if ( success )
167 {
168 notify( tr( "Raster Attribute Table Saved" ), tr( "The new Raster Attribute Table was successfully created." ), Qgis::MessageLevel::Success );
169 }
170
171 QDialog::accept();
172}
173
174void QgsCreateRasterAttributeTableDialog::notify( const QString &title, const QString &message, Qgis::MessageLevel level )
175{
176 if ( mMessageBar )
177 {
178 mMessageBar->pushMessage( message, level );
179 }
180 else
181 {
182 switch ( level )
183 {
187 {
188 QMessageBox::information( nullptr, title, message );
189 break;
190 }
192 {
193 QMessageBox::warning( nullptr, title, message );
194 break;
195 }
197 {
198 QMessageBox::critical( nullptr, title, message );
199 break;
200 }
201 }
202 }
203}
204
205void QgsCreateRasterAttributeTableDialog::updateButtons()
206{
207 mDbfPathWidget->setEnabled( mDbfRadioButton->isChecked() );
208}
@ NativeRasterAttributeTable
Indicates that the provider supports native raster attribute table.
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:154
@ NoLevel
No level.
Definition qgis.h:159
@ Warning
Warning message.
Definition qgis.h:156
@ Critical
Critical/error message.
Definition qgis.h:157
@ Info
Information message.
Definition qgis.h:155
@ Success
Used for reporting a successful operation.
Definition qgis.h:158
QgsCreateRasterAttributeTableDialog(QgsRasterLayer *rasterLayer, QWidget *parent=nullptr)
Creates a new QgsCreateRasterAttributeTableDialog.
void setOpenWhenDoneVisible(bool visible)
Sets the visibility of the "Open newly created raster attribute table" option to visible,...
QString filePath() const
Returns the file path in case of VAT.DBF save option.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
bool openWhenDone() const
Returns true if the option to open the newly created attribute table is checked.
bool saveToFile() const
Returns true if the option to save to a file is selected.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition qgsgui.cpp:210
A bar for displaying non-blocking messages to the user.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
The QgsRasterAttributeTable class represents a Raster Attribute Table (RAT).
static QgsRasterAttributeTable * createFromRaster(QgsRasterLayer *rasterLayer, int *bandNumber=nullptr)
Creates a new Raster Attribute Table from a raster layer, the renderer must be Paletted or SingleBand...
virtual bool writeNativeAttributeTable(QString *errorMessage=nullptr)
Writes the native attribute table, optionally reporting any error in errorMessage,...
void setAttributeTable(int bandNumber, QgsRasterAttributeTable *attributeTable)
Set the attribute table to attributeTable for the specified bandNumber, if the attributeTable is null...
virtual Qgis::RasterProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
Represents a raster layer.
bool canCreateRasterAttributeTable()
Returns true if the raster renderer is suitable for creation of a raster attribute table.
QgsRasterAttributeTable * attributeTable(int bandNumber) const
Returns the (possibly NULL) raster attribute table for the given band bandNumber.
int attributeTableCount() const
Returns the number of attribute tables for the raster by counting the number of bands that have an as...
int bandCount() const
Returns the number of bands in this layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.