Skip to content

Commit

Permalink
Raster: do not list RasterLite2 as a supported output format, and use…
Browse files Browse the repository at this point in the history
… a helper for every call site (fixes #19483)
  • Loading branch information
rouault committed Sep 22, 2018
1 parent 9dd1406 commit d2a7668
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 21 deletions.
7 changes: 3 additions & 4 deletions src/analysis/raster/qgsninecellfilter.cpp
Expand Up @@ -15,6 +15,7 @@
* *
***************************************************************************/

#include "qgsgdalutils.h"
#include "qgsninecellfilter.h"
#include "qgslogger.h"
#include "cpl_string.h"
Expand Down Expand Up @@ -100,8 +101,6 @@ gdal::dataset_unique_ptr QgsNineCellFilter::openInputFile( int &nCellsX, int &nC

GDALDriverH QgsNineCellFilter::openOutputDriver()
{
char **driverMetadata = nullptr;

//open driver
GDALDriverH outputDriver = GDALGetDriverByName( mOutputFormat.toLocal8Bit().data() );

Expand All @@ -110,15 +109,15 @@ GDALDriverH QgsNineCellFilter::openOutputDriver()
return outputDriver; //return nullptr, driver does not exist
}

driverMetadata = GDALGetMetadata( outputDriver, nullptr );
if ( !CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, false ) )
if ( !QgsGdalUtils::supportsRasterCreate( outputDriver ) )
{
return nullptr; //driver exist, but it does not support the create operation
}

return outputDriver;
}


gdal::dataset_unique_ptr QgsNineCellFilter::openOutputFile( GDALDatasetH inputDataset, GDALDriverH outputDriver )
{
if ( !inputDataset )
Expand Down
6 changes: 2 additions & 4 deletions src/analysis/raster/qgsrastercalculator.cpp
Expand Up @@ -15,6 +15,7 @@
* *
***************************************************************************/

#include "qgsgdalutils.h"
#include "qgsrastercalculator.h"
#include "qgsrastercalcnode.h"
#include "qgsrasterdataprovider.h"
Expand Down Expand Up @@ -185,8 +186,6 @@ int QgsRasterCalculator::processCalculation( QgsFeedback *feedback )

GDALDriverH QgsRasterCalculator::openOutputDriver()
{
char **driverMetadata = nullptr;

//open driver
GDALDriverH outputDriver = GDALGetDriverByName( mOutputFormat.toLocal8Bit().data() );

Expand All @@ -195,8 +194,7 @@ GDALDriverH QgsRasterCalculator::openOutputDriver()
return outputDriver; //return nullptr, driver does not exist
}

driverMetadata = GDALGetMetadata( outputDriver, nullptr );
if ( !CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, false ) )
if ( !QgsGdalUtils::supportsRasterCreate( outputDriver ) )
{
return nullptr; //driver exist, but it does not support the create operation
}
Expand Down
6 changes: 2 additions & 4 deletions src/analysis/raster/qgsrelief.cpp
Expand Up @@ -15,6 +15,7 @@
* *
***************************************************************************/

#include "qgsgdalutils.h"
#include "qgslogger.h"
#include "qgsrelief.h"
#include "qgsaspectfilter.h"
Expand Down Expand Up @@ -402,8 +403,6 @@ gdal::dataset_unique_ptr QgsRelief::openInputFile( int &nCellsX, int &nCellsY )

GDALDriverH QgsRelief::openOutputDriver()
{
char **driverMetadata = nullptr;

//open driver
GDALDriverH outputDriver = GDALGetDriverByName( mOutputFormat.toLocal8Bit().data() );

Expand All @@ -412,8 +411,7 @@ GDALDriverH QgsRelief::openOutputDriver()
return outputDriver; //return nullptr, driver does not exist
}

