QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
18#include "qgsgui.h"
19#include "qgsmessagebar.h"
20#include "qgsrasterlayer.h"
21
22#include <QMessageBox>
23
24#include "moc_qgscreaterasterattributetabledialog.cpp"
25
27 : QDialog( parent )
28 , mRasterLayer( rasterLayer )
29{
30 Q_ASSERT( mRasterLayer );
31 Q_ASSERT( mRasterLayer->canCreateRasterAttributeTable() );
32
33 setupUi( this );
34
35 // Apparently, some drivers (HFA) ignore Min/Max fields and set them to generic,
36 // for this reason we disable the native support for thematic RATs (later in the loop)
37 bool nativeRatSupported { mRasterLayer->dataProvider()->providerCapabilities().testFlag( Qgis::RasterProviderCapability::NativeRasterAttributeTable ) };
38
39 connect( mNativeRadioButton, &QRadioButton::toggled, this, &QgsCreateRasterAttributeTableDialog::updateButtons );
40 connect( mDbfRadioButton, &QRadioButton::toggled, this, &QgsCreateRasterAttributeTableDialog::updateButtons );
41
42
43 // Check for existing RATs
44 QStringList existingRatsInfo;
45 if ( mRasterLayer->attributeTableCount() > 0 )
46 {
47 for ( int bandNo = 1; bandNo <= mRasterLayer->bandCount(); ++bandNo )
48 {
49 if ( QgsRasterAttributeTable *rat = mRasterLayer->attributeTable( bandNo ) )
50 {
51 // disable the native support for thematic RATs
52 if ( nativeRatSupported && rat->type() != Qgis::RasterAttributeTableType::Athematic )
53 {
54 nativeRatSupported = false;
55 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." ) );
56 }
57 if ( !rat->filePath().isEmpty() )
58 {
59 existingRatsInfo.push_back( tr( "Raster band %1 already has an associated attribute table at %2." ).arg( QString::number( bandNo ), rat->filePath() ) );
60 }
61 else
62 {
63 existingRatsInfo.push_back( tr( "Raster band %1 already has an associated attribute table." ).arg( bandNo ) );
64 }
65 }
66 }
67 }
68
69 if ( !existingRatsInfo.isEmpty() )
70 {
71 mCreateInfoLabel->setText( mCreateInfoLabel->text().append( QStringLiteral( "<br><ul><li>" ) + existingRatsInfo.join( QLatin1String( "</li><li>" ) ) ).append( QStringLiteral( "</ul>" ) ) );
72 mCreateInfoLabel->adjustSize();
73 mCreateInfoLabel->show();
74 }
75
76 if ( !nativeRatSupported )
77 {
78 mNativeRadioButton->setEnabled( false );
79 mDbfRadioButton->setChecked( true );
80 }
81 else
82 {
83 mDbfPathWidget->setFilter( QStringLiteral( "VAT DBF Files (*.vat.dbf)" ) );
84 if ( QFile::exists( mRasterLayer->dataProvider()->dataSourceUri() ) )
85 {
86 mDbfPathWidget->setFilePath( mRasterLayer->dataProvider()->dataSourceUri() + ".vat.dbf" );
87 }
88 }
89
90 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
91 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
92
93 updateButtons();
94
96}
97
99{
100 return mDbfPathWidget->filePath();
101}
102
104{
105 return mDbfRadioButton->isChecked();
106}
107
109{
110 return mOpenRat->isChecked();
111}
112
114{
115 mMessageBar = bar;
116}
117
119{
120 if ( !visible )
121 {
122 mOpenRat->setChecked( false );
123 }
124
125 mOpenRat->setVisible( visible );
126}
127
129{
130 QString errorMessage;
131 int bandNumber { 0 };
132 QgsRasterAttributeTable *rat { QgsRasterAttributeTable::createFromRaster( mRasterLayer, &bandNumber ) };
133 bool success { false };
134
135 if ( !rat )
136 {
137 notify( tr( "Error Creating Raster Attribute Table" ), tr( "The raster attribute table could not be created." ), Qgis::MessageLevel::Critical );
138 }
139 else
140 {
141 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, rat );
142
143 // Save it
144 const bool storageIsFile { saveToFile() };
145 if ( storageIsFile )
146 {
147 const QString destinationPath { filePath() };
148 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 )
149 {
150 success = rat->writeToFile( destinationPath, &errorMessage );
151 if ( !success )
152 {
153 notify( tr( "Error Saving Raster Attribute Table" ), errorMessage, Qgis::MessageLevel::Critical );
154 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
155 }
156 }
157 }
158 else
159 {
160 success = mRasterLayer->dataProvider()->writeNativeAttributeTable( &errorMessage ); //#spellok
161 if ( !success )
162 {
163 notify( tr( "Error Saving Raster Attribute Table" ), errorMessage, Qgis::MessageLevel::Critical );
164 mRasterLayer->dataProvider()->setAttributeTable( bandNumber, nullptr );
165 }
166 }
167 }
168
169 if ( success )
170 {
171 notify( tr( "Raster Attribute Table Saved" ), tr( "The new Raster Attribute Table was successfully created." ), Qgis::MessageLevel::Success );
172 }
173
174 QDialog::accept();
175}
176
177void QgsCreateRasterAttributeTableDialog::notify( const QString &title, const QString &message, Qgis::MessageLevel level )
178{
179 if ( mMessageBar )
180 {
181 mMessageBar->pushMessage( message, level );
182 }
183 else
184 {
185 switch ( level )
186 {
190 {
191 QMessageBox::information( nullptr, title, message );
192 break;
193 }
195 {
196 QMessageBox::warning( nullptr, title, message );
197 break;
198 }
200 {
201 QMessageBox::critical( nullptr, title, message );
202 break;
203 }
204 }
205 }
206}
207
208void QgsCreateRasterAttributeTableDialog::updateButtons()
209{
210 mDbfPathWidget->setEnabled( mDbfRadioButton->isChecked() );
211}
@ NativeRasterAttributeTable
Indicates that the provider supports native raster attribute table.
Definition qgis.h:4894
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:156
@ NoLevel
No level.
Definition qgis.h:161
@ Warning
Warning message.
Definition qgis.h:158
@ Critical
Critical/error message.
Definition qgis.h:159
@ Info
Information message.
Definition qgis.h:157
@ Success
Used for reporting a successful operation.
Definition qgis.h:160
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.
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:221
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.
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...
bool writeToFile(const QString &path, QString *errorMessage=nullptr)
Writes the Raster Attribute Table to a DBF file specified by path, optionally reporting any error in ...
Represents a raster layer.