44 #include <QTextStream>
48 #include <QRegularExpression>
54 #include <ogr_srs_api.h>
55 #include <cpl_error.h>
57 #include <cpl_string.h>
63 static OGRDataSourceH myOGROpen(
const char *pszName,
int bUpdate, OGRSFDriverH *phDriver )
65 OGRSFDriverH hDriver =
nullptr;
66 OGRDataSourceH hDS = OGROpen( pszName, bUpdate, &hDriver );
69 QString drvName = OGR_Dr_GetName( hDriver );
70 if ( drvName ==
"BNA" )
72 OGR_DS_Destroy( hDS );
99 const QString &vectorFileName,
100 const QString &fileEncoding,
104 const QString &driverName,
105 const QStringList &datasourceOptions,
106 const QStringList &layerOptions,
107 QString *newFilename,
109 QgsFeatureSink::SinkFlags sinkFlags,
119 init( vectorFileName, fileEncoding, fields, geometryType,
120 srs, driverName, datasourceOptions, layerOptions, newFilename,
nullptr,
125 const QString &vectorFileName,
126 const QString &fileEncoding,
130 const QString &driverName,
131 const QStringList &datasourceOptions,
132 const QStringList &layerOptions,
133 QString *newFilename,
136 const QString &layerName,
140 QgsFeatureSink::SinkFlags sinkFlags,
144 , mWkbType( geometryType )
145 , mSymbologyExport( symbologyExport )
146 , mSymbologyScale( 1.0 )
148 init( vectorFileName, fileEncoding, fields, geometryType, srs, driverName,
149 datasourceOptions, layerOptions, newFilename, fieldValueConverter,
150 layerName, action, newLayer, sinkFlags, transformContext, fieldNameSource );
154 const QString &fileName,
160 QgsFeatureSink::SinkFlags sinkFlags,
161 QString *newFilename,
175 if ( driverName == QLatin1String(
"MapInfo MIF" ) )
179 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0)
180 GDALDriverH gdalDriver = GDALGetDriverByName( driverName.toLocal8Bit().constData() );
188 return CSLFetchBoolean(
driverMetadata, GDAL_DCAP_FEATURE_STYLES,
false );
190 return driverName == QLatin1String(
"DXF" ) || driverName == QLatin1String(
"KML" ) || driverName == QLatin1String(
"MapInfo File" );
194 void QgsVectorFileWriter::init( QString vectorFileName,
195 QString fileEncoding,
199 const QString &driverName,
200 QStringList datasourceOptions,
201 QStringList layerOptions,
202 QString *newFilename,
203 FieldValueConverter *fieldValueConverter,
204 const QString &layerNameIn,
205 ActionOnExistingFile action,
206 QString *newLayer, SinkFlags sinkFlags,
211 if ( vectorFileName.isEmpty() )
218 if ( driverName == QLatin1String(
"MapInfo MIF" ) )
222 else if ( driverName == QLatin1String(
"SpatiaLite" ) )
225 if ( !datasourceOptions.contains( QStringLiteral(
"SPATIALITE=YES" ) ) )
227 datasourceOptions.append( QStringLiteral(
"SPATIALITE=YES" ) );
230 else if ( driverName == QLatin1String(
"DBF file" ) )
233 if ( !layerOptions.contains( QStringLiteral(
"SHPT=NULL" ) ) )
235 layerOptions.append( QStringLiteral(
"SHPT=NULL" ) );
245 OGRSFDriverH poDriver;
248 poDriver = OGRGetDriverByName(
mOgrDriverName.toLocal8Bit().constData() );
252 mErrorMessage = QObject::tr(
"OGR driver for '%1' not found (OGR error: %2)" )
254 QString::fromUtf8( CPLGetLastErrorMsg() ) );
264 if ( layerOptions.join( QString() ).toUpper().indexOf( QLatin1String(
"ENCODING=" ) ) == -1 )
269 if ( driverName == QLatin1String(
"ESRI Shapefile" ) && !vectorFileName.endsWith( QLatin1String(
".shp" ), Qt::CaseInsensitive ) )
271 vectorFileName += QLatin1String(
".shp" );
273 else if ( driverName == QLatin1String(
"DBF file" ) && !vectorFileName.endsWith( QLatin1String(
".dbf" ), Qt::CaseInsensitive ) )
275 vectorFileName += QLatin1String(
".dbf" );
285 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
286 QStringList allExts = metadata.ext.split(
' ', QString::SkipEmptyParts );
288 QStringList allExts = metadata.ext.split(
' ', Qt::SkipEmptyParts );
291 const auto constAllExts = allExts;
292 for (
const QString &ext : constAllExts )
294 if ( vectorFileName.endsWith(
'.' + ext, Qt::CaseInsensitive ) )
303 vectorFileName +=
'.' + allExts[0];
309 if ( vectorFileName.endsWith( QLatin1String(
".gdb" ), Qt::CaseInsensitive ) )
311 QDir dir( vectorFileName );
314 QFileInfoList fileList = dir.entryInfoList(
315 QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst );
316 const auto constFileList = fileList;
317 for (
const QFileInfo &info : constFileList )
319 QFile::remove( info.absoluteFilePath() );
322 QDir().rmdir( vectorFileName );
326 QFile::remove( vectorFileName );
331 if ( metadataFound && !metadata.compulsoryEncoding.isEmpty() )
333 if ( fileEncoding.compare( metadata.compulsoryEncoding, Qt::CaseInsensitive ) != 0 )
335 QgsDebugMsgLevel( QStringLiteral(
"forced %1 encoding for %2" ).arg( metadata.compulsoryEncoding, driverName ), 2 );
336 fileEncoding = metadata.compulsoryEncoding;
341 char **options =
nullptr;
342 if ( !datasourceOptions.isEmpty() )
344 options =
new char *[ datasourceOptions.size() + 1 ];
345 for (
int i = 0; i < datasourceOptions.size(); i++ )
347 QgsDebugMsgLevel( QStringLiteral(
"-dsco=%1" ).arg( datasourceOptions[i] ), 2 );
348 options[i] = CPLStrdup( datasourceOptions[i].toLocal8Bit().constData() );
350 options[ datasourceOptions.size()] =
nullptr;
356 mDS.reset( OGR_Dr_CreateDataSource( poDriver, vectorFileName.toUtf8().constData(), options ) );
358 mDS.reset( myOGROpen( vectorFileName.toUtf8().constData(), TRUE,
nullptr ) );
362 for (
int i = 0; i < datasourceOptions.size(); i++ )
363 CPLFree( options[i] );
372 mErrorMessage = QObject::tr(
"Creation of data source failed (OGR error: %1)" )
373 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
375 mErrorMessage = QObject::tr(
"Opening of data source in update mode failed (OGR error: %1)" )
376 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
380 QString layerName( layerNameIn );
381 if ( layerName.isEmpty() )
382 layerName = QFileInfo( vectorFileName ).baseName();
386 const int layer_count = OGR_DS_GetLayerCount(
mDS.get() );
387 for (
int i = 0; i < layer_count; i++ )
389 OGRLayerH hLayer = OGR_DS_GetLayer(
mDS.get(), i );
390 if ( EQUAL( OGR_L_GetName( hLayer ), layerName.toUtf8().constData() ) )
392 if ( OGR_DS_DeleteLayer(
mDS.get(), i ) != OGRERR_NONE )
395 mErrorMessage = QObject::tr(
"Overwriting of existing layer failed (OGR error: %1)" )
396 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
410 QgsDebugMsgLevel( QStringLiteral(
"Opened data source in update mode" ), 2 );
414 mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().constData() );
417 QgsDebugMsg(
"error finding QTextCodec for " + fileEncoding );
420 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
421 mCodec = QTextCodec::codecForName( enc.toLocal8Bit().constData() );
424 QgsDebugMsg(
"error finding QTextCodec for " + enc );
425 mCodec = QTextCodec::codecForLocale();
431 if ( driverName == QLatin1String(
"KML" ) || driverName == QLatin1String(
"LIBKML" ) || driverName == QLatin1String(
"GPX" ) )
433 if ( srs.
authid() != QLatin1String(
"EPSG:4326" ) )
446 mOgrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().constData() );
447 #if GDAL_VERSION_MAJOR >= 3
450 OSRSetAxisMappingStrategy(
mOgrRef, OAMS_TRADITIONAL_GIS_ORDER );
459 int optIndex = layerOptions.indexOf( QLatin1String(
"FEATURE_DATASET=" ) );
460 if ( optIndex != -1 )
462 layerOptions.removeAt( optIndex );
465 if ( !layerOptions.isEmpty() )
467 options =
new char *[ layerOptions.size() + 1 ];
468 for (
int i = 0; i < layerOptions.size(); i++ )
471 options[i] = CPLStrdup( layerOptions[i].toLocal8Bit().constData() );
473 options[ layerOptions.size()] =
nullptr;
477 CPLSetConfigOption(
"SHAPE_ENCODING",
"" );
481 mLayer = OGR_DS_CreateLayer(
mDS.get(), layerName.toUtf8().constData(),
mOgrRef, wkbType, options );
484 *newLayer = OGR_L_GetName(
mLayer );
485 if ( driverName == QLatin1String(
"GPX" ) )
492 if ( !EQUAL( layerName.toUtf8().constData(),
"track_points" ) &&
493 !EQUAL( layerName.toUtf8().constData(),
"route_points" ) )
495 *newLayer = QStringLiteral(
"waypoints" );
502 const char *pszForceGPXTrack
503 = CSLFetchNameValue( options,
"FORCE_GPX_TRACK" );
504 if ( pszForceGPXTrack && CPLTestBool( pszForceGPXTrack ) )
505 *newLayer = QStringLiteral(
"tracks" );
507 *newLayer = QStringLiteral(
"routes" );
514 const char *pszForceGPXRoute
515 = CSLFetchNameValue( options,
"FORCE_GPX_ROUTE" );
516 if ( pszForceGPXRoute && CPLTestBool( pszForceGPXRoute ) )
517 *newLayer = QStringLiteral(
"routes" );
519 *newLayer = QStringLiteral(
"tracks" );
529 else if ( driverName == QLatin1String(
"DGN" ) )
531 mLayer = OGR_DS_GetLayerByName(
mDS.get(),
"elements" );
535 mLayer = OGR_DS_GetLayerByName(
mDS.get(), layerName.toUtf8().constData() );
540 for (
int i = 0; i < layerOptions.size(); i++ )
541 CPLFree( options[i] );
550 QString layerName = vectorFileName.left( vectorFileName.indexOf( QLatin1String(
".shp" ), Qt::CaseInsensitive ) );
551 QFile prjFile( layerName +
".qpj" );
552 #if PROJ_VERSION_MAJOR<6
553 if ( prjFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
555 QTextStream prjStream( &prjFile );
556 prjStream << srs.
toWkt().toLocal8Bit().constData() << endl;
561 QgsDebugMsg(
"Couldn't open file " + layerName +
".qpj" );
564 if ( prjFile.exists() )
573 mErrorMessage = QObject::tr(
"Creation of layer failed (OGR error: %1)" )
574 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
576 mErrorMessage = QObject::tr(
"Opening of layer failed (OGR error: %1)" )
577 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
582 OGRFeatureDefnH defn = OGR_L_GetLayerDefn(
mLayer );
591 QSet<int> existingIdxs;
601 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
605 if ( fieldValueConverter )
607 attrField = fieldValueConverter->fieldDefinition( fields.
at( fldIdx ) );
612 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( attrField.
name() ) );
621 switch ( fieldNameSource )
624 name = attrField.
name();
628 name = !attrField.
alias().isEmpty() ? attrField.
alias() : attrField.
name();
632 OGRFieldType ogrType = OFTString;
633 int ogrWidth = attrField.
length();
634 int ogrPrecision = attrField.
precision();
635 if ( ogrPrecision > 0 )
638 switch ( attrField.
type() )
640 case QVariant::LongLong:
642 const char *pszDataTypes = GDALGetMetadataItem( poDriver, GDAL_DMD_CREATIONFIELDDATATYPES,
nullptr );
643 if ( pszDataTypes && strstr( pszDataTypes,
"Integer64" ) )
644 ogrType = OFTInteger64;
647 ogrWidth = ogrWidth > 0 && ogrWidth <= 20 ? ogrWidth : 20;
651 case QVariant::String:
653 if ( ( ogrWidth <= 0 || ogrWidth > 255 ) &&
mOgrDriverName == QLatin1String(
"ESRI Shapefile" ) )
658 ogrType = OFTInteger;
659 ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
664 ogrType = OFTInteger;
669 case QVariant::Double:
689 case QVariant::DateTime:
697 ogrType = OFTDateTime;
701 case QVariant::ByteArray:
705 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,4,0)
708 if ( attrField.
subType() == QVariant::String )
710 const char *pszDataTypes = GDALGetMetadataItem( poDriver, GDAL_DMD_CREATIONFIELDDATATYPES,
nullptr );
711 if ( pszDataTypes && strstr( pszDataTypes,
"StringList" ) )
713 ogrType = OFTStringList;
714 supportsStringList =
true;
729 mErrorMessage = QObject::tr(
"Unsupported type for field %1" )
730 .arg( attrField.
name() );
735 if (
mOgrDriverName == QLatin1String(
"SQLite" ) && name.compare( QLatin1String(
"ogc_fid" ), Qt::CaseInsensitive ) == 0 )
738 for ( i = 0; i < 10; i++ )
740 name = QStringLiteral(
"ogc_fid%1" ).arg( i );
743 for ( j = 0; j < fields.
size() && name.compare( fields.
at( j ).
name(), Qt::CaseInsensitive ) != 0; j++ )
746 if ( j == fields.
size() )
752 mErrorMessage = QObject::tr(
"No available replacement for internal fieldname ogc_fid found" ).arg( attrField.
name() );
757 QgsMessageLog::logMessage( QObject::tr(
"Reserved attribute name ogc_fid replaced with %1" ).arg( name ), QObject::tr(
"OGR" ) );
764 OGR_Fld_SetWidth( fld.get(), ogrWidth );
767 if ( ogrPrecision >= 0 )
769 OGR_Fld_SetPrecision( fld.get(), ogrPrecision );
772 switch ( attrField.
type() )
775 OGR_Fld_SetSubType( fld.get(), OFSTBoolean );
783 " type " + QString( QVariant::typeToName( attrField.
type() ) ) +
784 " width " + QString::number( ogrWidth ) +
785 " precision " + QString::number( ogrPrecision ), 2 );
786 if ( OGR_L_CreateField(
mLayer, fld.get(),
true ) != OGRERR_NONE )
789 mErrorMessage = QObject::tr(
"Creation of field %1 failed (OGR error: %2)" )
790 .arg( attrField.
name(),
791 QString::fromUtf8( CPLGetLastErrorMsg() ) );
796 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
797 QgsDebugMsgLevel( QStringLiteral(
"returned field index for %1: %2" ).arg( name ).arg( ogrIdx ), 2 );
798 if ( ogrIdx < 0 || existingIdxs.contains( ogrIdx ) )
801 ogrIdx = OGR_FD_GetFieldCount( defn ) - 1;
806 mErrorMessage = QObject::tr(
"Created field %1 not found (OGR error: %2)" )
807 .arg( attrField.
name(),
808 QString::fromUtf8( CPLGetLastErrorMsg() ) );
814 existingIdxs.insert( ogrIdx );
822 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
825 QString name( attrField.
name() );
826 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
838 int fidIdx = fields.
lookupField( QStringLiteral(
"FID" ) );
849 *newFilename = vectorFileName;
852 mUsingTransaction =
true;
853 if ( OGRERR_NONE != OGR_L_StartTransaction(
mLayer ) )
855 mUsingTransaction =
false;
865 class QgsVectorFileWriterMetadataContainer
869 QgsVectorFileWriterMetadataContainer()
871 QMap<QString, QgsVectorFileWriter::Option *> datasetOptions;
872 QMap<QString, QgsVectorFileWriter::Option *> layerOptions;
875 datasetOptions.clear();
876 layerOptions.clear();
878 driverMetadata.insert( QStringLiteral(
"AVCE00" ),
880 QStringLiteral(
"Arc/Info ASCII Coverage" ),
881 QObject::tr(
"Arc/Info ASCII Coverage" ),
882 QStringLiteral(
"*.e00" ),
883 QStringLiteral(
"e00" ),
890 datasetOptions.clear();
891 layerOptions.clear();
894 QObject::tr(
"New BNA files are created by the "
895 "systems default line termination conventions. "
896 "This may be overridden here." ),
898 << QStringLiteral(
"CRLF" )
899 << QStringLiteral(
"LF" ),
905 QObject::tr(
"By default, BNA files are created in multi-line format. "
906 "For each record, the first line contains the identifiers and the "
907 "type/number of coordinates to follow. Each following line contains "
908 "a pair of coordinates." ),
913 QObject::tr(
"BNA records may contain from 2 to 4 identifiers per record. "
914 "Some software packages only support a precise number of identifiers. "
915 "You can override the default value (2) by a precise value." ),
917 << QStringLiteral(
"2" )
918 << QStringLiteral(
"3" )
919 << QStringLiteral(
"4" )
920 << QStringLiteral(
"NB_SOURCE_FIELDS" ),
921 QStringLiteral(
"2" )
925 QObject::tr(
"The BNA writer will try to recognize ellipses and circles when writing a polygon. "
926 "This will only work if the feature has previously been read from a BNA file. "
927 "As some software packages do not support ellipses/circles in BNA data file, "
928 "it may be useful to tell the writer by specifying ELLIPSES_AS_ELLIPSES=NO not "
929 "to export them as such, but keep them as polygons." ),
934 QObject::tr(
"Limit the number of coordinate pairs per line in multiline format." ),
939 QObject::tr(
"Set the number of decimal for coordinates. Default value is 10." ),
943 driverMetadata.insert( QStringLiteral(
"BNA" ),
945 QStringLiteral(
"Atlas BNA" ),
946 QObject::tr(
"Atlas BNA" ),
947 QStringLiteral(
"*.bna" ),
948 QStringLiteral(
"bna" ),
955 datasetOptions.clear();
956 layerOptions.clear();
959 QObject::tr(
"By default when creating new .csv files they "
960 "are created with the line termination conventions "
961 "of the local platform (CR/LF on Win32 or LF on all other systems). "
962 "This may be overridden through the use of the LINEFORMAT option." ),
964 << QStringLiteral(
"CRLF" )
965 << QStringLiteral(
"LF" ),
971 QObject::tr(
"By default, the geometry of a feature written to a .csv file is discarded. "
972 "It is possible to export the geometry in its WKT representation by "
973 "specifying GEOMETRY=AS_WKT. It is also possible to export point geometries "
974 "into their X,Y,Z components by specifying GEOMETRY=AS_XYZ, GEOMETRY=AS_XY "
975 "or GEOMETRY=AS_YX." ),
977 << QStringLiteral(
"AS_WKT" )
978 << QStringLiteral(
"AS_XYZ" )
979 << QStringLiteral(
"AS_XY" )
980 << QStringLiteral(
"AS_YX" ),
986 QObject::tr(
"Create the associated .csvt file to describe the type of each "
987 "column of the layer and its optional width and precision." ),
992 QObject::tr(
"Field separator character." ),
994 << QStringLiteral(
"COMMA" )
995 << QStringLiteral(
"SEMICOLON" )
996 << QStringLiteral(
"TAB" ),
997 QStringLiteral(
"COMMA" )
1000 #if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0)
1002 QObject::tr(
"Double-quote strings. IF_AMBIGUOUS means that string values that look like numbers will be quoted." ),
1004 << QStringLiteral(
"IF_NEEDED" )
1005 << QStringLiteral(
"IF_AMBIGUOUS" )
1006 << QStringLiteral(
"ALWAYS" ),
1007 QStringLiteral(
"IF_AMBIGUOUS" )
1012 QObject::tr(
"Write a UTF-8 Byte Order Mark (BOM) at the start of the file." ),
1016 driverMetadata.insert( QStringLiteral(
"CSV" ),
1018 QStringLiteral(
"Comma Separated Value [CSV]" ),
1019 QObject::tr(
"Comma Separated Value [CSV]" ),
1020 QStringLiteral(
"*.csv" ),
1021 QStringLiteral(
"csv" ),
1027 #if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
1029 datasetOptions.clear();
1030 layerOptions.clear();
1032 driverMetadata.insert( QStringLiteral(
"FlatGeobuf" ),
1034 QStringLiteral(
"FlatGeobuf" ),
1035 QObject::tr(
"FlatGeobuf" ),
1036 QStringLiteral(
"*.fgb" ),
1037 QStringLiteral(
"fgb" ),
1045 datasetOptions.clear();
1046 layerOptions.clear();
1049 QObject::tr(
"Override the type of shapefile created. "
1050 "Can be one of NULL for a simple .dbf file with no .shp file, POINT, "
1051 "ARC, POLYGON or MULTIPOINT for 2D, or POINTZ, ARCZ, POLYGONZ or "
1052 "MULTIPOINTZ for 3D;" ) +
1053 QObject::tr(
" POINTM, ARCM, POLYGONM or MULTIPOINTM for measured geometries"
1054 " and POINTZM, ARCZM, POLYGONZM or MULTIPOINTZM for 3D measured"
1056 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
1057 QObject::tr(
" MULTIPATCH files are supported since GDAL 2.2." ) +
1061 << QStringLiteral(
"NULL" )
1062 << QStringLiteral(
"POINT" )
1063 << QStringLiteral(
"ARC" )
1064 << QStringLiteral(
"POLYGON" )
1065 << QStringLiteral(
"MULTIPOINT" )
1066 << QStringLiteral(
"POINTZ" )
1067 << QStringLiteral(
"ARCZ" )
1068 << QStringLiteral(
"POLYGONZ" )
1069 << QStringLiteral(
"MULTIPOINTZ" )
1070 << QStringLiteral(
"POINTM" )
1071 << QStringLiteral(
"ARCM" )
1072 << QStringLiteral(
"POLYGONM" )
1073 << QStringLiteral(
"MULTIPOINTM" )
1074 << QStringLiteral(
"POINTZM" )
1075 << QStringLiteral(
"ARCZM" )
1076 << QStringLiteral(
"POLYGONZM" )
1077 << QStringLiteral(
"MULTIPOINTZM" )
1078 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
1079 << QStringLiteral(
"MULTIPATCH" )
1090 QObject::tr(
"Set the encoding value in the DBF file. "
1091 "The default value is LDID/87. It is not clear "
1092 "what other values may be appropriate." ),
1100 QObject::tr(
"Set to YES to resize fields to their optimal size." ),
1104 driverMetadata.insert( QStringLiteral(
"ESRI" ),
1106 QStringLiteral(
"ESRI Shapefile" ),
1107 QObject::tr(
"ESRI Shapefile" ),
1108 QStringLiteral(
"*.shp" ),
1109 QStringLiteral(
"shp" ),
1116 datasetOptions.clear();
1117 layerOptions.clear();
1119 driverMetadata.insert( QStringLiteral(
"DBF File" ),
1121 QStringLiteral(
"DBF File" ),
1122 QObject::tr(
"DBF File" ),
1123 QStringLiteral(
"*.dbf" ),
1124 QStringLiteral(
"dbf" ),
1131 datasetOptions.clear();
1132 layerOptions.clear();
1134 driverMetadata.insert( QStringLiteral(
"FMEObjects Gateway" ),
1136 QStringLiteral(
"FMEObjects Gateway" ),
1137 QObject::tr(
"FMEObjects Gateway" ),
1138 QStringLiteral(
"*.fdd" ),
1139 QStringLiteral(
"fdd" ),
1146 datasetOptions.clear();
1147 layerOptions.clear();
1150 QObject::tr(
"Set to YES to write a bbox property with the bounding box "
1151 "of the geometries at the feature and feature collection level." ),
1156 QObject::tr(
"Maximum number of figures after decimal separator to write in coordinates. "
1157 "Defaults to 15. Truncation will occur to remove trailing zeros." ),
1162 QObject::tr(
"Whether to use RFC 7946 standard. "
1163 "If disabled GeoJSON 2008 initial version will be used. "
1164 "Default is NO (thus GeoJSON 2008). See also Documentation (via Help button)" ),
1168 driverMetadata.insert( QStringLiteral(
"GeoJSON" ),
1170 QStringLiteral(
"GeoJSON" ),
1171 QObject::tr(
"GeoJSON" ),
1172 QStringLiteral(
"*.geojson" ),
1173 QStringLiteral(
"geojson" ),
1176 QStringLiteral(
"UTF-8" )
1181 datasetOptions.clear();
1182 layerOptions.clear();
1185 QObject::tr(
"Maximum number of figures after decimal separator to write in coordinates. "
1186 "Defaults to 15. Truncation will occur to remove trailing zeros." ),
1191 QObject::tr(
"Whether to start records with the RS=0x1E character (RFC 8142 standard). "
1192 "Defaults to NO: Newline Delimited JSON (geojsonl). \n"
1193 "If set to YES: RFC 8142 standard: GeoJSON Text Sequences (geojsons)." ),
1197 driverMetadata.insert( QStringLiteral(
"GeoJSONSeq" ),
1199 QStringLiteral(
"GeoJSON - Newline Delimited" ),
1200 QObject::tr(
"GeoJSON - Newline Delimited" ),
1201 QStringLiteral(
"*.geojsonl *.geojsons *.json" ),
1202 QStringLiteral(
"json" ),
1205 QStringLiteral(
"UTF-8" )
1210 datasetOptions.clear();
1211 layerOptions.clear();
1214 QObject::tr(
"whether the document must be in RSS 2.0 or Atom 1.0 format. "
1215 "Default value : RSS" ),
1217 << QStringLiteral(
"RSS" )
1218 << QStringLiteral(
"ATOM" ),
1219 QStringLiteral(
"RSS" )
1223 QObject::tr(
"The encoding of location information. Default value : SIMPLE. "
1224 "W3C_GEO only supports point geometries. "
1225 "SIMPLE or W3C_GEO only support geometries in geographic WGS84 coordinates." ),
1227 << QStringLiteral(
"SIMPLE" )
1228 << QStringLiteral(
"GML" )
1229 << QStringLiteral(
"W3C_GEO" ),
1230 QStringLiteral(
"SIMPLE" )
1234 QObject::tr(
"If defined to YES, extension fields will be written. "
1235 "If the field name not found in the base schema matches "
1236 "the foo_bar pattern, foo will be considered as the namespace "
1237 "of the element, and a <foo:bar> element will be written. "
1238 "Otherwise, elements will be written in the <ogr:> namespace." ),
1243 QObject::tr(
"If defined to NO, only <entry> or <item> elements will be written. "
1244 "The user will have to provide the appropriate header and footer of the document." ),
1249 QObject::tr(
"XML content that will be put between the <channel> element and the "
1250 "first <item> element for a RSS document, or between the xml tag and "
1251 "the first <entry> element for an Atom document." ),
1256 QObject::tr(
"Value put inside the <title> element in the header. "
1257 "If not provided, a dummy value will be used as that element is compulsory." ),
1262 QObject::tr(
"Value put inside the <description> element in the header. "
1263 "If not provided, a dummy value will be used as that element is compulsory." ),
1268 QObject::tr(
"Value put inside the <link> element in the header. "
1269 "If not provided, a dummy value will be used as that element is compulsory." ),
1274 QObject::tr(
"Value put inside the <updated> element in the header. "
1275 "Should be formatted as a XML datetime. "
1276 "If not provided, a dummy value will be used as that element is compulsory." ),
1281 QObject::tr(
"Value put inside the <author><name> element in the header. "
1282 "If not provided, a dummy value will be used as that element is compulsory." ),
1287 QObject::tr(
"Value put inside the <id> element in the header. "
1288 "If not provided, a dummy value will be used as that element is compulsory." ),
1292 driverMetadata.insert( QStringLiteral(
"GeoRSS" ),
1294 QStringLiteral(
"GeoRSS" ),
1295 QObject::tr(
"GeoRSS" ),
1296 QStringLiteral(
"*.xml" ),
1297 QStringLiteral(
"xml" ),
1300 QStringLiteral(
"UTF-8" )
1305 datasetOptions.clear();
1306 layerOptions.clear();
1309 QObject::tr(
"If provided, this URI will be inserted as the schema location. "
1310 "Note that the schema file isn't actually accessed by OGR, so it "
1311 "is up to the user to ensure it will match the schema of the OGR "
1312 "produced GML data file." ),
1317 QObject::tr(
"This writes a GML application schema file to a corresponding "
1318 ".xsd file (with the same basename). If INTERNAL is used the "
1319 "schema is written within the GML file, but this is experimental "
1320 "and almost certainly not valid XML. "
1321 "OFF disables schema generation (and is implicit if XSISCHEMAURI is used)." ),
1323 << QStringLiteral(
"EXTERNAL" )
1324 << QStringLiteral(
"INTERNAL" )
1325 << QStringLiteral(
"OFF" ),
1326 QStringLiteral(
"EXTERNAL" )
1330 QObject::tr(
"This is the prefix for the application target namespace." ),
1331 QStringLiteral(
"ogr" )
1335 QObject::tr(
"Can be set to TRUE to avoid writing the prefix of the "
1336 "application target namespace in the GML file." ),
1341 QObject::tr(
"Defaults to 'http://ogr.maptools.org/'. "
1342 "This is the application target namespace." ),
1343 QStringLiteral(
"http://ogr.maptools.org/" )
1347 QObject::tr(
"If not specified, GML2 will be used." ),
1349 << QStringLiteral(
"GML3" )
1350 << QStringLiteral(
"GML3Deegree" )
1351 << QStringLiteral(
"GML3.2" ),
1357 QObject::tr(
"Only valid when FORMAT=GML3/GML3Degree/GML3.2. Default to YES. "
1358 "If YES, SRS with EPSG authority will be written with the "
1359 "'urn:ogc:def:crs:EPSG::' prefix. In the case the SRS is a "
1360 "geographic SRS without explicit AXIS order, but that the same "
1361 "SRS authority code imported with ImportFromEPSGA() should be "
1362 "treated as lat/long, then the function will take care of coordinate "
1363 "order swapping. If set to NO, SRS with EPSG authority will be "
1364 "written with the 'EPSG:' prefix, even if they are in lat/long order." ),
1369 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. "
1370 "If set to NO, the <gml:boundedBy> element will not be written for "
1376 QObject::tr(
"Default to YES. If YES, the output will be indented with spaces "
1377 "for more readability, but at the expense of file size." ),
1382 driverMetadata.insert( QStringLiteral(
"GML" ),
1384 QStringLiteral(
"Geography Markup Language [GML]" ),
1385 QObject::tr(
"Geography Markup Language [GML]" ),
1386 QStringLiteral(
"*.gml" ),
1387 QStringLiteral(
"gml" ),
1390 QStringLiteral(
"UTF-8" )
1395 datasetOptions.clear();
1396 layerOptions.clear();
1399 QObject::tr(
"Human-readable identifier (e.g. short name) for the layer content" ),
1404 QObject::tr(
"Human-readable description for the layer content" ),
1409 QObject::tr(
"Name for the feature identifier column" ),
1410 QStringLiteral(
"fid" )
1414 QObject::tr(
"Name for the geometry column" ),
1415 QStringLiteral(
"geom" )
1419 QObject::tr(
"If a spatial index must be created." ),
1423 driverMetadata.insert( QStringLiteral(
"GPKG" ),
1425 QStringLiteral(
"GeoPackage" ),
1426 QObject::tr(
"GeoPackage" ),
1427 QStringLiteral(
"*.gpkg" ),
1428 QStringLiteral(
"gpkg" ),
1431 QStringLiteral(
"UTF-8" )
1436 datasetOptions.clear();
1437 layerOptions.clear();
1439 driverMetadata.insert( QStringLiteral(
"GMT" ),
1441 QStringLiteral(
"Generic Mapping Tools [GMT]" ),
1442 QObject::tr(
"Generic Mapping Tools [GMT]" ),
1443 QStringLiteral(
"*.gmt" ),
1444 QStringLiteral(
"gmt" ),
1451 datasetOptions.clear();
1452 layerOptions.clear();
1455 QObject::tr(
"By default when writing a layer whose features are of "
1456 "type wkbLineString, the GPX driver chooses to write "
1457 "them as routes. If FORCE_GPX_TRACK=YES is specified, "
1458 "they will be written as tracks." ),
1463 QObject::tr(
"By default when writing a layer whose features are of "
1464 "type wkbMultiLineString, the GPX driver chooses to write "
1465 "them as tracks. If FORCE_GPX_ROUTE=YES is specified, "
1466 "they will be written as routes, provided that the multilines "
1467 "are composed of only one single line." ),
1472 QObject::tr(
"If GPX_USE_EXTENSIONS=YES is specified, "
1473 "extra fields will be written inside the <extensions> tag." ),
1478 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS_URL "
1479 "is set. The namespace value used for extension tags. By default, 'ogr'." ),
1480 QStringLiteral(
"ogr" )
1484 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS "
1485 "is set. The namespace URI. By default, 'http://osgeo.org/gdal'." ),
1486 QStringLiteral(
"http://osgeo.org/gdal" )
1490 QObject::tr(
"By default files are created with the line termination "
1491 "conventions of the local platform (CR/LF on win32 or LF "
1492 "on all other systems). This may be overridden through use "
1493 "of the LINEFORMAT layer creation option which may have a value "
1494 "of CRLF (DOS format) or LF (Unix format)." ),
1496 << QStringLiteral(
"CRLF" )
1497 << QStringLiteral(
"LF" ),
1502 driverMetadata.insert( QStringLiteral(
"GPX" ),
1504 QStringLiteral(
"GPS eXchange Format [GPX]" ),
1505 QObject::tr(
"GPS eXchange Format [GPX]" ),
1506 QStringLiteral(
"*.gpx" ),
1507 QStringLiteral(
"gpx" ),
1510 QStringLiteral(
"UTF-8" )
1515 datasetOptions.clear();
1516 layerOptions.clear();
1518 driverMetadata.insert( QStringLiteral(
"Interlis 1" ),
1520 QStringLiteral(
"INTERLIS 1" ),
1521 QObject::tr(
"INTERLIS 1" ),
1522 QStringLiteral(
"*.itf *.xml *.ili" ),
1523 QStringLiteral(
"ili" ),
1530 datasetOptions.clear();
1531 layerOptions.clear();
1533 driverMetadata.insert( QStringLiteral(
"Interlis 2" ),
1535 QStringLiteral(
"INTERLIS 2" ),
1536 QObject::tr(
"INTERLIS 2" ),
1537 QStringLiteral(
"*.xtf *.xml *.ili" ),
1538 QStringLiteral(
"ili" ),
1545 datasetOptions.clear();
1546 layerOptions.clear();
1549 QObject::tr(
"Allows you to specify the field to use for the KML <name> element." ),
1550 QStringLiteral(
"Name" )
1554 QObject::tr(
"Allows you to specify the field to use for the KML <description> element." ),
1555 QStringLiteral(
"Description" )
1559 QObject::tr(
"Allows you to specify the AltitudeMode to use for KML geometries. "
1560 "This will only affect 3D geometries and must be one of the valid KML options." ),
1562 << QStringLiteral(
"clampToGround" )
1563 << QStringLiteral(
"relativeToGround" )
1564 << QStringLiteral(
"absolute" ),
1565 QStringLiteral(
"relativeToGround" )
1568 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
1570 QObject::tr(
"The DOCUMENT_ID datasource creation option can be used to specified "
1571 "the id of the root <Document> node. The default value is root_doc." ),
1572 QStringLiteral(
"root_doc" )
1576 driverMetadata.insert( QStringLiteral(
"KML" ),
1578 QStringLiteral(
"Keyhole Markup Language [KML]" ),
1579 QObject::tr(
"Keyhole Markup Language [KML]" ),
1580 QStringLiteral(
"*.kml" ),
1581 QStringLiteral(
"kml" ),
1584 QStringLiteral(
"UTF-8" )
1589 datasetOptions.clear();
1590 layerOptions.clear();
1592 auto insertMapInfoOptions = []( QMap<QString, QgsVectorFileWriter::Option *> &datasetOptions, QMap<QString, QgsVectorFileWriter::Option *> &layerOptions )
1595 QObject::tr(
"Use this to turn on 'quick spatial index mode'. "
1596 "In this mode writing files can be about 5 times faster, "
1597 "but spatial queries can be up to 30 times slower." ),
1599 << QStringLiteral(
"QUICK" )
1600 << QStringLiteral(
"OPTIMIZED" ),
1601 QStringLiteral(
"QUICK" ),
1606 QObject::tr(
"(multiples of 512): Block size for .map files. Defaults "
1607 "to 512. MapInfo 15.2 and above creates .tab files with a "
1608 "blocksize of 16384 bytes. Any MapInfo version should be "
1609 "able to handle block sizes from 512 to 32256." ),
1613 QObject::tr(
"xmin,ymin,xmax,ymax: Define custom layer bounds to increase the "
1614 "accuracy of the coordinates. Note: the geometry of written "
1615 "features must be within the defined box." ),
1619 insertMapInfoOptions( datasetOptions, layerOptions );
1621 driverMetadata.insert( QStringLiteral(
"MapInfo File" ),
1623 QStringLiteral(
"Mapinfo" ),
1624 QObject::tr(
"Mapinfo TAB" ),
1625 QStringLiteral(
"*.tab" ),
1626 QStringLiteral(
"tab" ),
1631 datasetOptions.clear();
1632 layerOptions.clear();
1633 insertMapInfoOptions( datasetOptions, layerOptions );
1636 driverMetadata.insert( QStringLiteral(
"MapInfo MIF" ),
1638 QStringLiteral(
"Mapinfo" ),
1639 QObject::tr(
"Mapinfo MIF" ),
1640 QStringLiteral(
"*.mif" ),
1641 QStringLiteral(
"mif" ),
1648 datasetOptions.clear();
1649 layerOptions.clear();
1652 QObject::tr(
"Determine whether 2D (seed_2d.dgn) or 3D (seed_3d.dgn) "
1653 "seed file should be used. This option is ignored if the SEED option is provided." ),
1658 QObject::tr(
"Override the seed file to use." ),
1663 QObject::tr(
"Indicate whether the whole seed file should be copied. "
1664 "If not, only the first three elements will be copied." ),
1669 QObject::tr(
"Indicates whether the color table should be copied from the seed file." ),
1674 QObject::tr(
"Override the master unit name from the seed file with "
1675 "the provided one or two character unit name." ),
1680 QObject::tr(
"Override the sub unit name from the seed file with the provided "
1681 "one or two character unit name." ),
1686 QObject::tr(
"Override the number of subunits per master unit. "
1687 "By default the seed file value is used." ),
1692 QObject::tr(
"Override the number of UORs (Units of Resolution) "
1693 "per sub unit. By default the seed file value is used." ),
1698 QObject::tr(
"ORIGIN=x,y,z: Override the origin of the design plane. "
1699 "By default the origin from the seed file is used." ),
1703 driverMetadata.insert( QStringLiteral(
"DGN" ),
1705 QStringLiteral(
"Microstation DGN" ),
1706 QObject::tr(
"Microstation DGN" ),
1707 QStringLiteral(
"*.dgn" ),
1708 QStringLiteral(
"dgn" ),
1715 datasetOptions.clear();
1716 layerOptions.clear();
1719 QObject::tr(
"Should update files be incorporated into the base data on the fly." ),
1721 << QStringLiteral(
"APPLY" )
1722 << QStringLiteral(
"IGNORE" ),
1723 QStringLiteral(
"APPLY" )
1727 QObject::tr(
"Should multipoint soundings be split into many single point sounding features. "
1728 "Multipoint geometries are not well handled by many formats, "
1729 "so it can be convenient to split single sounding features with many points "
1730 "into many single point features." ),
1735 QObject::tr(
"Should a DEPTH attribute be added on SOUNDG features and assign the depth "
1736 "of the sounding. This should only be enabled when SPLIT_MULTIPOINT is "
1742 QObject::tr(
"Should all the low level geometry primitives be returned as special "
1743 "IsolatedNode, ConnectedNode, Edge and Face layers." ),
1748 QObject::tr(
"If enabled, numeric attributes assigned an empty string as a value will "
1749 "be preserved as a special numeric value. This option should not generally "
1750 "be needed, but may be useful when translated S-57 to S-57 losslessly." ),
1755 QObject::tr(
"Should LNAM and LNAM_REFS fields be attached to features capturing "
1756 "the feature to feature relationships in the FFPT group of the S-57 file." ),
1761 QObject::tr(
"Should additional attributes relating features to their underlying "
1762 "geometric primitives be attached. These are the values of the FSPT group, "
1763 "and are primarily needed when doing S-57 to S-57 translations." ),
1768 QObject::tr(
"Should attribute values be recoded to UTF-8 from the character encoding "
1769 "specified in the S57 DSSI record." ),
1775 driverMetadata.insert( QStringLiteral(
"S57" ),
1777 QStringLiteral(
"S-57 Base file" ),
1778 QObject::tr(
"S-57 Base file" ),
1779 QStringLiteral(
"*.000" ),
1780 QStringLiteral(
"000" ),
1787 datasetOptions.clear();
1788 layerOptions.clear();
1790 driverMetadata.insert( QStringLiteral(
"SDTS" ),
1792 QStringLiteral(
"Spatial Data Transfer Standard [SDTS]" ),
1793 QObject::tr(
"Spatial Data Transfer Standard [SDTS]" ),
1794 QStringLiteral(
"*catd.ddf" ),
1795 QStringLiteral(
"ddf" ),
1802 datasetOptions.clear();
1803 layerOptions.clear();
1806 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys "
1807 "tables in a new database. By default these metadata tables are created "
1808 "when a new database is created." ),
1814 QStringLiteral(
"NO" )
1819 QStringLiteral(
"NO" )
1823 QObject::tr(
"Controls the format used for the geometry column. Defaults to WKB. "
1824 "This is generally more space and processing efficient, but harder "
1825 "to inspect or use in simple applications than WKT (Well Known Text)." ),
1827 << QStringLiteral(
"WKB" )
1828 << QStringLiteral(
"WKT" ),
1829 QStringLiteral(
"WKB" )
1833 QObject::tr(
"Controls whether layer and field names will be laundered for easier use "
1834 "in SQLite. Laundered names will be converted to lower case and some special "
1835 "characters(' - #) will be changed to underscores." ),
1840 QStringLiteral(
"NO" )
1844 QStringLiteral(
"NO" )
1852 QObject::tr(
"column_name1[,column_name2, …] A list of (String) columns that "
1853 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial "
1854 "for databases that have big string blobs. However, use with care, since "
1855 "the value of such columns will be seen as compressed binary content with "
1856 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, "
1857 "modifying or querying compressed columns, compression/decompression is "
1858 "done transparently. However, such columns cannot be (easily) queried with "
1859 "an attribute filter or WHERE clause. Note: in table definition, such columns "
1860 "have the 'VARCHAR_deflate' declaration type." ),
1864 driverMetadata.insert( QStringLiteral(
"SQLite" ),
1866 QStringLiteral(
"SQLite" ),
1867 QObject::tr(
"SQLite" ),
1868 QStringLiteral(
"*.sqlite" ),
1869 QStringLiteral(
"sqlite" ),
1872 QStringLiteral(
"UTF-8" )
1877 datasetOptions.clear();
1878 layerOptions.clear();
1881 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys "
1882 "tables in a new database. By default these metadata tables are created "
1883 "when a new database is created." ),
1888 QStringLiteral(
"YES" )
1892 QObject::tr(
"Insert the content of the EPSG CSV files into the spatial_ref_sys table. "
1893 "Set to NO for regular SQLite databases." ),
1898 QStringLiteral(
"SPATIALITE" )
1902 QObject::tr(
"Controls whether layer and field names will be laundered for easier use "
1903 "in SQLite. Laundered names will be converted to lower case and some special "
1904 "characters(' - #) will be changed to underscores." ),
1909 QObject::tr(
"If the database is of the SpatiaLite flavor, and if OGR is linked "
1910 "against libspatialite, this option can be used to control if a spatial "
1911 "index must be created." ),
1916 QObject::tr(
"If the format of the geometry BLOB is of the SpatiaLite flavor, "
1917 "this option can be used to control if the compressed format for "
1918 "geometries (LINESTRINGs, POLYGONs) must be used." ),
1923 QObject::tr(
"Used to force the SRID number of the SRS associated with the layer. "
1924 "When this option isn't specified and that a SRS is associated with the "
1925 "layer, a search is made in the spatial_ref_sys to find a match for the "
1926 "SRS, and, if there is no match, a new entry is inserted for the SRS in "
1927 "the spatial_ref_sys table. When the SRID option is specified, this "
1928 "search (and the eventual insertion of a new entry) will not be done: "
1929 "the specified SRID is used as such." ),
1934 QObject::tr(
"column_name1[,column_name2, …] A list of (String) columns that "
1935 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial "
1936 "for databases that have big string blobs. However, use with care, since "
1937 "the value of such columns will be seen as compressed binary content with "
1938 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, "
1939 "modifying or queryings compressed columns, compression/decompression is "
1940 "done transparently. However, such columns cannot be (easily) queried with "
1941 "an attribute filter or WHERE clause. Note: in table definition, such columns "
1942 "have the 'VARCHAR_deflate' declaration type." ),
1946 driverMetadata.insert( QStringLiteral(
"SpatiaLite" ),
1948 QStringLiteral(
"SpatiaLite" ),
1949 QObject::tr(
"SpatiaLite" ),
1950 QStringLiteral(
"*.sqlite" ),
1951 QStringLiteral(
"sqlite" ),
1954 QStringLiteral(
"UTF-8" )
1958 datasetOptions.clear();
1959 layerOptions.clear();
1962 QObject::tr(
"Override the header file used - in place of header.dxf." ),
1967 QObject::tr(
"Override the trailer file used - in place of trailer.dxf." ),
1971 driverMetadata.insert( QStringLiteral(
"DXF" ),
1973 QStringLiteral(
"AutoCAD DXF" ),
1974 QObject::tr(
"AutoCAD DXF" ),
1975 QStringLiteral(
"*.dxf" ),
1976 QStringLiteral(
"dxf" ),
1983 datasetOptions.clear();
1984 layerOptions.clear();
1987 QObject::tr(
"Indicates the GeoConcept export file extension. "
1988 "TXT was used by earlier releases of GeoConcept. GXT is currently used." ),
1990 << QStringLiteral(
"GXT" )
1991 << QStringLiteral(
"TXT" ),
1992 QStringLiteral(
"GXT" )
1996 QObject::tr(
"Path to the GCT: the GCT file describes the GeoConcept types definitions: "
1997 "In this file, every line must start with //# followed by a keyword. "
1998 "Lines starting with // are comments." ),
2003 QObject::tr(
"Defines the feature to be created. The TYPE corresponds to one of the Name "
2004 "found in the GCT file for a type section. The SUBTYPE corresponds to one of "
2005 "the Name found in the GCT file for a sub-type section within the previous "
2010 driverMetadata.insert( QStringLiteral(
"Geoconcept" ),
2012 QStringLiteral(
"Geoconcept" ),
2013 QObject::tr(
"Geoconcept" ),
2014 QStringLiteral(
"*.gxt *.txt" ),
2015 QStringLiteral(
"gxt" ),
2022 datasetOptions.clear();
2023 layerOptions.clear();
2026 QObject::tr(
"When this option is set, the new layer will be created inside the named "
2027 "FeatureDataset folder. If the folder does not already exist, it will be created." ),
2032 QObject::tr(
"Set name of geometry column in new layer. Defaults to 'SHAPE'." ),
2033 QStringLiteral(
"SHAPE" )
2037 QObject::tr(
"Name of the OID column to create. Defaults to 'OBJECTID'." ),
2038 QStringLiteral(
"OBJECTID" )
2041 driverMetadata.insert( QStringLiteral(
"FileGDB" ),
2043 QStringLiteral(
"ESRI FileGDB" ),
2044 QObject::tr(
"ESRI FileGDB" ),
2045 QStringLiteral(
"*.gdb" ),
2046 QStringLiteral(
"gdb" ),
2049 QStringLiteral(
"UTF-8" )
2054 datasetOptions.clear();
2055 layerOptions.clear();
2058 QObject::tr(
"By default, the driver will try to detect the data type of fields. If set "
2059 "to STRING, all fields will be of String type." ),
2061 << QStringLiteral(
"AUTO" )
2062 << QStringLiteral(
"STRING" ),
2063 QStringLiteral(
"AUTO" ),
2068 QObject::tr(
"By default, the driver will read the first lines of each sheet to detect "
2069 "if the first line might be the name of columns. If set to FORCE, the driver "
2070 "will consider the first line as the header line. If set to "
2071 "DISABLE, it will be considered as the first feature. Otherwise "
2072 "auto-detection will occur." ),
2074 << QStringLiteral(
"FORCE" )
2075 << QStringLiteral(
"DISABLE" )
2076 << QStringLiteral(
"AUTO" ),
2077 QStringLiteral(
"AUTO" ),
2081 driverMetadata.insert( QStringLiteral(
"XLSX" ),
2083 QStringLiteral(
"MS Office Open XML spreadsheet" ),
2084 QObject::tr(
"MS Office Open XML spreadsheet [XLSX]" ),
2085 QStringLiteral(
"*.xlsx" ),
2086 QStringLiteral(
"xlsx" ),
2089 QStringLiteral(
"UTF-8" )
2094 datasetOptions.clear();
2095 layerOptions.clear();
2098 QObject::tr(
"By default, the driver will try to detect the data type of fields. If set "
2099 "to STRING, all fields will be of String type." ),
2101 << QStringLiteral(
"AUTO" )
2102 << QStringLiteral(
"STRING" ),
2103 QStringLiteral(
"AUTO" ),
2108 QObject::tr(
"By default, the driver will read the first lines of each sheet to detect "
2109 "if the first line might be the name of columns. If set to FORCE, the driver "
2110 "will consider the first line as the header line. If set to "
2111 "DISABLE, it will be considered as the first feature. Otherwise "
2112 "auto-detection will occur." ),
2114 << QStringLiteral(
"FORCE" )
2115 << QStringLiteral(
"DISABLE" )
2116 << QStringLiteral(
"AUTO" ),
2117 QStringLiteral(
"AUTO" ),
2121 driverMetadata.insert( QStringLiteral(
"ODS" ),
2123 QStringLiteral(
"Open Document Spreadsheet" ),
2124 QObject::tr(
"Open Document Spreadsheet [ODS]" ),
2125 QStringLiteral(
"*.ods" ),
2126 QStringLiteral(
"ods" ),
2129 QStringLiteral(
"UTF-8" )
2134 datasetOptions.clear();
2135 layerOptions.clear();
2138 QObject::tr(
"Line termination character sequence." ),
2140 << QStringLiteral(
"CRLF" )
2141 << QStringLiteral(
"LF" ),
2148 QObject::tr(
"Format of geometry columns." ),
2150 << QStringLiteral(
"geometry" )
2151 << QStringLiteral(
"geography" ),
2152 QStringLiteral(
"geometry" ),
2157 QObject::tr(
"Controls whether layer and field names will be laundered for easier use. "
2158 "Laundered names will be converted to lower case and some special "
2159 "characters(' - #) will be changed to underscores." ),
2164 QObject::tr(
"Name for the geometry column. Defaults to wkb_geometry "
2165 "for GEOM_TYPE=geometry or the_geog for GEOM_TYPE=geography" ) ) );
2168 QObject::tr(
"Name of schema into which to create the new table" ) ) );
2171 QObject::tr(
"Whether to explicitly emit the CREATE SCHEMA statement to create the specified schema." ),
2176 QObject::tr(
"Whether to explicitly recreate the table if necessary." ),
2181 QObject::tr(
"Whether to explicitly destroy tables before recreating them." ),
2183 << QStringLiteral(
"YES" )
2184 << QStringLiteral(
"NO" )
2185 << QStringLiteral(
"IF_EXISTS" ),
2186 QStringLiteral(
"YES" ),
2191 QObject::tr(
"Used to force the SRID number of the SRS associated with the layer. "
2192 "When this option isn't specified and that a SRS is associated with the "
2193 "layer, a search is made in the spatial_ref_sys to find a match for the "
2194 "SRS, and, if there is no match, a new entry is inserted for the SRS in "
2195 "the spatial_ref_sys table. When the SRID option is specified, this "
2196 "search (and the eventual insertion of a new entry) will not be done: "
2197 "the specified SRID is used as such." ),
2202 QObject::tr(
"Can be set to 2.0 or 2.2 for PostGIS 2.0/2.2 compatibility. "
2203 "Important to set it correctly if using non-linear geometry types" ),
2207 driverMetadata.insert( QStringLiteral(
"PGDUMP" ),
2209 QStringLiteral(
"PostgreSQL SQL dump" ),
2210 QObject::tr(
"PostgreSQL SQL dump" ),
2211 QStringLiteral(
"*.sql" ),
2212 QStringLiteral(
"sql" ),
2215 QStringLiteral(
"UTF-8" )
2221 QgsVectorFileWriterMetadataContainer(
const QgsVectorFileWriterMetadataContainer &other ) =
delete;
2222 QgsVectorFileWriterMetadataContainer &operator=(
const QgsVectorFileWriterMetadataContainer &other ) =
delete;
2223 ~QgsVectorFileWriterMetadataContainer()
2225 for (
auto it = driverMetadata.constBegin(); it != driverMetadata.constEnd(); ++it )
2227 for (
auto optionIt = it.value().driverOptions.constBegin(); optionIt != it.value().driverOptions.constEnd(); ++optionIt )
2228 delete optionIt.value();
2229 for (
auto optionIt = it.value().layerOptions.constBegin(); optionIt != it.value().layerOptions.constEnd(); ++optionIt )
2230 delete optionIt.value();
2234 QMap<QString, QgsVectorFileWriter::MetaData> driverMetadata;
2241 static QgsVectorFileWriterMetadataContainer sDriverMetadata;
2242 QMap<QString, MetaData>::ConstIterator it = sDriverMetadata.driverMetadata.constBegin();
2244 for ( ; it != sDriverMetadata.driverMetadata.constEnd(); ++it )
2246 if ( it.key() == QLatin1String(
"PGDUMP" ) &&
2247 driverName != QLatin1String(
"PGDUMP" ) &&
2248 driverName != QLatin1String(
"PostgreSQL SQL dump" ) )
2253 if ( it.key().startsWith( driverName ) || it.value().longName.startsWith( driverName ) )
2268 return QStringList();
2277 return QStringList();
2284 OGRwkbGeometryType ogrType =
static_cast<OGRwkbGeometryType
>( type );
2310 QgsFeatureList::iterator fIt = features.begin();
2312 for ( ; fIt != features.end(); ++fIt )
2337 QString styleString;
2338 QString currentStyle;
2340 QgsSymbolList::const_iterator symbolIt = symbols.constBegin();
2341 for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
2343 int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
2344 for (
int i = 0; i < nSymbolLayers; ++i )
2347 QMap< QgsSymbolLayer *, QString >::const_iterator it =
mSymbolLayerTable.find( ( *symbolIt )->symbolLayer( i ) );
2353 double mmsf = mmScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
2354 double musf = mapUnitScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
2356 currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
2360 if ( symbolIt != symbols.constBegin() || i != 0 )
2362 styleString.append(
';' );
2364 styleString.append( currentStyle );
2368 OGR_F_SetStyleString( poFeature.get(), currentStyle.toLocal8Bit().constData() );
2369 if ( !writeFeature(
mLayer, poFeature.get() ) )
2376 OGR_F_SetStyleString( poFeature.get(), styleString.toLocal8Bit().constData() );
2381 if ( !writeFeature(
mLayer, poFeature.get() ) )
2398 if ( fid > std::numeric_limits<int>::max() )
2400 QgsDebugMsg( QStringLiteral(
"feature id %1 too large." ).arg( fid ) );
2401 OGRErr err = OGR_F_SetFID( poFeature.get(),
static_cast<long>( fid ) );
2402 if ( err != OGRERR_NONE )
2404 QgsDebugMsg( QStringLiteral(
"Failed to set feature id to %1: %2 (OGR error: %3)" )
2405 .arg( feature.
id() )
2406 .arg( err ).arg( CPLGetLastErrorMsg() )
2414 int fldIdx = it.key();
2415 int ogrField = it.value();
2417 QVariant attrValue = feature.
attribute( fldIdx );
2420 if ( !attrValue.isValid() || attrValue.isNull() )
2429 #ifdef OGRNullMarker
2430 OGR_F_SetFieldNull( poFeature.get(), ogrField );
2445 mErrorMessage = QObject::tr(
"Error converting value (%1) for attribute field %2: %3" )
2446 .arg( feature.
attribute( fldIdx ).toString(),
2456 OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
2458 case QVariant::LongLong:
2459 OGR_F_SetFieldInteger64( poFeature.get(), ogrField, attrValue.toLongLong() );
2461 case QVariant::Bool:
2462 OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
2464 case QVariant::String:
2465 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toString() ).constData() );
2467 case QVariant::Double:
2468 OGR_F_SetFieldDouble( poFeature.get(), ogrField, attrValue.toDouble() );
2470 case QVariant::Date:
2471 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2472 attrValue.toDate().year(),
2473 attrValue.toDate().month(),
2474 attrValue.toDate().day(),
2477 case QVariant::DateTime:
2480 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toDateTime().toString( QStringLiteral(
"yyyy/MM/dd hh:mm:ss.zzz" ) ) ).constData() );
2484 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2485 attrValue.toDateTime().date().year(),
2486 attrValue.toDateTime().date().month(),
2487 attrValue.toDateTime().date().day(),
2488 attrValue.toDateTime().time().hour(),
2489 attrValue.toDateTime().time().minute(),
2490 attrValue.toDateTime().time().second(),
2494 case QVariant::Time:
2497 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toString() ).constData() );
2501 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2503 attrValue.toTime().hour(),
2504 attrValue.toTime().minute(),
2505 attrValue.toTime().second(),
2510 case QVariant::ByteArray:
2512 const QByteArray ba = attrValue.toByteArray();
2513 OGR_F_SetFieldBinary( poFeature.get(), ogrField, ba.size(),
const_cast< GByte *
>(
reinterpret_cast< const GByte *
>( ba.data() ) ) );
2517 case QVariant::Invalid:
2520 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,4,0)
2521 case QVariant::List:
2525 QStringList list = attrValue.toStringList();
2526 if ( supportsStringList )
2528 int count = list.count();
2529 char **lst =
new char *[count + 1];
2533 for ( QString
string : list )
2535 lst[pos] =
mCodec->fromUnicode(
string ).data();
2539 lst[count] =
nullptr;
2540 OGR_F_SetFieldStringList( poFeature.get(), ogrField, lst );
2544 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( list.join(
',' ) ).constData() );
2553 mErrorMessage = QObject::tr(
"Invalid variant type for field %1[%2]: received %3 with type %4" )
2556 .arg( attrValue.typeName(),
2557 attrValue.toString() );
2570 if ( mCoordinateTransform )
2575 geom.
transform( *mCoordinateTransform );
2593 OGRGeometryH mGeom2 =
nullptr;
2639 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2640 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2646 QByteArray wkb( geom.
asWkb() );
2647 OGRErr err = OGR_G_ImportFromWkb( mGeom2,
reinterpret_cast<unsigned char *
>(
const_cast<char *
>( wkb.constData() ) ), wkb.length() );
2648 if ( err != OGRERR_NONE )
2650 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2651 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2658 OGR_F_SetGeometryDirectly( poFeature.get(), mGeom2 );
2664 OGRErr err = OGR_G_ImportFromWkb( ogrGeom,
reinterpret_cast<unsigned char *
>(
const_cast<char *
>( wkb.constData() ) ), wkb.length() );
2665 if ( err != OGRERR_NONE )
2667 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2668 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2675 OGR_F_SetGeometryDirectly( poFeature.get(), ogrGeom );
2690 for (
int i = 0; i < attributes.size(); i++ )
2692 if ( omap.find( i ) != omap.end() )
2697 bool QgsVectorFileWriter::writeFeature( OGRLayerH layer, OGRFeatureH feature )
2699 if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
2701 mErrorMessage = QObject::tr(
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2711 if ( mUsingTransaction )
2713 if ( OGRERR_NONE != OGR_L_CommitTransaction(
mLayer ) )
2715 QgsDebugMsg( QStringLiteral(
"Error while committing transaction on OGRLayer." ) );
2719 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0) && GDAL_VERSION_NUM <= GDAL_COMPUTE_VERSION(3,1,3)
2723 QString drvName = GDALGetDriverShortName( GDALGetDatasetDriver(
mDS.get() ) );
2724 if ( drvName == QLatin1String(
"XLSX" ) ||
2725 drvName == QLatin1String(
"ODS" ) )
2727 CPLSetThreadLocalConfigOption(
"CPL_CREATE_ZIP64",
"NO" );
2729 CPLSetThreadLocalConfigOption(
"CPL_CREATE_ZIP64",
nullptr );
2738 OSRDestroySpatialReference(
mOgrRef );
2744 const QString &fileName,
2745 const QString &fileEncoding,
2747 const QString &driverName,
2749 QString *errorMessage,
2750 const QStringList &datasourceOptions,
2751 const QStringList &layerOptions,
2752 bool skipAttributeCreation,
2753 QString *newFilename,
2755 double symbologyScale,
2765 if ( destCRS.
isValid() && layer )
2791 const QString &fileName,
2792 const QString &fileEncoding,
2794 const QString &driverName,
2796 QString *errorMessage,
2797 const QStringList &datasourceOptions,
2798 const QStringList &layerOptions,
2799 bool skipAttributeCreation,
2800 QString *newFilename,
2802 double symbologyScale,
2833 : driverName( QStringLiteral(
"GPKG" ) )
2841 if ( !layer || !layer->
isValid() )
2848 details.sourceCrs = layer->
crs();
2849 details.sourceWkbType = layer->
wkbType();
2850 details.sourceFields = layer->
fields();
2859 if ( details.storageType == QLatin1String(
"ESRI Shapefile" ) )
2867 details.geometryTypeScanIterator = layer->
getFeatures( req );
2871 details.renderContext.setExpressionContext( details.expressionContext );
2872 details.renderContext.setRendererScale( options.
symbologyScale );
2874 details.shallTransform =
false;
2879 details.shallTransform =
true;
2884 details.outputCrs = details.sourceCrs;
2887 details.destWkbType = details.sourceWkbType;
2901 details.attributes.clear();
2902 else if ( details.attributes.isEmpty() )
2904 const QgsAttributeList allAttributes = details.sourceFields.allAttributesList();
2905 for (
int idx : allAttributes )
2907 QgsField fld = details.sourceFields.at( idx );
2908 if ( details.providerType == QLatin1String(
"oracle" ) && fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) )
2910 details.attributes.append( idx );
2914 if ( !details.attributes.isEmpty() )
2916 for (
int attrIdx : qgis::as_const( details.attributes ) )
2918 details.outputFields.append( details.sourceFields.at( attrIdx ) );
2924 if ( details.providerType == QLatin1String(
"spatialite" ) )
2926 for (
int i = 0; i < details.outputFields.size(); i++ )
2928 if ( details.outputFields.at( i ).type() == QVariant::LongLong )
2932 if ( std::max( std::llabs( min.toLongLong() ), std::llabs( max.toLongLong() ) ) < std::numeric_limits<int>::max() )
2934 details.outputFields[i].setType( QVariant::Int );
2942 addRendererAttributes( details.renderer.get(), details.renderContext, details.sourceFields, details.attributes );
2952 bool useFilterRect =
true;
2953 if ( details.shallTransform )
2962 useFilterRect =
false;
2965 if ( useFilterRect )
2971 details.filterRectEngine->prepareGeometry();
2973 details.sourceFeatureIterator = layer->
getFeatures( req );
2987 int lastProgressReport = 0;
2988 long total = details.featureCount;
2991 if ( details.providerType == QLatin1String(
"ogr" ) && !details.dataSourceUri.isEmpty() )
2993 QString srcFileName( details.providerUriParams.value( QLatin1String(
"path" ) ).toString() );
2994 if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
2998 if ( !( ( options.
driverName == QLatin1String(
"GPKG" ) ||
2999 options.
driverName == QLatin1String(
"SpatiaLite" ) ||
3000 options.
driverName == QLatin1String(
"SQLite" ) ) &&
3001 options.
layerName != details.providerUriParams.value( QLatin1String(
"layerName" ) ) ) )
3004 *
errorMessage = QObject::tr(
"Cannot overwrite a OGR layer in place" );
3024 int newProgress =
static_cast<int>( ( 5.0 * scanned ) / total );
3025 if ( newProgress != lastProgressReport )
3027 lastProgressReport = newProgress;
3042 std::unique_ptr< QgsVectorFileWriter > writer(
create( fileName, details.outputFields, destWkbType, details.outputCrs, transformContext, options, QgsFeatureSink::SinkFlags(), newFilename, newLayer ) );
3083 int n = 0, errors = 0;
3092 writer->startRender( details.renderer.get(), details.sourceFields );
3094 writer->resetMap( details.attributes );
3096 writer->mFields = details.sourceFields;
3100 int initialProgress = lastProgressReport;
3101 while ( details.sourceFeatureIterator.nextFeature( fet ) )
3112 int newProgress =
static_cast<int>( initialProgress + ( ( 100.0 - initialProgress ) * saved ) / total );
3113 if ( newProgress < 100 && newProgress != lastProgressReport )
3115 lastProgressReport = newProgress;
3120 if ( details.shallTransform )
3133 QString msg = QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
3134 .arg( fet.
id() ).arg( e.
what() );
3151 if ( !writer->addFeatureWithStyle( fet, writer->mRenderer.get(), mapUnits ) )
3158 *
errorMessage = QObject::tr(
"Feature write errors:" );
3164 if ( errors > 1000 )
3168 *
errorMessage += QObject::tr(
"Stopping after %1 errors" ).arg( errors );
3178 writer->stopRender();
3182 *
errorMessage += QObject::tr(
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
3189 const QString &fileName,
3191 QString *newFilename,
3195 QgsVectorFileWriter::PreparedWriterDetails details;
3196 WriterError err = prepareWriteAsVectorFormat( layer, options, details );
3204 const QString &fileName,
3207 QString *newFilename,
3211 QgsVectorFileWriter::PreparedWriterDetails details;
3212 WriterError err = prepareWriteAsVectorFormat( layer, options, details );
3221 QFileInfo fi( fileName );
3222 QDir dir = fi.dir();
3225 const char *suffixes[] = {
".shp",
".shx",
".dbf",
".prj",
".qix",
".qpj",
".cpg",
".sbn",
".sbx",
".idm",
".ind" };
3226 for ( std::size_t i = 0; i <
sizeof( suffixes ) /
sizeof( *suffixes ); i++ )
3228 filter << fi.completeBaseName() + suffixes[i];
3232 const auto constEntryList = dir.entryList( filter );
3233 for (
const QString &file : constEntryList )
3235 QFile f( dir.canonicalPath() +
'/' + file );
3238 QgsDebugMsg( QStringLiteral(
"Removing file %1 failed: %2" ).arg( file, f.errorString() ) );
3254 static QReadWriteLock sFilterLock;
3255 static QMap< VectorFormatOptions, QList< QgsVectorFileWriter::FilterFormatDetails > > sFilters;
3259 const auto it = sFilters.constFind( options );
3260 if ( it != sFilters.constEnd() )
3264 QList< QgsVectorFileWriter::FilterFormatDetails > results;
3267 int const drvCount = OGRGetDriverCount();
3269 for (
int i = 0; i < drvCount; ++i )
3271 OGRSFDriverH drv = OGRGetDriver( i );
3274 QString drvName = OGR_Dr_GetName( drv );
3276 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0)
3277 GDALDriverH gdalDriver = GDALGetDriverByName( drvName.toLocal8Bit().constData() );
3278 char **metadata =
nullptr;
3281 metadata = GDALGetMetadata( gdalDriver,
nullptr );
3284 bool nonSpatialFormat = CSLFetchBoolean( metadata, GDAL_DCAP_NONSPATIAL,
false );
3286 bool nonSpatialFormat = ( drvName == QLatin1String(
"ODS" ) || drvName == QLatin1String(
"XLSX" ) || drvName == QLatin1String(
"XLS" ) );
3289 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
3294 if ( nonSpatialFormat )
3299 if ( filterString.isEmpty() )
3306 globs = metadata.
glob.toLower().split(
' ' );
3312 details.
globs = globs;
3321 if ( options & SortRecommended )
3323 if ( a.driverName == QLatin1String(
"GPKG" ) )
3325 else if ( b.driverName == QLatin1String(
"GPKG" ) )
3327 else if ( a.driverName == QLatin1String(
"ESRI Shapefile" ) )
3329 else if ( b.driverName == QLatin1String(
"ESRI Shapefile" ) )
3336 sFilters.insert( options, results );
3343 QSet< QString > extensions;
3345 const QRegularExpression rx( QStringLiteral(
"\\*\\.(.*)$" ) );
3349 for (
const QString &glob : format.globs )
3351 const QRegularExpressionMatch match = rx.match( glob );
3352 if ( !match.hasMatch() )
3355 const QString matched = match.captured( 1 );
3356 extensions.insert( matched );
3360 QStringList extensionList = qgis::setToList( extensions );
3362 std::sort( extensionList.begin(), extensionList.end(), [options](
const QString & a,
const QString & b ) ->
bool
3364 if ( options & SortRecommended )
3366 if ( a == QLatin1String(
"gpkg" ) )
3368 else if ( b == QLatin1String(
"gpkg" ) )
3370 else if ( a == QLatin1String(
"shp" ) )
3372 else if ( b == QLatin1String(
"shp" ) )
3376 return a.toLower().localeAwareCompare( b.toLower() ) < 0;
3379 return extensionList;
3384 QList< QgsVectorFileWriter::DriverDetails > results;
3387 const int drvCount = OGRGetDriverCount();
3389 QStringList writableDrivers;
3390 for (
int i = 0; i < drvCount; ++i )
3392 OGRSFDriverH drv = OGRGetDriver( i );
3395 QString drvName = OGR_Dr_GetName( drv );
3401 if ( drvName == QLatin1String(
"ODS" ) || drvName == QLatin1String(
"XLSX" ) || drvName == QLatin1String(
"XLS" ) )
3405 if ( drvName == QLatin1String(
"ESRI Shapefile" ) )
3407 writableDrivers << QStringLiteral(
"DBF file" );
3409 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
3412 if ( drvName == QLatin1String(
"MapInfo File" ) )
3414 writableDrivers << QStringLiteral(
"MapInfo MIF" );
3416 else if ( drvName == QLatin1String(
"SQLite" ) )
3423 QString option = QStringLiteral(
"SPATIALITE=YES" );
3424 char *options[2] = { CPLStrdup( option.toLocal8Bit().constData() ),
nullptr };
3425 OGRSFDriverH poDriver;
3427 poDriver = OGRGetDriverByName( drvName.toLocal8Bit().constData() );
3430 gdal::ogr_datasource_unique_ptr ds( OGR_Dr_CreateDataSource( poDriver, QStringLiteral(
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData(), options ) );
3433 writableDrivers << QStringLiteral(
"SpatiaLite" );
3434 OGR_Dr_DeleteDataSource( poDriver, QStringLiteral(
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData() );
3437 CPLFree( options[0] );
3439 writableDrivers << drvName;
3444 results.reserve( writableDrivers.count() );
3445 for (
const QString &drvName : qgis::as_const( writableDrivers ) )
3459 if ( options & SortRecommended )
3461 if ( a.driverName == QLatin1String(
"GPKG" ) )
3463 else if ( b.driverName == QLatin1String(
"GPKG" ) )
3465 else if ( a.driverName == QLatin1String(
"ESRI Shapefile" ) )
3467 else if ( b.driverName == QLatin1String(
"ESRI Shapefile" ) )
3471 return a.
longName.toLower().localeAwareCompare( b.
longName.toLower() ) < 0;
3478 QString ext = extension.trimmed();
3479 if ( ext.isEmpty() )
3482 if ( ext.startsWith(
'.' ) )
3486 int const drvCount = GDALGetDriverCount();
3488 for (
int i = 0; i < drvCount; ++i )
3490 GDALDriverH drv = GDALGetDriver( i );
3496 QString drvName = GDALGetDriverShortName( drv );
3497 QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
3499 const auto constDriverExtensions = driverExtensions;
3500 for (
const QString &driver : constDriverExtensions )
3502 if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
3513 QString filterString;
3517 if ( !filterString.isEmpty() )
3518 filterString += QLatin1String(
";;" );
3520 filterString += details.filterString;
3522 return filterString;
3531 return QStringLiteral(
"%1 (%2 %3)" ).arg( metadata.
trLongName,
3532 metadata.
glob.toLower(),
3533 metadata.
glob.toUpper() );
3538 if ( codecName == QLatin1String(
"System" ) )
3539 return QStringLiteral(
"LDID/0" );
3541 QRegExp re = QRegExp( QString(
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
3542 if ( re.exactMatch( codecName ) )
3544 QString
c = re.cap( 2 ).remove(
'-' );
3546 ( void )
c.toInt( &isNumber );
3574 OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
3575 OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
3578 int nTotalLevels = 0;
3580 QgsSymbolList::iterator symbolIt = symbolList.begin();
3581 for ( ; symbolIt != symbolList.end(); ++symbolIt )
3583 double mmsf = mmScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
3584 double musf = mapUnitScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
3586 int nLevels = ( *symbolIt )->symbolLayerCount();
3587 for (
int i = 0; i < nLevels; ++i )
3589 mSymbolLayerTable.insert( ( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
3590 OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
3591 ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
3595 OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
3601 if ( !details.renderer )
3606 QHash< QgsSymbol *, QList<QgsFeature> > features;
3615 startRender( details.renderer.get(), details.sourceFields );
3635 QString msg = QObject::tr(
"Failed to transform, writing stopped. (Exception: %1)" )
3646 featureSymbol = mRenderer->symbolForFeature( fet, mRenderContext );
3647 if ( !featureSymbol )
3652 QHash< QgsSymbol *, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
3653 if ( it == features.end() )
3655 it = features.insert( featureSymbol, QList<QgsFeature>() );
3657 it.value().append( fet );
3662 QgsSymbolList symbols = mRenderer->symbols( mRenderContext );
3663 for (
int i = 0; i < symbols.count(); i++ )
3669 if ( level < 0 || level >= 1000 )
3672 while ( level >= levels.count() )
3674 levels[level].append( item );
3679 int nTotalFeatures = 0;
3682 for (
int l = 0; l < levels.count(); l++ )
3685 for (
int i = 0; i < level.count(); i++ )
3688 QHash< QgsSymbol *, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
3689 if ( levelIt == features.end() )
3695 double mmsf = mmScaleFactor(
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
3696 double musf = mapUnitScaleFactor(
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
3698 int llayer = item.
layer();
3699 QList<QgsFeature> &featureList = levelIt.value();
3700 QList<QgsFeature>::iterator featureIt = featureList.begin();
3701 for ( ; featureIt != featureList.end(); ++featureIt )
3711 QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
3712 if ( !styleString.isEmpty() )
3714 OGR_F_SetStyleString( ogrFeature.get(), styleString.toLocal8Bit().constData() );
3715 if ( !writeFeature(
mLayer, ogrFeature.get() ) )
3728 *
errorMessage += QObject::tr(
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
3745 return 1000 / scale;
3762 return scale / 1000;
3770 mRenderer = createSymbologyRenderer( sourceRenderer );
3776 mRenderer->startRender( mRenderContext, fields );
3779 void QgsVectorFileWriter::stopRender()
3786 mRenderer->stopRender( mRenderContext );
3789 std::unique_ptr<QgsFeatureRenderer> QgsVectorFileWriter::createSymbologyRenderer(
QgsFeatureRenderer *sourceRenderer )
const
3795 if ( !sourceRenderer )
3800 return std::unique_ptr< QgsFeatureRenderer >( sourceRenderer->
clone() );
3807 const QSet<QString> rendererAttributes = renderer->
usedAttributes( context );
3808 for (
const QString &attr : rendererAttributes )
3813 attList.append( index );
3819 QStringList QgsVectorFileWriter::concatenateOptions(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
3822 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
3824 for ( it = options.constBegin(); it != options.constEnd(); ++it )
3827 switch ( option->
type )
3834 list.append( QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( opt->
defaultValue ) );
3844 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
3854 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
3863 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue ) );
3874 OGRSFDriverH hDriver =
nullptr;
3877 return QgsVectorFileWriter::EditionCapabilities();
3878 QString drvName = OGR_Dr_GetName( hDriver );
3879 QgsVectorFileWriter::EditionCapabilities caps = QgsVectorFileWriter::EditionCapabilities();
3880 if ( OGR_DS_TestCapability( hDS.get(), ODsCCreateLayer ) )
3885 if ( !( drvName == QLatin1String(
"ESRI Shapefile" ) && QFile::exists( datasetName ) ) )
3888 if ( OGR_DS_TestCapability( hDS.get(), ODsCDeleteLayer ) )
3892 int layer_count = OGR_DS_GetLayerCount( hDS.get() );
3895 OGRLayerH hLayer = OGR_DS_GetLayer( hDS.get(), 0 );
3898 if ( OGR_L_TestCapability( hLayer, OLCSequentialWrite ) )
3901 if ( OGR_L_TestCapability( hLayer, OLCCreateField ) )
3912 const QString &layerNameIn )
3914 OGRSFDriverH hDriver =
nullptr;
3919 QString layerName( layerNameIn );
3920 if ( layerName.isEmpty() )
3921 layerName = QFileInfo( datasetName ).baseName();
3923 return OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
3928 const QString &layerName,
3932 OGRSFDriverH hDriver =
nullptr;
3936 OGRLayerH hLayer = OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
3942 OGRFeatureDefnH defn = OGR_L_GetLayerDefn( hLayer );
3943 const auto constAttributes = attributes;
3944 for (
int idx : constAttributes )
3947 if ( OGR_FD_GetFieldIndex( defn, fld.
name().toUtf8().constData() ) < 0 )
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
@ FlagExportTrianglesAsPolygons
Triangles should be exported as polygon geometries.
static void registerOgrDrivers()
Register OGR drivers ensuring this only happens once.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
static Q_INVOKABLE QgsCoordinateReferenceSystem fromEpsgId(long epsg)
Creates a CRS from a given EPSG ID.
QString authid() const
Returns the authority identifier for the CRS.
@ WKT_PREFERRED_GDAL
Preferred format for conversion of CRS to WKT for use with the GDAL library.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Q_GADGET QgsUnitTypes::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
Custom exception class for Coordinate Reference System related exceptions.
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
Class for storing the component parts of a RDBMS data source URI (e.g.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
virtual QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const
Returns list of symbols used for rendering the feature.
virtual QgsSymbolList symbols(QgsRenderContext &context) const
Returns list of symbols used by the renderer.
bool usingSymbolLevels() const
virtual QgsFeatureRenderer::Capabilities capabilities()
Returns details about internals of this renderer.
@ SymbolLevels
Rendering with symbol levels (i.e. implements symbols(), symbolForFeature())
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const =0
Returns a list of attributes required by this renderer.
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
bool hasGeometry() const
Returns true if the feature has an associated geometry.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
QString typeName() const
Gets the field type.
bool convertCompatible(QVariant &v, QString *errorMessage=nullptr) const
Converts the provided variant to a compatible format.
QVariant::Type subType() const
If the field is a collection, gets its element's type.
Container of fields for a vector layer.
int count() const
Returns number of items.
int size() const
Returns number of items.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsWkbTypes::Type wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
static QgsGeometry fromRect(const QgsRectangle &rect) SIP_HOLDGIL
Creates a new geometry from a QgsRectangle.
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
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.
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const
Export the geometry to WKB.
static void warning(const QString &msg)
Goes to qWarning.
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsCoordinateReferenceSystem crs
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
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).
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
The QgsReadWriteLocker class is a convenience class that simplifies locking and unlocking QReadWriteL...
void changeMode(Mode mode)
Change the mode of the lock to mode.
A rectangle specified with double values.
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Contains information about the context of a rendering operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
void setRendererScale(double scale)
Sets the renderer map scale.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
int renderingPass() const
Specifies the rendering pass in which this symbol layer should be rendered.
int layer() const
The layer of this symbol level.
QgsSymbol * symbol() const
The symbol of this symbol level.
Abstract base class for all rendered symbols.
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
DistanceUnit
Units of distance.
RenderUnit
Rendering size units.
@ RenderMillimeters
Millimeters.
@ RenderMapUnits
Map units.
Interface to convert raw field values to their user-friendly value.
virtual QVariant convert(int fieldIdxInLayer, const QVariant &value)
Convert the provided value, for field fieldIdxInLayer.
virtual QgsVectorFileWriter::FieldValueConverter * clone() const
Creates a clone of the FieldValueConverter.
virtual QgsField fieldDefinition(const QgsField &field)
Returns a possibly modified field definition.
QgsVectorFileWriter::OptionType type
Options to pass to writeAsVectorFormat()
QString fileEncoding
Encoding to use.
bool forceMulti
Sets to true to force creation of multi* geometries.
FieldNameSource fieldNameSource
Source for exported field names.
QString driverName
OGR driver to use.
QgsCoordinateTransform ct
Transform to reproject exported geometries with, or invalid transform for no transformation.
SaveVectorOptions()
Constructor.
QString layerName
Layer name. If let empty, it will be derived from the filename.
QgsRectangle filterExtent
If not empty, only features intersecting the extent will be saved.
QgsVectorFileWriter::FieldValueConverter * fieldValueConverter
Field value converter.
QStringList layerOptions
List of OGR layer creation options.
QgsVectorFileWriter::SymbologyExport symbologyExport
Symbology to export.
bool includeZ
Sets to true to include z dimension in output. This option is only valid if overrideGeometryType is s...
QgsVectorFileWriter::ActionOnExistingFile actionOnExistingFile
Action on existing file.
QgsAttributeList attributes
Attributes to export (empty means all unless skipAttributeCreation is set)
bool onlySelectedFeatures
Write only selected features of layer.
bool skipAttributeCreation
Only write geometries.
double symbologyScale
Scale of symbology.
QStringList datasourceOptions
List of OGR data source creation options.
QgsWkbTypes::Type overrideGeometryType
Set to a valid geometry type to override the default geometry type for the layer.
QgsFeedback * feedback
Optional feedback object allowing cancellation of layer save.
A convenience class for writing vector files to disk.
QString lastError() const override
Returns the most recent error encountered by the sink, e.g.
@ CanAddNewFieldsToExistingLayer
Flag to indicate that new fields can be added to an existing layer. Imply CanAppendToExistingLayer.
@ CanAppendToExistingLayer
Flag to indicate that new features can be added to an existing layer.
@ CanAddNewLayer
Flag to indicate that a new layer can be added to the dataset.
@ CanDeleteLayer
Flag to indicate that an existing layer can be deleted.
static QgsVectorFileWriter::EditionCapabilities editionCapabilities(const QString &datasetName)
Returns edition capabilities for an existing dataset name.
static QgsVectorFileWriter * create(const QString &fileName, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &srs, const QgsCoordinateTransformContext &transformContext, const QgsVectorFileWriter::SaveVectorOptions &options, QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags(), QString *newFilename=nullptr, QString *newLayer=nullptr)
Create a new vector file writer.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
static bool supportsFeatureStyles(const QString &driverName)
Returns true if the specified driverName supports feature styles.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
double mSymbologyScale
Scale for symbology export (e.g. for symbols units in map units)
OGRGeometryH createEmptyGeometry(QgsWkbTypes::Type wkbType)
QMap< int, int > mAttrIdxToOgrIdx
Map attribute indizes to OGR field indexes.
Q_DECL_DEPRECATED 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=QgsFeatureSink::SinkFlags(), QString *newLayer=nullptr, QgsCoordinateTransformContext transformContext=QgsCoordinateTransformContext(), FieldNameSource fieldNameSource=Original)
Create a new vector file writer.
@ ErrAttributeTypeUnsupported
@ Canceled
Writing was interrupted by manual cancellation.
@ ErrAttributeCreationFailed
gdal::ogr_datasource_unique_ptr mDS
static QgsVectorFileWriter::WriterError writeAsVectorFormatV2(QgsVectorLayer *layer, const QString &fileName, const QgsCoordinateTransformContext &transformContext, const QgsVectorFileWriter::SaveVectorOptions &options, QString *newFilename=nullptr, QString *newLayer=nullptr, QString *errorMessage=nullptr)
Writes a layer out to a vector file.
~QgsVectorFileWriter() override
Close opened shapefile for writing.
static bool targetLayerExists(const QString &datasetName, const QString &layerName)
Returns whether the target layer already exists.
double symbologyScale() const
Returns the reference scale for output.
static QStringList defaultLayerOptions(const QString &driverName)
Returns a list of the default layer options for a specified driver.
SymbologyExport mSymbologyExport
static QString driverForExtension(const QString &extension)
Returns the OGR driver name for a specified file extension.
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...
OGRSpatialReferenceH mOgrRef
static bool driverMetadata(const QString &driverName, MetaData &driverMetadata)
QgsVectorFileWriter::WriterError hasError()
Checks whether there were any errors in constructor.
static bool deleteShapeFile(const QString &fileName)
Delete a shapefile (and its accompanying shx / dbf / prj / qix / qpj / cpg / sbn / sbx / idm / ind)
static QString filterForDriver(const QString &driverName)
Creates a filter for an OGR driver key.
QgsWkbTypes::Type mWkbType
Geometry type which is being used.
static OGRwkbGeometryType ogrTypeFromWkbType(QgsWkbTypes::Type type)
Gets the ogr geometry type from an internal QGIS wkb type enum.
@ SkipNonSpatialFormats
Filter out any formats which do not have spatial support (e.g. those which cannot save geometries)
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.
static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList(VectorFormatOptions options=SortRecommended)
Returns the driver list that can be used for dialogs.
static Q_DECL_DEPRECATED 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.
WriterError mError
Contains error value if construction was not successful.
FieldNameSource
Source for exported field names.
@ PreferAlias
Use the field alias as the exported field name, wherever one is set. Otherwise use the original field...
@ Original
Use original field names.
static QStringList defaultDatasetOptions(const QString &driverName)
Returns a list of the default dataset options for a specified driver.
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
QString errorMessage()
Retrieves error message.
static QString convertCodecNameForEncodingOption(const QString &codecName)
Converts codec name to string passed to ENCODING layer creation option of OGR Shapefile.
FieldValueConverter * mFieldValueConverter
Field value converter.
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.
QgsVectorFileWriter::SymbologyExport symbologyExport() const
void setSymbologyScale(double scale)
Set reference scale for output.
QMap< QgsSymbolLayer *, QString > mSymbolLayerTable
static QString fileFilterString(VectorFormatOptions options=SortRecommended)
Returns filter string that can be used for dialogs.
ActionOnExistingFile
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
@ CreateOrOverwriteLayer
Create or overwrite layer.
@ CreateOrOverwriteFile
Create or overwrite file.
@ AppendToLayerNoNewFields
Append features to existing layer, but do not create new fields.
@ AppendToLayerAddFields
Append features to existing layer, and create new fields if needed.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
QVariant maximumValue(int index) const FINAL
Returns the maximum value for an attribute column or an invalid variant in case of error.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QVariant minimumValue(int index) const FINAL
Returns the minimum value for an attribute column or an invalid variant in case of error.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
static bool isMultiType(Type type) SIP_HOLDGIL
Returns true if the WKB type is a multi type.
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Type
The WKB type describes the number of dimensions a geometry has.
static Type to25D(Type type) SIP_HOLDGIL
Will convert the 25D version of the flat type if supported or Unknown if not supported.
static Type singleType(Type type) SIP_HOLDGIL
Returns the single type for a WKB type.
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
static Type multiType(Type type) SIP_HOLDGIL
Returns the multi type for a WKB type.
static Type addZ(Type type) SIP_HOLDGIL
Adds the z dimension to a WKB type and returns the new type.
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
std::unique_ptr< std::remove_pointer< OGRFeatureH >::type, OGRFeatureDeleter > ogr_feature_unique_ptr
Scoped OGR feature.
std::unique_ptr< std::remove_pointer< OGRDataSourceH >::type, OGRDataSourceDeleter > ogr_datasource_unique_ptr
Scoped OGR data source.
std::unique_ptr< std::remove_pointer< OGRFieldDefnH >::type, OGRFldDeleter > ogr_field_def_unique_ptr
Scoped OGR field definition.
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
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
QList< QgsFeature > QgsFeatureList
#define FID_TO_NUMBER(fid)
QList< int > QgsAttributeList
#define QgsDebugMsgLevel(str, level)
QList< QgsSymbolLevel > QgsSymbolLevelOrder
QList< QgsSymbolLevelItem > QgsSymbolLevel
QList< QgsSymbol * > QgsSymbolList
Details of available driver formats.
QString longName
Descriptive, user friendly name for the driver.
QString driverName
Unique driver name.