Skip to content

Commit

Permalink
add basic driver create options - simple line edit in save dialog and…
Browse files Browse the repository at this point in the history
… in gdal driver options
  • Loading branch information
etiennesky committed Jul 20, 2012
1 parent 73f991f commit 4e49c42
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 69 deletions.
2 changes: 2 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -3894,6 +3894,8 @@ void QgisApp::saveAsRasterFile()
{
nRows = d.nRows();
}
fileWriter.setCreateOptions( d.createOptions() );

fileWriter.writeRaster( &iterator, d.nColumns(), nRows, d.outputRectangle(), rasterLayer->crs(), &pd );
}
}
Expand Down
54 changes: 51 additions & 3 deletions src/app/qgsoptions.cpp
Expand Up @@ -1063,6 +1063,49 @@ void QgsOptions::on_pbnSelectOtfProjection_clicked()
}
}

void QgsOptions::on_lstGdalDrivers_itemPressed( QTreeWidgetItem * item, int column )
{
// edit driver if "options" icon (column 3) is pressed
if ( item && column == 3 )
{
editGdalDriver( item->text( 0 ) );
}
}

void QgsOptions::on_lstGdalDrivers_itemDoubleClicked( QTreeWidgetItem * item, int column )
{
Q_UNUSED( column );
// edit driver if "options" icon (column 3) exists (only if driver supports write)
if ( item && ! item->icon( 3 ).isNull() )
{
editGdalDriver( item->text( 0 ) );
}
}


void QgsOptions::editGdalDriver( const QString& driverName )
{
QSettings mySettings;

// this will go to a standalone widget class
QDialog dlg( this );
QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
connect(buttonBox, SIGNAL(accepted()), &dlg, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), &dlg, SLOT(reject()));
QVBoxLayout *layout = new QVBoxLayout();
QLineEdit *lineEdit = new QLineEdit();
layout->addWidget( lineEdit );
layout->addWidget( buttonBox );
dlg.setLayout( layout );

lineEdit->setText( mySettings.value( "gdal/driverOptions/" + driverName.toLower() + "/create", "" ).toString() );
if ( dlg.exec() == QDialog::Accepted )
{
// perhaps setting should not be applied already, but this is easier
mySettings.setValue( "gdal/driverOptions/" + driverName.toLower() + "/create", lineEdit->text().trimmed().toUpper() );
}
}

// Return state of the visibility flag for newly added layers. If

bool QgsOptions::newVisible()
Expand Down Expand Up @@ -1405,11 +1448,11 @@ void QgsOptions::loadGdalDriverList()
myDrivers = strMap.values();

QStringListIterator myIterator( myDrivers );
QIcon myIcon = QgsApplication::getThemeIcon( "mActionOptions.png" );

while ( myIterator.hasNext() )
{
QString myName = myIterator.next();

// QListWidgetItem * mypItem = new QListWidgetItem( myName );
QTreeWidgetItem * mypItem = new QTreeWidgetItem( QStringList( myName ) );
if ( mySkippedDrivers.contains( myName ) )
Expand All @@ -1423,8 +1466,13 @@ void QgsOptions::loadGdalDriverList()

// add driver metadata
mypItem->setText( 1, myDriversExt[myName] );
mypItem->setText( 2, myDriversFlags[myName] );
mypItem->setText( 3, myDriversLongName[myName] );
QString myFlags = myDriversFlags[myName];
mypItem->setText( 2, myFlags );
if ( myFlags.contains( "w+" ) )
{
mypItem->setIcon( 3, myIcon );
}
mypItem->setText( 4, myDriversLongName[myName] );

lstGdalDrivers->addTopLevelItem( mypItem );
}
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgsoptions.h
Expand Up @@ -59,6 +59,9 @@ class QgsOptions : public QDialog, private Ui::QgsOptionsBase
void on_pbnSelectProjection_clicked();
//! Slot called when user chooses to change the default 'on the fly' projection.
void on_pbnSelectOtfProjection_clicked();
void on_lstGdalDrivers_itemPressed( QTreeWidgetItem * item, int column );
void on_lstGdalDrivers_itemDoubleClicked( QTreeWidgetItem * item, int column );
void editGdalDriver( const QString& driverName );
void saveOptions();
//! Slot to change the theme this is handled when the user
// activates or highlights a theme name in the drop-down list
Expand Down
9 changes: 6 additions & 3 deletions src/core/qgsrasterdataprovider.h
Expand Up @@ -110,7 +110,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
QgsRasterInterface * srcInput() { return this; }

