37 #include <QTextStream> 45 #include <ogr_srs_api.h> 46 #include <cpl_error.h> 49 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800 50 #define TO8(x) (x).toUtf8().constData() 51 #define TO8F(x) (x).toUtf8().constData() 53 #define TO8(x) (x).toLocal8Bit().constData() 54 #define TO8F(x) QFile::encodeName( x ).constData() 59 const QString &theVectorFileName,
60 const QString &theFileEncoding,
64 const QString& driverName,
65 const QStringList &datasourceOptions,
66 const QStringList &layerOptions,
76 , mWkbType( geometryType )
77 , mSymbologyExport( symbologyExport )
78 , mSymbologyScaleDenominator( 1.0 )
80 QString vectorFileName = theVectorFileName;
81 QString fileEncoding = theFileEncoding;
82 QStringList layOptions = layerOptions;
83 QStringList dsOptions = datasourceOptions;
85 if ( theVectorFileName.isEmpty() )
92 QString ogrDriverName;
93 if ( driverName ==
"MapInfo MIF" )
95 ogrDriverName =
"MapInfo File";
97 else if ( driverName ==
"SpatiaLite" )
99 ogrDriverName =
"SQLite";
100 if ( !dsOptions.contains(
"SPATIALITE=YES" ) )
102 dsOptions.append(
"SPATIALITE=YES" );
105 else if ( driverName ==
"DBF file" )
107 ogrDriverName =
"ESRI Shapefile";
108 if ( !layOptions.contains(
"SHPT=NULL" ) )
110 layOptions.append(
"SHPT=NULL" );
116 ogrDriverName = driverName;
120 OGRSFDriverH poDriver;
123 poDriver = OGRGetDriverByName( ogrDriverName.toLocal8Bit().data() );
129 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
134 if ( ogrDriverName ==
"ESRI Shapefile" )
136 if ( layOptions.join(
"" ).toUpper().indexOf(
"ENCODING=" ) == -1 )
141 if ( driverName ==
"ESRI Shapefile" && !vectorFileName.endsWith(
".shp", Qt::CaseInsensitive ) )
143 vectorFileName +=
".shp";
145 else if ( driverName ==
"DBF file" && !vectorFileName.endsWith(
".dbf", Qt::CaseInsensitive ) )
147 vectorFileName +=
".dbf";
150 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM < 1700 152 QSet<QString> fieldNames;
153 for (
int i = 0; i < fields.
count(); ++i )
155 QString name = fields[i].name().left( 10 );
156 if ( fieldNames.contains( name ) )
158 mErrorMessage =
QObject::tr(
"trimming attribute name '%1' to ten significant characters produces duplicate column name." )
159 .arg( fields[i].name() );
169 else if ( driverName ==
"KML" )
171 if ( !vectorFileName.endsWith(
".kml", Qt::CaseInsensitive ) )
173 vectorFileName +=
".kml";
176 if ( fileEncoding.compare(
"UTF-8", Qt::CaseInsensitive ) != 0 )
179 fileEncoding =
"UTF-8";
182 QFile::remove( vectorFileName );
192 QStringList allExts = exts.split(
" ", QString::SkipEmptyParts );
194 foreach ( QString ext, allExts )
196 if ( vectorFileName.endsWith(
"." + ext, Qt::CaseInsensitive ) )
205 vectorFileName +=
"." + allExts[0];
209 QFile::remove( vectorFileName );
212 char **options = NULL;
213 if ( !dsOptions.isEmpty() )
215 options =
new char *[ dsOptions.size()+1 ];
216 for (
int i = 0; i < dsOptions.size(); i++ )
218 options[i] = CPLStrdup( dsOptions[i].toLocal8Bit().data() );
220 options[ dsOptions.size()] = NULL;
224 mDS = OGR_Dr_CreateDataSource( poDriver,
TO8F( vectorFileName ), options );
228 for (
int i = 0; i < dsOptions.size(); i++ )
229 CPLFree( options[i] );
238 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
245 mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().constData() );
248 QgsDebugMsg(
"error finding QTextCodec for " + fileEncoding );
251 QString enc = settings.value(
"/UI/encoding",
"System" ).toString();
252 mCodec = QTextCodec::codecForName( enc.toLocal8Bit().constData() );
255 QgsDebugMsg(
"error finding QTextCodec for " + enc );
256 mCodec = QTextCodec::codecForLocale();
264 QString srsWkt = srs->
toWkt();
266 mOgrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().data() );
270 QString layerName = QFileInfo( vectorFileName ).baseName();
271 OGRwkbGeometryType wkbType =
static_cast<OGRwkbGeometryType
>( geometryType );
273 if ( !layOptions.isEmpty() )
275 options =
new char *[ layOptions.size()+1 ];
276 for (
int i = 0; i < layOptions.size(); i++ )
278 options[i] = CPLStrdup( layOptions[i].toLocal8Bit().data() );
280 options[ layOptions.size()] = NULL;
284 CPLSetConfigOption(
"SHAPE_ENCODING",
"" );
290 for (
int i = 0; i < layOptions.size(); i++ )
291 CPLFree( options[i] );
297 if ( !settings.value(
"/qgis/ignoreShapeEncoding",
true ).toBool() )
299 CPLSetConfigOption(
"SHAPE_ENCODING", 0 );
304 if ( ogrDriverName ==
"ESRI Shapefile" )
306 QString layerName = vectorFileName.left( vectorFileName.indexOf(
".shp", Qt::CaseInsensitive ) );
307 QFile prjFile( layerName +
".qpj" );
308 if ( prjFile.open( QIODevice::WriteOnly ) )
310 QTextStream prjStream( &prjFile );
311 prjStream << srs->
toWkt().toLocal8Bit().data() << endl;
316 QgsDebugMsg(
"Couldn't open file " + layerName +
".qpj" );
324 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
329 OGRFeatureDefnH defn = OGR_L_GetLayerDefn(
mLayer );
334 QgsDebugMsg(
"creating " + QString::number( fields.
size() ) +
" fields" );
338 QSet<int> existingIdxs;
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 if ( ogrPrecision > 0 )
350 switch ( attrField.
type() )
352 case QVariant::LongLong:
354 ogrWidth = ogrWidth > 0 && ogrWidth <= 21 ? ogrWidth : 21;
358 case QVariant::String:
360 if ( ogrWidth <= 0 || ogrWidth > 255 )
365 ogrType = OFTInteger;
366 ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
370 case QVariant::Double:
378 case QVariant::DateTime:
379 ogrType = OFTDateTime;
385 .arg( attrField.
name() );
390 QString name( attrField.
name() );
392 if ( ogrDriverName ==
"SQLite" && name.compare(
"ogc_fid", Qt::CaseInsensitive ) == 0 )
395 for ( i = 0; i < 10; i++ )
397 name = QString(
"ogc_fid%1" ).arg( i );
400 for ( j = 0; j < fields.
size() && name.compare( fields[j].name(), Qt::CaseInsensitive ) != 0; j++ )
403 if ( j == fields.
size() )
418 OGRFieldDefnH fld = OGR_Fld_Create(
mCodec->fromUnicode( name ), ogrType );
421 OGR_Fld_SetWidth( fld, ogrWidth );
424 if ( ogrPrecision >= 0 )
426 OGR_Fld_SetPrecision( fld, ogrPrecision );
431 " type " + QString( QVariant::typeToName( attrField.
type() ) ) +
432 " width " + QString::number( ogrWidth ) +
433 " precision " + QString::number( ogrPrecision ) );
434 if ( OGR_L_CreateField(
mLayer, fld,
true ) != OGRERR_NONE )
438 .arg( attrField.
name() )
439 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
441 OGR_Fld_Destroy( fld );
444 OGR_Fld_Destroy( fld );
446 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
447 QgsDebugMsg( QString(
"returned field index for %1: %2" ).arg( name ).arg( ogrIdx ) );
448 if ( ogrIdx < 0 || existingIdxs.contains( ogrIdx ) )
450 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM < 1700 453 int fieldCount = OGR_FD_GetFieldCount( defn );
455 OGRFieldDefnH fdefn = OGR_FD_GetFieldDefn( defn, fieldCount - 1 );
458 const char *fieldName = OGR_Fld_GetNameRef( fdefn );
460 if ( attrField.
name().left( strlen( fieldName ) ) == fieldName )
462 ogrIdx = fieldCount - 1;
467 ogrIdx = OGR_FD_GetFieldCount( defn ) - 1;
474 .arg( attrField.
name() )
475 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
481 existingIdxs.insert( ogrIdx );
495 *newFilename = vectorFileName;
500 return OGR_G_CreateGeometry(( OGRwkbGeometryType ) wkbType );
503 QMap<QString, QgsVectorFileWriter::MetaData> QgsVectorFileWriter::initMetaData()
507 QMap<QString, Option*> datasetOptions;
508 QMap<QString, Option*> layerOptions;
511 datasetOptions.clear();
512 layerOptions.clear();
514 driverMetadata.insert(
"AVCE00",
516 "Arc/Info ASCII Coverage",
526 datasetOptions.clear();
527 layerOptions.clear();
529 datasetOptions.insert(
"LINEFORMAT",
new SetOption(
531 "systems default line termination conventions. " 532 "This may be overridden here." ),
540 datasetOptions.insert(
"MULTILINE",
new BoolOption(
541 QObject::tr(
"By default, BNA files are created in multi-line format. " 542 "For each record, the first line contains the identifiers and the " 543 "type/number of coordinates to follow. Each following line contains " 544 "a pair of coordinates." ),
548 datasetOptions.insert(
"NB_IDS",
new SetOption(
549 QObject::tr(
"BNA records may contain from 2 to 4 identifiers per record. " 550 "Some software packages only support a precise number of identifiers. " 551 "You can override the default value (2) by a precise value" ),
556 <<
"NB_SOURCE_FIELDS",
560 datasetOptions.insert(
"ELLIPSES_AS_ELLIPSES",
new BoolOption(
561 QObject::tr(
"The BNA writer will try to recognize ellipses and circles when writing a polygon. " 562 "This will only work if the feature has previously been read from a BNA file. " 563 "As some software packages do not support ellipses/circles in BNA data file, " 564 "it may be useful to tell the writer by specifying ELLIPSES_AS_ELLIPSES=NO not " 565 "to export them as such, but keep them as polygons." ),
569 datasetOptions.insert(
"NB_PAIRS_PER_LINE",
new IntOption(
570 QObject::tr(
"Limit the number of coordinate pairs per line in multiline format." ),
574 datasetOptions.insert(
"COORDINATE_PRECISION",
new IntOption(
575 QObject::tr(
"Set the number of decimal for coordinates. Default value is 10." ),
579 driverMetadata.insert(
"BNA",
591 datasetOptions.clear();
592 layerOptions.clear();
594 layerOptions.insert(
"LINEFORMAT",
new SetOption(
595 QObject::tr(
"By default when creating new .csv files they " 596 "are created with the line termination conventions " 597 "of the local platform (CR/LF on Win32 or LF on all other systems). " 598 "This may be overridden through the use of the LINEFORMAT option." ),
606 layerOptions.insert(
"GEOMETRY",
new SetOption(
607 QObject::tr(
"By default, the geometry of a feature written to a .csv file is discarded. " 608 "It is possible to export the geometry in its WKT representation by " 609 "specifying GEOMETRY=AS_WKT. It is also possible to export point geometries " 610 "into their X,Y,Z components by specifying GEOMETRY=AS_XYZ, GEOMETRY=AS_XY " 611 "or GEOMETRY=AS_YX." ),
621 layerOptions.insert(
"CREATE_CSVT",
new BoolOption(
622 QObject::tr(
"Create the associated .csvt file to describe the type of each " 623 "column of the layer and its optional width and precision." ),
627 layerOptions.insert(
"SEPARATOR",
new SetOption(
636 layerOptions.insert(
"WRITE_BOM",
new BoolOption(
637 QObject::tr(
"Write a UTF-8 Byte Order Mark (BOM) at the start of the file." ),
641 driverMetadata.insert(
"CSV",
643 "Comma Separated Value [CSV]",
653 datasetOptions.clear();
654 layerOptions.clear();
656 layerOptions.insert(
"SHPT",
new SetOption(
657 QObject::tr(
"Override the type of shapefile created. " 658 "Can be one of NULL for a simple .dbf file with no .shp file, POINT, " 659 "ARC, POLYGON or MULTIPOINT for 2D, or POINTZ, ARCZ, POLYGONZ or " 660 "MULTIPOINTZ for 3D. Shapefiles with measure values are not supported, " 661 "nor are MULTIPATCH files." ),
675 layerOptions.insert(
"ENCODING",
new SetOption(
676 QObject::tr(
"set the encoding value in the DBF file. " 677 "The default value is LDID/87. It is not clear " 678 "what other values may be appropriate." ),
684 layerOptions.insert(
"RESIZE",
new BoolOption(
685 QObject::tr(
"Set to YES to resize fields to their optimal size." ),
689 driverMetadata.insert(
"ESRI",
701 datasetOptions.clear();
702 layerOptions.clear();
704 driverMetadata.insert(
"DBF File",
716 datasetOptions.clear();
717 layerOptions.clear();
719 driverMetadata.insert(
"FMEObjects Gateway",
721 "FMEObjects Gateway",
731 datasetOptions.clear();
732 layerOptions.clear();
734 layerOptions.insert(
"WRITE_BBOX",
new BoolOption(
735 QObject::tr(
"Set to YES to write a bbox property with the bounding box " 736 "of the geometries at the feature and feature collection level." ),
740 layerOptions.insert(
"COORDINATE_PRECISION",
new IntOption(
741 QObject::tr(
"Maximum number of figures after decimal separator to write in coordinates. " 742 "Default to 15. Truncation will occur to remove trailing zeros." ),
746 driverMetadata.insert(
"GeoJSON",
758 datasetOptions.clear();
759 layerOptions.clear();
761 datasetOptions.insert(
"FORMAT",
new SetOption(
762 QObject::tr(
"whether the document must be in RSS 2.0 or Atom 1.0 format. " 763 "Default value : RSS" ),
770 datasetOptions.insert(
"GEOM_DIALECT",
new SetOption(
771 QObject::tr(
"The encoding of location information. Default value : SIMPLE. " 772 "W3C_GEO only supports point geometries. " 773 "SIMPLE or W3C_GEO only support geometries in geographic WGS84 coordinates." ),
781 datasetOptions.insert(
"USE_EXTENSIONS",
new BoolOption(
782 QObject::tr(
"If defined to YES, extension fields will be written. " 783 "If the field name not found in the base schema matches " 784 "the foo_bar pattern, foo will be considered as the namespace " 785 "of the element, and a <foo:bar> element will be written. " 786 "Otherwise, elements will be written in the <ogr:> namespace." ),
790 datasetOptions.insert(
"WRITE_HEADER_AND_FOOTER",
new BoolOption(
791 QObject::tr(
"If defined to NO, only <entry> or <item> elements will be written. " 792 "The user will have to provide the appropriate header and footer of the document." ),
797 QObject::tr(
"XML content that will be put between the <channel> element and the " 798 "first <item> element for a RSS document, or between the xml tag and " 799 "the first <entry> element for an Atom document. " ),
804 QObject::tr(
"Value put inside the <title> element in the header. " 805 "If not provided, a dummy value will be used as that element is compulsory." ),
810 QObject::tr(
"Value put inside the <description> element in the header. " 811 "If not provided, a dummy value will be used as that element is compulsory." ),
816 QObject::tr(
"Value put inside the <link> element in the header. " 817 "If not provided, a dummy value will be used as that element is compulsory." ),
822 QObject::tr(
"Value put inside the <updated> element in the header. " 823 "Should be formatted as a XML datetime. " 824 "If not provided, a dummy value will be used as that element is compulsory." ),
829 QObject::tr(
"Value put inside the <author><name> element in the header. " 830 "If not provided, a dummy value will be used as that element is compulsory." ),
835 QObject::tr(
"Value put inside the <id> element in the header. " 836 "If not provided, a dummy value will be used as that element is compulsory." ),
840 driverMetadata.insert(
"GeoRSS",
852 datasetOptions.clear();
853 layerOptions.clear();
855 datasetOptions.insert(
"XSISCHEMAURI",
new StringOption(
856 QObject::tr(
"If provided, this URI will be inserted as the schema location. " 857 "Note that the schema file isn't actually accessed by OGR, so it " 858 "is up to the user to ensure it will match the schema of the OGR " 859 "produced GML data file." ),
863 datasetOptions.insert(
"XSISCHEMA",
new SetOption(
864 QObject::tr(
"This writes a GML application schema file to a corresponding " 865 ".xsd file (with the same basename). If INTERNAL is used the " 866 "schema is written within the GML file, but this is experimental " 867 "and almost certainly not valid XML. " 868 "OFF disables schema generation (and is implicit if XSISCHEMAURI is used)." ),
877 QObject::tr(
"This is the prefix for the application target namespace." ),
881 datasetOptions.insert(
"STRIP_PREFIX",
new BoolOption(
882 QObject::tr(
"Can be set to TRUE to avoid writing the prefix of the " 883 "application target namespace in the GML file." ),
887 datasetOptions.insert(
"TARGET_NAMESPACE",
new StringOption(
888 QObject::tr(
"Defaults to 'http://ogr.maptools.org/'. " 889 "This is the application target namespace." ),
890 "http://ogr.maptools.org/" 893 datasetOptions.insert(
"FORMAT",
new SetOption(
894 QObject::tr(
"If not specified, GML2 will be used." ),
903 datasetOptions.insert(
"GML3_LONGSRS",
new BoolOption(
904 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. " 905 "If YES, SRS with EPSG authority will be written with the " 906 "'urn:ogc:def:crs:EPSG::' prefix. In the case, if the SRS is a " 907 "geographic SRS without explicit AXIS order, but that the same " 908 "SRS authority code imported with ImportFromEPSGA() should be " 909 "treated as lat/long, then the function will take care of coordinate " 910 "order swapping. If set to NO, SRS with EPSG authority will be " 911 "written with the 'EPSG:' prefix, even if they are in lat/long order." ),
915 datasetOptions.insert(
"WRITE_FEATURE_BOUNDED_BY",
new BoolOption(
916 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. " 917 "If set to NO, the <gml:boundedBy> element will not be written for " 922 datasetOptions.insert(
"SPACE_INDENTATION",
new BoolOption(
923 QObject::tr(
"Default to YES. If YES, the output will be indented with spaces " 924 "for more readability, but at the expense of file size." ),
929 driverMetadata.insert(
"GML",
931 "Geography Markup Language [GML]",
941 datasetOptions.clear();
942 layerOptions.clear();
944 driverMetadata.insert(
"GMT",
946 "Generic Mapping Tools [GMT]",
956 datasetOptions.clear();
957 layerOptions.clear();
959 layerOptions.insert(
"FORCE_GPX_TRACK",
new BoolOption(
960 QObject::tr(
"By default when writing a layer whose features are of " 961 "type wkbLineString, the GPX driver chooses to write " 962 "them as routes. If FORCE_GPX_TRACK=YES is specified, " 963 "they will be written as tracks." ),
967 layerOptions.insert(
"FORCE_GPX_ROUTE",
new BoolOption(
968 QObject::tr(
"By default when writing a layer whose features are of " 969 "type wkbMultiLineString, the GPX driver chooses to write " 970 "them as tracks. If FORCE_GPX_ROUTE=YES is specified, " 971 "they will be written as routes, provided that the multilines " 972 "are composed of only one single line." ),
976 datasetOptions.insert(
"GPX_USE_EXTENSIONS",
new BoolOption(
977 QObject::tr(
"If GPX_USE_EXTENSIONS=YES is specified, " 978 "extra fields will be written inside the <extensions> tag." ),
982 datasetOptions.insert(
"GPX_EXTENSIONS_NS",
new StringOption(
983 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS_URL " 984 "is set. The namespace value used for extension tags. By default, 'ogr'." ),
988 datasetOptions.insert(
"GPX_EXTENSIONS_NS_URL",
new StringOption(
989 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS " 990 "is set. The namespace URI. By default, 'http://osgeo.org/gdal'." ),
991 "http://osgeo.org/gdal" 994 datasetOptions.insert(
"LINEFORMAT",
new SetOption(
995 QObject::tr(
"By default files are created with the line termination " 996 "conventions of the local platform (CR/LF on win32 or LF " 997 "on all other systems). This may be overridden through use " 998 "of the LINEFORMAT layer creation option which may have a value " 999 "of CRLF (DOS format) or LF (Unix format)." ),
1007 driverMetadata.insert(
"GPX",
1009 "GPS eXchange Format [GPX]",
1019 datasetOptions.clear();
1020 layerOptions.clear();
1022 driverMetadata.insert(
"Interlis 1",
1026 "*.itf *.xml *.ili",
1034 datasetOptions.clear();
1035 layerOptions.clear();
1037 driverMetadata.insert(
"Interlis 2",
1041 "*.itf *.xml *.ili",
1049 datasetOptions.clear();
1050 layerOptions.clear();
1053 QObject::tr(
"Allows you to specify the field to use for the KML <name> element. " ),
1057 datasetOptions.insert(
"DescriptionField",
new StringOption(
1058 QObject::tr(
"Allows you to specify the field to use for the KML <description> element." ),
1062 datasetOptions.insert(
"AltitudeMode",
new SetOption(
1063 QObject::tr(
"Allows you to specify the AltitudeMode to use for KML geometries. " 1064 "This will only affect 3D geometries and must be one of the valid KML options." ),
1066 <<
"relativeToGround" 1072 driverMetadata.insert(
"KML",
1074 "Keyhole Markup Language [KML]",
1084 datasetOptions.clear();
1085 layerOptions.clear();
1087 layerOptions.insert(
"SPATIAL_INDEX_MODE",
new SetOption(
1088 QObject::tr(
"Use this to turn on 'quick spatial index mode'. " 1089 "In this mode writing files can be about 5 times faster, " 1090 "but spatial queries can be up to 30 times slower." ),
1097 driverMetadata.insert(
"MapInfo File",
1109 driverMetadata.insert(
"MapInfo MIF",
1121 datasetOptions.clear();
1122 layerOptions.clear();
1125 QObject::tr(
"Determine whether 2D (seed_2d.dgn) or 3D (seed_3d.dgn) " 1126 "seed file should be used. This option is ignored if the SEED option is provided." ),
1135 datasetOptions.insert(
"COPY_WHOLE_SEED_FILE",
new BoolOption(
1136 QObject::tr(
"Indicate whether the whole seed file should be copied. " 1137 "If not, only the first three elements will be copied." ),
1141 datasetOptions.insert(
"COPY_SEED_FILE_COLOR_TABLEE",
new BoolOption(
1142 QObject::tr(
"Indicates whether the color table should be copied from the seed file." ),
1146 datasetOptions.insert(
"MASTER_UNIT_NAME",
new StringOption(
1147 QObject::tr(
"Override the master unit name from the seed file with " 1148 "the provided one or two character unit name." ),
1152 datasetOptions.insert(
"SUB_UNIT_NAME",
new StringOption(
1153 QObject::tr(
"Override the sub unit name from the seed file with the provided " 1154 "one or two character unit name." ),
1158 datasetOptions.insert(
"SUB_UNITS_PER_MASTER_UNIT",
new IntOption(
1159 QObject::tr(
"Override the number of subunits per master unit. " 1160 "By default the seed file value is used." ),
1164 datasetOptions.insert(
"UOR_PER_SUB_UNIT",
new IntOption(
1165 QObject::tr(
"Override the number of UORs (Units of Resolution) " 1166 "per sub unit. By default the seed file value is used." ),
1171 QObject::tr(
"ORIGIN=x,y,z: Override the origin of the design plane. " 1172 "By default the origin from the seed file is used." ),
1176 driverMetadata.insert(
"DGN",
1188 datasetOptions.clear();
1189 layerOptions.clear();
1191 driverMetadata.insert(
"DGN",
1203 datasetOptions.clear();
1204 layerOptions.clear();
1206 datasetOptions.insert(
"UPDATES",
new SetOption(
1207 QObject::tr(
"Should update files be incorporated into the base data on the fly. " ),
1214 datasetOptions.insert(
"SPLIT_MULTIPOINT",
new BoolOption(
1215 QObject::tr(
"Should multipoint soundings be split into many single point sounding features. " 1216 "Multipoint geometries are not well handled by many formats, " 1217 "so it can be convenient to split single sounding features with many points " 1218 "into many single point features." ),
1222 datasetOptions.insert(
"ADD_SOUNDG_DEPTH",
new BoolOption(
1223 QObject::tr(
"Should a DEPTH attribute be added on SOUNDG features and assign the depth " 1224 "of the sounding. This should only be enabled with SPLIT_MULTIPOINT is " 1229 datasetOptions.insert(
"RETURN_PRIMITIVES",
new BoolOption(
1230 QObject::tr(
"Should all the low level geometry primitives be returned as special " 1231 "IsolatedNode, ConnectedNode, Edge and Face layers." ),
1235 datasetOptions.insert(
"PRESERVE_EMPTY_NUMBERS",
new BoolOption(
1236 QObject::tr(
"If enabled, numeric attributes assigned an empty string as a value will " 1237 "be preserved as a special numeric value. This option should not generally " 1238 "be needed, but may be useful when translated S-57 to S-57 losslessly." ),
1242 datasetOptions.insert(
"LNAM_REFS",
new BoolOption(
1243 QObject::tr(
"Should LNAM and LNAM_REFS fields be attached to features capturing " 1244 "the feature to feature relationships in the FFPT group of the S-57 file." ),
1248 datasetOptions.insert(
"RETURN_LINKAGES",
new BoolOption(
1249 QObject::tr(
"Should additional attributes relating features to their underlying " 1250 "geometric primitives be attached. These are the values of the FSPT group, " 1251 "and are primarily needed when doing S-57 to S-57 translations." ),
1255 datasetOptions.insert(
"RECODE_BY_DSSI",
new BoolOption(
1256 QObject::tr(
"Should attribute values be recoded to UTF-8 from the character encoding " 1257 "specified in the S57 DSSI record." ),
1263 driverMetadata.insert(
"S57",
1275 datasetOptions.clear();
1276 layerOptions.clear();
1278 driverMetadata.insert(
"SDTS",
1280 "Spatial Data Transfer Standard [SDTS]",
1281 QObject::tr(
"Spatial Data Transfer Standard [SDTS]" ),
1290 datasetOptions.clear();
1291 layerOptions.clear();
1293 datasetOptions.insert(
"METADATA",
new BoolOption(
1294 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys " 1295 "tables in a new database. By default these metadata tables are created " 1296 "when a new database is created." ),
1306 datasetOptions.insert(
"INIT_WITH_EPSG",
new HiddenOption(
1310 layerOptions.insert(
"FORMAT",
new SetOption(
1311 QObject::tr(
"Controls the format used for the geometry column. Defaults to WKB." 1312 "This is generally more space and processing efficient, but harder " 1313 "to inspect or use in simple applications than WKT (Well Known Text)." ),
1320 layerOptions.insert(
"LAUNDER",
new BoolOption(
1321 QObject::tr(
"Controls whether layer and field names will be laundered for easier use " 1322 "in SQLite. Laundered names will be converted to lower case and some special " 1323 "characters(' - #) will be changed to underscores." ),
1327 layerOptions.insert(
"SPATIAL_INDEX",
new HiddenOption(
1331 layerOptions.insert(
"COMPRESS_GEOM",
new HiddenOption(
1339 layerOptions.insert(
"COMPRESS_COLUMNS",
new StringOption(
1340 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that " 1341 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial " 1342 "for databases that have big string blobs. However, use with care, since " 1343 "the value of such columns will be seen as compressed binary content with " 1344 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, " 1345 "modifying or queryings compressed columns, compression/decompression is " 1346 "done transparently. However, such columns cannot be (easily) queried with " 1347 "an attribute filter or WHERE clause. Note: in table definition, such columns " 1348 "have the 'VARCHAR_deflate' declaration type." ),
1352 driverMetadata.insert(
"SQLite",
1364 datasetOptions.clear();
1365 layerOptions.clear();
1367 datasetOptions.insert(
"METADATA",
new BoolOption(
1368 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys " 1369 "tables in a new database. By default these metadata tables are created " 1370 "when a new database is created." ),
1378 datasetOptions.insert(
"INIT_WITH_EPSG",
new BoolOption(
1379 QObject::tr(
"Insert the content of the EPSG CSV files into the spatial_ref_sys table. " 1380 "Set to NO for regular SQLite databases." ),
1388 layerOptions.insert(
"LAUNDER",
new BoolOption(
1389 QObject::tr(
"Controls whether layer and field names will be laundered for easier use " 1390 "in SQLite. Laundered names will be converted to lower case and some special " 1391 "characters(' - #) will be changed to underscores." ),
1395 layerOptions.insert(
"SPATIAL_INDEX",
new BoolOption(
1396 QObject::tr(
"If the database is of the SpatiaLite flavour, and if OGR is linked " 1397 "against libspatialite, this option can be used to control if a spatial " 1398 "index must be created." ),
1402 layerOptions.insert(
"COMPRESS_GEOM",
new BoolOption(
1403 QObject::tr(
"If the format of the geometry BLOB is of the SpatiaLite flavour, " 1404 "this option can be used to control if the compressed format for " 1405 "geometries (LINESTRINGs, POLYGONs) must be used" ),
1410 QObject::tr(
"Used to force the SRID number of the SRS associated with the layer. " 1411 "When this option isn't specified and that a SRS is associated with the " 1412 "layer, a search is made in the spatial_ref_sys to find a match for the " 1413 "SRS, and, if there is no match, a new entry is inserted for the SRS in " 1414 "the spatial_ref_sys table. When the SRID option is specified, this " 1415 "search (and the eventual insertion of a new entry) will not be done: " 1416 "the specified SRID is used as such." ),
1420 layerOptions.insert(
"COMPRESS_COLUMNS",
new StringOption(
1421 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that " 1422 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial " 1423 "for databases that have big string blobs. However, use with care, since " 1424 "the value of such columns will be seen as compressed binary content with " 1425 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, " 1426 "modifying or queryings compressed columns, compression/decompression is " 1427 "done transparently. However, such columns cannot be (easily) queried with " 1428 "an attribute filter or WHERE clause. Note: in table definition, such columns " 1429 "have the 'VARCHAR_deflate' declaration type." ),
1433 driverMetadata.insert(
"SpatiaLite",
1444 datasetOptions.clear();
1445 layerOptions.clear();
1449 QObject::tr(
"Override the header file used - in place of header.dxf." ),
1454 QObject::tr(
"Override the trailer file used - in place of trailer.dxf." ),
1459 driverMetadata.insert(
"DXF",
1471 datasetOptions.clear();
1472 layerOptions.clear();
1474 datasetOptions.insert(
"EXTENSION",
new SetOption(
1475 QObject::tr(
"Indicates the GeoConcept export file extension. " 1476 "TXT was used by earlier releases of GeoConcept. GXT is currently used." ),
1485 QObject::tr(
"path to the GCT : the GCT file describe the GeoConcept types definitions: " 1486 "In this file, every line must start with //# followed by a keyword. " 1487 "Lines starting with // are comments." ),
1492 driverMetadata.insert(
"Geoconcept",
1504 datasetOptions.clear();
1505 layerOptions.clear();
1507 layerOptions.insert(
"FEATURE_DATASET",
new StringOption(
1508 QObject::tr(
"When this option is set, the new layer will be created inside the named " 1509 "FeatureDataset folder. If the folder does not already exist, it will be created." ),
1513 layerOptions.insert(
"GEOMETRY_NAME",
new StringOption(
1514 QObject::tr(
"Set name of geometry column in new layer. Defaults to 'SHAPE'." ),
1519 QObject::tr(
"Name of the OID column to create. Defaults to 'OBJECTID'." ),
1523 driverMetadata.insert(
"FileGDB",
1538 static const QMap<QString, MetaData> sDriverMetadata = initMetaData();
1540 QMap<QString, MetaData>::ConstIterator it = sDriverMetadata.constBegin();
1542 for ( ; it != sDriverMetadata.constEnd(); ++it )
1544 if ( it.key().startsWith( driverName ) )
1546 driverMetadata = it.value();
1568 OGRFeatureH poFeature = createFeature( feature );
1577 QString styleString;
1578 QString currentStyle;
1580 QgsSymbolV2List::const_iterator symbolIt = symbols.constBegin();
1581 for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
1583 int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
1584 for (
int i = 0; i < nSymbolLayers; ++i )
1587 QMap< QgsSymbolLayerV2*, QString >::const_iterator it = mSymbolLayerTable.find(( *symbolIt )->symbolLayer( i ) );
1588 if ( it == mSymbolLayerTable.constEnd() )
1596 currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
1600 if ( symbolIt != symbols.constBegin() || i != 0 )
1602 styleString.append(
";" );
1604 styleString.append( currentStyle );
1608 OGR_F_SetStyleString( poFeature, currentStyle.toLocal8Bit().data() );
1609 if ( !writeFeature(
mLayer, poFeature ) )
1616 OGR_F_SetStyleString( poFeature, styleString.toLocal8Bit().data() );
1621 if ( !writeFeature(
mLayer, poFeature ) )
1627 OGR_F_Destroy( poFeature );
1631 OGRFeatureH QgsVectorFileWriter::createFeature(
QgsFeature& feature )
1635 OGRFeatureH poFeature = OGR_F_Create( OGR_L_GetLayerDefn(
mLayer ) );
1640 QgsDebugMsg( QString(
"feature id %1 too large." ).arg( fid ) );
1641 OGRErr err = OGR_F_SetFID( poFeature, static_cast<long>( fid ) );
1642 if ( err != OGRERR_NONE )
1644 QgsDebugMsg( QString(
"Failed to set feature id to %1: %2 (OGR error: %3)" )
1645 .arg( feature.
id() )
1646 .arg( err ).arg( CPLGetLastErrorMsg() )
1652 for (
int fldIdx = 0; fldIdx <
mFields.
count(); ++fldIdx )
1656 QgsDebugMsg( QString(
"no ogr field for field %1" ).arg( fldIdx ) );
1660 const QVariant& attrValue = feature.
attribute( fldIdx );
1663 if ( !attrValue.isValid() || attrValue.isNull() )
1666 switch ( attrValue.type() )
1669 OGR_F_SetFieldInteger( poFeature, ogrField, attrValue.toInt() );
1671 case QVariant::Double:
1672 OGR_F_SetFieldDouble( poFeature, ogrField, attrValue.toDouble() );
1674 case QVariant::LongLong:
1675 case QVariant::UInt:
1676 case QVariant::ULongLong:
1677 case QVariant::String:
1678 OGR_F_SetFieldString( poFeature, ogrField,
mCodec->fromUnicode( attrValue.toString() ).data() );
1680 case QVariant::Date:
1681 OGR_F_SetFieldDateTime( poFeature, ogrField,
1682 attrValue.toDate().year(),
1683 attrValue.toDate().month(),
1684 attrValue.toDate().day(),
1687 case QVariant::DateTime:
1688 OGR_F_SetFieldDateTime( poFeature, ogrField,
1689 attrValue.toDateTime().date().year(),
1690 attrValue.toDateTime().date().month(),
1691 attrValue.toDateTime().date().day(),
1692 attrValue.toDateTime().time().hour(),
1693 attrValue.toDateTime().time().minute(),
1694 attrValue.toDateTime().time().second(),
1697 case QVariant::Time:
1698 OGR_F_SetFieldDateTime( poFeature, ogrField,
1700 attrValue.toDateTime().time().hour(),
1701 attrValue.toDateTime().time().minute(),
1702 attrValue.toDateTime().time().second(),
1705 case QVariant::Invalid:
1709 .arg(
mFields[fldIdx].name() )
1711 .arg( attrValue.typeName() )
1712 .arg( attrValue.toString() );
1746 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1749 OGR_F_Destroy( poFeature );
1753 OGRErr err = OGR_G_ImportFromWkb( mGeom2, const_cast<unsigned char *>( geom->
asWkb() ), (
int ) geom->
wkbSize() );
1754 if ( err != OGRERR_NONE )
1757 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1760 OGR_F_Destroy( poFeature );
1765 OGR_F_SetGeometryDirectly( poFeature, mGeom2 );
1769 OGRErr err = OGR_G_ImportFromWkb(
mGeom, const_cast<unsigned char *>( geom->
asWkb() ), (
int ) geom->
wkbSize() );
1770 if ( err != OGRERR_NONE )
1773 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1776 OGR_F_Destroy( poFeature );
1781 OGR_F_SetGeometry( poFeature,
mGeom );
1787 bool QgsVectorFileWriter::writeFeature( OGRLayerH layer, OGRFeatureH feature )
1789 if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
1791 mErrorMessage =
QObject::tr(
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1794 OGR_F_Destroy( feature );
1804 OGR_G_DestroyGeometry(
mGeom );
1809 OGR_DS_Destroy(
mDS );
1814 OSRDestroySpatialReference(
mOgrRef );
1820 const QString& fileName,
1821 const QString& fileEncoding,
1823 const QString& driverName,
1826 const QStringList &datasourceOptions,
1827 const QStringList &layerOptions,
1828 bool skipAttributeCreation,
1829 QString *newFilename,
1831 double symbologyScale,
1835 if ( destCRS && layer )
1841 errorMessage, datasourceOptions, layerOptions, skipAttributeCreation, newFilename, symbologyExport, symbologyScale, filterExtent );
1847 const QString& fileName,
1848 const QString& fileEncoding,
1850 const QString& driverName,
1853 const QStringList &datasourceOptions,
1854 const QStringList &layerOptions,
1855 bool skipAttributeCreation,
1856 QString *newFilename,
1858 double symbologyScale,
1866 bool shallTransform =
false;
1871 outputCRS = &( ct->
destCRS() );
1872 shallTransform =
true;
1877 outputCRS = &layer->
crs();
1886 QString srcFileName = theURIParts[0];
1888 if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
1891 *errorMessage =
QObject::tr(
"Cannot overwrite a OGR layer in place" );
1903 if ( onlySelected && !ids.contains( fet.
id() ) )
1916 for (
int i = 0; i < fields.
size(); i++ )
1918 if ( fields[i].type() == QVariant::LongLong )
1922 if ( qMax( qAbs( min.toLongLong() ), qAbs( max.toLongLong() ) ) < INT_MAX )
1924 fields[i].setType( QVariant::Int );
1931 new QgsVectorFileWriter( fileName, fileEncoding, fields, wkbType, outputCRS, driverName, datasourceOptions, layerOptions, newFilename, symbologyExport );
1951 errorMessage->clear();
1958 writer->addRendererAttributes( layer, allAttr );
1988 int n = 0, errors = 0;
1997 writer->startRender( layer );
2000 bool transactionsEnabled =
true;
2002 if ( OGRERR_NONE != OGR_L_StartTransaction( writer->
mLayer ) )
2004 QgsDebugMsg(
"Error when trying to enable transactions on OGRLayer." );
2005 transactionsEnabled =
false;
2011 if ( onlySelected && !ids.contains( fet.
id() ) )
2014 if ( shallTransform )
2027 QString msg =
QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
2028 .arg( fet.
id() ).arg( e.
what() );
2031 *errorMessage = msg;
2040 if ( allAttr.size() < 1 && skipAttributeCreation )
2048 if ( err !=
NoError && errorMessage )
2050 if ( errorMessage->isEmpty() )
2052 *errorMessage =
QObject::tr(
"Feature write errors:" );
2058 if ( errors > 1000 )
2062 *errorMessage +=
QObject::tr(
"Stopping after %1 errors" ).arg( errors );
2072 if ( transactionsEnabled )
2074 if ( OGRERR_NONE != OGR_L_CommitTransaction( writer->
mLayer ) )
2076 QgsDebugMsg(
"Error while committing transaction on OGRLayer." );
2080 writer->stopRender( layer );
2083 if ( errors > 0 && errorMessage && n > 0 )
2085 *errorMessage +=
QObject::tr(
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
2094 QFileInfo fi( theFileName );
2095 QDir dir = fi.dir();
2098 const char *suffixes[] = {
".shp",
".shx",
".dbf",
".prj",
".qix",
".qpj" };
2099 for ( std::size_t i = 0; i <
sizeof( suffixes ) /
sizeof( *suffixes ); i++ )
2101 filter << fi.completeBaseName() + suffixes[i];
2105 foreach ( QString file, dir.entryList( filter ) )
2107 if ( !QFile::remove( dir.canonicalPath() +
"/" + file ) )
2119 QMap<QString, QString> resultMap;
2122 int const drvCount = OGRGetDriverCount();
2124 for (
int i = 0; i < drvCount; ++i )
2126 OGRSFDriverH drv = OGRGetDriver( i );
2129 QString drvName = OGR_Dr_GetName( drv );
2130 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2133 if ( filterString.isEmpty() )
2136 resultMap.insert( filterString, drvName );
2146 QMap<QString, QString> resultMap;
2149 int const drvCount = OGRGetDriverCount();
2151 QStringList writableDrivers;
2152 for (
int i = 0; i < drvCount; ++i )
2154 OGRSFDriverH drv = OGRGetDriver( i );
2157 QString drvName = OGR_Dr_GetName( drv );
2158 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2161 if ( drvName ==
"MapInfo File" )
2163 writableDrivers <<
"MapInfo MIF";
2165 else if ( drvName ==
"SQLite" )
2172 QString option =
"SPATIALITE=YES";
2173 char **options =
new char *[2];
2174 options[0] = CPLStrdup( option.toLocal8Bit().data() );
2176 OGRSFDriverH poDriver;
2178 poDriver = OGRGetDriverByName( drvName.toLocal8Bit().data() );
2181 OGRDataSourceH ds = OGR_Dr_CreateDataSource( poDriver,
TO8F( QString(
"/vsimem/spatialitetest.sqlite" ) ), options );
2184 writableDrivers <<
"SpatiaLite";
2185 OGR_Dr_DeleteDataSource( poDriver,
TO8F( QString(
"/vsimem/spatialitetest.sqlite" ) ) );
2186 OGR_DS_Destroy( ds );
2189 CPLFree( options[0] );
2192 else if ( drvName ==
"ESRI Shapefile" )
2194 writableDrivers <<
"DBF file";
2196 writableDrivers << drvName;
2201 foreach ( QString drvName, writableDrivers )
2209 resultMap.insert( trLongName, drvName );
2218 QString filterString;
2220 QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin();
2221 for ( ; it != driverFormatMap.constEnd(); ++it )
2223 if ( !filterString.isEmpty() )
2224 filterString +=
";;";
2226 filterString += it.key();
2228 return filterString;
2237 if ( !
driverMetadata( driverName, longName, trLongName, glob, exts ) || trLongName.isEmpty() || glob.isEmpty() )
2240 return trLongName +
" [OGR] (" + glob.toLower() +
" " + glob.toUpper() +
")";
2245 if ( codecName ==
"System" )
2246 return QString(
"LDID/0" );
2248 QRegExp re = QRegExp( QString(
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
2249 if ( re.exactMatch( codecName ) )
2251 QString c = re.cap( 2 ).replace(
"-",
"" );
2253 c.toInt( &isNumber );
2262 if ( driverName.startsWith(
"AVCE00" ) )
2264 longName =
"Arc/Info ASCII Coverage";
2265 trLongName =
QObject::tr(
"Arc/Info ASCII Coverage" );
2269 else if ( driverName.startsWith(
"BNA" ) )
2271 longName =
"Atlas BNA";
2276 else if ( driverName.startsWith(
"CSV" ) )
2278 longName =
"Comma Separated Value [CSV]";
2279 trLongName =
QObject::tr(
"Comma Separated Value [CSV]" );
2283 else if ( driverName.startsWith(
"ESRI" ) )
2285 longName =
"ESRI Shapefile";
2290 else if ( driverName.startsWith(
"DBF file" ) )
2292 longName =
"DBF File";
2297 else if ( driverName.startsWith(
"FMEObjects Gateway" ) )
2299 longName =
"FMEObjects Gateway";
2304 else if ( driverName.startsWith(
"GeoJSON" ) )
2306 longName =
"GeoJSON";
2311 else if ( driverName.startsWith(
"GeoRSS" ) )
2313 longName =
"GeoRSS";
2318 else if ( driverName.startsWith(
"GML" ) )
2320 longName =
"Geography Markup Language [GML]";
2321 trLongName =
QObject::tr(
"Geography Markup Language [GML]" );
2325 else if ( driverName.startsWith(
"GMT" ) )
2327 longName =
"Generic Mapping Tools [GMT]";
2328 trLongName =
QObject::tr(
"Generic Mapping Tools [GMT]" );
2332 else if ( driverName.startsWith(
"GPX" ) )
2334 longName =
"GPS eXchange Format [GPX]";
2335 trLongName =
QObject::tr(
"GPS eXchange Format [GPX]" );
2339 else if ( driverName.startsWith(
"Interlis 1" ) )
2341 longName =
"INTERLIS 1";
2343 glob =
"*.itf *.xml *.ili";
2346 else if ( driverName.startsWith(
"Interlis 2" ) )
2348 longName =
"INTERLIS 2";
2350 glob =
"*.itf *.xml *.ili";
2353 else if ( driverName.startsWith(
"KML" ) )
2355 longName =
"Keyhole Markup Language [KML]";
2356 trLongName =
QObject::tr(
"Keyhole Markup Language [KML]" );
2360 else if ( driverName.startsWith(
"MapInfo File" ) )
2362 longName =
"Mapinfo TAB";
2368 else if ( driverName.startsWith(
"MapInfo MIF" ) )
2370 longName =
"Mapinfo MIF";
2375 else if ( driverName.startsWith(
"DGN" ) )
2377 longName =
"Microstation DGN";
2382 else if ( driverName.startsWith(
"S57" ) )
2384 longName =
"S-57 Base file";
2389 else if ( driverName.startsWith(
"SDTS" ) )
2391 longName =
"Spatial Data Transfer Standard [SDTS]";
2392 trLongName =
QObject::tr(
"Spatial Data Transfer Standard [SDTS]" );
2396 else if ( driverName.startsWith(
"SQLite" ) )
2398 longName =
"SQLite";
2404 else if ( driverName.startsWith(
"SpatiaLite" ) )
2406 longName =
"SpatiaLite";
2411 else if ( driverName.startsWith(
"DXF" ) )
2413 longName =
"AutoCAD DXF";
2418 else if ( driverName.startsWith(
"Geoconcept" ) )
2420 longName =
"Geoconcept";
2422 glob =
"*.gxt *.txt";
2425 else if ( driverName.startsWith(
"FileGDB" ) )
2427 longName =
"ESRI FileGDB";
2460 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1700 2461 mSymbolLayerTable.clear();
2462 OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
2463 OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
2466 int nTotalLevels = 0;
2468 QgsSymbolV2List::iterator symbolIt = symbolList.begin();
2469 for ( ; symbolIt != symbolList.end(); ++symbolIt )
2474 int nLevels = ( *symbolIt )->symbolLayerCount();
2475 for (
int i = 0; i < nLevels; ++i )
2477 mSymbolLayerTable.insert(( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
2478 OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
2479 ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
2483 OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
2497 QHash< QgsSymbolV2*, QList<QgsFeature> > features;
2506 startRender( layer );
2524 QString msg =
QObject::tr(
"Failed to transform, writing stopped. (Exception: %1)" )
2528 *errorMessage = msg;
2535 if ( !featureSymbol )
2540 QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
2541 if ( it == features.end() )
2543 it = features.insert( featureSymbol, QList<QgsFeature>() );
2545 it.value().append( fet );
2551 for (
int i = 0; i < symbols.count(); i++ )
2557 if ( level < 0 || level >= 1000 )
2560 while ( level >= levels.count() )
2562 levels[level].append( item );
2567 int nTotalFeatures = 0;
2570 for (
int l = 0; l < levels.count(); l++ )
2573 for (
int i = 0; i < level.count(); i++ )
2576 QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
2577 if ( levelIt == features.end() )
2586 int llayer = item.
layer();
2587 QList<QgsFeature>& featureList = levelIt.value();
2588 QList<QgsFeature>::iterator featureIt = featureList.begin();
2589 for ( ; featureIt != featureList.end(); ++featureIt )
2592 OGRFeatureH ogrFeature = createFeature( *featureIt );
2599 QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
2600 if ( !styleString.isEmpty() )
2602 OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
2603 if ( !writeFeature(
mLayer, ogrFeature ) )
2608 OGR_F_Destroy( ogrFeature );
2613 stopRender( layer );
2615 if ( nErrors > 0 && errorMessage )
2617 *errorMessage +=
QObject::tr(
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
2634 return 1000 / scaleDenominator;
2651 return scaleDenominator / 1000;
2664 void QgsVectorFileWriter::startRender(
QgsVectorLayer* vl )
const 2708 for (
int i = 0; i < rendererAttributes.size(); ++i )
2713 attList.push_back( vl->
fieldNameIndex( rendererAttributes.at( i ) ) );
QgsFeatureId id() const
Get the feature id for this feature.
static WkbType singleType(WkbType type)
const QString & name() const
Gets the name of the field.
Wrapper for iterator of features from vector data provider or vector layer.
QgsFeatureRendererV2 * rendererV2()
Return renderer V2.
A rectangle specified with double values.
static QMap< QString, QString > supportedFiltersAndFormats()
Returns map with format filter string as key and OGR format key as value.
SymbologyExport symbologyExport() const
QList< QgsSymbolV2 * > QgsSymbolV2List
WriterError mError
contains error value if construction was not successful
QVariant maximumValue(int index)
Returns maximum value for an attribute column or invalid variant in case of error.
size_t wkbSize() const
Returns the size of the WKB in asWkb().
static QString fileFilterString()
Returns filter string that can be used for dialogs.
QSet< QgsFeatureId > QgsFeatureIds
SymbologyExport mSymbologyExport
double mSymbologyScaleDenominator
Scale for symbology export (e.g.
static void warning(const QString &msg)
Goes to qWarning.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
void setRendererScale(double scale)
int precision() const
Gets the precision of the field.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
static void registerOgrDrivers()
Register OGR drivers ensuring this only happens once.
static bool deleteShapeFile(QString theFileName)
Delete a shapefile (and its accompanying shx / dbf / prf)
Container of fields for a vector layer.
WkbType
Used for symbology operations.
virtual QList< QString > usedAttributes()=0
A convenience class for writing vector files to disk.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QVariant minimumValue(int index)
Returns minimum value for an attribute column or invalid variant in case of error.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
virtual void stopRender(QgsRenderContext &context)=0
virtual QgsSymbolV2List symbols()=0
for symbol levels
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
#define FID_TO_NUMBER(fid)
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
~QgsVectorFileWriter()
close opened shapefile for writing
QList< int > QgsAttributeList
int symbolLayerCount()
Returns total number of symbol layers contained in the symbol.
bool addFeature(QgsFeature &feature, QgsFeatureRendererV2 *renderer=0, QGis::UnitType outputUnit=QGis::Meters)
add feature to the currently opened shapefile
int count() const
Return number of items.
QGis::WkbType wkbType() const
Returns type of wkb (point / linestring / polygon etc.)
QGis::WkbType mWkbType
geometry type which is being used
Encapsulate a field in an attribute table or data source.
QMap< int, int > mAttrIdxToOgrIdx
map attribute indizes to OGR field indexes
OGRSpatialReferenceH mOgrRef
QList< QgsSymbolV2LevelItem > QgsSymbolV2Level
int renderingPass() const
static QMap< QString, QString > ogrDriverList()
Returns driver list that can be used for dialogs.
QString errorMessage()
retrieves error message
QString providerType() const
Return the provider type for this layer.
Contains information about the context of a rendering operation.
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.
WriterError hasError()
checks whether there were any errors in constructor
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
QgsAttributeList pendingAllAttributesList()
returns list of attributes
QgsVectorFileWriter(const QString &vectorFileName, const QString &fileEncoding, const QgsFields &fields, QGis::WkbType geometryType, const QgsCoordinateReferenceSystem *srs, const QString &driverName="ESRI Shapefile", const QStringList &datasourceOptions=QStringList(), const QStringList &layerOptions=QStringList(), QString *newFilename=0, SymbologyExport symbologyExport=NoSymbology)
create shapefile and initialize it
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat)
return list of symbols used for rendering the feature.
void setSymbologyScaleDenominator(double d)
bool usingSymbolLevels() const
Class for storing a coordinate reference system (CRS)
int length() const
Gets the length of the field.
int size() const
Return number of items.
UnitType
Map units that qgis supports.
int transform(const QgsCoordinateTransform &ct)
Transform this geometry as described by CoordinateTransform ct.
QList< QgsSymbolV2Level > QgsSymbolV2LevelOrder
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
Custom exception class for Coordinate Reference System related exceptions.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
QgsSymbolLayerV2 * symbolLayer(int layer)
Returns a specific symbol layers contained in the symbol.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
virtual int capabilities()
returns bitwise OR-ed capabilities of the renderer
bool nextFeature(QgsFeature &f)
Geometry is not required. It may still be returned if e.g. required for a filter condition.
bool intersects(const QgsRectangle &r) const
Test for intersection with a rectangle (uses GEOS)
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature)=0
to be overridden
QgsFeatureRequest & setFlags(Flags flags)
Set flags that affect how features will be fetched.
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
OGRGeometryH createEmptyGeometry(QGis::WkbType wkbType)
static WriterError writeAsVectorFormat(QgsVectorLayer *layer, const QString &fileName, const QString &fileEncoding, const QgsCoordinateReferenceSystem *destCRS, const QString &driverName="ESRI Shapefile", bool onlySelected=false, QString *errorMessage=0, const QStringList &datasourceOptions=QStringList(), const QStringList &layerOptions=QStringList(), bool skipAttributeCreation=false, QString *newFilename=0, SymbologyExport symbologyExport=NoSymbology, double symbologyScale=1.0, const QgsRectangle *filterExtent=0)
Write contents of vector layer to an (OGR supported) vector formt.
static QString filterForDriver(const QString &driverName)
Creates a filter for an OGR driver key.
virtual QString dataSourceUri() const
Get the data source specification.
static WkbType multiType(WkbType type)
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
static bool driverMetadata(const QString &driverName, MetaData &driverMetadata)
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
QGis::UnitType mapUnits() const