driverMetadata = GDALGetMetadata( outputDriver, nullptr );
if ( !CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, false ) )
if ( !QgsGdalUtils::supportsRasterCreate( outputDriver ) )
{
return nullptr; //driver exist, but it does not support the create operation
}
Expand Down
3 changes: 2 additions & 1 deletion src/app/qgsoptions.cpp
Expand Up @@ -21,6 +21,7 @@
#include "qgis.h"
#include "qgisapp.h"
#include "qgisappstylesheet.h"
#include "qgsgdalutils.h"
#include "qgshighlight.h"
#include "qgsmapcanvas.h"
#include "qgsprojectionselectiondialog.h"
Expand Down Expand Up @@ -2161,7 +2162,7 @@ void QgsOptions::loadGdalDriverList()

// get driver R/W flags, taken from GDALGeneralCmdLineProcessor()
const char *pszRWFlag, *pszVirtualIO;
if ( GDALGetMetadataItem( myGdalDriver, GDAL_DCAP_CREATE, nullptr ) )
if ( QgsGdalUtils::supportsRasterCreate( myGdalDriver ) )
{
myGdalWriteDrivers << myGdalDriverDescription;
pszRWFlag = "rw+";
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsrastercalcdialog.cpp
Expand Up @@ -15,6 +15,7 @@
* *
***************************************************************************/

#include "qgsgdalutils.h"
#include "qgsrastercalcdialog.h"
#include "qgsproject.h"
#include "qgsrastercalcnode.h"
Expand Down Expand Up @@ -202,8 +203,7 @@ void QgsRasterCalcDialog::insertAvailableOutputFormats()
GDALDriverH driver = GDALGetDriver( i );
if ( driver )
{
char **driverMetadata = GDALGetMetadata( driver, nullptr );
if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, false ) )
if ( QgsGdalUtils::supportsRasterCreate( driver ) )
{
QString driverShortName = GDALGetDriverShortName( driver );
QString driverLongName = GDALGetDriverLongName( driver );
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -202,6 +202,7 @@ SET(QGIS_CORE_SRCS
qgsfiledownloader.cpp
qgsfileutils.cpp
qgsfontutils.cpp
qgsgdalutils.cpp
qgsgeometrysimplifier.cpp
qgsgeometryvalidator.cpp
qgsgeometryoptions.cpp
Expand Down
35 changes: 35 additions & 0 deletions src/core/qgsgdalutils.cpp
@@ -0,0 +1,35 @@
/***************************************************************************
qgsgdalutils.cpp
----------------
begin : September 2018
copyright : (C) 2018 Even Rouault
email : even.rouault at spatialys.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsgdalutils.h"

#define CPL_SUPRESS_CPLUSPLUS //#spellok
#include "gdal.h"
#include "cpl_string.h"

#include <QString>

bool QgsGdalUtils::supportsRasterCreate( GDALDriverH driver )
{
QString driverShortName = GDALGetDriverShortName( driver );
if ( driverShortName == QLatin1String( "SQLite" ) )
{
// it supports Create() but only for vector side
return false;
}
char **driverMetadata = GDALGetMetadata( driver, nullptr );
return CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, false ) &&
CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER, false );
}
44 changes: 44 additions & 0 deletions src/core/qgsgdalutils.h
@@ -0,0 +1,44 @@
/***************************************************************************
qgsgdalutils.h
--------------
begin : September 2018
copyright : (C) 2018 Even Rouault
email : even.rouault at spatialys.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSGDALUTILS_H
#define QGSGDALUTILS_H

#define SIP_NO_FILE

#include "qgis_core.h"
#include <gdal.h>

/**
* \ingroup core
* \class QgsGdalUtils
* \brief Utilities for working with GDAL
*
* \note not available in Python bindings
* \since QGIS 3.4
*/
class CORE_EXPORT QgsGdalUtils
{
public:

/**
* Reads whether a driver supports GDALCreate() for raster purposes.
* \param driver GDAL driver
* \returns true if a driver supports GDALCreate() for raster purposes.
*/
static bool supportsRasterCreate( GDALDriverH driver );
};

#endif // QGSGDALUTILS_H
6 changes: 3 additions & 3 deletions src/core/raster/qgsrasterfilewriter.cpp
Expand Up @@ -14,6 +14,7 @@
***************************************************************************/
#include <typeinfo>

#include "qgsgdalutils.h"
#include "qgsrasterfilewriter.h"
#include "qgscoordinatetransform.h"
#include "qgsproviderregistry.h"
Expand Down Expand Up @@ -1067,10 +1068,9 @@ QList< QgsRasterFileWriter::FilterFormatDetails > QgsRasterFileWriter::supported
GDALDriverH drv = GDALGetDriver( i );
if ( drv )
{
QString drvName = GDALGetDriverShortName( drv );
char **driverMetadata = GDALGetMetadata( drv, nullptr );
if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, false ) && CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER, false ) )
if ( QgsGdalUtils::supportsRasterCreate( drv ) )
{
QString drvName = GDALGetDriverShortName( drv );
QString filterString = filterForDriver( drvName );
if ( filterString.isEmpty() )
continue;
Expand Down
5 changes: 2 additions & 3 deletions src/gui/qgsrasterlayersaveasdialog.cpp
Expand Up @@ -13,6 +13,7 @@
* *
***************************************************************************/
#include "qgsapplication.h"
#include "qgsgdalutils.h"
#include "qgslogger.h"
#include "qgscoordinatetransform.h"
#include "qgsrasterlayer.h"
Expand Down Expand Up @@ -241,9 +242,7 @@ void QgsRasterLayerSaveAsDialog::insertAvailableOutputFormats()
GDALDriverH driver = GDALGetDriver( i );
if ( driver )
{
char **driverMetadata = GDALGetMetadata( driver, nullptr );

if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, false ) && CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER, false ) )
if ( QgsGdalUtils::supportsRasterCreate( driver ) )
{
QString driverShortName = GDALGetDriverShortName( driver );
QString driverLongName = GDALGetDriverLongName( driver );
Expand Down
1 change: 1 addition & 0 deletions tests/src/core/CMakeLists.txt
Expand Up @@ -99,6 +99,7 @@ SET(TESTS
testqgsfields.cpp
testqgsfield.cpp
testqgsfilledmarker.cpp
testqgsgdalutils.cpp
testqgsvectorfilewriter.cpp
testqgsfontmarker.cpp
testqgsgeometryimport.cpp
Expand Down
78 changes: 78 additions & 0 deletions tests/src/core/testqgsgdalutils.cpp
@@ -0,0 +1,78 @@
/***************************************************************************
testqgsgdalutils.cpp
--------------------
begin : September 2018
copyright : (C) 2018 Even Rouault
email : even.rouault at spatialys.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgstest.h"
#include <QObject>
#include <QString>
#include <QStringList>
#include <QSettings>

#include <gdal.h>

#include "qgsgdalutils.h"
#include "qgsapplication.h"

class TestQgsGdalUtils: public QObject
{
Q_OBJECT

private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init();// will be called before each testfunction is executed.
void cleanup();// will be called after every testfunction.
void supportsRasterCreate();

private:
};

void TestQgsGdalUtils::initTestCase()
{
QgsApplication::init();
QgsApplication::initQgis();
GDALAllRegister();
}

void TestQgsGdalUtils::cleanupTestCase()
{
QgsApplication::exitQgis();
}

void TestQgsGdalUtils::init()
{

}

void TestQgsGdalUtils::cleanup()
{

}

void TestQgsGdalUtils::supportsRasterCreate()
{
QVERIFY( QgsGdalUtils::supportsRasterCreate( GDALGetDriverByName( "GTiff" ) ) );
QVERIFY( QgsGdalUtils::supportsRasterCreate( GDALGetDriverByName( "GPKG" ) ) );

// special case
QVERIFY( !QgsGdalUtils::supportsRasterCreate( GDALGetDriverByName( "SQLite" ) ) );

// create-only
QVERIFY( !QgsGdalUtils::supportsRasterCreate( GDALGetDriverByName( "DTED" ) ) );

// vector-only
QVERIFY( !QgsGdalUtils::supportsRasterCreate( GDALGetDriverByName( "ESRI Shapefile" ) ) );
}

QGSTEST_MAIN( TestQgsGdalUtils )
#include "testqgsgdalutils.moc"

0 comments on commit d2a7668

Please sign in to comment.