|
Quantum GIS API Documentation
master-ce49b66
|
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