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