/* It makes no sense to set input on provider */
bool setInput( QgsRasterInterface* input ) { return false; }
bool setInput( QgsRasterInterface* input ) { Q_UNUSED( input ); return false; }

/**
* Add the list of WMS layer names to be rendered by this server
Expand Down Expand Up @@ -463,8 +463,10 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/** Creates a new dataset with mDataSourceURI
@return true in case of success*/
virtual bool create( const QString& format, int nBands,
QgsRasterDataProvider::DataType type, int width, int height, double* geoTransform,
const QgsCoordinateReferenceSystem& crs /*e.v. color table*/ )
QgsRasterDataProvider::DataType type,
int width, int height, double* geoTransform,
const QgsCoordinateReferenceSystem& crs,
QStringList createOptions = QStringList() /*e.v. color table*/ )
{
Q_UNUSED( format );
Q_UNUSED( nBands );
Expand All @@ -473,6 +475,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
Q_UNUSED( height );
Q_UNUSED( geoTransform );
Q_UNUSED( crs );
Q_UNUSED( createOptions );
return false;
}

Expand Down
16 changes: 9 additions & 7 deletions src/core/raster/qgsrasterfilewriter.cpp
Expand Up @@ -126,7 +126,7 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeDataRaster( QgsRaster
QFileInfo outputInfo( mOutputUrl );
QString vrtFilePath( mOutputUrl + "/" + outputInfo.baseName() + ".vrt" );
writeVRT( vrtFilePath );
buildPyramides( vrtFilePath );
buildPyramids( vrtFilePath );
}

return NoError; //reached last tile, bail out
Expand Down Expand Up @@ -262,7 +262,7 @@ QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRaste
QFileInfo outputInfo( mOutputUrl );
QString vrtFilePath( mOutputUrl + "/" + outputInfo.baseName() + ".vrt" );
writeVRT( vrtFilePath );
buildPyramides( vrtFilePath );
buildPyramids( vrtFilePath );
}
return NoError;
}
Expand Down Expand Up @@ -332,7 +332,7 @@ void QgsRasterFileWriter::addToVRT( const QString& filename, int band, int xSize
bandElem.appendChild( simpleSourceElem );
}

void QgsRasterFileWriter::buildPyramides( const QString& filename )
void QgsRasterFileWriter::buildPyramids( const QString& filename )
{
GDALDatasetH dataSet;
GDALAllRegister();
Expand All @@ -353,15 +353,15 @@ void QgsRasterFileWriter::buildPyramides( const QString& filename )

/*if ( mProgressDialog )
{
mProgressDialog->setLabelText( QObject::tr( "Building Pyramides..." ) );
mProgressDialog->setLabelText( QObject::tr( "Building Pyramids..." ) );
mProgressDialog->setValue( 0 );
mProgressDialog->setWindowModality( Qt::WindowModal );
mProgressDialog->show();
}*/
GDALBuildOverviews( dataSet, "AVERAGE", 6, overviewList, 0, 0, /*pyramidesProgress*/ 0, /*mProgressDialog*/ 0 );
GDALBuildOverviews( dataSet, "AVERAGE", 6, overviewList, 0, 0, /*pyramidsProgress*/ 0, /*mProgressDialog*/ 0 );
}

