43 #include <QTextStream> 51 #include <ogr_srs_api.h> 52 #include <cpl_error.h> 54 #include <cpl_string.h> 60 static OGRDataSourceH myOGROpen(
const char *pszName,
int bUpdate, OGRSFDriverH *phDriver )
62 OGRSFDriverH hDriver =
nullptr;
63 OGRDataSourceH hDS = OGROpen( pszName, bUpdate, &hDriver );
66 QString drvName = OGR_Dr_GetName( hDriver );
67 if ( drvName ==
"BNA" )
69 OGR_DS_Destroy( hDS );
96 const QString &vectorFileName,
97 const QString &fileEncoding,
101 const QString &driverName,
102 const QStringList &datasourceOptions,
103 const QStringList &layerOptions,
104 QString *newFilename,
106 QgsFeatureSink::SinkFlags sinkFlags,
114 init( vectorFileName, fileEncoding, fields, geometryType,
115 srs, driverName, datasourceOptions, layerOptions, newFilename,
nullptr,
120 const QString &fileEncoding,
124 const QString &driverName,
125 const QStringList &datasourceOptions,
126 const QStringList &layerOptions,
127 QString *newFilename,
130 const QString &layerName,
138 init( vectorFileName, fileEncoding, fields, geometryType, srs, driverName,
139 datasourceOptions, layerOptions, newFilename, fieldValueConverter,
140 layerName, action, newLayer,
nullptr );
145 if ( driverName == QLatin1String(
"MapInfo MIF" ) )
149 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0) 150 GDALDriverH gdalDriver = GDALGetDriverByName( driverName.toLocal8Bit().constData() );
155 if ( !driverMetadata )
158 return CSLFetchBoolean( driverMetadata, GDAL_DCAP_FEATURE_STYLES,
false );
160 return driverName == QLatin1String(
"DXF" ) || driverName == QLatin1String(
"KML" ) || driverName == QLatin1String(
"MapInfo File" );
164 void QgsVectorFileWriter::init( QString vectorFileName,
165 QString fileEncoding,
169 const QString &driverName,
170 QStringList datasourceOptions,
171 QStringList layerOptions,
172 QString *newFilename,
174 const QString &layerNameIn,
176 QString *newLayer, SinkFlags sinkFlags )
180 if ( vectorFileName.isEmpty() )
187 if ( driverName == QLatin1String(
"MapInfo MIF" ) )
191 else if ( driverName == QLatin1String(
"SpatiaLite" ) )
194 if ( !datasourceOptions.contains( QStringLiteral(
"SPATIALITE=YES" ) ) )
196 datasourceOptions.append( QStringLiteral(
"SPATIALITE=YES" ) );
199 else if ( driverName == QLatin1String(
"DBF file" ) )
202 if ( !layerOptions.contains( QStringLiteral(
"SHPT=NULL" ) ) )
204 layerOptions.append( QStringLiteral(
"SHPT=NULL" ) );
214 OGRSFDriverH poDriver;
217 poDriver = OGRGetDriverByName(
mOgrDriverName.toLocal8Bit().constData() );
221 mErrorMessage = QObject::tr(
"OGR driver for '%1' not found (OGR error: %2)" )
223 QString::fromUtf8( CPLGetLastErrorMsg() ) );
233 if ( layerOptions.join( QString() ).toUpper().indexOf( QLatin1String(
"ENCODING=" ) ) == -1 )
238 if ( driverName == QLatin1String(
"ESRI Shapefile" ) && !vectorFileName.endsWith( QLatin1String(
".shp" ), Qt::CaseInsensitive ) )
240 vectorFileName += QLatin1String(
".shp" );
242 else if ( driverName == QLatin1String(
"DBF file" ) && !vectorFileName.endsWith( QLatin1String(
".dbf" ), Qt::CaseInsensitive ) )
244 vectorFileName += QLatin1String(
".dbf" );
254 QStringList allExts = metadata.
ext.split(
' ', QString::SkipEmptyParts );
256 Q_FOREACH (
const QString &ext, allExts )
258 if ( vectorFileName.endsWith(
'.' + ext, Qt::CaseInsensitive ) )
267 vectorFileName +=
'.' + allExts[0];
273 if ( vectorFileName.endsWith( QLatin1String(
".gdb" ), Qt::CaseInsensitive ) )
275 QDir dir( vectorFileName );
278 QFileInfoList fileList = dir.entryInfoList(
279 QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst );
280 Q_FOREACH (
const QFileInfo &info, fileList )
282 QFile::remove( info.absoluteFilePath() );
285 QDir().rmdir( vectorFileName );
289 QFile::remove( vectorFileName );
304 char **options =
nullptr;
305 if ( !datasourceOptions.isEmpty() )
307 options =
new char *[ datasourceOptions.size() + 1 ];
308 for (
int i = 0; i < datasourceOptions.size(); i++ )
310 QgsDebugMsg( QStringLiteral(
"-dsco=%1" ).arg( datasourceOptions[i] ) );
311 options[i] = CPLStrdup( datasourceOptions[i].toLocal8Bit().constData() );
313 options[ datasourceOptions.size()] =
nullptr;
319 mDS.reset( OGR_Dr_CreateDataSource( poDriver, vectorFileName.toUtf8().constData(), options ) );
321 mDS.reset( myOGROpen( vectorFileName.toUtf8().constData(), TRUE, nullptr ) );
325 for (
int i = 0; i < datasourceOptions.size(); i++ )
326 CPLFree( options[i] );
335 mErrorMessage = QObject::tr(
"Creation of data source failed (OGR error: %1)" )
336 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
338 mErrorMessage = QObject::tr(
"Opening of data source in update mode failed (OGR error: %1)" )
339 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
343 QString layerName( layerNameIn );
344 if ( layerName.isEmpty() )
345 layerName = QFileInfo( vectorFileName ).baseName();
349 const int layer_count = OGR_DS_GetLayerCount(
mDS.get() );
350 for (
int i = 0; i < layer_count; i++ )
352 OGRLayerH hLayer = OGR_DS_GetLayer(
mDS.get(), i );
353 if ( EQUAL( OGR_L_GetName( hLayer ), layerName.toUtf8().constData() ) )
355 if ( OGR_DS_DeleteLayer(
mDS.get(), i ) != OGRERR_NONE )
358 mErrorMessage = QObject::tr(
"Overwriting of existing layer failed (OGR error: %1)" )
359 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
369 QgsDebugMsg( QStringLiteral(
"Created data source" ) );
373 QgsDebugMsg( QStringLiteral(
"Opened data source in update mode" ) );
377 mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().constData() );
380 QgsDebugMsg(
"error finding QTextCodec for " + fileEncoding );
383 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
384 mCodec = QTextCodec::codecForName( enc.toLocal8Bit().constData() );
387 QgsDebugMsg(
"error finding QTextCodec for " + enc );
388 mCodec = QTextCodec::codecForLocale();
396 QString srsWkt = srs.
toWkt();
398 mOgrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().constData() );
405 int optIndex = layerOptions.indexOf( QStringLiteral(
"FEATURE_DATASET=" ) );
406 if ( optIndex != -1 )
408 layerOptions.removeAt( optIndex );
411 if ( !layerOptions.isEmpty() )
413 options =
new char *[ layerOptions.size() + 1 ];
414 for (
int i = 0; i < layerOptions.size(); i++ )
416 QgsDebugMsg( QStringLiteral(
"-lco=%1" ).arg( layerOptions[i] ) );
417 options[i] = CPLStrdup( layerOptions[i].toLocal8Bit().constData() );
419 options[ layerOptions.size()] =
nullptr;
423 CPLSetConfigOption(
"SHAPE_ENCODING",
"" );
427 mLayer = OGR_DS_CreateLayer(
mDS.get(), layerName.toUtf8().constData(),
mOgrRef, wkbType, options );
429 *newLayer = OGR_L_GetName(
mLayer );
431 else if ( driverName == QLatin1String(
"DGN" ) )
433 mLayer = OGR_DS_GetLayerByName(
mDS.get(),
"elements" );
437 mLayer = OGR_DS_GetLayerByName(
mDS.get(), layerName.toUtf8().constData() );
442 for (
int i = 0; i < layerOptions.size(); i++ )
443 CPLFree( options[i] );
449 if ( !settings.
value( QStringLiteral(
"qgis/ignoreShapeEncoding" ),
true ).toBool() )
451 CPLSetConfigOption(
"SHAPE_ENCODING",
nullptr );
458 QString layerName = vectorFileName.left( vectorFileName.indexOf( QLatin1String(
".shp" ), Qt::CaseInsensitive ) );
459 QFile prjFile( layerName +
".qpj" );
460 if ( prjFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
462 QTextStream prjStream( &prjFile );
463 prjStream << srs.
toWkt().toLocal8Bit().constData() << endl;
468 QgsDebugMsg(
"Couldn't open file " + layerName +
".qpj" );
476 mErrorMessage = QObject::tr(
"Creation of layer failed (OGR error: %1)" )
477 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
479 mErrorMessage = QObject::tr(
"Opening of layer failed (OGR error: %1)" )
480 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
485 OGRFeatureDefnH defn = OGR_L_GetLayerDefn(
mLayer );
490 QgsDebugMsg(
"creating " + QString::number( fields.
size() ) +
" fields" );
494 QSet<int> existingIdxs;
504 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
508 if ( fieldValueConverter )
513 QString name( attrField.
name() );
516 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
524 OGRFieldType ogrType = OFTString;
525 int ogrWidth = attrField.
length();
526 int ogrPrecision = attrField.
precision();
527 if ( ogrPrecision > 0 )
530 switch ( attrField.
type() )
532 case QVariant::LongLong:
534 const char *pszDataTypes = GDALGetMetadataItem( poDriver, GDAL_DMD_CREATIONFIELDDATATYPES,
nullptr );
535 if ( pszDataTypes && strstr( pszDataTypes,
"Integer64" ) )
536 ogrType = OFTInteger64;
539 ogrWidth = ogrWidth > 0 && ogrWidth <= 20 ? ogrWidth : 20;
543 case QVariant::String:
545 if ( ogrWidth <= 0 || ogrWidth > 255 )
550 ogrType = OFTInteger;
551 ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
556 ogrType = OFTInteger;
561 case QVariant::Double:
581 case QVariant::DateTime:
589 ogrType = OFTDateTime;
593 case QVariant::ByteArray:
599 mErrorMessage = QObject::tr(
"Unsupported type for field %1" )
600 .arg( attrField.
name() );
605 if (
mOgrDriverName == QLatin1String(
"SQLite" ) && name.compare( QLatin1String(
"ogc_fid" ), Qt::CaseInsensitive ) == 0 )
608 for ( i = 0; i < 10; i++ )
610 name = QStringLiteral(
"ogc_fid%1" ).arg( i );
613 for ( j = 0; j < fields.
size() && name.compare( fields.
at( j ).
name(), Qt::CaseInsensitive ) != 0; j++ )
616 if ( j == fields.
size() )
622 mErrorMessage = QObject::tr(
"No available replacement for internal fieldname ogc_fid found" ).arg( attrField.
name() );
627 QgsMessageLog::logMessage( QObject::tr(
"Reserved attribute name ogc_fid replaced with %1" ).arg( name ), QObject::tr(
"OGR" ) );
634 OGR_Fld_SetWidth( fld.get(), ogrWidth );
637 if ( ogrPrecision >= 0 )
639 OGR_Fld_SetPrecision( fld.get(), ogrPrecision );
642 switch ( attrField.
type() )
645 OGR_Fld_SetSubType( fld.get(), OFSTBoolean );
653 " type " + QString( QVariant::typeToName( attrField.
type() ) ) +
654 " width " + QString::number( ogrWidth ) +
655 " precision " + QString::number( ogrPrecision ) );
656 if ( OGR_L_CreateField(
mLayer, fld.get(), true ) != OGRERR_NONE )
659 mErrorMessage = QObject::tr(
"Creation of field %1 failed (OGR error: %2)" )
660 .arg( attrField.
name(),
661 QString::fromUtf8( CPLGetLastErrorMsg() ) );
666 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
667 QgsDebugMsg( QStringLiteral(
"returned field index for %1: %2" ).arg( name ).arg( ogrIdx ) );
668 if ( ogrIdx < 0 || existingIdxs.contains( ogrIdx ) )
671 ogrIdx = OGR_FD_GetFieldCount( defn ) - 1;
676 mErrorMessage = QObject::tr(
"Created field %1 not found (OGR error: %2)" )
677 .arg( attrField.
name(),
678 QString::fromUtf8( CPLGetLastErrorMsg() ) );
684 existingIdxs.insert( ogrIdx );
692 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
695 QString name( attrField.
name() );
696 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
708 int fidIdx = fields.
lookupField( QStringLiteral(
"FID" ) );
714 QgsDebugMsg( QStringLiteral(
"Done creating fields" ) );
719 *newFilename = vectorFileName;
722 mUsingTransaction =
true;
723 if ( OGRERR_NONE != OGR_L_StartTransaction(
mLayer ) )
725 mUsingTransaction =
false;
735 class QgsVectorFileWriterMetadataContainer
739 QgsVectorFileWriterMetadataContainer()
741 QMap<QString, QgsVectorFileWriter::Option *> datasetOptions;
742 QMap<QString, QgsVectorFileWriter::Option *> layerOptions;
745 datasetOptions.clear();
746 layerOptions.clear();
750 QStringLiteral(
"Arc/Info ASCII Coverage" ),
751 QObject::tr(
"Arc/Info ASCII Coverage" ),
752 QStringLiteral(
"*.e00" ),
753 QStringLiteral(
"e00" ),
760 datasetOptions.clear();
761 layerOptions.clear();
764 QObject::tr(
"New BNA files are created by the " 765 "systems default line termination conventions. " 766 "This may be overridden here." ),
768 << QStringLiteral(
"CRLF" )
769 << QStringLiteral(
"LF" ),
775 QObject::tr(
"By default, BNA files are created in multi-line format. " 776 "For each record, the first line contains the identifiers and the " 777 "type/number of coordinates to follow. Each following line contains " 778 "a pair of coordinates." ),
783 QObject::tr(
"BNA records may contain from 2 to 4 identifiers per record. " 784 "Some software packages only support a precise number of identifiers. " 785 "You can override the default value (2) by a precise value." ),
787 << QStringLiteral(
"2" )
788 << QStringLiteral(
"3" )
789 << QStringLiteral(
"4" )
790 << QStringLiteral(
"NB_SOURCE_FIELDS" ),
791 QStringLiteral(
"2" )
795 QObject::tr(
"The BNA writer will try to recognize ellipses and circles when writing a polygon. " 796 "This will only work if the feature has previously been read from a BNA file. " 797 "As some software packages do not support ellipses/circles in BNA data file, " 798 "it may be useful to tell the writer by specifying ELLIPSES_AS_ELLIPSES=NO not " 799 "to export them as such, but keep them as polygons." ),
804 QObject::tr(
"Limit the number of coordinate pairs per line in multiline format." ),
809 QObject::tr(
"Set the number of decimal for coordinates. Default value is 10." ),
815 QStringLiteral(
"Atlas BNA" ),
816 QObject::tr(
"Atlas BNA" ),
817 QStringLiteral(
"*.bna" ),
818 QStringLiteral(
"bna" ),
825 datasetOptions.clear();
826 layerOptions.clear();
829 QObject::tr(
"By default when creating new .csv files they " 830 "are created with the line termination conventions " 831 "of the local platform (CR/LF on Win32 or LF on all other systems). " 832 "This may be overridden through the use of the LINEFORMAT option." ),
834 << QStringLiteral(
"CRLF" )
835 << QStringLiteral(
"LF" ),
841 QObject::tr(
"By default, the geometry of a feature written to a .csv file is discarded. " 842 "It is possible to export the geometry in its WKT representation by " 843 "specifying GEOMETRY=AS_WKT. It is also possible to export point geometries " 844 "into their X,Y,Z components by specifying GEOMETRY=AS_XYZ, GEOMETRY=AS_XY " 845 "or GEOMETRY=AS_YX." ),
847 << QStringLiteral(
"AS_WKT" )
848 << QStringLiteral(
"AS_XYZ" )
849 << QStringLiteral(
"AS_XY" )
850 << QStringLiteral(
"AS_YX" ),
856 QObject::tr(
"Create the associated .csvt file to describe the type of each " 857 "column of the layer and its optional width and precision." ),
862 QObject::tr(
"Field separator character." ),
864 << QStringLiteral(
"COMMA" )
865 << QStringLiteral(
"SEMICOLON" )
866 << QStringLiteral(
"TAB" ),
867 QStringLiteral(
"COMMA" )
870 #if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0) 872 QObject::tr(
"Double-quote strings. IF_AMBIGUOUS means that string values that look like numbers will be quoted." ),
874 << QStringLiteral(
"IF_NEEDED" )
875 << QStringLiteral(
"IF_AMBIGUOUS" )
876 << QStringLiteral(
"ALWAYS" ),
877 QStringLiteral(
"IF_AMBIGUOUS" )
882 QObject::tr(
"Write a UTF-8 Byte Order Mark (BOM) at the start of the file." ),
888 QStringLiteral(
"Comma Separated Value [CSV]" ),
889 QObject::tr(
"Comma Separated Value [CSV]" ),
890 QStringLiteral(
"*.csv" ),
891 QStringLiteral(
"csv" ),
898 datasetOptions.clear();
899 layerOptions.clear();
902 QObject::tr(
"Override the type of shapefile created. " 903 "Can be one of NULL for a simple .dbf file with no .shp file, POINT, " 904 "ARC, POLYGON or MULTIPOINT for 2D, or POINTZ, ARCZ, POLYGONZ or " 905 "MULTIPOINTZ for 3D;" ) +
906 QObject::tr(
" POINTM, ARCM, POLYGONM or MULTIPOINTM for measured geometries" 907 " and POINTZM, ARCZM, POLYGONZM or MULTIPOINTZM for 3D measured" 909 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
910 QObject::tr(
" MULTIPATCH files are supported since GDAL 2.2." ) +
914 << QStringLiteral(
"NULL" )
915 << QStringLiteral(
"POINT" )
916 << QStringLiteral(
"ARC" )
917 << QStringLiteral(
"POLYGON" )
918 << QStringLiteral(
"MULTIPOINT" )
919 << QStringLiteral(
"POINTZ" )
920 << QStringLiteral(
"ARCZ" )
921 << QStringLiteral(
"POLYGONZ" )
922 << QStringLiteral(
"MULTIPOINTZ" )
923 << QStringLiteral(
"POINTM" )
924 << QStringLiteral(
"ARCM" )
925 << QStringLiteral(
"POLYGONM" )
926 << QStringLiteral(
"MULTIPOINTM" )
927 << QStringLiteral(
"POINTZM" )
928 << QStringLiteral(
"ARCZM" )
929 << QStringLiteral(
"POLYGONZM" )
930 << QStringLiteral(
"MULTIPOINTZM" )
931 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
932 << QStringLiteral(
"MULTIPATCH" )
943 QObject::tr(
"Set the encoding value in the DBF file. " 944 "The default value is LDID/87. It is not clear " 945 "what other values may be appropriate." ),
953 QObject::tr(
"Set to YES to resize fields to their optimal size." ),
959 QStringLiteral(
"ESRI Shapefile" ),
960 QObject::tr(
"ESRI Shapefile" ),
961 QStringLiteral(
"*.shp" ),
962 QStringLiteral(
"shp" ),
969 datasetOptions.clear();
970 layerOptions.clear();
974 QStringLiteral(
"DBF File" ),
975 QObject::tr(
"DBF File" ),
976 QStringLiteral(
"*.dbf" ),
977 QStringLiteral(
"dbf" ),
984 datasetOptions.clear();
985 layerOptions.clear();
989 QStringLiteral(
"FMEObjects Gateway" ),
990 QObject::tr(
"FMEObjects Gateway" ),
991 QStringLiteral(
"*.fdd" ),
992 QStringLiteral(
"fdd" ),
999 datasetOptions.clear();
1000 layerOptions.clear();
1003 QObject::tr(
"Set to YES to write a bbox property with the bounding box " 1004 "of the geometries at the feature and feature collection level." ),
1009 QObject::tr(
"Maximum number of figures after decimal separator to write in coordinates. " 1010 "Default to 15. Truncation will occur to remove trailing zeros." ),
1016 QStringLiteral(
"GeoJSON" ),
1017 QObject::tr(
"GeoJSON" ),
1018 QStringLiteral(
"*.geojson" ),
1019 QStringLiteral(
"geojson" ),
1022 QStringLiteral(
"UTF-8" )
1027 datasetOptions.clear();
1028 layerOptions.clear();
1031 QObject::tr(
"whether the document must be in RSS 2.0 or Atom 1.0 format. " 1032 "Default value : RSS" ),
1034 << QStringLiteral(
"RSS" )
1035 << QStringLiteral(
"ATOM" ),
1036 QStringLiteral(
"RSS" )
1040 QObject::tr(
"The encoding of location information. Default value : SIMPLE. " 1041 "W3C_GEO only supports point geometries. " 1042 "SIMPLE or W3C_GEO only support geometries in geographic WGS84 coordinates." ),
1044 << QStringLiteral(
"SIMPLE" )
1045 << QStringLiteral(
"GML" )
1046 << QStringLiteral(
"W3C_GEO" ),
1047 QStringLiteral(
"SIMPLE" )
1051 QObject::tr(
"If defined to YES, extension fields will be written. " 1052 "If the field name not found in the base schema matches " 1053 "the foo_bar pattern, foo will be considered as the namespace " 1054 "of the element, and a <foo:bar> element will be written. " 1055 "Otherwise, elements will be written in the <ogr:> namespace." ),
1060 QObject::tr(
"If defined to NO, only <entry> or <item> elements will be written. " 1061 "The user will have to provide the appropriate header and footer of the document." ),
1066 QObject::tr(
"XML content that will be put between the <channel> element and the " 1067 "first <item> element for a RSS document, or between the xml tag and " 1068 "the first <entry> element for an Atom document." ),
1073 QObject::tr(
"Value put inside the <title> element in the header. " 1074 "If not provided, a dummy value will be used as that element is compulsory." ),
1079 QObject::tr(
"Value put inside the <description> element in the header. " 1080 "If not provided, a dummy value will be used as that element is compulsory." ),
1085 QObject::tr(
"Value put inside the <link> element in the header. " 1086 "If not provided, a dummy value will be used as that element is compulsory." ),
1091 QObject::tr(
"Value put inside the <updated> element in the header. " 1092 "Should be formatted as a XML datetime. " 1093 "If not provided, a dummy value will be used as that element is compulsory." ),
1098 QObject::tr(
"Value put inside the <author><name> element in the header. " 1099 "If not provided, a dummy value will be used as that element is compulsory." ),
1104 QObject::tr(
"Value put inside the <id> element in the header. " 1105 "If not provided, a dummy value will be used as that element is compulsory." ),
1111 QStringLiteral(
"GeoRSS" ),
1112 QObject::tr(
"GeoRSS" ),
1113 QStringLiteral(
"*.xml" ),
1114 QStringLiteral(
"xml" ),
1117 QStringLiteral(
"UTF-8" )
1122 datasetOptions.clear();
1123 layerOptions.clear();
1126 QObject::tr(
"If provided, this URI will be inserted as the schema location. " 1127 "Note that the schema file isn't actually accessed by OGR, so it " 1128 "is up to the user to ensure it will match the schema of the OGR " 1129 "produced GML data file." ),
1134 QObject::tr(
"This writes a GML application schema file to a corresponding " 1135 ".xsd file (with the same basename). If INTERNAL is used the " 1136 "schema is written within the GML file, but this is experimental " 1137 "and almost certainly not valid XML. " 1138 "OFF disables schema generation (and is implicit if XSISCHEMAURI is used)." ),
1140 << QStringLiteral(
"EXTERNAL" )
1141 << QStringLiteral(
"INTERNAL" )
1142 << QStringLiteral(
"OFF" ),
1143 QStringLiteral(
"EXTERNAL" )
1147 QObject::tr(
"This is the prefix for the application target namespace." ),
1148 QStringLiteral(
"ogr" )
1152 QObject::tr(
"Can be set to TRUE to avoid writing the prefix of the " 1153 "application target namespace in the GML file." ),
1158 QObject::tr(
"Defaults to 'http://ogr.maptools.org/'. " 1159 "This is the application target namespace." ),
1160 QStringLiteral(
"http://ogr.maptools.org/" )
1164 QObject::tr(
"If not specified, GML2 will be used." ),
1166 << QStringLiteral(
"GML3" )
1167 << QStringLiteral(
"GML3Deegree" )
1168 << QStringLiteral(
"GML3.2" ),
1174 QObject::tr(
"Only valid when FORMAT=GML3/GML3Degree/GML3.2. Default to YES. " 1175 "If YES, SRS with EPSG authority will be written with the " 1176 "'urn:ogc:def:crs:EPSG::' prefix. In the case the SRS is a " 1177 "geographic SRS without explicit AXIS order, but that the same " 1178 "SRS authority code imported with ImportFromEPSGA() should be " 1179 "treated as lat/long, then the function will take care of coordinate " 1180 "order swapping. If set to NO, SRS with EPSG authority will be " 1181 "written with the 'EPSG:' prefix, even if they are in lat/long order." ),
1186 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. " 1187 "If set to NO, the <gml:boundedBy> element will not be written for " 1193 QObject::tr(
"Default to YES. If YES, the output will be indented with spaces " 1194 "for more readability, but at the expense of file size." ),
1201 QStringLiteral(
"Geography Markup Language [GML]" ),
1202 QObject::tr(
"Geography Markup Language [GML]" ),
1203 QStringLiteral(
"*.gml" ),
1204 QStringLiteral(
"gml" ),
1207 QStringLiteral(
"UTF-8" )
1212 datasetOptions.clear();
1213 layerOptions.clear();
1216 QObject::tr(
"Human-readable identifier (e.g. short name) for the layer content" ),
1221 QObject::tr(
"Human-readable description for the layer content" ),
1226 QObject::tr(
"Name for the feature identifier column" ),
1227 QStringLiteral(
"fid" )
1231 QObject::tr(
"Name for the geometry column" ),
1232 QStringLiteral(
"geom" )
1236 QObject::tr(
"If a spatial index must be created." ),
1242 QStringLiteral(
"GeoPackage" ),
1243 QObject::tr(
"GeoPackage" ),
1244 QStringLiteral(
"*.gpkg" ),
1245 QStringLiteral(
"gpkg" ),
1248 QStringLiteral(
"UTF-8" )
1253 datasetOptions.clear();
1254 layerOptions.clear();
1258 QStringLiteral(
"Generic Mapping Tools [GMT]" ),
1259 QObject::tr(
"Generic Mapping Tools [GMT]" ),
1260 QStringLiteral(
"*.gmt" ),
1261 QStringLiteral(
"gmt" ),
1268 datasetOptions.clear();
1269 layerOptions.clear();
1272 QObject::tr(
"By default when writing a layer whose features are of " 1273 "type wkbLineString, the GPX driver chooses to write " 1274 "them as routes. If FORCE_GPX_TRACK=YES is specified, " 1275 "they will be written as tracks." ),
1280 QObject::tr(
"By default when writing a layer whose features are of " 1281 "type wkbMultiLineString, the GPX driver chooses to write " 1282 "them as tracks. If FORCE_GPX_ROUTE=YES is specified, " 1283 "they will be written as routes, provided that the multilines " 1284 "are composed of only one single line." ),
1289 QObject::tr(
"If GPX_USE_EXTENSIONS=YES is specified, " 1290 "extra fields will be written inside the <extensions> tag." ),
1295 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS_URL " 1296 "is set. The namespace value used for extension tags. By default, 'ogr'." ),
1297 QStringLiteral(
"ogr" )
1301 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS " 1302 "is set. The namespace URI. By default, 'http://osgeo.org/gdal'." ),
1303 QStringLiteral(
"http://osgeo.org/gdal" )
1307 QObject::tr(
"By default files are created with the line termination " 1308 "conventions of the local platform (CR/LF on win32 or LF " 1309 "on all other systems). This may be overridden through use " 1310 "of the LINEFORMAT layer creation option which may have a value " 1311 "of CRLF (DOS format) or LF (Unix format)." ),
1313 << QStringLiteral(
"CRLF" )
1314 << QStringLiteral(
"LF" ),
1321 QStringLiteral(
"GPS eXchange Format [GPX]" ),
1322 QObject::tr(
"GPS eXchange Format [GPX]" ),
1323 QStringLiteral(
"*.gpx" ),
1324 QStringLiteral(
"gpx" ),
1327 QStringLiteral(
"UTF-8" )
1332 datasetOptions.clear();
1333 layerOptions.clear();
1337 QStringLiteral(
"INTERLIS 1" ),
1338 QObject::tr(
"INTERLIS 1" ),
1339 QStringLiteral(
"*.itf *.xml *.ili" ),
1340 QStringLiteral(
"ili" ),
1347 datasetOptions.clear();
1348 layerOptions.clear();
1352 QStringLiteral(
"INTERLIS 2" ),
1353 QObject::tr(
"INTERLIS 2" ),
1354 QStringLiteral(
"*.xtf *.xml *.ili" ),
1355 QStringLiteral(
"ili" ),
1362 datasetOptions.clear();
1363 layerOptions.clear();
1366 QObject::tr(
"Allows you to specify the field to use for the KML <name> element." ),
1367 QStringLiteral(
"Name" )
1371 QObject::tr(
"Allows you to specify the field to use for the KML <description> element." ),
1372 QStringLiteral(
"Description" )
1376 QObject::tr(
"Allows you to specify the AltitudeMode to use for KML geometries. " 1377 "This will only affect 3D geometries and must be one of the valid KML options." ),
1379 << QStringLiteral(
"clampToGround" )
1380 << QStringLiteral(
"relativeToGround" )
1381 << QStringLiteral(
"absolute" ),
1382 QStringLiteral(
"relativeToGround" )
1385 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0) 1387 QObject::tr(
"The DOCUMENT_ID datasource creation option can be used to specified " 1388 "the id of the root <Document> node. The default value is root_doc." ),
1389 QStringLiteral(
"root_doc" )
1395 QStringLiteral(
"Keyhole Markup Language [KML]" ),
1396 QObject::tr(
"Keyhole Markup Language [KML]" ),
1397 QStringLiteral(
"*.kml" ),
1398 QStringLiteral(
"kml" ),
1401 QStringLiteral(
"UTF-8" )
1406 datasetOptions.clear();
1407 layerOptions.clear();
1409 auto insertMapInfoOptions = []( QMap<QString, QgsVectorFileWriter::Option *> &datasetOptions, QMap<QString, QgsVectorFileWriter::Option *> &layerOptions )
1412 QObject::tr(
"Use this to turn on 'quick spatial index mode'. " 1413 "In this mode writing files can be about 5 times faster, " 1414 "but spatial queries can be up to 30 times slower." ),
1416 << QStringLiteral(
"QUICK" )
1417 << QStringLiteral(
"OPTIMIZED" ),
1418 QStringLiteral(
"QUICK" ),
1423 QObject::tr(
"(multiples of 512): Block size for .map files. Defaults " 1424 "to 512. MapInfo 15.2 and above creates .tab files with a " 1425 "blocksize of 16384 bytes. Any MapInfo version should be " 1426 "able to handle block sizes from 512 to 32256." ),
1430 QObject::tr(
"xmin,ymin,xmax,ymax: Define custom layer bounds to increase the " 1431 "accuracy of the coordinates. Note: the geometry of written " 1432 "features must be within the defined box." ),
1436 insertMapInfoOptions( datasetOptions, layerOptions );
1440 QStringLiteral(
"Mapinfo" ),
1441 QObject::tr(
"Mapinfo TAB" ),
1442 QStringLiteral(
"*.tab" ),
1443 QStringLiteral(
"tab" ),
1448 datasetOptions.clear();
1449 layerOptions.clear();
1450 insertMapInfoOptions( datasetOptions, layerOptions );
1455 QStringLiteral(
"Mapinfo" ),
1456 QObject::tr(
"Mapinfo MIF" ),
1457 QStringLiteral(
"*.mif" ),
1458 QStringLiteral(
"mif" ),
1465 datasetOptions.clear();
1466 layerOptions.clear();
1469 QObject::tr(
"Determine whether 2D (seed_2d.dgn) or 3D (seed_3d.dgn) " 1470 "seed file should be used. This option is ignored if the SEED option is provided." ),
1475 QObject::tr(
"Override the seed file to use." ),
1480 QObject::tr(
"Indicate whether the whole seed file should be copied. " 1481 "If not, only the first three elements will be copied." ),
1486 QObject::tr(
"Indicates whether the color table should be copied from the seed file." ),
1491 QObject::tr(
"Override the master unit name from the seed file with " 1492 "the provided one or two character unit name." ),
1497 QObject::tr(
"Override the sub unit name from the seed file with the provided " 1498 "one or two character unit name." ),
1503 QObject::tr(
"Override the number of subunits per master unit. " 1504 "By default the seed file value is used." ),
1509 QObject::tr(
"Override the number of UORs (Units of Resolution) " 1510 "per sub unit. By default the seed file value is used." ),
1515 QObject::tr(
"ORIGIN=x,y,z: Override the origin of the design plane. " 1516 "By default the origin from the seed file is used." ),
1522 QStringLiteral(
"Microstation DGN" ),
1523 QObject::tr(
"Microstation DGN" ),
1524 QStringLiteral(
"*.dgn" ),
1525 QStringLiteral(
"dgn" ),
1532 datasetOptions.clear();
1533 layerOptions.clear();
1536 QObject::tr(
"Should update files be incorporated into the base data on the fly." ),
1538 << QStringLiteral(
"APPLY" )
1539 << QStringLiteral(
"IGNORE" ),
1540 QStringLiteral(
"APPLY" )
1544 QObject::tr(
"Should multipoint soundings be split into many single point sounding features. " 1545 "Multipoint geometries are not well handled by many formats, " 1546 "so it can be convenient to split single sounding features with many points " 1547 "into many single point features." ),
1552 QObject::tr(
"Should a DEPTH attribute be added on SOUNDG features and assign the depth " 1553 "of the sounding. This should only be enabled when SPLIT_MULTIPOINT is " 1559 QObject::tr(
"Should all the low level geometry primitives be returned as special " 1560 "IsolatedNode, ConnectedNode, Edge and Face layers." ),
1565 QObject::tr(
"If enabled, numeric attributes assigned an empty string as a value will " 1566 "be preserved as a special numeric value. This option should not generally " 1567 "be needed, but may be useful when translated S-57 to S-57 losslessly." ),
1572 QObject::tr(
"Should LNAM and LNAM_REFS fields be attached to features capturing " 1573 "the feature to feature relationships in the FFPT group of the S-57 file." ),
1578 QObject::tr(
"Should additional attributes relating features to their underlying " 1579 "geometric primitives be attached. These are the values of the FSPT group, " 1580 "and are primarily needed when doing S-57 to S-57 translations." ),
1585 QObject::tr(
"Should attribute values be recoded to UTF-8 from the character encoding " 1586 "specified in the S57 DSSI record." ),
1594 QStringLiteral(
"S-57 Base file" ),
1595 QObject::tr(
"S-57 Base file" ),
1596 QStringLiteral(
"*.000" ),
1597 QStringLiteral(
"000" ),
1604 datasetOptions.clear();
1605 layerOptions.clear();
1609 QStringLiteral(
"Spatial Data Transfer Standard [SDTS]" ),
1610 QObject::tr(
"Spatial Data Transfer Standard [SDTS]" ),
1611 QStringLiteral(
"*catd.ddf" ),
1612 QStringLiteral(
"ddf" ),
1619 datasetOptions.clear();
1620 layerOptions.clear();
1623 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys " 1624 "tables in a new database. By default these metadata tables are created " 1625 "when a new database is created." ),
1631 QStringLiteral(
"NO" )
1636 QStringLiteral(
"NO" )
1640 QObject::tr(
"Controls the format used for the geometry column. Defaults to WKB. " 1641 "This is generally more space and processing efficient, but harder " 1642 "to inspect or use in simple applications than WKT (Well Known Text)." ),
1644 << QStringLiteral(
"WKB" )
1645 << QStringLiteral(
"WKT" ),
1646 QStringLiteral(
"WKB" )
1650 QObject::tr(
"Controls whether layer and field names will be laundered for easier use " 1651 "in SQLite. Laundered names will be converted to lower case and some special " 1652 "characters(' - #) will be changed to underscores." ),
1657 QStringLiteral(
"NO" )
1661 QStringLiteral(
"NO" )
1669 QObject::tr(
"column_name1[,column_name2, …] A list of (String) columns that " 1670 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial " 1671 "for databases that have big string blobs. However, use with care, since " 1672 "the value of such columns will be seen as compressed binary content with " 1673 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, " 1674 "modifying or querying compressed columns, compression/decompression is " 1675 "done transparently. However, such columns cannot be (easily) queried with " 1676 "an attribute filter or WHERE clause. Note: in table definition, such columns " 1677 "have the 'VARCHAR_deflate' declaration type." ),
1683 QStringLiteral(
"SQLite" ),
1684 QObject::tr(
"SQLite" ),
1685 QStringLiteral(
"*.sqlite" ),
1686 QStringLiteral(
"sqlite" ),
1689 QStringLiteral(
"UTF-8" )
1694 datasetOptions.clear();
1695 layerOptions.clear();
1698 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys " 1699 "tables in a new database. By default these metadata tables are created " 1700 "when a new database is created." ),
1705 QStringLiteral(
"YES" )
1709 QObject::tr(
"Insert the content of the EPSG CSV files into the spatial_ref_sys table. " 1710 "Set to NO for regular SQLite databases." ),
1715 QStringLiteral(
"SPATIALITE" )
1719 QObject::tr(
"Controls whether layer and field names will be laundered for easier use " 1720 "in SQLite. Laundered names will be converted to lower case and some special " 1721 "characters(' - #) will be changed to underscores." ),
1726 QObject::tr(
"If the database is of the SpatiaLite flavor, and if OGR is linked " 1727 "against libspatialite, this option can be used to control if a spatial " 1728 "index must be created." ),
1733 QObject::tr(
"If the format of the geometry BLOB is of the SpatiaLite flavor, " 1734 "this option can be used to control if the compressed format for " 1735 "geometries (LINESTRINGs, POLYGONs) must be used." ),
1740 QObject::tr(
"Used to force the SRID number of the SRS associated with the layer. " 1741 "When this option isn't specified and that a SRS is associated with the " 1742 "layer, a search is made in the spatial_ref_sys to find a match for the " 1743 "SRS, and, if there is no match, a new entry is inserted for the SRS in " 1744 "the spatial_ref_sys table. When the SRID option is specified, this " 1745 "search (and the eventual insertion of a new entry) will not be done: " 1746 "the specified SRID is used as such." ),
1751 QObject::tr(
"column_name1[,column_name2, …] A list of (String) columns that " 1752 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial " 1753 "for databases that have big string blobs. However, use with care, since " 1754 "the value of such columns will be seen as compressed binary content with " 1755 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, " 1756 "modifying or queryings compressed columns, compression/decompression is " 1757 "done transparently. However, such columns cannot be (easily) queried with " 1758 "an attribute filter or WHERE clause. Note: in table definition, such columns " 1759 "have the 'VARCHAR_deflate' declaration type." ),
1765 QStringLiteral(
"SpatiaLite" ),
1766 QObject::tr(
"SpatiaLite" ),
1767 QStringLiteral(
"*.sqlite" ),
1768 QStringLiteral(
"sqlite" ),
1771 QStringLiteral(
"UTF-8" )
1775 datasetOptions.clear();
1776 layerOptions.clear();
1779 QObject::tr(
"Override the header file used - in place of header.dxf." ),
1784 QObject::tr(
"Override the trailer file used - in place of trailer.dxf." ),
1790 QStringLiteral(
"AutoCAD DXF" ),
1791 QObject::tr(
"AutoCAD DXF" ),
1792 QStringLiteral(
"*.dxf" ),
1793 QStringLiteral(
"dxf" ),
1800 datasetOptions.clear();
1801 layerOptions.clear();
1804 QObject::tr(
"Indicates the GeoConcept export file extension. " 1805 "TXT was used by earlier releases of GeoConcept. GXT is currently used." ),
1807 << QStringLiteral(
"GXT" )
1808 << QStringLiteral(
"TXT" ),
1809 QStringLiteral(
"GXT" )
1813 QObject::tr(
"Path to the GCT: the GCT file describes the GeoConcept types definitions: " 1814 "In this file, every line must start with //# followed by a keyword. " 1815 "Lines starting with // are comments." ),
1820 QObject::tr(
"Defines the feature to be created. The TYPE corresponds to one of the Name " 1821 "found in the GCT file for a type section. The SUBTYPE corresponds to one of " 1822 "the Name found in the GCT file for a sub-type section within the previous " 1829 QStringLiteral(
"Geoconcept" ),
1830 QObject::tr(
"Geoconcept" ),
1831 QStringLiteral(
"*.gxt *.txt" ),
1832 QStringLiteral(
"gxt" ),
1839 datasetOptions.clear();
1840 layerOptions.clear();
1843 QObject::tr(
"When this option is set, the new layer will be created inside the named " 1844 "FeatureDataset folder. If the folder does not already exist, it will be created." ),
1849 QObject::tr(
"Set name of geometry column in new layer. Defaults to 'SHAPE'." ),
1850 QStringLiteral(
"SHAPE" )
1854 QObject::tr(
"Name of the OID column to create. Defaults to 'OBJECTID'." ),
1855 QStringLiteral(
"OBJECTID" )
1860 QStringLiteral(
"ESRI FileGDB" ),
1861 QObject::tr(
"ESRI FileGDB" ),
1862 QStringLiteral(
"*.gdb" ),
1863 QStringLiteral(
"gdb" ),
1866 QStringLiteral(
"UTF-8" )
1871 datasetOptions.clear();
1872 layerOptions.clear();
1875 QObject::tr(
"By default, the driver will try to detect the data type of fields. If set " 1876 "to STRING, all fields will be of String type." ),
1878 << QStringLiteral(
"AUTO" )
1879 << QStringLiteral(
"STRING" ),
1880 QStringLiteral(
"AUTO" ),
1885 QObject::tr(
"By default, the driver will read the first lines of each sheet to detect " 1886 "if the first line might be the name of columns. If set to FORCE, the driver " 1887 "will consider the first line as the header line. If set to " 1888 "DISABLE, it will be considered as the first feature. Otherwise " 1889 "auto-detection will occur." ),
1891 << QStringLiteral(
"FORCE" )
1892 << QStringLiteral(
"DISABLE" )
1893 << QStringLiteral(
"AUTO" ),
1894 QStringLiteral(
"AUTO" ),
1900 QStringLiteral(
"MS Office Open XML spreadsheet" ),
1901 QObject::tr(
"MS Office Open XML spreadsheet [XLSX]" ),
1902 QStringLiteral(
"*.xlsx" ),
1903 QStringLiteral(
"xlsx" ),
1906 QStringLiteral(
"UTF-8" )
1911 datasetOptions.clear();
1912 layerOptions.clear();
1915 QObject::tr(
"By default, the driver will try to detect the data type of fields. If set " 1916 "to STRING, all fields will be of String type." ),
1918 << QStringLiteral(
"AUTO" )
1919 << QStringLiteral(
"STRING" ),
1920 QStringLiteral(
"AUTO" ),
1925 QObject::tr(
"By default, the driver will read the first lines of each sheet to detect " 1926 "if the first line might be the name of columns. If set to FORCE, the driver " 1927 "will consider the first line as the header line. If set to " 1928 "DISABLE, it will be considered as the first feature. Otherwise " 1929 "auto-detection will occur." ),
1931 << QStringLiteral(
"FORCE" )
1932 << QStringLiteral(
"DISABLE" )
1933 << QStringLiteral(
"AUTO" ),
1934 QStringLiteral(
"AUTO" ),
1940 QStringLiteral(
"Open Document Spreadsheet" ),
1941 QObject::tr(
"Open Document Spreadsheet [ODS]" ),
1942 QStringLiteral(
"*.ods" ),
1943 QStringLiteral(
"ods" ),
1946 QStringLiteral(
"UTF-8" )
1951 QgsVectorFileWriterMetadataContainer(
const QgsVectorFileWriterMetadataContainer &other ) =
delete;
1952 QgsVectorFileWriterMetadataContainer &
operator=(
const QgsVectorFileWriterMetadataContainer &other ) =
delete;
1953 ~QgsVectorFileWriterMetadataContainer()
1957 for (
auto optionIt = it.value().driverOptions.constBegin(); optionIt != it.value().driverOptions.constEnd(); ++optionIt )
1958 delete optionIt.value();
1959 for (
auto optionIt = it.value().layerOptions.constBegin(); optionIt != it.value().layerOptions.constEnd(); ++optionIt )
1960 delete optionIt.value();
1971 static QgsVectorFileWriterMetadataContainer sDriverMetadata;
1972 QMap<QString, MetaData>::ConstIterator it = sDriverMetadata.driverMetadata.constBegin();
1974 for ( ; it != sDriverMetadata.driverMetadata.constEnd(); ++it )
1976 if ( it.key().startsWith( driverName ) || it.value().longName.startsWith( driverName ) )
1978 driverMetadata = it.value();
1991 return QStringList();
2000 return QStringList();
2007 OGRwkbGeometryType ogrType =
static_cast<OGRwkbGeometryType
>( type );
2033 QgsFeatureList::iterator fIt = features.begin();
2035 for ( ; fIt != features.end(); ++fIt )
2052 mRenderContext.expressionContext().setFeature( feature );
2055 QString styleString;
2056 QString currentStyle;
2058 QgsSymbolList::const_iterator symbolIt = symbols.constBegin();
2059 for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
2061 int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
2062 for (
int i = 0; i < nSymbolLayers; ++i )
2065 QMap< QgsSymbolLayer *, QString >::const_iterator it =
mSymbolLayerTable.find( ( *symbolIt )->symbolLayer( i ) );
2071 double mmsf = mmScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
2072 double musf = mapUnitScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
2074 currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
2078 if ( symbolIt != symbols.constBegin() || i != 0 )
2080 styleString.append(
';' );
2082 styleString.append( currentStyle );
2086 OGR_F_SetStyleString( poFeature.get(), currentStyle.toLocal8Bit().constData() );
2087 if ( !writeFeature(
mLayer, poFeature.get() ) )
2094 OGR_F_SetStyleString( poFeature.get(), styleString.toLocal8Bit().constData() );
2099 if ( !writeFeature(
mLayer, poFeature.get() ) )
2116 if ( fid > std::numeric_limits<int>::max() )
2118 QgsDebugMsg( QStringLiteral(
"feature id %1 too large." ).arg( fid ) );
2119 OGRErr err = OGR_F_SetFID( poFeature.get(),
static_cast<long>( fid ) );
2120 if ( err != OGRERR_NONE )
2122 QgsDebugMsg( QStringLiteral(
"Failed to set feature id to %1: %2 (OGR error: %3)" )
2123 .arg( feature.
id() )
2124 .arg( err ).arg( CPLGetLastErrorMsg() )
2132 int fldIdx = it.key();
2133 int ogrField = it.value();
2135 QVariant attrValue = feature.
attribute( fldIdx );
2138 if ( !attrValue.isValid() || attrValue.isNull() )
2147 #ifdef OGRNullMarker 2148 OGR_F_SetFieldNull( poFeature.get(), ogrField );
2159 switch ( field.
type() )
2162 OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
2164 case QVariant::LongLong:
2165 OGR_F_SetFieldInteger64( poFeature.get(), ogrField, attrValue.toLongLong() );
2167 case QVariant::Bool:
2168 OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
2170 case QVariant::String:
2171 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toString() ).constData() );
2173 case QVariant::Double:
2174 OGR_F_SetFieldDouble( poFeature.get(), ogrField, attrValue.toDouble() );
2176 case QVariant::Date:
2177 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2178 attrValue.toDate().year(),
2179 attrValue.toDate().month(),
2180 attrValue.toDate().day(),
2183 case QVariant::DateTime:
2186 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toDateTime().toString( QStringLiteral(
"yyyy/MM/dd hh:mm:ss.zzz" ) ) ).constData() );
2190 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2191 attrValue.toDateTime().date().year(),
2192 attrValue.toDateTime().date().month(),
2193 attrValue.toDateTime().date().day(),
2194 attrValue.toDateTime().time().hour(),
2195 attrValue.toDateTime().time().minute(),
2196 attrValue.toDateTime().time().second(),
2200 case QVariant::Time:
2203 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toString() ).constData() );
2207 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2209 attrValue.toTime().hour(),
2210 attrValue.toTime().minute(),
2211 attrValue.toTime().second(),
2216 case QVariant::ByteArray:
2218 const QByteArray ba = attrValue.toByteArray();
2219 OGR_F_SetFieldBinary( poFeature.get(), ogrField, ba.size(),
const_cast< GByte *
>(
reinterpret_cast< const GByte *
>( ba.data() ) ) );
2223 case QVariant::Invalid:
2226 mErrorMessage = QObject::tr(
"Invalid variant type for field %1[%2]: received %3 with type %4" )
2229 .arg( attrValue.typeName(),
2230 attrValue.toString() );
2253 OGRGeometryH mGeom2 =
nullptr;
2299 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2300 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2306 QByteArray wkb( geom.
asWkb() );
2307 OGRErr err = OGR_G_ImportFromWkb( mGeom2, reinterpret_cast<unsigned char *>( const_cast<char *>( wkb.constData() ) ), wkb.length() );
2308 if ( err != OGRERR_NONE )
2310 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2311 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2318 OGR_F_SetGeometryDirectly( poFeature.get(), mGeom2 );
2322 QByteArray wkb( geom.
asWkb() );
2324 OGRErr err = OGR_G_ImportFromWkb( ogrGeom, reinterpret_cast<unsigned char *>( const_cast<char *>( wkb.constData() ) ), wkb.length() );
2325 if ( err != OGRERR_NONE )
2327 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2328 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2335 OGR_F_SetGeometryDirectly( poFeature.get(), ogrGeom );
2350 for (
int i = 0; i < attributes.size(); i++ )
2352 if ( omap.find( i ) != omap.end() )
2357 bool QgsVectorFileWriter::writeFeature( OGRLayerH layer, OGRFeatureH feature )
2359 if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
2361 mErrorMessage = QObject::tr(
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2371 if ( mUsingTransaction )
2373 if ( OGRERR_NONE != OGR_L_CommitTransaction(
mLayer ) )
2375 QgsDebugMsg( QStringLiteral(
"Error while committing transaction on OGRLayer." ) );
2383 OSRDestroySpatialReference(
mOgrRef );
2389 const QString &fileName,
2390 const QString &fileEncoding,
2392 const QString &driverName,
2395 const QStringList &datasourceOptions,
2396 const QStringList &layerOptions,
2397 bool skipAttributeCreation,
2398 QString *newFilename,
2410 if ( destCRS.
isValid() && layer )
2418 errorMessage, datasourceOptions, layerOptions, skipAttributeCreation,
2419 newFilename, symbologyExport, symbologyScale, filterExtent,
2420 overrideGeometryType, forceMulti, includeZ, attributes,
2421 fieldValueConverter, newLayer );
2426 const QString &fileName,
2427 const QString &fileEncoding,
2429 const QString &driverName,
2432 const QStringList &datasourceOptions,
2433 const QStringList &layerOptions,
2434 bool skipAttributeCreation,
2435 QString *newFilename,
2463 return writeAsVectorFormat( layer, fileName, options, newFilename, errorMessage, newLayer );
2468 : driverName( QStringLiteral(
"GPKG" ) )
2484 details.sourceCrs = layer->
crs();
2485 details.sourceWkbType = layer->
wkbType();
2486 details.sourceFields = layer->
fields();
2495 if ( details.storageType == QLatin1String(
"ESRI Shapefile" ) )
2503 details.geometryTypeScanIterator = layer->
getFeatures( req );
2507 details.renderContext.setExpressionContext( details.expressionContext );
2508 details.renderContext.setRendererScale( options.
symbologyScale );
2510 details.shallTransform =
false;
2515 details.shallTransform =
true;
2520 details.outputCrs = details.sourceCrs;
2523 details.destWkbType = details.sourceWkbType;
2537 details.attributes.clear();
2538 else if ( details.attributes.isEmpty() )
2540 const QgsAttributeList allAttributes = details.sourceFields.allAttributesList();
2541 for (
int idx : allAttributes )
2543 QgsField fld = details.sourceFields.at( idx );
2544 if ( details.providerType == QLatin1String(
"oracle" ) && fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) )
2546 details.attributes.append( idx );
2550 if ( !details.attributes.isEmpty() )
2552 for (
int attrIdx : qgis::as_const( details.attributes ) )
2554 details.outputFields.append( details.sourceFields.at( attrIdx ) );
2560 if ( details.providerType == QLatin1String(
"spatialite" ) )
2562 for (
int i = 0; i < details.outputFields.size(); i++ )
2564 if ( details.outputFields.at( i ).type() == QVariant::LongLong )
2568 if ( std::max( std::llabs( min.toLongLong() ), std::llabs( max.toLongLong() ) ) < std::numeric_limits<int>::max() )
2570 details.outputFields[i].setType( QVariant::Int );
2578 addRendererAttributes( details.renderer.get(), details.renderContext, details.sourceFields, details.attributes );
2588 bool useFilterRect =
true;
2589 if ( details.shallTransform )
2598 useFilterRect =
false;
2601 if ( useFilterRect )
2603 req.setFilterRect( filterRect );
2607 details.filterRectEngine->prepareGeometry();
2609 details.sourceFeatureIterator = layer->
getFeatures( req );
2619 int lastProgressReport = 0;
2620 long total = details.featureCount;
2623 if ( details.providerType == QLatin1String(
"ogr" ) && !details.dataSourceUri.isEmpty() )
2625 QString srcFileName( details.providerUriParams.value( QLatin1String(
"path" ) ).toString() );
2626 if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
2630 if ( !( ( options.
driverName == QLatin1String(
"GPKG" ) ||
2631 options.
driverName == QLatin1String(
"SpatiaLite" ) ||
2632 options.
driverName == QLatin1String(
"SQLite" ) ) &&
2633 options.
layerName != details.providerUriParams.value( QLatin1String(
"layerName" ) ) ) )
2636 *errorMessage = QObject::tr(
"Cannot overwrite a OGR layer in place" );
2656 int newProgress =
static_cast<int>( ( 5.0 * scanned ) / total );
2657 if ( newProgress != lastProgressReport )
2659 lastProgressReport = newProgress;
2674 std::unique_ptr< QgsVectorFileWriter > writer =
2675 qgis::make_unique< QgsVectorFileWriter >( fileName,
2676 options.
fileEncoding, details.outputFields, destWkbType,
2698 *errorMessage = writer->errorMessage();
2704 errorMessage->clear();
2726 int n = 0, errors = 0;
2735 writer->startRender( details.renderer.get(), details.sourceFields );
2737 writer->resetMap( details.attributes );
2739 writer->mFields = details.sourceFields;
2743 int initialProgress = lastProgressReport;
2744 while ( details.sourceFeatureIterator.nextFeature( fet ) )
2755 int newProgress =
static_cast<int>( initialProgress + ( ( 100.0 - initialProgress ) * saved ) / total );
2756 if ( newProgress < 100 && newProgress != lastProgressReport )
2758 lastProgressReport = newProgress;
2763 if ( details.shallTransform )
2776 QString msg = QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
2777 .arg( fet.
id() ).arg( e.
what() );
2780 *errorMessage = msg;
2794 if ( !writer->addFeatureWithStyle( fet, writer->mRenderer.get(), mapUnits ) )
2797 if ( err !=
NoError && errorMessage )
2799 if ( errorMessage->isEmpty() )
2801 *errorMessage = QObject::tr(
"Feature write errors:" );
2803 *errorMessage +=
'\n' + writer->errorMessage();
2807 if ( errors > 1000 )
2811 *errorMessage += QObject::tr(
"Stopping after %1 errors" ).arg( errors );
2821 writer->stopRender();
2823 if ( errors > 0 && errorMessage && n > 0 )
2825 *errorMessage += QObject::tr(
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
2833 const QString &fileName,
2835 QString *newFilename,
2836 QString *errorMessage,
2839 QgsVectorFileWriter::PreparedWriterDetails details;
2840 WriterError err = prepareWriteAsVectorFormat( layer, options, details );
2844 return writeAsVectorFormat( details, fileName, options, newFilename, errorMessage, newLayer );
2850 QFileInfo fi( fileName );
2851 QDir dir = fi.dir();
2854 const char *suffixes[] = {
".shp",
".shx",
".dbf",
".prj",
".qix",
".qpj" };
2855 for ( std::size_t i = 0; i <
sizeof( suffixes ) /
sizeof( *suffixes ); i++ )
2857 filter << fi.completeBaseName() + suffixes[i];
2861 Q_FOREACH (
const QString &file, dir.entryList( filter ) )
2863 QFile f( dir.canonicalPath() +
'/' + file );
2866 QgsDebugMsg( QStringLiteral(
"Removing file %1 failed: %2" ).arg( file, f.errorString() ) );
2882 QList< FilterFormatDetails > results;
2885 int const drvCount = OGRGetDriverCount();
2887 for (
int i = 0; i < drvCount; ++i )
2889 OGRSFDriverH drv = OGRGetDriver( i );
2892 QString drvName = OGR_Dr_GetName( drv );
2894 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0) 2895 GDALDriverH gdalDriver = GDALGetDriverByName( drvName.toLocal8Bit().constData() );
2896 char **metadata =
nullptr;
2899 metadata = GDALGetMetadata( gdalDriver,
nullptr );
2902 bool nonSpatialFormat = CSLFetchBoolean( metadata, GDAL_DCAP_NONSPATIAL,
false );
2904 bool nonSpatialFormat = ( drvName == QLatin1String(
"ODS" ) || drvName == QLatin1String(
"XLSX" ) || drvName == QLatin1String(
"XLS" ) );
2907 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2912 if ( nonSpatialFormat )
2917 if ( filterString.isEmpty() )
2924 globs = metadata.
glob.toLower().split(
' ' );
2930 details.
globs = globs;
2941 if ( a.
driverName == QLatin1String(
"GPKG" ) )
2943 else if ( b.driverName == QLatin1String(
"GPKG" ) )
2945 else if ( a.
driverName == QLatin1String(
"ESRI Shapefile" ) )
2947 else if ( b.driverName == QLatin1String(
"ESRI Shapefile" ) )
2951 return a.
filterString.toLower().localeAwareCompare( b.filterString.toLower() ) < 0;
2960 QSet< QString > extensions;
2962 const QRegularExpression rx( QStringLiteral(
"\\*\\.(.*)$" ) );
2966 for (
const QString &glob : format.globs )
2968 const QRegularExpressionMatch match = rx.match( glob );
2969 if ( !match.hasMatch() )
2972 const QString matched = match.captured( 1 );
2973 extensions.insert( matched );
2977 QStringList extensionList = extensions.toList();
2979 std::sort( extensionList.begin(), extensionList.end(), [options](
const QString & a,
const QString & b ) ->
bool 2983 if ( a == QLatin1String(
"gpkg" ) )
2985 else if ( b == QLatin1String(
"gpkg" ) )
2987 else if ( a == QLatin1String(
"shp" ) )
2989 else if ( b == QLatin1String(
"shp" ) )
2993 return a.toLower().localeAwareCompare( b.toLower() ) < 0;
2996 return extensionList;
3001 QList< QgsVectorFileWriter::DriverDetails > results;
3004 const int drvCount = OGRGetDriverCount();
3006 QStringList writableDrivers;
3007 for (
int i = 0; i < drvCount; ++i )
3009 OGRSFDriverH drv = OGRGetDriver( i );
3012 QString drvName = OGR_Dr_GetName( drv );
3018 if ( drvName == QLatin1String(
"ODS" ) || drvName == QLatin1String(
"XLSX" ) || drvName == QLatin1String(
"XLS" ) )
3022 if ( drvName == QLatin1String(
"ESRI Shapefile" ) )
3024 writableDrivers << QStringLiteral(
"DBF file" );
3026 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
3029 if ( drvName == QLatin1String(
"MapInfo File" ) )
3031 writableDrivers << QStringLiteral(
"MapInfo MIF" );
3033 else if ( drvName == QLatin1String(
"SQLite" ) )
3040 QString option = QStringLiteral(
"SPATIALITE=YES" );
3041 char *options[2] = { CPLStrdup( option.toLocal8Bit().constData() ),
nullptr };
3042 OGRSFDriverH poDriver;
3044 poDriver = OGRGetDriverByName( drvName.toLocal8Bit().constData() );
3047 gdal::ogr_datasource_unique_ptr ds( OGR_Dr_CreateDataSource( poDriver, QStringLiteral(
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData(), options ) );
3050 writableDrivers << QStringLiteral(
"SpatiaLite" );
3051 OGR_Dr_DeleteDataSource( poDriver, QStringLiteral(
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData() );
3054 CPLFree( options[0] );
3056 writableDrivers << drvName;
3061 results.reserve( writableDrivers.count() );
3062 for (
const QString &drvName : qgis::as_const( writableDrivers ) )
3078 if ( a.
driverName == QLatin1String(
"GPKG" ) )
3080 else if ( b.driverName == QLatin1String(
"GPKG" ) )
3082 else if ( a.
driverName == QLatin1String(
"ESRI Shapefile" ) )
3084 else if ( b.driverName == QLatin1String(
"ESRI Shapefile" ) )
3088 return a.
longName.toLower().localeAwareCompare( b.longName.toLower() ) < 0;
3095 QString ext = extension.trimmed();
3096 if ( ext.isEmpty() )
3099 if ( ext.startsWith(
'.' ) )
3103 int const drvCount = GDALGetDriverCount();
3105 for (
int i = 0; i < drvCount; ++i )
3107 GDALDriverH drv = GDALGetDriver( i );
3111 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE,
false ) && CSLFetchBoolean( driverMetadata, GDAL_DCAP_VECTOR,
false ) )
3113 QString drvName = GDALGetDriverShortName( drv );
3114 QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
3116 Q_FOREACH (
const QString &driver, driverExtensions )
3118 if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
3129 QString filterString;
3133 if ( !filterString.isEmpty() )
3134 filterString += QLatin1String(
";;" );
3136 filterString += details.filterString;
3138 return filterString;
3147 return QStringLiteral(
"%1 (%2 %3)" ).arg( metadata.
trLongName,
3148 metadata.
glob.toLower(),
3149 metadata.
glob.toUpper() );
3154 if ( codecName == QLatin1String(
"System" ) )
3155 return QStringLiteral(
"LDID/0" );
3157 QRegExp re = QRegExp( QString(
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
3158 if ( re.exactMatch( codecName ) )
3160 QString
c = re.cap( 2 ).remove(
'-' );
3162 c.toInt( &isNumber );
3190 OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
3191 OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
3194 int nTotalLevels = 0;
3196 QgsSymbolList::iterator symbolIt = symbolList.begin();
3197 for ( ; symbolIt != symbolList.end(); ++symbolIt )
3199 double mmsf = mmScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
3200 double musf = mapUnitScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
3202 int nLevels = ( *symbolIt )->symbolLayerCount();
3203 for (
int i = 0; i < nLevels; ++i )
3205 mSymbolLayerTable.insert( ( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
3206 OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
3207 ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
3211 OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
3217 if ( !details.renderer )
3220 mRenderContext.expressionContext() = details.expressionContext;
3222 QHash< QgsSymbol *, QList<QgsFeature> > features;
3231 startRender( details.renderer.get(), details.sourceFields );
3242 if ( fet.hasGeometry() )
3246 fet.setGeometry( g );
3251 QString msg = QObject::tr(
"Failed to transform, writing stopped. (Exception: %1)" )
3255 *errorMessage = msg;
3260 mRenderContext.expressionContext().setFeature( fet );
3262 featureSymbol = mRenderer->symbolForFeature( fet, mRenderContext );
3263 if ( !featureSymbol )
3268 QHash< QgsSymbol *, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
3269 if ( it == features.end() )
3271 it = features.insert( featureSymbol, QList<QgsFeature>() );
3273 it.value().append( fet );
3278 QgsSymbolList symbols = mRenderer->symbols( mRenderContext );
3279 for (
int i = 0; i < symbols.count(); i++ )
3285 if ( level < 0 || level >= 1000 )
3288 while ( level >= levels.count() )
3290 levels[level].append( item );
3295 int nTotalFeatures = 0;
3298 for (
int l = 0; l < levels.count(); l++ )
3301 for (
int i = 0; i < level.count(); i++ )
3304 QHash< QgsSymbol *, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
3305 if ( levelIt == features.end() )
3311 double mmsf = mmScaleFactor(
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
3312 double musf = mapUnitScaleFactor(
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
3314 int llayer = item.
layer();
3315 QList<QgsFeature> &featureList = levelIt.value();
3316 QList<QgsFeature>::iterator featureIt = featureList.begin();
3317 for ( ; featureIt != featureList.end(); ++featureIt )
3327 QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
3328 if ( !styleString.isEmpty() )
3330 OGR_F_SetStyleString( ogrFeature.get(), styleString.toLocal8Bit().constData() );
3331 if ( !writeFeature(
mLayer, ogrFeature.get() ) )
3342 if ( nErrors > 0 && errorMessage )
3344 *errorMessage += QObject::tr(
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
3361 return 1000 / scale;
3378 return scale / 1000;
3386 mRenderer = createSymbologyRenderer( sourceRenderer );
3392 mRenderer->startRender( mRenderContext, fields );
3395 void QgsVectorFileWriter::stopRender()
3402 mRenderer->stopRender( mRenderContext );
3405 std::unique_ptr<QgsFeatureRenderer> QgsVectorFileWriter::createSymbologyRenderer(
QgsFeatureRenderer *sourceRenderer )
const 3411 if ( !sourceRenderer )
3416 return std::unique_ptr< QgsFeatureRenderer >( sourceRenderer->
clone() );
3423 const QSet<QString> rendererAttributes = renderer->
usedAttributes( context );
3424 for (
const QString &attr : rendererAttributes )
3429 attList.append( index );
3435 QStringList QgsVectorFileWriter::concatenateOptions(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
3438 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
3440 for ( it = options.constBegin(); it != options.constEnd(); ++it )
3443 switch ( option->
type )
3450 list.append( QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( opt->
defaultValue ) );
3460 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
3470 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
3479 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue ) );
3490 OGRSFDriverH hDriver =
nullptr;
3494 QString drvName = OGR_Dr_GetName( hDriver );
3495 QgsVectorFileWriter::EditionCapabilities caps =
nullptr;
3496 if ( OGR_DS_TestCapability( hDS.get(), ODsCCreateLayer ) )
3501 if ( !( drvName == QLatin1String(
"ESRI Shapefile" ) && QFile::exists( datasetName ) ) )
3504 if ( OGR_DS_TestCapability( hDS.get(), ODsCDeleteLayer ) )
3508 int layer_count = OGR_DS_GetLayerCount( hDS.get() );
3511 OGRLayerH hLayer = OGR_DS_GetLayer( hDS.get(), 0 );
3514 if ( OGR_L_TestCapability( hLayer, OLCSequentialWrite ) )
3517 if ( OGR_L_TestCapability( hLayer, OLCCreateField ) )
3528 const QString &layerNameIn )
3530 OGRSFDriverH hDriver =
nullptr;
3536 if ( layerName.isEmpty() )
3537 layerName = QFileInfo( datasetName ).baseName();
3539 return OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
3548 OGRSFDriverH hDriver =
nullptr;
3552 OGRLayerH hLayer = OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
3558 OGRFeatureDefnH defn = OGR_L_GetLayerDefn( hLayer );
3559 Q_FOREACH (
int idx, attributes )
3562 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.
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Append features to existing layer, but do not create new fields.
Wrapper for iterator of features from vector data provider or vector layer.
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.
int size() const
Returns number of items.
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.
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.
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
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.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
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) ...
QList< QgsFeature > QgsFeatureList
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
SymbologyExport mSymbologyExport
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)
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
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...
#define Q_NOWARN_DEPRECATED_PUSH
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QMap< QgsSymbolLayer *, QString > mSymbolLayerTable
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)
Breaks a provider data source URI into its component paths (e.g.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
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
bool hasGeometry() const
Returns true if the feature has an associated geometry.
int count() const
Returns number of items.
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. ...
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
QList< QgsSymbolLevel > QgsSymbolLevelOrder
QgsVectorFileWriter::SymbologyExport symbologyExport
Symbology to export.
Create or overwrite file.
QgsVectorFileWriter::SymbologyExport symbologyExport() const
~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()
virtual QgsVectorFileWriter::FieldValueConverter * clone() const
Creates a clone of the FieldValueConverter.
void setSymbologyScale(double scale)
Set reference scale for output.
int renderingPass() const
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
QgsFields fields() const FINAL
Returns the list of fields of this layer.
const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in 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.
QString typeName() const
Gets the field type.
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.
long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
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).
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Gets the data source specification.
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.
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
Create or overwrite layer.
ActionOnExistingFile
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
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.
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...
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
QByteArray asWkb() const
Export the geometry to WKB.
double symbologyScale() const
Returns the reference scale for output.
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.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
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.
Contains information about the context of a rendering operation.
bool usingSymbolLevels() const
static QString convertCodecNameForEncodingOption(const QString &codecName)
Converts codec name to string passed to ENCODING layer creation option of OGR Shapefile.
virtual QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const
Returns list of symbols used for rendering the feature.
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.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets feature IDs that should be fetched.
bool isCanceled() const
Tells whether the operation has been canceled already.
QList< QgsSymbolLevelItem > QgsSymbolLevel
bool skipAttributeCreation
Only write geometries.
double symbologyScale
Scale of symbology.
virtual QgsSymbolList symbols(QgsRenderContext &context) const
Returns list of symbols used by the renderer.
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).
QString toWkt() const
Returns a WKT representation of this 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 isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
#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, it may be null.
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 cancelation 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.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
static Type flatType(Type type)
Returns the flat type for a WKB type.
Writing was interrupted by manual cancelation.
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)
bool isValid() const
Returns whether this CRS is correctly initialized and usable.