Skip to content
Permalink
Browse files

raster save creation options validation:

- move help and validation to gdal provider
- validate options before saving
- test for valid PREDICTOR option, depending raster properties
  • Loading branch information
etiennesky committed Sep 20, 2012
1 parent bb7dc52 commit c5cc63452044e945d384f33233aeb3ecd6810ab5
@@ -29,7 +29,7 @@ class QgsRasterFormatSaveOptionsWidget : QWidget

void apply();
void helpOptions();
bool validateOptions( bool gui = true );
QString validateOptions( bool gui = true, bool reportOk = true );

private slots:

@@ -597,6 +597,11 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
tr( "Cubic" ) << tr( "Mode" ) << tr( "None" ) : QStringList();
}

/** Validates creation options for a specific dataset and destination format - used by GDAL provider only.
* See also validateCreationOptionsFormat() in gdal provider for validating options based on format only. */
virtual QString validateCreationOptions( const QStringList& createOptions, QString format )
{ Q_UNUSED( createOptions ); Q_UNUSED( format ); return QString(); }

signals:
/** Emit a signal to notify of the progress event.
* Emited theProgress is in percents (0.0-100.0) */
@@ -18,11 +18,8 @@
#include "qgsrasterformatsaveoptionswidget.h"
#include "qgslogger.h"
#include "qgsdialog.h"

#include "gdal.h"
#include "cpl_string.h"
#include "cpl_conv.h"
#include "cpl_minixml.h"
#include "qgsrasterlayer.h"
#include "qgsproviderregistry.h"

#include <QSettings>
#include <QInputDialog>
@@ -31,28 +28,16 @@
#include <QMouseEvent>
#include <QMenu>

// todo put this somewhere else - how can we access gdal provider?
char** papszFromStringList( const QStringList& list )
{
char **papszRetList = NULL;
foreach ( QString elem, list )
{
papszRetList = CSLAddString( papszRetList, elem.toLocal8Bit().constData() );
}
return papszRetList;
}

QMap< QString, QStringList > QgsRasterFormatSaveOptionsWidget::mBuiltinProfiles;

QgsRasterFormatSaveOptionsWidget::QgsRasterFormatSaveOptionsWidget( QWidget* parent, QString format,
QgsRasterFormatSaveOptionsWidget::Type type,
QString provider )
: QWidget( parent ), mFormat( format ), mProvider( provider )
QgsRasterFormatSaveOptionsWidget::Type type, QString provider )
: QWidget( parent ), mFormat( format ), mProvider( provider ), mRasterLayer( 0 )

{
setupUi( this );


setType( type );

if ( mBuiltinProfiles.isEmpty() )
@@ -104,6 +89,7 @@ QgsRasterFormatSaveOptionsWidget::QgsRasterFormatSaveOptionsWidget( QWidget* par
mOptionsLineEdit->installEventFilter( this );
mOptionsStackedWidget->installEventFilter( this );

updateControls();
updateProfiles();
}

@@ -114,12 +100,14 @@ QgsRasterFormatSaveOptionsWidget::~QgsRasterFormatSaveOptionsWidget()
void QgsRasterFormatSaveOptionsWidget::setFormat( QString format )
{
mFormat = format;
updateControls();
updateProfiles();
}

void QgsRasterFormatSaveOptionsWidget::setProvider( QString provider )
{
mProvider = provider;
updateControls();
}

// show/hide widgets - we need this function if widget is used in creator
@@ -236,27 +224,35 @@ void QgsRasterFormatSaveOptionsWidget::apply()
setCreateOptions();
}

// typedefs for gdal provider function pointers
typedef QString validateCreationOptionsFormat_t( const QStringList& createOptions, QString format );
typedef QString helpCreationOptionsFormat_t( QString format );

