Skip to content
Permalink
Browse files

Merge pull request #5534 from nyalldawson/format

Add flags to QgsVectorFileWriter methods which return lists of drivers
  • Loading branch information
nyalldawson committed Nov 5, 2017
2 parents bfe0355 + 2df5332 commit 31f98dac034461d593eafa6014759ce26daf9c91
@@ -2672,6 +2672,8 @@ for consistency with other parts of the QGIS API.
- The addFeature which takes a renderer argument was renamed to addFeatureWithStyle.
- static `writeAsVectorFormat` calls no longer take a errorMessage argument in
python and instead return a `(errorCode, errorMessage)` tuple.
- ogrDriverList now returns a list of QgsVectorFileWriter.DriverDetails structs, instead of a map
- supportedFiltersAndFormats now returns a list of QgsVectorFileWriter.FilterFormatDetails structs, instead of a map


QgsWMSLegendNode {#qgis_api_break_3_0_QgsWMSLegendNode}
@@ -10,8 +10,6 @@





class QgsVectorFileWriter : QgsFeatureSink
{
%Docstring
@@ -145,6 +143,15 @@ Some formats require a compulsory encoding, typically UTF-8. If no compulsory en
SymbolLayerSymbology
};


enum VectorFormatOption
{
SortRecommended,
SkipNonSpatialFormats,
};
typedef QFlags<QgsVectorFileWriter::VectorFormatOption> VectorFormatOptions;


class FieldValueConverter
{
%Docstring
@@ -460,27 +467,67 @@ Create a new vector file writer



static QMap< QString, QString> supportedFiltersAndFormats();
struct FilterFormatDetails
{
QString driverName;
%Docstring
Unique driver name
%End

QString filterString;
%Docstring
Filter string for file picker dialogs
%End
};

static QList< QgsVectorFileWriter::FilterFormatDetails > supportedFiltersAndFormats( VectorFormatOptions options = SortRecommended );
%Docstring
Returns a map with format filter string as key and OGR format key as value.
Returns a list or pairs, with format filter string as first element and OGR format key as second element.

The ``options`` argument can be used to control the sorting and filtering of
returned formats.

.. seealso:: supportedOutputVectorLayerExtensions()
:rtype: QMap< str, QString>
:rtype: list of QgsVectorFileWriter.FilterFormatDetails
%End

static QStringList supportedFormatExtensions();
static QStringList supportedFormatExtensions( VectorFormatOptions 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:: supportedFiltersAndFormats()
:rtype: list of str
%End

static QMap< QString, QString> ogrDriverList();
struct DriverDetails
{
QString longName;
%Docstring
Descriptive, user friendly name for the driver
%End

QString driverName;
%Docstring
Returns driver list that can be used for dialogs. It contains all OGR drivers
+ some additional internal QGIS driver names to distinguish between more
supported formats of the same OGR driver
:rtype: QMap< str, QString>
Unique driver name
%End
};

static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList( VectorFormatOptions options = SortRecommended );
%Docstring
Returns the driver list that can be used for dialogs. It contains all OGR drivers
plus some additional internal QGIS driver names to distinguish between more
supported formats of the same OGR driver.

The returned list consists of structs containing the driver long name (e.g. user-friendly
display name for the format) and internal driver short name.

The ``options`` argument can be used to control the sorting and filtering of
returned drivers.
:rtype: list of QgsVectorFileWriter.DriverDetails
%End

static QString driverForExtension( const QString &extension );
@@ -492,9 +539,12 @@ Create a new vector file writer
:rtype: str
%End

static QString fileFilterString();
static QString fileFilterString( VectorFormatOptions options = SortRecommended );
%Docstring
Returns filter string that can be used for dialogs
Returns filter string that can be used for dialogs.

The ``options`` argument can be used to control the sorting and filtering of
returned drivers.
:rtype: str
%End

@@ -639,6 +689,8 @@ Close opened shapefile for writing

QFlags<QgsVectorFileWriter::EditionCapability> operator|(QgsVectorFileWriter::EditionCapability f1, QFlags<QgsVectorFileWriter::EditionCapability> f2);

QFlags<QgsVectorFileWriter::VectorFormatOption> operator|(QgsVectorFileWriter::VectorFormatOption f1, QFlags<QgsVectorFileWriter::VectorFormatOption> f2);



/************************************************************************
@@ -174,9 +174,9 @@ def getVectorDriverFromFileName(filename):
return 'ESRI Shapefile'

formats = QgsVectorFileWriter.supportedFiltersAndFormats()
for k, v in list(formats.items()):
if ext in k:
return v
for format in formats:
if ext in format.filterString:
return format.driverName
return 'ESRI Shapefile'

@staticmethod
@@ -2681,13 +2681,16 @@ void QgsVectorFileWriter::setSymbologyScale( double d )
mRenderContext.setRendererScale( mSymbologyScale );
}

QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats()
QList< QgsVectorFileWriter::FilterFormatDetails > QgsVectorFileWriter::supportedFiltersAndFormats( const VectorFormatOptions options )
{
QMap<QString, QString> resultMap;
QList< FilterFormatDetails > results;

QgsApplication::registerOgrDrivers();
int const drvCount = OGRGetDriverCount();

FilterFormatDetails shapeFormat;
FilterFormatDetails gpkgFormat;

for ( int i = 0; i < drvCount; ++i )
{
OGRSFDriverH drv = OGRGetDriver( i );
@@ -2696,58 +2699,87 @@ QMap< QString, QString> QgsVectorFileWriter::supportedFiltersAndFormats()
QString drvName = OGR_Dr_GetName( drv );
if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 )
{
if ( options & SkipNonSpatialFormats )
{
// skip non-spatial formats
// TODO - use GDAL metadata to determine this, when support exists in GDAL
if ( drvName == QLatin1String( "ODS" ) || drvName == QLatin1String( "XLSX" ) || drvName == QLatin1String( "XLS" ) )
continue;
}

QString filterString = filterForDriver( drvName );
if ( filterString.isEmpty() )
continue;

resultMap.insert( filterString, drvName );
FilterFormatDetails details;
details.driverName = drvName;
details.filterString = filterString;

if ( options & SortRecommended )
{
if ( drvName == QLatin1String( "ESRI Shapefile" ) )
{
shapeFormat = details;
continue;
}
else if ( drvName == QLatin1String( "GPKG" ) )
{
gpkgFormat = details;
continue;
}
}

results << details;
}
}
}

return resultMap;
std::sort( results.begin(), results.end(), []( const FilterFormatDetails & a, const FilterFormatDetails & b ) -> bool
{
return a.driverName < b.driverName;
} );

if ( options & SortRecommended )
{
if ( !shapeFormat.filterString.isEmpty() )
{
results.insert( 0, shapeFormat );
}
if ( !gpkgFormat.filterString.isEmpty() )
{
results.insert( 0, gpkgFormat );
}
}

return results;
}

QStringList QgsVectorFileWriter::supportedFormatExtensions()
QStringList QgsVectorFileWriter::supportedFormatExtensions( const VectorFormatOptions options )
{
QgsStringMap formats = supportedFiltersAndFormats();
const auto formats = supportedFiltersAndFormats( options );
QStringList extensions;

QRegularExpression rx( QStringLiteral( "\\*\\.([a-zA-Z0-9]*)" ) );

QgsStringMap::const_iterator formatIt = formats.constBegin();
for ( ; formatIt != formats.constEnd(); ++formatIt )
for ( const FilterFormatDetails &format : formats )
{
QString ext = formatIt.key();
QString ext = format.filterString;
QRegularExpressionMatch match = rx.match( ext );
if ( !match.hasMatch() )
continue;

QString matched = match.captured( 1 );

// special handling for the two main contenders for glory
if ( matched.compare( QStringLiteral( "gpkg" ), Qt::CaseInsensitive ) == 0 )
continue;
if ( matched.compare( QStringLiteral( "shp" ), Qt::CaseInsensitive ) == 0 )
continue;

extensions << matched;
}

std::sort( extensions.begin(), extensions.end() );

// Make https://twitter.com/shapefiIe a sad little fellow
extensions.insert( 0, QStringLiteral( "gpkg" ) );
extensions.insert( 1, QStringLiteral( "shp" ) );
return extensions;
}

QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
QList< QgsVectorFileWriter::DriverDetails > QgsVectorFileWriter::ogrDriverList( const VectorFormatOptions options )
{
QMap<QString, QString> resultMap;
QList< QgsVectorFileWriter::DriverDetails > results;

QgsApplication::registerOgrDrivers();
int const drvCount = OGRGetDriverCount();
const int drvCount = OGRGetDriverCount();

QStringList writableDrivers;
for ( int i = 0; i < drvCount; ++i )
@@ -2756,6 +2788,19 @@ QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
if ( drv )
{
QString drvName = OGR_Dr_GetName( drv );

if ( options & SkipNonSpatialFormats )
{
// skip non-spatial formats
// TODO - use GDAL metadata to determine this, when support exists in GDAL
if ( drvName == QLatin1String( "ODS" ) || drvName == QLatin1String( "XLSX" ) || drvName == QLatin1String( "XLS" ) )
continue;
}

if ( drvName == QLatin1String( "ESRI Shapefile" ) )
{
writableDrivers << QStringLiteral( "DBF file" );
}
if ( OGR_Dr_TestCapability( drv, "CreateDataSource" ) != 0 )
{
// Add separate format for Mapinfo MIF (MITAB is OGR default)
@@ -2786,25 +2831,39 @@ QMap<QString, QString> QgsVectorFileWriter::ogrDriverList()
}
CPLFree( options[0] );
}
else if ( drvName == QLatin1String( "ESRI Shapefile" ) )
{
writableDrivers << QStringLiteral( "DBF file" );
}
writableDrivers << drvName;
}
}
}
std::sort( writableDrivers.begin(), writableDrivers.end() );
if ( options & SortRecommended )
{
// recommended order sorting, so we shift certain formats to the top
if ( writableDrivers.contains( QStringLiteral( "ESRI Shapefile" ) ) )
{
writableDrivers.removeAll( QStringLiteral( "ESRI Shapefile" ) );
writableDrivers.insert( 0, QStringLiteral( "ESRI Shapefile" ) );
}
if ( writableDrivers.contains( QStringLiteral( "GPKG" ) ) )
{
// Make https://twitter.com/shapefiIe a sad little fellow
writableDrivers.removeAll( QStringLiteral( "GPKG" ) );
writableDrivers.insert( 0, QStringLiteral( "GPKG" ) );
}
}

Q_FOREACH ( const QString &drvName, writableDrivers )
for ( const QString &drvName : qgis::as_const( writableDrivers ) )
{
MetaData metadata;
if ( driverMetadata( drvName, metadata ) && !metadata.trLongName.isEmpty() )
{
resultMap.insert( metadata.trLongName, drvName );
DriverDetails details;
details.driverName = drvName;
details.longName = metadata.trLongName;
results << details;
}
}

return resultMap;
return results;
}

QString QgsVectorFileWriter::driverForExtension( const QString &extension )
@@ -2841,17 +2900,16 @@ QString QgsVectorFileWriter::driverForExtension( const QString &extension )
return QString();
}

QString QgsVectorFileWriter::fileFilterString()
QString QgsVectorFileWriter::fileFilterString( const VectorFormatOptions options )
{
QString filterString;
QMap< QString, QString> driverFormatMap = supportedFiltersAndFormats();
QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin();
for ( ; it != driverFormatMap.constEnd(); ++it )
const auto driverFormats = supportedFiltersAndFormats( options );
for ( const FilterFormatDetails &details : driverFormats )
{
if ( !filterString.isEmpty() )
filterString += QLatin1String( ";;" );

filterString += it.key();
filterString += details.filterString;
}
return filterString;
}
@@ -2860,9 +2918,11 @@ QString QgsVectorFileWriter::filterForDriver( const QString &driverName )
{
MetaData metadata;
if ( !driverMetadata( driverName, metadata ) || metadata.trLongName.isEmpty() || metadata.glob.isEmpty() )
return QLatin1String( "" );
return QString();

return metadata.trLongName + " [OGR] (" + metadata.glob.toLower() + ' ' + metadata.glob.toUpper() + ')';
return QStringLiteral( "%1 (%2 %3)" ).arg( metadata.trLongName,
metadata.glob.toLower(),
metadata.glob.toUpper() );
}

QString QgsVectorFileWriter::convertCodecNameForEncodingOption( const QString &codecName )

0 comments on commit 31f98da

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