QGIS API Documentation 3.41.0-Master (45a0abf3bec)
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" ),
135 tr( "The raster attribute table could not be created." ),
137 }
138 else
139 {
140 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, rat );
141
142 // Save it
143 const bool storageIsFile { saveToFile() };
144 if ( storageIsFile )
145 {
146 const QString destinationPath { filePath() };
147 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 )
148 {
149 success = rat->writeToFile( destinationPath, &errorMessage );
150 if ( ! success )
151 {
152 notify( tr( "Error Saving Raster Attribute Table" ),
153 errorMessage,
155 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
156 }
157 }
158 }
159 else
160 {
161 success = mRasterLayer->dataProvider()->writeNativeAttributeTable( &errorMessage ); //#spellok
162 if ( ! success )
163 {
164 notify( tr( "Error Saving Raster Attribute Table" ),
165 errorMessage,
167 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
168
169 }
170 }
171 }
172
173 if ( success )
174 {
175 notify( tr( "Raster Attribute Table Saved" ),
176 tr( "The new Raster Attribute Table was successfully created." ),
178 }
179
180 QDialog::accept();
181}
182
183void QgsCreateRasterAttributeTableDialog::notify( const QString &title, const QString &message, Qgis::MessageLevel level )
184{
185 if ( mMessageBar )
186 {
187 mMessageBar->pushMessage( message, level );
188 }
189 else
190 {
191 switch ( level )
192 {
196 {
197 QMessageBox::information( nullptr, title, message );
198 break;
199 }
201 {
202 QMessageBox::warning( nullptr, title, message );
203 break;
204 }
206 {
207 QMessageBox::critical( nullptr, title, message );
208 break;
209 }
210 }
211 }
212}
213
214void QgsCreateRasterAttributeTableDialog::updateButtons()
215{
216 mDbfPathWidget->setEnabled( mDbfRadioButton->isChecked() );
217}
@ 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:209
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.