void QgsRasterFormatSaveOptionsWidget::helpOptions()
{
QString message;

if ( mProvider == "gdal" && mFormat != "" && mFormat != "_pyramids" )
{
GDALDriverH myGdalDriver = GDALGetDriverByName( mFormat.toLocal8Bit().constData() );
if ( myGdalDriver )
// get helpCreationOptionsFormat() function ptr for provider
QLibrary *library = QgsProviderRegistry::instance()->providerLibrary( mProvider );
if ( library )
{
// need to serialize xml to get newlines
CPLXMLNode *psCOL = CPLParseXMLString( GDALGetMetadataItem( myGdalDriver,
GDAL_DMD_CREATIONOPTIONLIST, "" ) );
char *pszFormattedXML = CPLSerializeXMLTree( psCOL );
if ( pszFormattedXML )
message = tr( "Create Options:\n\n%1" ).arg( pszFormattedXML );
if ( psCOL )
CPLDestroyXMLNode( psCOL );
if ( pszFormattedXML )
CPLFree( pszFormattedXML );
helpCreationOptionsFormat_t * helpCreationOptionsFormat =
( helpCreationOptionsFormat_t * ) cast_to_fptr( library->resolve( "helpCreationOptionsFormat" ) );
if ( helpCreationOptionsFormat )
{
message = helpCreationOptionsFormat( mFormat );
}
else
{
message = library->fileName() + " does not have helpCreationOptionsFormat";
}
}
else
message = QString( "cannot load provider library %1" ).arg( mProvider );


if ( message.isEmpty() )
message = tr( "Cannot get create options for driver %1" ).arg( mFormat );
}
@@ -267,36 +263,65 @@ void QgsRasterFormatSaveOptionsWidget::helpOptions()
QgsDialog *dlg = new QgsDialog( this );
QTextEdit *textEdit = new QTextEdit( dlg );
textEdit->setReadOnly( true );
message = tr( "Create Options:\n\n%1" ).arg( message );
textEdit->setText( message );
dlg->layout()->addWidget( textEdit );
dlg->resize( 600, 600 );
dlg->resize( 600, 400 );
dlg->show(); //non modal
}

bool QgsRasterFormatSaveOptionsWidget::validateOptions( bool gui )
QString QgsRasterFormatSaveOptionsWidget::validateOptions( bool gui, bool reportOK )
{
QStringList createOptions = options();
bool ok = false;
QString message;

if ( !createOptions.isEmpty() && mProvider == "gdal" && mFormat != "" && mFormat != "_pyramids" )
{
GDALDriverH myGdalDriver = GDALGetDriverByName( mFormat.toLocal8Bit().constData() );
if ( myGdalDriver )
if ( mRasterLayer )
{
QgsDebugMsg( "calling validate on layer's data provider" );
message = mRasterLayer->dataProvider()->validateCreationOptions( createOptions, mFormat );
}
else
{
// print error string?
char** papszOptions = papszFromStringList( createOptions );
ok = GDALValidateCreationOptions( myGdalDriver, papszOptions );
CSLDestroy( papszOptions );
if ( gui )
// get validateCreationOptionsFormat() function ptr for provider
QLibrary *library = QgsProviderRegistry::instance()->providerLibrary( mProvider );
if ( library )
{
if ( ok )
QMessageBox::information( this, "", tr( "Valid" ), QMessageBox::Close );
validateCreationOptionsFormat_t * validateCreationOptionsFormat =
( validateCreationOptionsFormat_t * ) cast_to_fptr( library->resolve( "validateCreationOptionsFormat" ) );
if ( validateCreationOptionsFormat )
{
message = validateCreationOptionsFormat( createOptions, mFormat );
}
else
QMessageBox::warning( this, "", tr( "Invalid" ), QMessageBox::Close );
{
message = library->fileName() + " does not have validateCreationOptionsFormat";
}
}
else
message = QString( "cannot load provider library %1" ).arg( mProvider );
}

if ( gui )
{
if ( message.isNull() )
{
if ( reportOK )
QMessageBox::information( this, "", tr( "Valid" ), QMessageBox::Close );
}
else
{
QMessageBox::warning( this, "", tr( "Invalid creation option :\n\n%1\n\nClick on help button to get valid creation options for this format" ).arg( message ), QMessageBox::Close );
}
}
}
return ok;
else
{
QMessageBox::information( this, "", tr( "Cannot validate" ), QMessageBox::Close );
}

return message;
}

