41 #include <QTextStream> 49 #include <ogr_srs_api.h> 50 #include <cpl_error.h> 52 #include <cpl_string.h> 58 static OGRDataSourceH myOGROpen(
const char *pszName,
int bUpdate, OGRSFDriverH *phDriver )
60 OGRSFDriverH hDriver =
nullptr;
61 OGRDataSourceH hDS = OGROpen( pszName, bUpdate, &hDriver );
64 QString drvName = OGR_Dr_GetName( hDriver );
65 if ( drvName ==
"BNA" )
67 OGR_DS_Destroy( hDS );
94 const QString &vectorFileName,
95 const QString &fileEncoding,
99 const QString &driverName,
100 const QStringList &datasourceOptions,
101 const QStringList &layerOptions,
102 QString *newFilename,
110 init( vectorFileName, fileEncoding, fields, geometryType,
111 srs, driverName, datasourceOptions, layerOptions, newFilename,
nullptr,
116 const QString &fileEncoding,
120 const QString &driverName,
121 const QStringList &datasourceOptions,
122 const QStringList &layerOptions,
123 QString *newFilename,
126 const QString &layerName,
133 init( vectorFileName, fileEncoding, fields, geometryType, srs, driverName,
134 datasourceOptions, layerOptions, newFilename, fieldValueConverter,
140 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0) 141 GDALDriverH gdalDriver = GDALGetDriverByName( driverName.toLocal8Bit().constData() );
146 if ( !driverMetadata )
149 return CSLFetchBoolean( driverMetadata, GDAL_DCAP_FEATURE_STYLES,
false );
151 return driverName == QLatin1String(
"DXF" ) || driverName == QLatin1String(
"KML" ) || driverName == QLatin1String(
"MapInfo File" ) || driverName == QLatin1String(
"MapInfo MIF" );
155 void QgsVectorFileWriter::init( QString vectorFileName,
156 QString fileEncoding,
160 const QString &driverName,
161 QStringList datasourceOptions,
162 QStringList layerOptions,
163 QString *newFilename,
165 const QString &layerNameIn,
170 if ( vectorFileName.isEmpty() )
177 if ( driverName == QLatin1String(
"MapInfo MIF" ) )
181 else if ( driverName == QLatin1String(
"SpatiaLite" ) )
184 if ( !datasourceOptions.contains( QStringLiteral(
"SPATIALITE=YES" ) ) )
186 datasourceOptions.append( QStringLiteral(
"SPATIALITE=YES" ) );
189 else if ( driverName == QLatin1String(
"DBF file" ) )
192 if ( !layerOptions.contains( QStringLiteral(
"SHPT=NULL" ) ) )
194 layerOptions.append( QStringLiteral(
"SHPT=NULL" ) );
204 OGRSFDriverH poDriver;
207 poDriver = OGRGetDriverByName(
mOgrDriverName.toLocal8Bit().constData() );
211 mErrorMessage = QObject::tr(
"OGR driver for '%1' not found (OGR error: %2)" )
213 QString::fromUtf8( CPLGetLastErrorMsg() ) );
223 if ( layerOptions.join( QLatin1String(
"" ) ).toUpper().indexOf( QLatin1String(
"ENCODING=" ) ) == -1 )
228 if ( driverName == QLatin1String(
"ESRI Shapefile" ) && !vectorFileName.endsWith( QLatin1String(
".shp" ), Qt::CaseInsensitive ) )
230 vectorFileName += QLatin1String(
".shp" );
232 else if ( driverName == QLatin1String(
"DBF file" ) && !vectorFileName.endsWith( QLatin1String(
".dbf" ), Qt::CaseInsensitive ) )
234 vectorFileName += QLatin1String(
".dbf" );
244 QStringList allExts = metadata.
ext.split(
' ', QString::SkipEmptyParts );
246 Q_FOREACH (
const QString &ext, allExts )
248 if ( vectorFileName.endsWith(
'.' + ext, Qt::CaseInsensitive ) )
257 vectorFileName +=
'.' + allExts[0];
263 if ( vectorFileName.endsWith( QLatin1String(
".gdb" ), Qt::CaseInsensitive ) )
265 QDir dir( vectorFileName );
268 QFileInfoList fileList = dir.entryInfoList(
269 QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst );
270 Q_FOREACH (
const QFileInfo &info, fileList )
272 QFile::remove( info.absoluteFilePath() );
275 QDir().rmdir( vectorFileName );
279 QFile::remove( vectorFileName );
294 char **options =
nullptr;
295 if ( !datasourceOptions.isEmpty() )
297 options =
new char *[ datasourceOptions.size() + 1 ];
298 for (
int i = 0; i < datasourceOptions.size(); i++ )
300 QgsDebugMsg( QString(
"-dsco=%1" ).arg( datasourceOptions[i] ) );
301 options[i] = CPLStrdup( datasourceOptions[i].toLocal8Bit().constData() );
303 options[ datasourceOptions.size()] =
nullptr;
308 mDS.reset( OGR_Dr_CreateDataSource( poDriver, vectorFileName.toUtf8().constData(), options ) );
310 mDS.reset( myOGROpen( vectorFileName.toUtf8().constData(), TRUE, nullptr ) );
314 for (
int i = 0; i < datasourceOptions.size(); i++ )
315 CPLFree( options[i] );
324 mErrorMessage = QObject::tr(
"Creation of data source failed (OGR error: %1)" )
325 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
327 mErrorMessage = QObject::tr(
"Opening of data source in update mode failed (OGR error: %1)" )
328 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
332 QString layerName( layerNameIn );
333 if ( layerName.isEmpty() )
334 layerName = QFileInfo( vectorFileName ).baseName();
338 const int layer_count = OGR_DS_GetLayerCount(
mDS.get() );
339 for (
int i = 0; i < layer_count; i++ )
341 OGRLayerH hLayer = OGR_DS_GetLayer(
mDS.get(), i );
342 if ( EQUAL( OGR_L_GetName( hLayer ), layerName.toUtf8().constData() ) )
344 if ( OGR_DS_DeleteLayer(
mDS.get(), i ) != OGRERR_NONE )
347 mErrorMessage = QObject::tr(
"Overwriting of existing layer failed (OGR error: %1)" )
348 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
362 QgsDebugMsg(
"Opened data source in update mode" );
366 mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().constData() );
369 QgsDebugMsg(
"error finding QTextCodec for " + fileEncoding );
372 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
373 mCodec = QTextCodec::codecForName( enc.toLocal8Bit().constData() );
376 QgsDebugMsg(
"error finding QTextCodec for " + enc );
377 mCodec = QTextCodec::codecForLocale();
385 QString srsWkt = srs.
toWkt();
387 mOgrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().constData() );
394 int optIndex = layerOptions.indexOf( QStringLiteral(
"FEATURE_DATASET=" ) );
395 if ( optIndex != -1 )
397 layerOptions.removeAt( optIndex );
400 if ( !layerOptions.isEmpty() )
402 options =
new char *[ layerOptions.size() + 1 ];
403 for (
int i = 0; i < layerOptions.size(); i++ )
405 QgsDebugMsg( QString(
"-lco=%1" ).arg( layerOptions[i] ) );
406 options[i] = CPLStrdup( layerOptions[i].toLocal8Bit().constData() );
408 options[ layerOptions.size()] =
nullptr;
412 CPLSetConfigOption(
"SHAPE_ENCODING",
"" );
414 if ( driverName == QLatin1String(
"DGN" ) )
416 mLayer = OGR_DS_GetLayerByName(
mDS.get(),
"elements" );
420 mLayer = OGR_DS_CreateLayer(
mDS.get(), layerName.toUtf8().constData(),
mOgrRef, wkbType, options );
424 mLayer = OGR_DS_GetLayerByName(
mDS.get(), layerName.toUtf8().constData() );
429 for (
int i = 0; i < layerOptions.size(); i++ )
430 CPLFree( options[i] );
436 if ( !settings.
value( QStringLiteral(
"qgis/ignoreShapeEncoding" ),
true ).toBool() )
438 CPLSetConfigOption(
"SHAPE_ENCODING",
nullptr );
445 QString layerName = vectorFileName.left( vectorFileName.indexOf( QLatin1String(
".shp" ), Qt::CaseInsensitive ) );
446 QFile prjFile( layerName +
".qpj" );
447 if ( prjFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
449 QTextStream prjStream( &prjFile );
450 prjStream << srs.
toWkt().toLocal8Bit().constData() << endl;
455 QgsDebugMsg(
"Couldn't open file " + layerName +
".qpj" );
463 mErrorMessage = QObject::tr(
"Creation of layer failed (OGR error: %1)" )
464 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
466 mErrorMessage = QObject::tr(
"Opening of layer failed (OGR error: %1)" )
467 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
472 OGRFeatureDefnH defn = OGR_L_GetLayerDefn(
mLayer );
477 QgsDebugMsg(
"creating " + QString::number( fields.
size() ) +
" fields" );
481 QSet<int> existingIdxs;
488 fldIdx < fields.
count(); ++fldIdx )
492 if ( fieldValueConverter )
497 QString name( attrField.
name() );
500 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
508 OGRFieldType ogrType = OFTString;
509 int ogrWidth = attrField.
length();
510 int ogrPrecision = attrField.
precision();
511 if ( ogrPrecision > 0 )
514 switch ( attrField.
type() )
516 case QVariant::LongLong:
518 const char *pszDataTypes = GDALGetMetadataItem( poDriver, GDAL_DMD_CREATIONFIELDDATATYPES,
nullptr );
519 if ( pszDataTypes && strstr( pszDataTypes,
"Integer64" ) )
520 ogrType = OFTInteger64;
523 ogrWidth = ogrWidth > 0 && ogrWidth <= 20 ? ogrWidth : 20;
527 case QVariant::String:
529 if ( ogrWidth <= 0 || ogrWidth > 255 )
534 ogrType = OFTInteger;
535 ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
540 ogrType = OFTInteger;
545 case QVariant::Double:
565 case QVariant::DateTime:
573 ogrType = OFTDateTime;
579 mErrorMessage = QObject::tr(
"Unsupported type for field %1" )
580 .arg( attrField.
name() );
585 if (
mOgrDriverName == QLatin1String(
"SQLite" ) && name.compare( QLatin1String(
"ogc_fid" ), Qt::CaseInsensitive ) == 0 )
588 for ( i = 0; i < 10; i++ )
590 name = QStringLiteral(
"ogc_fid%1" ).arg( i );
593 for ( j = 0; j < fields.
size() && name.compare( fields.
at( j ).
name(), Qt::CaseInsensitive ) != 0; j++ )
596 if ( j == fields.
size() )
602 mErrorMessage = QObject::tr(
"No available replacement for internal fieldname ogc_fid found" ).arg( attrField.
name() );
607 QgsMessageLog::logMessage( QObject::tr(
"Reserved attribute name ogc_fid replaced with %1" ).arg( name ), QObject::tr(
"OGR" ) );
614 OGR_Fld_SetWidth( fld.get(), ogrWidth );
617 if ( ogrPrecision >= 0 )
619 OGR_Fld_SetPrecision( fld.get(), ogrPrecision );
622 switch ( attrField.
type() )
625 OGR_Fld_SetSubType( fld.get(), OFSTBoolean );
633 " type " + QString( QVariant::typeToName( attrField.
type() ) ) +
634 " width " + QString::number( ogrWidth ) +
635 " precision " + QString::number( ogrPrecision ) );
636 if ( OGR_L_CreateField(
mLayer, fld.get(), true ) != OGRERR_NONE )
639 mErrorMessage = QObject::tr(
"Creation of field %1 failed (OGR error: %2)" )
640 .arg( attrField.
name(),
641 QString::fromUtf8( CPLGetLastErrorMsg() ) );
646 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
647 QgsDebugMsg( QString(
"returned field index for %1: %2" ).arg( name ).arg( ogrIdx ) );
648 if ( ogrIdx < 0 || existingIdxs.contains( ogrIdx ) )
651 ogrIdx = OGR_FD_GetFieldCount( defn ) - 1;
656 mErrorMessage = QObject::tr(
"Created field %1 not found (OGR error: %2)" )
657 .arg( attrField.
name(),
658 QString::fromUtf8( CPLGetLastErrorMsg() ) );
664 existingIdxs.insert( ogrIdx );
670 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
673 QString name( attrField.
name() );
674 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
685 *newFilename = vectorFileName;
688 mUsingTransaction =
true;
689 if ( OGRERR_NONE != OGR_L_StartTransaction(
mLayer ) )
691 mUsingTransaction =
false;
701 class QgsVectorFileWriterMetadataContainer
705 QgsVectorFileWriterMetadataContainer()
707 QMap<QString, QgsVectorFileWriter::Option *> datasetOptions;
708 QMap<QString, QgsVectorFileWriter::Option *> layerOptions;
711 datasetOptions.clear();
712 layerOptions.clear();
716 QStringLiteral(
"Arc/Info ASCII Coverage" ),
717 QObject::tr(
"Arc/Info ASCII Coverage" ),
718 QStringLiteral(
"*.e00" ),
719 QStringLiteral(
"e00" ),
726 datasetOptions.clear();
727 layerOptions.clear();
730 QObject::tr(
"New BNA files are created by the " 731 "systems default line termination conventions. " 732 "This may be overridden here." ),
734 << QStringLiteral(
"CRLF" )
735 << QStringLiteral(
"LF" ),
741 QObject::tr(
"By default, BNA files are created in multi-line format. " 742 "For each record, the first line contains the identifiers and the " 743 "type/number of coordinates to follow. Each following line contains " 744 "a pair of coordinates." ),
749 QObject::tr(
"BNA records may contain from 2 to 4 identifiers per record. " 750 "Some software packages only support a precise number of identifiers. " 751 "You can override the default value (2) by a precise value." ),
753 << QStringLiteral(
"2" )
754 << QStringLiteral(
"3" )
755 << QStringLiteral(
"4" )
756 << QStringLiteral(
"NB_SOURCE_FIELDS" ),
757 QStringLiteral(
"2" )
761 QObject::tr(
"The BNA writer will try to recognize ellipses and circles when writing a polygon. " 762 "This will only work if the feature has previously been read from a BNA file. " 763 "As some software packages do not support ellipses/circles in BNA data file, " 764 "it may be useful to tell the writer by specifying ELLIPSES_AS_ELLIPSES=NO not " 765 "to export them as such, but keep them as polygons." ),
770 QObject::tr(
"Limit the number of coordinate pairs per line in multiline format." ),
775 QObject::tr(
"Set the number of decimal for coordinates. Default value is 10." ),
781 QStringLiteral(
"Atlas BNA" ),
782 QObject::tr(
"Atlas BNA" ),
783 QStringLiteral(
"*.bna" ),
784 QStringLiteral(
"bna" ),
791 datasetOptions.clear();
792 layerOptions.clear();
795 QObject::tr(
"By default when creating new .csv files they " 796 "are created with the line termination conventions " 797 "of the local platform (CR/LF on Win32 or LF on all other systems). " 798 "This may be overridden through the use of the LINEFORMAT option." ),
800 << QStringLiteral(
"CRLF" )
801 << QStringLiteral(
"LF" ),
807 QObject::tr(
"By default, the geometry of a feature written to a .csv file is discarded. " 808 "It is possible to export the geometry in its WKT representation by " 809 "specifying GEOMETRY=AS_WKT. It is also possible to export point geometries " 810 "into their X,Y,Z components by specifying GEOMETRY=AS_XYZ, GEOMETRY=AS_XY " 811 "or GEOMETRY=AS_YX." ),
813 << QStringLiteral(
"AS_WKT" )
814 << QStringLiteral(
"AS_XYZ" )
815 << QStringLiteral(
"AS_XY" )
816 << QStringLiteral(
"AS_YX" ),
822 QObject::tr(
"Create the associated .csvt file to describe the type of each " 823 "column of the layer and its optional width and precision." ),
828 QObject::tr(
"Field separator character." ),
830 << QStringLiteral(
"COMMA" )
831 << QStringLiteral(
"SEMICOLON" )
832 << QStringLiteral(
"TAB" ),
833 QStringLiteral(
"COMMA" )
837 QObject::tr(
"Write a UTF-8 Byte Order Mark (BOM) at the start of the file." ),
843 QStringLiteral(
"Comma Separated Value [CSV]" ),
844 QObject::tr(
"Comma Separated Value [CSV]" ),
845 QStringLiteral(
"*.csv" ),
846 QStringLiteral(
"csv" ),
853 datasetOptions.clear();
854 layerOptions.clear();
857 QObject::tr(
"Override the type of shapefile created. " 858 "Can be one of NULL for a simple .dbf file with no .shp file, POINT, " 859 "ARC, POLYGON or MULTIPOINT for 2D, or POINTZ, ARCZ, POLYGONZ or " 860 "MULTIPOINTZ for 3D;" ) +
861 QObject::tr(
" POINTM, ARCM, POLYGONM or MULTIPOINTM for measured geometries" 862 " and POINTZM, ARCZM, POLYGONZM or MULTIPOINTZM for 3D measured" 864 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
865 QObject::tr(
" MULTIPATCH files are supported since GDAL 2.2." ) +
869 << QStringLiteral(
"NULL" )
870 << QStringLiteral(
"POINT" )
871 << QStringLiteral(
"ARC" )
872 << QStringLiteral(
"POLYGON" )
873 << QStringLiteral(
"MULTIPOINT" )
874 << QStringLiteral(
"POINTZ" )
875 << QStringLiteral(
"ARCZ" )
876 << QStringLiteral(
"POLYGONZ" )
877 << QStringLiteral(
"MULTIPOINTZ" )
878 << QStringLiteral(
"POINTM" )
879 << QStringLiteral(
"ARCM" )
880 << QStringLiteral(
"POLYGONM" )
881 << QStringLiteral(
"MULTIPOINTM" )
882 << QStringLiteral(
"POINTZM" )
883 << QStringLiteral(
"ARCZM" )
884 << QStringLiteral(
"POLYGONZM" )
885 << QStringLiteral(
"MULTIPOINTZM" )
886 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
887 << QStringLiteral(
"MULTIPATCH" )
889 << QStringLiteral(
"" ),
898 QObject::tr(
"Set the encoding value in the DBF file. " 899 "The default value is LDID/87. It is not clear " 900 "what other values may be appropriate." ),
908 QObject::tr(
"Set to YES to resize fields to their optimal size." ),
914 QStringLiteral(
"ESRI Shapefile" ),
915 QObject::tr(
"ESRI Shapefile" ),
916 QStringLiteral(
"*.shp" ),
917 QStringLiteral(
"shp" ),
924 datasetOptions.clear();
925 layerOptions.clear();
929 QStringLiteral(
"DBF File" ),
930 QObject::tr(
"DBF File" ),
931 QStringLiteral(
"*.dbf" ),
932 QStringLiteral(
"dbf" ),
939 datasetOptions.clear();
940 layerOptions.clear();
944 QStringLiteral(
"FMEObjects Gateway" ),
945 QObject::tr(
"FMEObjects Gateway" ),
946 QStringLiteral(
"*.fdd" ),
947 QStringLiteral(
"fdd" ),
954 datasetOptions.clear();
955 layerOptions.clear();
958 QObject::tr(
"Set to YES to write a bbox property with the bounding box " 959 "of the geometries at the feature and feature collection level." ),
964 QObject::tr(
"Maximum number of figures after decimal separator to write in coordinates. " 965 "Default to 15. Truncation will occur to remove trailing zeros." ),
971 QStringLiteral(
"GeoJSON" ),
972 QObject::tr(
"GeoJSON" ),
973 QStringLiteral(
"*.geojson" ),
974 QStringLiteral(
"geojson" ),
977 QStringLiteral(
"UTF-8" )
982 datasetOptions.clear();
983 layerOptions.clear();
986 QObject::tr(
"whether the document must be in RSS 2.0 or Atom 1.0 format. " 987 "Default value : RSS" ),
989 << QStringLiteral(
"RSS" )
990 << QStringLiteral(
"ATOM" ),
991 QStringLiteral(
"RSS" )
995 QObject::tr(
"The encoding of location information. Default value : SIMPLE. " 996 "W3C_GEO only supports point geometries. " 997 "SIMPLE or W3C_GEO only support geometries in geographic WGS84 coordinates." ),
999 << QStringLiteral(
"SIMPLE" )
1000 << QStringLiteral(
"GML" )
1001 << QStringLiteral(
"W3C_GEO" ),
1002 QStringLiteral(
"SIMPLE" )
1006 QObject::tr(
"If defined to YES, extension fields will be written. " 1007 "If the field name not found in the base schema matches " 1008 "the foo_bar pattern, foo will be considered as the namespace " 1009 "of the element, and a <foo:bar> element will be written. " 1010 "Otherwise, elements will be written in the <ogr:> namespace." ),
1015 QObject::tr(
"If defined to NO, only <entry> or <item> elements will be written. " 1016 "The user will have to provide the appropriate header and footer of the document." ),
1021 QObject::tr(
"XML content that will be put between the <channel> element and the " 1022 "first <item> element for a RSS document, or between the xml tag and " 1023 "the first <entry> element for an Atom document." ),
1028 QObject::tr(
"Value put inside the <title> element in the header. " 1029 "If not provided, a dummy value will be used as that element is compulsory." ),
1034 QObject::tr(
"Value put inside the <description> element in the header. " 1035 "If not provided, a dummy value will be used as that element is compulsory." ),
1040 QObject::tr(
"Value put inside the <link> element in the header. " 1041 "If not provided, a dummy value will be used as that element is compulsory." ),
1046 QObject::tr(
"Value put inside the <updated> element in the header. " 1047 "Should be formatted as a XML datetime. " 1048 "If not provided, a dummy value will be used as that element is compulsory." ),
1053 QObject::tr(
"Value put inside the <author><name> element in the header. " 1054 "If not provided, a dummy value will be used as that element is compulsory." ),
1059 QObject::tr(
"Value put inside the <id> element in the header. " 1060 "If not provided, a dummy value will be used as that element is compulsory." ),
1066 QStringLiteral(
"GeoRSS" ),
1067 QObject::tr(
"GeoRSS" ),
1068 QStringLiteral(
"*.xml" ),
1069 QStringLiteral(
"xml" ),
1072 QStringLiteral(
"UTF-8" )
1077 datasetOptions.clear();
1078 layerOptions.clear();
1081 QObject::tr(
"If provided, this URI will be inserted as the schema location. " 1082 "Note that the schema file isn't actually accessed by OGR, so it " 1083 "is up to the user to ensure it will match the schema of the OGR " 1084 "produced GML data file." ),
1089 QObject::tr(
"This writes a GML application schema file to a corresponding " 1090 ".xsd file (with the same basename). If INTERNAL is used the " 1091 "schema is written within the GML file, but this is experimental " 1092 "and almost certainly not valid XML. " 1093 "OFF disables schema generation (and is implicit if XSISCHEMAURI is used)." ),
1095 << QStringLiteral(
"EXTERNAL" )
1096 << QStringLiteral(
"INTERNAL" )
1097 << QStringLiteral(
"OFF" ),
1098 QStringLiteral(
"EXTERNAL" )
1102 QObject::tr(
"This is the prefix for the application target namespace." ),
1103 QStringLiteral(
"ogr" )
1107 QObject::tr(
"Can be set to TRUE to avoid writing the prefix of the " 1108 "application target namespace in the GML file." ),
1113 QObject::tr(
"Defaults to 'http://ogr.maptools.org/'. " 1114 "This is the application target namespace." ),
1115 QStringLiteral(
"http://ogr.maptools.org/" )
1119 QObject::tr(
"If not specified, GML2 will be used." ),
1121 << QStringLiteral(
"GML3" )
1122 << QStringLiteral(
"GML3Deegree" )
1123 << QStringLiteral(
"GML3.2" ),
1124 QLatin1String(
"" ),
1129 QObject::tr(
"Only valid when FORMAT=GML3/GML3Degree/GML3.2. Default to YES. " 1130 "If YES, SRS with EPSG authority will be written with the " 1131 "'urn:ogc:def:crs:EPSG::' prefix. In the case the SRS is a " 1132 "geographic SRS without explicit AXIS order, but that the same " 1133 "SRS authority code imported with ImportFromEPSGA() should be " 1134 "treated as lat/long, then the function will take care of coordinate " 1135 "order swapping. If set to NO, SRS with EPSG authority will be " 1136 "written with the 'EPSG:' prefix, even if they are in lat/long order." ),
1141 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. " 1142 "If set to NO, the <gml:boundedBy> element will not be written for " 1148 QObject::tr(
"Default to YES. If YES, the output will be indented with spaces " 1149 "for more readability, but at the expense of file size." ),
1156 QStringLiteral(
"Geography Markup Language [GML]" ),
1157 QObject::tr(
"Geography Markup Language [GML]" ),
1158 QStringLiteral(
"*.gml" ),
1159 QStringLiteral(
"gml" ),
1162 QStringLiteral(
"UTF-8" )
1167 datasetOptions.clear();
1168 layerOptions.clear();
1171 QObject::tr(
"Human-readable identifier (e.g. short name) for the layer content" ),
1176 QObject::tr(
"Human-readable description for the layer content" ),
1181 QObject::tr(
"Name for the feature identifier column" ),
1182 QStringLiteral(
"fid" )
1186 QObject::tr(
"Name for the geometry column" ),
1187 QStringLiteral(
"geom" )
1191 QObject::tr(
"If a spatial index must be created." ),
1197 QStringLiteral(
"GeoPackage" ),
1198 QObject::tr(
"GeoPackage" ),
1199 QStringLiteral(
"*.gpkg" ),
1200 QStringLiteral(
"gpkg" ),
1203 QStringLiteral(
"UTF-8" )
1208 datasetOptions.clear();
1209 layerOptions.clear();
1213 QStringLiteral(
"Generic Mapping Tools [GMT]" ),
1214 QObject::tr(
"Generic Mapping Tools [GMT]" ),
1215 QStringLiteral(
"*.gmt" ),
1216 QStringLiteral(
"gmt" ),
1223 datasetOptions.clear();
1224 layerOptions.clear();
1227 QObject::tr(
"By default when writing a layer whose features are of " 1228 "type wkbLineString, the GPX driver chooses to write " 1229 "them as routes. If FORCE_GPX_TRACK=YES is specified, " 1230 "they will be written as tracks." ),
1235 QObject::tr(
"By default when writing a layer whose features are of " 1236 "type wkbMultiLineString, the GPX driver chooses to write " 1237 "them as tracks. If FORCE_GPX_ROUTE=YES is specified, " 1238 "they will be written as routes, provided that the multilines " 1239 "are composed of only one single line." ),
1244 QObject::tr(
"If GPX_USE_EXTENSIONS=YES is specified, " 1245 "extra fields will be written inside the <extensions> tag." ),
1250 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS_URL " 1251 "is set. The namespace value used for extension tags. By default, 'ogr'." ),
1252 QStringLiteral(
"ogr" )
1256 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS " 1257 "is set. The namespace URI. By default, 'http://osgeo.org/gdal'." ),
1258 QStringLiteral(
"http://osgeo.org/gdal" )
1262 QObject::tr(
"By default files are created with the line termination " 1263 "conventions of the local platform (CR/LF on win32 or LF " 1264 "on all other systems). This may be overridden through use " 1265 "of the LINEFORMAT layer creation option which may have a value " 1266 "of CRLF (DOS format) or LF (Unix format)." ),
1268 << QStringLiteral(
"CRLF" )
1269 << QStringLiteral(
"LF" ),
1270 QLatin1String(
"" ),
1276 QStringLiteral(
"GPS eXchange Format [GPX]" ),
1277 QObject::tr(
"GPS eXchange Format [GPX]" ),
1278 QStringLiteral(
"*.gpx" ),
1279 QStringLiteral(
"gpx" ),
1282 QStringLiteral(
"UTF-8" )
1287 datasetOptions.clear();
1288 layerOptions.clear();
1292 QStringLiteral(
"INTERLIS 1" ),
1293 QObject::tr(
"INTERLIS 1" ),
1294 QStringLiteral(
"*.itf *.xml *.ili" ),
1295 QStringLiteral(
"ili" ),
1302 datasetOptions.clear();
1303 layerOptions.clear();
1307 QStringLiteral(
"INTERLIS 2" ),
1308 QObject::tr(
"INTERLIS 2" ),
1309 QStringLiteral(
"*.xtf *.xml *.ili" ),
1310 QStringLiteral(
"ili" ),
1317 datasetOptions.clear();
1318 layerOptions.clear();
1321 QObject::tr(
"Allows you to specify the field to use for the KML <name> element." ),
1322 QStringLiteral(
"Name" )
1326 QObject::tr(
"Allows you to specify the field to use for the KML <description> element." ),
1327 QStringLiteral(
"Description" )
1331 QObject::tr(
"Allows you to specify the AltitudeMode to use for KML geometries. " 1332 "This will only affect 3D geometries and must be one of the valid KML options." ),
1334 << QStringLiteral(
"clampToGround" )
1335 << QStringLiteral(
"relativeToGround" )
1336 << QStringLiteral(
"absolute" ),
1337 QStringLiteral(
"relativeToGround" )
1340 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0) 1342 QObject::tr(
"The DOCUMENT_ID datasource creation option can be used to specified " 1343 "the id of the root <Document> node. The default value is root_doc." ),
1344 QStringLiteral(
"root_doc" )
1350 QStringLiteral(
"Keyhole Markup Language [KML]" ),
1351 QObject::tr(
"Keyhole Markup Language [KML]" ),
1352 QStringLiteral(
"*.kml" ),
1353 QStringLiteral(
"kml" ),
1356 QStringLiteral(
"UTF-8" )
1361 datasetOptions.clear();
1362 layerOptions.clear();
1364 auto insertMapInfoOptions = []( QMap<QString, QgsVectorFileWriter::Option *> &datasetOptions, QMap<QString, QgsVectorFileWriter::Option *> &layerOptions )
1367 QObject::tr(
"Use this to turn on 'quick spatial index mode'. " 1368 "In this mode writing files can be about 5 times faster, " 1369 "but spatial queries can be up to 30 times slower." ),
1371 << QStringLiteral(
"QUICK" )
1372 << QStringLiteral(
"OPTIMIZED" ),
1373 QStringLiteral(
"QUICK" ),
1378 QObject::tr(
"(multiples of 512): Block size for .map files. Defaults " 1379 "to 512. MapInfo 15.2 and above creates .tab files with a " 1380 "blocksize of 16384 bytes. Any MapInfo version should be " 1381 "able to handle block sizes from 512 to 32256." ),
1385 QObject::tr(
"xmin,ymin,xmax,ymax: Define custom layer bounds to increase the " 1386 "accuracy of the coordinates. Note: the geometry of written " 1387 "features must be within the defined box." ),
1391 insertMapInfoOptions( datasetOptions, layerOptions );
1395 QStringLiteral(
"Mapinfo" ),
1396 QObject::tr(
"Mapinfo TAB" ),
1397 QStringLiteral(
"*.tab" ),
1398 QStringLiteral(
"tab" ),
1403 datasetOptions.clear();
1404 layerOptions.clear();
1405 insertMapInfoOptions( datasetOptions, layerOptions );
1410 QStringLiteral(
"Mapinfo" ),
1411 QObject::tr(
"Mapinfo MIF" ),
1412 QStringLiteral(
"*.mif" ),
1413 QStringLiteral(
"mif" ),
1420 datasetOptions.clear();
1421 layerOptions.clear();
1424 QObject::tr(
"Determine whether 2D (seed_2d.dgn) or 3D (seed_3d.dgn) " 1425 "seed file should be used. This option is ignored if the SEED option is provided." ),
1430 QObject::tr(
"Override the seed file to use." ),
1435 QObject::tr(
"Indicate whether the whole seed file should be copied. " 1436 "If not, only the first three elements will be copied." ),
1441 QObject::tr(
"Indicates whether the color table should be copied from the seed file." ),
1446 QObject::tr(
"Override the master unit name from the seed file with " 1447 "the provided one or two character unit name." ),
1452 QObject::tr(
"Override the sub unit name from the seed file with the provided " 1453 "one or two character unit name." ),
1458 QObject::tr(
"Override the number of subunits per master unit. " 1459 "By default the seed file value is used." ),
1464 QObject::tr(
"Override the number of UORs (Units of Resolution) " 1465 "per sub unit. By default the seed file value is used." ),
1470 QObject::tr(
"ORIGIN=x,y,z: Override the origin of the design plane. " 1471 "By default the origin from the seed file is used." ),
1477 QStringLiteral(
"Microstation DGN" ),
1478 QObject::tr(
"Microstation DGN" ),
1479 QStringLiteral(
"*.dgn" ),
1480 QStringLiteral(
"dgn" ),
1487 datasetOptions.clear();
1488 layerOptions.clear();
1491 QObject::tr(
"Should update files be incorporated into the base data on the fly." ),
1493 << QStringLiteral(
"APPLY" )
1494 << QStringLiteral(
"IGNORE" ),
1495 QStringLiteral(
"APPLY" )
1499 QObject::tr(
"Should multipoint soundings be split into many single point sounding features. " 1500 "Multipoint geometries are not well handled by many formats, " 1501 "so it can be convenient to split single sounding features with many points " 1502 "into many single point features." ),
1507 QObject::tr(
"Should a DEPTH attribute be added on SOUNDG features and assign the depth " 1508 "of the sounding. This should only be enabled when SPLIT_MULTIPOINT is " 1514 QObject::tr(
"Should all the low level geometry primitives be returned as special " 1515 "IsolatedNode, ConnectedNode, Edge and Face layers." ),
1520 QObject::tr(
"If enabled, numeric attributes assigned an empty string as a value will " 1521 "be preserved as a special numeric value. This option should not generally " 1522 "be needed, but may be useful when translated S-57 to S-57 losslessly." ),
1527 QObject::tr(
"Should LNAM and LNAM_REFS fields be attached to features capturing " 1528 "the feature to feature relationships in the FFPT group of the S-57 file." ),
1533 QObject::tr(
"Should additional attributes relating features to their underlying " 1534 "geometric primitives be attached. These are the values of the FSPT group, " 1535 "and are primarily needed when doing S-57 to S-57 translations." ),
1540 QObject::tr(
"Should attribute values be recoded to UTF-8 from the character encoding " 1541 "specified in the S57 DSSI record." ),
1549 QStringLiteral(
"S-57 Base file" ),
1550 QObject::tr(
"S-57 Base file" ),
1551 QStringLiteral(
"*.000" ),
1552 QStringLiteral(
"000" ),
1559 datasetOptions.clear();
1560 layerOptions.clear();
1564 QStringLiteral(
"Spatial Data Transfer Standard [SDTS]" ),
1565 QObject::tr(
"Spatial Data Transfer Standard [SDTS]" ),
1566 QStringLiteral(
"*catd.ddf" ),
1567 QStringLiteral(
"ddf" ),
1574 datasetOptions.clear();
1575 layerOptions.clear();
1578 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys " 1579 "tables in a new database. By default these metadata tables are created " 1580 "when a new database is created." ),
1586 QStringLiteral(
"NO" )
1591 QStringLiteral(
"NO" )
1595 QObject::tr(
"Controls the format used for the geometry column. Defaults to WKB. " 1596 "This is generally more space and processing efficient, but harder " 1597 "to inspect or use in simple applications than WKT (Well Known Text)." ),
1599 << QStringLiteral(
"WKB" )
1600 << QStringLiteral(
"WKT" ),
1601 QStringLiteral(
"WKB" )
1605 QObject::tr(
"Controls whether layer and field names will be laundered for easier use " 1606 "in SQLite. Laundered names will be converted to lower case and some special " 1607 "characters(' - #) will be changed to underscores." ),
1612 QStringLiteral(
"NO" )
1616 QStringLiteral(
"NO" )
1624 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that " 1625 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial " 1626 "for databases that have big string blobs. However, use with care, since " 1627 "the value of such columns will be seen as compressed binary content with " 1628 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, " 1629 "modifying or querying compressed columns, compression/decompression is " 1630 "done transparently. However, such columns cannot be (easily) queried with " 1631 "an attribute filter or WHERE clause. Note: in table definition, such columns " 1632 "have the 'VARCHAR_deflate' declaration type." ),
1638 QStringLiteral(
"SQLite" ),
1639 QObject::tr(
"SQLite" ),
1640 QStringLiteral(
"*.sqlite" ),
1641 QStringLiteral(
"sqlite" ),
1644 QStringLiteral(
"UTF-8" )
1649 datasetOptions.clear();
1650 layerOptions.clear();
1653 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys " 1654 "tables in a new database. By default these metadata tables are created " 1655 "when a new database is created." ),
1660 QStringLiteral(
"YES" )
1664 QObject::tr(
"Insert the content of the EPSG CSV files into the spatial_ref_sys table. " 1665 "Set to NO for regular SQLite databases." ),
1670 QStringLiteral(
"SPATIALITE" )
1674 QObject::tr(
"Controls whether layer and field names will be laundered for easier use " 1675 "in SQLite. Laundered names will be converted to lower case and some special " 1676 "characters(' - #) will be changed to underscores." ),
1681 QObject::tr(
"If the database is of the SpatiaLite flavor, and if OGR is linked " 1682 "against libspatialite, this option can be used to control if a spatial " 1683 "index must be created." ),
1688 QObject::tr(
"If the format of the geometry BLOB is of the SpatiaLite flavor, " 1689 "this option can be used to control if the compressed format for " 1690 "geometries (LINESTRINGs, POLYGONs) must be used." ),
1695 QObject::tr(
"Used to force the SRID number of the SRS associated with the layer. " 1696 "When this option isn't specified and that a SRS is associated with the " 1697 "layer, a search is made in the spatial_ref_sys to find a match for the " 1698 "SRS, and, if there is no match, a new entry is inserted for the SRS in " 1699 "the spatial_ref_sys table. When the SRID option is specified, this " 1700 "search (and the eventual insertion of a new entry) will not be done: " 1701 "the specified SRID is used as such." ),
1706 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that " 1707 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial " 1708 "for databases that have big string blobs. However, use with care, since " 1709 "the value of such columns will be seen as compressed binary content with " 1710 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, " 1711 "modifying or queryings compressed columns, compression/decompression is " 1712 "done transparently. However, such columns cannot be (easily) queried with " 1713 "an attribute filter or WHERE clause. Note: in table definition, such columns " 1714 "have the 'VARCHAR_deflate' declaration type." ),
1720 QStringLiteral(
"SpatiaLite" ),
1721 QObject::tr(
"SpatiaLite" ),
1722 QStringLiteral(
"*.sqlite" ),
1723 QStringLiteral(
"sqlite" ),
1726 QStringLiteral(
"UTF-8" )
1730 datasetOptions.clear();
1731 layerOptions.clear();
1734 QObject::tr(
"Override the header file used - in place of header.dxf." ),
1739 QObject::tr(
"Override the trailer file used - in place of trailer.dxf." ),
1745 QStringLiteral(
"AutoCAD DXF" ),
1746 QObject::tr(
"AutoCAD DXF" ),
1747 QStringLiteral(
"*.dxf" ),
1748 QStringLiteral(
"dxf" ),
1755 datasetOptions.clear();
1756 layerOptions.clear();
1759 QObject::tr(
"Indicates the GeoConcept export file extension. " 1760 "TXT was used by earlier releases of GeoConcept. GXT is currently used." ),
1762 << QStringLiteral(
"GXT" )
1763 << QStringLiteral(
"TXT" ),
1764 QStringLiteral(
"GXT" )
1768 QObject::tr(
"Path to the GCT: the GCT file describes the GeoConcept types definitions: " 1769 "In this file, every line must start with //# followed by a keyword. " 1770 "Lines starting with // are comments." ),
1775 QObject::tr(
"Defines the feature to be created. The TYPE corresponds to one of the Name " 1776 "found in the GCT file for a type section. The SUBTYPE corresponds to one of " 1777 "the Name found in the GCT file for a sub-type section within the previous " 1784 QStringLiteral(
"Geoconcept" ),
1785 QObject::tr(
"Geoconcept" ),
1786 QStringLiteral(
"*.gxt *.txt" ),
1787 QStringLiteral(
"gxt" ),
1794 datasetOptions.clear();
1795 layerOptions.clear();
1798 QObject::tr(
"When this option is set, the new layer will be created inside the named " 1799 "FeatureDataset folder. If the folder does not already exist, it will be created." ),
1804 QObject::tr(
"Set name of geometry column in new layer. Defaults to 'SHAPE'." ),
1805 QStringLiteral(
"SHAPE" )
1809 QObject::tr(
"Name of the OID column to create. Defaults to 'OBJECTID'." ),
1810 QStringLiteral(
"OBJECTID" )
1815 QStringLiteral(
"ESRI FileGDB" ),
1816 QObject::tr(
"ESRI FileGDB" ),
1817 QStringLiteral(
"*.gdb" ),
1818 QStringLiteral(
"gdb" ),
1821 QStringLiteral(
"UTF-8" )
1826 datasetOptions.clear();
1827 layerOptions.clear();
1830 QObject::tr(
"By default, the driver will try to detect the data type of fields. If set " 1831 "to STRING, all fields will be of String type." ),
1833 << QStringLiteral(
"AUTO" )
1834 << QStringLiteral(
"STRING" ),
1835 QStringLiteral(
"AUTO" ),
1840 QObject::tr(
"By default, the driver will read the first lines of each sheet to detect " 1841 "if the first line might be the name of columns. If set to FORCE, the driver " 1842 "will consider the first line as the header line. If set to " 1843 "DISABLE, it will be considered as the first feature. Otherwise " 1844 "auto-detection will occur." ),
1846 << QStringLiteral(
"FORCE" )
1847 << QStringLiteral(
"DISABLE" )
1848 << QStringLiteral(
"AUTO" ),
1849 QStringLiteral(
"AUTO" ),
1855 QStringLiteral(
"MS Office Open XML spreadsheet" ),
1856 QObject::tr(
"MS Office Open XML spreadsheet [XLSX]" ),
1857 QStringLiteral(
"*.xlsx" ),
1858 QStringLiteral(
"xlsx" ),
1861 QStringLiteral(
"UTF-8" )
1866 datasetOptions.clear();
1867 layerOptions.clear();
1870 QObject::tr(
"By default, the driver will try to detect the data type of fields. If set " 1871 "to STRING, all fields will be of String type." ),
1873 << QStringLiteral(
"AUTO" )
1874 << QStringLiteral(
"STRING" ),
1875 QStringLiteral(
"AUTO" ),
1880 QObject::tr(
"By default, the driver will read the first lines of each sheet to detect " 1881 "if the first line might be the name of columns. If set to FORCE, the driver " 1882 "will consider the first line as the header line. If set to " 1883 "DISABLE, it will be considered as the first feature. Otherwise " 1884 "auto-detection will occur." ),
1886 << QStringLiteral(
"FORCE" )
1887 << QStringLiteral(
"DISABLE" )
1888 << QStringLiteral(
"AUTO" ),
1889 QStringLiteral(
"AUTO" ),
1895 QStringLiteral(
"Open Document Spreadsheet" ),
1896 QObject::tr(
"Open Document Spreadsheet [ODS]" ),
1897 QStringLiteral(
"*.ods" ),
1898 QStringLiteral(
"ods" ),
1901 QStringLiteral(
"UTF-8" )
1906 QgsVectorFileWriterMetadataContainer(
const QgsVectorFileWriterMetadataContainer &other ) =
delete;
1907 QgsVectorFileWriterMetadataContainer &
operator=(
const QgsVectorFileWriterMetadataContainer &other ) =
delete;
1908 ~QgsVectorFileWriterMetadataContainer()
1912 for (
auto optionIt = it.value().driverOptions.constBegin(); optionIt != it.value().driverOptions.constEnd(); ++optionIt )
1913 delete optionIt.value();
1914 for (
auto optionIt = it.value().layerOptions.constBegin(); optionIt != it.value().layerOptions.constEnd(); ++optionIt )
1915 delete optionIt.value();
1926 static QgsVectorFileWriterMetadataContainer sDriverMetadata;
1927 QMap<QString, MetaData>::ConstIterator it = sDriverMetadata.driverMetadata.constBegin();
1929 for ( ; it != sDriverMetadata.driverMetadata.constEnd(); ++it )
1931 if ( it.key().startsWith( driverName ) || it.value().longName.startsWith( driverName ) )
1933 driverMetadata = it.value();
1946 return QStringList();
1955 return QStringList();
1962 OGRwkbGeometryType ogrType =
static_cast<OGRwkbGeometryType
>( type );
1988 QgsFeatureList::iterator fIt = features.begin();
1990 for ( ; fIt != features.end(); ++fIt )
2007 mRenderContext.expressionContext().setFeature( feature );
2010 QString styleString;
2011 QString currentStyle;
2013 QgsSymbolList::const_iterator symbolIt = symbols.constBegin();
2014 for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
2016 int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
2017 for (
int i = 0; i < nSymbolLayers; ++i )
2020 QMap< QgsSymbolLayer *, QString >::const_iterator it =
mSymbolLayerTable.find( ( *symbolIt )->symbolLayer( i ) );
2026 double mmsf = mmScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
2027 double musf = mapUnitScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
2029 currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
2033 if ( symbolIt != symbols.constBegin() || i != 0 )
2035 styleString.append(
';' );
2037 styleString.append( currentStyle );
2041 OGR_F_SetStyleString( poFeature.get(), currentStyle.toLocal8Bit().constData() );
2042 if ( !writeFeature(
mLayer, poFeature.get() ) )
2049 OGR_F_SetStyleString( poFeature.get(), styleString.toLocal8Bit().constData() );
2054 if ( !writeFeature(
mLayer, poFeature.get() ) )
2071 if ( fid > std::numeric_limits<int>::max() )
2073 QgsDebugMsg( QString(
"feature id %1 too large." ).arg( fid ) );
2074 OGRErr err = OGR_F_SetFID( poFeature.get(),
static_cast<long>( fid ) );
2075 if ( err != OGRERR_NONE )
2077 QgsDebugMsg( QString(
"Failed to set feature id to %1: %2 (OGR error: %3)" )
2078 .arg( feature.
id() )
2079 .arg( err ).arg( CPLGetLastErrorMsg() )
2087 int fldIdx = it.key();
2088 int ogrField = it.value();
2090 QVariant attrValue = feature.
attribute( fldIdx );
2092 if ( !attrValue.isValid() || attrValue.isNull() )
2101 #ifdef OGRNullMarker 2102 OGR_F_SetFieldNull( poFeature.get(), ogrField );
2112 switch ( attrValue.type() )
2115 case QVariant::UInt:
2116 OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
2118 case QVariant::LongLong:
2119 case QVariant::ULongLong:
2120 OGR_F_SetFieldInteger64( poFeature.get(), ogrField, attrValue.toLongLong() );
2122 case QVariant::Bool:
2123 OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
2125 case QVariant::String:
2126 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toString() ).constData() );
2128 case QVariant::Double:
2129 OGR_F_SetFieldDouble( poFeature.get(), ogrField, attrValue.toDouble() );
2131 case QVariant::Date:
2132 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2133 attrValue.toDate().year(),
2134 attrValue.toDate().month(),
2135 attrValue.toDate().day(),
2138 case QVariant::DateTime:
2141 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toDateTime().toString( QStringLiteral(
"yyyy/MM/dd hh:mm:ss.zzz" ) ) ).constData() );
2145 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2146 attrValue.toDateTime().date().year(),
2147 attrValue.toDateTime().date().month(),
2148 attrValue.toDateTime().date().day(),
2149 attrValue.toDateTime().time().hour(),
2150 attrValue.toDateTime().time().minute(),
2151 attrValue.toDateTime().time().second(),
2155 case QVariant::Time:
2158 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toString() ).constData() );
2162 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2164 attrValue.toTime().hour(),
2165 attrValue.toTime().minute(),
2166 attrValue.toTime().second(),
2170 case QVariant::Invalid:
2173 mErrorMessage = QObject::tr(
"Invalid variant type for field %1[%2]: received %3 with type %4" )
2176 .arg( attrValue.typeName(),
2177 attrValue.toString() );
2200 OGRGeometryH mGeom2 =
nullptr;
2233 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2234 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2240 QByteArray wkb( geom.
asWkb() );
2241 OGRErr err = OGR_G_ImportFromWkb( mGeom2, reinterpret_cast<unsigned char *>( const_cast<char *>( wkb.constData() ) ), wkb.length() );
2242 if ( err != OGRERR_NONE )
2244 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2245 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2252 OGR_F_SetGeometryDirectly( poFeature.get(), mGeom2 );
2256 QByteArray wkb( geom.
asWkb() );
2258 OGRErr err = OGR_G_ImportFromWkb( ogrGeom, reinterpret_cast<unsigned char *>( const_cast<char *>( wkb.constData() ) ), wkb.length() );
2259 if ( err != OGRERR_NONE )
2261 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2262 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2269 OGR_F_SetGeometryDirectly( poFeature.get(), ogrGeom );
2284 for (
int i = 0; i < attributes.size(); i++ )
2286 if ( omap.find( i ) != omap.end() )
2291 bool QgsVectorFileWriter::writeFeature( OGRLayerH layer, OGRFeatureH feature )
2293 if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
2295 mErrorMessage = QObject::tr(
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2305 if ( mUsingTransaction )
2307 if ( OGRERR_NONE != OGR_L_CommitTransaction(
mLayer ) )
2309 QgsDebugMsg(
"Error while committing transaction on OGRLayer." );
2317 OSRDestroySpatialReference(
mOgrRef );
2323 const QString &fileName,
2324 const QString &fileEncoding,
2326 const QString &driverName,
2329 const QStringList &datasourceOptions,
2330 const QStringList &layerOptions,
2331 bool skipAttributeCreation,
2332 QString *newFilename,
2343 if ( destCRS.
isValid() && layer )
2351 errorMessage, datasourceOptions, layerOptions, skipAttributeCreation,
2352 newFilename, symbologyExport, symbologyScale, filterExtent,
2353 overrideGeometryType, forceMulti, includeZ, attributes,
2354 fieldValueConverter );
2359 const QString &fileName,
2360 const QString &fileEncoding,
2362 const QString &driverName,
2365 const QStringList &datasourceOptions,
2366 const QStringList &layerOptions,
2367 bool skipAttributeCreation,
2368 QString *newFilename,
2400 : driverName( QStringLiteral(
"GPKG" ) )
2416 details.sourceCrs = layer->
crs();
2417 details.sourceWkbType = layer->
wkbType();
2418 details.sourceFields = layer->
fields();
2426 if ( details.storageType == QLatin1String(
"ESRI Shapefile" ) )
2434 details.geometryTypeScanIterator = layer->
getFeatures( req );
2438 details.renderContext.setExpressionContext( details.expressionContext );
2439 details.renderContext.setRendererScale( options.
symbologyScale );
2441 details.shallTransform =
false;
2446 details.shallTransform =
true;
2451 details.outputCrs = details.sourceCrs;
2454 details.destWkbType = details.sourceWkbType;
2468 details.attributes.clear();
2469 else if ( details.attributes.isEmpty() )
2471 const QgsAttributeList allAttributes = details.sourceFields.allAttributesList();
2472 for (
int idx : allAttributes )
2474 QgsField fld = details.sourceFields.at( idx );
2475 if ( details.providerType == QLatin1String(
"oracle" ) && fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) )
2477 details.attributes.append( idx );
2481 if ( !details.attributes.isEmpty() )
2483 for (
int attrIdx : qgis::as_const( details.attributes ) )
2485 details.outputFields.append( details.sourceFields.at( attrIdx ) );
2491 if ( details.providerType == QLatin1String(
"spatialite" ) )
2493 for (
int i = 0; i < details.outputFields.size(); i++ )
2495 if ( details.outputFields.at( i ).type() == QVariant::LongLong )
2499 if ( std::max( std::llabs( min.toLongLong() ), std::llabs( max.toLongLong() ) ) < std::numeric_limits<int>::max() )
2501 details.outputFields[i].setType( QVariant::Int );
2509 addRendererAttributes( details.renderer.get(), details.renderContext, details.sourceFields, details.attributes );
2519 bool useFilterRect =
true;
2520 if ( details.shallTransform )
2529 useFilterRect =
false;
2532 if ( useFilterRect )
2534 req.setFilterRect( filterRect );
2538 details.filterRectEngine->prepareGeometry();
2540 details.sourceFeatureIterator = layer->
getFeatures( req );
2550 int lastProgressReport = 0;
2551 long total = details.featureCount;
2553 if ( details.providerType == QLatin1String(
"ogr" ) && !details.dataSourceUri.isEmpty() )
2555 QStringList theURIParts = details.dataSourceUri.split(
'|' );
2556 QString srcFileName = theURIParts[0];
2558 if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
2561 *errorMessage = QObject::tr(
"Cannot overwrite a OGR layer in place" );
2580 int newProgress = ( 5.0 * scanned ) / total;
2581 if ( newProgress != lastProgressReport )
2583 lastProgressReport = newProgress;
2598 std::unique_ptr< QgsVectorFileWriter > writer =
2599 qgis::make_unique< QgsVectorFileWriter >( fileName,
2600 options.
fileEncoding, details.outputFields, destWkbType,
2621 *errorMessage = writer->errorMessage();
2627 errorMessage->clear();
2649 int n = 0, errors = 0;
2658 writer->startRender( details.renderer.get(), details.sourceFields );
2660 writer->resetMap( details.attributes );
2662 writer->mFields = details.sourceFields;
2666 int initialProgress = lastProgressReport;
2667 while ( details.sourceFeatureIterator.nextFeature( fet ) )
2678 int newProgress = initialProgress + ( ( 100.0 - initialProgress ) * saved ) / total;
2679 if ( newProgress < 100 && newProgress != lastProgressReport )
2681 lastProgressReport = newProgress;
2686 if ( details.shallTransform )
2699 QString msg = QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
2700 .arg( fet.
id() ).arg( e.
what() );
2703 *errorMessage = msg;
2717 if ( !writer->addFeatureWithStyle( fet, writer->mRenderer.get(), mapUnits ) )
2720 if ( err !=
NoError && errorMessage )
2722 if ( errorMessage->isEmpty() )
2724 *errorMessage = QObject::tr(
"Feature write errors:" );
2726 *errorMessage +=
'\n' + writer->errorMessage();
2730 if ( errors > 1000 )
2734 *errorMessage += QObject::tr(
"Stopping after %1 errors" ).arg( errors );
2744 writer->stopRender();
2746 if ( errors > 0 && errorMessage && n > 0 )
2748 *errorMessage += QObject::tr(
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
2756 const QString &fileName,
2758 QString *newFilename,
2759 QString *errorMessage )
2761 QgsVectorFileWriter::PreparedWriterDetails details;
2762 WriterError err = prepareWriteAsVectorFormat( layer, options, details );
2772 QFileInfo fi( fileName );
2773 QDir dir = fi.dir();
2776 const char *suffixes[] = {
".shp",
".shx",
".dbf",
".prj",
".qix",
".qpj" };
2777 for ( std::size_t i = 0; i <
sizeof( suffixes ) /
sizeof( *suffixes ); i++ )
2779 filter << fi.completeBaseName() + suffixes[i];
2783 Q_FOREACH (
const QString &file, dir.entryList( filter ) )
2785 QFile f( dir.canonicalPath() +
'/' + file );
2788 QgsDebugMsg( QString(
"Removing file %1 failed: %2" ).arg( file, f.errorString() ) );
2804 QList< FilterFormatDetails > results;
2807 int const drvCount = OGRGetDriverCount();
2809 for (
int i = 0; i < drvCount; ++i )
2811 OGRSFDriverH drv = OGRGetDriver( i );
2814 QString drvName = OGR_Dr_GetName( drv );
2816 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0) 2817 GDALDriverH gdalDriver = GDALGetDriverByName( drvName.toLocal8Bit().constData() );
2818 char **metadata =
nullptr;
2821 metadata = GDALGetMetadata( gdalDriver,
nullptr );
2824 bool nonSpatialFormat = CSLFetchBoolean( metadata, GDAL_DCAP_NONSPATIAL,
false );
2826 bool nonSpatialFormat = ( drvName == QLatin1String(
"ODS" ) || drvName == QLatin1String(
"XLSX" ) || drvName == QLatin1String(
"XLS" ) );
2829 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2834 if ( nonSpatialFormat )
2839 if ( filterString.isEmpty() )
2846 globs = metadata.
glob.toLower().split(
' ' );
2852 details.
globs = globs;
2863 if ( a.
driverName == QLatin1String(
"GPKG" ) )
2865 else if ( b.driverName == QLatin1String(
"GPKG" ) )
2867 else if ( a.
driverName == QLatin1String(
"ESRI Shapefile" ) )
2869 else if ( b.driverName == QLatin1String(
"ESRI Shapefile" ) )
2873 return a.
filterString.toLower().localeAwareCompare( b.filterString.toLower() ) < 0;
2882 QSet< QString > extensions;
2884 const QRegularExpression rx( QStringLiteral(
"\\*\\.(.*)$" ) );
2888 for (
const QString &glob : format.globs )
2890 const QRegularExpressionMatch match = rx.match( glob );
2891 if ( !match.hasMatch() )
2894 const QString matched = match.captured( 1 );
2895 extensions.insert( matched );
2899 QStringList extensionList = extensions.toList();
2901 std::sort( extensionList.begin(), extensionList.end(), [options](
const QString & a,
const QString & b ) ->
bool 2905 if ( a == QLatin1String(
"gpkg" ) )
2907 else if ( b == QLatin1String(
"gpkg" ) )
2909 else if ( a == QLatin1String(
"shp" ) )
2911 else if ( b == QLatin1String(
"shp" ) )
2915 return a.toLower().localeAwareCompare( b.toLower() ) < 0;
2918 return extensionList;
2923 QList< QgsVectorFileWriter::DriverDetails > results;
2926 const int drvCount = OGRGetDriverCount();
2928 QStringList writableDrivers;
2929 for (
int i = 0; i < drvCount; ++i )
2931 OGRSFDriverH drv = OGRGetDriver( i );
2934 QString drvName = OGR_Dr_GetName( drv );
2940 if ( drvName == QLatin1String(
"ODS" ) || drvName == QLatin1String(
"XLSX" ) || drvName == QLatin1String(
"XLS" ) )
2944 if ( drvName == QLatin1String(
"ESRI Shapefile" ) )
2946 writableDrivers << QStringLiteral(
"DBF file" );
2948 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2951 if ( drvName == QLatin1String(
"MapInfo File" ) )
2953 writableDrivers << QStringLiteral(
"MapInfo MIF" );
2955 else if ( drvName == QLatin1String(
"SQLite" ) )
2962 QString option = QStringLiteral(
"SPATIALITE=YES" );
2963 char *options[2] = { CPLStrdup( option.toLocal8Bit().constData() ),
nullptr };
2964 OGRSFDriverH poDriver;
2966 poDriver = OGRGetDriverByName( drvName.toLocal8Bit().constData() );
2969 gdal::ogr_datasource_unique_ptr ds( OGR_Dr_CreateDataSource( poDriver, QStringLiteral(
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData(), options ) );
2972 writableDrivers << QStringLiteral(
"SpatiaLite" );
2973 OGR_Dr_DeleteDataSource( poDriver, QStringLiteral(
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData() );
2976 CPLFree( options[0] );
2978 writableDrivers << drvName;
2983 results.reserve( writableDrivers.count() );
2984 for (
const QString &drvName : qgis::as_const( writableDrivers ) )
3000 if ( a.
driverName == QLatin1String(
"GPKG" ) )
3002 else if ( b.driverName == QLatin1String(
"GPKG" ) )
3004 else if ( a.
driverName == QLatin1String(
"ESRI Shapefile" ) )
3006 else if ( b.driverName == QLatin1String(
"ESRI Shapefile" ) )
3010 return a.
longName.toLower().localeAwareCompare( b.longName.toLower() ) < 0;
3017 QString ext = extension.trimmed();
3018 if ( ext.isEmpty() )
3021 if ( ext.startsWith(
'.' ) )
3025 int const drvCount = GDALGetDriverCount();
3027 for (
int i = 0; i < drvCount; ++i )
3029 GDALDriverH drv = GDALGetDriver( i );
3033 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE,
false ) && CSLFetchBoolean( driverMetadata, GDAL_DCAP_VECTOR,
false ) )
3035 QString drvName = GDALGetDriverShortName( drv );
3036 QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
3038 Q_FOREACH (
const QString &driver, driverExtensions )
3040 if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
3051 QString filterString;
3055 if ( !filterString.isEmpty() )
3056 filterString += QLatin1String(
";;" );
3058 filterString += details.filterString;
3060 return filterString;
3069 return QStringLiteral(
"%1 (%2 %3)" ).arg( metadata.
trLongName,
3070 metadata.
glob.toLower(),
3071 metadata.
glob.toUpper() );
3076 if ( codecName == QLatin1String(
"System" ) )
3077 return QStringLiteral(
"LDID/0" );
3079 QRegExp re = QRegExp( QString(
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
3080 if ( re.exactMatch( codecName ) )
3082 QString
c = re.cap( 2 ).remove(
'-' );
3084 c.toInt( &isNumber );
3112 OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
3113 OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
3116 int nTotalLevels = 0;
3118 QgsSymbolList::iterator symbolIt = symbolList.begin();
3119 for ( ; symbolIt != symbolList.end(); ++symbolIt )
3121 double mmsf = mmScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
3122 double musf = mapUnitScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
3124 int nLevels = ( *symbolIt )->symbolLayerCount();
3125 for (
int i = 0; i < nLevels; ++i )
3127 mSymbolLayerTable.insert( ( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
3128 OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
3129 ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
3133 OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
3139 if ( !details.renderer )
3142 mRenderContext.expressionContext() = details.expressionContext;
3144 QHash< QgsSymbol *, QList<QgsFeature> > features;
3153 startRender( details.renderer.get(), details.sourceFields );
3164 if ( fet.hasGeometry() )
3168 fet.setGeometry( g );
3173 QString msg = QObject::tr(
"Failed to transform, writing stopped. (Exception: %1)" )
3177 *errorMessage = msg;
3182 mRenderContext.expressionContext().setFeature( fet );
3184 featureSymbol = mRenderer->symbolForFeature( fet, mRenderContext );
3185 if ( !featureSymbol )
3190 QHash< QgsSymbol *, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
3191 if ( it == features.end() )
3193 it = features.insert( featureSymbol, QList<QgsFeature>() );
3195 it.value().append( fet );
3200 QgsSymbolList symbols = mRenderer->symbols( mRenderContext );
3201 for (
int i = 0; i < symbols.count(); i++ )
3207 if ( level < 0 || level >= 1000 )
3210 while ( level >= levels.count() )
3212 levels[level].append( item );
3217 int nTotalFeatures = 0;
3220 for (
int l = 0; l < levels.count(); l++ )
3223 for (
int i = 0; i < level.count(); i++ )
3226 QHash< QgsSymbol *, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
3227 if ( levelIt == features.end() )
3233 double mmsf = mmScaleFactor(
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
3234 double musf = mapUnitScaleFactor(
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
3236 int llayer = item.
layer();
3237 QList<QgsFeature> &featureList = levelIt.value();
3238 QList<QgsFeature>::iterator featureIt = featureList.begin();
3239 for ( ; featureIt != featureList.end(); ++featureIt )
3249 QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
3250 if ( !styleString.isEmpty() )
3252 OGR_F_SetStyleString( ogrFeature.get(), styleString.toLocal8Bit().constData() );
3253 if ( !writeFeature(
mLayer, ogrFeature.get() ) )
3264 if ( nErrors > 0 && errorMessage )
3266 *errorMessage += QObject::tr(
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
3283 return 1000 / scale;
3300 return scale / 1000;
3308 mRenderer = createSymbologyRenderer( sourceRenderer );
3314 mRenderer->startRender( mRenderContext, fields );
3317 void QgsVectorFileWriter::stopRender()
3324 mRenderer->stopRender( mRenderContext );
3327 std::unique_ptr<QgsFeatureRenderer> QgsVectorFileWriter::createSymbologyRenderer(
QgsFeatureRenderer *sourceRenderer )
const 3333 if ( !sourceRenderer )
3338 return std::unique_ptr< QgsFeatureRenderer >( sourceRenderer->
clone() );
3345 const QSet<QString> rendererAttributes = renderer->
usedAttributes( context );
3346 for (
const QString &attr : rendererAttributes )
3351 attList.append( index );
3357 QStringList QgsVectorFileWriter::concatenateOptions(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
3360 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
3362 for ( it = options.constBegin(); it != options.constEnd(); ++it )
3365 switch ( option->
type )
3372 list.append( QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( opt->
defaultValue ) );
3382 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
3392 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
3401 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue ) );
3412 OGRSFDriverH hDriver =
nullptr;
3416 QString drvName = OGR_Dr_GetName( hDriver );
3417 QgsVectorFileWriter::EditionCapabilities caps =
nullptr;
3418 if ( OGR_DS_TestCapability( hDS.get(), ODsCCreateLayer ) )
3423 if ( !( drvName == QLatin1String(
"ESRI Shapefile" ) && QFile::exists( datasetName ) ) )
3426 if ( OGR_DS_TestCapability( hDS.get(), ODsCDeleteLayer ) )
3430 int layer_count = OGR_DS_GetLayerCount( hDS.get() );
3433 OGRLayerH hLayer = OGR_DS_GetLayer( hDS.get(), 0 );
3436 if ( OGR_L_TestCapability( hLayer, OLCSequentialWrite ) )
3439 if ( OGR_L_TestCapability( hLayer, OLCCreateField ) )
3450 const QString &layerNameIn )
3452 OGRSFDriverH hDriver =
nullptr;
3458 if ( layerName.isEmpty() )
3459 layerName = QFileInfo( datasetName ).baseName();
3461 return OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
3470 OGRSFDriverH hDriver =
nullptr;
3474 OGRLayerH hLayer = OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
3480 OGRFeatureDefnH defn = OGR_L_GetLayerDefn( hLayer );
3481 Q_FOREACH (
int idx, attributes )
3484 if ( OGR_FD_GetFieldIndex( defn, fld.
name().toUtf8().constData() ) < 0 )
int lookupField(const QString &fieldName) const
Look 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.
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.
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.
QVariant minimumValue(int index) const override
Returns the minimum value for an attribute column or an invalid variant in case of error...
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.
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.
A geometry is the spatial representation of a feature.
int symbolLayerCount() const
Returns 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.
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.
QList< QgsSymbol * > QgsSymbolList
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.
QgsFields fields() const override
Returns the list of fields of this layer.
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.
#define FID_TO_NUMBER(fid)
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...
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.
QgsWkbTypes::Type wkbType() const override
Returns the WKBType or WKBUnknown in case of error.
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.
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)
Create a new vector file writer.
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
Create or overwrite layer.
QgsCoordinateReferenceSystem crs() const
Returns the layer's spatial reference system.
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.
QgsGeometry geometry() const
Returns the geometry associated with this feature.
QgsSymbolLayer * symbolLayer(int layer)
Returns a specific symbol layers 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.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const override
Query the layer for features specified in request.
Append features to existing layer, and create new fields if needed.
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
QVariant maximumValue(int index) const override
Returns the maximum value for an attribute column or an invalid variant in case of error...
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 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)
Write contents of vector layer to an (OGR supported) vector formt.
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)
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()).
QgsVectorDataProvider * dataProvider() override
Returns the layer's data provider.
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.
bool includeZ
Sets to true to include z dimension in output. This option is only valid if overrideGeometryType is s...
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...
QList< int > QgsAttributeList
SaveVectorOptions()
Constructor.
static bool targetLayerExists(const QString &datasetName, const QString &layerName)
Returns whether the target layer already exists.
QString providerType() const
Returns the provider type for this layer.
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.
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.
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.
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.