36 #include <QTextStream>
44 #include <ogr_srs_api.h>
45 #include <cpl_error.h>
48 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
49 #define TO8(x) (x).toUtf8().constData()
50 #define TO8F(x) (x).toUtf8().constData()
52 #define TO8(x) (x).toLocal8Bit().constData()
53 #define TO8F(x) QFile::encodeName( x ).constData()
58 const QString &theVectorFileName,
59 const QString &theFileEncoding,
63 const QString& driverName,
64 const QStringList &datasourceOptions,
65 const QStringList &layerOptions,
74 , mWkbType( geometryType )
75 , mSymbologyExport( symbologyExport )
76 , mSymbologyScaleDenominator( 1.0 )
78 QString vectorFileName = theVectorFileName;
79 QString fileEncoding = theFileEncoding;
80 QStringList layOptions = layerOptions;
81 QStringList dsOptions = datasourceOptions;
83 if ( theVectorFileName.isEmpty() )
90 QString ogrDriverName;
91 if ( driverName ==
"MapInfo MIF" )
93 ogrDriverName =
"MapInfo File";
95 else if ( driverName ==
"SpatiaLite" )
97 ogrDriverName =
"SQLite";
98 if ( !dsOptions.contains(
"SPATIALITE=YES" ) )
100 dsOptions.append(
"SPATIALITE=YES" );
103 else if ( driverName ==
"DBF file" )
105 ogrDriverName =
"ESRI Shapefile";
106 if ( !layOptions.contains(
"SHPT=NULL" ) )
108 layOptions.append(
"SHPT=NULL" );
114 ogrDriverName = driverName;
118 OGRSFDriverH poDriver;
121 poDriver = OGRGetDriverByName( ogrDriverName.toLocal8Bit().data() );
127 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
132 if ( ogrDriverName ==
"ESRI Shapefile" )
134 if ( layOptions.join(
"" ).toUpper().indexOf(
"ENCODING=" ) == -1 )
139 if ( driverName ==
"ESRI Shapefile" && !vectorFileName.endsWith(
".shp", Qt::CaseInsensitive ) )
141 vectorFileName +=
".shp";
143 else if ( driverName ==
"DBF file" && !vectorFileName.endsWith(
".dbf", Qt::CaseInsensitive ) )
145 vectorFileName +=
".dbf";
148 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM < 1700
150 QSet<QString> fieldNames;
151 for (
int i = 0; i < fields.
count(); ++i )
153 QString name = fields[i].name().left( 10 );
154 if ( fieldNames.contains( name ) )
156 mErrorMessage =
QObject::tr(
"trimming attribute name '%1' to ten significant characters produces duplicate column name." )
157 .arg( fields[i].name() );
167 else if ( driverName ==
"KML" )
169 if ( !vectorFileName.endsWith(
".kml", Qt::CaseInsensitive ) )
171 vectorFileName +=
".kml";
174 if ( fileEncoding.compare(
"UTF-8", Qt::CaseInsensitive ) != 0 )
177 fileEncoding =
"UTF-8";
180 QFile::remove( vectorFileName );
190 QStringList allExts = exts.split(
" ", QString::SkipEmptyParts );
192 foreach ( QString ext, allExts )
194 if ( vectorFileName.endsWith(
"." + ext, Qt::CaseInsensitive ) )
203 vectorFileName +=
"." + allExts[0];
207 QFile::remove( vectorFileName );
210 char **options = NULL;
211 if ( !dsOptions.isEmpty() )
213 options =
new char *[ dsOptions.size()+1 ];
214 for (
int i = 0; i < dsOptions.size(); i++ )
216 options[i] = CPLStrdup( dsOptions[i].toLocal8Bit().data() );
218 options[ dsOptions.size()] = NULL;
222 mDS = OGR_Dr_CreateDataSource( poDriver,
TO8F( vectorFileName ), options );
226 for (
int i = 0; i < dsOptions.size(); i++ )
227 CPLFree( options[i] );
236 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
243 mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().constData() );
246 QgsDebugMsg(
"error finding QTextCodec for " + fileEncoding );
249 QString enc = settings.value(
"/UI/encoding",
"System" ).toString();
250 mCodec = QTextCodec::codecForName( enc.toLocal8Bit().constData() );
253 QgsDebugMsg(
"error finding QTextCodec for " + enc );
254 mCodec = QTextCodec::codecForLocale();
263 QString srsWkt = srs->
toWkt();
265 ogrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().data() );
269 QString layerName = QFileInfo( vectorFileName ).baseName();
270 OGRwkbGeometryType wkbType =
static_cast<OGRwkbGeometryType
>( geometryType );
272 if ( !layOptions.isEmpty() )
274 options =
new char *[ layOptions.size()+1 ];
275 for (
int i = 0; i < layOptions.size(); i++ )
277 options[i] = CPLStrdup( layOptions[i].toLocal8Bit().data() );
279 options[ layOptions.size()] = NULL;
283 CPLSetConfigOption(
"SHAPE_ENCODING",
"" );
285 mLayer = OGR_DS_CreateLayer(
mDS,
TO8F( layerName ), ogrRef, wkbType, options );
289 for (
int i = 0; i < layOptions.size(); i++ )
290 CPLFree( options[i] );
296 if ( !settings.value(
"/qgis/ignoreShapeEncoding",
true ).toBool() )
298 CPLSetConfigOption(
"SHAPE_ENCODING", 0 );
303 if ( ogrDriverName ==
"ESRI Shapefile" )
305 QString layerName = vectorFileName.left( vectorFileName.indexOf(
".shp", Qt::CaseInsensitive ) );
306 QFile prjFile( layerName +
".qpj" );
307 if ( prjFile.open( QIODevice::WriteOnly ) )
309 QTextStream prjStream( &prjFile );
310 prjStream << srs->
toWkt().toLocal8Bit().data() << endl;
315 QgsDebugMsg(
"Couldn't open file " + layerName +
".qpj" );
319 OSRDestroySpatialReference( ogrRef );
325 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
330 OGRFeatureDefnH defn = OGR_L_GetLayerDefn(
mLayer );
335 QgsDebugMsg(
"creating " + QString::number( fields.
size() ) +
" fields" );
340 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
342 const QgsField& attrField = fields[fldIdx];
344 OGRFieldType ogrType = OFTString;
345 int ogrWidth = attrField.
length();
346 int ogrPrecision = attrField.
precision();
347 switch ( attrField.
type() )
349 case QVariant::LongLong:
351 ogrWidth = ogrWidth > 0 && ogrWidth <= 21 ? ogrWidth : 21;
355 case QVariant::String:
357 if ( ogrWidth <= 0 || ogrWidth > 255 )
362 ogrType = OFTInteger;
363 ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
367 case QVariant::Double:
375 case QVariant::DateTime:
376 ogrType = OFTDateTime;
382 .arg( attrField.
name() );
387 QString name( attrField.
name() );
389 if ( ogrDriverName ==
"SQLite" && name.compare(
"ogc_fid", Qt::CaseInsensitive ) == 0 )
392 for ( i = 0; i < 10; i++ )
394 name = QString(
"ogc_fid%1" ).arg( i );
397 for ( j = 0; j < fields.
size() && name.compare( fields[j].name(), Qt::CaseInsensitive ) != 0; j++ )
400 if ( j == fields.
size() )
415 OGRFieldDefnH fld = OGR_Fld_Create(
mCodec->fromUnicode( name ), ogrType );
418 OGR_Fld_SetWidth( fld, ogrWidth );
421 if ( ogrPrecision >= 0 )
423 OGR_Fld_SetPrecision( fld, ogrPrecision );
428 " type " + QString( QVariant::typeToName( attrField.
type() ) ) +
429 " width " + QString::number( ogrWidth ) +
430 " precision " + QString::number( ogrPrecision ) );
431 if ( OGR_L_CreateField(
mLayer, fld,
true ) != OGRERR_NONE )
435 .arg( attrField.
name() )
436 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
438 OGR_Fld_Destroy( fld );
441 OGR_Fld_Destroy( fld );
443 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
446 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM < 1700
449 int fieldCount = OGR_FD_GetFieldCount( defn );
451 OGRFieldDefnH fdefn = OGR_FD_GetFieldDefn( defn, fieldCount - 1 );
454 const char *fieldName = OGR_Fld_GetNameRef( fdefn );
456 if ( attrField.
name().left( strlen( fieldName ) ) == fieldName )
458 ogrIdx = fieldCount - 1;
463 ogrIdx = OGR_FD_GetFieldCount( defn ) - 1;
470 .arg( attrField.
name() )
471 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
490 *newFilename = vectorFileName;
495 return OGR_G_CreateGeometry(( OGRwkbGeometryType ) wkbType );
498 QMap<QString, QgsVectorFileWriter::MetaData> QgsVectorFileWriter::initMetaData()
502 QMap<QString, Option*> datasetOptions;
503 QMap<QString, Option*> layerOptions;
506 datasetOptions.clear();
507 layerOptions.clear();
509 driverMetadata.insert(
"AVCE00",
511 "Arc/Info ASCII Coverage",
521 datasetOptions.clear();
522 layerOptions.clear();
524 datasetOptions.insert(
"LINEFORMAT",
new SetOption(
526 "systems default line termination conventions. "
527 "This may be overridden here." ),
535 datasetOptions.insert(
"MULTILINE",
new BoolOption(
536 QObject::tr(
"By default, BNA files are created in multi-line format. "
537 "For each record, the first line contains the identifiers and the "
538 "type/number of coordinates to follow. Each following line contains "
539 "a pair of coordinates." ),
543 datasetOptions.insert(
"NB_IDS",
new SetOption(
544 QObject::tr(
"BNA records may contain from 2 to 4 identifiers per record. "
545 "Some software packages only support a precise number of identifiers. "
546 "You can override the default value (2) by a precise value" ),
551 <<
"NB_SOURCE_FIELDS",
555 datasetOptions.insert(
"ELLIPSES_AS_ELLIPSES",
new BoolOption(
556 QObject::tr(
"The BNA writer will try to recognize ellipses and circles when writing a polygon. "
557 "This will only work if the feature has previously been read from a BNA file. "
558 "As some software packages do not support ellipses/circles in BNA data file, "
559 "it may be useful to tell the writer by specifying ELLIPSES_AS_ELLIPSES=NO not "
560 "to export them as such, but keep them as polygons." ),
564 datasetOptions.insert(
"NB_PAIRS_PER_LINE",
new IntOption(
565 QObject::tr(
"Limit the number of coordinate pairs per line in multiline format." ),
569 datasetOptions.insert(
"COORDINATE_PRECISION",
new IntOption(
570 QObject::tr(
"Set the number of decimal for coordinates. Default value is 10." ),
574 driverMetadata.insert(
"BNA",
586 datasetOptions.clear();
587 layerOptions.clear();
589 layerOptions.insert(
"LINEFORMAT",
new SetOption(
590 QObject::tr(
"By default when creating new .csv files they "
591 "are created with the line termination conventions "
592 "of the local platform (CR/LF on Win32 or LF on all other systems). "
593 "This may be overridden through the use of the LINEFORMAT option." ),
601 layerOptions.insert(
"GEOMETRY",
new SetOption(
602 QObject::tr(
"By default, the geometry of a feature written to a .csv file is discarded. "
603 "It is possible to export the geometry in its WKT representation by "
604 "specifying GEOMETRY=AS_WKT. It is also possible to export point geometries "
605 "into their X,Y,Z components by specifying GEOMETRY=AS_XYZ, GEOMETRY=AS_XY "
606 "or GEOMETRY=AS_YX." ),
616 layerOptions.insert(
"CREATE_CSVT",
new BoolOption(
617 QObject::tr(
"Create the associated .csvt file to describe the type of each "
618 "column of the layer and its optional width and precision." ),
622 layerOptions.insert(
"SEPARATOR",
new SetOption(
631 layerOptions.insert(
"WRITE_BOM",
new BoolOption(
632 QObject::tr(
"Write a UTF-8 Byte Order Mark (BOM) at the start of the file." ),
636 driverMetadata.insert(
"CSV",
638 "Comma Separated Value [CSV]",
648 datasetOptions.clear();
649 layerOptions.clear();
651 layerOptions.insert(
"SHPT",
new SetOption(
652 QObject::tr(
"Override the type of shapefile created. "
653 "Can be one of NULL for a simple .dbf file with no .shp file, POINT, "
654 "ARC, POLYGON or MULTIPOINT for 2D, or POINTZ, ARCZ, POLYGONZ or "
655 "MULTIPOINTZ for 3D. Shapefiles with measure values are not supported, "
656 "nor are MULTIPATCH files." ),
670 layerOptions.insert(
"ENCODING",
new SetOption(
671 QObject::tr(
"set the encoding value in the DBF file. "
672 "The default value is LDID/87. It is not clear "
673 "what other values may be appropriate." ),
679 layerOptions.insert(
"RESIZE",
new BoolOption(
680 QObject::tr(
"Set to YES to resize fields to their optimal size." ),
684 driverMetadata.insert(
"ESRI",
696 datasetOptions.clear();
697 layerOptions.clear();
699 driverMetadata.insert(
"DBF File",
711 datasetOptions.clear();
712 layerOptions.clear();
714 driverMetadata.insert(
"FMEObjects Gateway",
716 "FMEObjects Gateway",
726 datasetOptions.clear();
727 layerOptions.clear();
729 layerOptions.insert(
"WRITE_BBOX",
new BoolOption(
730 QObject::tr(
"Set to YES to write a bbox property with the bounding box "
731 "of the geometries at the feature and feature collection level." ),
735 layerOptions.insert(
"COORDINATE_PRECISION",
new IntOption(
736 QObject::tr(
"Maximum number of figures after decimal separator to write in coordinates. "
737 "Default to 15. Truncation will occur to remove trailing zeros." ),
741 driverMetadata.insert(
"GeoJSON",
753 datasetOptions.clear();
754 layerOptions.clear();
756 datasetOptions.insert(
"FORMAT",
new SetOption(
757 QObject::tr(
"whether the document must be in RSS 2.0 or Atom 1.0 format. "
758 "Default value : RSS" ),
765 datasetOptions.insert(
"GEOM_DIALECT",
new SetOption(
766 QObject::tr(
"The encoding of location information. Default value : SIMPLE. "
767 "W3C_GEO only supports point geometries. "
768 "SIMPLE or W3C_GEO only support geometries in geographic WGS84 coordinates." ),
776 datasetOptions.insert(
"USE_EXTENSIONS",
new BoolOption(
777 QObject::tr(
"If defined to YES, extension fields will be written. "
778 "If the field name not found in the base schema matches "
779 "the foo_bar pattern, foo will be considered as the namespace "
780 "of the element, and a <foo:bar> element will be written. "
781 "Otherwise, elements will be written in the <ogr:> namespace." ),
785 datasetOptions.insert(
"WRITE_HEADER_AND_FOOTER",
new BoolOption(
786 QObject::tr(
"If defined to NO, only <entry> or <item> elements will be written. "
787 "The user will have to provide the appropriate header and footer of the document." ),
791 datasetOptions.insert(
"HEADER",
new StringOption(
792 QObject::tr(
"XML content that will be put between the <channel> element and the "
793 "first <item> element for a RSS document, or between the xml tag and "
794 "the first <entry> element for an Atom document. " ),
798 datasetOptions.insert(
"TITLE",
new StringOption(
799 QObject::tr(
"Value put inside the <title> element in the header. "
800 "If not provided, a dummy value will be used as that element is compulsory." ),
804 datasetOptions.insert(
"DESCRIPTION",
new StringOption(
805 QObject::tr(
"Value put inside the <description> element in the header. "
806 "If not provided, a dummy value will be used as that element is compulsory." ),
810 datasetOptions.insert(
"LINK",
new StringOption(
811 QObject::tr(
"Value put inside the <link> element in the header. "
812 "If not provided, a dummy value will be used as that element is compulsory." ),
816 datasetOptions.insert(
"UPDATED",
new StringOption(
817 QObject::tr(
"Value put inside the <updated> element in the header. "
818 "Should be formatted as a XML datetime. "
819 "If not provided, a dummy value will be used as that element is compulsory." ),
823 datasetOptions.insert(
"AUTHOR_NAME",
new StringOption(
824 QObject::tr(
"Value put inside the <author><name> element in the header. "
825 "If not provided, a dummy value will be used as that element is compulsory." ),
829 datasetOptions.insert(
"ID",
new StringOption(
830 QObject::tr(
"Value put inside the <id> element in the header. "
831 "If not provided, a dummy value will be used as that element is compulsory." ),
835 driverMetadata.insert(
"GeoRSS",
847 datasetOptions.clear();
848 layerOptions.clear();
850 datasetOptions.insert(
"XSISCHEMAURI",
new StringOption(
851 QObject::tr(
"If provided, this URI will be inserted as the schema location. "
852 "Note that the schema file isn't actually accessed by OGR, so it "
853 "is up to the user to ensure it will match the schema of the OGR "
854 "produced GML data file." ),
858 datasetOptions.insert(
"XSISCHEMA",
new SetOption(
859 QObject::tr(
"This writes a GML application schema file to a corresponding "
860 ".xsd file (with the same basename). If INTERNAL is used the "
861 "schema is written within the GML file, but this is experimental "
862 "and almost certainly not valid XML. "
863 "OFF disables schema generation (and is implicit if XSISCHEMAURI is used)." ),
871 datasetOptions.insert(
"PREFIX",
new StringOption(
872 QObject::tr(
"This is the prefix for the application target namespace." ),
876 datasetOptions.insert(
"STRIP_PREFIX",
new BoolOption(
877 QObject::tr(
"Can be set to TRUE to avoid writing the prefix of the "
878 "application target namespace in the GML file." ),
882 datasetOptions.insert(
"TARGET_NAMESPACE",
new StringOption(
883 QObject::tr(
"Defaults to 'http://ogr.maptools.org/'. "
884 "This is the application target namespace." ),
885 "http://ogr.maptools.org/"
888 datasetOptions.insert(
"FORMAT",
new SetOption(
889 QObject::tr(
"If not specified, GML2 will be used." ),
898 datasetOptions.insert(
"GML3_LONGSRS",
new BoolOption(
899 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. "
900 "If YES, SRS with EPSG authority will be written with the "
901 "'urn:ogc:def:crs:EPSG::' prefix. In the case, if the SRS is a "
902 "geographic SRS without explicit AXIS order, but that the same "
903 "SRS authority code imported with ImportFromEPSGA() should be "
904 "treated as lat/long, then the function will take care of coordinate "
905 "order swapping. If set to NO, SRS with EPSG authority will be "
906 "written with the 'EPSG:' prefix, even if they are in lat/long order." ),
910 datasetOptions.insert(
"WRITE_FEATURE_BOUNDED_BY",
new BoolOption(
911 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. "
912 "If set to NO, the <gml:boundedBy> element will not be written for "
917 datasetOptions.insert(
"SPACE_INDENTATION",
new BoolOption(
918 QObject::tr(
"Default to YES. If YES, the output will be indented with spaces "
919 "for more readability, but at the expense of file size." ),
924 driverMetadata.insert(
"GML",
926 "Geography Markup Language [GML]",
936 datasetOptions.clear();
937 layerOptions.clear();
939 driverMetadata.insert(
"GMT",
941 "Generic Mapping Tools [GMT]",
951 datasetOptions.clear();
952 layerOptions.clear();
954 layerOptions.insert(
"FORCE_GPX_TRACK",
new BoolOption(
955 QObject::tr(
"By default when writing a layer whose features are of "
956 "type wkbLineString, the GPX driver chooses to write "
957 "them as routes. If FORCE_GPX_TRACK=YES is specified, "
958 "they will be written as tracks." ),
962 layerOptions.insert(
"FORCE_GPX_ROUTE",
new BoolOption(
963 QObject::tr(
"By default when writing a layer whose features are of "
964 "type wkbMultiLineString, the GPX driver chooses to write "
965 "them as tracks. If FORCE_GPX_ROUTE=YES is specified, "
966 "they will be written as routes, provided that the multilines "
967 "are composed of only one single line." ),
971 datasetOptions.insert(
"GPX_USE_EXTENSIONS",
new BoolOption(
972 QObject::tr(
"If GPX_USE_EXTENSIONS=YES is specified, "
973 "extra fields will be written inside the <extensions> tag." ),
977 datasetOptions.insert(
"GPX_EXTENSIONS_NS",
new StringOption(
978 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS_URL "
979 "is set. The namespace value used for extension tags. By default, 'ogr'." ),
983 datasetOptions.insert(
"GPX_EXTENSIONS_NS_URL",
new StringOption(
984 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS "
985 "is set. The namespace URI. By default, 'http://osgeo.org/gdal'." ),
986 "http://osgeo.org/gdal"
989 datasetOptions.insert(
"LINEFORMAT",
new SetOption(
990 QObject::tr(
"By default files are created with the line termination "
991 "conventions of the local platform (CR/LF on win32 or LF "
992 "on all other systems). This may be overridden through use "
993 "of the LINEFORMAT layer creation option which may have a value "
994 "of CRLF (DOS format) or LF (Unix format)." ),
1002 driverMetadata.insert(
"GPX",
1004 "GPS eXchange Format [GPX]",
1014 datasetOptions.clear();
1015 layerOptions.clear();
1017 driverMetadata.insert(
"Interlis 1",
1021 "*.itf *.xml *.ili",
1029 datasetOptions.clear();
1030 layerOptions.clear();
1032 driverMetadata.insert(
"Interlis 2",
1036 "*.itf *.xml *.ili",
1044 datasetOptions.clear();
1045 layerOptions.clear();
1047 datasetOptions.insert(
"NameField",
new StringOption(
1048 QObject::tr(
"Allows you to specify the field to use for the KML <name> element. " ),
1052 datasetOptions.insert(
"DescriptionField",
new StringOption(
1053 QObject::tr(
"Allows you to specify the field to use for the KML <description> element." ),
1057 datasetOptions.insert(
"AltitudeMode",
new SetOption(
1058 QObject::tr(
"Allows you to specify the AltitudeMode to use for KML geometries. "
1059 "This will only affect 3D geometries and must be one of the valid KML options." ),
1061 <<
"relativeToGround"
1067 driverMetadata.insert(
"KML",
1069 "Keyhole Markup Language [KML]",
1079 datasetOptions.clear();
1080 layerOptions.clear();
1082 layerOptions.insert(
"SPATIAL_INDEX_MODE",
new SetOption(
1083 QObject::tr(
"Use this to turn on 'quick spatial index mode'. "
1084 "In this mode writing files can be about 5 times faster, "
1085 "but spatial queries can be up to 30 times slower." ),
1092 driverMetadata.insert(
"MapInfo File",
1104 driverMetadata.insert(
"MapInfo MIF",
1116 datasetOptions.clear();
1117 layerOptions.clear();
1119 datasetOptions.insert(
"3D",
new BoolOption(
1120 QObject::tr(
"Determine whether 2D (seed_2d.dgn) or 3D (seed_3d.dgn) "
1121 "seed file should be used. This option is ignored if the SEED option is provided." ),
1125 datasetOptions.insert(
"SEED",
new StringOption(
1130 datasetOptions.insert(
"COPY_WHOLE_SEED_FILE",
new BoolOption(
1131 QObject::tr(
"Indicate whether the whole seed file should be copied. "
1132 "If not, only the first three elements will be copied." ),
1136 datasetOptions.insert(
"COPY_SEED_FILE_COLOR_TABLEE",
new BoolOption(
1137 QObject::tr(
"Indicates whether the color table should be copied from the seed file." ),
1141 datasetOptions.insert(
"MASTER_UNIT_NAME",
new StringOption(
1142 QObject::tr(
"Override the master unit name from the seed file with "
1143 "the provided one or two character unit name." ),
1147 datasetOptions.insert(
"SUB_UNIT_NAME",
new StringOption(
1148 QObject::tr(
"Override the sub unit name from the seed file with the provided "
1149 "one or two character unit name." ),
1153 datasetOptions.insert(
"SUB_UNITS_PER_MASTER_UNIT",
new IntOption(
1154 QObject::tr(
"Override the number of subunits per master unit. "
1155 "By default the seed file value is used." ),
1159 datasetOptions.insert(
"UOR_PER_SUB_UNIT",
new IntOption(
1160 QObject::tr(
"Override the number of UORs (Units of Resolution) "
1161 "per sub unit. By default the seed file value is used." ),
1165 datasetOptions.insert(
"ORIGIN",
new StringOption(
1166 QObject::tr(
"ORIGIN=x,y,z: Override the origin of the design plane. "
1167 "By default the origin from the seed file is used." ),
1171 driverMetadata.insert(
"DGN",
1183 datasetOptions.clear();
1184 layerOptions.clear();
1186 driverMetadata.insert(
"DGN",
1198 datasetOptions.clear();
1199 layerOptions.clear();
1201 datasetOptions.insert(
"UPDATES",
new SetOption(
1202 QObject::tr(
"Should update files be incorporated into the base data on the fly. " ),
1209 datasetOptions.insert(
"SPLIT_MULTIPOINT",
new BoolOption(
1210 QObject::tr(
"Should multipoint soundings be split into many single point sounding features. "
1211 "Multipoint geometries are not well handled by many formats, "
1212 "so it can be convenient to split single sounding features with many points "
1213 "into many single point features." ),
1217 datasetOptions.insert(
"ADD_SOUNDG_DEPTH",
new BoolOption(
1218 QObject::tr(
"Should a DEPTH attribute be added on SOUNDG features and assign the depth "
1219 "of the sounding. This should only be enabled with SPLIT_MULTIPOINT is "
1224 datasetOptions.insert(
"RETURN_PRIMITIVES",
new BoolOption(
1225 QObject::tr(
"Should all the low level geometry primitives be returned as special "
1226 "IsolatedNode, ConnectedNode, Edge and Face layers." ),
1230 datasetOptions.insert(
"PRESERVE_EMPTY_NUMBERS",
new BoolOption(
1231 QObject::tr(
"If enabled, numeric attributes assigned an empty string as a value will "
1232 "be preserved as a special numeric value. This option should not generally "
1233 "be needed, but may be useful when translated S-57 to S-57 losslessly." ),
1237 datasetOptions.insert(
"LNAM_REFS",
new BoolOption(
1238 QObject::tr(
"Should LNAM and LNAM_REFS fields be attached to features capturing "
1239 "the feature to feature relationships in the FFPT group of the S-57 file." ),
1243 datasetOptions.insert(
"RETURN_LINKAGES",
new BoolOption(
1244 QObject::tr(
"Should additional attributes relating features to their underlying "
1245 "geometric primitives be attached. These are the values of the FSPT group, "
1246 "and are primarily needed when doing S-57 to S-57 translations." ),
1250 datasetOptions.insert(
"RECODE_BY_DSSI",
new BoolOption(
1251 QObject::tr(
"Should attribute values be recoded to UTF-8 from the character encoding "
1252 "specified in the S57 DSSI record." ),
1258 driverMetadata.insert(
"S57",
1270 datasetOptions.clear();
1271 layerOptions.clear();
1273 driverMetadata.insert(
"SDTS",
1275 "Spatial Data Transfer Standard [SDTS]",
1276 QObject::tr(
"Spatial Data Transfer Standard [SDTS]" ),
1285 datasetOptions.clear();
1286 layerOptions.clear();
1288 datasetOptions.insert(
"METADATA",
new BoolOption(
1289 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys "
1290 "tables in a new database. By default these metadata tables are created "
1291 "when a new database is created." ),
1296 datasetOptions.insert(
"SPATIALITE",
new HiddenOption(
1301 datasetOptions.insert(
"INIT_WITH_EPSG",
new HiddenOption(
1305 layerOptions.insert(
"FORMAT",
new SetOption(
1306 QObject::tr(
"Controls the format used for the geometry column. Defaults to WKB."
1307 "This is generally more space and processing efficient, but harder "
1308 "to inspect or use in simple applications than WKT (Well Known Text)." ),
1315 layerOptions.insert(
"LAUNDER",
new BoolOption(
1316 QObject::tr(
"Controls whether layer and field names will be laundered for easier use "
1317 "in SQLite. Laundered names will be converted to lower case and some special "
1318 "characters(' - #) will be changed to underscores." ),
1322 layerOptions.insert(
"SPATIAL_INDEX",
new HiddenOption(
1326 layerOptions.insert(
"COMPRESS_GEOM",
new HiddenOption(
1330 layerOptions.insert(
"SRID",
new HiddenOption(
1334 layerOptions.insert(
"COMPRESS_COLUMNS",
new StringOption(
1335 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that "
1336 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial "
1337 "for databases that have big string blobs. However, use with care, since "
1338 "the value of such columns will be seen as compressed binary content with "
1339 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, "
1340 "modifying or queryings compressed columns, compression/decompression is "
1341 "done transparently. However, such columns cannot be (easily) queried with "
1342 "an attribute filter or WHERE clause. Note: in table definition, such columns "
1343 "have the 'VARCHAR_deflate' declaration type." ),
1347 driverMetadata.insert(
"SQLite",
1359 datasetOptions.clear();
1360 layerOptions.clear();
1362 datasetOptions.insert(
"METADATA",
new BoolOption(
1363 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys "
1364 "tables in a new database. By default these metadata tables are created "
1365 "when a new database is created." ),
1369 datasetOptions.insert(
"SPATIALITE",
new HiddenOption(
1373 datasetOptions.insert(
"INIT_WITH_EPSG",
new BoolOption(
1374 QObject::tr(
"Insert the content of the EPSG CSV files into the spatial_ref_sys table. "
1375 "Set to NO for regular SQLite databases." ),
1379 layerOptions.insert(
"FORMAT",
new HiddenOption(
1383 layerOptions.insert(
"LAUNDER",
new BoolOption(
1384 QObject::tr(
"Controls whether layer and field names will be laundered for easier use "
1385 "in SQLite. Laundered names will be convered to lower case and some special "
1386 "characters(' - #) will be changed to underscores." ),
1390 layerOptions.insert(
"SPATIAL_INDEX",
new BoolOption(
1391 QObject::tr(
"If the database is of the SpatiaLite flavour, and if OGR is linked "
1392 "against libspatialite, this option can be used to control if a spatial "
1393 "index must be created." ),
1397 layerOptions.insert(
"COMPRESS_GEOM",
new BoolOption(
1398 QObject::tr(
"If the format of the geometry BLOB is of the SpatiaLite flavour, "
1399 "this option can be used to control if the compressed format for "
1400 "geometries (LINESTRINGs, POLYGONs) must be used" ),
1404 layerOptions.insert(
"SRID",
new StringOption(
1405 QObject::tr(
"Used to force the SRID number of the SRS associated with the layer. "
1406 "When this option isn't specified and that a SRS is associated with the "
1407 "layer, a search is made in the spatial_ref_sys to find a match for the "
1408 "SRS, and, if there is no match, a new entry is inserted for the SRS in "
1409 "the spatial_ref_sys table. When the SRID option is specified, this "
1410 "search (and the eventual insertion of a new entry) will not be done: "
1411 "the specified SRID is used as such." ),
1415 layerOptions.insert(
"COMPRESS_COLUMNS",
new StringOption(
1416 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that "
1417 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial "
1418 "for databases that have big string blobs. However, use with care, since "
1419 "the value of such columns will be seen as compressed binary content with "
1420 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, "
1421 "modifying or queryings compressed columns, compression/decompression is "
1422 "done transparently. However, such columns cannot be (easily) queried with "
1423 "an attribute filter or WHERE clause. Note: in table definition, such columns "
1424 "have the 'VARCHAR_deflate' declaration type." ),
1428 driverMetadata.insert(
"SpatiaLite",
1439 datasetOptions.clear();
1440 layerOptions.clear();
1444 QObject::tr(
"Override the header file used - in place of header.dxf." ),
1448 datasetOptions.insert(
"TRAILER",
new StringOption(
1449 QObject::tr(
"Override the trailer file used - in place of trailer.dxf." ),
1454 driverMetadata.insert(
"DXF",
1466 datasetOptions.clear();
1467 layerOptions.clear();
1469 datasetOptions.insert(
"EXTENSION",
new SetOption(
1470 QObject::tr(
"Indicates the GeoConcept export file extension. "
1471 "TXT was used by earlier releases of GeoConcept. GXT is currently used." ),
1479 datasetOptions.insert(
"CONFIG",
new StringOption(
1480 QObject::tr(
"path to the GCT : the GCT file describe the GeoConcept types definitions: "
1481 "In this file, every line must start with //# followed by a keyword. "
1482 "Lines starting with // are comments." ),
1487 driverMetadata.insert(
"Geoconcept",
1499 datasetOptions.clear();
1500 layerOptions.clear();
1502 layerOptions.insert(
"FEATURE_DATASET",
new StringOption(
1503 QObject::tr(
"When this option is set, the new layer will be created inside the named "
1504 "FeatureDataset folder. If the folder does not already exist, it will be created." ),
1508 layerOptions.insert(
"GEOMETRY_NAME",
new StringOption(
1509 QObject::tr(
"Set name of geometry column in new layer. Defaults to 'SHAPE'." ),
1513 layerOptions.insert(
"OID_NAME",
new StringOption(
1514 QObject::tr(
"Name of the OID column to create. Defaults to 'OBJECTID'." ),
1518 driverMetadata.insert(
"FileGDB",
1533 static const QMap<QString, MetaData> sDriverMetadata = initMetaData();
1535 QMap<QString, MetaData>::ConstIterator it = sDriverMetadata.constBegin();
1537 for ( ; it != sDriverMetadata.constEnd(); ++it )
1539 if ( it.key().startsWith( driverName ) )
1541 driverMetadata = it.value();
1563 OGRFeatureH poFeature = createFeature( feature );
1572 QString styleString;
1573 QString currentStyle;
1575 QgsSymbolV2List::const_iterator symbolIt = symbols.constBegin();
1576 for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
1578 int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
1579 for (
int i = 0; i < nSymbolLayers; ++i )
1582 QMap< QgsSymbolLayerV2*, QString >::const_iterator it = mSymbolLayerTable.find(( *symbolIt )->symbolLayer( i ) );
1583 if ( it == mSymbolLayerTable.constEnd() )
1591 currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
1595 if ( symbolIt != symbols.constBegin() || i != 0 )
1597 styleString.append(
";" );
1599 styleString.append( currentStyle );
1603 OGR_F_SetStyleString( poFeature, currentStyle.toLocal8Bit().data() );
1604 if ( !writeFeature(
mLayer, poFeature ) )
1611 OGR_F_SetStyleString( poFeature, styleString.toLocal8Bit().data() );
1616 if ( !writeFeature(
mLayer, poFeature ) )
1622 OGR_F_Destroy( poFeature );
1626 OGRFeatureH QgsVectorFileWriter::createFeature(
QgsFeature& feature )
1628 OGRFeatureH poFeature = OGR_F_Create( OGR_L_GetLayerDefn(
mLayer ) );
1633 QgsDebugMsg( QString(
"feature id %1 too large." ).arg( fid ) );
1634 OGRErr err = OGR_F_SetFID( poFeature, static_cast<long>( fid ) );
1635 if ( err != OGRERR_NONE )
1637 QgsDebugMsg( QString(
"Failed to set feature id to %1: %2 (OGR error: %3)" )
1638 .arg( feature.
id() )
1639 .arg( err ).arg( CPLGetLastErrorMsg() )
1645 for (
int fldIdx = 0; fldIdx <
mFields.
count(); ++fldIdx )
1649 QgsDebugMsg( QString(
"no ogr field for field %1" ).arg( fldIdx ) );
1653 const QVariant& attrValue = feature.
attribute( fldIdx );
1656 if ( !attrValue.isValid() || attrValue.isNull() )
1659 switch ( attrValue.type() )
1662 OGR_F_SetFieldInteger( poFeature, ogrField, attrValue.toInt() );
1664 case QVariant::Double:
1665 OGR_F_SetFieldDouble( poFeature, ogrField, attrValue.toDouble() );
1667 case QVariant::LongLong:
1668 case QVariant::String:
1669 OGR_F_SetFieldString( poFeature, ogrField,
mCodec->fromUnicode( attrValue.toString() ).data() );
1671 case QVariant::Date:
1672 OGR_F_SetFieldDateTime( poFeature, ogrField,
1673 attrValue.toDate().year(),
1674 attrValue.toDate().month(),
1675 attrValue.toDate().day(),
1678 case QVariant::DateTime:
1679 OGR_F_SetFieldDateTime( poFeature, ogrField,
1680 attrValue.toDateTime().date().year(),
1681 attrValue.toDateTime().date().month(),
1682 attrValue.toDateTime().date().day(),
1683 attrValue.toDateTime().time().hour(),
1684 attrValue.toDateTime().time().minute(),
1685 attrValue.toDateTime().time().second(),
1688 case QVariant::Invalid:
1692 .arg(
mFields[fldIdx].name() )
1694 .arg( QMetaType::typeName( attrValue.type() ) )
1695 .arg( attrValue.toString() );
1729 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1732 OGR_F_Destroy( poFeature );
1736 OGRErr err = OGR_G_ImportFromWkb( mGeom2, const_cast<unsigned char *>( geom->
asWkb() ), (
int ) geom->wkbSize() );
1737 if ( err != OGRERR_NONE )
1740 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1743 OGR_F_Destroy( poFeature );
1748 OGR_F_SetGeometryDirectly( poFeature, mGeom2 );
1752 OGRErr err = OGR_G_ImportFromWkb(
mGeom, const_cast<unsigned char *>( geom->
asWkb() ), (
int ) geom->wkbSize() );
1753 if ( err != OGRERR_NONE )
1756 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1759 OGR_F_Destroy( poFeature );
1764 OGR_F_SetGeometry( poFeature,
mGeom );
1770 bool QgsVectorFileWriter::writeFeature( OGRLayerH layer, OGRFeatureH feature )
1772 if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
1774 mErrorMessage =
QObject::tr(
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1777 OGR_F_Destroy( feature );
1787 OGR_G_DestroyGeometry(
mGeom );
1792 OGR_DS_Destroy(
mDS );
1798 const QString& fileName,
1799 const QString& fileEncoding,
1801 const QString& driverName,
1803 QString *errorMessage,
1804 const QStringList &datasourceOptions,
1805 const QStringList &layerOptions,
1806 bool skipAttributeCreation,
1807 QString *newFilename,
1809 double symbologyScale,
1813 if ( destCRS && layer )
1819 errorMessage, datasourceOptions, layerOptions, skipAttributeCreation, newFilename, symbologyExport, symbologyScale, filterExtent );
1825 const QString& fileName,
1826 const QString& fileEncoding,
1828 const QString& driverName,
1830 QString *errorMessage,
1831 const QStringList &datasourceOptions,
1832 const QStringList &layerOptions,
1833 bool skipAttributeCreation,
1834 QString *newFilename,
1836 double symbologyScale,
1844 bool shallTransform =
false;
1849 outputCRS = &( ct->
destCRS() );
1850 shallTransform =
true;
1855 outputCRS = &layer->
crs();
1863 QString srcFileName = theURIParts[0];
1865 if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
1868 *errorMessage =
QObject::tr(
"Cannot overwrite a OGR layer in place" );
1880 if ( onlySelected && !ids.contains( fet.
id() ) )
1913 errorMessage->clear();
1920 writer->addRendererAttributes( layer, allAttr );
1950 int n = 0, errors = 0;
1959 writer->startRender( layer );
1962 bool transactionsEnabled =
true;
1964 if ( OGRERR_NONE != OGR_L_StartTransaction( writer->
mLayer ) )
1966 QgsDebugMsg(
"Error when trying to enable transactions on OGRLayer." );
1967 transactionsEnabled =
false;
1973 if ( onlySelected && !ids.contains( fet.
id() ) )
1976 if ( shallTransform )
1989 QString msg =
QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
1990 .arg( fet.
id() ).arg( e.
what() );
1993 *errorMessage = msg;
2002 if ( allAttr.size() < 1 && skipAttributeCreation )
2010 if ( err !=
NoError && errorMessage )
2012 if ( errorMessage->isEmpty() )
2014 *errorMessage =
QObject::tr(
"Feature write errors:" );
2020 if ( errors > 1000 )
2024 *errorMessage +=
QObject::tr(
"Stopping after %1 errors" ).arg( errors );
2034 if ( transactionsEnabled )
2036 if ( OGRERR_NONE != OGR_L_CommitTransaction( writer->
mLayer ) )
2038 QgsDebugMsg(
"Error while committing transaction on OGRLayer." );
2042 writer->stopRender( layer );
2045 if ( errors > 0 && errorMessage && n > 0 )
2047 *errorMessage +=
QObject::tr(
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
2056 QFileInfo fi( theFileName );
2057 QDir dir = fi.dir();
2060 const char *suffixes[] = {
".shp",
".shx",
".dbf",
".prj",
".qix",
".qpj" };
2061 for ( std::size_t i = 0; i <
sizeof( suffixes ) /
sizeof( *suffixes ); i++ )
2063 filter << fi.completeBaseName() + suffixes[i];
2067 foreach ( QString
file, dir.entryList( filter ) )
2069 if ( !QFile::remove( dir.canonicalPath() +
"/" +
file ) )
2081 QMap<QString, QString> resultMap;
2084 int const drvCount = OGRGetDriverCount();
2086 for (
int i = 0; i < drvCount; ++i )
2088 OGRSFDriverH drv = OGRGetDriver( i );
2091 QString drvName = OGR_Dr_GetName( drv );
2092 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2095 if ( filterString.isEmpty() )
2098 resultMap.insert( filterString, drvName );
2108 QMap<QString, QString> resultMap;
2111 int const drvCount = OGRGetDriverCount();
2113 QStringList writableDrivers;
2114 for (
int i = 0; i < drvCount; ++i )
2116 OGRSFDriverH drv = OGRGetDriver( i );
2119 QString drvName = OGR_Dr_GetName( drv );
2120 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2123 if ( drvName ==
"MapInfo File" )
2125 writableDrivers <<
"MapInfo MIF";
2127 else if ( drvName ==
"SQLite" )
2134 QString option =
"SPATIALITE=YES";
2135 char **options =
new char *[2];
2136 options[0] = CPLStrdup( option.toLocal8Bit().data() );
2138 OGRSFDriverH poDriver;
2140 poDriver = OGRGetDriverByName( drvName.toLocal8Bit().data() );
2143 OGRDataSourceH ds = OGR_Dr_CreateDataSource( poDriver,
TO8F( QString(
"/vsimem/spatialitetest.sqlite" ) ), options );
2146 writableDrivers <<
"SpatiaLite";
2147 OGR_Dr_DeleteDataSource( poDriver,
TO8F( QString(
"/vsimem/spatialitetest.sqlite" ) ) );
2148 OGR_DS_Destroy( ds );
2151 CPLFree( options[0] );
2154 else if ( drvName ==
"ESRI Shapefile" )
2156 writableDrivers <<
"DBF file";
2158 writableDrivers << drvName;
2163 foreach ( QString drvName, writableDrivers )
2171 resultMap.insert( trLongName, drvName );
2180 QString filterString;
2182 QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin();
2183 for ( ; it != driverFormatMap.constEnd(); ++it )
2185 if ( !filterString.isEmpty() )
2186 filterString +=
";;";
2188 filterString += it.key();
2190 return filterString;
2199 if ( !
driverMetadata( driverName, longName, trLongName, glob, exts ) || trLongName.isEmpty() || glob.isEmpty() )
2202 return trLongName +
" [OGR] (" + glob.toLower() +
" " + glob.toUpper() +
")";
2207 if ( codecName ==
"System" )
2208 return QString(
"LDID/0" );
2210 QRegExp re = QRegExp( QString(
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
2211 if ( re.exactMatch( codecName ) )
2213 QString c = re.cap( 2 ).replace(
"-",
"" );
2215 c.toInt( &isNumber );
2224 if ( driverName.startsWith(
"AVCE00" ) )
2226 longName =
"Arc/Info ASCII Coverage";
2227 trLongName =
QObject::tr(
"Arc/Info ASCII Coverage" );
2231 else if ( driverName.startsWith(
"BNA" ) )
2233 longName =
"Atlas BNA";
2238 else if ( driverName.startsWith(
"CSV" ) )
2240 longName =
"Comma Separated Value [CSV]";
2241 trLongName =
QObject::tr(
"Comma Separated Value [CSV]" );
2245 else if ( driverName.startsWith(
"ESRI" ) )
2247 longName =
"ESRI Shapefile";
2252 else if ( driverName.startsWith(
"DBF file" ) )
2254 longName =
"DBF File";
2259 else if ( driverName.startsWith(
"FMEObjects Gateway" ) )
2261 longName =
"FMEObjects Gateway";
2266 else if ( driverName.startsWith(
"GeoJSON" ) )
2268 longName =
"GeoJSON";
2273 else if ( driverName.startsWith(
"GeoRSS" ) )
2275 longName =
"GeoRSS";
2280 else if ( driverName.startsWith(
"GML" ) )
2282 longName =
"Geography Markup Language [GML]";
2283 trLongName =
QObject::tr(
"Geography Markup Language [GML]" );
2287 else if ( driverName.startsWith(
"GMT" ) )
2289 longName =
"Generic Mapping Tools [GMT]";
2290 trLongName =
QObject::tr(
"Generic Mapping Tools [GMT]" );
2294 else if ( driverName.startsWith(
"GPX" ) )
2296 longName =
"GPS eXchange Format [GPX]";
2297 trLongName =
QObject::tr(
"GPS eXchange Format [GPX]" );
2301 else if ( driverName.startsWith(
"Interlis 1" ) )
2303 longName =
"INTERLIS 1";
2305 glob =
"*.itf *.xml *.ili";
2308 else if ( driverName.startsWith(
"Interlis 2" ) )
2310 longName =
"INTERLIS 2";
2312 glob =
"*.itf *.xml *.ili";
2315 else if ( driverName.startsWith(
"KML" ) )
2317 longName =
"Keyhole Markup Language [KML]";
2318 trLongName =
QObject::tr(
"Keyhole Markup Language [KML]" );
2322 else if ( driverName.startsWith(
"MapInfo File" ) )
2324 longName =
"Mapinfo TAB";
2330 else if ( driverName.startsWith(
"MapInfo MIF" ) )
2332 longName =
"Mapinfo MIF";
2337 else if ( driverName.startsWith(
"DGN" ) )
2339 longName =
"Microstation DGN";
2344 else if ( driverName.startsWith(
"S57" ) )
2346 longName =
"S-57 Base file";
2351 else if ( driverName.startsWith(
"SDTS" ) )
2353 longName =
"Spatial Data Transfer Standard [SDTS]";
2354 trLongName =
QObject::tr(
"Spatial Data Transfer Standard [SDTS]" );
2358 else if ( driverName.startsWith(
"SQLite" ) )
2360 longName =
"SQLite";
2366 else if ( driverName.startsWith(
"SpatiaLite" ) )
2368 longName =
"SpatiaLite";
2373 else if ( driverName.startsWith(
"DXF" ) )
2375 longName =
"AutoCAD DXF";
2380 else if ( driverName.startsWith(
"Geoconcept" ) )
2382 longName =
"Geoconcept";
2384 glob =
"*.gxt *.txt";
2387 else if ( driverName.startsWith(
"FileGDB" ) )
2389 longName =
"ESRI FileGDB";
2422 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1700
2423 mSymbolLayerTable.clear();
2424 OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
2425 OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
2428 int nTotalLevels = 0;
2430 QgsSymbolV2List::iterator symbolIt = symbolList.begin();
2431 for ( ; symbolIt != symbolList.end(); ++symbolIt )
2436 int nLevels = ( *symbolIt )->symbolLayerCount();
2437 for (
int i = 0; i < nLevels; ++i )
2439 mSymbolLayerTable.insert(( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
2440 OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
2441 ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
2445 OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
2459 QHash< QgsSymbolV2*, QList<QgsFeature> > features;
2468 startRender( layer );
2486 QString msg =
QObject::tr(
"Failed to transform, writing stopped. (Exception: %1)" )
2490 *errorMessage = msg;
2497 if ( !featureSymbol )
2502 QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
2503 if ( it == features.end() )
2505 it = features.insert( featureSymbol, QList<QgsFeature>() );
2507 it.value().append( fet );
2513 for (
int i = 0; i < symbols.count(); i++ )
2519 if ( level < 0 || level >= 1000 )
2522 while ( level >= levels.count() )
2524 levels[level].append( item );
2529 int nTotalFeatures = 0;
2532 for (
int l = 0; l < levels.count(); l++ )
2535 for (
int i = 0; i < level.count(); i++ )
2538 QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
2539 if ( levelIt == features.end() )
2548 int llayer = item.
layer();
2549 QList<QgsFeature>& featureList = levelIt.value();
2550 QList<QgsFeature>::iterator featureIt = featureList.begin();
2551 for ( ; featureIt != featureList.end(); ++featureIt )
2554 OGRFeatureH ogrFeature = createFeature( *featureIt );
2561 QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
2562 if ( !styleString.isEmpty() )
2564 OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
2565 if ( ! writeFeature(
mLayer, ogrFeature ) )
2570 OGR_F_Destroy( ogrFeature );
2575 stopRender( layer );
2577 if ( nErrors > 0 && errorMessage )
2579 *errorMessage +=
QObject::tr(
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
2596 return 1000 / scaleDenominator;
2613 return scaleDenominator / 1000;
2626 void QgsVectorFileWriter::startRender(
QgsVectorLayer* vl )
const
2670 for (
int i = 0; i < rendererAttributes.size(); ++i )
2675 attList.push_back( vl->
fieldNameIndex( rendererAttributes.at( i ) ) );