int QgsRasterFileWriter::pyramidesProgress( double dfComplete, const char *pszMessage, void* pData )
int QgsRasterFileWriter::pyramidsProgress( double dfComplete, const char *pszMessage, void* pData )
{
Q_UNUSED( pszMessage );
GDALTermProgress( dfComplete, 0, 0 );
Expand Down Expand Up @@ -484,6 +484,8 @@ QgsRasterDataProvider* QgsRasterFileWriter::createPartProvider( const QgsRectang
geoTransform[3] = mapRect.yMaximum();
geoTransform[4] = 0.0;
geoTransform[5] = -mup;

// perhaps we need a separate createOptions for tiles ?
if ( !destProvider->create( mOutputFormat, nBands, type, iterCols, iterRows, geoTransform,
crs ) )
{
Expand All @@ -510,7 +512,7 @@ QgsRasterDataProvider* QgsRasterFileWriter::initOutput( int nCols, int nRows, co
}

if ( !destProvider->create( mOutputFormat, nBands, type, nCols, nRows, geoTransform,
crs ) )
crs, mCreateOptions ) )
{
delete destProvider;
return 0;
Expand Down
13 changes: 9 additions & 4 deletions src/core/raster/qgsrasterfilewriter.h
Expand Up @@ -45,7 +45,11 @@ class CORE_EXPORT QgsRasterFileWriter
int maxTileWidth() const { return mMaxTileWidth; }

void setMaxTileHeight( int h ) { mMaxTileHeight = h; }
int maxTileHeight() const { return mMaxTileHeight; }
int maxTileHeight() const { return mMaxTileHeight; }

// for now not putting createOptions in all methods, use createOptions()
void setCreateOptions( const QStringList& list ) { mCreateOptions = list; }
QStringList createOptions() const { return mCreateOptions; }

private:
QgsRasterFileWriter(); //forbidden
Expand All @@ -60,15 +64,15 @@ class CORE_EXPORT QgsRasterFileWriter
bool writeVRT( const QString& file );
//add file entry to vrt
void addToVRT( const QString& filename, int band, int xSize, int ySize, int xOffset, int yOffset );
void buildPyramides( const QString& filename );
void buildPyramids( const QString& filename );

static int pyramidesProgress( double dfComplete, const char *pszMessage, void* pData );
static int pyramidsProgress( double dfComplete, const char *pszMessage, void* pData );

/**Create provider and datasource for a part image (vrt mode)*/
QgsRasterDataProvider* createPartProvider( const QgsRectangle& extent, int nCols, int iterCols, int iterRows,
int iterLeft, int iterTop,
const QString& outputUrl, int fileIndex, int nBands, QgsRasterInterface::DataType type,
const QgsCoordinateReferenceSystem& crs );
const QgsCoordinateReferenceSystem& crs );

/**Init VRT (for tiled mode) or create global output provider (single-file mode)*/
QgsRasterDataProvider* initOutput( int nCols, int nRows, const QgsCoordinateReferenceSystem& crs, double* geoTransform, int nBands,
Expand All @@ -80,6 +84,7 @@ class CORE_EXPORT QgsRasterFileWriter
QString mOutputUrl;
QString mOutputProviderKey;
QString mOutputFormat;
QStringList mCreateOptions;
QgsCoordinateReferenceSystem mOutputCRS;

/**False: Write one file, true: create a directory and add the files numbered*/
Expand Down
26 changes: 24 additions & 2 deletions src/gui/qgsrasterlayersaveasdialog.cpp
@@ -1,6 +1,7 @@
#include "qgsrasterlayersaveasdialog.h"
#include "qgsrasterdataprovider.h"
#include <QFileDialog>
#include <QSettings>

QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterDataProvider* sourceProvider, const QgsRectangle& currentExtent,
QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f ),
Expand All @@ -10,7 +11,13 @@ QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterDataProvider* s
setupUi( this );
setValidators();

mFormatComboBox->addItem( "GeoTIFF" ); //only one hardcoded format at the moment
//only one hardcoded format at the moment
QStringList myFormats;
myFormats << "GTiff";
foreach ( QString myFormat, myFormats )
{
mFormatComboBox->addItem( myFormat );
}

//fill reasonable default values depending on the provider
if ( mDataProvider )
Expand Down Expand Up @@ -102,6 +109,16 @@ void QgsRasterLayerSaveAsDialog::on_mProviderExtentButton_clicked()
}
}

void QgsRasterLayerSaveAsDialog::on_mFormatComboBox_currentIndexChanged( const QString & text )
{
//gdal-specific
if ( mDataProvider && mDataProvider->name() == "gdal" )
{
QSettings mySettings;
mCreateOptionsLineEdit->setText( mySettings.value( "gdal/driverOptions/" + text.toLower() + "/create", "" ).toString() );
}
}

