Quantum GIS API Documentation  master-ce49b66
src/gui/qgsrasterlayersaveasdialog.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgsrasterlayersaveasdialog.cpp
00003     ---------------------
00004     begin                : May 2012
00005     copyright            : (C) 2012 by Marco Hugentobler
00006     email                : marco dot hugentobler at sourcepole dot ch
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 #include "qgsapplication.h"
00016 #include "qgslogger.h"
00017 #include "qgscoordinatetransform.h"
00018 #include "qgsrasterlayer.h"
00019 #include "qgsrasterlayersaveasdialog.h"
00020 #include "qgsrasterdataprovider.h"
00021 #include "qgsrasterformatsaveoptionswidget.h"
00022 #include "qgsgenericprojectionselector.h"
00023 
00024 #include <QFileDialog>
00025 #include <QMessageBox>
00026 #include <QSettings>
00027 
00028 QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterLayer* rasterLayer,
00029     QgsRasterDataProvider* sourceProvider, const QgsRectangle& currentExtent,
00030     const QgsCoordinateReferenceSystem& layerCrs, const QgsCoordinateReferenceSystem& currentCrs,
00031     QWidget* parent, Qt::WindowFlags f ) :
00032     QDialog( parent, f )
00033     , mRasterLayer( rasterLayer ), mDataProvider( sourceProvider )
00034     , mCurrentExtent( currentExtent ), mLayerCrs( layerCrs )
00035     , mCurrentCrs( currentCrs ), mExtentState( OriginalExtent )
00036     , mResolutionState( OriginalResolution )
00037 {
00038   setupUi( this );
00039   mAddNoDataManuallyToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionNewAttribute.png" ) );
00040   mLoadTransparentNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionCopySelected.png" ) );
00041   mRemoveSelectedNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionDeleteAttribute.png" ) );
00042   mRemoveAllNoDataToolButton->setIcon( QgsApplication::getThemeIcon( "/mActionRemove.png" ) );
00043 
00044   mNoDataTableWidget->setColumnCount( 2 );
00045   mNoDataTableWidget->setHorizontalHeaderItem( 0, new QTableWidgetItem( tr( "From" ) ) );
00046   mNoDataTableWidget->setHorizontalHeaderItem( 1, new QTableWidgetItem( tr( "To" ) ) );
00047 
00048   on_mRawModeRadioButton_toggled( true );
00049 
00050   setValidators();
00051   // Translated labels + EPSG are updated later
00052   mCrsComboBox->addItem( "Layer", OriginalCrs );
00053   mCrsComboBox->addItem( "Project", CurrentCrs );
00054   mCrsComboBox->addItem( "Selected", UserCrs );
00055 
00056   toggleResolutionSize();
00057   mUserCrs.createFromOgcWmsCrs( "EPSG:4326" );
00058 
00059   //only one hardcoded format at the moment
00060   QStringList myFormats;
00061   myFormats << "GTiff";
00062   foreach ( QString myFormat, myFormats )
00063   {
00064     mFormatComboBox->addItem( myFormat );
00065   }
00066 
00067   //fill reasonable default values depending on the provider
00068   if ( mDataProvider )
00069   {
00070     //extent
00071     setOutputExtent( mDataProvider->extent(), mLayerCrs, OriginalExtent );
00072 
00073     if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
00074     {
00075       setOriginalResolution();
00076       int xSize = mDataProvider->xSize();
00077       int ySize = mDataProvider->ySize();
00078       mMaximumSizeXLineEdit->setText( QString::number( xSize ) );
00079       mMaximumSizeYLineEdit->setText( QString::number( ySize ) );
00080     }
00081     else //wms, sometimes wcs
00082     {
00083       mTileModeCheckBox->setChecked( true );
00084       mMaximumSizeXLineEdit->setText( QString::number( 2000 ) );
00085       mMaximumSizeYLineEdit->setText( QString::number( 2000 ) );
00086     }
00087 
00088     // setup creation option widget
00089     mCreateOptionsWidget->setProvider( mDataProvider->name() );
00090     if ( mDataProvider->name() == "gdal" )
00091     {
00092       mCreateOptionsWidget->setFormat( myFormats[0] );
00093     }
00094     mCreateOptionsWidget->setRasterLayer( mRasterLayer );
00095     mCreateOptionsWidget->update();
00096   }
00097 
00098   // Only do pyramids if dealing directly with GDAL.
00099   if ( mDataProvider->capabilities() & QgsRasterDataProvider::BuildPyramids )
00100   {
00101     // setup pyramids option widget
00102     // mPyramidsOptionsWidget->createOptionsWidget()->setType( QgsRasterFormatSaveOptionsWidget::ProfileLineEdit );
00103     mPyramidsOptionsWidget->createOptionsWidget()->setRasterLayer( mRasterLayer );
00104 
00105     // TODO enable "use existing", has no effect for now, because using Create() in gdal provider
00106     // if ( ! mDataProvider->hasPyramids() )
00107     //   mPyramidsButtonGroup->button( QgsRaster::PyramidsCopyExisting )->setEnabled( false );
00108     mPyramidsUseExistingCheckBox->setEnabled( false );
00109     mPyramidsUseExistingCheckBox->setVisible( false );
00110 
00111     populatePyramidsLevels();
00112     connect( mPyramidsOptionsWidget, SIGNAL( overviewListChanged() ),
00113              this, SLOT( populatePyramidsLevels() ) );
00114   }
00115   else
00116   {
00117     mPyramidsGroupBox->setEnabled( false );
00118   }
00119 
00120   // restore checked state for most groupboxes (default is to restore collapsed state)
00121   // create options and pyramids will be preset, if user has selected defaults in the gdal options dlg
00122   mCreateOptionsGroupBox->setSaveCheckedState( true );
00123   //mTilesGroupBox->setSaveCheckedState( true );
00124   // don't restore nodata, it needs user input
00125   // pyramids are not necessarily built every time
00126 
00127   mTilesGroupBox->hide();
00128 
00129   updateCrsGroup();
00130 
00131   QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
00132   if ( okButton )
00133   {
00134     okButton->setEnabled( false );
00135   }
00136 }
00137 
00138 void QgsRasterLayerSaveAsDialog::setValidators()
00139 {
00140   mXResolutionLineEdit->setValidator( new QDoubleValidator( this ) );
00141   mYResolutionLineEdit->setValidator( new QDoubleValidator( this ) );
00142   mColumnsLineEdit->setValidator( new QIntValidator( this ) );
00143   mRowsLineEdit->setValidator( new QIntValidator( this ) );
00144   mMaximumSizeXLineEdit->setValidator( new QIntValidator( this ) );
00145   mMaximumSizeYLineEdit->setValidator( new QIntValidator( this ) );
00146   mXMinLineEdit->setValidator( new QDoubleValidator( this ) );
00147   mXMaxLineEdit->setValidator( new QDoubleValidator( this ) );
00148   mYMinLineEdit->setValidator( new QDoubleValidator( this ) );
00149   mYMaxLineEdit->setValidator( new QDoubleValidator( this ) );
00150 }
00151 
00152 QgsRasterLayerSaveAsDialog::~QgsRasterLayerSaveAsDialog()
00153 {
00154 }
00155 
00156 void QgsRasterLayerSaveAsDialog::on_mBrowseButton_clicked()
00157 {
00158   QString fileName;
00159   if ( mTileModeCheckBox->isChecked() )
00160   {
00161     while ( true )
00162     {
00163       // TODO: would not it be better to select .vrt file instead of directory?
00164       fileName = QFileDialog::getExistingDirectory( this, tr( "Select output directory" ) );
00165       //fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), QString(), tr( "VRT" ) + " (*.vrt *.VRT)" );
00166 
00167       if ( fileName.isEmpty() ) break; // canceled
00168 
00169       // Check if directory is empty
00170       QDir dir( fileName );
00171       QString baseName = QFileInfo( fileName ).baseName();
00172       QStringList filters;
00173       filters << QString( "%1.*" ).arg( baseName );
00174       QStringList files = dir.entryList( filters );
00175       if ( !files.isEmpty() )
00176       {
00177         QMessageBox::StandardButton button = QMessageBox::warning( this, tr( "Warning" ),
00178                                              tr( "The directory %1 contains files which will be overwritten: %2" ).arg( dir.absolutePath() ).arg( files.join( ", " ) ),
00179                                              QMessageBox::Ok | QMessageBox::Cancel );
00180 
00181         if ( button == QMessageBox::Ok )
00182         {
00183           break;
00184         }
00185         else
00186         {
00187           fileName = "";
00188         }
00189       }
00190       else
00191       {
00192         break;
00193       }
00194     }
00195   }
00196   else
00197   {
00198     fileName = QFileDialog::getSaveFileName( this, tr( "Select output file" ), QString(), tr( "GeoTIFF" ) + " (*.tif *.tiff *.TIF *.TIFF)" );
00199   }
00200 
00201   if ( !fileName.isEmpty() )
00202   {
00203     mSaveAsLineEdit->setText( fileName );
00204   }
00205 }
00206 
00207 void QgsRasterLayerSaveAsDialog::on_mSaveAsLineEdit_textChanged( const QString& text )
00208 {
00209   QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
00210   if ( !okButton )
00211   {
00212     return;
00213   }
00214 
00215   okButton->setEnabled( QFileInfo( text ).absoluteDir().exists() );
00216 }
00217 
00218 void QgsRasterLayerSaveAsDialog::on_mCurrentExtentButton_clicked()
00219 {
00220   setOutputExtent( mCurrentExtent, mCurrentCrs, CurrentExtent );
00221 }
00222 
00223 void QgsRasterLayerSaveAsDialog::on_mOriginalExtentButton_clicked()
00224 {
00225   if ( mDataProvider )
00226   {
00227     setOutputExtent( mDataProvider->extent(), mLayerCrs, OriginalExtent );
00228   }
00229 }
00230 
00231 void QgsRasterLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( const QString & text )
00232 {
00233   //gdal-specific
00234   if ( mDataProvider && mDataProvider->name() == "gdal" )
00235   {
00236     mCreateOptionsWidget->setFormat( text );
00237     mCreateOptionsWidget->update();
00238   }
00239 }
00240 
00241 int QgsRasterLayerSaveAsDialog::nColumns() const
00242 {
00243   return mColumnsLineEdit->text().toInt();
00244 }
00245 
00246 int QgsRasterLayerSaveAsDialog::nRows() const
00247 {
00248   return mRowsLineEdit->text().toInt();
00249 }
00250 
00251 double QgsRasterLayerSaveAsDialog::xResolution() const
00252 {
00253   return mXResolutionLineEdit->text().toDouble();
00254 }
00255 
00256 double QgsRasterLayerSaveAsDialog::yResolution() const
00257 {
00258   return mYResolutionLineEdit->text().toDouble();
00259 }
00260 
00261 int QgsRasterLayerSaveAsDialog::maximumTileSizeX() const
00262 {
00263   return mMaximumSizeXLineEdit->text().toInt();
00264 }
00265 
00266 int QgsRasterLayerSaveAsDialog::maximumTileSizeY() const
00267 {
00268   return mMaximumSizeYLineEdit->text().toInt();
00269 }
00270 
00271 bool QgsRasterLayerSaveAsDialog::tileMode() const
00272 {
00273   return mTileModeCheckBox->isChecked();
00274 }
00275 
00276 QString QgsRasterLayerSaveAsDialog::outputFileName() const
00277 {
00278   return mSaveAsLineEdit->text();
00279 }
00280 
00281 QString QgsRasterLayerSaveAsDialog::outputFormat() const
00282 {
00283   return mFormatComboBox->currentText();
00284 }
00285 
00286 QStringList QgsRasterLayerSaveAsDialog::createOptions() const
00287 {
00288   return mCreateOptionsGroupBox->isChecked() ? mCreateOptionsWidget->options() : QStringList();
00289 }
00290 
00291 QgsRectangle QgsRasterLayerSaveAsDialog::outputRectangle() const
00292 {
00293   return QgsRectangle( mXMinLineEdit->text().toDouble(), mYMinLineEdit->text().toDouble(), mXMaxLineEdit->text().toDouble(), mYMaxLineEdit->text().toDouble() );
00294 }
00295 
00296 void QgsRasterLayerSaveAsDialog::setOutputExtent( const QgsRectangle& r, const QgsCoordinateReferenceSystem& srcCrs, ExtentState state )
00297 {
00298   QgsRectangle extent;
00299   if ( outputCrs() == srcCrs )
00300   {
00301     extent = r;
00302   }
00303   else
00304   {
00305     QgsCoordinateTransform ct( srcCrs, outputCrs() );
00306     extent = ct.transformBoundingBox( r );
00307   }
00308 
00309   mXMinLineEdit->setText( QgsRasterBlock::printValue( extent.xMinimum() ) );
00310   mXMaxLineEdit->setText( QgsRasterBlock::printValue( extent.xMaximum() ) );
00311   mYMinLineEdit->setText( QgsRasterBlock::printValue( extent.yMinimum() ) );
00312   mYMaxLineEdit->setText( QgsRasterBlock::printValue( extent.yMaximum() ) );
00313 
00314   mExtentState = state;
00315   extentChanged();
00316 }
00317 
00318 void QgsRasterLayerSaveAsDialog::hideFormat()
00319 {
00320   mFormatLabel->hide();
00321   mFormatComboBox->hide();
00322 }
00323 
00324 void QgsRasterLayerSaveAsDialog::hideOutput()
00325 {
00326   mSaveAsLabel->hide();
00327   mSaveAsLineEdit->hide();
00328   mBrowseButton->hide();
00329   QPushButton* okButton = mButtonBox->button( QDialogButtonBox::Ok );
00330   if ( okButton )
00331   {
00332     okButton->setEnabled( true );
00333   }
00334 }
00335 
00336 void QgsRasterLayerSaveAsDialog::toggleResolutionSize()
00337 {
00338   bool hasResolution = mDataProvider && mDataProvider->capabilities() & QgsRasterDataProvider::Size;
00339 
00340   bool on = mResolutionRadioButton->isChecked();
00341   mXResolutionLineEdit->setEnabled( on );
00342   mYResolutionLineEdit->setEnabled( on );
00343   mOriginalResolutionPushButton->setEnabled( on && hasResolution );
00344   mColumnsLineEdit->setEnabled( !on );
00345   mRowsLineEdit->setEnabled( !on );
00346   mOriginalSizePushButton->setEnabled( !on && hasResolution );
00347 }
00348 
00349 void QgsRasterLayerSaveAsDialog::setOriginalResolution()
00350 {
00351   double xRes, yRes;
00352 
00353   if ( mDataProvider->capabilities() & QgsRasterDataProvider::Size )
00354   {
00355     xRes = mDataProvider->extent().width() / mDataProvider->xSize();
00356     yRes = mDataProvider->extent().height() / mDataProvider->ySize();
00357   }
00358   else
00359   {
00360     // Init to something if no original resolution is available
00361     xRes = yRes = mDataProvider->extent().width() / 100;
00362   }
00363   setResolution( xRes, yRes, mLayerCrs );
00364   mResolutionState = OriginalResolution;
00365   recalcSize();
00366 }
00367 
00368 void QgsRasterLayerSaveAsDialog::setResolution( double xRes, double yRes, const QgsCoordinateReferenceSystem& srcCrs )
00369 {
00370   if ( srcCrs != outputCrs() )
00371   {
00372     // We reproject pixel rectangle from center of selected extent, of course, it gives
00373     // bigger xRes,yRes than reprojected edges (envelope), it may also be that
00374     // close to margins are higher resolutions (even very, too high)
00375     // TODO: consider more precise resolution calculation
00376 
00377     QgsPoint center = outputRectangle().center();
00378     QgsCoordinateTransform ct( srcCrs, outputCrs() );
00379     QgsPoint srsCenter = ct.transform( center, QgsCoordinateTransform::ReverseTransform );
00380 
00381     QgsRectangle srcExtent( srsCenter.x() - xRes / 2, srsCenter.y() - yRes / 2, srsCenter.x() + xRes / 2, srsCenter.y() + yRes / 2 );
00382 
00383     QgsRectangle extent =  ct.transform( srcExtent );
00384     xRes = extent.width();
00385     yRes = extent.height();
00386   }
00387   mXResolutionLineEdit->setText( QString::number( xRes ) );
00388   mYResolutionLineEdit->setText( QString::number( yRes ) );
00389 }
00390 
00391 void QgsRasterLayerSaveAsDialog::recalcSize()
00392 {
00393   QgsDebugMsg( "Entered" );
00394   QgsRectangle extent = outputRectangle();
00395   int xSize =  xResolution() != 0 ? static_cast<int>( qRound( extent.width() / xResolution() ) ) : 0;
00396   int ySize =  yResolution() != 0 ? static_cast<int>( qRound( extent.height() / yResolution() ) ) : 0;
00397   mColumnsLineEdit->setText( QString::number( xSize ) );
00398   mRowsLineEdit->setText( QString::number( ySize ) );
00399   updateResolutionStateMsg();
00400 }
00401 
00402 void QgsRasterLayerSaveAsDialog::setOriginalSize()
00403 {
00404   mColumnsLineEdit->setText( QString::number( mDataProvider->xSize() ) );
00405   mRowsLineEdit->setText( QString::number( mDataProvider->ySize() ) );
00406   recalcResolution();
00407 }
00408 
00409 void QgsRasterLayerSaveAsDialog::recalcResolution()
00410 {
00411   QgsDebugMsg( "Entered" );
00412   QgsRectangle extent = outputRectangle();
00413   double xRes = nColumns() != 0 ? extent.width() / nColumns() : 0;
00414   double yRes = nRows() != 0 ? extent.height() / nRows() : 0;
00415   mXResolutionLineEdit->setText( QString::number( xRes ) );
00416   mYResolutionLineEdit->setText( QString::number( yRes ) );
00417   updateResolutionStateMsg();
00418 }
00419 
00420 void QgsRasterLayerSaveAsDialog::recalcResolutionSize()
00421 {
00422   QgsDebugMsg( "Entered" );
00423   if ( mResolutionRadioButton->isChecked() )
00424   {
00425     recalcSize();
00426   }
00427   else
00428   {
00429     mResolutionState = UserResolution;
00430     recalcResolution();
00431   }
00432 }
00433 
00434 void QgsRasterLayerSaveAsDialog::updateResolutionStateMsg()
00435 {
00436   QString msg;
00437   switch ( mResolutionState )
00438   {
00439     case OriginalResolution:
00440       msg = tr( "layer" );
00441       break;
00442     case UserResolution:
00443       msg = tr( "user defined" );
00444       break;
00445     default:
00446       break;
00447   }
00448   msg = tr( "Resolution (current: %1)" ).arg( msg );
00449   mResolutionGroupBox->setTitle( msg );
00450 }
00451 
00452 void QgsRasterLayerSaveAsDialog::extentChanged()
00453 {
00454   updateExtentStateMsg();
00455   // Whenever extent changes with fixed size, original resolution is lost
00456   if ( mSizeRadioButton->isChecked() )
00457   {
00458     mResolutionState = UserResolution;
00459   }
00460   recalcResolutionSize();
00461 }
00462 
00463 void QgsRasterLayerSaveAsDialog::updateExtentStateMsg()
00464 {
00465   QString msg;
00466   switch ( mExtentState )
00467   {
00468     case OriginalExtent:
00469       msg = tr( "layer" );
00470       break;
00471     case CurrentExtent:
00472       msg = tr( "map view" );
00473       break;
00474     case UserExtent:
00475       msg = tr( "user defined" );
00476       break;
00477     default:
00478       break;
00479   }
00480   msg = tr( "Extent (current: %1)" ).arg( msg );
00481   mExtentGroupBox->setTitle( msg );
00482 }
00483 
00484 void QgsRasterLayerSaveAsDialog::on_mChangeCrsPushButton_clicked()
00485 {
00486   QgsGenericProjectionSelector * selector = new QgsGenericProjectionSelector( this );
00487   selector->setMessage();
00488   selector->setSelectedCrsId( mUserCrs.srsid() );
00489   if ( selector->exec() )
00490   {
00491     mUserCrs.createFromId( selector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId );
00492     mCrsComboBox->setCurrentIndex( mCrsComboBox->findData( UserCrs ) );
00493   }
00494   delete selector;
00495   crsChanged();
00496 }
00497 
00498 void QgsRasterLayerSaveAsDialog::crsChanged()
00499 {
00500   QgsDebugMsg( "Entered" );
00501   if ( outputCrs() != mPreviousCrs )
00502   {
00503     // Reset extent
00504     QgsRectangle previousExtent;
00505     QgsCoordinateReferenceSystem previousCrs;
00506     // We could reproject previous but that would add additional space also if
00507     // it is was not necessary or at leas it could decrease accuracy
00508     if ( mExtentState == OriginalExtent )
00509     {
00510       previousExtent = mDataProvider->extent();
00511       previousCrs = mLayerCrs;
00512     }
00513     else if ( mExtentState == CurrentExtent )
00514     {
00515       previousExtent = mCurrentExtent;
00516       previousCrs = mCurrentCrs;
00517     }
00518     else
00519     {
00520       previousExtent = outputRectangle();
00521       previousCrs = mPreviousCrs;
00522     }
00523     setOutputExtent( previousExtent, previousCrs, mExtentState );
00524 
00525     // Reset resolution
00526     if ( mResolutionRadioButton->isChecked() )
00527     {
00528       if ( mResolutionState == OriginalResolution )
00529       {
00530         setOriginalResolution();
00531       }
00532       else
00533       {
00534         // reset from present resolution and present crs
00535         setResolution( xResolution(), yResolution(), mPreviousCrs );
00536       }
00537     }
00538     else
00539     {
00540       // Size does not change, we just recalc resolution from new extent
00541       recalcResolution();
00542     }
00543   }
00544   mPreviousCrs = outputCrs();
00545   updateCrsGroup();
00546 }
00547 
00548 void QgsRasterLayerSaveAsDialog::updateCrsGroup()
00549 {
00550   QgsDebugMsg( "Entered" );
00551 
00552   mCrsComboBox->setItemText( mCrsComboBox->findData( OriginalCrs ),
00553                              tr( "Layer (%1, %2)" ).arg( mLayerCrs.description() ).arg( mLayerCrs.authid() ) );
00554 
00555   mCrsComboBox->setItemText( mCrsComboBox->findData( CurrentCrs ),
00556                              tr( "Project (%1, %2)" ).arg( mCurrentCrs.description() ).arg( mCurrentCrs.authid() ) );
00557 
00558   mCrsComboBox->setItemText( mCrsComboBox->findData( UserCrs ),
00559                              tr( "Selected (%1, %2)" ).arg( mUserCrs.description() ).arg( mUserCrs.authid() ) );
00560 }
00561 
00562 QgsCoordinateReferenceSystem QgsRasterLayerSaveAsDialog::outputCrs()
00563 {
00564   int state = mCrsComboBox->itemData( mCrsComboBox->currentIndex() ).toInt();
00565   if ( state == OriginalCrs )
00566   {
00567     return mLayerCrs;
00568   }
00569   else if ( state == CurrentCrs )
00570   {
00571     return mCurrentCrs;
00572   }
00573   return mUserCrs;
00574 }
00575 
00576 QgsRasterLayerSaveAsDialog::Mode QgsRasterLayerSaveAsDialog::mode() const
00577 {
00578   if ( mRenderedModeRadioButton->isChecked() ) return RenderedImageMode;
00579   return RawDataMode;
00580 }
00581 
00582 void QgsRasterLayerSaveAsDialog::on_mRawModeRadioButton_toggled( bool checked )
00583 {
00584   mNoDataGroupBox->setEnabled( checked && mDataProvider->bandCount() == 1 );
00585 }
00586 
00587 void QgsRasterLayerSaveAsDialog::on_mAddNoDataManuallyToolButton_clicked()
00588 {
00589   addNoDataRow( std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN() );
00590 }
00591 
00592 void QgsRasterLayerSaveAsDialog::on_mLoadTransparentNoDataToolButton_clicked()
00593 {
00594   if ( !mRasterLayer->renderer() ) return;
00595   const QgsRasterTransparency* rasterTransparency = mRasterLayer->renderer()->rasterTransparency();
00596   if ( !rasterTransparency ) return;
00597 
00598   foreach ( QgsRasterTransparency::TransparentSingleValuePixel transparencyPixel, rasterTransparency->transparentSingleValuePixelList() )
00599   {
00600     if ( transparencyPixel.percentTransparent == 100 )
00601     {
00602       addNoDataRow( transparencyPixel.min, transparencyPixel.max );
00603       if ( transparencyPixel.min != transparencyPixel.max )
00604       {
00605         setNoDataToEdited( mNoDataTableWidget->rowCount() - 1 );
00606       }
00607     }
00608   }
00609 }
00610 
00611 void QgsRasterLayerSaveAsDialog::on_mRemoveSelectedNoDataToolButton_clicked()
00612 {
00613   mNoDataTableWidget->removeRow( mNoDataTableWidget->currentRow() );
00614 }
00615 
00616 void QgsRasterLayerSaveAsDialog::on_mRemoveAllNoDataToolButton_clicked()
00617 {
00618   while ( mNoDataTableWidget->rowCount() > 0 )
00619   {
00620     mNoDataTableWidget->removeRow( 0 );
00621   }
00622 }
00623 
00624 void QgsRasterLayerSaveAsDialog::addNoDataRow( double min, double max )
00625 {
00626   mNoDataTableWidget->insertRow( mNoDataTableWidget->rowCount() );
00627   for ( int i = 0; i < 2; i++ )
00628   {
00629     double value = i == 0 ? min : max;
00630     QLineEdit *lineEdit = new QLineEdit();
00631     lineEdit->setFrame( false );
00632     lineEdit->setContentsMargins( 1, 1, 1, 1 );
00633     QString valueString;
00634     switch ( mRasterLayer->dataProvider()->srcDataType( 1 ) )
00635     {
00636       case QGis::Float32:
00637       case QGis::Float64:
00638         lineEdit->setValidator( new QDoubleValidator( 0 ) );
00639         if ( !qIsNaN( value ) )
00640         {
00641           valueString = QgsRasterBlock::printValue( value );
00642         }
00643         break;
00644       default:
00645         lineEdit->setValidator( new QIntValidator( 0 ) );
00646         if ( !qIsNaN( value ) )
00647         {
00648           valueString = QString::number( static_cast<int>( value ) );
00649         }
00650         break;
00651     }
00652     lineEdit->setText( valueString );
00653     mNoDataTableWidget->setCellWidget( mNoDataTableWidget->rowCount() - 1, i, lineEdit );
00654 
00655     adjustNoDataCellWidth( mNoDataTableWidget->rowCount() - 1, i );
00656 
00657     connect( lineEdit, SIGNAL( textEdited( const QString & ) ), this, SLOT( noDataCellTextEdited( const QString & ) ) );
00658   }
00659   mNoDataTableWidget->resizeColumnsToContents();
00660   mNoDataTableWidget->resizeRowsToContents();
00661 }
00662 
00663 void QgsRasterLayerSaveAsDialog::noDataCellTextEdited( const QString & text )
00664 {
00665   Q_UNUSED( text );
00666 
00667   QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( sender() );
00668   if ( !lineEdit ) return;
00669   int row = -1;
00670   int column = -1;
00671   for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
00672   {
00673     for ( int c = 0 ; c < mNoDataTableWidget->columnCount(); c++ )
00674     {
00675       if ( mNoDataTableWidget->cellWidget( r, c ) == sender() )
00676       {
00677         row = r;
00678         column = c;
00679         break;
00680       }
00681     }
00682     if ( row != -1 ) break;
00683   }
00684   QgsDebugMsg( QString( "row = %1 column =%2" ).arg( row ).arg( column ) );
00685 
00686   if ( column == 0 )
00687   {
00688     QLineEdit *toLineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, 1 ) );
00689     if ( !toLineEdit ) return;
00690     bool toChanged = mNoDataToEdited.value( row );
00691     QgsDebugMsg( QString( "toChanged = %1" ).arg( toChanged ) );
00692     if ( !toChanged )
00693     {
00694       toLineEdit->setText( lineEdit->text() );
00695     }
00696   }
00697   else if ( column == 1 )
00698   {
00699     setNoDataToEdited( row );
00700   }
00701 }
00702 
00703 void QgsRasterLayerSaveAsDialog::on_mTileModeCheckBox_toggled( bool toggled )
00704 {
00705   if ( toggled )
00706   {
00707     // enable pyramids
00708 
00709     // Disabled (Radim), auto enabling of pyramids was making impression that
00710     // we (programmers) know better what you (user) want to do,
00711     // certainly auto expaning was bad experience
00712 
00713     //if ( ! mPyramidsGroupBox->isChecked() )
00714     //  mPyramidsGroupBox->setChecked( true );
00715 
00716     // Auto expanding mPyramidsGroupBox is bad - it auto crolls content of dialog
00717     //if ( mPyramidsGroupBox->isCollapsed() )
00718     //  mPyramidsGroupBox->setCollapsed( false );
00719     //mPyramidsOptionsWidget->checkAllLevels( true );
00720 
00721     // Show / hide tile options
00722     mTilesGroupBox->show();
00723   }
00724   else
00725   {
00726     mTilesGroupBox->hide();
00727   }
00728 }
00729 
00730 void QgsRasterLayerSaveAsDialog::on_mPyramidsGroupBox_toggled( bool toggled )
00731 {
00732   Q_UNUSED( toggled );
00733   populatePyramidsLevels();
00734 }
00735 
00736 void QgsRasterLayerSaveAsDialog::populatePyramidsLevels()
00737 {
00738   QString text;
00739 
00740   if ( mPyramidsGroupBox->isChecked() )
00741   {
00742     QList<QgsRasterPyramid> myPyramidList;
00743     // if use existing, get pyramids from actual layer
00744     // but that's not available yet
00745     if ( mPyramidsUseExistingCheckBox->isChecked() )
00746     {
00747       myPyramidList = mDataProvider->buildPyramidList();
00748     }
00749     else
00750     {
00751       if ( ! mPyramidsOptionsWidget->overviewList().isEmpty() )
00752         myPyramidList = mDataProvider->buildPyramidList( mPyramidsOptionsWidget->overviewList() );
00753     }
00754     QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
00755     for ( myRasterPyramidIterator = myPyramidList.begin();
00756           myRasterPyramidIterator != myPyramidList.end();
00757           ++myRasterPyramidIterator )
00758     {
00759       if ( ! mPyramidsUseExistingCheckBox->isChecked() ||  myRasterPyramidIterator->exists )
00760       {
00761         text += QString::number( myRasterPyramidIterator->xDim ) + QString( "x" ) +
00762                 QString::number( myRasterPyramidIterator->yDim ) + " ";
00763       }
00764     }
00765   }
00766 
00767   mPyramidResolutionsLineEdit->setText( text.trimmed() );
00768 }
00769 
00770 void QgsRasterLayerSaveAsDialog::setNoDataToEdited( int row )
00771 {
00772   if ( row >= mNoDataToEdited.size() )
00773   {
00774     mNoDataToEdited.resize( row + 1 );
00775   }
00776   mNoDataToEdited[row] = true;
00777 }
00778 
00779 double QgsRasterLayerSaveAsDialog::noDataCellValue( int row, int column ) const
00780 {
00781   QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
00782   if ( !lineEdit || lineEdit->text().isEmpty() )
00783   {
00784     std::numeric_limits<double>::quiet_NaN();
00785   }
00786   return lineEdit->text().toDouble();
00787 }
00788 
00789 void QgsRasterLayerSaveAsDialog::adjustNoDataCellWidth( int row, int column )
00790 {
00791   QLineEdit *lineEdit = dynamic_cast<QLineEdit *>( mNoDataTableWidget->cellWidget( row, column ) );
00792   if ( !lineEdit ) return;
00793 
00794   int width = qMax( lineEdit->fontMetrics().width( lineEdit->text() ) + 10, 100 );
00795   width = qMax( width, mNoDataTableWidget->columnWidth( column ) );
00796 
00797   lineEdit->setFixedWidth( width );
00798 }
00799 
00800 QgsRasterRangeList QgsRasterLayerSaveAsDialog::noData() const
00801 {
00802   QgsRasterRangeList noDataList;
00803   if ( ! mNoDataGroupBox->isChecked() )
00804     return noDataList;
00805 
00806   for ( int r = 0 ; r < mNoDataTableWidget->rowCount(); r++ )
00807   {
00808     QgsRasterRange noData( noDataCellValue( r, 0 ), noDataCellValue( r, 1 ) );
00809     noDataList.append( noData );
00810 
00811   }
00812   return noDataList;
00813 }
00814 
00815 QList<int> QgsRasterLayerSaveAsDialog::pyramidsList() const
00816 {
00817   return mPyramidsGroupBox->isChecked() ? mPyramidsOptionsWidget->overviewList() : QList<int>();
00818 }
00819 
00820 QgsRaster::RasterBuildPyramids QgsRasterLayerSaveAsDialog::buildPyramidsFlag() const
00821 {
00822   if ( ! mPyramidsGroupBox->isChecked() )
00823     return QgsRaster::PyramidsFlagNo;
00824   else if ( mPyramidsUseExistingCheckBox->isChecked() )
00825     return QgsRaster::PyramidsCopyExisting;
00826   else
00827     return QgsRaster::PyramidsFlagYes;
00828 }
00829 
00830 bool QgsRasterLayerSaveAsDialog::validate() const
00831 {
00832   if ( mCreateOptionsGroupBox->isChecked() )
00833   {
00834     QString message = mCreateOptionsWidget->validateOptions( true, false );
00835     if ( !message.isNull() )
00836       return false;
00837   }
00838   if ( mPyramidsGroupBox->isChecked() )
00839   {
00840     QString message = mPyramidsOptionsWidget->createOptionsWidget()->validateOptions( true, false );
00841     if ( !message.isNull() )
00842       return false;
00843   }
00844   return true;
00845 }
00846 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines