QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsrasterlayersaveasdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterlayersaveasdialog.cpp
3  ---------------------
4  begin : May 2012
5  copyright : (C) 2012 by Marco Hugentobler
6  email : marco dot hugentobler at sourcepole dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 #include "qgsapplication.h"
16 #include "qgsgdalutils.h"
17 #include "qgslogger.h"
18 #include "qgscoordinatetransform.h"
19 #include "qgsrasterlayer.h"
21 #include "qgsrasterdataprovider.h"
23 #include "qgsrasterrenderer.h"
24 #include "qgsrastertransparency.h"
26 #include "qgssettings.h"
27 #include "qgsrasterfilewriter.h"
28 #include "qgsvectorlayer.h"
29 #include "cpl_string.h"
30 #include "qgsproject.h"
31 #include <gdal.h>
32 #include "qgsmessagelog.h"
33 #include "qgsgui.h"
34 #include "qgsdoublevalidator.h"
35 #include "qgsdatums.h"
36 
37 #include <QFileDialog>
38 #include <QMessageBox>
39 #include <QRegularExpression>
40 
42  QgsRasterDataProvider *sourceProvider, const QgsRectangle &currentExtent,
43  const QgsCoordinateReferenceSystem &layerCrs, const QgsCoordinateReferenceSystem &currentCrs,
44  QWidget *parent, Qt::WindowFlags f )
45  : QDialog( parent, f )
46  , mRasterLayer( rasterLayer )
47  , mDataProvider( sourceProvider )
48  , mCurrentExtent( currentExtent )
49  , mLayerCrs( layerCrs )
50  , mCurrentCrs( currentCrs )
51  , mResolutionState( OriginalResolution )
52 {
53  setupUi( this );
55  connect( mRawModeRadioButton, &QRadioButton::toggled, this, &QgsRasterLayerSaveAsDialog::mRawModeRadioButton_toggled );
56  connect( mFormatComboBox, &QComboBox::currentTextChanged, this, &QgsRasterLayerSaveAsDialog::mFormatComboBox_currentIndexChanged );
57  connect( mResolutionRadioButton, &QRadioButton::toggled, this, &QgsRasterLayerSaveAsDialog::mResolutionRadioButton_toggled );
58  connect( mOriginalResolutionPushButton, &QPushButton::clicked, this, &QgsRasterLayerSaveAsDialog::mOriginalResolutionPushButton_clicked );
59  connect( mXResolutionLineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerSaveAsDialog::mXResolutionLineEdit_textEdited );
60  connect( mYResolutionLineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerSaveAsDialog::mYResolutionLineEdit_textEdited );
61  connect( mOriginalSizePushButton, &QPushButton::clicked, this, &QgsRasterLayerSaveAsDialog::mOriginalSizePushButton_clicked );
62  connect( mColumnsLineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerSaveAsDialog::mColumnsLineEdit_textEdited );
63  connect( mRowsLineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerSaveAsDialog::mRowsLineEdit_textEdited );
64  connect( mAddNoDataManuallyToolButton, &QPushButton::clicked, this, &QgsRasterLayerSaveAsDialog::mAddNoDataManuallyToolButton_clicked );
65  connect( mLoadTransparentNoDataToolButton, &QPushButton::clicked, this, &QgsRasterLayerSaveAsDialog::mLoadTransparentNoDataToolButton_clicked );
66  connect( mRemoveSelectedNoDataToolButton, &QPushButton::clicked, this, &QgsRasterLayerSaveAsDialog::mRemoveSelectedNoDataToolButton_clicked );
67  connect( mRemoveAllNoDataToolButton, &QPushButton::clicked, this, &QgsRasterLayerSaveAsDialog::mRemoveAllNoDataToolButton_clicked );
68  connect( mTileModeCheckBox, &QCheckBox::toggled, this, &QgsRasterLayerSaveAsDialog::mTileModeCheckBox_toggled );
69  connect( mPyramidsGroupBox, &QgsCollapsibleGroupBox::toggled, this, &QgsRasterLayerSaveAsDialog::mPyramidsGroupBox_toggled );
70  mAddNoDataManuallyToolButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyAdd.svg" ) ) );
71  mLoadTransparentNoDataToolButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionFileOpen.svg" ) ) );
72  mRemoveSelectedNoDataToolButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/symbologyRemove.svg" ) ) );
73  mRemoveAllNoDataToolButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemove.svg" ) ) );
74 
75  mNoDataTableWidget->setColumnCount( 2 );
76  mNoDataTableWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "From" ) ) );
77  mNoDataTableWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "To" ) ) );
78 
79  mRawModeRadioButton_toggled( true );
80 
81  setValidators();
82 
83  toggleResolutionSize();
84 
85  insertAvailableOutputFormats();
86 
87  //fill reasonable default values depending on the provider
88  if ( mDataProvider )
89  {
90  if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
91  {
92  setOriginalResolution();
93  int xSize = mDataProvider->xSize();
94  int ySize = mDataProvider->ySize();
95  mMaximumSizeXLineEdit->setText( QString::number( xSize ) );
96  mMaximumSizeYLineEdit->setText( QString::number( ySize ) );
97  }
98  else //wms, sometimes wcs
99  {
100  mTileModeCheckBox->setChecked( true );
101  mMaximumSizeXLineEdit->setText( QString::number( 2000 ) );
102  mMaximumSizeYLineEdit->setText( QString::number( 2000 ) );
103  }
104 
105  // setup creation option widget
106  mCreateOptionsWidget->setProvider( mDataProvider->name() );
107  if ( mDataProvider->name() == QLatin1String( "gdal" ) )
108  {
109  mCreateOptionsWidget->setFormat( mFormatComboBox->currentData().toString() );
110  }
111  mCreateOptionsWidget->setRasterLayer( mRasterLayer );
112  mCreateOptionsWidget->update();
113  }
114 
115  // Only do pyramids if dealing directly with GDAL.
116  if ( mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::BuildPyramids )
117  {
118  // setup pyramids option widget
119  // mPyramidsOptionsWidget->createOptionsWidget()->setType( QgsRasterFormatSaveOptionsWidget::ProfileLineEdit );
120  mPyramidsOptionsWidget->createOptionsWidget()->setRasterLayer( mRasterLayer );
121 
122  // TODO enable "use existing", has no effect for now, because using Create() in gdal provider
123  // if ( ! mDataProvider->hasPyramids() )
124  // mPyramidsButtonGroup->button( QgsRaster::PyramidsCopyExisting )->setEnabled( false );
125  mPyramidsUseExistingCheckBox->setEnabled( false );
126  mPyramidsUseExistingCheckBox->setVisible( false );
127 
128  populatePyramidsLevels();
129  connect( mPyramidsOptionsWidget, &QgsRasterPyramidsOptionsWidget::overviewListChanged,
130  this, &QgsRasterLayerSaveAsDialog::populatePyramidsLevels );
131  }
132  else
133  {
134  mPyramidsGroupBox->setEnabled( false );
135  }
136 
137  // restore checked state for most groupboxes (default is to restore collapsed state)
138  // create options and pyramids will be preset, if user has selected defaults in the gdal options dlg
139  mCreateOptionsGroupBox->setSaveCheckedState( true );
140  //mTilesGroupBox->setSaveCheckedState( true );
141  // don't restore nodata, it needs user input
142  // pyramids are not necessarily built every time
143 
144  try
145  {
146  const QgsDatumEnsemble ensemble = mLayerCrs.datumEnsemble();
147  if ( ensemble.isValid() )
148  {
149  mCrsSelector->setSourceEnsemble( ensemble.name() );
150  }
151  }
152  catch ( QgsNotSupportedException & )
153  {
154  }
155  mCrsSelector->setShowAccuracyWarnings( true );
156 
157  mCrsSelector->setLayerCrs( mLayerCrs );
158  //default to layer CRS - see https://github.com/qgis/QGIS/issues/22211 for discussion
159  mCrsSelector->setCrs( mLayerCrs );
160 
161  connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged,
162  this, &QgsRasterLayerSaveAsDialog::crsChanged );
163 
164  QPushButton *okButton = mButtonBox->button( QDialogButtonBox::Ok );
165  if ( okButton )
166  {
167  okButton->setEnabled( false );
168  }
169 
170 #ifdef Q_OS_WIN
171  mHelpButtonBox->setVisible( false );
172  mButtonBox->addButton( QDialogButtonBox::Help );
173  connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerSaveAsDialog::showHelp );
174 #else
175  connect( mHelpButtonBox, &QDialogButtonBox::helpRequested, this, &QgsRasterLayerSaveAsDialog::showHelp );
176 #endif
177  connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsRasterLayerSaveAsDialog::accept );
178  connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsRasterLayerSaveAsDialog::reject );
179 
180  mExtentGroupBox->setOutputCrs( outputCrs() );
181  mExtentGroupBox->setOriginalExtent( mDataProvider->extent(), mLayerCrs );
182  mExtentGroupBox->setCurrentExtent( mCurrentExtent, mCurrentCrs );
183  mExtentGroupBox->setOutputExtentFromOriginal();
184  connect( mExtentGroupBox, &QgsExtentGroupBox::extentChanged, this, &QgsRasterLayerSaveAsDialog::extentChanged );
185 
186  recalcResolutionSize();
187 
188  QgsSettings settings;
189 
190  if ( mTileModeCheckBox->isChecked() )
191  {
192  mTilesGroupBox->show();
193  mFilename->setStorageMode( QgsFileWidget::GetDirectory );
194  mFilename->setDialogTitle( tr( "Select Output Directory" ) );
195  }
196  else
197  {
198  mTilesGroupBox->hide();
199  mFilename->setStorageMode( QgsFileWidget::SaveFile );
200  mFilename->setDialogTitle( tr( "Save Layer As" ) );
201  }
202 
203  mFilename->setDefaultRoot( settings.value( QStringLiteral( "UI/lastRasterFileDir" ), QDir::homePath() ).toString() );
204  connect( mFilename, &QgsFileWidget::fileChanged, this, [ = ]( const QString & filePath )
205  {
206  QgsSettings settings;
207  QFileInfo tmplFileInfo( filePath );
208  settings.setValue( QStringLiteral( "UI/lastRasterFileDir" ), tmplFileInfo.absolutePath() );
209 
210  if ( !filePath.isEmpty() && mLayerName->isEnabled() )
211  {
212  QFileInfo fileInfo( filePath );
213  mLayerName->setText( fileInfo.baseName() );
214  }
215 
216  if ( mTileModeCheckBox->isChecked() )
217  {
218  QString fileName = filePath;
219  Q_FOREVER
220  {
221  // TODO: would not it be better to select .vrt file instead of directory?
222  //fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), QString(), tr( "VRT" ) + " (*.vrt *.VRT)" );
223  if ( fileName.isEmpty() )
224  break; // canceled
225 
226  // Check if directory is empty
227  QDir dir( fileName );
228  QString baseName = QFileInfo( fileName ).baseName();
229  QStringList filters;
230  filters << QStringLiteral( "%1.*" ).arg( baseName );
231  QStringList files = dir.entryList( filters );
232  if ( files.isEmpty() )
233  break;
234 
235  if ( QMessageBox::warning( this, tr( "Save Raster Layer" ),
236  tr( "The directory %1 contains files which will be overwritten: %2" ).arg( dir.absolutePath(), files.join( QLatin1String( ", " ) ) ),
237  QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Ok )
238  break;
239 
240  fileName = QFileDialog::getExistingDirectory( this, tr( "Select output directory" ), tmplFileInfo.absolutePath() );
241  }
242  }
243 
244  QPushButton *okButton = mButtonBox->button( QDialogButtonBox::Ok );
245  if ( !okButton )
246  {
247  return;
248  }
249  okButton->setEnabled( tmplFileInfo.absoluteDir().exists() );
250  } );
251 }
252 
253 void QgsRasterLayerSaveAsDialog::insertAvailableOutputFormats()
254 {
255  GDALAllRegister();
256 
257  int nDrivers = GDALGetDriverCount();
258  QMap< int, QPair< QString, QString > > topPriorityDrivers;
259  QMap< QString, QString > lowPriorityDrivers;
260 
261  for ( int i = 0; i < nDrivers; ++i )
262  {
263  GDALDriverH driver = GDALGetDriver( i );
264  if ( driver )
265  {
266  if ( QgsGdalUtils::supportsRasterCreate( driver ) )
267  {
268  QString driverShortName = GDALGetDriverShortName( driver );
269  QString driverLongName = GDALGetDriverLongName( driver );
270  if ( driverShortName == QLatin1String( "MEM" ) )
271  {
272  // in memory rasters are not (yet) supported because the GDAL dataset handle
273  // would need to be passed directly to QgsRasterLayer (it is not possible to
274  // close it in raster calculator and reopen the dataset again in raster layer)
275  continue;
276  }
277  else if ( driverShortName == QLatin1String( "VRT" ) )
278  {
279  // skip GDAL vrt driver, since we handle that format manually
280  continue;
281  }
282  else if ( driverShortName == QLatin1String( "GTiff" ) )
283  {
284  // always list geotiff first
285  topPriorityDrivers.insert( 1, qMakePair( driverLongName, driverShortName ) );
286  }
287  else if ( driverShortName == QLatin1String( "GPKG" ) )
288  {
289  // and gpkg second
290  topPriorityDrivers.insert( 2, qMakePair( driverLongName, driverShortName ) );
291  }
292  else
293  {
294  lowPriorityDrivers.insert( driverLongName, driverShortName );
295  }
296  }
297  }
298  }
299 
300  // will be sorted by priority, so that geotiff and geopackage are listed first
301  for ( auto priorityDriversIt = topPriorityDrivers.constBegin(); priorityDriversIt != topPriorityDrivers.constEnd(); ++priorityDriversIt )
302  {
303  mFormatComboBox->addItem( priorityDriversIt.value().first, priorityDriversIt.value().second );
304  }
305  // will be sorted by driver name
306  for ( auto lowPriorityDriversIt = lowPriorityDrivers.constBegin(); lowPriorityDriversIt != lowPriorityDrivers.constEnd(); ++lowPriorityDriversIt )
307  {
308  mFormatComboBox->addItem( lowPriorityDriversIt.key(), lowPriorityDriversIt.value() );
309  }
310 
311 }
312 
313 void QgsRasterLayerSaveAsDialog::setValidators()
314 {
315  mXResolutionLineEdit->setValidator( new QgsDoubleValidator( this ) );
316  mYResolutionLineEdit->setValidator( new QgsDoubleValidator( this ) );
317  mColumnsLineEdit->setValidator( new QIntValidator( this ) );
318  mRowsLineEdit->setValidator( new QIntValidator( this ) );
319  mMaximumSizeXLineEdit->setValidator( new QIntValidator( this ) );
320  mMaximumSizeYLineEdit->setValidator( new QIntValidator( this ) );
321 }
322 
323 void QgsRasterLayerSaveAsDialog::mFormatComboBox_currentIndexChanged( const QString & )
324 {
325  //gdal-specific
326  if ( mDataProvider && mDataProvider->name() == QLatin1String( "gdal" ) )
327  {
328  mCreateOptionsWidget->setFormat( outputFormat() );
329  mCreateOptionsWidget->update();
330  }
331 
332  QStringList extensions = QgsRasterFileWriter::extensionsForFormat( outputFormat() );
333  QString filter;
334  if ( extensions.empty() )
335  filter = tr( "All files (*.*)" );
336  else
337  {
338  filter = QStringLiteral( "%1 (*.%2);;%3" ).arg( mFormatComboBox->currentText(),
339  extensions.join( QLatin1String( " *." ) ),
340  tr( "All files (*.*)" ) );
341  }
342  mFilename->setFilter( filter );
343 
344  // Disable mTileModeCheckBox for GeoPackages
345  mTileModeCheckBox->setEnabled( outputFormat() != QLatin1String( "GPKG" ) );
346  mFilename->setConfirmOverwrite( outputFormat() != QLatin1String( "GPKG" ) );
347  mLayerName->setEnabled( outputFormat() == QLatin1String( "GPKG" ) );
348  if ( mLayerName->isEnabled() )
349  {
350  QString layerName = QFileInfo( mFilename->filePath() ).baseName();
351  mLayerName->setText( layerName );
352  mTileModeCheckBox->setChecked( false );
353  }
354  else
355  {
356  mLayerName->setText( QString() );
357  }
358 }
359 
361 {
362  return mColumnsLineEdit->text().toInt();
363 }
364 
366 {
367  return mRowsLineEdit->text().toInt();
368 }
369 
371 {
372  return QgsDoubleValidator::toDouble( mXResolutionLineEdit->text() );
373 }
374 
376 {
377  return QgsDoubleValidator::toDouble( mYResolutionLineEdit->text() );
378 }
379 
381 {
382  return mMaximumSizeXLineEdit->text().toInt();
383 }
384 
386 {
387  return mMaximumSizeYLineEdit->text().toInt();
388 }
389 
391 {
392  return mTileModeCheckBox->isChecked();
393 }
394 
396 {
397  return mAddToCanvas->isChecked();
398 }
399 
401 {
402  mAddToCanvas->setChecked( checked );
403 }
404 
406 {
407  QString fileName = mFilename->filePath();
408 
409  if ( mFilename->storageMode() != QgsFileWidget::GetDirectory )
410  {
411  QStringList extensions = QgsRasterFileWriter::extensionsForFormat( outputFormat() );
412  QString defaultExt;
413  if ( !extensions.empty() )
414  {
415  defaultExt = extensions.at( 0 );
416  }
417 
418  // ensure the user never omits the extension from the file name
419  QFileInfo fi( fileName );
420  if ( !fileName.isEmpty() && fi.suffix().isEmpty() && !defaultExt.isEmpty() )
421  {
422  fileName += '.' + defaultExt;
423  }
424  }
425 
426  return fileName;
427 }
428 
430 {
431  if ( mLayerName->text().isEmpty() && outputFormat() == QLatin1String( "GPKG" ) && !mTileModeCheckBox->isChecked() )
432  {
433  // Always return layer name for GeoPackages
434  return QFileInfo( mFilename->filePath() ).baseName();
435  }
436  else
437  {
438  return mLayerName->text();
439  }
440 }
441 
443 {
444  return mFormatComboBox->currentData().toString();
445 }
446 
448 {
449  QStringList options = mCreateOptionsGroupBox->isChecked() ? mCreateOptionsWidget->options() : QStringList();
450  if ( outputFormat() == QLatin1String( "GPKG" ) )
451  {
452  // Overwrite the GPKG table options
453  int indx = options.indexOf( QRegularExpression( "^RASTER_TABLE=.*", QRegularExpression::CaseInsensitiveOption | QRegularExpression::MultilineOption ) );
454  if ( indx > -1 )
455  {
456  options.replace( indx, QStringLiteral( "RASTER_TABLE=%1" ).arg( outputLayerName() ) );
457  }
458  else
459  {
460  options.append( QStringLiteral( "RASTER_TABLE=%1" ).arg( outputLayerName() ) );
461  }
462 
463  // Only enable the append mode if the layer doesn't exist yet. For existing layers a 'confirm overwrite' dialog will be shown.
464  if ( !outputLayerExists() )
465  {
466  indx = options.indexOf( QRegularExpression( "^APPEND_SUBDATASET=.*", QRegularExpression::CaseInsensitiveOption | QRegularExpression::MultilineOption ) );
467  if ( indx > -1 )
468  {
469  options.replace( indx, QStringLiteral( "APPEND_SUBDATASET=YES" ) );
470  }
471  else
472  {
473  options.append( QStringLiteral( "APPEND_SUBDATASET=YES" ) );
474  }
475  }
476  }
477  return options;
478 }
479 
481 {
482  return mExtentGroupBox->outputExtent();
483 }
484 
486 {
487  mFormatLabel->hide();
488  mFormatComboBox->hide();
489 }
490 
492 {
493  mSaveAsLabel->hide();
494  mFilename->hide();
495  QPushButton *okButton = mButtonBox->button( QDialogButtonBox::Ok );
496  if ( okButton )
497  {
498  okButton->setEnabled( true );
499  }
500 }
501 
502 void QgsRasterLayerSaveAsDialog::toggleResolutionSize()
503 {
504  bool hasResolution = mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::Size;
505 
506  bool on = mResolutionRadioButton->isChecked();
507  mXResolutionLineEdit->setEnabled( on );
508  mYResolutionLineEdit->setEnabled( on );
509  mOriginalResolutionPushButton->setEnabled( on && hasResolution );
510  mColumnsLineEdit->setEnabled( !on );
511  mRowsLineEdit->setEnabled( !on );
512  mOriginalSizePushButton->setEnabled( !on && hasResolution );
513 }
514 
515 void QgsRasterLayerSaveAsDialog::setOriginalResolution()
516 {
517  double xRes, yRes;
518 
519  if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
520  {
521  xRes = mDataProvider->extent().width() / mDataProvider->xSize();
522  yRes = mDataProvider->extent().height() / mDataProvider->ySize();
523  }
524  else
525  {
526  // Init to something if no original resolution is available
527  xRes = yRes = mDataProvider->extent().width() / 100;
528  }
529  setResolution( xRes, yRes, mLayerCrs );
530  mResolutionState = OriginalResolution;
531  recalcSize();
532 }
533 
534 void QgsRasterLayerSaveAsDialog::setResolution( double xRes, double yRes, const QgsCoordinateReferenceSystem &srcCrs )
535 {
536  if ( srcCrs != outputCrs() )
537  {
538  // We reproject pixel rectangle from center of selected extent, of course, it gives
539  // bigger xRes,yRes than reprojected edges (envelope), it may also be that
540  // close to margins are higher resolutions (even very, too high)
541  // TODO: consider more precise resolution calculation
542 
543  QgsPointXY center = outputRectangle().center();
545  QgsPointXY srsCenter = ct.transform( center, Qgis::TransformDirection::Reverse );
546 
547  QgsRectangle srcExtent( srsCenter.x() - xRes / 2, srsCenter.y() - yRes / 2, srsCenter.x() + xRes / 2, srsCenter.y() + yRes / 2 );
548 
549  QgsRectangle extent = ct.transform( srcExtent );
550  xRes = extent.width();
551  yRes = extent.height();
552  }
553  mXResolutionLineEdit->setText( QLocale().toString( xRes ) );
554  mYResolutionLineEdit->setText( QLocale().toString( yRes ) );
555 }
556 
557 void QgsRasterLayerSaveAsDialog::recalcSize()
558 {
559  QgsRectangle extent = outputRectangle();
560  int xSize = xResolution() != 0 ? static_cast<int>( std::round( extent.width() / xResolution() ) ) : 0;
561  int ySize = yResolution() != 0 ? static_cast<int>( std::round( extent.height() / yResolution() ) ) : 0;
562  mColumnsLineEdit->setText( QString::number( xSize ) );
563  mRowsLineEdit->setText( QString::number( ySize ) );
564  updateResolutionStateMsg();
565 }
566 
567 void QgsRasterLayerSaveAsDialog::setOriginalSize()
568 {
569  mColumnsLineEdit->setText( QString::number( mDataProvider->xSize() ) );
570  mRowsLineEdit->setText( QString::number( mDataProvider->ySize() ) );
571  recalcResolution();
572 }
573 
574 void QgsRasterLayerSaveAsDialog::recalcResolution()
575 {
576  QgsRectangle extent = outputRectangle();
577  double xRes = nColumns() != 0 ? extent.width() / nColumns() : 0;
578  double yRes = nRows() != 0 ? extent.height() / nRows() : 0;
579  mXResolutionLineEdit->setText( QLocale().toString( xRes ) );
580  mYResolutionLineEdit->setText( QLocale().toString( yRes ) );
581  updateResolutionStateMsg();
582 }
583 
584 void QgsRasterLayerSaveAsDialog::recalcResolutionSize()
585 {
586  if ( mResolutionRadioButton->isChecked() )
587  {
588  recalcSize();
589  }
590  else
591  {
592  mResolutionState = UserResolution;
593  recalcResolution();
594  }
595 }
596 
597 void QgsRasterLayerSaveAsDialog::updateResolutionStateMsg()
598 {
599  QString msg;
600  switch ( mResolutionState )
601  {
602  case OriginalResolution:
603  msg = tr( "layer" );
604  break;
605  case UserResolution:
606  msg = tr( "user defined" );
607  break;
608  default:
609  break;
610  }
611  msg = tr( "Resolution (current: %1)" ).arg( msg );
612  mResolutionGroupBox->setTitle( msg );
613 }
614 
615 void QgsRasterLayerSaveAsDialog::extentChanged()
616 {
617  // Whenever extent changes with fixed size, original resolution is lost
618  if ( mSizeRadioButton->isChecked() )
619  {
620  mResolutionState = UserResolution;
621  }
622  recalcResolutionSize();
623 }
624 
625 void QgsRasterLayerSaveAsDialog::crsChanged()
626 {
627  if ( outputCrs() != mPreviousCrs )
628  {
629  mExtentGroupBox->setOutputCrs( outputCrs() );
630 
631  // Reset resolution
632  if ( mResolutionRadioButton->isChecked() )
633  {
634  if ( mResolutionState == OriginalResolution )
635  {
636  setOriginalResolution();
637  }
638  else
639  {
640  // reset from present resolution and present crs
641  setResolution( xResolution(), yResolution(), mPreviousCrs );
642  }
643  }
644  else
645  {
646  // Size does not change, we just recalc resolution from new extent
647  recalcResolution();
648  }
649  }
650  mPreviousCrs = outputCrs();
651 }
652 
654 {
655  return mCrsSelector->crs();
656 }
657 
659 {
660  if ( mRenderedModeRadioButton->isChecked() ) return RenderedImageMode;
661  return RawDataMode;
662 }
663 
664 void QgsRasterLayerSaveAsDialog::mRawModeRadioButton_toggled( bool checked )
665 {
666  mNoDataGroupBox->setEnabled( checked && mDataProvider->bandCount() == 1 );
667 }
668 
669 void QgsRasterLayerSaveAsDialog::mAddNoDataManuallyToolButton_clicked()
670 {
671  addNoDataRow( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
672 }
673 
674 void QgsRasterLayerSaveAsDialog::mLoadTransparentNoDataToolButton_clicked()
675 {
676  if ( !mRasterLayer->renderer() ) return;
677  const QgsRasterTransparency *rasterTransparency = mRasterLayer->renderer()->rasterTransparency();
678  if ( !rasterTransparency ) return;
679 
680  const auto constTransparentSingleValuePixelList = rasterTransparency->transparentSingleValuePixelList();
681  for ( const QgsRasterTransparency::TransparentSingleValuePixel &transparencyPixel : constTransparentSingleValuePixelList )
682  {
683  if ( transparencyPixel.percentTransparent == 100 )
684  {
685  addNoDataRow( transparencyPixel.min, transparencyPixel.max );
686  if ( transparencyPixel.min != transparencyPixel.max )
687  {
688  setNoDataToEdited( mNoDataTableWidget->rowCount() - 1 );
689  }
690  }
691  }
692 }
693 
694 void QgsRasterLayerSaveAsDialog::mRemoveSelectedNoDataToolButton_clicked()
695 {
696  mNoDataTableWidget->removeRow( mNoDataTableWidget->currentRow() );
697 }
698 
699 void QgsRasterLayerSaveAsDialog::mRemoveAllNoDataToolButton_clicked()
700 {
701  while ( mNoDataTableWidget->rowCount() > 0 )
702  {
703  mNoDataTableWidget->removeRow( 0 );
704  }
705 }
706 
707 void QgsRasterLayerSaveAsDialog::addNoDataRow( double min, double max )
708 {
709  mNoDataTableWidget->insertRow( mNoDataTableWidget->rowCount() );
710  for ( int i = 0; i < 2; i++ )
711  {
712  double value = i == 0 ? min : max;
713  QLineEdit *lineEdit = new QLineEdit();
714  lineEdit->setFrame( false );
715  lineEdit->setContentsMargins( 1, 1, 1, 1 );
716  QString valueString;
717  switch ( mRasterLayer->dataProvider()->sourceDataType( 1 ) )
718  {
721  lineEdit->setValidator( new QgsDoubleValidator( nullptr ) );
722  if ( !std::isnan( value ) )
723  {
724  valueString = QgsRasterBlock::printValue( value );
725  }
726  break;
727  default:
728  lineEdit->setValidator( new QIntValidator( nullptr ) );
729  if ( !std::isnan( value ) )
730  {
731  valueString = QLocale().toString( static_cast<int>( value ) );
732  }
733  break;
734  }
735  lineEdit->setText( valueString );
736  mNoDataTableWidget->setCellWidget( mNoDataTableWidget->rowCount() - 1, i, lineEdit );
737 
738  adjustNoDataCellWidth( mNoDataTableWidget->rowCount() - 1, i );
739 
740  connect( lineEdit, &QLineEdit::textEdited, this, &QgsRasterLayerSaveAsDialog::noDataCellTextEdited );
741  }
742  mNoDataTableWidget->resizeColumnsToContents();
743  mNoDataTableWidget->resizeRowsToContents();
744 }
745 
746 void QgsRasterLayerSaveAsDialog::noDataCellTextEdited( const QString &text )
747 {
748  Q_UNUSED( text )
749 
750  QLineEdit *lineEdit = qobject_cast<QLineEdit *>( sender() );
751  if ( !lineEdit ) return;
752  int row = -1;
753  int column = -1;
754  for ( int r = 0; r < mNoDataTableWidget->rowCount(); r++ )
755  {
756  for ( int c = 0; c < mNoDataTableWidget->columnCount(); c++ )
757  {
758  if ( mNoDataTableWidget->cellWidget( r, c ) == sender() )
759  {
760  row = r;
761  column = c;
762  break;
763  }
764  }
765  if ( row != -1 ) break;
766  }
767  QgsDebugMsg( QStringLiteral( "row = %1 column =%2" ).arg( row ).arg( column ) );
768 
769  if ( column == 0 )
770  {
771  QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, 1 ) );
772  if ( !toLineEdit ) return;
773  bool toChanged = mNoDataToEdited.value( row );
774  QgsDebugMsg( QStringLiteral( "toChanged = %1" ).arg( toChanged ) );
775  if ( !toChanged )
776  {
777  toLineEdit->setText( lineEdit->text() );
778  }
779  }
780  else if ( column == 1 )
781  {
782  setNoDataToEdited( row );
783  }
784 }
785 
786 void QgsRasterLayerSaveAsDialog::mTileModeCheckBox_toggled( bool toggled )
787 {
788  if ( toggled )
789  {
790  // enable pyramids
791 
792  // Disabled (Radim), auto enabling of pyramids was making impression that
793  // we (programmers) know better what you (user) want to do,
794  // certainly auto expanding was a bad experience
795 
796  //if ( ! mPyramidsGroupBox->isChecked() )
797  // mPyramidsGroupBox->setChecked( true );
798 
799  // Auto expanding mPyramidsGroupBox is bad - it auto scrolls content of dialog
800  //if ( mPyramidsGroupBox->isCollapsed() )
801  // mPyramidsGroupBox->setCollapsed( false );
802  //mPyramidsOptionsWidget->checkAllLevels( true );
803 
804  // Show / hide tile options
805  mTilesGroupBox->show();
806  mFilename->setStorageMode( QgsFileWidget::GetDirectory );
807  mFilename->setDialogTitle( tr( "Select Output Directory" ) );
808  }
809  else
810  {
811  mTilesGroupBox->hide();
812  mFilename->setStorageMode( QgsFileWidget::SaveFile );
813  mFilename->setDialogTitle( tr( "Save Layer As" ) );
814  }
815 }
816 
817 void QgsRasterLayerSaveAsDialog::mPyramidsGroupBox_toggled( bool toggled )
818 {
819  Q_UNUSED( toggled )
820  populatePyramidsLevels();
821 }
822 
823 void QgsRasterLayerSaveAsDialog::populatePyramidsLevels()
824 {
825  QString text;
826 
827  if ( mPyramidsGroupBox->isChecked() )
828  {
829  QList<QgsRasterPyramid> myPyramidList;
830  // if use existing, get pyramids from actual layer
831  // but that's not available yet
832  if ( mPyramidsUseExistingCheckBox->isChecked() )
833  {
834  myPyramidList = mDataProvider->buildPyramidList();
835  }
836  else
837  {
838  if ( ! mPyramidsOptionsWidget->overviewList().isEmpty() )
839  myPyramidList = mDataProvider->buildPyramidList( mPyramidsOptionsWidget->overviewList() );
840  }
841  for ( const QgsRasterPyramid &pyramid : std::as_const( myPyramidList ) )
842  {
843  if ( ! mPyramidsUseExistingCheckBox->isChecked() || pyramid.getExists() )
844  {
845  text += QString::number( pyramid.getXDim() ) + QStringLiteral( "x" ) +
846  QString::number( pyramid.getYDim() ) + ' ';
847  }
848  }
849  }
850 
851  mPyramidResolutionsLineEdit->setText( text.trimmed() );
852 }
853 
854 void QgsRasterLayerSaveAsDialog::setNoDataToEdited( int row )
855 {
856  if ( row >= mNoDataToEdited.size() )
857  {
858  mNoDataToEdited.resize( row + 1 );
859  }
860  mNoDataToEdited[row] = true;
861 }
862 
863 double QgsRasterLayerSaveAsDialog::noDataCellValue( int row, int column ) const
864 {
865  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
866  if ( !lineEdit || lineEdit->text().isEmpty() )
867  {
868  return std::numeric_limits<double>::quiet_NaN();
869  }
870  return QgsDoubleValidator::toDouble( lineEdit->text() );
871 }
872 
873 void QgsRasterLayerSaveAsDialog::adjustNoDataCellWidth( int row, int column )
874 {
875  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
876  if ( !lineEdit ) return;
877 
878  int width = std::max( lineEdit->fontMetrics().boundingRect( lineEdit->text() ).width() + 10, 100 );
879  width = std::max( width, mNoDataTableWidget->columnWidth( column ) );
880 
881  lineEdit->setFixedWidth( width );
882 }
883 
885 {
886  QgsRasterRangeList noDataList;
887  if ( ! mNoDataGroupBox->isChecked() )
888  return noDataList;
889 
890  int rows = mNoDataTableWidget->rowCount();
891  noDataList.reserve( rows );
892  for ( int r = 0; r < rows; r++ )
893  {
894  QgsRasterRange noData( noDataCellValue( r, 0 ), noDataCellValue( r, 1 ) );
895  noDataList.append( noData );
896 
897  }
898  return noDataList;
899 }
900 
902 {
903  return mPyramidsGroupBox->isChecked() ? mPyramidsOptionsWidget->overviewList() : QList<int>();
904 }
905 
907 {
908  if ( ! mPyramidsGroupBox->isChecked() )
910  else if ( mPyramidsUseExistingCheckBox->isChecked() )
912  else
914 }
915 
916 bool QgsRasterLayerSaveAsDialog::validate() const
917 {
918  if ( mCreateOptionsGroupBox->isChecked() )
919  {
920  QString message = mCreateOptionsWidget->validateOptions( true, false );
921  if ( !message.isNull() )
922  return false;
923  }
924  if ( mPyramidsGroupBox->isChecked() )
925  {
926  QString message = mPyramidsOptionsWidget->createOptionsWidget()->validateOptions( true, false );
927  if ( !message.isNull() )
928  return false;
929  }
930  return true;
931 }
932 
933 bool QgsRasterLayerSaveAsDialog::outputLayerExists() const
934 {
935  QString vectorUri;
936  QString rasterUri;
937  if ( outputFormat() == QLatin1String( "GPKG" ) )
938  {
939  rasterUri = QStringLiteral( "GPKG:%1:%2" ).arg( outputFileName(), outputLayerName() );
940  vectorUri = QStringLiteral( "%1|layername=%2" ).arg( outputFileName(), outputLayerName() );
941  }
942  else
943  {
944  rasterUri = outputFileName();
945  }
946 
947  QgsRasterLayer rasterLayer( rasterUri, QString( ), QStringLiteral( "gdal" ) );
948  if ( !vectorUri.isEmpty() )
949  {
950  QgsVectorLayer vectorLayer( vectorUri, QString( ), QStringLiteral( "ogr" ) );
951  return rasterLayer.isValid() || vectorLayer.isValid();
952  }
953  else
954  {
955  return rasterLayer.isValid();
956  }
957 }
958 
960 {
961  if ( !validate() )
962  {
963  return;
964  }
965 
966  if ( outputFormat() == QLatin1String( "GPKG" ) && outputLayerExists() &&
967  QMessageBox::warning( this, tr( "Save Raster Layer" ),
968  tr( "The layer %1 already exists in the target file, and overwriting layers in GeoPackage is not supported. "
969  "Do you want to overwrite the whole file?" ).arg( outputLayerName() ),
970  QMessageBox::Yes | QMessageBox::No ) == QMessageBox::No )
971  {
972  return;
973  }
974 
975  QDialog::accept();
976 }
977 
978 void QgsRasterLayerSaveAsDialog::showHelp()
979 {
980  QgsHelp::openHelp( QStringLiteral( "managing_data_source/create_layers.html#creating-new-layers-from-an-existing-layer" ) );
981 }
QgsRasterLayerSaveAsDialog::outputLayerName
QString outputLayerName() const
Name of the output layer within GeoPackage file.
Definition: qgsrasterlayersaveasdialog.cpp:429
QgsFileWidget::fileChanged
void fileChanged(const QString &path)
Emitted whenever the current file or directory path is changed.
QgsRasterBlock::printValue
static QString printValue(double value)
Print double value with all necessary significant digits.
Definition: qgsrasterblock.cpp:618
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsPointXY::y
double y
Definition: qgspointxy.h:63
QgsRasterLayerSaveAsDialog::mode
Mode mode() const
Definition: qgsrasterlayersaveasdialog.cpp:658
qgsrasterlayer.h
QgsRasterLayerSaveAsDialog::noData
QgsRasterRangeList noData() const
Definition: qgsrasterlayersaveasdialog.cpp:884
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:161
QgsRasterInterface::Size
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
Definition: qgsrasterinterface.h:205
QgsRasterTransparency::transparentSingleValuePixelList
QList< QgsRasterTransparency::TransparentSingleValuePixel > transparentSingleValuePixelList() const
Returns the transparent single value pixel list.
Definition: qgsrastertransparency.cpp:27
QgsRasterLayerSaveAsDialog::hideOutput
void hideOutput()
Definition: qgsrasterlayersaveasdialog.cpp:491
QgsRasterLayerSaveAsDialog::outputRectangle
QgsRectangle outputRectangle() const
Definition: qgsrasterlayersaveasdialog.cpp:480
QgsRectangle::center
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
qgsgui.h
QgsRasterLayerSaveAsDialog::outputFileName
QString outputFileName() const
Definition: qgsrasterlayersaveasdialog.cpp:405
qgsgdalutils.h
qgsrasterlayersaveasdialog.h
QgsProjectionSelectionWidget::crsChanged
void crsChanged(const QgsCoordinateReferenceSystem &)
Emitted when the selected CRS is changed.
QgsRasterDataProvider::extent
QgsRectangle extent() const override=0
Returns the extent of the layer.
QgsRasterInterface::BuildPyramids
@ BuildPyramids
Supports building of pyramids (overviews)
Definition: qgsrasterinterface.h:208
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsRasterLayerSaveAsDialog::nColumns
int nColumns() const
Definition: qgsrasterlayersaveasdialog.cpp:360
qgsrasterrenderer.h
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
QgsGdalUtils::supportsRasterCreate
static bool supportsRasterCreate(GDALDriverH driver)
Reads whether a driver supports GDALCreate() for raster purposes.
Definition: qgsgdalutils.cpp:35
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsRasterPyramidsOptionsWidget::overviewListChanged
void overviewListChanged()
QgsRasterLayerSaveAsDialog::maximumTileSizeY
int maximumTileSizeY() const
Definition: qgsrasterlayersaveasdialog.cpp:385
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsRaster::PyramidsFlagNo
@ PyramidsFlagNo
Definition: qgsraster.h:89
qgsrasterfilewriter.h
QgsRasterLayerSaveAsDialog::accept
void accept() override
Definition: qgsrasterlayersaveasdialog.cpp:959
QgsFileWidget::SaveFile
@ SaveFile
Select a single new or pre-existing file.
Definition: qgsfilewidget.h:71
qgsapplication.h
qgsprojectionselectiondialog.h
QgsRasterLayer::renderer
QgsRasterRenderer * renderer() const
Returns the raster's renderer.
Definition: qgsrasterlayer.cpp:1758
QgsGui::enableAutoGeometryRestore
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:180
QgsRaster::RasterBuildPyramids
RasterBuildPyramids
Definition: qgsraster.h:87
QgsRasterLayerSaveAsDialog::createOptions
QStringList createOptions() const
Definition: qgsrasterlayersaveasdialog.cpp:447
QgsRasterLayerSaveAsDialog::Mode
Mode
Definition: qgsrasterlayersaveasdialog.h:37
QgsFileWidget::GetDirectory
@ GetDirectory
Select a directory.
Definition: qgsfilewidget.h:69
QgsRasterLayerSaveAsDialog::maximumTileSizeX
int maximumTileSizeX() const
Definition: qgsrasterlayersaveasdialog.cpp:380
QgsRasterInterface::xSize
virtual int xSize() const
Gets raster size.
Definition: qgsrasterinterface.h:263
qgsdatums.h
QgsRasterRenderer::rasterTransparency
const QgsRasterTransparency * rasterTransparency() const
Definition: qgsrasterrenderer.h:116
qgsrasterformatsaveoptionswidget.h
QgsDoubleValidator
QgsDoubleValidator is a QLineEdit Validator that combines QDoubleValidator and QRegularExpressionVali...
Definition: qgsdoublevalidator.h:40
Qgis::DataType::Float64
@ Float64
Sixty four bit floating point (double)
QgsRasterDataProvider::buildPyramidList
virtual QList< QgsRasterPyramid > buildPyramidList(const QList< int > &overviewList=QList< int >())
Returns the raster layers pyramid list.
Definition: qgsrasterdataprovider.h:361
qgscoordinatetransform.h
QgsRasterRangeList
QList< QgsRasterRange > QgsRasterRangeList
Definition: qgsrasterrange.h:26
QgsRasterTransparency::TransparentSingleValuePixel
Definition: qgsrastertransparency.h:53
QgsRasterLayerSaveAsDialog::setAddToCanvas
void setAddToCanvas(bool checked)
Sets whether the "add to canvas" checkbox should be checked.
Definition: qgsrasterlayersaveasdialog.cpp:400
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:279
QgsRasterLayer
Represents a raster layer.
Definition: qgsrasterlayer.h:76
QgsRasterTransparency
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
Definition: qgsrastertransparency.h:32
qgsrastertransparency.h
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
QgsRasterInterface::ySize
virtual int ySize() const
Definition: qgsrasterinterface.h:264
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsRasterLayerSaveAsDialog::outputCrs
QgsCoordinateReferenceSystem outputCrs()
Definition: qgsrasterlayersaveasdialog.cpp:653
QgsRasterDataProvider::sourceDataType
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...
QgsRasterLayerSaveAsDialog::UserResolution
@ UserResolution
Definition: qgsrasterlayersaveasdialog.h:51
Qgis::DataType::Float32
@ Float32
Thirty two bit floating point (float)
QgsRasterLayerSaveAsDialog::OriginalResolution
@ OriginalResolution
Definition: qgsrasterlayersaveasdialog.h:50
QgsRasterLayerSaveAsDialog::tileMode
bool tileMode() const
Definition: qgsrasterlayersaveasdialog.cpp:390
c
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
Definition: porting_processing.dox:1
QgsRaster::PyramidsFlagYes
@ PyramidsFlagYes
Definition: qgsraster.h:90
QgsHelp::openHelp
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsCoordinateReferenceSystem::datumEnsemble
QgsDatumEnsemble datumEnsemble() const SIP_THROW(QgsNotSupportedException)
Attempts to retrieve datum ensemble details from the CRS.
Definition: qgscoordinatereferencesystem.cpp:1355
QgsPointXY::x
double x
Definition: qgspointxy.h:62
QgsDoubleValidator::toDouble
static double toDouble(const QString &input, bool *ok)
Converts input string to double value.
Definition: qgsdoublevalidator.cpp:134
qgssettings.h
QgsRasterLayerSaveAsDialog::xResolution
double xResolution() const
Definition: qgsrasterlayersaveasdialog.cpp:370
QgsRasterRange
Raster values range container. Represents range of values between min and max including min and max v...
Definition: qgsrasterrange.h:35
QgsRasterLayerSaveAsDialog::addToCanvas
bool addToCanvas() const
Returns true if the "add to canvas" checkbox is checked.
Definition: qgsrasterlayersaveasdialog.cpp:395
QgsRasterFileWriter::extensionsForFormat
static QStringList extensionsForFormat(const QString &format)
Returns a list of known file extensions for the given GDAL driver format.
Definition: qgsrasterfilewriter.cpp:1101
QgsRasterLayerSaveAsDialog::buildPyramidsFlag
QgsRaster::RasterBuildPyramids buildPyramidsFlag() const
Definition: qgsrasterlayersaveasdialog.cpp:906
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Definition: qgsapplication.cpp:693
QgsNotSupportedException
Custom exception class which is raised when an operation is not supported.
Definition: qgsexception.h:117
QgsDataProvider::name
virtual QString name() const =0
Returns a provider name.
QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog
QgsRasterLayerSaveAsDialog(QgsRasterLayer *rasterLayer, QgsRasterDataProvider *sourceProvider, const QgsRectangle &currentExtent, const QgsCoordinateReferenceSystem &layerCrs, const QgsCoordinateReferenceSystem &currentCrs, QWidget *parent SIP_TRANSFERTHIS=nullptr, Qt::WindowFlags f=Qt::WindowFlags())
Constructor for QgsRasterLayerSaveAsDialog.
Definition: qgsrasterlayersaveasdialog.cpp:41
QgsRasterLayerSaveAsDialog::RenderedImageMode
@ RenderedImageMode
Definition: qgsrasterlayersaveasdialog.h:40
QgsRasterInterface::bandCount
virtual int bandCount() const =0
Gets number of bands.
QgsRasterLayerSaveAsDialog::RawDataMode
@ RawDataMode
Definition: qgsrasterlayersaveasdialog.h:39
qgsdoublevalidator.h
qgslogger.h
QgsRasterLayerSaveAsDialog::pyramidsList
QList< int > pyramidsList() const
Definition: qgsrasterlayersaveasdialog.cpp:901
QgsRasterPyramid
This struct is used to store pyramid info for the raster layer.
Definition: qgsrasterpyramid.h:28
QgsRasterLayerSaveAsDialog::outputFormat
QString outputFormat() const
Definition: qgsrasterlayersaveasdialog.cpp:442
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
QgsRasterLayerSaveAsDialog::yResolution
double yResolution() const
Definition: qgsrasterlayersaveasdialog.cpp:375
QgsRasterLayerSaveAsDialog::nRows
int nRows() const
Definition: qgsrasterlayersaveasdialog.cpp:365
QgsRasterInterface::capabilities
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
Definition: qgsrasterinterface.h:225
QgsDatumEnsemble::name
QString name() const
Display name of datum ensemble.
Definition: qgsdatums.h:107
QgsExtentGroupBox::extentChanged
void extentChanged(const QgsRectangle &r)
Emitted when the widget's extent is changed.
QgsRasterDataProvider
Base class for raster data providers.
Definition: qgsrasterdataprovider.h:88
qgsproject.h
QgsDatumEnsemble::isValid
bool isValid() const
Returns true if the datum ensemble is a valid object, or false if it is a null/invalid object.
Definition: qgsdatums.h:102
QgsRasterLayer::dataProvider
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
Definition: qgsrasterlayer.cpp:257
QgsDatumEnsemble
Contains information about a datum ensemble.
Definition: qgsdatums.h:94
QgsRasterLayerSaveAsDialog::hideFormat
void hideFormat()
Definition: qgsrasterlayersaveasdialog.cpp:485
QgsRaster::PyramidsCopyExisting
@ PyramidsCopyExisting
Definition: qgsraster.h:91
qgsrasterdataprovider.h
qgsmessagelog.h