mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
Merge pull request #5839 from alexbruy/raster-extensions
Add methods to get supported raster formats and extensions to QgsRasterFileWriter
This commit is contained in:
commit
6b73f78198
@ -35,6 +35,13 @@ class QgsRasterFileWriter
|
||||
WriteCanceled,
|
||||
};
|
||||
|
||||
enum RasterFormatOption
|
||||
{
|
||||
SortRecommended,
|
||||
};
|
||||
typedef QFlags<QgsRasterFileWriter::RasterFormatOption> RasterFormatOptions;
|
||||
|
||||
|
||||
QgsRasterFileWriter( const QString &outputUrl );
|
||||
|
||||
QgsRasterDataProvider *createOneBandRaster( Qgis::DataType dataType,
|
||||
@ -156,6 +163,49 @@ class QgsRasterFileWriter
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
static QString filterForDriver( const QString &driverName );
|
||||
%Docstring
|
||||
Creates a filter for an GDAL driver key
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
struct FilterFormatDetails
|
||||
{
|
||||
QString driverName;
|
||||
%Docstring
|
||||
Unique driver name
|
||||
%End
|
||||
|
||||
QString filterString;
|
||||
%Docstring
|
||||
Filter string for file picker dialogs
|
||||
%End
|
||||
};
|
||||
|
||||
static QList< QgsRasterFileWriter::FilterFormatDetails > supportedFiltersAndFormats( RasterFormatOptions options = SortRecommended );
|
||||
%Docstring
|
||||
Returns a list or pairs, with format filter string as first element and GDAL format key as second element.
|
||||
Relies on GDAL_DMD_EXTENSIONS metadata, if it is empty corresponding driver will be skipped even if supported.
|
||||
|
||||
The ``options`` argument can be used to control the sorting and filtering of
|
||||
returned formats.
|
||||
|
||||
.. seealso:: :py:func:`supportedOutputRasterLayerExtensions()`
|
||||
:rtype: list of QgsRasterFileWriter.FilterFormatDetails
|
||||
%End
|
||||
|
||||
static QStringList supportedFormatExtensions( RasterFormatOptions options = SortRecommended );
|
||||
%Docstring
|
||||
Returns a list of file extensions for supported formats.
|
||||
|
||||
The ``options`` argument can be used to control the sorting and filtering of
|
||||
returned formats.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
.. seealso:: :py:func:`supportedFiltersAndFormats()`
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
static QString driverForExtension( const QString &extension );
|
||||
%Docstring
|
||||
Returns the GDAL driver name for a specified file ``extension``. E.g. the
|
||||
|
@ -31,7 +31,8 @@ from qgis.PyQt.QtCore import QCoreApplication, QObject, pyqtSignal
|
||||
from qgis.core import (NULL,
|
||||
QgsApplication,
|
||||
QgsSettings,
|
||||
QgsVectorFileWriter)
|
||||
QgsVectorFileWriter,
|
||||
QgsRasterFileWriter)
|
||||
from processing.tools.system import defaultOutputFolder
|
||||
import processing.tools.dataobjects
|
||||
|
||||
@ -170,7 +171,7 @@ class ProcessingConfig:
|
||||
valuetype=Setting.SELECTION,
|
||||
options=extensions))
|
||||
|
||||
extensions = processing.tools.dataobjects.getSupportedOutputRasterLayerExtensions()
|
||||
extensions = QgsRasterFileWriter.supportedFormatExtensions()
|
||||
ProcessingConfig.addSetting(Setting(
|
||||
ProcessingConfig.tr('General'),
|
||||
ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT,
|
||||
|
@ -29,7 +29,8 @@ __revision__ = '$Format:%H$'
|
||||
from qgis.core import (QgsProcessing,
|
||||
QgsProviderRegistry,
|
||||
QgsProcessingFeatureSourceDefinition,
|
||||
QgsVectorFileWriter)
|
||||
QgsVectorFileWriter,
|
||||
QgsRasterFileWriter)
|
||||
from qgis.PyQt.QtCore import QCoreApplication
|
||||
from processing.tools import dataobjects
|
||||
|
||||
@ -48,7 +49,7 @@ def getFileFilter(param):
|
||||
"""
|
||||
if param.type() == 'multilayer':
|
||||
if param.layerType() == QgsProcessing.TypeRaster:
|
||||
exts = dataobjects.getSupportedOutputRasterLayerExtensions()
|
||||
exts = QgsRasterFileWriter.supportedFormatExtensions()
|
||||
elif param.layerType() == QgsProcessing.TypeFile:
|
||||
return tr('All files (*.*)', 'QgsProcessingParameterMultipleLayers')
|
||||
else:
|
||||
@ -59,7 +60,12 @@ def getFileFilter(param):
|
||||
elif param.type() == 'raster':
|
||||
return QgsProviderRegistry.instance().fileRasterFilters()
|
||||
elif param.type() == 'rasterDestination':
|
||||
exts = dataobjects.getSupportedOutputRasterFilters()
|
||||
if param.provider() is not None:
|
||||
exts = param.provider().supportedOutputRasterLayerExtensions()
|
||||
else:
|
||||
exts = QgsRasterFileWriter.supportedFormatExtensions()
|
||||
for i in range(len(exts)):
|
||||
exts[i] = tr('{0} files (*.{1})', 'ParameterRaster').format(exts[i].upper(), exts[i].lower())
|
||||
return ';;'.join(exts) + ';;' + tr('All files (*.*)')
|
||||
elif param.type() in ('sink', 'vectorDestination'):
|
||||
if param.provider() is not None:
|
||||
|
@ -105,35 +105,6 @@ def createExpressionContext():
|
||||
return context
|
||||
|
||||
|
||||
def getSupportedOutputRasterLayerExtensions():
|
||||
allexts = []
|
||||
for exts in list(GdalUtils.getSupportedRasters().values()):
|
||||
for ext in exts:
|
||||
if ext != 'tif' and ext not in allexts:
|
||||
allexts.append(ext)
|
||||
allexts.sort()
|
||||
allexts.insert(0, 'tif') # tif is the default, should be the first
|
||||
return allexts
|
||||
|
||||
|
||||
def getSupportedOutputRasterFilters():
|
||||
"""
|
||||
Return a list of file filters for supported raster formats.
|
||||
Supported formats come from Gdal.
|
||||
:return: a list of strings for Qt file filters.
|
||||
"""
|
||||
allFilters = []
|
||||
supported = GdalUtils.getSupportedOutputRasters()
|
||||
formatList = sorted(supported.keys())
|
||||
# Place GTiff as the first format
|
||||
if 'GTiff' in formatList:
|
||||
formatList.pop(formatList.index('GTiff'))
|
||||
formatList.insert(0, 'GTiff')
|
||||
for f in formatList:
|
||||
allFilters.append('{0} files (*.{1})'.format(f, ' *.'.join(supported[f])))
|
||||
return allFilters
|
||||
|
||||
|
||||
def load(fileName, name=None, crs=None, style=None, isRaster=False):
|
||||
"""Loads a layer/table into the current project, given its file.
|
||||
"""
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "qgsprocessingprovider.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsvectorfilewriter.h"
|
||||
#include "qgsrasterfilewriter.h"
|
||||
#include "qgssettings.h"
|
||||
|
||||
QgsProcessingProvider::QgsProcessingProvider( QObject *parent SIP_TRANSFERTHIS )
|
||||
@ -47,7 +48,7 @@ QString QgsProcessingProvider::longName() const
|
||||
|
||||
QStringList QgsProcessingProvider::supportedOutputRasterLayerExtensions() const
|
||||
{
|
||||
return QStringList() << QStringLiteral( "tif" );
|
||||
return QgsRasterFileWriter::supportedFormatExtensions();
|
||||
}
|
||||
|
||||
void QgsProcessingProvider::refreshAlgorithms()
|
||||
@ -136,4 +137,3 @@ QString QgsProcessingProvider::defaultRasterFileExtension() const
|
||||
return defaultExtension;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1023,3 +1023,103 @@ QStringList QgsRasterFileWriter::extensionsForFormat( const QString &format )
|
||||
}
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QString QgsRasterFileWriter::filterForDriver( const QString &driverName )
|
||||
{
|
||||
GDALDriverH drv = GDALGetDriverByName( driverName.toLocal8Bit().data() );
|
||||
if ( drv )
|
||||
{
|
||||
QString drvName = GDALGetDriverLongName( drv );
|
||||
QString extensionsString = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS, nullptr ) );
|
||||
if ( extensionsString.isEmpty() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
QStringList extensions = extensionsString.split( ' ' );
|
||||
QString filter = drvName + " (";
|
||||
for ( const QString &ext : extensions )
|
||||
{
|
||||
filter.append( QStringLiteral( "*.%1 *.%2 " ).arg( ext.toLower(), ext.toUpper() ) );
|
||||
}
|
||||
filter = filter.trimmed().append( QStringLiteral( ")" ) );
|
||||
return filter;
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QList< QgsRasterFileWriter::FilterFormatDetails > QgsRasterFileWriter::supportedFiltersAndFormats( RasterFormatOptions options )
|
||||
{
|
||||
QList< FilterFormatDetails > results;
|
||||
|
||||
GDALAllRegister();
|
||||
int const drvCount = GDALGetDriverCount();
|
||||
|
||||
FilterFormatDetails tifFormat;
|
||||
|
||||
for ( int i = 0; i < drvCount; ++i )
|
||||
{
|
||||
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 ) )
|
||||
{
|
||||
QString filterString = filterForDriver( drvName );
|
||||
if ( filterString.isEmpty() )
|
||||
continue;
|
||||
|
||||
FilterFormatDetails details;
|
||||
details.driverName = drvName;
|
||||
details.filterString = filterString;
|
||||
|
||||
if ( options & SortRecommended )
|
||||
{
|
||||
if ( drvName == QLatin1String( "GTiff" ) )
|
||||
{
|
||||
tifFormat = details;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
results << details;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort( results.begin(), results.end(), []( const FilterFormatDetails & a, const FilterFormatDetails & b ) -> bool
|
||||
{
|
||||
return a.driverName < b.driverName;
|
||||
} );
|
||||
|
||||
if ( options & SortRecommended )
|
||||
{
|
||||
if ( !tifFormat.filterString.isEmpty() )
|
||||
{
|
||||
results.insert( 0, tifFormat );
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
QStringList QgsRasterFileWriter::supportedFormatExtensions( const RasterFormatOptions options )
|
||||
{
|
||||
const auto formats = supportedFiltersAndFormats( options );
|
||||
QStringList extensions;
|
||||
|
||||
QRegularExpression rx( QStringLiteral( "\\*\\.([a-zA-Z0-9]*)" ) );
|
||||
|
||||
for ( const FilterFormatDetails &format : formats )
|
||||
{
|
||||
QString ext = format.filterString;
|
||||
QRegularExpressionMatch match = rx.match( ext );
|
||||
if ( !match.hasMatch() )
|
||||
continue;
|
||||
|
||||
QString matched = match.captured( 1 );
|
||||
extensions << matched;
|
||||
}
|
||||
return extensions;
|
||||
}
|
||||
|
@ -54,6 +54,16 @@ class CORE_EXPORT QgsRasterFileWriter
|
||||
WriteCanceled = 6, //!< Writing was manually canceled
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for sorting and filtering raster formats.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
enum RasterFormatOption
|
||||
{
|
||||
SortRecommended = 1 << 1, //!< Use recommended sort order, with extremely commonly used formats listed first
|
||||
};
|
||||
Q_DECLARE_FLAGS( RasterFormatOptions, RasterFormatOption )
|
||||
|
||||
QgsRasterFileWriter( const QString &outputUrl );
|
||||
|
||||
/**
|
||||
@ -134,6 +144,44 @@ class CORE_EXPORT QgsRasterFileWriter
|
||||
void setPyramidsConfigOptions( const QStringList &list ) { mPyramidsConfigOptions = list; }
|
||||
QStringList pyramidsConfigOptions() const { return mPyramidsConfigOptions; }
|
||||
|
||||
//! Creates a filter for an GDAL driver key
|
||||
static QString filterForDriver( const QString &driverName );
|
||||
|
||||
/**
|
||||
* Details of available filters and formats.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
struct FilterFormatDetails
|
||||
{
|
||||
//! Unique driver name
|
||||
QString driverName;
|
||||
|
||||
//! Filter string for file picker dialogs
|
||||
QString filterString;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a list or pairs, with format filter string as first element and GDAL format key as second element.
|
||||
* Relies on GDAL_DMD_EXTENSIONS metadata, if it is empty corresponding driver will be skipped even if supported.
|
||||
*
|
||||
* The \a options argument can be used to control the sorting and filtering of
|
||||
* returned formats.
|
||||
*
|
||||
* \see supportedOutputRasterLayerExtensions()
|
||||
*/
|
||||
static QList< QgsRasterFileWriter::FilterFormatDetails > supportedFiltersAndFormats( RasterFormatOptions options = SortRecommended );
|
||||
|
||||
/**
|
||||
* Returns a list of file extensions for supported formats.
|
||||
*
|
||||
* The \a options argument can be used to control the sorting and filtering of
|
||||
* returned formats.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
* \see supportedFiltersAndFormats()
|
||||
*/
|
||||
static QStringList supportedFormatExtensions( RasterFormatOptions options = SortRecommended );
|
||||
|
||||
/**
|
||||
* Returns the GDAL driver name for a specified file \a extension. E.g. the
|
||||
* driver name for the ".tif" extension is "GTiff".
|
||||
|
@ -114,6 +114,32 @@ class TestQgsRasterFileWriter(unittest.TestCase):
|
||||
self.assertCountEqual(QgsRasterFileWriter.extensionsForFormat('GTiff'), ['tiff', 'tif'])
|
||||
self.assertCountEqual(QgsRasterFileWriter.extensionsForFormat('GPKG'), ['gpkg'])
|
||||
|
||||
def testSupportedFiltersAndFormat(self):
|
||||
# test with formats in recommended order
|
||||
formats = QgsRasterFileWriter.supportedFiltersAndFormats(QgsRasterFileWriter.SortRecommended)
|
||||
self.assertEqual(formats[0].filterString, 'GeoTIFF (*.tif *.TIF *.tiff *.TIFF)')
|
||||
self.assertEqual(formats[0].driverName, 'GTiff')
|
||||
self.assertTrue('netCDF' in [f.driverName for f in formats])
|
||||
|
||||
# alphabetical sorting
|
||||
formats2 = QgsRasterFileWriter.supportedFiltersAndFormats(QgsRasterFileWriter.RasterFormatOptions())
|
||||
self.assertTrue(formats2[0].driverName < formats2[1].driverName)
|
||||
self.assertCountEqual([f.driverName for f in formats], [f.driverName for f in formats2])
|
||||
self.assertNotEqual(formats2[0].driverName, 'GTiff')
|
||||
|
||||
def testSupportedFormatExtensions(self):
|
||||
formats = QgsRasterFileWriter.supportedFormatExtensions()
|
||||
self.assertTrue('tif' in formats)
|
||||
self.assertFalse('exe' in formats)
|
||||
self.assertEqual(formats[0], 'tif')
|
||||
self.assertTrue('nc' in formats)
|
||||
|
||||
# alphabetical sorting
|
||||
formats2 = QgsRasterFileWriter.supportedFormatExtensions(QgsRasterFileWriter.RasterFormatOptions())
|
||||
self.assertTrue(formats2[1] < formats2[2])
|
||||
self.assertCountEqual(formats, formats2)
|
||||
self.assertNotEqual(formats2[0], 'tif')
|
||||
|
||||
def testImportIntoGpkg(self):
|
||||
# init target file
|
||||
test_gpkg = tempfile.mktemp(suffix='.gpkg', dir=self.testDataDir)
|
||||
|
Loading…
x
Reference in New Issue
Block a user