int QgsRasterLayerSaveAsDialog::nColumns() const
{
return mColumnsLineEdit->text().toInt();
Expand Down Expand Up @@ -134,7 +151,12 @@ QString QgsRasterLayerSaveAsDialog::outputFileName() const

QString QgsRasterLayerSaveAsDialog::outputFormat() const
{
return ""; //soon...
return mFormatComboBox->currentText();
}

QStringList QgsRasterLayerSaveAsDialog::createOptions() const
{
return mCreateOptionsLineEdit->text().trimmed().toUpper().split( " " );
}

QgsRectangle QgsRasterLayerSaveAsDialog::outputRectangle() const
Expand Down
2 changes: 2 additions & 0 deletions src/gui/qgsrasterlayersaveasdialog.h
Expand Up @@ -20,6 +20,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
bool tileMode() const;
QString outputFileName() const;
QString outputFormat() const;
QStringList createOptions() const;
QgsRectangle outputRectangle() const;

void hideFormat();
Expand All @@ -30,6 +31,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
void on_mSaveAsLineEdit_textChanged( const QString& text );
void on_mCurrentExtentButton_clicked();
void on_mProviderExtentButton_clicked();
void on_mFormatComboBox_currentIndexChanged( const QString& text );

private:
QgsRasterDataProvider* mDataProvider;
Expand Down
24 changes: 20 additions & 4 deletions src/providers/gdal/qgsgdalprovider.cpp
Expand Up @@ -49,6 +49,7 @@
#include "gdalwarper.h"
#include "ogr_spatialref.h"
#include "cpl_conv.h"
#include "cpl_string.h"


static QString PROVIDER_KEY = "gdal";
Expand Down Expand Up @@ -2163,8 +2164,21 @@ void QgsGdalProvider::initBaseDataset()
mValid = true;
}

bool QgsGdalProvider::create( const QString& format, int nBands, QgsRasterDataProvider::DataType type, int width, int height,
double* geoTransform, const QgsCoordinateReferenceSystem& crs )
char** papszFromStringList( const QStringList& list )
{
char **papszRetList = NULL;
foreach( QString elem, list )
{
papszRetList = CSLAddString( papszRetList, elem.toLocal8Bit().constData() );
}
return papszRetList;
}

bool QgsGdalProvider::create( const QString& format, int nBands,
QgsRasterDataProvider::DataType type,
int width, int height, double* geoTransform,
const QgsCoordinateReferenceSystem& crs,
QStringList createOptions )
{
//get driver
GDALDriverH driver = GDALGetDriverByName( format.toLocal8Bit().data() );
Expand All @@ -2173,8 +2187,10 @@ bool QgsGdalProvider::create( const QString& format, int nBands, QgsRasterDataPr
return false;
}

//create dataset
GDALDatasetH dataset = GDALCreate( driver, dataSourceUri().toLocal8Bit().data(), width, height, nBands, ( GDALDataType )type, 0 );
//create dataset
char **papszOptions = papszFromStringList( createOptions );
GDALDatasetH dataset = GDALCreate( driver, dataSourceUri().toLocal8Bit().data(), width, height, nBands, ( GDALDataType )type, papszOptions );
CSLDestroy( papszOptions );
if ( dataset == NULL )
{
return false;
Expand Down
7 changes: 5 additions & 2 deletions src/providers/gdal/qgsgdalprovider.h
Expand Up @@ -269,8 +269,11 @@ class QgsGdalProvider : public QgsRasterDataProvider

/** Creates a new dataset with mDataSourceURI
@return true in case of success*/
bool create( const QString& format, int nBands, QgsRasterDataProvider::DataType type, int width, int height,
double* geoTransform, const QgsCoordinateReferenceSystem& crs );
bool create( const QString& format, int nBands,
QgsRasterDataProvider::DataType type,
int width, int height, double* geoTransform,
const QgsCoordinateReferenceSystem& crs,
QStringList createOptions = QStringList() );

/**Writes into the provider datasource*/
bool write( void* data, int band, int width, int height, int xOffset, int yOffset );
Expand Down

0 comments on commit 4e49c42

Please sign in to comment.