void QgsRasterFormatSaveOptionsWidget::optionsTableChanged()
@@ -481,6 +506,13 @@ void QgsRasterFormatSaveOptionsWidget::swapOptionsUI( int newIndex )
updateOptions();
}

void QgsRasterFormatSaveOptionsWidget::updateControls()
{
bool enabled = ( mProvider == "gdal" && mFormat != "" && mFormat != "_pyramids" );
mOptionsValidateButton->setEnabled( enabled );
mOptionsHelpButton->setEnabled( enabled );
}

// map options label left mouse click to optionsToggle()
bool QgsRasterFormatSaveOptionsWidget::eventFilter( QObject *obj, QEvent *event )
{
@@ -20,6 +20,8 @@

#include "ui_qgsrasterformatsaveoptionswidgetbase.h"

class QgsRasterLayer;

/** \ingroup gui
* A widget to select format-specific raster saving options
*/
@@ -46,14 +48,15 @@ class GUI_EXPORT QgsRasterFormatSaveOptionsWidget: public QWidget,

void setFormat( QString format );
void setProvider( QString provider );
void setRasterLayer( QgsRasterLayer* rasterLayer ) { mRasterLayer = rasterLayer; }
QStringList options() const;
void setType( QgsRasterFormatSaveOptionsWidget::Type type = Default );

public slots:

void apply();
void helpOptions();
bool validateOptions( bool gui = true );
QString validateOptions( bool gui = true, bool reportOk = true );
void updateProfiles();

private slots:
@@ -68,11 +71,13 @@ class GUI_EXPORT QgsRasterFormatSaveOptionsWidget: public QWidget,
void optionsTableEnableDeleteButton();
void updateOptions();
void swapOptionsUI( int newIndex = -1 );
void updateControls();

private:

QString mFormat;
QString mProvider;
QgsRasterLayer* mRasterLayer;
QMap< QString, QString> mOptionsMap;
static QMap< QString, QStringList > mBuiltinProfiles;

@@ -76,6 +76,7 @@ QgsRasterLayerSaveAsDialog::QgsRasterLayerSaveAsDialog( QgsRasterLayer* rasterLa
{
mCreateOptionsWidget->setFormat( myFormats[0] );
}
mCreateOptionsWidget->setRasterLayer( mRasterLayer );
mCreateOptionsWidget->update();
}

@@ -753,3 +754,14 @@ QgsRasterDataProvider::RasterBuildPyramids QgsRasterLayerSaveAsDialog::buildPyra
return QgsRasterDataProvider::PyramidsFlagYes;
}

bool QgsRasterLayerSaveAsDialog::validate() const
{
if ( mCreateOptionsGroupBox->isChecked() )
{
QString message = mCreateOptionsWidget->validateOptions( true, false );
if ( !message.isNull() )
return false;
}
return true;
}

@@ -67,6 +67,9 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
void hideFormat();
void hideOutput();

public slots:
virtual void accept() { if ( validate() ) return QDialog::accept(); }

private slots:
void on_mRawModeRadioButton_toggled( bool );
void on_mBrowseButton_clicked();
@@ -132,6 +135,7 @@ class GUI_EXPORT QgsRasterLayerSaveAsDialog: public QDialog, private Ui::QgsRast
void setNoDataToEdited( int row );
double noDataCellValue( int row, int column ) const;
void adjustNoDataCellWidth( int row, int column );
bool validate() const;
};


0 comments on commit c5cc634

Please sign in to comment.
You can’t perform that action at this time.