41 #include <QTextStream> 49 #include <ogr_srs_api.h> 50 #include <cpl_error.h> 52 #include <cpl_string.h> 71 const QString &vectorFileName,
72 const QString &fileEncoding,
76 const QString &driverName,
77 const QStringList &datasourceOptions,
78 const QStringList &layerOptions,
87 init( vectorFileName, fileEncoding, fields, geometryType,
88 srs, driverName, datasourceOptions, layerOptions, newFilename,
nullptr,
93 const QString &fileEncoding,
97 const QString &driverName,
98 const QStringList &datasourceOptions,
99 const QStringList &layerOptions,
100 QString *newFilename,
103 const QString &layerName,
110 init( vectorFileName, fileEncoding, fields, geometryType, srs, driverName,
111 datasourceOptions, layerOptions, newFilename, fieldValueConverter,
117 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0) 118 GDALDriverH gdalDriver = GDALGetDriverByName( driverName.toLocal8Bit().constData() );
123 if ( !driverMetadata )
126 return CSLFetchBoolean( driverMetadata, GDAL_DCAP_FEATURE_STYLES,
false );
128 return driverName == QLatin1String(
"DXF" ) || driverName == QLatin1String(
"KML" ) || driverName == QLatin1String(
"MapInfo File" ) || driverName == QLatin1String(
"MapInfo MIF" );
132 void QgsVectorFileWriter::init( QString vectorFileName,
133 QString fileEncoding,
137 const QString &driverName,
138 QStringList datasourceOptions,
139 QStringList layerOptions,
140 QString *newFilename,
142 const QString &layerNameIn,
147 if ( vectorFileName.isEmpty() )
154 if ( driverName == QLatin1String(
"MapInfo MIF" ) )
158 else if ( driverName == QLatin1String(
"SpatiaLite" ) )
161 if ( !datasourceOptions.contains( QStringLiteral(
"SPATIALITE=YES" ) ) )
163 datasourceOptions.append( QStringLiteral(
"SPATIALITE=YES" ) );
166 else if ( driverName == QLatin1String(
"DBF file" ) )
169 if ( !layerOptions.contains( QStringLiteral(
"SHPT=NULL" ) ) )
171 layerOptions.append( QStringLiteral(
"SHPT=NULL" ) );
181 OGRSFDriverH poDriver;
184 poDriver = OGRGetDriverByName(
mOgrDriverName.toLocal8Bit().constData() );
188 mErrorMessage = QObject::tr(
"OGR driver for '%1' not found (OGR error: %2)" )
190 QString::fromUtf8( CPLGetLastErrorMsg() ) );
200 if ( layerOptions.join( QLatin1String(
"" ) ).toUpper().indexOf( QLatin1String(
"ENCODING=" ) ) == -1 )
205 if ( driverName == QLatin1String(
"ESRI Shapefile" ) && !vectorFileName.endsWith( QLatin1String(
".shp" ), Qt::CaseInsensitive ) )
207 vectorFileName += QLatin1String(
".shp" );
209 else if ( driverName == QLatin1String(
"DBF file" ) && !vectorFileName.endsWith( QLatin1String(
".dbf" ), Qt::CaseInsensitive ) )
211 vectorFileName += QLatin1String(
".dbf" );
221 QStringList allExts = metadata.
ext.split(
' ', QString::SkipEmptyParts );
223 Q_FOREACH (
const QString &ext, allExts )
225 if ( vectorFileName.endsWith(
'.' + ext, Qt::CaseInsensitive ) )
234 vectorFileName +=
'.' + allExts[0];
240 if ( vectorFileName.endsWith( QLatin1String(
".gdb" ), Qt::CaseInsensitive ) )
242 QDir dir( vectorFileName );
245 QFileInfoList fileList = dir.entryInfoList(
246 QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst );
247 Q_FOREACH (
const QFileInfo &info, fileList )
249 QFile::remove( info.absoluteFilePath() );
252 QDir().rmdir( vectorFileName );
256 QFile::remove( vectorFileName );
271 char **options =
nullptr;
272 if ( !datasourceOptions.isEmpty() )
274 options =
new char *[ datasourceOptions.size() + 1 ];
275 for (
int i = 0; i < datasourceOptions.size(); i++ )
277 QgsDebugMsg( QString(
"-dsco=%1" ).arg( datasourceOptions[i] ) );
278 options[i] = CPLStrdup( datasourceOptions[i].toLocal8Bit().constData() );
280 options[ datasourceOptions.size()] =
nullptr;
285 mDS.reset( OGR_Dr_CreateDataSource( poDriver, vectorFileName.toUtf8().constData(), options ) );
287 mDS.reset( OGROpen( vectorFileName.toUtf8().constData(), TRUE, nullptr ) );
291 for (
int i = 0; i < datasourceOptions.size(); i++ )
292 CPLFree( options[i] );
301 mErrorMessage = QObject::tr(
"Creation of data source failed (OGR error: %1)" )
302 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
304 mErrorMessage = QObject::tr(
"Opening of data source in update mode failed (OGR error: %1)" )
305 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
309 QString layerName( layerNameIn );
310 if ( layerName.isEmpty() )
311 layerName = QFileInfo( vectorFileName ).baseName();
315 const int layer_count = OGR_DS_GetLayerCount(
mDS.get() );
316 for (
int i = 0; i < layer_count; i++ )
318 OGRLayerH hLayer = OGR_DS_GetLayer(
mDS.get(), i );
319 if ( EQUAL( OGR_L_GetName( hLayer ), layerName.toUtf8().constData() ) )
321 if ( OGR_DS_DeleteLayer(
mDS.get(), i ) != OGRERR_NONE )
324 mErrorMessage = QObject::tr(
"Overwriting of existing layer failed (OGR error: %1)" )
325 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
339 QgsDebugMsg(
"Opened data source in update mode" );
343 mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().constData() );
346 QgsDebugMsg(
"error finding QTextCodec for " + fileEncoding );
349 QString enc = settings.
value( QStringLiteral(
"UI/encoding" ),
"System" ).toString();
350 mCodec = QTextCodec::codecForName( enc.toLocal8Bit().constData() );
353 QgsDebugMsg(
"error finding QTextCodec for " + enc );
354 mCodec = QTextCodec::codecForLocale();
362 QString srsWkt = srs.
toWkt();
364 mOgrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().constData() );
371 int optIndex = layerOptions.indexOf( QStringLiteral(
"FEATURE_DATASET=" ) );
372 if ( optIndex != -1 )
374 layerOptions.removeAt( optIndex );
377 if ( !layerOptions.isEmpty() )
379 options =
new char *[ layerOptions.size() + 1 ];
380 for (
int i = 0; i < layerOptions.size(); i++ )
382 QgsDebugMsg( QString(
"-lco=%1" ).arg( layerOptions[i] ) );
383 options[i] = CPLStrdup( layerOptions[i].toLocal8Bit().constData() );
385 options[ layerOptions.size()] =
nullptr;
389 CPLSetConfigOption(
"SHAPE_ENCODING",
"" );
391 if ( driverName == QLatin1String(
"DGN" ) )
393 mLayer = OGR_DS_GetLayerByName(
mDS.get(),
"elements" );
397 mLayer = OGR_DS_CreateLayer(
mDS.get(), layerName.toUtf8().constData(),
mOgrRef, wkbType, options );
401 mLayer = OGR_DS_GetLayerByName(
mDS.get(), layerName.toUtf8().constData() );
406 for (
int i = 0; i < layerOptions.size(); i++ )
407 CPLFree( options[i] );
413 if ( !settings.
value( QStringLiteral(
"qgis/ignoreShapeEncoding" ),
true ).toBool() )
415 CPLSetConfigOption(
"SHAPE_ENCODING",
nullptr );
422 QString layerName = vectorFileName.left( vectorFileName.indexOf( QLatin1String(
".shp" ), Qt::CaseInsensitive ) );
423 QFile prjFile( layerName +
".qpj" );
424 if ( prjFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
426 QTextStream prjStream( &prjFile );
427 prjStream << srs.
toWkt().toLocal8Bit().constData() << endl;
432 QgsDebugMsg(
"Couldn't open file " + layerName +
".qpj" );
440 mErrorMessage = QObject::tr(
"Creation of layer failed (OGR error: %1)" )
441 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
443 mErrorMessage = QObject::tr(
"Opening of layer failed (OGR error: %1)" )
444 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
449 OGRFeatureDefnH defn = OGR_L_GetLayerDefn(
mLayer );
454 QgsDebugMsg(
"creating " + QString::number( fields.
size() ) +
" fields" );
458 QSet<int> existingIdxs;
465 fldIdx < fields.
count(); ++fldIdx )
469 if ( fieldValueConverter )
474 QString name( attrField.
name() );
477 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
485 OGRFieldType ogrType = OFTString;
486 int ogrWidth = attrField.
length();
487 int ogrPrecision = attrField.
precision();
488 if ( ogrPrecision > 0 )
491 switch ( attrField.
type() )
493 case QVariant::LongLong:
495 const char *pszDataTypes = GDALGetMetadataItem( poDriver, GDAL_DMD_CREATIONFIELDDATATYPES,
nullptr );
496 if ( pszDataTypes && strstr( pszDataTypes,
"Integer64" ) )
497 ogrType = OFTInteger64;
500 ogrWidth = ogrWidth > 0 && ogrWidth <= 20 ? ogrWidth : 20;
504 case QVariant::String:
506 if ( ogrWidth <= 0 || ogrWidth > 255 )
511 ogrType = OFTInteger;
512 ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
517 ogrType = OFTInteger;
522 case QVariant::Double:
542 case QVariant::DateTime:
550 ogrType = OFTDateTime;
556 mErrorMessage = QObject::tr(
"Unsupported type for field %1" )
557 .arg( attrField.
name() );
562 if (
mOgrDriverName == QLatin1String(
"SQLite" ) && name.compare( QLatin1String(
"ogc_fid" ), Qt::CaseInsensitive ) == 0 )
565 for ( i = 0; i < 10; i++ )
567 name = QStringLiteral(
"ogc_fid%1" ).arg( i );
570 for ( j = 0; j < fields.
size() && name.compare( fields.
at( j ).
name(), Qt::CaseInsensitive ) != 0; j++ )
573 if ( j == fields.
size() )
579 mErrorMessage = QObject::tr(
"No available replacement for internal fieldname ogc_fid found" ).arg( attrField.
name() );
584 QgsMessageLog::logMessage( QObject::tr(
"Reserved attribute name ogc_fid replaced with %1" ).arg( name ), QObject::tr(
"OGR" ) );
591 OGR_Fld_SetWidth( fld.get(), ogrWidth );
594 if ( ogrPrecision >= 0 )
596 OGR_Fld_SetPrecision( fld.get(), ogrPrecision );
599 switch ( attrField.
type() )
602 OGR_Fld_SetSubType( fld.get(), OFSTBoolean );
610 " type " + QString( QVariant::typeToName( attrField.
type() ) ) +
611 " width " + QString::number( ogrWidth ) +
612 " precision " + QString::number( ogrPrecision ) );
613 if ( OGR_L_CreateField(
mLayer, fld.get(), true ) != OGRERR_NONE )
616 mErrorMessage = QObject::tr(
"Creation of field %1 failed (OGR error: %2)" )
617 .arg( attrField.
name(),
618 QString::fromUtf8( CPLGetLastErrorMsg() ) );
623 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
624 QgsDebugMsg( QString(
"returned field index for %1: %2" ).arg( name ).arg( ogrIdx ) );
625 if ( ogrIdx < 0 || existingIdxs.contains( ogrIdx ) )
628 ogrIdx = OGR_FD_GetFieldCount( defn ) - 1;
633 mErrorMessage = QObject::tr(
"Created field %1 not found (OGR error: %2)" )
634 .arg( attrField.
name(),
635 QString::fromUtf8( CPLGetLastErrorMsg() ) );
641 existingIdxs.insert( ogrIdx );
647 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
650 QString name( attrField.
name() );
651 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
662 *newFilename = vectorFileName;
665 mUsingTransaction =
true;
666 if ( OGRERR_NONE != OGR_L_StartTransaction(
mLayer ) )
668 mUsingTransaction =
false;
677 QMap<QString, QgsVectorFileWriter::MetaData> QgsVectorFileWriter::initMetaData()
681 QMap<QString, Option *> datasetOptions;
682 QMap<QString, Option *> layerOptions;
685 datasetOptions.clear();
686 layerOptions.clear();
688 driverMetadata.insert( QStringLiteral(
"AVCE00" ),
690 QStringLiteral(
"Arc/Info ASCII Coverage" ),
691 QObject::tr(
"Arc/Info ASCII Coverage" ),
692 QStringLiteral(
"*.e00" ),
693 QStringLiteral(
"e00" ),
700 datasetOptions.clear();
701 layerOptions.clear();
703 datasetOptions.insert( QStringLiteral(
"LINEFORMAT" ),
new SetOption(
704 QObject::tr(
"New BNA files are created by the " 705 "systems default line termination conventions. " 706 "This may be overridden here." ),
708 << QStringLiteral(
"CRLF" )
709 << QStringLiteral(
"LF" ),
714 datasetOptions.insert( QStringLiteral(
"MULTILINE" ),
new BoolOption(
715 QObject::tr(
"By default, BNA files are created in multi-line format. " 716 "For each record, the first line contains the identifiers and the " 717 "type/number of coordinates to follow. Each following line contains " 718 "a pair of coordinates." ),
722 datasetOptions.insert( QStringLiteral(
"NB_IDS" ),
new SetOption(
723 QObject::tr(
"BNA records may contain from 2 to 4 identifiers per record. " 724 "Some software packages only support a precise number of identifiers. " 725 "You can override the default value (2) by a precise value." ),
727 << QStringLiteral(
"2" )
728 << QStringLiteral(
"3" )
729 << QStringLiteral(
"4" )
730 << QStringLiteral(
"NB_SOURCE_FIELDS" ),
731 QStringLiteral(
"2" )
734 datasetOptions.insert( QStringLiteral(
"ELLIPSES_AS_ELLIPSES" ),
new BoolOption(
735 QObject::tr(
"The BNA writer will try to recognize ellipses and circles when writing a polygon. " 736 "This will only work if the feature has previously been read from a BNA file. " 737 "As some software packages do not support ellipses/circles in BNA data file, " 738 "it may be useful to tell the writer by specifying ELLIPSES_AS_ELLIPSES=NO not " 739 "to export them as such, but keep them as polygons." ),
743 datasetOptions.insert( QStringLiteral(
"NB_PAIRS_PER_LINE" ),
new IntOption(
744 QObject::tr(
"Limit the number of coordinate pairs per line in multiline format." ),
748 datasetOptions.insert( QStringLiteral(
"COORDINATE_PRECISION" ),
new IntOption(
749 QObject::tr(
"Set the number of decimal for coordinates. Default value is 10." ),
753 driverMetadata.insert( QStringLiteral(
"BNA" ),
755 QStringLiteral(
"Atlas BNA" ),
756 QObject::tr(
"Atlas BNA" ),
757 QStringLiteral(
"*.bna" ),
758 QStringLiteral(
"bna" ),
765 datasetOptions.clear();
766 layerOptions.clear();
768 layerOptions.insert( QStringLiteral(
"LINEFORMAT" ),
new SetOption(
769 QObject::tr(
"By default when creating new .csv files they " 770 "are created with the line termination conventions " 771 "of the local platform (CR/LF on Win32 or LF on all other systems). " 772 "This may be overridden through the use of the LINEFORMAT option." ),
774 << QStringLiteral(
"CRLF" )
775 << QStringLiteral(
"LF" ),
780 layerOptions.insert( QStringLiteral(
"GEOMETRY" ),
new SetOption(
781 QObject::tr(
"By default, the geometry of a feature written to a .csv file is discarded. " 782 "It is possible to export the geometry in its WKT representation by " 783 "specifying GEOMETRY=AS_WKT. It is also possible to export point geometries " 784 "into their X,Y,Z components by specifying GEOMETRY=AS_XYZ, GEOMETRY=AS_XY " 785 "or GEOMETRY=AS_YX." ),
787 << QStringLiteral(
"AS_WKT" )
788 << QStringLiteral(
"AS_XYZ" )
789 << QStringLiteral(
"AS_XY" )
790 << QStringLiteral(
"AS_YX" ),
795 layerOptions.insert( QStringLiteral(
"CREATE_CSVT" ),
new BoolOption(
796 QObject::tr(
"Create the associated .csvt file to describe the type of each " 797 "column of the layer and its optional width and precision." ),
801 layerOptions.insert( QStringLiteral(
"SEPARATOR" ),
new SetOption(
802 QObject::tr(
"Field separator character." ),
804 << QStringLiteral(
"COMMA" )
805 << QStringLiteral(
"SEMICOLON" )
806 << QStringLiteral(
"TAB" ),
807 QStringLiteral(
"COMMA" )
810 layerOptions.insert( QStringLiteral(
"WRITE_BOM" ),
new BoolOption(
811 QObject::tr(
"Write a UTF-8 Byte Order Mark (BOM) at the start of the file." ),
815 driverMetadata.insert( QStringLiteral(
"CSV" ),
817 QStringLiteral(
"Comma Separated Value [CSV]" ),
818 QObject::tr(
"Comma Separated Value [CSV]" ),
819 QStringLiteral(
"*.csv" ),
820 QStringLiteral(
"csv" ),
827 datasetOptions.clear();
828 layerOptions.clear();
830 layerOptions.insert( QStringLiteral(
"SHPT" ),
new SetOption(
831 QObject::tr(
"Override the type of shapefile created. " 832 "Can be one of NULL for a simple .dbf file with no .shp file, POINT, " 833 "ARC, POLYGON or MULTIPOINT for 2D, or POINTZ, ARCZ, POLYGONZ or " 834 "MULTIPOINTZ for 3D;" ) +
835 QObject::tr(
" POINTM, ARCM, POLYGONM or MULTIPOINTM for measured geometries" 836 " and POINTZM, ARCZM, POLYGONZM or MULTIPOINTZM for 3D measured" 838 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
839 QObject::tr(
" MULTIPATCH files are supported since GDAL 2.2." ) +
843 << QStringLiteral(
"NULL" )
844 << QStringLiteral(
"POINT" )
845 << QStringLiteral(
"ARC" )
846 << QStringLiteral(
"POLYGON" )
847 << QStringLiteral(
"MULTIPOINT" )
848 << QStringLiteral(
"POINTZ" )
849 << QStringLiteral(
"ARCZ" )
850 << QStringLiteral(
"POLYGONZ" )
851 << QStringLiteral(
"MULTIPOINTZ" )
852 << QStringLiteral(
"POINTM" )
853 << QStringLiteral(
"ARCM" )
854 << QStringLiteral(
"POLYGONM" )
855 << QStringLiteral(
"MULTIPOINTM" )
856 << QStringLiteral(
"POINTZM" )
857 << QStringLiteral(
"ARCZM" )
858 << QStringLiteral(
"POLYGONZM" )
859 << QStringLiteral(
"MULTIPOINTZM" )
860 #
if defined(GDAL_COMPUTE_VERSION) && GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0)
861 << QStringLiteral(
"MULTIPATCH" )
863 << QStringLiteral(
"" ),
871 layerOptions.insert(
"ENCODING",
new SetOption(
872 QObject::tr(
"Set the encoding value in the DBF file. " 873 "The default value is LDID/87. It is not clear " 874 "what other values may be appropriate." ),
881 layerOptions.insert( QStringLiteral(
"RESIZE" ),
new BoolOption(
882 QObject::tr(
"Set to YES to resize fields to their optimal size." ),
886 driverMetadata.insert( QStringLiteral(
"ESRI" ),
888 QStringLiteral(
"ESRI Shapefile" ),
889 QObject::tr(
"ESRI Shapefile" ),
890 QStringLiteral(
"*.shp" ),
891 QStringLiteral(
"shp" ),
898 datasetOptions.clear();
899 layerOptions.clear();
901 driverMetadata.insert( QStringLiteral(
"DBF File" ),
903 QStringLiteral(
"DBF File" ),
904 QObject::tr(
"DBF File" ),
905 QStringLiteral(
"*.dbf" ),
906 QStringLiteral(
"dbf" ),
913 datasetOptions.clear();
914 layerOptions.clear();
916 driverMetadata.insert( QStringLiteral(
"FMEObjects Gateway" ),
918 QStringLiteral(
"FMEObjects Gateway" ),
919 QObject::tr(
"FMEObjects Gateway" ),
920 QStringLiteral(
"*.fdd" ),
921 QStringLiteral(
"fdd" ),
928 datasetOptions.clear();
929 layerOptions.clear();
931 layerOptions.insert( QStringLiteral(
"WRITE_BBOX" ),
new BoolOption(
932 QObject::tr(
"Set to YES to write a bbox property with the bounding box " 933 "of the geometries at the feature and feature collection level." ),
937 layerOptions.insert( QStringLiteral(
"COORDINATE_PRECISION" ),
new IntOption(
938 QObject::tr(
"Maximum number of figures after decimal separator to write in coordinates. " 939 "Default to 15. Truncation will occur to remove trailing zeros." ),
943 driverMetadata.insert( QStringLiteral(
"GeoJSON" ),
945 QStringLiteral(
"GeoJSON" ),
946 QObject::tr(
"GeoJSON" ),
947 QStringLiteral(
"*.geojson" ),
948 QStringLiteral(
"geojson" ),
951 QStringLiteral(
"UTF-8" )
956 datasetOptions.clear();
957 layerOptions.clear();
959 datasetOptions.insert( QStringLiteral(
"FORMAT" ),
new SetOption(
960 QObject::tr(
"whether the document must be in RSS 2.0 or Atom 1.0 format. " 961 "Default value : RSS" ),
963 << QStringLiteral(
"RSS" )
964 << QStringLiteral(
"ATOM" ),
965 QStringLiteral(
"RSS" )
968 datasetOptions.insert( QStringLiteral(
"GEOM_DIALECT" ),
new SetOption(
969 QObject::tr(
"The encoding of location information. Default value : SIMPLE. " 970 "W3C_GEO only supports point geometries. " 971 "SIMPLE or W3C_GEO only support geometries in geographic WGS84 coordinates." ),
973 << QStringLiteral(
"SIMPLE" )
974 << QStringLiteral(
"GML" )
975 << QStringLiteral(
"W3C_GEO" ),
976 QStringLiteral(
"SIMPLE" )
979 datasetOptions.insert( QStringLiteral(
"USE_EXTENSIONS" ),
new BoolOption(
980 QObject::tr(
"If defined to YES, extension fields will be written. " 981 "If the field name not found in the base schema matches " 982 "the foo_bar pattern, foo will be considered as the namespace " 983 "of the element, and a <foo:bar> element will be written. " 984 "Otherwise, elements will be written in the <ogr:> namespace." ),
988 datasetOptions.insert( QStringLiteral(
"WRITE_HEADER_AND_FOOTER" ),
new BoolOption(
989 QObject::tr(
"If defined to NO, only <entry> or <item> elements will be written. " 990 "The user will have to provide the appropriate header and footer of the document." ),
994 datasetOptions.insert( QStringLiteral(
"HEADER" ),
new StringOption(
995 QObject::tr(
"XML content that will be put between the <channel> element and the " 996 "first <item> element for a RSS document, or between the xml tag and " 997 "the first <entry> element for an Atom document." ),
1001 datasetOptions.insert( QStringLiteral(
"TITLE" ),
new StringOption(
1002 QObject::tr(
"Value put inside the <title> element in the header. " 1003 "If not provided, a dummy value will be used as that element is compulsory." ),
1007 datasetOptions.insert( QStringLiteral(
"DESCRIPTION" ),
new StringOption(
1008 QObject::tr(
"Value put inside the <description> element in the header. " 1009 "If not provided, a dummy value will be used as that element is compulsory." ),
1013 datasetOptions.insert( QStringLiteral(
"LINK" ),
new StringOption(
1014 QObject::tr(
"Value put inside the <link> element in the header. " 1015 "If not provided, a dummy value will be used as that element is compulsory." ),
1019 datasetOptions.insert( QStringLiteral(
"UPDATED" ),
new StringOption(
1020 QObject::tr(
"Value put inside the <updated> element in the header. " 1021 "Should be formatted as a XML datetime. " 1022 "If not provided, a dummy value will be used as that element is compulsory." ),
1026 datasetOptions.insert( QStringLiteral(
"AUTHOR_NAME" ),
new StringOption(
1027 QObject::tr(
"Value put inside the <author><name> element in the header. " 1028 "If not provided, a dummy value will be used as that element is compulsory." ),
1032 datasetOptions.insert( QStringLiteral(
"ID" ),
new StringOption(
1033 QObject::tr(
"Value put inside the <id> element in the header. " 1034 "If not provided, a dummy value will be used as that element is compulsory." ),
1038 driverMetadata.insert( QStringLiteral(
"GeoRSS" ),
1040 QStringLiteral(
"GeoRSS" ),
1041 QObject::tr(
"GeoRSS" ),
1042 QStringLiteral(
"*.xml" ),
1043 QStringLiteral(
"xml" ),
1046 QStringLiteral(
"UTF-8" )
1051 datasetOptions.clear();
1052 layerOptions.clear();
1054 datasetOptions.insert( QStringLiteral(
"XSISCHEMAURI" ),
new StringOption(
1055 QObject::tr(
"If provided, this URI will be inserted as the schema location. " 1056 "Note that the schema file isn't actually accessed by OGR, so it " 1057 "is up to the user to ensure it will match the schema of the OGR " 1058 "produced GML data file." ),
1062 datasetOptions.insert( QStringLiteral(
"XSISCHEMA" ),
new SetOption(
1063 QObject::tr(
"This writes a GML application schema file to a corresponding " 1064 ".xsd file (with the same basename). If INTERNAL is used the " 1065 "schema is written within the GML file, but this is experimental " 1066 "and almost certainly not valid XML. " 1067 "OFF disables schema generation (and is implicit if XSISCHEMAURI is used)." ),
1069 << QStringLiteral(
"EXTERNAL" )
1070 << QStringLiteral(
"INTERNAL" )
1071 << QStringLiteral(
"OFF" ),
1072 QStringLiteral(
"EXTERNAL" )
1075 datasetOptions.insert( QStringLiteral(
"PREFIX" ),
new StringOption(
1076 QObject::tr(
"This is the prefix for the application target namespace." ),
1077 QStringLiteral(
"ogr" )
1080 datasetOptions.insert( QStringLiteral(
"STRIP_PREFIX" ),
new BoolOption(
1081 QObject::tr(
"Can be set to TRUE to avoid writing the prefix of the " 1082 "application target namespace in the GML file." ),
1086 datasetOptions.insert( QStringLiteral(
"TARGET_NAMESPACE" ),
new StringOption(
1087 QObject::tr(
"Defaults to 'http://ogr.maptools.org/'. " 1088 "This is the application target namespace." ),
1089 QStringLiteral(
"http://ogr.maptools.org/" )
1092 datasetOptions.insert( QStringLiteral(
"FORMAT" ),
new SetOption(
1093 QObject::tr(
"If not specified, GML2 will be used." ),
1095 << QStringLiteral(
"GML3" )
1096 << QStringLiteral(
"GML3Deegree" )
1097 << QStringLiteral(
"GML3.2" ),
1098 QLatin1String(
"" ),
1102 datasetOptions.insert( QStringLiteral(
"GML3_LONGSRS" ),
new BoolOption(
1103 QObject::tr(
"Only valid when FORMAT=GML3/GML3Degree/GML3.2. Default to YES. " 1104 "If YES, SRS with EPSG authority will be written with the " 1105 "'urn:ogc:def:crs:EPSG::' prefix. In the case the SRS is a " 1106 "geographic SRS without explicit AXIS order, but that the same " 1107 "SRS authority code imported with ImportFromEPSGA() should be " 1108 "treated as lat/long, then the function will take care of coordinate " 1109 "order swapping. If set to NO, SRS with EPSG authority will be " 1110 "written with the 'EPSG:' prefix, even if they are in lat/long order." ),
1114 datasetOptions.insert( QStringLiteral(
"WRITE_FEATURE_BOUNDED_BY" ),
new BoolOption(
1115 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. " 1116 "If set to NO, the <gml:boundedBy> element will not be written for " 1121 datasetOptions.insert( QStringLiteral(
"SPACE_INDENTATION" ),
new BoolOption(
1122 QObject::tr(
"Default to YES. If YES, the output will be indented with spaces " 1123 "for more readability, but at the expense of file size." ),
1128 driverMetadata.insert( QStringLiteral(
"GML" ),
1130 QStringLiteral(
"Geography Markup Language [GML]" ),
1131 QObject::tr(
"Geography Markup Language [GML]" ),
1132 QStringLiteral(
"*.gml" ),
1133 QStringLiteral(
"gml" ),
1136 QStringLiteral(
"UTF-8" )
1141 datasetOptions.clear();
1142 layerOptions.clear();
1144 layerOptions.insert( QStringLiteral(
"IDENTIFIER" ),
new StringOption(
1145 QObject::tr(
"Human-readable identifier (e.g. short name) for the layer content" ),
1149 layerOptions.insert( QStringLiteral(
"DESCRIPTION" ),
new StringOption(
1150 QObject::tr(
"Human-readable description for the layer content" ),
1154 layerOptions.insert( QStringLiteral(
"FID" ),
new StringOption(
1155 QObject::tr(
"Name for the feature identifier column" ),
1156 QStringLiteral(
"fid" )
1159 layerOptions.insert( QStringLiteral(
"GEOMETRY_NAME" ),
new StringOption(
1160 QObject::tr(
"Name for the geometry column" ),
1161 QStringLiteral(
"geom" )
1164 layerOptions.insert( QStringLiteral(
"SPATIAL_INDEX" ),
new BoolOption(
1165 QObject::tr(
"If a spatial index must be created." ),
1169 driverMetadata.insert( QStringLiteral(
"GPKG" ),
1171 QStringLiteral(
"GeoPackage" ),
1172 QObject::tr(
"GeoPackage" ),
1173 QStringLiteral(
"*.gpkg" ),
1174 QStringLiteral(
"gpkg" ),
1177 QStringLiteral(
"UTF-8" )
1182 datasetOptions.clear();
1183 layerOptions.clear();
1185 driverMetadata.insert( QStringLiteral(
"GMT" ),
1187 QStringLiteral(
"Generic Mapping Tools [GMT]" ),
1188 QObject::tr(
"Generic Mapping Tools [GMT]" ),
1189 QStringLiteral(
"*.gmt" ),
1190 QStringLiteral(
"gmt" ),
1197 datasetOptions.clear();
1198 layerOptions.clear();
1200 layerOptions.insert( QStringLiteral(
"FORCE_GPX_TRACK" ),
new BoolOption(
1201 QObject::tr(
"By default when writing a layer whose features are of " 1202 "type wkbLineString, the GPX driver chooses to write " 1203 "them as routes. If FORCE_GPX_TRACK=YES is specified, " 1204 "they will be written as tracks." ),
1208 layerOptions.insert( QStringLiteral(
"FORCE_GPX_ROUTE" ),
new BoolOption(
1209 QObject::tr(
"By default when writing a layer whose features are of " 1210 "type wkbMultiLineString, the GPX driver chooses to write " 1211 "them as tracks. If FORCE_GPX_ROUTE=YES is specified, " 1212 "they will be written as routes, provided that the multilines " 1213 "are composed of only one single line." ),
1217 datasetOptions.insert( QStringLiteral(
"GPX_USE_EXTENSIONS" ),
new BoolOption(
1218 QObject::tr(
"If GPX_USE_EXTENSIONS=YES is specified, " 1219 "extra fields will be written inside the <extensions> tag." ),
1223 datasetOptions.insert( QStringLiteral(
"GPX_EXTENSIONS_NS" ),
new StringOption(
1224 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS_URL " 1225 "is set. The namespace value used for extension tags. By default, 'ogr'." ),
1226 QStringLiteral(
"ogr" )
1229 datasetOptions.insert( QStringLiteral(
"GPX_EXTENSIONS_NS_URL" ),
new StringOption(
1230 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS " 1231 "is set. The namespace URI. By default, 'http://osgeo.org/gdal'." ),
1232 QStringLiteral(
"http://osgeo.org/gdal" )
1235 datasetOptions.insert( QStringLiteral(
"LINEFORMAT" ),
new SetOption(
1236 QObject::tr(
"By default files are created with the line termination " 1237 "conventions of the local platform (CR/LF on win32 or LF " 1238 "on all other systems). This may be overridden through use " 1239 "of the LINEFORMAT layer creation option which may have a value " 1240 "of CRLF (DOS format) or LF (Unix format)." ),
1242 << QStringLiteral(
"CRLF" )
1243 << QStringLiteral(
"LF" ),
1244 QLatin1String(
"" ),
1248 driverMetadata.insert( QStringLiteral(
"GPX" ),
1250 QStringLiteral(
"GPS eXchange Format [GPX]" ),
1251 QObject::tr(
"GPS eXchange Format [GPX]" ),
1252 QStringLiteral(
"*.gpx" ),
1253 QStringLiteral(
"gpx" ),
1256 QStringLiteral(
"UTF-8" )
1261 datasetOptions.clear();
1262 layerOptions.clear();
1264 driverMetadata.insert( QStringLiteral(
"Interlis 1" ),
1266 QStringLiteral(
"INTERLIS 1" ),
1267 QObject::tr(
"INTERLIS 1" ),
1268 QStringLiteral(
"*.itf *.xml *.ili" ),
1269 QStringLiteral(
"ili" ),
1276 datasetOptions.clear();
1277 layerOptions.clear();
1279 driverMetadata.insert( QStringLiteral(
"Interlis 2" ),
1281 QStringLiteral(
"INTERLIS 2" ),
1282 QObject::tr(
"INTERLIS 2" ),
1283 QStringLiteral(
"*.xtf *.xml *.ili" ),
1284 QStringLiteral(
"ili" ),
1291 datasetOptions.clear();
1292 layerOptions.clear();
1294 datasetOptions.insert( QStringLiteral(
"NameField" ),
new StringOption(
1295 QObject::tr(
"Allows you to specify the field to use for the KML <name> element." ),
1296 QStringLiteral(
"Name" )
1299 datasetOptions.insert( QStringLiteral(
"DescriptionField" ),
new StringOption(
1300 QObject::tr(
"Allows you to specify the field to use for the KML <description> element." ),
1301 QStringLiteral(
"Description" )
1304 datasetOptions.insert( QStringLiteral(
"AltitudeMode" ),
new SetOption(
1305 QObject::tr(
"Allows you to specify the AltitudeMode to use for KML geometries. " 1306 "This will only affect 3D geometries and must be one of the valid KML options." ),
1308 << QStringLiteral(
"clampToGround" )
1309 << QStringLiteral(
"relativeToGround" )
1310 << QStringLiteral(
"absolute" ),
1311 QStringLiteral(
"relativeToGround" )
1314 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,2,0) 1315 datasetOptions.insert( QStringLiteral(
"DOCUMENT_ID" ),
new StringOption(
1316 QObject::tr(
"The DOCUMENT_ID datasource creation option can be used to specified " 1317 "the id of the root <Document> node. The default value is root_doc." ),
1318 QStringLiteral(
"root_doc" )
1322 driverMetadata.insert( QStringLiteral(
"KML" ),
1324 QStringLiteral(
"Keyhole Markup Language [KML]" ),
1325 QObject::tr(
"Keyhole Markup Language [KML]" ),
1326 QStringLiteral(
"*.kml" ),
1327 QStringLiteral(
"kml" ),
1330 QStringLiteral(
"UTF-8" )
1335 datasetOptions.clear();
1336 layerOptions.clear();
1338 datasetOptions.insert( QStringLiteral(
"SPATIAL_INDEX_MODE" ),
new SetOption(
1339 QObject::tr(
"Use this to turn on 'quick spatial index mode'. " 1340 "In this mode writing files can be about 5 times faster, " 1341 "but spatial queries can be up to 30 times slower." ),
1343 << QStringLiteral(
"QUICK" )
1344 << QStringLiteral(
"OPTIMIZED" ),
1345 QStringLiteral(
"QUICK" ),
1349 datasetOptions.insert( QStringLiteral(
"BLOCK_SIZE" ),
new IntOption(
1350 QObject::tr(
"(multiples of 512): Block size for .map files. Defaults " 1351 "to 512. MapInfo 15.2 and above creates .tab files with a " 1352 "blocksize of 16384 bytes. Any MapInfo version should be " 1353 "able to handle block sizes from 512 to 32256." ),
1356 layerOptions.insert( QStringLiteral(
"BOUNDS" ),
new StringOption(
1357 QObject::tr(
"xmin,ymin,xmax,ymax: Define custom layer bounds to increase the " 1358 "accuracy of the coordinates. Note: the geometry of written " 1359 "features must be within the defined box." ),
1363 driverMetadata.insert( QStringLiteral(
"MapInfo File" ),
1365 QStringLiteral(
"Mapinfo" ),
1366 QObject::tr(
"Mapinfo TAB" ),
1367 QStringLiteral(
"*.tab" ),
1368 QStringLiteral(
"tab" ),
1375 driverMetadata.insert( QStringLiteral(
"MapInfo MIF" ),
1377 QStringLiteral(
"Mapinfo" ),
1378 QObject::tr(
"Mapinfo MIF" ),
1379 QStringLiteral(
"*.mif" ),
1380 QStringLiteral(
"mif" ),
1387 datasetOptions.clear();
1388 layerOptions.clear();
1390 datasetOptions.insert( QStringLiteral(
"3D" ),
new BoolOption(
1391 QObject::tr(
"Determine whether 2D (seed_2d.dgn) or 3D (seed_3d.dgn) " 1392 "seed file should be used. This option is ignored if the SEED option is provided." ),
1396 datasetOptions.insert( QStringLiteral(
"SEED" ),
new StringOption(
1397 QObject::tr(
"Override the seed file to use." ),
1401 datasetOptions.insert( QStringLiteral(
"COPY_WHOLE_SEED_FILE" ),
new BoolOption(
1402 QObject::tr(
"Indicate whether the whole seed file should be copied. " 1403 "If not, only the first three elements will be copied." ),
1407 datasetOptions.insert( QStringLiteral(
"COPY_SEED_FILE_COLOR_TABLE" ),
new BoolOption(
1408 QObject::tr(
"Indicates whether the color table should be copied from the seed file." ),
1412 datasetOptions.insert( QStringLiteral(
"MASTER_UNIT_NAME" ),
new StringOption(
1413 QObject::tr(
"Override the master unit name from the seed file with " 1414 "the provided one or two character unit name." ),
1418 datasetOptions.insert( QStringLiteral(
"SUB_UNIT_NAME" ),
new StringOption(
1419 QObject::tr(
"Override the sub unit name from the seed file with the provided " 1420 "one or two character unit name." ),
1424 datasetOptions.insert( QStringLiteral(
"SUB_UNITS_PER_MASTER_UNIT" ),
new IntOption(
1425 QObject::tr(
"Override the number of subunits per master unit. " 1426 "By default the seed file value is used." ),
1430 datasetOptions.insert( QStringLiteral(
"UOR_PER_SUB_UNIT" ),
new IntOption(
1431 QObject::tr(
"Override the number of UORs (Units of Resolution) " 1432 "per sub unit. By default the seed file value is used." ),
1436 datasetOptions.insert( QStringLiteral(
"ORIGIN" ),
new StringOption(
1437 QObject::tr(
"ORIGIN=x,y,z: Override the origin of the design plane. " 1438 "By default the origin from the seed file is used." ),
1442 driverMetadata.insert( QStringLiteral(
"DGN" ),
1444 QStringLiteral(
"Microstation DGN" ),
1445 QObject::tr(
"Microstation DGN" ),
1446 QStringLiteral(
"*.dgn" ),
1447 QStringLiteral(
"dgn" ),
1454 datasetOptions.clear();
1455 layerOptions.clear();
1457 datasetOptions.insert( QStringLiteral(
"UPDATES" ),
new SetOption(
1458 QObject::tr(
"Should update files be incorporated into the base data on the fly." ),
1460 << QStringLiteral(
"APPLY" )
1461 << QStringLiteral(
"IGNORE" ),
1462 QStringLiteral(
"APPLY" )
1465 datasetOptions.insert( QStringLiteral(
"SPLIT_MULTIPOINT" ),
new BoolOption(
1466 QObject::tr(
"Should multipoint soundings be split into many single point sounding features. " 1467 "Multipoint geometries are not well handled by many formats, " 1468 "so it can be convenient to split single sounding features with many points " 1469 "into many single point features." ),
1473 datasetOptions.insert( QStringLiteral(
"ADD_SOUNDG_DEPTH" ),
new BoolOption(
1474 QObject::tr(
"Should a DEPTH attribute be added on SOUNDG features and assign the depth " 1475 "of the sounding. This should only be enabled when SPLIT_MULTIPOINT is " 1480 datasetOptions.insert( QStringLiteral(
"RETURN_PRIMITIVES" ),
new BoolOption(
1481 QObject::tr(
"Should all the low level geometry primitives be returned as special " 1482 "IsolatedNode, ConnectedNode, Edge and Face layers." ),
1486 datasetOptions.insert( QStringLiteral(
"PRESERVE_EMPTY_NUMBERS" ),
new BoolOption(
1487 QObject::tr(
"If enabled, numeric attributes assigned an empty string as a value will " 1488 "be preserved as a special numeric value. This option should not generally " 1489 "be needed, but may be useful when translated S-57 to S-57 losslessly." ),
1493 datasetOptions.insert( QStringLiteral(
"LNAM_REFS" ),
new BoolOption(
1494 QObject::tr(
"Should LNAM and LNAM_REFS fields be attached to features capturing " 1495 "the feature to feature relationships in the FFPT group of the S-57 file." ),
1499 datasetOptions.insert( QStringLiteral(
"RETURN_LINKAGES" ),
new BoolOption(
1500 QObject::tr(
"Should additional attributes relating features to their underlying " 1501 "geometric primitives be attached. These are the values of the FSPT group, " 1502 "and are primarily needed when doing S-57 to S-57 translations." ),
1506 datasetOptions.insert( QStringLiteral(
"RECODE_BY_DSSI" ),
new BoolOption(
1507 QObject::tr(
"Should attribute values be recoded to UTF-8 from the character encoding " 1508 "specified in the S57 DSSI record." ),
1514 driverMetadata.insert( QStringLiteral(
"S57" ),
1516 QStringLiteral(
"S-57 Base file" ),
1517 QObject::tr(
"S-57 Base file" ),
1518 QStringLiteral(
"*.000" ),
1519 QStringLiteral(
"000" ),
1526 datasetOptions.clear();
1527 layerOptions.clear();
1529 driverMetadata.insert( QStringLiteral(
"SDTS" ),
1531 QStringLiteral(
"Spatial Data Transfer Standard [SDTS]" ),
1532 QObject::tr(
"Spatial Data Transfer Standard [SDTS]" ),
1533 QStringLiteral(
"*catd.ddf" ),
1534 QStringLiteral(
"ddf" ),
1541 datasetOptions.clear();
1542 layerOptions.clear();
1544 datasetOptions.insert( QStringLiteral(
"METADATA" ),
new BoolOption(
1545 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys " 1546 "tables in a new database. By default these metadata tables are created " 1547 "when a new database is created." ),
1552 datasetOptions.insert( QStringLiteral(
"SPATIALITE" ),
new HiddenOption(
1553 QStringLiteral(
"NO" )
1557 datasetOptions.insert( QStringLiteral(
"INIT_WITH_EPSG" ),
new HiddenOption(
1558 QStringLiteral(
"NO" )
1561 layerOptions.insert( QStringLiteral(
"FORMAT" ),
new SetOption(
1562 QObject::tr(
"Controls the format used for the geometry column. Defaults to WKB. " 1563 "This is generally more space and processing efficient, but harder " 1564 "to inspect or use in simple applications than WKT (Well Known Text)." ),
1566 << QStringLiteral(
"WKB" )
1567 << QStringLiteral(
"WKT" ),
1568 QStringLiteral(
"WKB" )
1571 layerOptions.insert( QStringLiteral(
"LAUNDER" ),
new BoolOption(
1572 QObject::tr(
"Controls whether layer and field names will be laundered for easier use " 1573 "in SQLite. Laundered names will be converted to lower case and some special " 1574 "characters(' - #) will be changed to underscores." ),
1578 layerOptions.insert( QStringLiteral(
"SPATIAL_INDEX" ),
new HiddenOption(
1579 QStringLiteral(
"NO" )
1582 layerOptions.insert( QStringLiteral(
"COMPRESS_GEOM" ),
new HiddenOption(
1583 QStringLiteral(
"NO" )
1586 layerOptions.insert( QStringLiteral(
"SRID" ),
new HiddenOption(
1590 layerOptions.insert( QStringLiteral(
"COMPRESS_COLUMNS" ),
new StringOption(
1591 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that " 1592 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial " 1593 "for databases that have big string blobs. However, use with care, since " 1594 "the value of such columns will be seen as compressed binary content with " 1595 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, " 1596 "modifying or querying compressed columns, compression/decompression is " 1597 "done transparently. However, such columns cannot be (easily) queried with " 1598 "an attribute filter or WHERE clause. Note: in table definition, such columns " 1599 "have the 'VARCHAR_deflate' declaration type." ),
1603 driverMetadata.insert( QStringLiteral(
"SQLite" ),
1605 QStringLiteral(
"SQLite" ),
1606 QObject::tr(
"SQLite" ),
1607 QStringLiteral(
"*.sqlite" ),
1608 QStringLiteral(
"sqlite" ),
1611 QStringLiteral(
"UTF-8" )
1616 datasetOptions.clear();
1617 layerOptions.clear();
1619 datasetOptions.insert( QStringLiteral(
"METADATA" ),
new BoolOption(
1620 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys " 1621 "tables in a new database. By default these metadata tables are created " 1622 "when a new database is created." ),
1626 datasetOptions.insert( QStringLiteral(
"SPATIALITE" ),
new HiddenOption(
1627 QStringLiteral(
"YES" )
1630 datasetOptions.insert( QStringLiteral(
"INIT_WITH_EPSG" ),
new BoolOption(
1631 QObject::tr(
"Insert the content of the EPSG CSV files into the spatial_ref_sys table. " 1632 "Set to NO for regular SQLite databases." ),
1636 layerOptions.insert( QStringLiteral(
"FORMAT" ),
new HiddenOption(
1637 QStringLiteral(
"SPATIALITE" )
1640 layerOptions.insert( QStringLiteral(
"LAUNDER" ),
new BoolOption(
1641 QObject::tr(
"Controls whether layer and field names will be laundered for easier use " 1642 "in SQLite. Laundered names will be converted to lower case and some special " 1643 "characters(' - #) will be changed to underscores." ),
1647 layerOptions.insert( QStringLiteral(
"SPATIAL_INDEX" ),
new BoolOption(
1648 QObject::tr(
"If the database is of the SpatiaLite flavor, and if OGR is linked " 1649 "against libspatialite, this option can be used to control if a spatial " 1650 "index must be created." ),
1654 layerOptions.insert( QStringLiteral(
"COMPRESS_GEOM" ),
new BoolOption(
1655 QObject::tr(
"If the format of the geometry BLOB is of the SpatiaLite flavor, " 1656 "this option can be used to control if the compressed format for " 1657 "geometries (LINESTRINGs, POLYGONs) must be used." ),
1661 layerOptions.insert( QStringLiteral(
"SRID" ),
new StringOption(
1662 QObject::tr(
"Used to force the SRID number of the SRS associated with the layer. " 1663 "When this option isn't specified and that a SRS is associated with the " 1664 "layer, a search is made in the spatial_ref_sys to find a match for the " 1665 "SRS, and, if there is no match, a new entry is inserted for the SRS in " 1666 "the spatial_ref_sys table. When the SRID option is specified, this " 1667 "search (and the eventual insertion of a new entry) will not be done: " 1668 "the specified SRID is used as such." ),
1672 layerOptions.insert( QStringLiteral(
"COMPRESS_COLUMNS" ),
new StringOption(
1673 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that " 1674 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial " 1675 "for databases that have big string blobs. However, use with care, since " 1676 "the value of such columns will be seen as compressed binary content with " 1677 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, " 1678 "modifying or queryings compressed columns, compression/decompression is " 1679 "done transparently. However, such columns cannot be (easily) queried with " 1680 "an attribute filter or WHERE clause. Note: in table definition, such columns " 1681 "have the 'VARCHAR_deflate' declaration type." ),
1685 driverMetadata.insert( QStringLiteral(
"SpatiaLite" ),
1687 QStringLiteral(
"SpatiaLite" ),
1688 QObject::tr(
"SpatiaLite" ),
1689 QStringLiteral(
"*.sqlite" ),
1690 QStringLiteral(
"sqlite" ),
1693 QStringLiteral(
"UTF-8" )
1697 datasetOptions.clear();
1698 layerOptions.clear();
1700 datasetOptions.insert( QStringLiteral(
"HEADER" ),
new StringOption(
1701 QObject::tr(
"Override the header file used - in place of header.dxf." ),
1705 datasetOptions.insert( QStringLiteral(
"TRAILER" ),
new StringOption(
1706 QObject::tr(
"Override the trailer file used - in place of trailer.dxf." ),
1710 driverMetadata.insert( QStringLiteral(
"DXF" ),
1712 QStringLiteral(
"AutoCAD DXF" ),
1713 QObject::tr(
"AutoCAD DXF" ),
1714 QStringLiteral(
"*.dxf" ),
1715 QStringLiteral(
"dxf" ),
1722 datasetOptions.clear();
1723 layerOptions.clear();
1725 datasetOptions.insert( QStringLiteral(
"EXTENSION" ),
new SetOption(
1726 QObject::tr(
"Indicates the GeoConcept export file extension. " 1727 "TXT was used by earlier releases of GeoConcept. GXT is currently used." ),
1729 << QStringLiteral(
"GXT" )
1730 << QStringLiteral(
"TXT" ),
1731 QStringLiteral(
"GXT" )
1734 datasetOptions.insert( QStringLiteral(
"CONFIG" ),
new StringOption(
1735 QObject::tr(
"Path to the GCT: the GCT file describes the GeoConcept types definitions: " 1736 "In this file, every line must start with //# followed by a keyword. " 1737 "Lines starting with // are comments." ),
1741 datasetOptions.insert( QStringLiteral(
"FEATURETYPE" ),
new StringOption(
1742 QObject::tr(
"Defines the feature to be created. The TYPE corresponds to one of the Name " 1743 "found in the GCT file for a type section. The SUBTYPE corresponds to one of " 1744 "the Name found in the GCT file for a sub-type section within the previous " 1749 driverMetadata.insert( QStringLiteral(
"Geoconcept" ),
1751 QStringLiteral(
"Geoconcept" ),
1752 QObject::tr(
"Geoconcept" ),
1753 QStringLiteral(
"*.gxt *.txt" ),
1754 QStringLiteral(
"gxt" ),
1761 datasetOptions.clear();
1762 layerOptions.clear();
1764 layerOptions.insert( QStringLiteral(
"FEATURE_DATASET" ),
new StringOption(
1765 QObject::tr(
"When this option is set, the new layer will be created inside the named " 1766 "FeatureDataset folder. If the folder does not already exist, it will be created." ),
1770 layerOptions.insert( QStringLiteral(
"GEOMETRY_NAME" ),
new StringOption(
1771 QObject::tr(
"Set name of geometry column in new layer. Defaults to 'SHAPE'." ),
1772 QStringLiteral(
"SHAPE" )
1775 layerOptions.insert( QStringLiteral(
"FID" ),
new StringOption(
1776 QObject::tr(
"Name of the OID column to create. Defaults to 'OBJECTID'." ),
1777 QStringLiteral(
"OBJECTID" )
1780 driverMetadata.insert( QStringLiteral(
"FileGDB" ),
1782 QStringLiteral(
"ESRI FileGDB" ),
1783 QObject::tr(
"ESRI FileGDB" ),
1784 QStringLiteral(
"*.gdb" ),
1785 QStringLiteral(
"gdb" ),
1788 QStringLiteral(
"UTF-8" )
1793 datasetOptions.clear();
1794 layerOptions.clear();
1796 layerOptions.insert( QStringLiteral(
"OGR_XLSX_FIELD_TYPES" ),
new SetOption(
1797 QObject::tr(
"By default, the driver will try to detect the data type of fields. If set " 1798 "to STRING, all fields will be of String type." ),
1800 << QStringLiteral(
"AUTO" )
1801 << QStringLiteral(
"STRING" ),
1802 QStringLiteral(
"AUTO" ),
1806 layerOptions.insert( QStringLiteral(
"OGR_XLSX_HEADERS" ),
new SetOption(
1807 QObject::tr(
"By default, the driver will read the first lines of each sheet to detect " 1808 "if the first line might be the name of columns. If set to FORCE, the driver " 1809 "will consider the first line as the header line. If set to " 1810 "DISABLE, it will be considered as the first feature. Otherwise " 1811 "auto-detection will occur." ),
1813 << QStringLiteral(
"FORCE" )
1814 << QStringLiteral(
"DISABLE" )
1815 << QStringLiteral(
"AUTO" ),
1816 QStringLiteral(
"AUTO" ),
1820 driverMetadata.insert( QStringLiteral(
"XLSX" ),
1822 QStringLiteral(
"MS Office Open XML spreadsheet" ),
1823 QObject::tr(
"MS Office Open XML spreadsheet" ),
1824 QStringLiteral(
"*.xlsx" ),
1825 QStringLiteral(
"xlsx" ),
1828 QStringLiteral(
"UTF-8" )
1833 datasetOptions.clear();
1834 layerOptions.clear();
1836 layerOptions.insert( QStringLiteral(
"OGR_ODS_FIELD_TYPES" ),
new SetOption(
1837 QObject::tr(
"By default, the driver will try to detect the data type of fields. If set " 1838 "to STRING, all fields will be of String type." ),
1840 << QStringLiteral(
"AUTO" )
1841 << QStringLiteral(
"STRING" ),
1842 QStringLiteral(
"AUTO" ),
1846 layerOptions.insert( QStringLiteral(
"OGR_ODS_HEADERS" ),
new SetOption(
1847 QObject::tr(
"By default, the driver will read the first lines of each sheet to detect " 1848 "if the first line might be the name of columns. If set to FORCE, the driver " 1849 "will consider the first line as the header line. If set to " 1850 "DISABLE, it will be considered as the first feature. Otherwise " 1851 "auto-detection will occur." ),
1853 << QStringLiteral(
"FORCE" )
1854 << QStringLiteral(
"DISABLE" )
1855 << QStringLiteral(
"AUTO" ),
1856 QStringLiteral(
"AUTO" ),
1860 driverMetadata.insert( QStringLiteral(
"ODS" ),
1862 QStringLiteral(
"Open Document Spreadsheet" ),
1863 QObject::tr(
"Open Document Spreadsheet" ),
1864 QStringLiteral(
"*.ods" ),
1865 QStringLiteral(
"ods" ),
1868 QStringLiteral(
"UTF-8" )
1877 static const QMap<QString, MetaData> sDriverMetadata = initMetaData();
1879 QMap<QString, MetaData>::ConstIterator it = sDriverMetadata.constBegin();
1881 for ( ; it != sDriverMetadata.constEnd(); ++it )
1883 if ( it.key().startsWith( driverName ) || it.value().longName.startsWith( driverName ) )
1885 driverMetadata = it.value();
1898 return QStringList();
1907 return QStringList();
1914 OGRwkbGeometryType ogrType =
static_cast<OGRwkbGeometryType
>( type );
1940 QgsFeatureList::iterator fIt = features.begin();
1942 for ( ; fIt != features.end(); ++fIt )
1962 QString styleString;
1963 QString currentStyle;
1965 QgsSymbolList::const_iterator symbolIt = symbols.constBegin();
1966 for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
1968 int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
1969 for (
int i = 0; i < nSymbolLayers; ++i )
1972 QMap< QgsSymbolLayer *, QString >::const_iterator it =
mSymbolLayerTable.find( ( *symbolIt )->symbolLayer( i ) );
1978 double mmsf = mmScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
1979 double musf = mapUnitScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), outputUnit );
1981 currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
1985 if ( symbolIt != symbols.constBegin() || i != 0 )
1987 styleString.append(
';' );
1989 styleString.append( currentStyle );
1993 OGR_F_SetStyleString( poFeature.get(), currentStyle.toLocal8Bit().constData() );
1994 if ( !writeFeature(
mLayer, poFeature.get() ) )
2001 OGR_F_SetStyleString( poFeature.get(), styleString.toLocal8Bit().constData() );
2006 if ( !writeFeature(
mLayer, poFeature.get() ) )
2023 if ( fid > std::numeric_limits<int>::max() )
2025 QgsDebugMsg( QString(
"feature id %1 too large." ).arg( fid ) );
2026 OGRErr err = OGR_F_SetFID( poFeature.get(),
static_cast<long>( fid ) );
2027 if ( err != OGRERR_NONE )
2029 QgsDebugMsg( QString(
"Failed to set feature id to %1: %2 (OGR error: %3)" )
2030 .arg( feature.
id() )
2031 .arg( err ).arg( CPLGetLastErrorMsg() )
2039 int fldIdx = it.key();
2040 int ogrField = it.value();
2042 QVariant attrValue = feature.
attribute( fldIdx );
2044 if ( !attrValue.isValid() || attrValue.isNull() )
2053 #ifdef OGRNullMarker 2054 OGR_F_SetFieldNull( poFeature.get(), ogrField );
2064 switch ( attrValue.type() )
2067 case QVariant::UInt:
2068 OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
2070 case QVariant::LongLong:
2071 case QVariant::ULongLong:
2072 OGR_F_SetFieldInteger64( poFeature.get(), ogrField, attrValue.toLongLong() );
2074 case QVariant::Bool:
2075 OGR_F_SetFieldInteger( poFeature.get(), ogrField, attrValue.toInt() );
2077 case QVariant::String:
2078 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toString() ).constData() );
2080 case QVariant::Double:
2081 OGR_F_SetFieldDouble( poFeature.get(), ogrField, attrValue.toDouble() );
2083 case QVariant::Date:
2084 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2085 attrValue.toDate().year(),
2086 attrValue.toDate().month(),
2087 attrValue.toDate().day(),
2090 case QVariant::DateTime:
2093 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toDateTime().toString( QStringLiteral(
"yyyy/MM/dd hh:mm:ss.zzz" ) ) ).constData() );
2097 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2098 attrValue.toDateTime().date().year(),
2099 attrValue.toDateTime().date().month(),
2100 attrValue.toDateTime().date().day(),
2101 attrValue.toDateTime().time().hour(),
2102 attrValue.toDateTime().time().minute(),
2103 attrValue.toDateTime().time().second(),
2107 case QVariant::Time:
2110 OGR_F_SetFieldString( poFeature.get(), ogrField,
mCodec->fromUnicode( attrValue.toString() ).constData() );
2114 OGR_F_SetFieldDateTime( poFeature.get(), ogrField,
2116 attrValue.toTime().hour(),
2117 attrValue.toTime().minute(),
2118 attrValue.toTime().second(),
2122 case QVariant::Invalid:
2125 mErrorMessage = QObject::tr(
"Invalid variant type for field %1[%2]: received %3 with type %4" )
2128 .arg( attrValue.typeName(),
2129 attrValue.toString() );
2152 OGRGeometryH mGeom2 =
nullptr;
2185 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2186 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2192 QByteArray wkb( geom.
asWkb() );
2193 OGRErr err = OGR_G_ImportFromWkb( mGeom2, reinterpret_cast<unsigned char *>( const_cast<char *>( wkb.constData() ) ), wkb.length() );
2194 if ( err != OGRERR_NONE )
2196 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2197 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2204 OGR_F_SetGeometryDirectly( poFeature.get(), mGeom2 );
2208 QByteArray wkb( geom.
asWkb() );
2210 OGRErr err = OGR_G_ImportFromWkb( ogrGeom, reinterpret_cast<unsigned char *>( const_cast<char *>( wkb.constData() ) ), wkb.length() );
2211 if ( err != OGRERR_NONE )
2213 mErrorMessage = QObject::tr(
"Feature geometry not imported (OGR error: %1)" )
2214 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2221 OGR_F_SetGeometryDirectly( poFeature.get(), ogrGeom );
2236 for (
int i = 0; i < attributes.size(); i++ )
2238 if ( omap.find( i ) != omap.end() )
2243 bool QgsVectorFileWriter::writeFeature( OGRLayerH layer, OGRFeatureH feature )
2245 if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
2247 mErrorMessage = QObject::tr(
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
2257 if ( mUsingTransaction )
2259 if ( OGRERR_NONE != OGR_L_CommitTransaction(
mLayer ) )
2261 QgsDebugMsg(
"Error while committing transaction on OGRLayer." );
2269 OSRDestroySpatialReference(
mOgrRef );
2275 const QString &fileName,
2276 const QString &fileEncoding,
2278 const QString &driverName,
2281 const QStringList &datasourceOptions,
2282 const QStringList &layerOptions,
2283 bool skipAttributeCreation,
2284 QString *newFilename,
2295 if ( destCRS.
isValid() && layer )
2303 errorMessage, datasourceOptions, layerOptions, skipAttributeCreation,
2304 newFilename, symbologyExport, symbologyScale, filterExtent,
2305 overrideGeometryType, forceMulti, includeZ, attributes,
2306 fieldValueConverter );
2311 const QString &fileName,
2312 const QString &fileEncoding,
2314 const QString &driverName,
2317 const QStringList &datasourceOptions,
2318 const QStringList &layerOptions,
2319 bool skipAttributeCreation,
2320 QString *newFilename,
2352 : driverName( QStringLiteral(
"GPKG" ) )
2368 details.sourceCrs = layer->
crs();
2369 details.sourceWkbType = layer->
wkbType();
2370 details.sourceFields = layer->
fields();
2378 if ( details.storageType == QLatin1String(
"ESRI Shapefile" ) )
2386 details.geometryTypeScanIterator = layer->
getFeatures( req );
2390 details.renderContext.setExpressionContext( details.expressionContext );
2391 details.renderContext.setRendererScale( options.
symbologyScale );
2393 details.shallTransform =
false;
2398 details.shallTransform =
true;
2403 details.outputCrs = details.sourceCrs;
2406 details.destWkbType = details.sourceWkbType;
2420 details.attributes.clear();
2421 else if ( details.attributes.isEmpty() )
2423 const QgsAttributeList allAttributes = details.sourceFields.allAttributesList();
2424 for (
int idx : allAttributes )
2426 QgsField fld = details.sourceFields.at( idx );
2427 if ( details.providerType == QLatin1String(
"oracle" ) && fld.
typeName().contains( QLatin1String(
"SDO_GEOMETRY" ) ) )
2429 details.attributes.append( idx );
2433 if ( !details.attributes.isEmpty() )
2435 for (
int attrIdx : qgis::as_const( details.attributes ) )
2437 details.outputFields.append( details.sourceFields.at( attrIdx ) );
2443 if ( details.providerType == QLatin1String(
"spatialite" ) )
2445 for (
int i = 0; i < details.outputFields.size(); i++ )
2447 if ( details.outputFields.at( i ).type() == QVariant::LongLong )
2451 if ( std::max( std::llabs( min.toLongLong() ), std::llabs( max.toLongLong() ) ) < INT_MAX )
2453 details.outputFields[i].setType( QVariant::Int );
2461 addRendererAttributes( details.renderer.get(), details.renderContext, details.sourceFields, details.attributes );
2471 bool useFilterRect =
true;
2472 if ( details.shallTransform )
2481 useFilterRect =
false;
2484 if ( useFilterRect )
2486 req.setFilterRect( filterRect );
2490 details.filterRectEngine->prepareGeometry();
2492 details.sourceFeatureIterator = layer->
getFeatures( req );
2502 int lastProgressReport = 0;
2503 long total = details.featureCount;
2505 if ( details.providerType == QLatin1String(
"ogr" ) && !details.dataSourceUri.isEmpty() )
2507 QStringList theURIParts = details.dataSourceUri.split(
'|' );
2508 QString srcFileName = theURIParts[0];
2510 if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
2513 *errorMessage = QObject::tr(
"Cannot overwrite a OGR layer in place" );
2532 int newProgress = ( 5.0 * scanned ) / total;
2533 if ( newProgress != lastProgressReport )
2535 lastProgressReport = newProgress;
2550 std::unique_ptr< QgsVectorFileWriter > writer =
2551 qgis::make_unique< QgsVectorFileWriter >( fileName,
2552 options.
fileEncoding, details.outputFields, destWkbType,
2573 *errorMessage = writer->errorMessage();
2579 errorMessage->clear();
2601 int n = 0, errors = 0;
2610 writer->startRender( details.renderer.get(), details.sourceFields );
2612 writer->resetMap( details.attributes );
2614 writer->mFields = details.sourceFields;
2618 int initialProgress = lastProgressReport;
2619 while ( details.sourceFeatureIterator.nextFeature( fet ) )
2630 int newProgress = initialProgress + ( ( 100.0 - initialProgress ) * saved ) / total;
2631 if ( newProgress < 100 && newProgress != lastProgressReport )
2633 lastProgressReport = newProgress;
2638 if ( details.shallTransform )
2651 QString msg = QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
2652 .arg( fet.
id() ).arg( e.
what() );
2655 *errorMessage = msg;
2669 if ( !writer->addFeatureWithStyle( fet, writer->mRenderer.get(), mapUnits ) )
2672 if ( err !=
NoError && errorMessage )
2674 if ( errorMessage->isEmpty() )
2676 *errorMessage = QObject::tr(
"Feature write errors:" );
2678 *errorMessage +=
'\n' + writer->errorMessage();
2682 if ( errors > 1000 )
2686 *errorMessage += QObject::tr(
"Stopping after %1 errors" ).arg( errors );
2696 writer->stopRender();
2698 if ( errors > 0 && errorMessage && n > 0 )
2700 *errorMessage += QObject::tr(
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
2708 const QString &fileName,
2710 QString *newFilename,
2713 QgsVectorFileWriter::PreparedWriterDetails details;
2714 WriterError err = prepareWriteAsVectorFormat( layer, options, details );
2724 QFileInfo fi( fileName );
2725 QDir dir = fi.dir();
2728 const char *suffixes[] = {
".shp",
".shx",
".dbf",
".prj",
".qix",
".qpj" };
2729 for ( std::size_t i = 0; i <
sizeof( suffixes ) /
sizeof( *suffixes ); i++ )
2731 filter << fi.completeBaseName() + suffixes[i];
2735 Q_FOREACH (
const QString &file, dir.entryList( filter ) )
2737 QFile
f( dir.canonicalPath() +
'/' + file );
2740 QgsDebugMsg( QString(
"Removing file %1 failed: %2" ).arg( file,
f.errorString() ) );
2756 QList< FilterFormatDetails > results;
2759 int const drvCount = OGRGetDriverCount();
2764 for (
int i = 0; i < drvCount; ++i )
2766 OGRSFDriverH drv = OGRGetDriver( i );
2769 QString drvName = OGR_Dr_GetName( drv );
2771 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,3,0) 2772 GDALDriverH gdalDriver = GDALGetDriverByName( drvName.toLocal8Bit().constData() );
2776 driverMetadata = GDALGetMetadata( gdalDriver,
nullptr );
2779 bool nonSpatialFormat = CSLFetchBoolean( driverMetadata, GDAL_DCAP_NONSPATIAL,
false );
2781 bool nonSpatialFormat = ( drvName == QLatin1String(
"ODS" ) || drvName == QLatin1String(
"XLSX" ) || drvName == QLatin1String(
"XLS" ) );
2784 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2789 if ( nonSpatialFormat )
2794 if ( filterString.isEmpty() )
2803 if ( drvName == QLatin1String(
"ESRI Shapefile" ) )
2805 shapeFormat = details;
2808 else if ( drvName == QLatin1String(
"GPKG" ) )
2810 gpkgFormat = details;
2829 results.insert( 0, shapeFormat );
2833 results.insert( 0, gpkgFormat );
2843 QStringList extensions;
2845 QRegularExpression rx( QStringLiteral(
"\\*\\.([a-zA-Z0-9]*)" ) );
2849 QString ext = format.filterString;
2850 QRegularExpressionMatch match = rx.match( ext );
2851 if ( !match.hasMatch() )
2854 QString matched = match.captured( 1 );
2855 extensions << matched;
2862 QList< QgsVectorFileWriter::DriverDetails > results;
2865 const int drvCount = OGRGetDriverCount();
2867 QStringList writableDrivers;
2868 for (
int i = 0; i < drvCount; ++i )
2870 OGRSFDriverH drv = OGRGetDriver( i );
2873 QString drvName = OGR_Dr_GetName( drv );
2879 if ( drvName == QLatin1String(
"ODS" ) || drvName == QLatin1String(
"XLSX" ) || drvName == QLatin1String(
"XLS" ) )
2883 if ( drvName == QLatin1String(
"ESRI Shapefile" ) )
2885 writableDrivers << QStringLiteral(
"DBF file" );
2887 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2890 if ( drvName == QLatin1String(
"MapInfo File" ) )
2892 writableDrivers << QStringLiteral(
"MapInfo MIF" );
2894 else if ( drvName == QLatin1String(
"SQLite" ) )
2901 QString option = QStringLiteral(
"SPATIALITE=YES" );
2902 char *options[2] = { CPLStrdup( option.toLocal8Bit().constData() ),
nullptr };
2903 OGRSFDriverH poDriver;
2905 poDriver = OGRGetDriverByName( drvName.toLocal8Bit().constData() );
2908 gdal::ogr_datasource_unique_ptr ds( OGR_Dr_CreateDataSource( poDriver, QStringLiteral(
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData(), options ) );
2911 writableDrivers << QStringLiteral(
"SpatiaLite" );
2912 OGR_Dr_DeleteDataSource( poDriver, QStringLiteral(
"/vsimem/spatialitetest.sqlite" ).toUtf8().constData() );
2915 CPLFree( options[0] );
2917 writableDrivers << drvName;
2921 std::sort( writableDrivers.begin(), writableDrivers.end() );
2925 if ( writableDrivers.contains( QStringLiteral(
"ESRI Shapefile" ) ) )
2927 writableDrivers.removeAll( QStringLiteral(
"ESRI Shapefile" ) );
2928 writableDrivers.insert( 0, QStringLiteral(
"ESRI Shapefile" ) );
2930 if ( writableDrivers.contains( QStringLiteral(
"GPKG" ) ) )
2933 writableDrivers.removeAll( QStringLiteral(
"GPKG" ) );
2934 writableDrivers.insert( 0, QStringLiteral(
"GPKG" ) );
2938 for (
const QString &drvName : qgis::as_const( writableDrivers ) )
2954 QString ext = extension.trimmed();
2955 if ( ext.isEmpty() )
2958 if ( ext.startsWith(
'.' ) )
2962 int const drvCount = GDALGetDriverCount();
2964 for (
int i = 0; i < drvCount; ++i )
2966 GDALDriverH drv = GDALGetDriver( i );
2970 if ( CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE,
false ) && CSLFetchBoolean( driverMetadata, GDAL_DCAP_VECTOR,
false ) )
2972 QString drvName = GDALGetDriverShortName( drv );
2973 QStringList driverExtensions = QString( GDALGetMetadataItem( drv, GDAL_DMD_EXTENSIONS,
nullptr ) ).split(
' ' );
2975 Q_FOREACH (
const QString &driver, driverExtensions )
2977 if ( driver.compare( ext, Qt::CaseInsensitive ) == 0 )
2988 QString filterString;
2992 if ( !filterString.isEmpty() )
2993 filterString += QLatin1String(
";;" );
2995 filterString += details.filterString;
2997 return filterString;
3006 return QStringLiteral(
"%1 (%2 %3)" ).arg( metadata.
trLongName,
3007 metadata.
glob.toLower(),
3008 metadata.
glob.toUpper() );
3013 if ( codecName == QLatin1String(
"System" ) )
3014 return QStringLiteral(
"LDID/0" );
3016 QRegExp re = QRegExp( QString(
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
3017 if ( re.exactMatch( codecName ) )
3019 QString c = re.cap( 2 ).remove(
'-' );
3021 c.toInt( &isNumber );
3049 OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
3050 OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
3053 int nTotalLevels = 0;
3055 QgsSymbolList::iterator symbolIt = symbolList.begin();
3056 for ( ; symbolIt != symbolList.end(); ++symbolIt )
3058 double mmsf = mmScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
3059 double musf = mapUnitScaleFactor(
mSymbologyScale, ( *symbolIt )->outputUnit(), mapUnits );
3061 int nLevels = ( *symbolIt )->symbolLayerCount();
3062 for (
int i = 0; i < nLevels; ++i )
3064 mSymbolLayerTable.insert( ( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
3065 OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
3066 ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
3070 OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
3076 if ( !details.renderer )
3079 mRenderContext.expressionContext() = details.expressionContext;
3081 QHash< QgsSymbol *, QList<QgsFeature> > features;
3090 startRender( details.renderer.get(), details.sourceFields );
3101 if ( fet.hasGeometry() )
3105 fet.setGeometry( g );
3110 QString msg = QObject::tr(
"Failed to transform, writing stopped. (Exception: %1)" )
3114 *errorMessage = msg;
3119 mRenderContext.expressionContext().setFeature( fet );
3121 featureSymbol = mRenderer->symbolForFeature( fet, mRenderContext );
3122 if ( !featureSymbol )
3127 QHash< QgsSymbol *, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
3128 if ( it == features.end() )
3130 it = features.insert( featureSymbol, QList<QgsFeature>() );
3132 it.value().append( fet );
3137 QgsSymbolList symbols = mRenderer->symbols( mRenderContext );
3138 for (
int i = 0; i < symbols.count(); i++ )
3144 if ( level < 0 || level >= 1000 )
3147 while ( level >= levels.count() )
3149 levels[level].append( item );
3154 int nTotalFeatures = 0;
3157 for (
int l = 0; l < levels.count(); l++ )
3160 for (
int i = 0; i < level.count(); i++ )
3163 QHash< QgsSymbol *, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
3164 if ( levelIt == features.end() )
3170 double mmsf = mmScaleFactor(
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
3171 double musf = mapUnitScaleFactor(
mSymbologyScale, levelIt.key()->outputUnit(), mapUnits );
3173 int llayer = item.
layer();
3174 QList<QgsFeature> &featureList = levelIt.value();
3175 QList<QgsFeature>::iterator featureIt = featureList.begin();
3176 for ( ; featureIt != featureList.end(); ++featureIt )
3186 QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
3187 if ( !styleString.isEmpty() )
3189 OGR_F_SetStyleString( ogrFeature.get(), styleString.toLocal8Bit().constData() );
3190 if ( !writeFeature(
mLayer, ogrFeature.get() ) )
3201 if ( nErrors > 0 && errorMessage )
3203 *errorMessage += QObject::tr(
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
3220 return 1000 / scale;
3237 return scale / 1000;
3245 mRenderer = createSymbologyRenderer( sourceRenderer );
3251 mRenderer->startRender( mRenderContext, fields );
3254 void QgsVectorFileWriter::stopRender()
3261 mRenderer->stopRender( mRenderContext );
3264 std::unique_ptr<QgsFeatureRenderer> QgsVectorFileWriter::createSymbologyRenderer(
QgsFeatureRenderer *sourceRenderer )
const 3270 if ( !sourceRenderer )
3275 return std::unique_ptr< QgsFeatureRenderer >( sourceRenderer->
clone() );
3282 const QSet<QString> rendererAttributes = renderer->
usedAttributes( context );
3283 for (
const QString &attr : rendererAttributes )
3288 attList.append( index );
3294 QStringList QgsVectorFileWriter::concatenateOptions(
const QMap<QString, QgsVectorFileWriter::Option *> &options )
3297 QMap<QString, QgsVectorFileWriter::Option *>::ConstIterator it;
3299 for ( it = options.constBegin(); it != options.constEnd(); ++it )
3302 switch ( option->
type )
3309 list.append( QStringLiteral(
"%1=%2" ).arg( it.key() ).arg( opt->
defaultValue ) );
3319 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
3329 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
defaultValue ) );
3338 list.append( QStringLiteral(
"%1=%2" ).arg( it.key(), opt->
mValue ) );
3349 OGRSFDriverH hDriver =
nullptr;
3353 QString drvName = OGR_Dr_GetName( hDriver );
3354 QgsVectorFileWriter::EditionCapabilities caps =
nullptr;
3355 if ( OGR_DS_TestCapability( hDS.get(), ODsCCreateLayer ) )
3360 if ( !( drvName == QLatin1String(
"ESRI Shapefile" ) && QFile::exists( datasetName ) ) )
3363 if ( OGR_DS_TestCapability( hDS.get(), ODsCDeleteLayer ) )
3367 int layer_count = OGR_DS_GetLayerCount( hDS.get() );
3370 OGRLayerH hLayer = OGR_DS_GetLayer( hDS.get(), 0 );
3373 if ( OGR_L_TestCapability( hLayer, OLCSequentialWrite ) )
3376 if ( OGR_L_TestCapability( hLayer, OLCCreateField ) )
3387 const QString &layerNameIn )
3389 OGRSFDriverH hDriver =
nullptr;
3395 if ( layerName.isEmpty() )
3396 layerName = QFileInfo( datasetName ).baseName();
3398 return OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
3407 OGRSFDriverH hDriver =
nullptr;
3411 OGRLayerH hLayer = OGR_DS_GetLayerByName( hDS.get(), layerName.toUtf8().constData() );
3417 OGRFeatureDefnH defn = OGR_L_GetLayerDefn( hLayer );
3418 Q_FOREACH (
int idx, attributes )
3421 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
Return number of items.
Flag to indicate that new features can be added to an existing layer.
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
Set to true to force creation of multi* geometries.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
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
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
Return number of items.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning)
add a message to the instance (and create it if necessary)
static QgsVectorFileWriter::EditionCapabilities editionCapabilities(const QString &datasetName)
Return 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
Get 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.
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
Return 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
virtual QgsSymbolList symbolsForFeature(QgsFeature &feat, QgsRenderContext &context)
Returns list of symbols used for rendering the feature.
const QgsFeatureIds & selectedFeatureIds() const
Return reference to identifiers of selected features.
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.
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...
virtual QString dataSourceUri(bool expandAuthConfig=false) const
Get 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)
Get 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.
Create or overwrite layer.
QgsCoordinateReferenceSystem crs() const
Returns the layer's spatial reference system.
ActionOnExistingFile
Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteL...
QgsFeatureRenderer * renderer()
Return 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.
std::unique_ptr< void, OGRFldDeleter > ogr_field_def_unique_ptr
Scoped OGR field definition.
double symbologyScale() const
Returns the reference scale for output.
OperationResult transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection direction=QgsCoordinateTransform::ForwardTransform, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
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())
QgsExpressionContext & expressionContext()
Gets the expression context.
DistanceUnit
Units of distance.
QString errorMessage()
Retrieves error message.
#define Q_NOWARN_DEPRECATED_POP
virtual QgsSymbolList symbols(QgsRenderContext &context)
Returns list of symbols used by the renderer.
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.
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)
Set 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.
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.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), const Section section=NoSection) const
Returns the value for setting key.
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.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
std::unique_ptr< void, OGRDataSourceDeleter > ogr_datasource_unique_ptr
Scoped OGR data source.
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
Set to true to include z dimension in output. This option is only valid if overrideGeometryType is se...
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
Return 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)
Return a possibly modified field definition.
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)
std::unique_ptr< void, OGRFeatureDeleter > ogr_feature_unique_ptr
Scoped OGR feature.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.