42 #include <QTextStream>    50 #include <ogr_srs_api.h>    51 #include <cpl_error.h>    53 #include <cpl_string.h>    59 static OGRDataSourceH myOGROpen( 
const char *pszName, 
int bUpdate, OGRSFDriverH *phDriver )
    61   OGRSFDriverH hDriver = 
nullptr;
    62   OGRDataSourceH hDS = OGROpen( pszName, bUpdate, &hDriver );
    65     QString drvName = OGR_Dr_GetName( hDriver );
    66     if ( drvName == 
"BNA" )
    68       OGR_DS_Destroy( hDS );
    95   const QString &vectorFileName,
    96   const QString &fileEncoding,
   100   const QString &driverName,
   101   const QStringList &datasourceOptions,
   102   const QStringList &layerOptions,
   103   QString *newFilename,
   105   QgsFeatureSink::SinkFlags sinkFlags,
   113   init( vectorFileName, fileEncoding, fields,  geometryType,
   114         srs, driverName, datasourceOptions, layerOptions, newFilename, 
nullptr,
   119     const QString &fileEncoding,
   123     const QString &driverName,
   124     const QStringList &datasourceOptions,
   125     const QStringList &layerOptions,
   126     QString *newFilename,
   129     const QString &layerName,
   137   init( vectorFileName, fileEncoding, fields, geometryType, srs, driverName,
   138         datasourceOptions, layerOptions, newFilename, fieldValueConverter,
   139         layerName, action, newLayer, 
nullptr );
   144   if ( driverName == QLatin1String( 
"MapInfo MIF" ) )
   148 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0)   149   GDALDriverH gdalDriver = GDALGetDriverByName( driverName.toLocal8Bit().constData() );
   154   if ( !driverMetadata )
   157   return CSLFetchBoolean( driverMetadata, GDAL_DCAP_FEATURE_STYLES, 
false );
   159   return driverName == QLatin1String( 
"DXF" ) || driverName == QLatin1String( 
"KML" ) || driverName == QLatin1String( 
"MapInfo File" );
   163 void QgsVectorFileWriter::init( QString vectorFileName,
   164                                 QString fileEncoding,
   168                                 const QString &driverName,
   169                                 QStringList datasourceOptions,
   170                                 QStringList layerOptions,
   171                                 QString *newFilename,
   173                                 const QString &layerNameIn,
   175                                 QString *newLayer, SinkFlags sinkFlags )
   179   if ( vectorFileName.isEmpty() )
   186   if ( driverName == QLatin1String( 
"MapInfo MIF" ) )
   190   else if ( driverName == QLatin1String( 
"SpatiaLite" ) )
   193     if ( !datasourceOptions.contains( QStringLiteral( 
"SPATIALITE=YES" ) ) )
   195       datasourceOptions.append( QStringLiteral( 
"SPATIALITE=YES" ) );
   198   else if ( driverName == QLatin1String( 
"DBF file" ) )
   201     if ( !layerOptions.contains( QStringLiteral( 
"SHPT=NULL" ) ) )
   203       layerOptions.append( QStringLiteral( 
"SHPT=NULL" ) );
   213   OGRSFDriverH poDriver;
   216   poDriver = OGRGetDriverByName( 
mOgrDriverName.toLocal8Bit().constData() );
   220     mErrorMessage = QObject::tr( 
"OGR driver for '%1' not found (OGR error: %2)" )
   222                           QString::fromUtf8( CPLGetLastErrorMsg() ) );
   232     if ( layerOptions.join( QString() ).toUpper().indexOf( QLatin1String( 
"ENCODING=" ) ) == -1 )
   237     if ( driverName == QLatin1String( 
"ESRI Shapefile" ) && !vectorFileName.endsWith( QLatin1String( 
".shp" ), Qt::CaseInsensitive ) )
   239       vectorFileName += QLatin1String( 
".shp" );
   241     else if ( driverName == QLatin1String( 
"DBF file" ) && !vectorFileName.endsWith( QLatin1String( 
".dbf" ), Qt::CaseInsensitive ) )
   243       vectorFileName += QLatin1String( 
".dbf" );
   253       QStringList allExts = metadata.
ext.split( 
' ', QString::SkipEmptyParts );
   255       Q_FOREACH ( 
const QString &ext, allExts )
   257         if ( vectorFileName.endsWith( 
'.' + ext, Qt::CaseInsensitive ) )
   266         vectorFileName += 
'.' + allExts[0];
   272       if ( vectorFileName.endsWith( QLatin1String( 
".gdb" ), Qt::CaseInsensitive ) )
   274         QDir dir( vectorFileName );
   277           QFileInfoList fileList = dir.entryInfoList(
   278                                      QDir::NoDotAndDotDot | QDir::System | QDir::Hidden  | QDir::AllDirs | QDir::Files, QDir::DirsFirst );
   279           Q_FOREACH ( 
const QFileInfo &info, fileList )
   281             QFile::remove( info.absoluteFilePath() );
   284         QDir().rmdir( vectorFileName );
   288         QFile::remove( vectorFileName );
   303   char **options = 
nullptr;
   304   if ( !datasourceOptions.isEmpty() )
   306     options = 
new char *[ datasourceOptions.size() + 1 ];
   307     for ( 
int i = 0; i < datasourceOptions.size(); i++ )
   309       QgsDebugMsg( QStringLiteral( 
"-dsco=%1" ).arg( datasourceOptions[i] ) );
   310       options[i] = CPLStrdup( datasourceOptions[i].toLocal8Bit().constData() );
   312     options[ datasourceOptions.size()] = 
nullptr;
   318     mDS.reset( OGR_Dr_CreateDataSource( poDriver, vectorFileName.toUtf8().constData(), options ) );
   320     mDS.reset( myOGROpen( vectorFileName.toUtf8().constData(), TRUE, nullptr ) );
   324     for ( 
int i = 0; i < datasourceOptions.size(); i++ )
   325       CPLFree( options[i] );
   334       mErrorMessage = QObject::tr( 
"Creation of data source failed (OGR error: %1)" )
   335                       .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
   337       mErrorMessage = QObject::tr( 
"Opening of data source in update mode failed (OGR error: %1)" )
   338                       .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
   342   QString layerName( layerNameIn );
   343   if ( layerName.isEmpty() )
   344     layerName = QFileInfo( vectorFileName ).baseName();
   348     const int layer_count = OGR_DS_GetLayerCount( 
mDS.get() );
   349     for ( 
int i = 0; i < layer_count; i++ )
   351       OGRLayerH hLayer = OGR_DS_GetLayer( 
mDS.get(), i );
   352       if ( EQUAL( OGR_L_GetName( hLayer ), layerName.toUtf8().constData() ) )
   354         if ( OGR_DS_DeleteLayer( 
mDS.get(), i ) != OGRERR_NONE )
   357           mErrorMessage = QObject::tr( 
"Overwriting of existing layer failed (OGR error: %1)" )
   358                           .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
   368     QgsDebugMsg( QStringLiteral( 
"Created data source" ) );
   372     QgsDebugMsg( QStringLiteral( 
"Opened data source in update mode" ) );
   376   mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().constData() );
   379     QgsDebugMsg( 
"error finding QTextCodec for " + fileEncoding );
   382     QString enc = settings.
value( QStringLiteral( 
"UI/encoding" ), 
"System" ).toString();
   383     mCodec = QTextCodec::codecForName( enc.toLocal8Bit().constData() );
   386       QgsDebugMsg( 
"error finding QTextCodec for " + enc );
   387       mCodec = QTextCodec::codecForLocale();
   395     QString srsWkt = srs.
toWkt();
   397     mOgrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().constData() );
   398 #if GDAL_VERSION_MAJOR >= 3   401       OSRSetAxisMappingStrategy( 
mOgrRef, OAMS_TRADITIONAL_GIS_ORDER );
   410   int optIndex = layerOptions.indexOf( QStringLiteral( 
"FEATURE_DATASET=" ) );
   411   if ( optIndex != -1 )
   413     layerOptions.removeAt( optIndex );
   416   if ( !layerOptions.isEmpty() )
   418     options = 
new char *[ layerOptions.size() + 1 ];
   419     for ( 
int i = 0; i < layerOptions.size(); i++ )
   421       QgsDebugMsg( QStringLiteral( 
"-lco=%1" ).arg( layerOptions[i] ) );
   422       options[i] = CPLStrdup( layerOptions[i].toLocal8Bit().constData() );
   424     options[ layerOptions.size()] = 
nullptr;
   428   CPLSetConfigOption( 
"SHAPE_ENCODING", 
"" );
   432     mLayer = OGR_DS_CreateLayer( 
mDS.get(), layerName.toUtf8().constData(), 
mOgrRef, wkbType, options );
   435       *newLayer = OGR_L_GetName( 
mLayer );
   436       if ( driverName == QLatin1String( 
"GPX" ) )
   443             if ( !EQUAL( layerName.toUtf8().constData(), 
"track_points" ) &&
   444                  !EQUAL( layerName.toUtf8().constData(), 
"route_points" ) )
   446               *newLayer = QStringLiteral( 
"waypoints" );
   453             const char *pszForceGPXTrack
   454               = CSLFetchNameValue( options, 
"FORCE_GPX_TRACK" );
   455             if ( pszForceGPXTrack && CPLTestBool( pszForceGPXTrack ) )
   456               *newLayer = QStringLiteral( 
"tracks" );
   458               *newLayer = QStringLiteral( 
"routes" );
   465             const char *pszForceGPXRoute
   466               = CSLFetchNameValue( options, 
"FORCE_GPX_ROUTE" );
   467             if ( pszForceGPXRoute && CPLTestBool( pszForceGPXRoute ) )
   468               *newLayer = QStringLiteral( 
"routes" );
   470               *newLayer = QStringLiteral( 
"tracks" );
   480   else if ( driverName == QLatin1String( 
"DGN" ) )
   482     mLayer = OGR_DS_GetLayerByName( 
mDS.get(), 
"elements" );
   486     mLayer = OGR_DS_GetLayerByName( 
mDS.get(), layerName.toUtf8().constData() );
   491     for ( 
int i = 0; i < layerOptions.size(); i++ )
   492       CPLFree( options[i] );
   498   if ( !settings.
value( QStringLiteral( 
"qgis/ignoreShapeEncoding" ), 
true ).toBool() )
   500     CPLSetConfigOption( 
"SHAPE_ENCODING", 
nullptr );
   507       QString layerName = vectorFileName.left( vectorFileName.indexOf( QLatin1String( 
".shp" ), Qt::CaseInsensitive ) );
   508       QFile prjFile( layerName + 
".qpj" );
   509       if ( prjFile.open( QIODevice::WriteOnly  | QIODevice::Truncate ) )
   511         QTextStream prjStream( &prjFile );
   512         prjStream << srs.
toWkt().toLocal8Bit().constData() << endl;
   517         QgsDebugMsg( 
"Couldn't open file " + layerName + 
".qpj" );
   525       mErrorMessage = QObject::tr( 
"Creation of layer failed (OGR error: %1)" )
   526                       .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
   528       mErrorMessage = QObject::tr( 
"Opening of layer failed (OGR error: %1)" )
   529                       .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
   534   OGRFeatureDefnH defn = OGR_L_GetLayerDefn( 
mLayer );
   539   QgsDebugMsg( 
"creating " + QString::number( fields.
size() ) + 
" fields" );
   543   QSet<int> existingIdxs;
   550         fldIdx < fields.
