QGIS API Documentation  2.14.11-Essen
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 "qgslogger.h"
17 #include "qgscoordinatetransform.h"
18 #include "qgsrasterlayer.h"
20 #include "qgsrasterdataprovider.h"
23 
24 #include <QFileDialog>
25 #include <QMessageBox>
26 #include <QSettings>
27 
29  QgsRasterDataProvider* sourceProvider, const QgsRectangle& currentExtent,
30  const QgsCoordinateReferenceSystem& layerCrs, const QgsCoordinateReferenceSystem& currentCrs,
31  QWidget* parent, const Qt::WindowFlags& f ) :
32  QDialog( parent, f )
33  , mRasterLayer( rasterLayer ), mDataProvider( sourceProvider )
34  , mCurrentExtent( currentExtent ), mLayerCrs( layerCrs )
35  , mCurrentCrs( currentCrs )
36  , mResolutionState( OriginalResolution )
37 {
38  setupUi( this );
39  mAddNoDataManuallyToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
40  mLoadTransparentNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionCopySelected.png" ) );
41  mRemoveSelectedNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
42  mRemoveAllNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionRemove.png" ) );
43 
44  mNoDataTableWidget->setColumnCount( 2 );
45  mNoDataTableWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "From" ) ) );
46  mNoDataTableWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "To" ) ) );
47 
48  on_mRawModeRadioButton_toggled( true );
49 
50  setValidators();
51 
52  toggleResolutionSize();
53 
54  //only one hardcoded format at the moment
55  QStringList myFormats;
56  myFormats << "GTiff";
57  Q_FOREACH ( const QString& myFormat, myFormats )
58  {
59  mFormatComboBox->addItem( myFormat );
60  }
61 
62  //fill reasonable default values depending on the provider
63  if ( mDataProvider )
64  {
65  if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
66  {
67  setOriginalResolution();
68  int xSize = mDataProvider->xSize();
69  int ySize = mDataProvider->ySize();
70  mMaximumSizeXLineEdit->setText( QString::number( xSize ) );
71  mMaximumSizeYLineEdit->setText( QString::number( ySize ) );
72  }
73  else //wms, sometimes wcs
74  {
75  mTileModeCheckBox->setChecked( true );
76  mMaximumSizeXLineEdit->setText( QString::number( 2000 ) );
77  mMaximumSizeYLineEdit->setText( QString::number( 2000 ) );
78  }
79 
80  // setup creation option widget
81  mCreateOptionsWidget->setProvider( mDataProvider->name() );
82  if ( mDataProvider->name() == "gdal" )
83  {
84  mCreateOptionsWidget->setFormat( myFormats[0] );
85  }
86  mCreateOptionsWidget->setRasterLayer( mRasterLayer );
87  mCreateOptionsWidget->update();
88  }
89 
90  // Only do pyramids if dealing directly with GDAL.
91  if ( mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::BuildPyramids )
92  {
93  // setup pyramids option widget
94  // mPyramidsOptionsWidget->createOptionsWidget()->setType( QgsRasterFormatSaveOptionsWidget::ProfileLineEdit );
95  mPyramidsOptionsWidget->createOptionsWidget()->setRasterLayer( mRasterLayer );
96 
97  // TODO enable "use existing", has no effect for now, because using Create() in gdal provider
98  // if ( ! mDataProvider->hasPyramids() )
99  // mPyramidsButtonGroup->button( QgsRaster::PyramidsCopyExisting )->setEnabled( false );
100  mPyramidsUseExistingCheckBox->setEnabled( false );
101  mPyramidsUseExistingCheckBox->setVisible( false );
102 
103  populatePyramidsLevels();
104  connect( mPyramidsOptionsWidget, SIGNAL( overviewListChanged() ),
105  this, SLOT( populatePyramidsLevels() ) );
106  }
107  else
108  {
109  mPyramidsGroupBox->setEnabled( false );
110  }
111 
112  // restore checked state for most groupboxes (default is to restore collapsed state)
113  // create options and pyramids will be preset, if user has selected defaults in the gdal options dlg
114  mCreateOptionsGroupBox->setSaveCheckedState( true );
115  //mTilesGroupBox->setSaveCheckedState( true );
116  // don't restore nodata, it needs user input
117  // pyramids are not necessarily built every time
118 
119  mTilesGroupBox->hide();
120 
121  mCrsSelector->setLayerCrs( mLayerCrs );
122  //default to layer CRS - see http://hub.qgis.org/issues/14209 for discussion
123  mCrsSelector->setCrs( mLayerCrs );
124 
125  connect( mCrsSelector, SIGNAL( crsChanged( QgsCoordinateReferenceSystem ) ),
126  this, SLOT( crsChanged() ) );
127 
128  QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
129  if ( okButton )
130  {
131  okButton->setEnabled( false );
132  }
133 
134  mExtentGroupBox->setOutputCrs( outputCrs() );
135  mExtentGroupBox->setOriginalExtent( mDataProvider->extent(), mLayerCrs );
136  mExtentGroupBox->setCurrentExtent( mCurrentExtent, mCurrentCrs );
137  mExtentGroupBox->setOutputExtentFromOriginal();
138  connect( mExtentGroupBox, SIGNAL( extentChanged( QgsRectangle ) ), this, SLOT( extentChanged() ) );
139 
140  recalcResolutionSize();
141 }
142 
143 void QgsRasterLayerSaveAsDialog::setValidators()
144 {
145  mXResolutionLineEdit->setValidator( new QDoubleValidator( this ) );
146  mYResolutionLineEdit->setValidator( new QDoubleValidator( this ) );
147  mColumnsLineEdit->setValidator( new QIntValidator( this ) );
148  mRowsLineEdit->setValidator( new QIntValidator( this ) );
149  mMaximumSizeXLineEdit->setValidator( new QIntValidator( this ) );
150  mMaximumSizeYLineEdit->setValidator( new QIntValidator( this ) );
151 }
152 
154 {
155 }
156 
157 void QgsRasterLayerSaveAsDialog::on_mBrowseButton_clicked()
158 {
159  QString fileName;
160 
161  QSettings settings;
162  QString dirName = mSaveAsLineEdit->text().isEmpty() ? settings.value( "/UI/lastRasterFileDir", QDir::homePath() ).toString() : mSaveAsLineEdit->text();
163 
164  if ( mTileModeCheckBox->isChecked() )
165  {
166  Q_FOREVER
167  {
168  // TODO: would not it be better to select .vrt file instead of directory?
169  fileName = QFileDialog::getExistingDirectory( this, tr( "Select output directory" ), dirName );
170  //fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), QString(), tr( "VRT" ) + " (*.vrt *.VRT)" );
171 
172  if ( fileName.isEmpty() )
173  break; // canceled
174 
175  // Check if directory is empty
176  QDir dir( fileName );
177  QString baseName = QFileInfo( fileName ).baseName();
178  QStringList filters;
179  filters << QString( "%1.*" ).arg( baseName );
180  QStringList files = dir.entryList( filters );
181  if ( files.isEmpty() )
182  break;
183 
184  if ( QMessageBox::warning( this, tr( "Warning" ),
185  tr( "The directory %1 contains files which will be overwritten: %2" ).arg( dir.absolutePath(), files.join( ", " ) ),
186  QMessageBox::Ok | QMessageBox::Cancel ) == QMessageBox::Ok )
187  break;
188 
189  fileName = "";
190  }
191  }
192  else
193  {
194  fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), dirName, tr( "GeoTIFF" ) + " (*.tif *.tiff *.TIF *.TIFF)" );
195 
196  // ensure the user never omits the extension from the file name
197  if ( !fileName.isEmpty() && !fileName.endsWith( ".tif", Qt::CaseInsensitive ) && !fileName.endsWith( ".tiff", Qt::CaseInsensitive ) )
198  {
199  fileName += ".tif";
200  }
201  }
202 
203  if ( !fileName.isEmpty() )
204  {
205  mSaveAsLineEdit->setText( fileName );
206  }
207 }
208 
209 void QgsRasterLayerSaveAsDialog::on_mSaveAsLineEdit_textChanged( const QString& text )
210 {
211  QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
212  if ( !okButton )
213  {
214  return;
215  }
216 
217  okButton->setEnabled( QFileInfo( text ).absoluteDir().exists() );
218 }
219 
220 
221 void QgsRasterLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( const QString & text )
222 {
223  //gdal-specific
224  if ( mDataProvider && mDataProvider->name() == "gdal" )
225  {
226  mCreateOptionsWidget->setFormat( text );
227  mCreateOptionsWidget->update();
228  }
229 }
230 
232 {
233  return mColumnsLineEdit->text().toInt();
234 }
235 
237 {
238  return mRowsLineEdit->text().toInt();
239 }
240 
242 {
243  return mXResolutionLineEdit->text().toDouble();
244 }
245 
247 {
248  return mYResolutionLineEdit->text().toDouble();
249 }
250 
252 {
253  return mMaximumSizeXLineEdit->text().toInt();
254 }
255 
257 {
258  return mMaximumSizeYLineEdit->text().toInt();
259 }
260 
262 {
263  return mTileModeCheckBox->isChecked();
264 }
265 
267 {
268  return mAddToCanvas->isChecked();
269 }
270 
272 {
273  return mSaveAsLineEdit->text();
274 }
275 
277 {
278  return mFormatComboBox->currentText();
279 }
280 
282 {
283  return mCreateOptionsGroupBox->isChecked() ? mCreateOptionsWidget->options() : QStringList();
284 }
285 
287 {
288  return mExtentGroupBox->outputExtent();
289 }
290 
292 {
293  mFormatLabel->hide();
294  mFormatComboBox->hide();
295 }
296 
298 {
299  mSaveAsLabel->hide();
300  mSaveAsLineEdit->hide();
301  mBrowseButton->hide();
302  QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
303  if ( okButton )
304  {
305  okButton->setEnabled( true );
306  }
307 }
308 
309 void QgsRasterLayerSaveAsDialog::toggleResolutionSize()
310 {
311  bool hasResolution = mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::Size;
312 
313  bool on = mResolutionRadioButton->isChecked();
314  mXResolutionLineEdit->setEnabled( on );
315  mYResolutionLineEdit->setEnabled( on );
316  mOriginalResolutionPushButton->setEnabled( on && hasResolution );
317  mColumnsLineEdit->setEnabled( !on );
318  mRowsLineEdit->setEnabled( !on );
319  mOriginalSizePushButton->setEnabled( !on && hasResolution );
320 }
321 
322 void QgsRasterLayerSaveAsDialog::setOriginalResolution()
323 {
324  double xRes, yRes;
325 
326  if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
327  {
328  xRes = mDataProvider->extent().width() / mDataProvider->xSize();
329  yRes = mDataProvider->extent().height() / mDataProvider->ySize();
330  }
331  else
332  {
333  // Init to something if no original resolution is available
334  xRes = yRes = mDataProvider->extent().width() / 100;
335  }
336  setResolution( xRes, yRes, mLayerCrs );
337  mResolutionState = OriginalResolution;
338  recalcSize();
339 }
340 
341 void QgsRasterLayerSaveAsDialog::setResolution( double xRes, double yRes, const QgsCoordinateReferenceSystem& srcCrs )
342 {
343  if ( srcCrs != outputCrs() )
344  {
345  // We reproject pixel rectangle from center of selected extent, of course, it gives
346  // bigger xRes,yRes than reprojected edges (envelope), it may also be that
347  // close to margins are higher resolutions (even very, too high)
348  // TODO: consider more precise resolution calculation
349 
350  QgsPoint center = outputRectangle().center();
351  QgsCoordinateTransform ct( srcCrs, outputCrs() );
353 
354  QgsRectangle srcExtent( srsCenter.x() - xRes / 2, srsCenter.y() - yRes / 2, srsCenter.x() + xRes / 2, srsCenter.y() + yRes / 2 );
355 
356  QgsRectangle extent = ct.transform( srcExtent );
357  xRes = extent.width();
358  yRes = extent.height();
359  }
360  mXResolutionLineEdit->setText( QString::number( xRes ) );
361  mYResolutionLineEdit->setText( QString::number( yRes ) );
362 }
363 
364 void QgsRasterLayerSaveAsDialog::recalcSize()
365 {
366  QgsDebugMsg( "Entered" );
367  QgsRectangle extent = outputRectangle();
368  int xSize = xResolution() != 0 ? static_cast<int>( qRound( extent.width() / xResolution() ) ) : 0;
369  int ySize = yResolution() != 0 ? static_cast<int>( qRound( extent.height() / yResolution() ) ) : 0;
370  mColumnsLineEdit->setText( QString::number( xSize ) );
371  mRowsLineEdit->setText( QString::number( ySize ) );
372  updateResolutionStateMsg();
373 }
374 
375 void QgsRasterLayerSaveAsDialog::setOriginalSize()
376 {
377  mColumnsLineEdit->setText( QString::number( mDataProvider->xSize() ) );
378  mRowsLineEdit->setText( QString::number( mDataProvider->ySize() ) );
379  recalcResolution();
380 }
381 
382 void QgsRasterLayerSaveAsDialog::recalcResolution()
383 {
384  QgsDebugMsg( "Entered" );
385  QgsRectangle extent = outputRectangle();
386  double xRes = nColumns() != 0 ? extent.width() / nColumns() : 0;
387  double yRes = nRows() != 0 ? extent.height() / nRows() : 0;
388  mXResolutionLineEdit->setText( QString::number( xRes ) );
389  mYResolutionLineEdit->setText( QString::number( yRes ) );
390  updateResolutionStateMsg();
391 }
392 
393 void QgsRasterLayerSaveAsDialog::recalcResolutionSize()
394 {
395  QgsDebugMsg( "Entered" );
396  if ( mResolutionRadioButton->isChecked() )
397  {
398  recalcSize();
399  }
400  else
401  {
402  mResolutionState = UserResolution;
403  recalcResolution();
404  }
405 }
406 
407 void QgsRasterLayerSaveAsDialog::updateResolutionStateMsg()
408 {
409  QString msg;
410  switch ( mResolutionState )
411  {
412  case OriginalResolution:
413  msg = tr( "layer" );
414  break;
415  case UserResolution:
416  msg = tr( "user defined" );
417  break;
418  default:
419  break;
420  }
421  msg = tr( "Resolution (current: %1)" ).arg( msg );
422  mResolutionGroupBox->setTitle( msg );
423 }
424 
425 void QgsRasterLayerSaveAsDialog::extentChanged()
426 {
427  // Whenever extent changes with fixed size, original resolution is lost
428  if ( mSizeRadioButton->isChecked() )
429  {
430  mResolutionState = UserResolution;
431  }
432  recalcResolutionSize();
433 }
434 
435 void QgsRasterLayerSaveAsDialog::crsChanged()
436 {
437  if ( outputCrs() != mPreviousCrs )
438  {
439  mExtentGroupBox->setOutputCrs( outputCrs() );
440  QgsExtentGroupBox::ExtentState state = mExtentGroupBox->extentState();
441 
442  // Reset extent
443  // We could reproject previous but that would add additional space also if
444  // it is was not necessary or at leas it could decrease accuracy
445  if ( state == QgsExtentGroupBox::OriginalExtent )
446  {
447  mExtentGroupBox->setOutputExtentFromOriginal();
448  }
449  else if ( state == QgsExtentGroupBox::CurrentExtent )
450  {
451  mExtentGroupBox->setOutputExtentFromCurrent();
452  }
453  else
454  {
455  mExtentGroupBox->setOutputExtentFromUser( mExtentGroupBox->outputExtent(), mPreviousCrs );
456  }
457 
458  // Reset resolution
459  if ( mResolutionRadioButton->isChecked() )
460  {
461  if ( mResolutionState == OriginalResolution )
462  {
463  setOriginalResolution();
464  }
465  else
466  {
467  // reset from present resolution and present crs
468  setResolution( xResolution(), yResolution(), mPreviousCrs );
469  }
470  }
471  else
472  {
473  // Size does not change, we just recalc resolution from new extent
474  recalcResolution();
475  }
476  }
477  mPreviousCrs = outputCrs();
478 }
479 
481 {
482  return mCrsSelector->crs();
483 }
484 
486 {
487  if ( mRenderedModeRadioButton->isChecked() ) return RenderedImageMode;
488  return RawDataMode;
489 }
490 
491 void QgsRasterLayerSaveAsDialog::on_mRawModeRadioButton_toggled( bool checked )
492 {
493  mNoDataGroupBox->setEnabled( checked && mDataProvider->bandCount() == 1 );
494 }
495 
496 void QgsRasterLayerSaveAsDialog::on_mAddNoDataManuallyToolButton_clicked()
497 {
498  addNoDataRow( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
499 }
500 
501 void QgsRasterLayerSaveAsDialog::on_mLoadTransparentNoDataToolButton_clicked()
502 {
503  if ( !mRasterLayer->renderer() ) return;
504  const QgsRasterTransparency* rasterTransparency = mRasterLayer->renderer()->rasterTransparency();
505  if ( !rasterTransparency ) return;
506 
507  Q_FOREACH ( const QgsRasterTransparency::TransparentSingleValuePixel& transparencyPixel, rasterTransparency->transparentSingleValuePixelList() )
508  {
509  if ( transparencyPixel.percentTransparent == 100 )
510  {
511  addNoDataRow( transparencyPixel.min, transparencyPixel.max );
512  if ( transparencyPixel.min != transparencyPixel.max )
513  {
514  setNoDataToEdited( mNoDataTableWidget->rowCount() - 1 );
515  }
516  }
517  }
518 }
519 
520 void QgsRasterLayerSaveAsDialog::on_mRemoveSelectedNoDataToolButton_clicked()
521 {
522  mNoDataTableWidget->removeRow( mNoDataTableWidget->currentRow() );
523 }
524 
525 void QgsRasterLayerSaveAsDialog::on_mRemoveAllNoDataToolButton_clicked()
526 {
527  while ( mNoDataTableWidget->rowCount() > 0 )
528  {
529  mNoDataTableWidget->removeRow( 0 );
530  }
531 }
532 
533 void QgsRasterLayerSaveAsDialog::addNoDataRow( double min, double max )
534 {
535  mNoDataTableWidget->insertRow( mNoDataTableWidget->rowCount() );
536  for ( int i = 0; i < 2; i++ )
537  {
538  double value = i == 0 ? min : max;
539  QLineEdit *lineEdit = new QLineEdit();
540  lineEdit->setFrame( false );
541  lineEdit->setContentsMargins( 1, 1, 1, 1 );
542  QString valueString;
543  switch ( mRasterLayer->dataProvider()->srcDataType( 1 ) )
544  {
545  case QGis::Float32:
546  case QGis::Float64:
547  lineEdit->setValidator( new QDoubleValidator( nullptr ) );
548  if ( !qIsNaN( value ) )
549  {
550  valueString = QgsRasterBlock::printValue( value );
551  }
552  break;
553  default:
554  lineEdit->setValidator( new QIntValidator( nullptr ) );
555  if ( !qIsNaN( value ) )
556  {
557  valueString = QString::number( static_cast<int>( value ) );
558  }
559  break;
560  }
561  lineEdit->setText( valueString );
562  mNoDataTableWidget->setCellWidget( mNoDataTableWidget->rowCount() - 1, i, lineEdit );
563 
564  adjustNoDataCellWidth( mNoDataTableWidget->rowCount() - 1, i );
565 
566  connect( lineEdit, SIGNAL( textEdited( const QString & ) ), this, SLOT( noDataCellTextEdited( const QString & ) ) );
567  }
568  mNoDataTableWidget->resizeColumnsToContents();
569  mNoDataTableWidget->resizeRowsToContents();
570 }
571 
572 void QgsRasterLayerSaveAsDialog::noDataCellTextEdited( const QString & text )
573 {
574  Q_UNUSED( text );
575 
576  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( sender() );
577  if ( !lineEdit ) return;
578  int row = -1;
579  int column = -1;
580  for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
581  {
582  for ( int c = 0 ; c < mNoDataTableWidget->columnCount(); c++ )
583  {
584  if ( mNoDataTableWidget->cellWidget( r, c ) == sender() )
585  {
586  row = r;
587  column = c;
588  break;
589  }
590  }
591  if ( row != -1 ) break;
592  }
593  QgsDebugMsg( QString( "row = %1 column =%2" ).arg( row ).arg( column ) );
594 
595  if ( column == 0 )
596  {
597  QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, 1 ) );
598  if ( !toLineEdit ) return;
599  bool toChanged = mNoDataToEdited.value( row );
600  QgsDebugMsg( QString( "toChanged = %1" ).arg( toChanged ) );
601  if ( !toChanged )
602  {
603  toLineEdit->setText( lineEdit->text() );
604  }
605  }
606  else if ( column == 1 )
607  {
608  setNoDataToEdited( row );
609  }
610 }
611 
612 void QgsRasterLayerSaveAsDialog::on_mTileModeCheckBox_toggled( bool toggled )
613 {
614  if ( toggled )
615  {
616  // enable pyramids
617 
618  // Disabled (Radim), auto enabling of pyramids was making impression that
619  // we (programmers) know better what you (user) want to do,
620  // certainly auto expaning was bad experience
621 
622  //if ( ! mPyramidsGroupBox->isChecked() )
623  // mPyramidsGroupBox->setChecked( true );
624 
625  // Auto expanding mPyramidsGroupBox is bad - it auto crolls content of dialog
626  //if ( mPyramidsGroupBox->isCollapsed() )
627  // mPyramidsGroupBox->setCollapsed( false );
628  //mPyramidsOptionsWidget->checkAllLevels( true );
629 
630  // Show / hide tile options
631  mTilesGroupBox->show();
632  }
633  else
634  {
635  mTilesGroupBox->hide();
636  }
637 }
638 
639 void QgsRasterLayerSaveAsDialog::on_mPyramidsGroupBox_toggled( bool toggled )
640 {
641  Q_UNUSED( toggled );
642  populatePyramidsLevels();
643 }
644 
645 void QgsRasterLayerSaveAsDialog::populatePyramidsLevels()
646 {
647  QString text;
648 
649  if ( mPyramidsGroupBox->isChecked() )
650  {
651  QList<QgsRasterPyramid> myPyramidList;
652  // if use existing, get pyramids from actual layer
653  // but that's not available yet
654  if ( mPyramidsUseExistingCheckBox->isChecked() )
655  {
656  myPyramidList = mDataProvider->buildPyramidList();
657  }
658  else
659  {
660  if ( ! mPyramidsOptionsWidget->overviewList().isEmpty() )
661  myPyramidList = mDataProvider->buildPyramidList( mPyramidsOptionsWidget->overviewList() );
662  }
663  QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
664  for ( myRasterPyramidIterator = myPyramidList.begin();
665  myRasterPyramidIterator != myPyramidList.end();
666  ++myRasterPyramidIterator )
667  {
668  if ( ! mPyramidsUseExistingCheckBox->isChecked() || myRasterPyramidIterator->exists )
669  {
670  text += QString::number( myRasterPyramidIterator->xDim ) + QLatin1String( "x" ) +
671  QString::number( myRasterPyramidIterator->yDim ) + ' ';
672  }
673  }
674  }
675 
676  mPyramidResolutionsLineEdit->setText( text.trimmed() );
677 }
678 
679 void QgsRasterLayerSaveAsDialog::setNoDataToEdited( int row )
680 {
681  if ( row >= mNoDataToEdited.size() )
682  {
683  mNoDataToEdited.resize( row + 1 );
684  }
685  mNoDataToEdited[row] = true;
686 }
687 
688 double QgsRasterLayerSaveAsDialog::noDataCellValue( int row, int column ) const
689 {
690  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
691  if ( !lineEdit || lineEdit->text().isEmpty() )
692  {
693  std::numeric_limits<double>::quiet_NaN();
694  }
695  return lineEdit->text().toDouble();
696 }
697 
698 void QgsRasterLayerSaveAsDialog::adjustNoDataCellWidth( int row, int column )
699 {
700  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
701  if ( !lineEdit ) return;
702 
703  int width = qMax( lineEdit->fontMetrics().width( lineEdit->text() ) + 10, 100 );
704  width = qMax( width, mNoDataTableWidget->columnWidth( column ) );
705 
706  lineEdit->setFixedWidth( width );
707 }
708 
710 {
711  QgsRasterRangeList noDataList;
712  if ( ! mNoDataGroupBox->isChecked() )
713  return noDataList;
714 
715  int rows = mNoDataTableWidget->rowCount();
716  noDataList.reserve( rows );
717  for ( int r = 0 ; r < rows; r++ )
718  {
719  QgsRasterRange noData( noDataCellValue( r, 0 ), noDataCellValue( r, 1 ) );
720  noDataList.append( noData );
721 
722  }
723  return noDataList;
724 }
725 
727 {
728  return mPyramidsGroupBox->isChecked() ? mPyramidsOptionsWidget->overviewList() : QList<int>();
729 }
730 
732 {
733  if ( ! mPyramidsGroupBox->isChecked() )
735  else if ( mPyramidsUseExistingCheckBox->isChecked() )
737  else
739 }
740 
741 bool QgsRasterLayerSaveAsDialog::validate() const
742 {
743  if ( mCreateOptionsGroupBox->isChecked() )
744  {
745  QString message = mCreateOptionsWidget->validateOptions( true, false );
746  if ( !message.isNull() )
747  return false;
748  }
749  if ( mPyramidsGroupBox->isChecked() )
750  {
751  QString message = mPyramidsOptionsWidget->createOptionsWidget()->validateOptions( true, false );
752  if ( !message.isNull() )
753  return false;
754  }
755  return true;
756 }
757 
QgsPoint transform(const QgsPoint &p, TransformDirection direction=ForwardTransform) const
Transform the point from Source Coordinate System to Destination Coordinate System If the direction i...
virtual int bandCount() const =0
Get number of bands.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:217
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFlags< QFileDialog::Option > options)
void setupUi(QWidget *widget)
static QString printValue(double value)
Print double value with all necessary significant digits.
QgsRaster::RasterBuildPyramids buildPyramidsFlag() const
void setFixedWidth(int w)
void setText(const QString &)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
QObject * sender() const
void reserve(int alloc)
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
virtual int ySize() const
Thirty two bit floating point (float)
Definition: qgis.h:137
Raster values range container.
QgsCoordinateReferenceSystem outputCrs()
QgsRasterRenderer * renderer() const
QString join(const QString &separator) const
QString homePath()
QString tr(const char *sourceText, const char *disambiguation, int n)
const QgsRasterTransparency * rasterTransparency() const
virtual QString name() const =0
Return a provider name.
double y() const
Get the y value of the point.
Definition: qgspoint.h:136
bool isNull() const
T value(int i) const
int width() const
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
void setEnabled(bool)
QString number(int n, int base)
void append(const T &value)
Sixty four bit floating point (double)
Definition: qgis.h:138
void resize(int size)
virtual QGis::DataType srcDataType(int bandNo) const override=0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
virtual QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Accessor for ths raster layers pyramid list.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:207
bool isEmpty() const
bool isEmpty() const
QString trimmed() const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
A class to represent a point.
Definition: qgspoint.h:65
iterator end()
QList< QgsRasterTransparency::TransparentSingleValuePixel > transparentSingleValuePixelList() const
Accessor for transparentSingleValuePixelList.
int width(const QString &text, int len) const
virtual QgsRectangle extent() override=0
Get the extent of the data source.
QgsRasterLayerSaveAsDialog(QgsRasterLayer *rasterLayer, QgsRasterDataProvider *sourceProvider, const QgsRectangle &currentExtent, const QgsCoordinateReferenceSystem &layerCrs, const QgsCoordinateReferenceSystem &currentCrs, QWidget *parent=nullptr, const Qt::WindowFlags &f=nullptr)
QVariant value(const QString &key, const QVariant &defaultValue) const
void setFrame(bool)
QFontMetrics fontMetrics() const
QString absolutePath() const
QStringList entryList(QFlags< QDir::Filter > filters, QFlags< QDir::SortFlag > sort) const
Class for storing a coordinate reference system (CRS)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
Class for doing transforms between two map coordinate systems.
RasterBuildPyramids
Definition: qgsraster.h:71
StandardButton warning(QWidget *parent, const QString &title, const QString &text, QFlags< QMessageBox::StandardButton > buttons, StandardButton defaultButton)
typedef WindowFlags
QgsRasterDataProvider * dataProvider()
Returns the data provider.
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
double ANALYSIS_EXPORT min(double x, double y)
Returns the minimum of two doubles or the first argument if both are equal.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
int size() const
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const
void setValidator(const QValidator *v)
virtual int xSize() const
Get raster size.
QString baseName() const
iterator begin()
double x() const
Get the x value of the point.
Definition: qgspoint.h:128
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:212
void setContentsMargins(int left, int top, int right, int bottom)
Base class for raster data providers.