QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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, 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  // Translated labels + EPSG are updated later
52  mCrsComboBox->addItem( "Layer", OriginalCrs );
53  mCrsComboBox->addItem( "Project", CurrentCrs );
54  mCrsComboBox->addItem( "Selected", UserCrs );
55 
56  toggleResolutionSize();
57  mUserCrs.createFromOgcWmsCrs( "EPSG:4326" );
58 
59  //only one hardcoded format at the moment
60  QStringList myFormats;
61  myFormats << "GTiff";
62  foreach ( QString myFormat, myFormats )
63  {
64  mFormatComboBox->addItem( myFormat );
65  }
66 
67  //fill reasonable default values depending on the provider
68  if ( mDataProvider )
69  {
70  if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
71  {
72  setOriginalResolution();
73  int xSize = mDataProvider->xSize();
74  int ySize = mDataProvider->ySize();
75  mMaximumSizeXLineEdit->setText( QString::number( xSize ) );
76  mMaximumSizeYLineEdit->setText( QString::number( ySize ) );
77  }
78  else //wms, sometimes wcs
79  {
80  mTileModeCheckBox->setChecked( true );
81  mMaximumSizeXLineEdit->setText( QString::number( 2000 ) );
82  mMaximumSizeYLineEdit->setText( QString::number( 2000 ) );
83  }
84 
85  // setup creation option widget
86  mCreateOptionsWidget->setProvider( mDataProvider->name() );
87  if ( mDataProvider->name() == "gdal" )
88  {
89  mCreateOptionsWidget->setFormat( myFormats[0] );
90  }
91  mCreateOptionsWidget->setRasterLayer( mRasterLayer );
92  mCreateOptionsWidget->update();
93  }
94 
95  // Only do pyramids if dealing directly with GDAL.
96  if ( mDataProvider->capabilities() & QgsRasterDataProvider::BuildPyramids )
97  {
98  // setup pyramids option widget
99  // mPyramidsOptionsWidget->createOptionsWidget()->setType( QgsRasterFormatSaveOptionsWidget::ProfileLineEdit );
100  mPyramidsOptionsWidget->createOptionsWidget()->setRasterLayer( mRasterLayer );
101 
102  // TODO enable "use existing", has no effect for now, because using Create() in gdal provider
103  // if ( ! mDataProvider->hasPyramids() )
104  // mPyramidsButtonGroup->button( QgsRaster::PyramidsCopyExisting )->setEnabled( false );
105  mPyramidsUseExistingCheckBox->setEnabled( false );
106  mPyramidsUseExistingCheckBox->setVisible( false );
107 
108  populatePyramidsLevels();
109  connect( mPyramidsOptionsWidget, SIGNAL( overviewListChanged() ),
110  this, SLOT( populatePyramidsLevels() ) );
111  }
112  else
113  {
114  mPyramidsGroupBox->setEnabled( false );
115  }
116 
117  // restore checked state for most groupboxes (default is to restore collapsed state)
118  // create options and pyramids will be preset, if user has selected defaults in the gdal options dlg
119  mCreateOptionsGroupBox->setSaveCheckedState( true );
120  //mTilesGroupBox->setSaveCheckedState( true );
121  // don't restore nodata, it needs user input
122  // pyramids are not necessarily built every time
123 
124  mTilesGroupBox->hide();
125 
126  updateCrsGroup();
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  if ( mTileModeCheckBox->isChecked() )
161  {
162  while ( true )
163  {
164  // TODO: would not it be better to select .vrt file instead of directory?
165  fileName = QFileDialog::getExistingDirectory( this, tr( "Select output directory" ) );
166  //fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), QString(), tr( "VRT" ) + " (*.vrt *.VRT)" );
167 
168  if ( fileName.isEmpty() ) break; // canceled
169 
170  // Check if directory is empty
171  QDir dir( fileName );
172  QString baseName = QFileInfo( fileName ).baseName();
173  QStringList filters;
174  filters << QString( "%1.*" ).arg( baseName );
175  QStringList files = dir.entryList( filters );
176  if ( !files.isEmpty() )
177  {
178  QMessageBox::StandardButton button = QMessageBox::warning( this, tr( "Warning" ),
179  tr( "The directory %1 contains files which will be overwritten: %2" ).arg( dir.absolutePath() ).arg( files.join( ", " ) ),
180  QMessageBox::Ok | QMessageBox::Cancel );
181 
182  if ( button == QMessageBox::Ok )
183  {
184  break;
185  }
186  else
187  {
188  fileName = "";
189  }
190  }
191  else
192  {
193  break;
194  }
195  }
196  }
197  else
198  {
199  fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), QString(), tr( "GeoTIFF" ) + " (*.tif *.tiff *.TIF *.TIFF)" );
200  }
201 
202  if ( !fileName.isEmpty() )
203  {
204  mSaveAsLineEdit->setText( fileName );
205  }
206 }
207 
208 void QgsRasterLayerSaveAsDialog::on_mSaveAsLineEdit_textChanged( const QString& text )
209 {
210  QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
211  if ( !okButton )
212  {
213  return;
214  }
215 
216  okButton->setEnabled( QFileInfo( text ).absoluteDir().exists() );
217 }
218 
219 
220 void QgsRasterLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( const QString & text )
221 {
222  //gdal-specific
223  if ( mDataProvider && mDataProvider->name() == "gdal" )
224  {
225  mCreateOptionsWidget->setFormat( text );
226  mCreateOptionsWidget->update();
227  }
228 }
229 
231 {
232  return mColumnsLineEdit->text().toInt();
233 }
234 
236 {
237  return mRowsLineEdit->text().toInt();
238 }
239 
241 {
242  return mXResolutionLineEdit->text().toDouble();
243 }
244 
246 {
247  return mYResolutionLineEdit->text().toDouble();
248 }
249 
251 {
252  return mMaximumSizeXLineEdit->text().toInt();
253 }
254 
256 {
257  return mMaximumSizeYLineEdit->text().toInt();
258 }
259 
261 {
262  return mTileModeCheckBox->isChecked();
263 }
264 
266 {
267  return mSaveAsLineEdit->text();
268 }
269 
271 {
272  return mFormatComboBox->currentText();
273 }
274 
276 {
277  return mCreateOptionsGroupBox->isChecked() ? mCreateOptionsWidget->options() : QStringList();
278 }
279 
281 {
282  return mExtentGroupBox->outputExtent();
283 }
284 
286 {
287  mFormatLabel->hide();
288  mFormatComboBox->hide();
289 }
290 
292 {
293  mSaveAsLabel->hide();
294  mSaveAsLineEdit->hide();
295  mBrowseButton->hide();
296  QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
297  if ( okButton )
298  {
299  okButton->setEnabled( true );
300  }
301 }
302 
303 void QgsRasterLayerSaveAsDialog::toggleResolutionSize()
304 {
305  bool hasResolution = mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::Size;
306 
307  bool on = mResolutionRadioButton->isChecked();
308  mXResolutionLineEdit->setEnabled( on );
309  mYResolutionLineEdit->setEnabled( on );
310  mOriginalResolutionPushButton->setEnabled( on && hasResolution );
311  mColumnsLineEdit->setEnabled( !on );
312  mRowsLineEdit->setEnabled( !on );
313  mOriginalSizePushButton->setEnabled( !on && hasResolution );
314 }
315 
316 void QgsRasterLayerSaveAsDialog::setOriginalResolution()
317 {
318  double xRes, yRes;
319 
320  if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
321  {
322  xRes = mDataProvider->extent().width() / mDataProvider->xSize();
323  yRes = mDataProvider->extent().height() / mDataProvider->ySize();
324  }
325  else
326  {
327  // Init to something if no original resolution is available
328  xRes = yRes = mDataProvider->extent().width() / 100;
329  }
330  setResolution( xRes, yRes, mLayerCrs );
331  mResolutionState = OriginalResolution;
332  recalcSize();
333 }
334 
335 void QgsRasterLayerSaveAsDialog::setResolution( double xRes, double yRes, const QgsCoordinateReferenceSystem& srcCrs )
336 {
337  if ( srcCrs != outputCrs() )
338  {
339  // We reproject pixel rectangle from center of selected extent, of course, it gives
340  // bigger xRes,yRes than reprojected edges (envelope), it may also be that
341  // close to margins are higher resolutions (even very, too high)
342  // TODO: consider more precise resolution calculation
343 
344  QgsPoint center = outputRectangle().center();
345  QgsCoordinateTransform ct( srcCrs, outputCrs() );
346  QgsPoint srsCenter = ct.transform( center, QgsCoordinateTransform::ReverseTransform );
347 
348  QgsRectangle srcExtent( srsCenter.x() - xRes / 2, srsCenter.y() - yRes / 2, srsCenter.x() + xRes / 2, srsCenter.y() + yRes / 2 );
349 
350  QgsRectangle extent = ct.transform( srcExtent );
351  xRes = extent.width();
352  yRes = extent.height();
353  }
354  mXResolutionLineEdit->setText( QString::number( xRes ) );
355  mYResolutionLineEdit->setText( QString::number( yRes ) );
356 }
357 
358 void QgsRasterLayerSaveAsDialog::recalcSize()
359 {
360  QgsDebugMsg( "Entered" );
361  QgsRectangle extent = outputRectangle();
362  int xSize = xResolution() != 0 ? static_cast<int>( qRound( extent.width() / xResolution() ) ) : 0;
363  int ySize = yResolution() != 0 ? static_cast<int>( qRound( extent.height() / yResolution() ) ) : 0;
364  mColumnsLineEdit->setText( QString::number( xSize ) );
365  mRowsLineEdit->setText( QString::number( ySize ) );
366  updateResolutionStateMsg();
367 }
368 
369 void QgsRasterLayerSaveAsDialog::setOriginalSize()
370 {
371  mColumnsLineEdit->setText( QString::number( mDataProvider->xSize() ) );
372  mRowsLineEdit->setText( QString::number( mDataProvider->ySize() ) );
373  recalcResolution();
374 }
375 
376 void QgsRasterLayerSaveAsDialog::recalcResolution()
377 {
378  QgsDebugMsg( "Entered" );
379  QgsRectangle extent = outputRectangle();
380  double xRes = nColumns() != 0 ? extent.width() / nColumns() : 0;
381  double yRes = nRows() != 0 ? extent.height() / nRows() : 0;
382  mXResolutionLineEdit->setText( QString::number( xRes ) );
383  mYResolutionLineEdit->setText( QString::number( yRes ) );
384  updateResolutionStateMsg();
385 }
386 
387 void QgsRasterLayerSaveAsDialog::recalcResolutionSize()
388 {
389  QgsDebugMsg( "Entered" );
390  if ( mResolutionRadioButton->isChecked() )
391  {
392  recalcSize();
393  }
394  else
395  {
396  mResolutionState = UserResolution;
397  recalcResolution();
398  }
399 }
400 
401 void QgsRasterLayerSaveAsDialog::updateResolutionStateMsg()
402 {
403  QString msg;
404  switch ( mResolutionState )
405  {
406  case OriginalResolution:
407  msg = tr( "layer" );
408  break;
409  case UserResolution:
410  msg = tr( "user defined" );
411  break;
412  default:
413  break;
414  }
415  msg = tr( "Resolution (current: %1)" ).arg( msg );
416  mResolutionGroupBox->setTitle( msg );
417 }
418 
419 void QgsRasterLayerSaveAsDialog::extentChanged()
420 {
421  // Whenever extent changes with fixed size, original resolution is lost
422  if ( mSizeRadioButton->isChecked() )
423  {
424  mResolutionState = UserResolution;
425  }
426  recalcResolutionSize();
427 }
428 
429 void QgsRasterLayerSaveAsDialog::on_mChangeCrsPushButton_clicked()
430 {
432  selector->setMessage();
433  selector->setSelectedCrsId( mUserCrs.srsid() );
434  if ( selector->exec() )
435  {
437  mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( UserCrs ) );
438  }
439  delete selector;
440  crsChanged();
441 }
442 
443 void QgsRasterLayerSaveAsDialog::crsChanged()
444 {
445  QgsDebugMsg( "Entered" );
446  if ( outputCrs() != mPreviousCrs )
447  {
448  mExtentGroupBox->setOutputCrs( outputCrs() );
449  QgsExtentGroupBox::ExtentState state = mExtentGroupBox->extentState();
450 
451  // Reset extent
452  // We could reproject previous but that would add additional space also if
453  // it is was not necessary or at leas it could decrease accuracy
454  if ( state == QgsExtentGroupBox::OriginalExtent )
455  {
456  mExtentGroupBox->setOutputExtentFromOriginal();
457  }
458  else if ( state == QgsExtentGroupBox::CurrentExtent )
459  {
460  mExtentGroupBox->setOutputExtentFromCurrent();
461  }
462  else
463  {
464  mExtentGroupBox->setOutputExtentFromUser( mExtentGroupBox->outputExtent(), mPreviousCrs );
465  }
466 
467  // Reset resolution
468  if ( mResolutionRadioButton->isChecked() )
469  {
470  if ( mResolutionState == OriginalResolution )
471  {
472  setOriginalResolution();
473  }
474  else
475  {
476  // reset from present resolution and present crs
477  setResolution( xResolution(), yResolution(), mPreviousCrs );
478  }
479  }
480  else
481  {
482  // Size does not change, we just recalc resolution from new extent
483  recalcResolution();
484  }
485  }
486  mPreviousCrs = outputCrs();
487  updateCrsGroup();
488 }
489 
490 void QgsRasterLayerSaveAsDialog::updateCrsGroup()
491 {
492  QgsDebugMsg( "Entered" );
493 
494  mCrsComboBox->setItemText( mCrsComboBox->findData( OriginalCrs ),
495  tr( "Layer (%1, %2)" ).arg( mLayerCrs.description() ).arg( mLayerCrs.authid() ) );
496 
497  mCrsComboBox->setItemText( mCrsComboBox->findData( CurrentCrs ),
498  tr( "Project (%1, %2)" ).arg( mCurrentCrs.description() ).arg( mCurrentCrs.authid() ) );
499 
500  mCrsComboBox->setItemText( mCrsComboBox->findData( UserCrs ),
501  tr( "Selected (%1, %2)" ).arg( mUserCrs.description() ).arg( mUserCrs.authid() ) );
502 }
503 
505 {
506  int state = mCrsComboBox->itemData( mCrsComboBox->currentIndex() ).toInt();
507  if ( state == OriginalCrs )
508  {
509  return mLayerCrs;
510  }
511  else if ( state == CurrentCrs )
512  {
513  return mCurrentCrs;
514  }
515  return mUserCrs;
516 }
517 
519 {
520  if ( mRenderedModeRadioButton->isChecked() ) return RenderedImageMode;
521  return RawDataMode;
522 }
523 
524 void QgsRasterLayerSaveAsDialog::on_mRawModeRadioButton_toggled( bool checked )
525 {
526  mNoDataGroupBox->setEnabled( checked && mDataProvider->bandCount() == 1 );
527 }
528 
529 void QgsRasterLayerSaveAsDialog::on_mAddNoDataManuallyToolButton_clicked()
530 {
531  addNoDataRow( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
532 }
533 
534 void QgsRasterLayerSaveAsDialog::on_mLoadTransparentNoDataToolButton_clicked()
535 {
536  if ( !mRasterLayer->renderer() ) return;
537  const QgsRasterTransparency* rasterTransparency = mRasterLayer->renderer()->rasterTransparency();
538  if ( !rasterTransparency ) return;
539 
540  foreach ( QgsRasterTransparency::TransparentSingleValuePixel transparencyPixel, rasterTransparency->transparentSingleValuePixelList() )
541  {
542  if ( transparencyPixel.percentTransparent == 100 )
543  {
544  addNoDataRow( transparencyPixel.min, transparencyPixel.max );
545  if ( transparencyPixel.min != transparencyPixel.max )
546  {
547  setNoDataToEdited( mNoDataTableWidget->rowCount() - 1 );
548  }
549  }
550  }
551 }
552 
553 void QgsRasterLayerSaveAsDialog::on_mRemoveSelectedNoDataToolButton_clicked()
554 {
555  mNoDataTableWidget->removeRow( mNoDataTableWidget->currentRow() );
556 }
557 
558 void QgsRasterLayerSaveAsDialog::on_mRemoveAllNoDataToolButton_clicked()
559 {
560  while ( mNoDataTableWidget->rowCount() > 0 )
561  {
562  mNoDataTableWidget->removeRow( 0 );
563  }
564 }
565 
566 void QgsRasterLayerSaveAsDialog::addNoDataRow( double min, double max )
567 {
568  mNoDataTableWidget->insertRow( mNoDataTableWidget->rowCount() );
569  for ( int i = 0; i < 2; i++ )
570  {
571  double value = i == 0 ? min : max;
572  QLineEdit *lineEdit = new QLineEdit();
573  lineEdit->setFrame( false );
574  lineEdit->setContentsMargins( 1, 1, 1, 1 );
575  QString valueString;
576  switch ( mRasterLayer->dataProvider()->srcDataType( 1 ) )
577  {
578  case QGis::Float32:
579  case QGis::Float64:
580  lineEdit->setValidator( new QDoubleValidator( 0 ) );
581  if ( !qIsNaN( value ) )
582  {
583  valueString = QgsRasterBlock::printValue( value );
584  }
585  break;
586  default:
587  lineEdit->setValidator( new QIntValidator( 0 ) );
588  if ( !qIsNaN( value ) )
589  {
590  valueString = QString::number( static_cast<int>( value ) );
591  }
592  break;
593  }
594  lineEdit->setText( valueString );
595  mNoDataTableWidget->setCellWidget( mNoDataTableWidget->rowCount() - 1, i, lineEdit );
596 
597  adjustNoDataCellWidth( mNoDataTableWidget->rowCount() - 1, i );
598 
599  connect( lineEdit, SIGNAL( textEdited( const QString & ) ), this, SLOT( noDataCellTextEdited( const QString & ) ) );
600  }
601  mNoDataTableWidget->resizeColumnsToContents();
602  mNoDataTableWidget->resizeRowsToContents();
603 }
604 
605 void QgsRasterLayerSaveAsDialog::noDataCellTextEdited( const QString & text )
606 {
607  Q_UNUSED( text );
608 
609  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( sender() );
610  if ( !lineEdit ) return;
611  int row = -1;
612  int column = -1;
613  for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
614  {
615  for ( int c = 0 ; c < mNoDataTableWidget->columnCount(); c++ )
616  {
617  if ( mNoDataTableWidget->cellWidget( r, c ) == sender() )
618  {
619  row = r;
620  column = c;
621  break;
622  }
623  }
624  if ( row != -1 ) break;
625  }
626  QgsDebugMsg( QString( "row = %1 column =%2" ).arg( row ).arg( column ) );
627 
628  if ( column == 0 )
629  {
630  QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, 1 ) );
631  if ( !toLineEdit ) return;
632  bool toChanged = mNoDataToEdited.value( row );
633  QgsDebugMsg( QString( "toChanged = %1" ).arg( toChanged ) );
634  if ( !toChanged )
635  {
636  toLineEdit->setText( lineEdit->text() );
637  }
638  }
639  else if ( column == 1 )
640  {
641  setNoDataToEdited( row );
642  }
643 }
644 
645 void QgsRasterLayerSaveAsDialog::on_mTileModeCheckBox_toggled( bool toggled )
646 {
647  if ( toggled )
648  {
649  // enable pyramids
650 
651  // Disabled (Radim), auto enabling of pyramids was making impression that
652  // we (programmers) know better what you (user) want to do,
653  // certainly auto expaning was bad experience
654 
655  //if ( ! mPyramidsGroupBox->isChecked() )
656  // mPyramidsGroupBox->setChecked( true );
657 
658  // Auto expanding mPyramidsGroupBox is bad - it auto crolls content of dialog
659  //if ( mPyramidsGroupBox->isCollapsed() )
660  // mPyramidsGroupBox->setCollapsed( false );
661  //mPyramidsOptionsWidget->checkAllLevels( true );
662 
663  // Show / hide tile options
664  mTilesGroupBox->show();
665  }
666  else
667  {
668  mTilesGroupBox->hide();
669  }
670 }
671 
672 void QgsRasterLayerSaveAsDialog::on_mPyramidsGroupBox_toggled( bool toggled )
673 {
674  Q_UNUSED( toggled );
675  populatePyramidsLevels();
676 }
677 
678 void QgsRasterLayerSaveAsDialog::populatePyramidsLevels()
679 {
680  QString text;
681 
682  if ( mPyramidsGroupBox->isChecked() )
683  {
684  QList<QgsRasterPyramid> myPyramidList;
685  // if use existing, get pyramids from actual layer
686  // but that's not available yet
687  if ( mPyramidsUseExistingCheckBox->isChecked() )
688  {
689  myPyramidList = mDataProvider->buildPyramidList();
690  }
691  else
692  {
693  if ( ! mPyramidsOptionsWidget->overviewList().isEmpty() )
694  myPyramidList = mDataProvider->buildPyramidList( mPyramidsOptionsWidget->overviewList() );
695  }
696  QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
697  for ( myRasterPyramidIterator = myPyramidList.begin();
698  myRasterPyramidIterator != myPyramidList.end();
699  ++myRasterPyramidIterator )
700  {
701  if ( ! mPyramidsUseExistingCheckBox->isChecked() || myRasterPyramidIterator->exists )
702  {
703  text += QString::number( myRasterPyramidIterator->xDim ) + QString( "x" ) +
704  QString::number( myRasterPyramidIterator->yDim ) + " ";
705  }
706  }
707  }
708 
709  mPyramidResolutionsLineEdit->setText( text.trimmed() );
710 }
711 
712 void QgsRasterLayerSaveAsDialog::setNoDataToEdited( int row )
713 {
714  if ( row >= mNoDataToEdited.size() )
715  {
716  mNoDataToEdited.resize( row + 1 );
717  }
718  mNoDataToEdited[row] = true;
719 }
720 
721 double QgsRasterLayerSaveAsDialog::noDataCellValue( int row, int column ) const
722 {
723  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
724  if ( !lineEdit || lineEdit->text().isEmpty() )
725  {
726  std::numeric_limits<double>::quiet_NaN();
727  }
728  return lineEdit->text().toDouble();
729 }
730 
731 void QgsRasterLayerSaveAsDialog::adjustNoDataCellWidth( int row, int column )
732 {
733  QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
734  if ( !lineEdit ) return;
735 
736  int width = qMax( lineEdit->fontMetrics().width( lineEdit->text() ) + 10, 100 );
737  width = qMax( width, mNoDataTableWidget->columnWidth( column ) );
738 
739  lineEdit->setFixedWidth( width );
740 }
741 
743 {
744  QgsRasterRangeList noDataList;
745  if ( ! mNoDataGroupBox->isChecked() )
746  return noDataList;
747 
748  for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
749  {
750  QgsRasterRange noData( noDataCellValue( r, 0 ), noDataCellValue( r, 1 ) );
751  noDataList.append( noData );
752 
753  }
754  return noDataList;
755 }
756 
758 {
759  return mPyramidsGroupBox->isChecked() ? mPyramidsOptionsWidget->overviewList() : QList<int>();
760 }
761 
763 {
764  if ( ! mPyramidsGroupBox->isChecked() )
766  else if ( mPyramidsUseExistingCheckBox->isChecked() )
768  else
770 }
771 
772 bool QgsRasterLayerSaveAsDialog::validate() const
773 {
774  if ( mCreateOptionsGroupBox->isChecked() )
775  {
776  QString message = mCreateOptionsWidget->validateOptions( true, false );
777  if ( !message.isNull() )
778  return false;
779  }
780  if ( mPyramidsGroupBox->isChecked() )
781  {
782  QString message = mPyramidsOptionsWidget->createOptionsWidget()->validateOptions( true, false );
783  if ( !message.isNull() )
784  return false;
785  }
786  return true;
787 }
788 
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
static QString printValue(double value)
Print double value with all necessary significant digits.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
A generic dialog to prompt the user for a Coordinate Reference System.
bool createFromId(const long theId, CrsType theType=PostgisCrsId)
Raster values range container.
QgsCoordinateReferenceSystem outputCrs()
double x() const
Definition: qgspoint.h:126
virtual QString name() const =0
return a provider name
virtual int ySize() const
const QgsRasterTransparency * rasterTransparency() const
QgsRasterLayerSaveAsDialog(QgsRasterLayer *rasterLayer, QgsRasterDataProvider *sourceProvider, const QgsRectangle &currentExtent, const QgsCoordinateReferenceSystem &layerCrs, const QgsCoordinateReferenceSystem &currentCrs, QWidget *parent=0, Qt::WindowFlags f=0)
bool createFromOgcWmsCrs(QString theCrs)
Set up this CRS from the given OGC CRS.
QgsRasterRenderer * renderer() const
virtual QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Accessor for ths raster layers pyramid list.
virtual QGis::DataType srcDataType(int bandNo) const =0
Returns source data type for the band specified by number, source data type may be shorter than dataT...
virtual QgsRectangle extent()=0
Get the extent of the data source.
QgsRaster::RasterBuildPyramids buildPyramidsFlag() const
void setMessage(QString theMessage="")
If no parameter is passed, the message will be a generic 'define the CRS for this layer'...
A class to represent a point.
Definition: qgspoint.h:63
int min(int a, int b)
Definition: util.h:93
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
QgsRasterRangeList noData() const
QList< QgsRasterRange > QgsRasterRangeList
virtual int xSize() const
Get raster size.
RasterBuildPyramids
Definition: qgsraster.h:71
Class for storing a coordinate reference system (CRS)
Class for doing transforms between two map coordinate systems.
double y() const
Definition: qgspoint.h:134
QgsRasterDataProvider * dataProvider()
Returns the data provider.
Defines the list of pixel values to be considered as transparent or semi transparent when rendering r...
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:198
int max(int a, int b)
Definition: util.h:87
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:208
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:203
Base class for raster data providers.
#define tr(sourceText)