count(); ++fldIdx )
   554     if ( fieldValueConverter )
   559     QString name( attrField.
name() );
   562       int ogrIdx = OGR_FD_GetFieldIndex( defn, 
mCodec->fromUnicode( name ) );
   570     OGRFieldType ogrType = OFTString; 
   571     int ogrWidth = attrField.
length();
   572     int ogrPrecision = attrField.
precision();
   573     if ( ogrPrecision > 0 )
   576     switch ( attrField.
type() )
   578       case QVariant::LongLong:
   580         const char *pszDataTypes = GDALGetMetadataItem( poDriver, GDAL_DMD_CREATIONFIELDDATATYPES, 
nullptr );
   581         if ( pszDataTypes && strstr( pszDataTypes, 
"Integer64" ) )
   582           ogrType = OFTInteger64;
   585         ogrWidth = ogrWidth > 0 && ogrWidth <= 20 ? ogrWidth : 20;
   589       case QVariant::String:
   591         if ( ( ogrWidth <= 0 || ogrWidth > 255 ) && 
mOgrDriverName == QLatin1String( 
"ESRI Shapefile" ) )
   596         ogrType = OFTInteger;
   597         ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
   602         ogrType = OFTInteger;
   607       case QVariant::Double:
   627       case QVariant::DateTime:
   635           ogrType = OFTDateTime;
   641         mErrorMessage = QObject::tr( 
"Unsupported type for field %1" )
   642                         .arg( attrField.
name() );
   647     if ( 
mOgrDriverName == QLatin1String( 
"SQLite" ) && name.compare( QLatin1String( 
"ogc_fid" ), Qt::CaseInsensitive ) == 0 )
   650       for ( i = 0; i < 10; i++ )
   652         name = QStringLiteral( 
"ogc_fid%1" ).arg( i );
   655         for ( j = 0; j < fields.
size() && name.compare( fields.
at( j ).
name(), Qt::CaseInsensitive ) != 0; j++ )
   658         if ( j == fields.
size() )
   664         mErrorMessage = QObject::tr( 
"No available replacement for internal fieldname ogc_fid found" ).arg( attrField.
name() );
   669       QgsMessageLog::logMessage( QObject::tr( 
"Reserved attribute name ogc_fid replaced with %1" ).arg( name ), QObject::tr( 
"OGR" ) );
   676       OGR_Fld_SetWidth( fld.get(), ogrWidth );
   679     if ( ogrPrecision >= 0 )
   681       OGR_Fld_SetPrecision( fld.get(), ogrPrecision );
   684     switch ( attrField.
type() )
   687         OGR_Fld_SetSubType( fld.get(), OFSTBoolean );
   695                  " type " + QString( QVariant::typeToName( attrField.
type() ) ) +
   696                  " width " + QString::number( ogrWidth ) +
   697                  " precision " + QString::number( ogrPrecision ) );
   698     if ( OGR_L_CreateField( 
mLayer, fld.get(), true ) != OGRERR_NONE )
   701       mErrorMessage = QObject::tr( 
"Creation of field %1 failed (OGR error: %2)" )
   702                       .arg( attrField.
name(),
   703                             QString::fromUtf8( CPLGetLastErrorMsg() ) );
   708     int ogrIdx = OGR_FD_GetFieldIndex( defn, 
mCodec->fromUnicode( name ) );
   709     QgsDebugMsg( QStringLiteral( 
"returned field index for %1: %2" ).arg( name ).arg( ogrIdx ) );
   710     if ( ogrIdx < 0 || existingIdxs.contains( ogrIdx ) )
   713       ogrIdx = OGR_FD_GetFieldCount( defn ) - 1;
   718         mErrorMessage = QObject::tr( 
"Created field %1 not found (OGR error: %2)" )
   719                         .arg( attrField.
name(),
   720                               QString::fromUtf8( CPLGetLastErrorMsg() ) );
   726     existingIdxs.insert( ogrIdx );
   732     for ( 
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
   735       QString name( attrField.
name() );
   736       int ogrIdx = OGR_FD_GetFieldIndex( defn, 
mCodec->fromUnicode( name ) );
   746     int fidIdx = fields.
lookupField( QStringLiteral( 
"FID" ) );
   752   QgsDebugMsg( QStringLiteral( 
"Done creating fields" ) );
   757     *newFilename = vectorFileName;
   760   mUsingTransaction = 
true;
   761   if ( OGRERR_NONE != OGR_L_StartTransaction( 
mLayer ) )
   763     mUsingTransaction = 
false;
   773 class QgsVectorFileWriterMetadataContainer
   777     QgsVectorFileWriterMetadataContainer()
   779       QMap<QString, QgsVectorFileWriter::Option *> datasetOptions;
   780       QMap<QString, QgsVectorFileWriter::Option *> layerOptions;
   783       datasetOptions.clear();
   784       layerOptions.clear();
   788                                QStringLiteral( 
"Arc/Info ASCII Coverage" ),
   789                                QObject::tr( 
"Arc/Info ASCII Coverage" ),
   790                                QStringLiteral( 
"*.e00" ),
   791                                QStringLiteral( 
"e00" ),
   798       datasetOptions.clear();
   799       layerOptions.clear();
   802                                QObject::tr( 
"New BNA files are created by the "   803                                             "systems default line termination conventions. "   804                                             "This may be overridden here." ),
   806                                << QStringLiteral( 
"CRLF" )
   807                                << QStringLiteral( 
"LF" ),
   813                                QObject::tr( 
"By default, BNA files are created in multi-line format. "   814                                             "For each record, the first line contains the identifiers and the "   815                                             "type/number of coordinates to follow. Each following line contains "   816                                             "a pair of coordinates." ),
   821                                QObject::tr( 
"BNA records may contain from 2 to 4 identifiers per record. "   822                                             "Some software packages only support a precise number of identifiers. "   823                                             "You can override the default value (2) by a precise value." ),
   825                                << QStringLiteral( 
"2" )
   826                                << QStringLiteral( 
"3" )
   827                                << QStringLiteral( 
"4" )
   828                                << QStringLiteral( 
"NB_SOURCE_FIELDS" ),
   829                                QStringLiteral( 
"2" ) 
   833                                QObject::tr( 
"The BNA writer will try to recognize ellipses and circles when writing a polygon. "   834                                             "This will only work if the feature has previously been read from a BNA file. "   835                                             "As some software packages do not support ellipses/circles in BNA data file, "   836                                             "it may be useful to tell the writer by specifying ELLIPSES_AS_ELLIPSES=NO not "   837                                             "to export them as such, but keep them as polygons." ),
   842                                QObject::tr( 
"Limit the number of coordinate pairs per line in multiline format." ),
   847                                QObject::tr( 
"Set the number of decimal for coordinates. Default value is 10." ),
   853                                QStringLiteral( 
"Atlas BNA" ),
   854                                QObject::tr( 
"Atlas BNA" ),
   855                                QStringLiteral( 
"*.bna" ),
   856                                QStringLiteral( 
"bna" ),
   863       datasetOptions.clear();
   864       layerOptions.clear();
   867                              QObject::tr( 
"By default when creating new .csv files they "   868                                           "are created with the line termination conventions "   869                                           "of the local platform (CR/LF on Win32 or LF on all other systems). "   870                                           "This may be overridden through the use of the LINEFORMAT option." ),
   872                              << QStringLiteral( 
"CRLF" )
   873                              << QStringLiteral( 
"LF" ),
   879                              QObject::tr( 
"By default, the geometry of a feature written to a .csv file is discarded. "   880                                           "It is possible to export the geometry in its WKT representation by "   881                                           "specifying GEOMETRY=AS_WKT. It is also possible to export point geometries "   882                                           "into their X,Y,Z components by specifying GEOMETRY=AS_XYZ, GEOMETRY=AS_XY "   883                                           "or GEOMETRY=AS_YX." ),
   885                              << QStringLiteral( 
"AS_WKT" )
   886                              << QStringLiteral( 
"AS_XYZ" )
   887                              << QStringLiteral( 
"AS_XY" )
   888                              << QStringLiteral( 
"AS_YX" ),
   894                              QObject::tr( 
"Create the associated .csvt file to describe the type of each "   895                                           "column of the layer and its optional width and precision." ),
   900                              QObject::tr( 
"Field separator character." ),
   902                              << QStringLiteral( 
"COMMA" )
   903                              << QStringLiteral( 
"SEMICOLON" )
   904                              << QStringLiteral( 
"TAB" ),
   905                              QStringLiteral( 
"COMMA" ) 
   908 #if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0)   910                              QObject::tr( 
"Double-quote strings. IF_AMBIGUOUS means that string values that look like numbers will be quoted." ),
   912                              << QStringLiteral( 
"IF_NEEDED" )
   913                              << QStringLiteral( 
"IF_AMBIGUOUS" )
   914                              << QStringLiteral( 
"ALWAYS" ),
   915                              QStringLiteral( 
"IF_AMBIGUOUS" ) 
   920                              QObject::tr( 
"Write a UTF-8 Byte Order Mark (BOM) at the start of the file." ),
   926                                QStringLiteral( 
"Comma Separated Value [CSV]" ),
   927                                QObject::tr( 
"Comma Separated Value [CSV]" ),
   928                                QStringLiteral( 
"*.csv" ),
   929                                QStringLiteral( 
"csv" ),
   936       datasetOptions.clear();
   937       layerOptions.clear();
   940                              QObject::tr( 
"Override the type of shapefile created. "   941                                           "Can be one of NULL for a simple .dbf file with no .shp file, POINT, "   942                                           "ARC, POLYGON or MULTIPOINT for 2D, or POINTZ, ARCZ, POLYGONZ or "   943                                           "MULTIPOINTZ for 3D;" ) +
   944                              QObject::tr( 
" POINTM, ARCM, POLYGONM or MULTIPOINTM for measured geometries"   945                                           " and POINTZM, ARCZM, POLYGONZM or MULTIPOINTZM for 3D measured"   947 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
   948                              QObject::tr( 
" MULTIPATCH files are supported since GDAL 2.2." ) +
   952                              << QStringLiteral( 
"NULL" )
   953                              << QStringLiteral( 
"POINT" )
   954                              << QStringLiteral( 
"ARC" )
   955                              << QStringLiteral( 
"POLYGON" )
   956                              << QStringLiteral( 
"MULTIPOINT" )
   957                              << QStringLiteral( 
"POINTZ" )
   958                              << QStringLiteral( 
"ARCZ" )
   959                              << QStringLiteral( 
"POLYGONZ" )
   960                              << QStringLiteral( 
"MULTIPOINTZ" )
   961                              << QStringLiteral( 
"POINTM" )
   962                              << QStringLiteral( 
"ARCM" )
   963                              << QStringLiteral( 
"POLYGONM" )
   964                              << QStringLiteral( 
"MULTIPOINTM" )
   965                              << QStringLiteral( 
"POINTZM" )
   966                              << QStringLiteral( 
"ARCZM" )
   967                              << QStringLiteral( 
"POLYGONZM" )
   968                              << QStringLiteral( 
"MULTIPOINTZM" )
   969 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
   970                              << QStringLiteral( 
"MULTIPATCH" )
   981                              QObject::tr( 
"Set the encoding value in the DBF file. "   982                                           "The default value is LDID/87. It is not clear "   983                                           "what other values may be appropriate." ),
   991                              QObject::tr( 
"Set to YES to resize fields to their optimal size." ),
   997                                QStringLiteral( 
"ESRI Shapefile" ),
   998                                QObject::tr( 
"ESRI Shapefile" ),
   999                                QStringLiteral( 
"*.shp" ),
  1000                                QStringLiteral( 
"shp" ),
  1007       datasetOptions.clear();
  1008       layerOptions.clear();
  1012                                QStringLiteral( 
"DBF File" ),
  1013                                QObject::tr( 
"DBF File" ),
  1014                                QStringLiteral( 
"*.dbf" ),
  1015                                QStringLiteral( 
"dbf" ),
  1022       datasetOptions.clear();
  1023       layerOptions.clear();
  1027                                QStringLiteral( 
"FMEObjects Gateway" ),
  1028                                QObject::tr( 
"FMEObjects Gateway" ),
  1029                                QStringLiteral( 
"*.fdd" ),
  1030                                QStringLiteral( 
"fdd" ),
  1037       datasetOptions.clear();
  1038       layerOptions.clear();
  1041                              QObject::tr( 
"Set to YES to write a bbox property with the bounding box "  1042                                           "of the geometries at the feature and feature collection level." ),
  1047                              QObject::tr( 
"Maximum number of figures after decimal separator to write in coordinates. "  1048                                           "Default to 15. Truncation will occur to remove trailing zeros." ),
  1054                                QStringLiteral( 
"GeoJSON" ),
  1055                                QObject::tr( 
"GeoJSON" ),
  1056                                QStringLiteral( 
"*.geojson" ),
  1057                                QStringLiteral( 
"geojson" ),
  1060                                QStringLiteral( 
"UTF-8" )
  1065       datasetOptions.clear();
  1066       layerOptions.clear();
  1069                                QObject::tr( 
"whether the document must be in RSS 2.0 or Atom 1.0 format. "  1070                                             "Default value : RSS" ),
  1072                                << QStringLiteral( 
"RSS" )
  1073                                << QStringLiteral( 
"ATOM" ),
  1074                                QStringLiteral( 
"RSS" ) 
  1078                                QObject::tr( 
"The encoding of location information. Default value : SIMPLE. "  1079                                             "W3C_GEO only supports point geometries. "  1080                                             "SIMPLE or W3C_GEO only support geometries in geographic WGS84 coordinates." ),
  1082                                << QStringLiteral( 
"SIMPLE" )
  1083                                << QStringLiteral( 
"GML" )
  1084                                << QStringLiteral( 
"W3C_GEO" ),
  1085                                QStringLiteral( 
"SIMPLE" ) 
  1089                                QObject::tr( 
"If defined to YES, extension fields will be written. "  1090                                             "If the field name not found in the base schema matches "  1091                                             "the foo_bar pattern, foo will be considered as the namespace "  1092                                             "of the element, and a <foo:bar> element will be written. "  1093                                             "Otherwise, elements will be written in the <ogr:> namespace." ),
  1098                                QObject::tr( 
"If defined to NO, only <entry> or <item> elements will be written. "  1099                                             "The user will have to provide the appropriate header and footer of the document." ),
  1104                                QObject::tr( 
"XML content that will be put between the <channel> element and the "  1105                                             "first <item> element for a RSS document, or between the xml tag and "  1106                                             "the first <entry> element for an Atom document." ),
  1111                                QObject::tr( 
"Value put inside the <title> element in the header. "  1112                                             "If not provided, a dummy value will be used as that element is compulsory." ),
  1117                                QObject::tr( 
"Value put inside the <description> element in the header. "  1118                                             "If not provided, a dummy value will be used as that element is compulsory." ),
  1123                                QObject::tr( 
"Value put inside the <link> element in the header. "  1124                                             "If not provided, a dummy value will be used as that element is compulsory." ),
  1129                                QObject::tr( 
"Value put inside the <updated> element in the header. "  1130                                             "Should be formatted as a XML datetime. "  1131                                             "If not provided, a dummy value will be used as that element is compulsory." ),
  1136                                QObject::tr( 
"Value put inside the <author><name> element in the header. "  1137                                             "If not provided, a dummy value will be used as that element is compulsory." ),
  1142                                QObject::tr( 
"Value put inside the <id> element in the header. "  1143                                             "If not provided, a dummy value will be used as that element is compulsory." ),
  1149                                QStringLiteral( 
"GeoRSS" ),
  1150                                QObject::tr( 
"GeoRSS" ),
  1151                                QStringLiteral( 
"*.xml" ),
  1152                                QStringLiteral( 
"xml" ),
  1155                                QStringLiteral( 
"UTF-8" )
  1160       datasetOptions.clear();
  1161       layerOptions.clear();
  1164                                QObject::tr( 
"If provided, this URI will be inserted as the schema location. "  1165                                             "Note that the schema file isn't actually accessed by OGR, so it "  1166                                             "is up to the user to ensure it will match the schema of the OGR "  1167                                             "produced GML data file." ),
  1172                                QObject::tr( 
"This writes a GML application schema file to a corresponding "  1173                                             ".xsd file (with the same basename). If INTERNAL is used the "  1174                                             "schema is written within the GML file, but this is experimental "  1175                                             "and almost certainly not valid XML. "  1176                                             "OFF disables schema generation (and is implicit if XSISCHEMAURI is used)." ),
  1178                                << QStringLiteral( 
"EXTERNAL" )
  1179                                << QStringLiteral( 
"INTERNAL" )
  1180                                << QStringLiteral( 
"OFF" ),
  1181                                QStringLiteral( 
"EXTERNAL" ) 
  1185                                QObject::tr( 
"This is the prefix for the application target namespace." ),
  1186                                QStringLiteral( 
"ogr" )  
  1190                                QObject::tr( 
"Can be set to TRUE to avoid writing the prefix of the "  1191                                             "application target namespace in the GML file." ),
  1196                                QObject::tr( 
"Defaults to 'http://ogr.maptools.org/'. "  1197                                             "This is the application target namespace." ),
  1198                                QStringLiteral( 
"http://ogr.maptools.org/" )  
  1202                                QObject::tr( 
"If not specified, GML2 will be used." ),
  1204                                << QStringLiteral( 
"GML3" )
  1205                                << QStringLiteral( 
"GML3Deegree" )
  1206                                << QStringLiteral( 
"GML3.2" ),
  1212                                QObject::tr( 
"Only valid when FORMAT=GML3/GML3Degree/GML3.2. Default to YES. "   1213                                             "If YES, SRS with EPSG authority will be written with the "  1214                                             "'urn:ogc:def:crs:EPSG::' prefix. In the case the SRS is a "  1215                                             "geographic SRS without explicit AXIS order, but that the same "  1216                                             "SRS authority code imported with ImportFromEPSGA() should be "  1217                                             "treated as lat/long, then the function will take care of coordinate "  1218                                             "order swapping. If set to NO, SRS with EPSG authority will be "  1219                                             "written with the 'EPSG:' prefix, even if they are in lat/long order." ),
  1224                                QObject::tr( 
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. "  1225                                             "If set to NO, the <gml:boundedBy> element will not be written for "  1231                                QObject::tr( 
"Default to YES. If YES, the output will be indented with spaces "  1232                                             "for more readability, but at the expense of file size." ),
  1239                                QStringLiteral( 
"Geography Markup Language [GML]" ),
  1240                                QObject::tr( 
"Geography Markup Language [GML]" ),
  1241                                QStringLiteral( 
"*.gml" ),
  1242                                QStringLiteral( 
"gml" ),
  1245                                QStringLiteral( 
"UTF-8" )
  1250       datasetOptions.clear();
  1251       layerOptions.clear();
  1254                              QObject::tr( 
"Human-readable identifier (e.g. short name) for the layer content" ),
  1259                              QObject::tr( 
"Human-readable description for the layer content" ),
  1264                              QObject::tr( 
"Name for the feature identifier column" ),
  1265                              QStringLiteral( 
"fid" )  
  1269                              QObject::tr( 
"Name for the geometry column" ),
  1270                              QStringLiteral( 
"geom" )  
  1274                              QObject::tr( 
"If a spatial index must be created." ),
  1280                                QStringLiteral( 
"GeoPackage" ),
  1281                                QObject::tr( 
"GeoPackage" ),
  1282                                QStringLiteral( 
"*.gpkg" ),
  1283                                QStringLiteral( 
"gpkg" ),
  1286                                QStringLiteral( 
"UTF-8" )
  1291       datasetOptions.clear();
  1292       layerOptions.clear();
  1296                                QStringLiteral( 
"Generic Mapping Tools [GMT]" ),
  1297                                QObject::tr( 
"Generic Mapping Tools [GMT]" ),
  1298                                QStringLiteral( 
"*.gmt" ),
  1299                                QStringLiteral( 
"gmt" ),
  1306       datasetOptions.clear();
  1307       layerOptions.clear();
  1310                              QObject::tr( 
"By default when writing a layer whose features are of "  1311                                           "type wkbLineString, the GPX driver chooses to write "  1312                                           "them as routes. If FORCE_GPX_TRACK=YES is specified, "  1313                                           "they will be written as tracks." ),
  1318                              QObject::tr( 
"By default when writing a layer whose features are of "  1319                                           "type wkbMultiLineString, the GPX driver chooses to write "  1320                                           "them as tracks. If FORCE_GPX_ROUTE=YES is specified, "  1321                                           "they will be written as routes, provided that the multilines "  1322                                           "are composed of only one single line." ),
  1327                                QObject::tr( 
"If GPX_USE_EXTENSIONS=YES is specified, "  1328                                             "extra fields will be written inside the <extensions> tag." ),
  1333                                QObject::tr( 
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS_URL "  1334                                             "is set. The namespace value used for extension tags. By default, 'ogr'." ),
  1335                                QStringLiteral( 
"ogr" )  
  1339                                QObject::tr( 
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS "  1340                                             "is set. The namespace URI. By default, 'http://osgeo.org/gdal'." ),
  1341                                QStringLiteral( 
"http://osgeo.org/gdal" )  
  1345                                QObject::tr( 
"By default files are created with the line termination "  1346                                             "conventions of the local platform (CR/LF on win32 or LF "  1347                                             "on all other systems). This may be overridden through use "  1348                                             "of the LINEFORMAT layer creation option which may have a value "  1349                                             "of CRLF (DOS format) or LF (Unix format)." ),
  1351                                << QStringLiteral( 
"CRLF" )
  1352                                << QStringLiteral( 
"LF" ),
  1359                                QStringLiteral( 
"GPS eXchange Format [GPX]" ),
  1360                                QObject::tr( 
"GPS eXchange Format [GPX]" ),
  1361                                QStringLiteral( 
"*.gpx" ),
  1362                                QStringLiteral( 
"gpx" ),
  1365                                QStringLiteral( 
"UTF-8" )
  1370       datasetOptions.clear();
  1371       layerOptions.clear();
  1375                                QStringLiteral( 
"INTERLIS 1" ),
  1376                                QObject::tr( 
"INTERLIS 1" ),
  1377                                QStringLiteral( 
"*.itf *.xml *.ili" ),
  1378                                QStringLiteral( 
"ili" ),
  1385       datasetOptions.clear();
  1386       layerOptions.clear();
  1390                                QStringLiteral( 
"INTERLIS 2" ),
  1391                                QObject::tr( 
"INTERLIS 2" ),
  1392                                QStringLiteral( 
"*.xtf *.xml *.ili" ),
  1393                                QStringLiteral( 
"ili" ),
  1400       datasetOptions.clear();
  1401       layerOptions.clear();
  1404                                QObject::tr( 
"Allows you to specify the field to use for the KML <name> element." ),
  1405                                QStringLiteral( 
"Name" )  
  1409                                QObject::tr( 
"Allows you to specify the field to use for the KML <description> element." ),
  1410                                QStringLiteral( 
"Description" )  
  1414                                QObject::tr( 
"Allows you to specify the AltitudeMode to use for KML geometries. "  1415                                             "This will only affect 3D geometries and must be one of the valid KML options." ),
  1417                                << QStringLiteral( 
"clampToGround" )
  1418                                << QStringLiteral( 
"relativeToGround" )
  1419                                << QStringLiteral( 
"absolute" ),
  1420                                QStringLiteral( 
"relativeToGround" ) 
  1423 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)  1425                                QObject::tr( 
"The DOCUMENT_ID datasource creation option can be used to specified "  1426                                             "the id of the root <Document> node. The default value is root_doc." ),
  1427                                QStringLiteral( 
"root_doc" )  
  1433                                QStringLiteral( 
"Keyhole Markup Language [KML]" ),
  1434                                QObject::tr( 
"Keyhole Markup Language [KML]" ),
  1435                                QStringLiteral( 
"*.kml" ),
  1436                                QStringLiteral( 
"kml" ),
  1439                                QStringLiteral( 
"UTF-8" )
  1444       datasetOptions.clear();
  1445       layerOptions.clear();
  1447       auto insertMapInfoOptions = []( QMap<QString, QgsVectorFileWriter::Option *> &datasetOptions, QMap<QString, QgsVectorFileWriter::Option *> &layerOptions )
  1450                                  QObject::tr( 
"Use this to turn on 'quick spatial index mode'. "  1451                                               "In this mode writing files can be about 5 times faster, "  1452                                               "but spatial queries can be up to 30 times slower." ),
  1454                                  << QStringLiteral( 
"QUICK" )
  1455                                  << QStringLiteral( 
"OPTIMIZED" ),
  1456                                  QStringLiteral( 
"QUICK" ), 
  1461                                  QObject::tr( 
"(multiples of 512): Block size for .map files. Defaults "  1462                                               "to 512. MapInfo 15.2 and above creates .tab files with a "  1463                                               "blocksize of 16384 bytes. Any MapInfo version should be "  1464                                               "able to handle block sizes from 512 to 32256." ),
  1468                                QObject::tr( 
"xmin,ymin,xmax,ymax: Define custom layer bounds to increase the "  1469                                             "accuracy of the coordinates. Note: the geometry of written "  1470                                             "features must be within the defined box." ),
  1474       insertMapInfoOptions( datasetOptions, layerOptions );
  1478                                QStringLiteral( 
"Mapinfo" ),
  1479                                QObject::tr( 
"Mapinfo TAB" ),
  1480                                QStringLiteral( 
"*.tab" ),
  1481                                QStringLiteral( 
"tab" ),
  1486       datasetOptions.clear();
  1487       layerOptions.clear();
  1488       insertMapInfoOptions( datasetOptions, layerOptions );
  1493                                QStringLiteral( 
"Mapinfo" ),
  1494                                QObject::tr( 
"Mapinfo MIF" ),
  1495                                QStringLiteral( 
"*.mif" ),
  1496                                QStringLiteral( 
"mif" ),
  1503       datasetOptions.clear();
  1504       layerOptions.clear();
  1507                                QObject::tr( 
"Determine whether 2D (seed_2d.dgn) or 3D (seed_3d.dgn) "  1508                                             "seed file should be used. This option is ignored if the SEED option is provided." ),
  1513                                QObject::tr( 
"Override the seed file to use." ),
  1518                                QObject::tr( 
"Indicate whether the whole seed file should be copied. "  1519                                             "If not, only the first three elements will be copied." ),
  1524                                QObject::tr( 
"Indicates whether the color table should be copied from the seed file." ),
  1529                                QObject::tr( 
"Override the master unit name from the seed file with "  1530                                             "the provided one or two character unit name." ),
  1535                                QObject::tr( 
"Override the sub unit name from the seed file with the provided "  1536                                             "one or two character unit name." ),
  1541                                QObject::tr( 
"Override the number of subunits per master unit. "  1542                                             "By default the seed file value is used." ),
  1547                                QObject::tr( 
"Override the number of UORs (Units of Resolution) "  1548                                             "per sub unit. By default the seed file value is used." ),
  1553                                QObject::tr( 
"ORIGIN=x,y,z: Override the origin of the design plane. "  1554                                             "By default the origin from the seed file is used." ),
  1560                                QStringLiteral( 
"Microstation DGN" ),
  1561                                QObject::tr( 
"Microstation DGN" ),
  1562                                QStringLiteral( 
"*.dgn" ),
  1563                                QStringLiteral( 
"dgn" ),
  1570       datasetOptions.clear();
  1571       layerOptions.clear();
  1574                                QObject::tr( 
"Should update files be incorporated into the base data on the fly." ),
  1576                                << QStringLiteral( 
"APPLY" )
  1577                                << QStringLiteral( 
"IGNORE" ),
  1578                                QStringLiteral( 
"APPLY" ) 
  1582                                QObject::tr( 
"Should multipoint soundings be split into many single point sounding features. "  1583                                             "Multipoint geometries are not well handled by many formats, "  1584                                             "so it can be convenient to split single sounding features with many points "  1585                                             "into many single point features." ),
  1590                                QObject::tr( 
"Should a DEPTH attribute be added on SOUNDG features and assign the depth "  1591                                             "of the sounding. This should only be enabled when SPLIT_MULTIPOINT is "  1597                                QObject::tr( 
"Should all the low level geometry primitives be returned as special "  1598                                             "IsolatedNode, ConnectedNode, Edge and Face layers." ),
  1603                                QObject::tr( 
"If enabled, numeric attributes assigned an empty string as a value will "  1604                                             "be preserved as a special numeric value. This option should not generally "  1605                                             "be needed, but may be useful when translated S-57 to S-57 losslessly." ),
  1610                                QObject::tr( 
"Should LNAM and LNAM_REFS fields be attached to features capturing "  1611                                             "the feature to feature relationships in the FFPT group of the S-57 file." ),
  1616                                QObject::tr( 
"Should additional attributes relating features to their underlying "  1617                                             "geometric primitives be attached. These are the values of the FSPT group, "  1618                                             "and are primarily needed when doing S-57 to S-57 translations." ),
  1623                                QObject::tr( 
"Should attribute values be recoded to UTF-8 from the character encoding "  1624                                             "specified in the S57 DSSI record." ),
  1632                                QStringLiteral( 
"S-57 Base file" ),
  1633                                QObject::tr( 
"S-57 Base file" ),
  1634                                QStringLiteral( 
"*.000" ),
  1635                                QStringLiteral( 
"000" ),
  1642       datasetOptions.clear();
  1643       layerOptions.clear();
  1647                                QStringLiteral( 
"Spatial Data Transfer Standard [SDTS]" ),
  1648                                QObject::tr( 
"Spatial Data Transfer Standard [SDTS]" ),
  1649                                QStringLiteral( 
"*catd.ddf" ),
  1650                                QStringLiteral( 
"ddf" ),
  1657       datasetOptions.clear();
  1658       layerOptions.clear();
  1661                                QObject::tr( 
"Can be used to avoid creating the geometry_columns and spatial_ref_sys "  1662                                             "tables in a new database. By default these metadata tables are created "  1663                                             "when a new database is created." ),
  1669                                QStringLiteral( 
"NO" )
  1674                                QStringLiteral( 
"NO" )
  1678                              QObject::tr( 
"Controls the format used for the geometry column. Defaults to WKB. "  1679                                           "This is generally more space and processing efficient, but harder "  1680                                           "to inspect or use in simple applications than WKT (Well Known Text)." ),
  1682                              << QStringLiteral( 
"WKB" )
  1683                              << QStringLiteral( 
"WKT" ),
  1684                              QStringLiteral( 
"WKB" ) 
  1688                              QObject::tr( 
"Controls whether layer and field names will be laundered for easier use "  1689                                           "in SQLite. Laundered names will be converted to lower case and some special "  1690                                           "characters(' - #) will be changed to underscores." ),
  1695                              QStringLiteral( 
"NO" )
  1699                              QStringLiteral( 
"NO" )
  1707                              QObject::tr( 
"column_name1[,column_name2, ...] A list of (String) columns that "  1708                                           "must be compressed with ZLib DEFLATE algorithm. This might be beneficial "  1709                                           "for databases that have big string blobs. However, use with care, since "  1710                                           "the value of such columns will be seen as compressed binary content with "  1711                                           "other SQLite utilities (or previous OGR versions). With OGR, when inserting, "  1712                                           "modifying or querying compressed columns, compression/decompression is "  1713                                           "done transparently. However, such columns cannot be (easily) queried with "  1714                                           "an attribute filter or WHERE clause. Note: in table definition, such columns "  1715                                           "have the 'VARCHAR_deflate' declaration type." ),
  1721                                QStringLiteral( 
"SQLite" ),
  1722                                QObject::tr( 
"SQLite" ),
  1723                                QStringLiteral( 
"*.sqlite" ),
  1724                                QStringLiteral( 
"sqlite" ),
  1727                                QStringLiteral( 
"UTF-8" )
  1732       datasetOptions.clear();
  1733       layerOptions.clear();
  1736                                QObject::tr( 
"Can be used to avoid creating the geometry_columns and spatial_ref_sys "  1737                                             "tables in a new database. By default these metadata tables are created "  1738                                             "when a new database is created." ),
  1743                                QStringLiteral( 
"YES" )
  1747                                QObject::tr( 
"Insert the content of the EPSG CSV files into the spatial_ref_sys table. "  1748                                             "Set to NO for regular SQLite databases." ),
  1753                              QStringLiteral( 
"SPATIALITE" )
  1757                              QObject::tr( 
"Controls whether layer and field names will be laundered for easier use "  1758                                           "in SQLite. Laundered names will be converted to lower case and some special "  1759                                           "characters(' - #) will be changed to underscores." ),
  1764                              QObject::tr( 
"If the database is of the SpatiaLite flavor, and if OGR is linked "  1765                                           "against libspatialite, this option can be used to control if a spatial "  1766                                           "index must be created." ),
  1771                              QObject::tr( 
"If the format of the geometry BLOB is of the SpatiaLite flavor, "  1772                                           "this option can be used to control if the compressed format for "  1773                                           "geometries (LINESTRINGs, POLYGONs) must be used." ),
  1778                              QObject::tr( 
"Used to force the SRID number of the SRS associated with the layer. "  1779                                           "When this option isn't specified and that a SRS is associated with the "  1780                                           "layer, a search is made in the spatial_ref_sys to find a match for the "  1781                                           "SRS, and, if there is no match, a new entry is inserted for the SRS in "  1782                                           "the spatial_ref_sys table. When the SRID option is specified, this "  1783                                           "search (and the eventual insertion of a new entry) will not be done: "  1784                                           "the specified SRID is used as such." ),
  1789                              QObject::tr( 
"column_name1[,column_name2, ...] A list of (String) columns that "  1790                                           "must be compressed with ZLib DEFLATE algorithm. This might be beneficial "  1791                                           "for databases that have big string blobs. However, use with care, since "  1792                                           "the value of such columns will be seen as compressed binary content with "  1793                                           "other SQLite utilities (or previous OGR versions). With OGR, when inserting, "  1794                                           "modifying or queryings compressed columns, compression/decompression is "  1795                                           "done transparently. However, such columns cannot be (easily) queried with "  1796                                           "an attribute filter or WHERE clause. Note: in table definition, such columns "  1797                                           "have the 'VARCHAR_deflate' declaration type." ),
  1803                                QStringLiteral( 
"SpatiaLite" ),
  1804                                QObject::tr( 
"SpatiaLite" ),
  1805                                QStringLiteral( 
"*.sqlite" ),
  1806                                QStringLiteral( 
"sqlite" ),
  1809                                QStringLiteral( 
"UTF-8" )
  1813       datasetOptions.clear();
  1814       layerOptions.clear();
  1817                                QObject::tr( 
"Override the header file used - in place of header.dxf." ),
  1822                                QObject::tr( 
"Override the trailer file used - in place of trailer.dxf." ),
  1828                                QStringLiteral( 
"AutoCAD DXF" ),
  1829                                QObject::tr( 
"AutoCAD DXF" ),
  1830                                QStringLiteral( 
"*.dxf" ),
  1831                                QStringLiteral( 
"dxf" ),
  1838       datasetOptions.clear();
  1839       layerOptions.clear();
  1842                                QObject::tr( 
"Indicates the GeoConcept export file extension. "  1843                                             "TXT was used by earlier releases of GeoConcept. GXT is currently used." ),
  1845                                << QStringLiteral( 
"GXT" )
  1846                                << QStringLiteral( 
"TXT" ),
  1847                                QStringLiteral( 
"GXT" ) 
  1851                                QObject::tr( 
"Path to the GCT: the GCT file describes the GeoConcept types definitions: "  1852                                             "In this file, every line must start with //# followed by a keyword. "  1853                                             "Lines starting with // are comments." ),
  1858                                QObject::tr( 
"Defines the feature to be created. The TYPE corresponds to one of the Name "  1859                                             "found in the GCT file for a type section. The SUBTYPE corresponds to one of "  1860                                             "the Name found in the GCT file for a sub-type section within the previous "  1867                                QStringLiteral( 
"Geoconcept" ),
  1868                                QObject::tr( 
"Geoconcept" ),
  1869                                QStringLiteral( 
"*.gxt *.txt" ),
  1870                                QStringLiteral( 
"gxt" ),
  1877       datasetOptions.clear();
  1878       layerOptions.clear();
  1881                              QObject::tr( 
"When this option is set, the new layer will be created inside the named "  1882                                           "FeatureDataset folder. If the folder does not already exist, it will be created." ),
  1887                              QObject::tr( 
"Set name of geometry column in new layer. Defaults to 'SHAPE'." ),
  1888                              QStringLiteral( 
"SHAPE" )  
  1892                              QObject::tr( 
"Name of the OID column to create. Defaults to 'OBJECTID'." ),
  1893                              QStringLiteral( 
"OBJECTID" )  
  1898                                QStringLiteral( 
"ESRI FileGDB" ),
  1899                                QObject::tr( 
"ESRI FileGDB" ),
  1900                                QStringLiteral( 
"*.gdb" ),
  1901                                QStringLiteral( 
"gdb" ),
  1904                                QStringLiteral( 
"UTF-8" )
  1909       datasetOptions.clear();
  1910       layerOptions.clear();
  1913                              QObject::tr( 
"By default, the driver will try to detect the data type of fields. If set "  1914                                           "to STRING, all fields will be of String type." ),
  1916                              << QStringLiteral( 
"AUTO" )
  1917                              << QStringLiteral( 
"STRING" ),
  1918                              QStringLiteral( 
"AUTO" ), 
  1923                              QObject::tr( 
"By default, the driver will read the first lines of each sheet to detect "  1924                                           "if the first line might be the name of columns. If set to FORCE, the driver "  1925                                           "will consider the first line as the header line. If set to "  1926                                           "DISABLE, it will be considered as the first feature. Otherwise "  1927                                           "auto-detection will occur." ),
  1929                              << QStringLiteral( 
"FORCE" )
  1930                              << QStringLiteral( 
"DISABLE" )
  1931                              << QStringLiteral( 
"AUTO" ),
  1932                              QStringLiteral( 
"AUTO" ), 
  1938                                QStringLiteral( 
"MS Office Open XML spreadsheet" ),
  1939                                QObject::tr( 
"MS Office Open XML spreadsheet [XLSX]" ),
  1940                                QStringLiteral( 
"*.xlsx" ),
  1941                                QStringLiteral( 
"xlsx" ),
  1944                                QStringLiteral( 
"UTF-8" )
  1949       datasetOptions.clear();
  1950       layerOptions.clear();
  1953                              QObject::tr( 
"By default, the driver will try to detect the data type of fields. If set "  1954                                           "to STRING, all fields will be of String type." ),
  1956                              << QStringLiteral( 
"AUTO" )
  1957                              << QStringLiteral( 
"STRING" ),
  1958                              QStringLiteral( 
"AUTO" ), 
  1963                              QObject::tr( 
"By default, the driver will read the first lines of each sheet to detect "  1964                                           "if the first line might be the name of columns. If set to FORCE, the driver "  1965                                           "will consider the first line as the header line. If set to "  1966                                           "DISABLE, it will be considered as the first feature. Otherwise "  1967                                           "auto-detection will occur." ),
  1969                              << QStringLiteral( 
"FORCE" )
  1970                              << QStringLiteral( 
"DISABLE" )
  1971                              << QStringLiteral( 
"AUTO" ),
  1972                              QStringLiteral( 
"AUTO" ), 
  1978                                QStringLiteral( 
"Open Document Spreadsheet" ),
  1979                                QObject::tr( 
"Open Document Spreadsheet [ODS]" ),
  1980                                QStringLiteral( 
"*.ods" ),
  1981                                QStringLiteral( 
"ods" ),
  1984                                QStringLiteral( 
"UTF-8" )
  1989     QgsVectorFileWriterMetadataContainer( 
const QgsVectorFileWriterMetadataContainer &other ) = 
delete;
  1990     QgsVectorFileWriterMetadataContainer &
operator=( 
const QgsVectorFileWriterMetadataContainer &other ) = 
delete;
  1991     ~QgsVectorFileWriterMetadataContainer()
  1995         for ( 
auto optionIt = it.value().driverOptions.constBegin(); optionIt != it.value().driverOptions.constEnd(); ++optionIt )
  1996           delete optionIt.value();
  1997         for ( 
auto optionIt = it.value().layerOptions.constBegin(); optionIt != it.value().layerOptions.constEnd(); ++optionIt )
  1998           delete optionIt.value();
  2009   static QgsVectorFileWriterMetadataContainer sDriverMetadata;
  2010   QMap<QString, MetaData>::ConstIterator it = sDriverMetadata.driverMetadata.constBegin();
  2012   for ( ; it != sDriverMetadata.driverMetadata.constEnd(); ++it )
  2014     if ( it.key().startsWith( driverName ) || it.value().longName.startsWith( driverName ) )
  2016       driverMetadata = it.value();
  2029     return QStringList();
  2038     return QStringList();
  2045   OGRwkbGeometryType ogrType = 
static_cast<OGRwkbGeometryType
>( type );
  2071   QgsFeatureList::iterator fIt = features.begin();
  2073   for ( ; fIt != features.end(); ++fIt )
  2090     mRenderContext.expressionContext().setFeature( feature );
  2093     QString styleString;
  2094     QString currentStyle;
  2096     QgsSymbolList::const_iterator symbolIt = symbols.constBegin();
  2097     for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
  2099       int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
  2100       for ( 
int i = 0; i < nSymbolLayers; ++i )
  2103         QMap< QgsSymbolLayer *, QString >::const_iterator it = 
mSymbolLayerTable.find( ( *symbolIt )->symbolLayer( i ) );
  2109         double mmsf = mmScaleFactor( 
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
  2110         double musf = mapUnitScaleFactor( 
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
  2112         currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
  2116           if ( symbolIt != symbols.constBegin() || i != 0 )
  2118             styleString.append( 
';' );
  2120           styleString.append( currentStyle );
  2124           OGR_F_SetStyleString( poFeature.get(), currentStyle.toLocal8Bit().constData() );
  2125           if ( !writeFeature( 
mLayer, poFeature.get() ) )
  2132     OGR_F_SetStyleString( poFeature.get(), styleString.toLocal8Bit().constData() );
  2137     if ( !writeFeature( 
mLayer, poFeature.get() ) )
  2154   if ( fid > std::numeric_limits<int>::max() )
  2156     QgsDebugMsg( QStringLiteral( 
"feature id %1 too large." ).arg( fid ) );
  2157     OGRErr err = OGR_F_SetFID( poFeature.get(), 
static_cast<long>( fid ) );
  2158     if ( err != OGRERR_NONE )
  2160       QgsDebugMsg( QStringLiteral( 
"Failed to set feature id to %1: %2 (OGR error: %3)" )
  2161                    .arg( feature.
id() )
  2162                    .arg( err ).arg( CPLGetLastErrorMsg() )
  2170     int fldIdx = it.key();
  2171     int ogrField = it.value();
  2173     QVariant attrValue = feature.
attribute( fldIdx );
  2176     if ( !attrValue.isValid() || attrValue.isNull() )
  2185 #ifdef OGRNullMarker  2186       OGR_F_SetFieldNull( poFeature.get(), ogrField );
  2197     switch ( field.
type() )
  2200         OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
  2202       case QVariant::LongLong:
  2203         OGR_F_SetFieldInteger64( poFeature.get(), ogrField, attrValue.toLongLong() );
  2205       case QVariant::Bool:
  2206         OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
  2208       case QVariant::String:
  2209         OGR_F_SetFieldString( poFeature.get(), ogrField, 
mCodec->fromUnicode( attrValue.toString() ).constData() );
  2211       case QVariant::Double:
  2212         OGR_F_SetFieldDouble( poFeature.get(), ogrField, attrValue.toDouble() );
  2214       case QVariant::Date:
  2215         OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
  2216                                 attrValue.toDate().year(),
  2217                                 attrValue.toDate().month(),
  2218                                 attrValue.toDate().day(),
  2221       case QVariant::DateTime:
  2224           OGR_F_SetFieldString( poFeature.get(), ogrField, 
mCodec->fromUnicode( attrValue.toDateTime().toString( QStringLiteral( 
"yyyy/MM/dd hh:mm:ss.zzz" ) ) ).constData() );
  2228           OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
  2229                                   attrValue.toDateTime().date().year(),
  2230                                   attrValue.toDateTime().date().month(),
  2231                                   attrValue.toDateTime().date().day(),
  2232                                   attrValue.toDateTime().time().hour(),
  2233                                   attrValue.toDateTime().time().minute(),
  2234                                   attrValue.toDateTime().time().second(),
  2238       case QVariant::Time:
  2241           OGR_F_SetFieldString( poFeature.get(), ogrField, 
mCodec->fromUnicode( attrValue.toString() ).constData() );
  2245           OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
  2247                                   attrValue.toTime().hour(),
  2248                                   attrValue.toTime().minute(),
  2249                                   attrValue.toTime().second(),
  2253       case QVariant::Invalid:
  2256         mErrorMessage = QObject::tr( 
"Invalid variant type for field %1[%2]: received %3 with type %4" )
  2259                         .arg( attrValue.typeName(),
  2260                               attrValue.toString() );
  2283         OGRGeometryH mGeom2 = 
nullptr;
  2329           mErrorMessage = QObject::tr( 
"Feature geometry not imported (OGR error: %1)" )
  2330                           .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
  2336         QByteArray wkb( geom.
asWkb() );
  2337         OGRErr err = OGR_G_ImportFromWkb( mGeom2, reinterpret_cast<unsigned char *>( const_cast<char *>( wkb.constData() ) ), wkb.length() );
  2338         if ( err != OGRERR_NONE )
  2340           mErrorMessage = QObject::tr( 
"Feature geometry not imported (OGR error: %1)" )
  2341                           .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
  2348         OGR_F_SetGeometryDirectly( poFeature.get(), mGeom2 );
  2352         QByteArray wkb( geom.
asWkb() );
  2354         OGRErr err = OGR_G_ImportFromWkb( ogrGeom, reinterpret_cast<unsigned char *>( const_cast<char *>( wkb.constData() ) ), wkb.length() );
  2355         if ( err != OGRERR_NONE )
  2357           mErrorMessage = QObject::tr( 
"Feature geometry not imported (OGR error: %1)" )
  2358                           .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
  2365         OGR_F_SetGeometryDirectly( poFeature.get(), ogrGeom );
  2380   for ( 
int i = 0; i < attributes.size(); i++ )
  2382     if ( omap.find( i ) != omap.end() )
  2387 bool QgsVectorFileWriter::writeFeature( OGRLayerH layer, OGRFeatureH feature )
  2389   if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
  2391     mErrorMessage = QObject::tr( 
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
  2401   if ( mUsingTransaction )
  2403     if ( OGRERR_NONE != OGR_L_CommitTransaction( 
mLayer ) )
  2405       QgsDebugMsg( QStringLiteral( 
"Error while committing transaction on OGRLayer." ) );
  2413     OSRDestroySpatialReference( 
mOgrRef );
  2419     const QString &fileName,
  2420     const QString &fileEncoding,
  2422     const QString &driverName,
  2425     const QStringList &datasourceOptions,
  2426     const QStringList &layerOptions,
  2427     bool skipAttributeCreation,
  2428     QString *newFilename,
  2440   if ( destCRS.
isValid() && layer )
  2448       errorMessage, datasourceOptions, layerOptions, skipAttributeCreation,
  2449       newFilename, symbologyExport, symbologyScale, filterExtent,
  2450       overrideGeometryType, forceMulti, includeZ, attributes,
  2451       fieldValueConverter, newLayer );
  2456     const QString &fileName,
  2457     const QString &fileEncoding,
  2459     const QString &driverName,
  2462     const QStringList &datasourceOptions,
  2463     const QStringList &layerOptions,
  2464     bool skipAttributeCreation,
  2465     QString *newFilename,
  2493   return writeAsVectorFormat( layer, fileName, options, newFilename, errorMessage, newLayer );
  2498   : driverName( QStringLiteral( 
"GPKG" ) )
  2506   if ( !layer || !layer->
isValid() )
  2514   details.sourceCrs = layer->
crs();
  2515   details.sourceWkbType = layer->
wkbType();
  2516   details.sourceFields = layer->
fields();
  2525   if ( details.storageType == QLatin1String( 
"ESRI Shapefile" ) )
  2533     details.geometryTypeScanIterator = layer->
getFeatures( req );
  2537   details.renderContext.setExpressionContext( details.expressionContext );
  2538   details.renderContext.setRendererScale( options.
symbologyScale );
  2540   details.shallTransform = 
false;
  2545     details.shallTransform = 
true;
  2550     details.outputCrs = details.sourceCrs;
  2553   details.destWkbType = details.sourceWkbType;
  2567     details.attributes.clear();
  2568   else if ( details.attributes.isEmpty() )
  2570     const QgsAttributeList allAttributes = details.sourceFields.allAttributesList();
  2571     for ( 
int idx : allAttributes )
  2573       QgsField fld = details.sourceFields.at( idx );
  2574       if ( details.providerType == QLatin1String( 
"oracle" ) && fld.
typeName().contains( QLatin1String( 
"SDO_GEOMETRY" ) ) )
  2576       details.attributes.append( idx );
  2580   if ( !details.attributes.isEmpty() )
  2582     for ( 
int attrIdx : qgis::as_const( details.attributes ) )
  2584       details.outputFields.append( details.sourceFields.at( attrIdx ) );
  2590   if ( details.providerType == QLatin1String( 
"spatialite" ) )
  2592     for ( 
int i = 0; i < details.outputFields.size(); i++ )
  2594       if ( details.outputFields.at( i ).type() == QVariant::LongLong )
  2598         if ( std::max( std::llabs( min.toLongLong() ), std::llabs( max.toLongLong() ) ) < std::numeric_limits<int>::max() )
  2600           details.outputFields[i].setType( QVariant::Int );
  2608   addRendererAttributes( details.renderer.get(), details.renderContext, details.sourceFields, details.attributes );
  2618     bool useFilterRect = 
true;
  2619     if ( details.shallTransform )
  2628         useFilterRect = 
false;
  2631     if ( useFilterRect )
  2633       req.setFilterRect( filterRect );
  2637     details.filterRectEngine->prepareGeometry();
  2639   details.sourceFeatureIterator = layer->
getFeatures( req );
  2649   int lastProgressReport = 0;
  2650   long total = details.featureCount;
  2653   if ( details.providerType == QLatin1String( 
"ogr" ) && !details.dataSourceUri.isEmpty() )
  2655     QString srcFileName( details.providerUriParams.value( QLatin1String( 
"path" ) ).toString() );
  2656     if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
  2660       if ( !( ( options.
driverName == QLatin1String( 
"GPKG" ) ||
  2661                 options.
driverName == QLatin1String( 
"SpatiaLite" ) ||
  2662                 options.
driverName == QLatin1String( 
"SQLite" ) ) &&
  2663               options.
layerName != details.providerUriParams.value( QLatin1String( 
"layerName" ) ) ) )
  2666           *errorMessage = QObject::tr( 
"Cannot overwrite a OGR layer in place" );
  2686           int newProgress = 
static_cast<int>( ( 5.0 * scanned ) / total );
  2687           if ( newProgress != lastProgressReport )
  2689             lastProgressReport = newProgress;
  2704   std::unique_ptr< QgsVectorFileWriter > writer =
  2705     qgis::make_unique< QgsVectorFileWriter >( fileName,
  2706         options.
fileEncoding, details.outputFields, destWkbType,
  2728       *errorMessage = writer->errorMessage();
  2734     errorMessage->clear();
  2756   int n = 0, errors = 0;
  2765   writer->startRender( details.renderer.get(), details.sourceFields );
  2767   writer->resetMap( details.attributes );
  2769   writer->mFields = details.sourceFields;
  2773   int initialProgress = lastProgressReport;
  2774   while ( details.sourceFeatureIterator.nextFeature( fet ) )
  2785       int newProgress = 
static_cast<int>( initialProgress + ( ( 100.0 - initialProgress ) * saved ) / total );
  2786       if ( newProgress < 100 && newProgress != lastProgressReport )
  2788         lastProgressReport = newProgress;
  2793     if ( details.shallTransform )
  2806         QString msg = QObject::tr( 
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
  2807                       .arg( fet.
id() ).arg( e.
what() );
  2810           *errorMessage = msg;
  2824     if ( !writer->addFeatureWithStyle( fet, writer->mRenderer.get(), mapUnits ) )
  2827       if ( err != 
NoError && errorMessage )
  2829         if ( errorMessage->isEmpty() )
  2831           *errorMessage = QObject::tr( 
"Feature write errors:" );
  2833         *errorMessage += 
'\n' + writer->errorMessage();
  2837       if ( errors > 1000 )
  2841           *errorMessage += QObject::tr( 
"Stopping after %1 errors" ).arg( errors );
  2851   writer->stopRender();
  2853   if ( errors > 0 && errorMessage && n > 0 )
  2855     *errorMessage += QObject::tr( 
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
  2863     const QString &fileName,
  2865     QString *newFilename,
  2866     QString *errorMessage,
  2869   QgsVectorFileWriter::PreparedWriterDetails details;
  2870   WriterError err = prepareWriteAsVectorFormat( layer, options, details );
  2874   return writeAsVectorFormat( details, fileName, options, newFilename, errorMessage, newLayer );
  2880   QFileInfo fi( fileName );
  2881   QDir dir = fi.dir();
  2884   const char *suffixes[] = { 
".shp", 
".shx", 
".dbf", 
".prj", 
".qix", 
".qpj" };
  2885   for ( std::size_t i = 0; i < 
sizeof( suffixes ) / 
sizeof( *suffixes ); i++ )
  2887     filter << fi.completeBaseName() + suffixes[i];
  2891   Q_FOREACH ( 
const QString &file, dir.entryList( filter ) )
  2893     QFile f( dir.canonicalPath() + 
'/' + file );
  2896       QgsDebugMsg( QStringLiteral( 
"Removing file %1 failed: %2" ).arg( file, f.errorString() ) );
  2912   QList< FilterFormatDetails > results;
  2915   int const drvCount = OGRGetDriverCount();
  2917   for ( 
int i = 0; i < drvCount; ++i )
  2919     OGRSFDriverH drv = OGRGetDriver( i );
  2922       QString drvName = OGR_Dr_GetName( drv );
  2924 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0)  2925       GDALDriverH gdalDriver = GDALGetDriverByName( drvName.toLocal8Bit().constData() );
  2926       char **metadata = 
nullptr;
  2929         metadata = GDALGetMetadata( gdalDriver, 
nullptr );
  2932       bool nonSpatialFormat = CSLFetchBoolean( metadata, GDAL_DCAP_NONSPATIAL, 
false );
  2934       bool nonSpatialFormat = ( drvName == QLatin1String( 
"ODS" ) || drvName == QLatin1String( 
"XLSX" ) || drvName == QLatin1String( 
"XLS" ) );
  2937       if ( OGR_Dr_TestCapability( drv, 
"CreateDataSource" ) != 0 )
  2942           if ( nonSpatialFormat )
  2947         if ( filterString.isEmpty() )
  2954           globs = metadata.
glob.toLower().split( 
' ' );
  2960         details.
globs = globs;
  2971       if ( a.
driverName == QLatin1String( 
"GPKG" ) )
  2973       else if ( b.driverName == QLatin1String( 
"GPKG" ) )
  2975       else if ( a.
driverName == QLatin1String( 
"ESRI Shapefile" ) )
  2977       else if ( b.driverName == QLatin1String( 
"ESRI Shapefile" ) )
  2981     return a.
filterString.toLower().localeAwareCompare( b.filterString.toLower() ) < 0;
  2990   QSet< QString > extensions;
  2992   const QRegularExpression rx( QStringLiteral( 
"\\*\\.(.*)$" ) );
  2996     for ( 
const QString &glob : format.globs )
  2998       const QRegularExpressionMatch match = rx.match( glob );
  2999       if ( !match.hasMatch() )
  3002       const QString matched = match.captured( 1 );
  3003       extensions.insert( matched );
  3007   QStringList extensionList = extensions.toList();
  3009   std::sort( extensionList.begin(), extensionList.end(), [options]( 
const QString & a, 
const QString & b ) -> 
bool  3013       if ( a == QLatin1String( 
"gpkg" ) )
  3015       else if ( b == QLatin1String( 
"gpkg" ) )
  3017       else if ( a == QLatin1String( 
"shp" ) )
  3019       else if ( b == QLatin1String( 
"shp" ) )
  3023     return a.toLower().localeAwareCompare( b.toLower() ) < 0;
  3026   return extensionList;
  3031   QList< QgsVectorFileWriter::DriverDetails > results;
  3034   const int drvCount = OGRGetDriverCount();
  3036   QStringList writableDrivers;
  3037   for ( 
int i = 0; i < drvCount; ++i )
  3039     OGRSFDriverH drv = OGRGetDriver( i );
  3042       QString drvName = OGR_Dr_GetName( drv );
  3048         if ( drvName == QLatin1String( 
"ODS" ) || drvName == QLatin1String( 
"XLSX" ) || drvName == QLatin1String( 
"XLS" ) )
  3052       if ( drvName == QLatin1String( 
"ESRI Shapefile" ) )
  3054         writableDrivers << QStringLiteral( 
"DBF file" );
  3056       if ( OGR_Dr_TestCapability( drv, 
"CreateDataSource" ) != 0 )
  3059         if ( drvName == QLatin1String( 
"MapInfo File" ) )
  3061           writableDrivers << QStringLiteral( 
"MapInfo MIF" );
  3063         else if ( drvName == QLatin1String( 
"SQLite" ) )
  3070           QString option = QStringLiteral( 
"SPATIALITE=YES" );
  3071           char *options[2] = { CPLStrdup( option.toLocal8Bit().constData() ), 
nullptr };
  3072           OGRSFDriverH poDriver;
  3074           poDriver = OGRGetDriverByName( drvName.toLocal8Bit().constData() );
  3077             gdal::ogr_datasource_unique_ptr ds( OGR_Dr_CreateDataSource( poDriver, QStringLiteral( 
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData(), options ) );
  3080               writableDrivers << QStringLiteral( 
"SpatiaLite" );
  3081               OGR_Dr_DeleteDataSource( poDriver, QStringLiteral( 
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData() );
  3084           CPLFree( options[0] );
  3086         writableDrivers << drvName;
  3091   results.reserve( writableDrivers.count() );
  3092   for ( 
const QString &drvName : qgis::as_const( writableDrivers ) )
  3108       if ( a.
driverName == QLatin1String( 
"GPKG" ) )
  3110       else if ( b.driverName == QLatin1String( 
"GPKG" ) )
  3112       else if ( a.
driverName == QLatin1String( 
"ESRI Shapefile" ) )
  3114       else if ( b.driverName == QLatin1String( 
"ESRI Shapefile" ) )
  3118     return a.
longName.toLower().localeAwareCompare( b.longName.toLower() ) < 0;
  3125   QString ext = extension.trimmed();
  3126   if ( ext.isEmpty() )
  3129   if ( ext.startsWith( 
'.' ) )
  3133   int const drvCount = GDALGetDriverCount();
  3135   for ( 
int i = 0; i < drvCount; ++i )
  3137     GDALDriverH drv = GDALGetDriver( i );
  3141       if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, 
false ) && CSLFetchBoolean( driverMetadata, GDAL_DCAP_VECTOR, 
false ) )
  3143         QString drvName = GDALGetDriverShortName( drv );
  3144         QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS, 
nullptr ) ).split( 
' ' );
  3146         Q_FOREACH ( 
const QString &driver, driverExtensions )
  3148           if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
  3159   QString filterString;
  3163     if ( !filterString.isEmpty() )
  3164       filterString += QLatin1String( 
";;" );
  3166     filterString += details.filterString;
  3168   return filterString;
  3177   return QStringLiteral( 
"%1 (%2 %3)" ).arg( metadata.
trLongName,
  3178          metadata.
glob.toLower(),
  3179          metadata.
glob.toUpper() );
  3184   if ( codecName == QLatin1String( 
"System" ) )
  3185     return QStringLiteral( 
"LDID/0" );
  3187   QRegExp re = QRegExp( QString( 
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
  3188   if ( re.exactMatch( codecName ) )
  3190     QString 
c = re.cap( 2 ).remove( 
'-' );
  3192     c.toInt( &isNumber );
  3220   OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
  3221   OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
  3224   int nTotalLevels = 0;
  3226   QgsSymbolList::iterator symbolIt = symbolList.begin();
  3227   for ( ; symbolIt != symbolList.end(); ++symbolIt )
  3229     double mmsf = mmScaleFactor( 
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
  3230     double musf = mapUnitScaleFactor( 
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
  3232     int nLevels = ( *symbolIt )->symbolLayerCount();
  3233     for ( 
int i = 0; i < nLevels; ++i )
  3235       mSymbolLayerTable.insert( ( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
  3236       OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
  3237                        ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
  3241   OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
  3247   if ( !details.renderer )
  3250   mRenderContext.expressionContext() = details.expressionContext;
  3252   QHash< QgsSymbol *, QList<QgsFeature> > features;
  3261   startRender( details.renderer.get(), details.sourceFields );
  3272         if ( fet.hasGeometry() )
  3276           fet.setGeometry( g );
  3281         QString msg = QObject::tr( 
"Failed to transform, writing stopped. (Exception: %1)" )
  3285           *errorMessage = msg;
  3290     mRenderContext.expressionContext().setFeature( fet );
  3292     featureSymbol = mRenderer->symbolForFeature( fet, mRenderContext );
  3293     if ( !featureSymbol )
  3298     QHash< QgsSymbol *, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
  3299     if ( it == features.end() )
  3301       it = features.insert( featureSymbol, QList<QgsFeature>() );
  3303     it.value().append( fet );
  3308   QgsSymbolList symbols = mRenderer->symbols( mRenderContext );
  3309   for ( 
int i = 0; i < symbols.count(); i++ )
  3315       if ( level < 0 || level >= 1000 ) 
  3318       while ( level >= levels.count() ) 
  3320       levels[level].append( item );
  3325   int nTotalFeatures = 0;
  3328   for ( 
int l = 0; l < levels.count(); l++ )
  3331     for ( 
int i = 0; i < level.count(); i++ )
  3334       QHash< QgsSymbol *, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
  3335       if ( levelIt == features.end() )
  3341       double mmsf = mmScaleFactor( 
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
  3342       double musf = mapUnitScaleFactor( 
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
  3344       int llayer = item.
layer();
  3345       QList<QgsFeature> &featureList = levelIt.value();
  3346       QList<QgsFeature>::iterator featureIt = featureList.begin();
  3347       for ( ; featureIt != featureList.end(); ++featureIt )
  3357         QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
  3358         if ( !styleString.isEmpty() )
  3360           OGR_F_SetStyleString( ogrFeature.get(), styleString.toLocal8Bit().constData() );
  3361           if ( !writeFeature( 
mLayer, ogrFeature.get() ) )
  3372   if ( nErrors > 0 && errorMessage )
  3374     *errorMessage += QObject::tr( 
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
  3391       return 1000 / scale;
  3408       return scale / 1000;
  3416   mRenderer = createSymbologyRenderer( sourceRenderer );
  3422   mRenderer->startRender( mRenderContext,  fields );
  3425 void QgsVectorFileWriter::stopRender()
  3432   mRenderer->stopRender( mRenderContext );
  3435 std::unique_ptr<QgsFeatureRenderer> QgsVectorFileWriter::createSymbologyRenderer( 
QgsFeatureRenderer *sourceRenderer )
 const  3441   if ( !sourceRenderer )
  3446   return std::unique_ptr< QgsFeatureRenderer >( sourceRenderer->
clone() );
  3453     const QSet<QString> rendererAttributes = renderer->
usedAttributes( context );
  3454     for ( 
const QString &attr : rendererAttributes )
  3459         attList.append( index );
  3465 QStringList QgsVectorFileWriter::concatenateOptions( 
const QMap<QString, QgsVectorFileWriter::Option *> &options )
  3468   QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
  3470   for ( it = options.constBegin(); it != options.constEnd(); ++it )
  3473     switch ( option->
type )
  3480           list.append( QStringLiteral( 
"%1=%2" ).arg( it.key() ).arg( opt->
defaultValue ) );
  3490           list.append( QStringLiteral( 
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
  3500           list.append( QStringLiteral( 
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
  3509           list.append( QStringLiteral( 
"%1=%2" ).arg( it.key(), opt->
mValue ) );
  3520   OGRSFDriverH hDriver = 
nullptr;
  3524   QString drvName = OGR_Dr_GetName( hDriver );
  3525   QgsVectorFileWriter::EditionCapabilities caps = 
nullptr;
  3526   if ( OGR_DS_TestCapability( hDS.get(), ODsCCreateLayer ) )
  3531     if ( !( drvName == QLatin1String( 
"ESRI Shapefile" ) && QFile::exists( datasetName ) ) )
  3534   if ( OGR_DS_TestCapability( hDS.get(), ODsCDeleteLayer ) )
  3538   int layer_count = OGR_DS_GetLayerCount( hDS.get() );
  3541     OGRLayerH hLayer = OGR_DS_GetLayer( hDS.get(), 0 );
  3544       if ( OGR_L_TestCapability( hLayer, OLCSequentialWrite ) )
  3547         if ( OGR_L_TestCapability( hLayer, OLCCreateField ) )
  3558     const QString &layerNameIn )
  3560   OGRSFDriverH hDriver = 
nullptr;
  3566   if ( layerName.isEmpty() )
  3567     layerName = QFileInfo( datasetName ).baseName();
  3569   return OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
  3578   OGRSFDriverH hDriver = 
nullptr;
  3582   OGRLayerH hLayer = OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
  3588   OGRFeatureDefnH defn = OGR_L_GetLayerDefn( hLayer );
  3589   Q_FOREACH ( 
int idx, attributes )
  3592     if ( OGR_FD_GetFieldIndex( defn, fld.
name().toUtf8().constData() ) < 0 )
 QgsVectorFileWriter(const QString &vectorFileName, const QString &fileEncoding, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &srs=QgsCoordinateReferenceSystem(), const QString &driverName="GPKG", const QStringList &datasourceOptions=QStringList(), const QStringList &layerOptions=QStringList(), QString *newFilename=nullptr, QgsVectorFileWriter::SymbologyExport symbologyExport=QgsVectorFileWriter::NoSymbology, QgsFeatureSink::SinkFlags sinkFlags=nullptr, QString *newLayer=nullptr)
Create a new vector file writer. 
 
Append features to existing layer, but do not create new fields. 
 
Wrapper for iterator of features from vector data provider or vector layer. 
 
bool isCanceled() const 
Tells whether the operation has been canceled already. 
 
Flag to indicate that a new layer can be added to the dataset. 
 
QgsVectorFileWriter::ActionOnExistingFile actionOnExistingFile
Action on existing file. 
 
A rectangle specified with double values. 
 
QgsVectorFileWriter::OptionType type
 
Details of available driver formats. 
 
static Type to25D(Type type)
Will convert the 25D version of the flat type if supported or Unknown if not supported. 
 
static Type singleType(Type type)
Returns the single type for a WKB type. 
 
static Type multiType(Type type)
Returns the multi type for a WKB type. 
 
bool isValid() const 
Returns the status of the layer. 
 
QgsVectorFileWriter::SymbologyExport symbologyExport() const 
 
Flag to indicate that new features can be added to an existing layer. 
 
Abstract base class for all rendered symbols. 
 
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct. 
 
double symbologyScale() const 
Returns the reference scale for output. 
 
WriterError mError
Contains error value if construction was not successful. 
 
This class is a composition of two QSettings instances: 
 
static bool isMultiType(Type type)
Returns true if the WKB type is a multi type. 
 
bool forceMulti
Sets to true to force creation of multi* geometries. 
 
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error. 
 
QgsVectorFileWriter & operator=(const QgsVectorFileWriter &rh)=delete
QgsVectorFileWriter cannot be copied. 
 
Filter out any formats which do not have spatial support (e.g. those which cannot save geometries) ...
 
int symbolLayerCount() const 
Returns the total number of symbol layers contained in the symbol. 
 
QList< QgsFeature > QgsFeatureList
 
SymbologyExport mSymbologyExport
 
virtual QgsSymbolList symbols(QgsRenderContext &context) const 
Returns list of symbols used by the renderer. 
 
virtual QVariant convert(int fieldIdxInLayer, const QVariant &value)
Convert the provided value, for field fieldIdxInLayer. 
 
static void warning(const QString &msg)
Goes to qWarning. 
 
QgsAttributeList attributes
Attributes to export (empty means all unless skipAttributeCreation is set) 
 
void setProgress(double progress)
Sets the current progress for the feedback object. 
 
void setRendererScale(double scale)
Sets the renderer map scale. 
 
bool addFeatureWithStyle(QgsFeature &feature, QgsFeatureRenderer *renderer, QgsUnitTypes::DistanceUnit outputUnit=QgsUnitTypes::DistanceMeters)
Adds a feature to the currently opened data source, using the style from a specified renderer...
 
bool usingSymbolLevels() const 
 
QString toWkt() const 
Returns a WKT representation of this CRS. 
 
bool isNull() const 
Test if the rectangle is null (all coordinates zero or after call to setMinimal()). 
 
#define Q_NOWARN_DEPRECATED_PUSH
 
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched. 
 
int selectedFeatureCount() const 
Returns the number of features that are selected in this layer. 
 
QMap< QgsSymbolLayer *, QString > mSymbolLayerTable
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const 
Returns the value for setting key. 
 
static void registerOgrDrivers()
Register OGR drivers ensuring this only happens once. 
 
Container of fields for a vector layer. 
 
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value. 
 
A geometry is the spatial representation of a feature. 
 
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Returns the components (e.g. 
 
QgsUnitTypes::DistanceUnit mapUnits
 
static QString driverForExtension(const QString &extension)
Returns the OGR driver name for a specified file extension. 
 
QStringList layerOptions
List of OGR layer creation options. 
 
static bool supportsFeatureStyles(const QString &driverName)
Returns true if the specified driverName supports feature styles. 
 
FieldValueConverter()=default
Constructor. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
gdal::ogr_datasource_unique_ptr mDS
 
QgsField at(int i) const 
Gets field at particular index (must be in range 0..N-1) 
 
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension. 
 
static QgsVectorFileWriter::EditionCapabilities editionCapabilities(const QString &datasetName)
Returns edition capabilities for an existing dataset name. 
 
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
 
QgsWkbTypes::Type overrideGeometryType
Set to a valid geometry type to override the default geometry type for the layer. ...
 
QList< QgsSymbolLevel > QgsSymbolLevelOrder
 
QgsVectorFileWriter::SymbologyExport symbologyExport
Symbology to export. 
 
Create or overwrite file. 
 
~QgsVectorFileWriter() override
Close opened shapefile for writing. 
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
Flag to indicate that new fields can be added to an existing layer. Imply CanAppendToExistingLayer. 
 
bool onlySelectedFeatures
Write only selected features of layer. 
 
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const =0
Returns a list of attributes required by this renderer. 
 
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle. 
 
Options to pass to writeAsVectorFormat() 
 
void setSymbologyScale(double scale)
Set reference scale for output. 
 
const QgsAbstractGeometry * constGet() const 
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive. 
 
Type
The WKB type describes the number of dimensions a geometry has. 
 
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance. 
 
QList< QgsSymbol * > QgsSymbolList
 
QString typeName() const 
Gets the field type. 
 
QgsFields fields() const FINAL
Returns the list of fields of this layer. 
 
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) override
Adds a single feature to the sink. 
 
std::unique_ptr< std::remove_pointer< OGRFeatureH >::type, OGRFeatureDeleter > ogr_feature_unique_ptr
Scoped OGR feature. 
 
static QStringList defaultLayerOptions(const QString &driverName)
Returns a list of the default layer options for a specified driver. 
 
static bool areThereNewFieldsToCreate(const QString &datasetName, const QString &layerName, QgsVectorLayer *layer, const QgsAttributeList &attributes)
Returns whether there are among the attributes specified some that do not exist yet in the layer...
 
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched. 
 
QString driverName
Unique driver name. 
 
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields. 
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary). 
 
QStringList datasourceOptions
List of OGR data source creation options. 
 
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type. 
 
static OGRwkbGeometryType ogrTypeFromWkbType(QgsWkbTypes::Type type)
Gets the ogr geometry type from an internal QGIS wkb type enum. 
 
This class wraps a request for features to a vector layer (or directly its vector data provider)...
 
OGRGeometryH createEmptyGeometry(QgsWkbTypes::Type wkbType)
 
FieldValueConverter * mFieldValueConverter
Field value converter. 
 
virtual QString dataSourceUri(bool expandAuthConfig=false) const 
Gets the data source specification. 
 
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg". 
 
Create or overwrite layer. 
 
long featureCount(const QString &legendKey) const 
Number of features rendered with specified legend key. 
 
ActionOnExistingFile
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
 
int count() const 
Returns number of items. 
 
int renderingPass() const 
 
QgsFeatureRenderer * renderer()
Returns renderer. 
 
QString driverName
OGR driver to use. 
 
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer. 
 
Encapsulate a field in an attribute table or data source. 
 
const QgsFeatureIds & selectedFeatureIds() const 
Returns a list of the selected features IDs in this layer. 
 
static QgsVectorFileWriter::WriterError writeAsVectorFormat(QgsVectorLayer *layer, const QString &fileName, const QString &fileEncoding, const QgsCoordinateReferenceSystem &destCRS=QgsCoordinateReferenceSystem(), const QString &driverName="GPKG", bool onlySelected=false, QString *errorMessage=nullptr, const QStringList &datasourceOptions=QStringList(), const QStringList &layerOptions=QStringList(), bool skipAttributeCreation=false, QString *newFilename=nullptr, QgsVectorFileWriter::SymbologyExport symbologyExport=QgsVectorFileWriter::NoSymbology, double symbologyScale=1.0, const QgsRectangle *filterExtent=nullptr, QgsWkbTypes::Type overrideGeometryType=QgsWkbTypes::Unknown, bool forceMulti=false, bool includeZ=false, const QgsAttributeList &attributes=QgsAttributeList(), QgsVectorFileWriter::FieldValueConverter *fieldValueConverter=nullptr, QString *newLayer=nullptr)
Write contents of vector layer to an (OGR supported) vector format. 
 
QVariant minimumValue(int index) const FINAL
Returns the minimum value for an attribute column or an invalid variant in case of error...
 
int lookupField(const QString &fieldName) const 
Looks up field's index from the field name. 
 
QgsSymbolLayer * symbolLayer(int layer)
Returns a specific symbol layer contained in the symbol. 
 
QMap< int, int > mAttrIdxToOgrIdx
Map attribute indizes to OGR field indexes. 
 
QgsRectangle filterExtent
If not empty, only features intersecting the extent will be saved. 
 
OGRSpatialReferenceH mOgrRef
 
Append features to existing layer, and create new fields if needed. 
 
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive. 
 
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine. 
 
Rendering with symbol levels (i.e. implements symbols(), symbolForFeature()) 
 
DistanceUnit
Units of distance. 
 
QString errorMessage()
Retrieves error message. 
 
#define Q_NOWARN_DEPRECATED_POP
 
static QString fileFilterString(VectorFormatOptions options=SortRecommended)
Returns filter string that can be used for dialogs. 
 
bool isValid() const 
Returns whether this CRS is correctly initialized and usable. 
 
QString providerType() const 
Returns the provider type for this layer. 
 
Contains information about the context of a rendering operation. 
 
QByteArray asWkb() const 
Export the geometry to WKB. 
 
static QString convertCodecNameForEncodingOption(const QString &codecName)
Converts codec name to string passed to ENCODING layer creation option of OGR Shapefile. 
 
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g. 
 
QgsVectorFileWriter::WriterError hasError()
Checks whether there were any errors in constructor. 
 
QString fileEncoding
Encoding to use. 
 
QVariant attribute(const QString &name) const 
Lookup attribute value from attribute name. 
 
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched. 
 
QList< QgsSymbolLevelItem > QgsSymbolLevel
 
bool skipAttributeCreation
Only write geometries. 
 
double symbologyScale
Scale of symbology. 
 
virtual QgsVectorFileWriter::FieldValueConverter * clone() const 
Creates a clone of the FieldValueConverter. 
 
static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList(VectorFormatOptions options=SortRecommended)
Returns the driver list that can be used for dialogs. 
 
double mSymbologyScale
Scale for symbology export (e.g. for symbols units in map units) 
 
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value. 
 
static QStringList defaultDatasetOptions(const QString &driverName)
Returns a list of the default dataset options for a specified driver. 
 
This class represents a coordinate reference system (CRS). 
 
std::unique_ptr< std::remove_pointer< OGRFieldDefnH >::type, OGRFldDeleter > ogr_field_def_unique_ptr
Scoped OGR field definition. 
 
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry. 
 
bool hasGeometry() const 
Returns true if the feature has an associated geometry. 
 
int size() const 
Returns number of items. 
 
#define FID_TO_NUMBER(fid)
 
static bool deleteShapeFile(const QString &fileName)
Delete a shapefile (and its accompanying shx / dbf / prf) 
 
Flag to indicate that an existing layer can be deleted. 
 
QgsCoordinateTransform ct
Transform to reproject exported geometries with, or invalid transform for no transformation. 
 
Interface to convert raw field values to their user-friendly value. 
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request. 
 
bool includeZ
Sets to true to include z dimension in output. This option is only valid if overrideGeometryType is s...
 
static bool hasM(Type type)
Tests whether a WKB type contains m values. 
 
Custom exception class for Coordinate Reference System related exceptions. 
 
static QList< QgsVectorFileWriter::FilterFormatDetails > supportedFiltersAndFormats(VectorFormatOptions options=SortRecommended)
Returns a list or pairs, with format filter string as first element and OGR format key as second elem...
 
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider. 
 
QList< int > QgsAttributeList
 
SaveVectorOptions()
Constructor. 
 
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry. 
 
static bool targetLayerExists(const QString &datasetName, const QString &layerName)
Returns whether the target layer already exists. 
 
QgsVectorFileWriter::FieldValueConverter * fieldValueConverter
Field value converter. 
 
QString layerName
Layer name. If let empty, it will be derived from the filename. 
 
bool nextFeature(QgsFeature &f)
 
virtual QgsField fieldDefinition(const QgsField &field)
Returns a possibly modified field definition. 
 
std::unique_ptr< std::remove_pointer< OGRDataSourceH >::type, OGRDataSourceDeleter > ogr_datasource_unique_ptr
Scoped OGR data source. 
 
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI. 
 
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the sink. 
 
QgsFeedback * feedback
Optional feedback object allowing cancellation of layer save. 
 
QVariant maximumValue(int index) const FINAL
Returns the maximum value for an attribute column or an invalid variant in case of error...
 
Represents a vector layer which manages a vector based data sets. 
 
static Type flatType(Type type)
Returns the flat type for a WKB type. 
 
Writing was interrupted by manual cancellation. 
 
QgsWkbTypes::Type wkbType() const 
Returns type of the geometry as a WKB type (point / linestring / polygon etc.) 
 
virtual QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const 
Returns list of symbols used for rendering the feature. 
 
static QString filterForDriver(const QString &driverName)
Creates a filter for an OGR driver key. 
 
QgsWkbTypes::Type mWkbType
Geometry type which is being used. 
 
virtual QgsFeatureRenderer::Capabilities capabilities()
Returns details about internals of this renderer. 
 
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer. 
 
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry. 
 
QgsCoordinateReferenceSystem crs
 
RenderUnit
Rendering size units. 
 
QString longName
Descriptive, user friendly name for the driver. 
 
Use recommended sort order, with extremely commonly used formats listed first. 
 
static bool driverMetadata(const QString &driverName, MetaData &driverMetadata)
 
QString storageType() const 
Returns the permanent storage type for this layer as a friendly name.