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,
73 , mSymbologyExport( symbologyExport )
75 QString vectorFileName = theVectorFileName;
76 QString fileEncoding = theFileEncoding;
77 QStringList layOptions = layerOptions;
78 QStringList dsOptions = datasourceOptions;
80 QString ogrDriverName;
81 if ( driverName ==
"MapInfo MIF" )
83 ogrDriverName =
"MapInfo File";
85 else if ( driverName ==
"SpatiaLite" )
87 ogrDriverName =
"SQLite";
88 if ( !dsOptions.contains(
"SPATIALITE=YES" ) )
90 dsOptions.append(
"SPATIALITE=YES" );
93 else if ( driverName ==
"DBF file" )
95 ogrDriverName =
"ESRI Shapefile";
96 if ( !layOptions.contains(
"SHPT=NULL" ) )
98 layOptions.append(
"SHPT=NULL" );
104 ogrDriverName = driverName;
108 OGRSFDriverH poDriver;
111 poDriver = OGRGetDriverByName( ogrDriverName.toLocal8Bit().data() );
117 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
122 if ( ogrDriverName ==
"ESRI Shapefile" )
124 if ( layOptions.join(
"" ).toUpper().indexOf(
"ENCODING=" ) == -1 )
129 if ( driverName ==
"ESRI Shapefile" && !vectorFileName.endsWith(
".shp", Qt::CaseInsensitive ) )
131 vectorFileName +=
".shp";
133 else if ( driverName ==
"DBF file" && !vectorFileName.endsWith(
".dbf", Qt::CaseInsensitive ) )
135 vectorFileName +=
".dbf";
138 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM < 1700
140 QSet<QString> fieldNames;
141 for (
int i = 0; i < fields.
count(); ++i )
143 QString name = fields[i].name().left( 10 );
144 if ( fieldNames.contains( name ) )
146 mErrorMessage =
QObject::tr(
"trimming attribute name '%1' to ten significant characters produces duplicate column name." )
147 .arg( fields[i].name() );
157 else if ( driverName ==
"KML" )
159 if ( !vectorFileName.endsWith(
".kml", Qt::CaseInsensitive ) )
161 vectorFileName +=
".kml";
164 if ( fileEncoding.compare(
"UTF-8", Qt::CaseInsensitive ) != 0 )
167 fileEncoding =
"UTF-8";
170 QFile::remove( vectorFileName );
180 QStringList allExts = exts.split(
" ", QString::SkipEmptyParts );
182 foreach ( QString ext, allExts )
184 if ( vectorFileName.endsWith(
"." + ext, Qt::CaseInsensitive ) )
193 vectorFileName +=
"." + allExts[0];
197 QFile::remove( vectorFileName );
200 char **options = NULL;
201 if ( !dsOptions.isEmpty() )
203 options =
new char *[ dsOptions.size()+1 ];
204 for (
int i = 0; i < dsOptions.size(); i++ )
206 options[i] = CPLStrdup( dsOptions[i].toLocal8Bit().data() );
208 options[ dsOptions.size()] = NULL;
212 mDS = OGR_Dr_CreateDataSource( poDriver,
TO8F( vectorFileName ), options );
216 for (
int i = 0; i < dsOptions.size(); i++ )
217 CPLFree( options[i] );
226 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
233 mCodec = QTextCodec::codecForName( fileEncoding.toLocal8Bit().constData() );
236 QgsDebugMsg(
"error finding QTextCodec for " + fileEncoding );
239 QString enc = settings.value(
"/UI/encoding",
"System" ).toString();
240 mCodec = QTextCodec::codecForName( enc.toLocal8Bit().constData() );
243 QgsDebugMsg(
"error finding QTextCodec for " + enc );
244 mCodec = QTextCodec::codecForLocale();
253 QString srsWkt = srs->
toWkt();
255 ogrRef = OSRNewSpatialReference( srsWkt.toLocal8Bit().data() );
259 QString layerName = QFileInfo( vectorFileName ).baseName();
260 OGRwkbGeometryType wkbType =
static_cast<OGRwkbGeometryType
>( geometryType );
262 if ( !layOptions.isEmpty() )
264 options =
new char *[ layOptions.size()+1 ];
265 for (
int i = 0; i < layOptions.size(); i++ )
267 options[i] = CPLStrdup( layOptions[i].toLocal8Bit().data() );
269 options[ layOptions.size()] = NULL;
273 CPLSetConfigOption(
"SHAPE_ENCODING",
"" );
275 mLayer = OGR_DS_CreateLayer(
mDS,
TO8F( layerName ), ogrRef, wkbType, options );
279 for (
int i = 0; i < layOptions.size(); i++ )
280 CPLFree( options[i] );
286 if ( !settings.value(
"/qgis/ignoreShapeEncoding",
true ).toBool() )
288 CPLSetConfigOption(
"SHAPE_ENCODING", 0 );
293 if ( ogrDriverName ==
"ESRI Shapefile" )
295 QString layerName = vectorFileName.left( vectorFileName.indexOf(
".shp", Qt::CaseInsensitive ) );
296 QFile prjFile( layerName +
".qpj" );
297 if ( prjFile.open( QIODevice::WriteOnly ) )
299 QTextStream prjStream( &prjFile );
300 prjStream << srs->
toWkt().toLocal8Bit().data() << endl;
305 QgsDebugMsg(
"Couldn't open file " + layerName +
".qpj" );
309 OSRDestroySpatialReference( ogrRef );
315 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
320 OGRFeatureDefnH defn = OGR_L_GetLayerDefn(
mLayer );
325 QgsDebugMsg(
"creating " + QString::number( fields.
size() ) +
" fields" );
330 for (
int fldIdx = 0; fldIdx < fields.
count(); ++fldIdx )
332 const QgsField& attrField = fields[fldIdx];
334 OGRFieldType ogrType = OFTString;
335 int ogrWidth = attrField.
length();
336 int ogrPrecision = attrField.
precision();
337 switch ( attrField.
type() )
339 case QVariant::LongLong:
341 ogrWidth = ogrWidth > 0 && ogrWidth <= 21 ? ogrWidth : 21;
345 case QVariant::String:
347 if ( ogrWidth <= 0 || ogrWidth > 255 )
352 ogrType = OFTInteger;
353 ogrWidth = ogrWidth > 0 && ogrWidth <= 10 ? ogrWidth : 10;
357 case QVariant::Double:
365 case QVariant::DateTime:
366 ogrType = OFTDateTime;
372 .arg( attrField.
name() );
377 QString name( attrField.
name() );
379 if ( ogrDriverName ==
"SQLite" && name.compare(
"ogc_fid", Qt::CaseInsensitive ) == 0 )
382 for ( i = 0; i < 10; i++ )
384 name = QString(
"ogc_fid%1" ).arg( i );
387 for ( j = 0; j < fields.
size() && name.compare( fields[j].name(), Qt::CaseInsensitive ) != 0; j++ )
390 if ( j == fields.
size() )
405 OGRFieldDefnH fld = OGR_Fld_Create(
mCodec->fromUnicode( name ), ogrType );
408 OGR_Fld_SetWidth( fld, ogrWidth );
411 if ( ogrPrecision >= 0 )
413 OGR_Fld_SetPrecision( fld, ogrPrecision );
418 " type " + QString( QVariant::typeToName( attrField.
type() ) ) +
419 " width " + QString::number( ogrWidth ) +
420 " precision " + QString::number( ogrPrecision ) );
421 if ( OGR_L_CreateField(
mLayer, fld,
true ) != OGRERR_NONE )
425 .arg( attrField.
name() )
426 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
428 OGR_Fld_Destroy( fld );
431 OGR_Fld_Destroy( fld );
433 int ogrIdx = OGR_FD_GetFieldIndex( defn,
mCodec->fromUnicode( name ) );
436 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM < 1700
439 int fieldCount = OGR_FD_GetFieldCount( defn );
441 OGRFieldDefnH fdefn = OGR_FD_GetFieldDefn( defn, fieldCount - 1 );
444 const char *fieldName = OGR_Fld_GetNameRef( fdefn );
446 if ( attrField.
name().left( strlen( fieldName ) ) == fieldName )
448 ogrIdx = fieldCount - 1;
453 ogrIdx = OGR_FD_GetFieldCount( defn ) - 1;
460 .arg( attrField.
name() )
461 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
480 *newFilename = vectorFileName;
485 return OGR_G_CreateGeometry(( OGRwkbGeometryType ) wkbType );
492 QMap<QString, Option*> datasetOptions;
493 QMap<QString, Option*> layerOptions;
496 datasetOptions.clear();
497 layerOptions.clear();
499 driverMetadata.insert(
"AVCE00",
501 "Arc/Info ASCII Coverage",
511 datasetOptions.clear();
512 layerOptions.clear();
514 datasetOptions.insert(
"LINEFORMAT",
new SetOption(
516 "systems default line termination conventions. "
517 "This may be overridden here." ),
525 datasetOptions.insert(
"MULTILINE",
new BoolOption(
526 QObject::tr(
"By default, BNA files are created in multi-line format. "
527 "For each record, the first line contains the identifiers and the "
528 "type/number of coordinates to follow. Each following line contains "
529 "a pair of coordinates." )
533 datasetOptions.insert(
"NB_IDS",
new SetOption(
534 QObject::tr(
"BNA records may contain from 2 to 4 identifiers per record. "
535 "Some software packages only support a precise number of identifiers. "
536 "You can override the default value (2) by a precise value" ),
541 <<
"NB_SOURCE_FIELDS"
545 datasetOptions.insert(
"ELLIPSES_AS_ELLIPSES",
new BoolOption(
546 QObject::tr(
"The BNA writer will try to recognize ellipses and circles when writing a polygon. "
547 "This will only work if the feature has previously been read from a BNA file. "
548 "As some software packages do not support ellipses/circles in BNA data file, "
549 "it may be useful to tell the writer by specifying ELLIPSES_AS_ELLIPSES=NO not "
550 "to export them as such, but keep them as polygons." )
554 datasetOptions.insert(
"NB_PAIRS_PER_LINE",
new IntOption(
555 QObject::tr(
"Limit the number of coordinate pairs per line in multiline format." )
559 datasetOptions.insert(
"COORDINATE_PRECISION",
new IntOption(
560 QObject::tr(
"Set the number of decimal for coordinates. Default value is 10." )
564 driverMetadata.insert(
"BNA",
576 datasetOptions.clear();
577 layerOptions.clear();
579 layerOptions.insert(
"LINEFORMAT",
new SetOption(
580 QObject::tr(
"By default when creating new .csv files they "
581 "are created with the line termination conventions "
582 "of the local platform (CR/LF on win32 or LF on all other systems). "
583 "This may be overridden through use of the LINEFORMAT option." ),
591 layerOptions.insert(
"GEOMETRY",
new SetOption(
592 QObject::tr(
"By default, the geometry of a feature written to a .csv file is discarded. "
593 "It is possible to export the geometry in its WKT representation by "
594 "specifying GEOMETRY=AS_WKT. It is also possible to export point geometries "
595 "into their X,Y,Z components by specifying GEOMETRY=AS_XYZ, GEOMETRY=AS_XY "
596 "or GEOMETRY=AS_YX." ),
606 layerOptions.insert(
"CREATE_CSVT",
new BoolOption(
607 QObject::tr(
"Create the associated .csvt file to describe the type of each "
608 "column of the layer and its optional width and precision." )
612 layerOptions.insert(
"SEPARATOR",
new SetOption(
613 QObject::tr(
"Field separator character. Default value : COMMA" ),
621 layerOptions.insert(
"WRITE_BOM",
new BoolOption(
622 QObject::tr(
"Write a UTF-8 Byte Order Mark (BOM) at the start of the file." )
626 driverMetadata.insert(
"CSV",
628 "Comma Separated Value",
638 datasetOptions.clear();
639 layerOptions.clear();
641 layerOptions.insert(
"SHPT",
new SetOption(
642 QObject::tr(
"Override the type of shapefile created. "
643 "Can be one of NULL for a simple .dbf file with no .shp file, POINT, "
644 "ARC, POLYGON or MULTIPOINT for 2D, or POINTZ, ARCZ, POLYGONZ or "
645 "MULTIPOINTZ for 3D. Shapefiles with measure values are not supported, "
646 "nor are MULTIPATCH files." ),
660 layerOptions.insert(
"ENCODING",
new SetOption(
661 QObject::tr(
"set the encoding value in the DBF file. "
662 "The default value is LDID/87. It is not clear "
663 "what other values may be appropriate." ),
669 layerOptions.insert(
"RESIZE",
new BoolOption(
670 QObject::tr(
"Set to YES to resize fields to their optimal size." )
674 driverMetadata.insert(
"ESRI",
686 datasetOptions.clear();
687 layerOptions.clear();
689 driverMetadata.insert(
"DBF File",
701 datasetOptions.clear();
702 layerOptions.clear();
704 driverMetadata.insert(
"FMEObjects Gateway",
706 "FMEObjects Gateway",
716 datasetOptions.clear();
717 layerOptions.clear();
719 layerOptions.insert(
"WRITE_BBOX",
new BoolOption(
720 QObject::tr(
"Set to YES to write a bbox property with the bounding box "
721 "of the geometries at the feature and feature collection level." )
725 layerOptions.insert(
"COORDINATE_PRECISION",
new IntOption(
726 QObject::tr(
"Maximum number of figures after decimal separator to write in coordinates. "
727 "Default to 15. Truncation will occur to remove trailing zeros." )
731 driverMetadata.insert(
"GeoJSON",
743 datasetOptions.clear();
744 layerOptions.clear();
746 datasetOptions.insert(
"FORMAT",
new SetOption(
747 QObject::tr(
"whether the document must be in RSS 2.0 or Atom 1.0 format. "
748 "Default value : RSS" ),
755 datasetOptions.insert(
"GEOM_DIALECT",
new SetOption(
756 QObject::tr(
"The encoding of location information. Default value : SIMPLE. "
757 "W3C_GEO only supports point geometries. "
758 "SIMPLE or W3C_GEO only support geometries in geographic WGS84 coordinates." ),
766 datasetOptions.insert(
"USE_EXTENSIONS",
new BoolOption(
767 QObject::tr(
"If defined to YES, extension fields will be written. "
768 "If the field name not found in the base schema matches "
769 "the foo_bar pattern, foo will be considered as the namespace "
770 "of the element, and a <foo:bar> element will be written. "
771 "Otherwise, elements will be written in the <ogr:> namespace." )
775 datasetOptions.insert(
"WRITE_HEADER_AND_FOOTER",
new BoolOption(
776 QObject::tr(
"If defined to NO, only <entry> or <item> elements will be written. "
777 "The user will have to provide the appropriate header and footer of the document." )
782 QObject::tr(
"XML content that will be put between the <channel> element and the "
783 "first <item> element for a RSS document, or between the xml tag and "
784 "the first <entry> element for an Atom document. " )
789 QObject::tr(
"Value put inside the <title> element in the header. "
790 "If not provided, a dummy value will be used as that element is compulsory." )
795 QObject::tr(
"Value put inside the <description> element in the header. "
796 "If not provided, a dummy value will be used as that element is compulsory." )
801 QObject::tr(
"Value put inside the <link> element in the header. "
802 "If not provided, a dummy value will be used as that element is compulsory." )
807 QObject::tr(
"Value put inside the <updated> element in the header. "
808 "Should be formatted as a XML datetime. "
809 "If not provided, a dummy value will be used as that element is compulsory." )
814 QObject::tr(
"Value put inside the <author><name> element in the header. "
815 "If not provided, a dummy value will be used as that element is compulsory." )
820 QObject::tr(
"Value put inside the <id> element in the header. "
821 "If not provided, a dummy value will be used as that element is compulsory." )
825 driverMetadata.insert(
"GeoRSS",
837 datasetOptions.clear();
838 layerOptions.clear();
840 datasetOptions.insert(
"XSISCHEMAURI",
new StringOption(
841 QObject::tr(
"If provided, this URI will be inserted as the schema location. "
842 "Note that the schema file isn't actually accessed by OGR, so it "
843 "is up to the user to ensure it will match the schema of the OGR "
844 "produced GML data file." )
848 datasetOptions.insert(
"XSISCHEMA",
new SetOption(
849 QObject::tr(
"This writes a GML application schema file to a corresponding "
850 ".xsd file (with the same basename). If INTERNAL is used the "
851 "schema is written within the GML file, but this is experimental "
852 "and almost certainly not valid XML. "
853 "OFF disables schema generation (and is implicit if XSISCHEMAURI is used)." ),
862 QObject::tr(
"This is the prefix for the application target namespace." )
866 datasetOptions.insert(
"STRIP_PREFIX",
new BoolOption(
867 QObject::tr(
"Can be set to TRUE to avoid writing the prefix of the "
868 "application target namespace in the GML file." )
872 datasetOptions.insert(
"TARGET_NAMESPACE",
new StringOption(
873 QObject::tr(
"Defaults to 'http://ogr.maptools.org/'. "
874 "This is the application target namespace." )
875 ,
"http://ogr.maptools.org/"
878 datasetOptions.insert(
"FORMAT",
new SetOption(
879 QObject::tr(
"If not specified, GML2 will be used." ),
888 datasetOptions.insert(
"GML3_LONGSRS",
new BoolOption(
889 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. "
890 "If YES, SRS with EPSG authority will be written with the "
891 "'urn:ogc:def:crs:EPSG::' prefix. In the case, if the SRS is a "
892 "geographic SRS without explicit AXIS order, but that the same "
893 "SRS authority code imported with ImportFromEPSGA() should be "
894 "treated as lat/long, then the function will take care of coordinate "
895 "order swapping. If set to NO, SRS with EPSG authority will be "
896 "written with the 'EPSG:' prefix, even if they are in lat/long order." )
900 datasetOptions.insert(
"WRITE_FEATURE_BOUNDED_BY",
new BoolOption(
901 QObject::tr(
"only valid when FORMAT=GML3/GML3Degree/GML3.2) Default to YES. "
902 "If set to NO, the <gml:boundedBy> element will not be written for "
907 datasetOptions.insert(
"SPACE_INDENTATION",
new BoolOption(
908 QObject::tr(
"Default to YES. If YES, the output will be indented with spaces "
909 "for more readability, but at the expense of file size." )
914 driverMetadata.insert(
"GML",
916 "Geography Markup Language [GML]",
926 datasetOptions.clear();
927 layerOptions.clear();
929 driverMetadata.insert(
"GMT",
931 "Generic Mapping Tools [GMT]",
941 datasetOptions.clear();
942 layerOptions.clear();
944 layerOptions.insert(
"FORCE_GPX_TRACK",
new BoolOption(
945 QObject::tr(
"By default when writing a layer whose features are of "
946 "type wkbLineString, the GPX driver chooses to write "
947 "them as routes. If FORCE_GPX_TRACK=YES is specified, "
948 "they will be written as tracks." )
952 layerOptions.insert(
"FORCE_GPX_ROUTE",
new BoolOption(
953 QObject::tr(
"By default when writing a layer whose features are of "
954 "type wkbMultiLineString, the GPX driver chooses to write "
955 "them as tracks. If FORCE_GPX_ROUTE=YES is specified, "
956 "they will be written as routes, provided that the multilines "
957 "are composed of only one single line." )
961 datasetOptions.insert(
"GPX_USE_EXTENSIONS",
new BoolOption(
962 QObject::tr(
"If GPX_USE_EXTENSIONS=YES is specified, "
963 "extra fields will be written inside the <extensions> tag." )
967 datasetOptions.insert(
"GPX_EXTENSIONS_NS",
new StringOption(
968 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS_URL "
969 "is set. The namespace value used for extension tags. By default, 'ogr'." )
973 datasetOptions.insert(
"GPX_EXTENSIONS_NS_URL",
new StringOption(
974 QObject::tr(
"Only used if GPX_USE_EXTENSIONS=YES and GPX_EXTENSIONS_NS "
975 "is set. The namespace URI. By default, 'http://osgeo.org/gdal'." )
976 ,
"http://osgeo.org/gdal"
979 datasetOptions.insert(
"LINEFORMAT",
new SetOption(
980 QObject::tr(
"By default files are created with the line termination "
981 "conventions of the local platform (CR/LF on win32 or LF "
982 "on all other systems). This may be overridden through use "
983 "of the LINEFORMAT layer creation option which may have a value "
984 "of CRLF (DOS format) or LF (Unix format)." ),
992 driverMetadata.insert(
"GPX",
994 "GPS eXchange Format [GPX]",
1004 datasetOptions.clear();
1005 layerOptions.clear();
1007 driverMetadata.insert(
"Interlis 1",
1011 "*.itf *.xml *.ili",
1019 datasetOptions.clear();
1020 layerOptions.clear();
1022 driverMetadata.insert(
"Interlis 2",
1026 "*.itf *.xml *.ili",
1034 datasetOptions.clear();
1035 layerOptions.clear();
1038 QObject::tr(
"Allows you to specify the field to use for the KML <name> element. " )
1042 datasetOptions.insert(
"DescriptionField",
new StringOption(
1043 QObject::tr(
"Allows you to specify the field to use for the KML <description> element." )
1047 datasetOptions.insert(
"AltitudeMode",
new SetOption(
1048 QObject::tr(
"Allows you to specify the AltitudeMode to use for KML geometries. "
1049 "This will only affect 3D geometries and must be one of the valid KML options." ),
1051 <<
"relativeToGround"
1054 ,
"relativeToGround"
1057 driverMetadata.insert(
"KML",
1059 "Keyhole Markup Language [KML]",
1069 datasetOptions.clear();
1070 layerOptions.clear();
1072 layerOptions.insert(
"SPATIAL_INDEX_MODE",
new SetOption(
1073 QObject::tr(
"Use this to turn on 'quick spatial index mode'. "
1074 "In this mode writing files can be about 5 times faster, "
1075 "but spatial queries can be up to 30 times slower." ),
1082 driverMetadata.insert(
"MapInfo File",
1094 driverMetadata.insert(
"MapInfo MIF",
1106 datasetOptions.clear();
1107 layerOptions.clear();
1110 QObject::tr(
"Determine whether 2D (seed_2d.dgn) or 3D (seed_3d.dgn) "
1111 "seed file should be used. This option is ignored if the SEED option is provided." )
1120 datasetOptions.insert(
"COPY_WHOLE_SEED_FILE",
new BoolOption(
1121 QObject::tr(
"Indicate whether the whole seed file should be copied. "
1122 "If not, only the first three elements will be copied." )
1126 datasetOptions.insert(
"COPY_SEED_FILE_COLOR_TABLEE",
new BoolOption(
1127 QObject::tr(
"Indicates whether the color table should be copied from the seed file." )
1131 datasetOptions.insert(
"MASTER_UNIT_NAME",
new StringOption(
1132 QObject::tr(
"Override the master unit name from the seed file with "
1133 "the provided one or two character unit name." )
1137 datasetOptions.insert(
"SUB_UNIT_NAME",
new StringOption(
1138 QObject::tr(
"Override the sub unit name from the seed file with the provided "
1139 "one or two character unit name." )
1143 datasetOptions.insert(
"SUB_UNITS_PER_MASTER_UNIT",
new IntOption(
1144 QObject::tr(
"Override the number of subunits per master unit. "
1145 "By default the seed file value is used." )
1149 datasetOptions.insert(
"UOR_PER_SUB_UNIT",
new IntOption(
1150 QObject::tr(
"Override the number of UORs (Units of Resolution) "
1151 "per sub unit. By default the seed file value is used." )
1156 QObject::tr(
"ORIGIN=x,y,z: Override the origin of the design plane. "
1157 "By default the origin from the seed file is used." )
1161 driverMetadata.insert(
"DGN",
1173 datasetOptions.clear();
1174 layerOptions.clear();
1176 driverMetadata.insert(
"DGN",
1188 datasetOptions.clear();
1189 layerOptions.clear();
1191 datasetOptions.insert(
"UPDATES",
new SetOption(
1192 QObject::tr(
"Should update files be incorporated into the base data on the fly. " ),
1199 datasetOptions.insert(
"SPLIT_MULTIPOINT",
new BoolOption(
1200 QObject::tr(
"Should multipoint soundings be split into many single point sounding features. "
1201 "Multipoint geometries are not well handled by many formats, "
1202 "so it can be convenient to split single sounding features with many points "
1203 "into many single point features." )
1207 datasetOptions.insert(
"ADD_SOUNDG_DEPTH",
new BoolOption(
1208 QObject::tr(
"Should a DEPTH attribute be added on SOUNDG features and assign the depth "
1209 "of the sounding. This should only be enabled with SPLIT_MULTIPOINT is "
1214 datasetOptions.insert(
"RETURN_PRIMITIVES",
new BoolOption(
1215 QObject::tr(
"Should all the low level geometry primitives be returned as special "
1216 "IsolatedNode, ConnectedNode, Edge and Face layers." )
1220 datasetOptions.insert(
"PRESERVE_EMPTY_NUMBERS",
new BoolOption(
1221 QObject::tr(
"If enabled, numeric attributes assigned an empty string as a value will "
1222 "be preserved as a special numeric value. This option should not generally "
1223 "be needed, but may be useful when translated S-57 to S-57 losslessly." )
1227 datasetOptions.insert(
"LNAM_REFS",
new BoolOption(
1228 QObject::tr(
"Should LNAM and LNAM_REFS fields be attached to features capturing "
1229 "the feature to feature relationships in the FFPT group of the S-57 file." )
1233 datasetOptions.insert(
"RETURN_LINKAGES",
new BoolOption(
1234 QObject::tr(
"Should additional attributes relating features to their underlying "
1235 "geometric primitives be attached. These are the values of the FSPT group, "
1236 "and are primarily needed when doing S-57 to S-57 translations." )
1240 datasetOptions.insert(
"RECODE_BY_DSSI",
new BoolOption(
1241 QObject::tr(
"Should attribute values be recoded to UTF-8 from the character encoding "
1242 "specified in the S57 DSSI record." )
1248 driverMetadata.insert(
"S57",
1260 datasetOptions.clear();
1261 layerOptions.clear();
1263 driverMetadata.insert(
"SDTS",
1265 "Spatial Data Transfer Standard [SDTS]",
1266 QObject::tr(
"Spatial Data Transfer Standard [SDTS]" ),
1276 datasetOptions.clear();
1277 layerOptions.clear();
1279 datasetOptions.insert(
"METADATA",
new BoolOption(
1280 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys "
1281 "tables in a new database. By default these metadata tables are created "
1282 "when a new database is created." )
1292 datasetOptions.insert(
"INIT_WITH_EPSG",
new HiddenOption(
1296 layerOptions.insert(
"FORMAT",
new SetOption(
1297 QObject::tr(
"Controls the format used for the geometry column. Defaults to WKB."
1298 "This is generally more space and processing efficient, but harder "
1299 "to inspect or use in simple applications than WKT (Well Known Text)." ),
1306 layerOptions.insert(
"LAUNDER",
new BoolOption(
1307 QObject::tr(
"Controls whether layer and field names will be laundered for easier use "
1308 "in SQLite. Laundered names will be converted to lower case and some special "
1309 "characters(' - #) will be changed to underscores." )
1313 layerOptions.insert(
"SPATIAL_INDEX",
new HiddenOption(
1317 layerOptions.insert(
"COMPRESS_GEOM",
new HiddenOption(
1325 layerOptions.insert(
"COMPRESS_COLUMNS",
new StringOption(
1326 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that "
1327 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial "
1328 "for databases that have big string blobs. However, use with care, since "
1329 "the value of such columns will be seen as compressed binary content with "
1330 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, "
1331 "modifying or queryings compressed columns, compression/decompression is "
1332 "done transparently. However, such columns cannot be (easily) queried with "
1333 "an attribute filter or WHERE clause. Note: in table definition, such columns "
1334 "have the 'VARCHAR_deflate' declaration type." )
1338 driverMetadata.insert(
"SQLite",
1350 datasetOptions.clear();
1351 layerOptions.clear();
1353 datasetOptions.insert(
"METADATA",
new BoolOption(
1354 QObject::tr(
"Can be used to avoid creating the geometry_columns and spatial_ref_sys "
1355 "tables in a new database. By default these metadata tables are created "
1356 "when a new database is created." )
1364 datasetOptions.insert(
"INIT_WITH_EPSG",
new BoolOption(
1365 QObject::tr(
"Insert the content of the EPSG CSV files into the spatial_ref_sys table. "
1366 "Set to NO for regular SQLite databases." )
1374 layerOptions.insert(
"LAUNDER",
new BoolOption(
1375 QObject::tr(
"Controls whether layer and field names will be laundered for easier use "
1376 "in SQLite. Laundered names will be convered to lower case and some special "
1377 "characters(' - #) will be changed to underscores." )
1381 layerOptions.insert(
"SPATIAL_INDEX",
new BoolOption(
1382 QObject::tr(
"If the database is of the SpatiaLite flavour, and if OGR is linked "
1383 "against libspatialite, this option can be used to control if a spatial "
1384 "index must be created." )
1388 layerOptions.insert(
"COMPRESS_GEOM",
new BoolOption(
1389 QObject::tr(
"If the format of the geometry BLOB is of the SpatiaLite flavour, "
1390 "this option can be used to control if the compressed format for "
1391 "geometries (LINESTRINGs, POLYGONs) must be used" )
1396 QObject::tr(
"Used to force the SRID number of the SRS associated with the layer. "
1397 "When this option isn't specified and that a SRS is associated with the "
1398 "layer, a search is made in the spatial_ref_sys to find a match for the "
1399 "SRS, and, if there is no match, a new entry is inserted for the SRS in "
1400 "the spatial_ref_sys table. When the SRID option is specified, this "
1401 "search (and the eventual insertion of a new entry) will not be done: "
1402 "the specified SRID is used as such." )
1406 layerOptions.insert(
"COMPRESS_COLUMNS",
new StringOption(
1407 QObject::tr(
"column_name1[,column_name2, ...] A list of (String) columns that "
1408 "must be compressed with ZLib DEFLATE algorithm. This might be beneficial "
1409 "for databases that have big string blobs. However, use with care, since "
1410 "the value of such columns will be seen as compressed binary content with "
1411 "other SQLite utilities (or previous OGR versions). With OGR, when inserting, "
1412 "modifying or queryings compressed columns, compression/decompression is "
1413 "done transparently. However, such columns cannot be (easily) queried with "
1414 "an attribute filter or WHERE clause. Note: in table definition, such columns "
1415 "have the 'VARCHAR_deflate' declaration type." )
1419 driverMetadata.insert(
"SpatiaLite",
1430 datasetOptions.clear();
1431 layerOptions.clear();
1443 driverMetadata.insert(
"DXF",
1455 datasetOptions.clear();
1456 layerOptions.clear();
1458 datasetOptions.insert(
"EXTENSION",
new SetOption(
1459 QObject::tr(
"Indicates the GeoConcept export file extension. "
1460 "TXT was used by earlier releases of GeoConcept. GXT is currently used." ),
1474 driverMetadata.insert(
"Geoconcept",
1486 datasetOptions.clear();
1487 layerOptions.clear();
1489 layerOptions.insert(
"FEATURE_DATASET",
new StringOption(
1490 QObject::tr(
"When this option is set, the new layer will be created inside the named "
1491 "FeatureDataset folder. If the folder does not already exist, it will be created." )
1495 layerOptions.insert(
"GEOMETRY_NAME",
new StringOption(
1496 QObject::tr(
"Set name of geometry column in new layer. Defaults to 'SHAPE'." )
1501 QObject::tr(
"Name of the OID column to create. Defaults to 'OBJECTID'." )
1505 driverMetadata.insert(
"FileGDB",
1522 QMap<QString, MetaData>::ConstIterator it = sDriverMetadata.constBegin();
1524 for ( ; it != sDriverMetadata.constEnd(); ++it )
1526 if ( it.key().startsWith( driverName ) )
1528 driverMetadata = it.value();
1557 QString styleString;
1558 QString currentStyle;
1560 QgsSymbolV2List::const_iterator symbolIt = symbols.constBegin();
1561 for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
1563 int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
1564 for (
int i = 0; i < nSymbolLayers; ++i )
1567 QMap< QgsSymbolLayerV2*, QString >::const_iterator it = mSymbolLayerTable.find(( *symbolIt )->symbolLayer( i ) );
1568 if ( it == mSymbolLayerTable.constEnd() )
1576 currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
1580 if ( symbolIt != symbols.constBegin() || i != 0 )
1582 styleString.append(
";" );
1584 styleString.append( currentStyle );
1588 OGR_F_SetStyleString( poFeature, currentStyle.toLocal8Bit().data() );
1596 OGR_F_SetStyleString( poFeature, styleString.toLocal8Bit().data() );
1607 OGR_F_Destroy( poFeature );
1613 OGRFeatureH poFeature = OGR_F_Create( OGR_L_GetLayerDefn(
mLayer ) );
1618 QgsDebugMsg( QString(
"feature id %1 too large." ).arg( fid ) );
1619 OGRErr err = OGR_F_SetFID( poFeature, static_cast<long>( fid ) );
1620 if ( err != OGRERR_NONE )
1622 QgsDebugMsg( QString(
"Failed to set feature id to %1: %2 (OGR error: %3)" )
1623 .arg( feature.
id() )
1624 .arg( err ).arg( CPLGetLastErrorMsg() )
1630 for (
int fldIdx = 0; fldIdx <
mFields.
count(); ++fldIdx )
1634 QgsDebugMsg( QString(
"no ogr field for field %1" ).arg( fldIdx ) );
1638 const QVariant& attrValue = feature.
attribute( fldIdx );
1641 if ( !attrValue.isValid() || attrValue.isNull() )
1644 switch ( attrValue.type() )
1647 OGR_F_SetFieldInteger( poFeature, ogrField, attrValue.toInt() );
1649 case QVariant::Double:
1650 OGR_F_SetFieldDouble( poFeature, ogrField, attrValue.toDouble() );
1652 case QVariant::LongLong:
1653 case QVariant::String:
1654 OGR_F_SetFieldString( poFeature, ogrField,
mCodec->fromUnicode( attrValue.toString() ).data() );
1656 case QVariant::Date:
1657 OGR_F_SetFieldDateTime( poFeature, ogrField,
1658 attrValue.toDate().year(),
1659 attrValue.toDate().month(),
1660 attrValue.toDate().day(),
1663 case QVariant::DateTime:
1664 OGR_F_SetFieldDateTime( poFeature, ogrField,
1665 attrValue.toDateTime().date().year(),
1666 attrValue.toDateTime().date().month(),
1667 attrValue.toDateTime().date().day(),
1668 attrValue.toDateTime().time().hour(),
1669 attrValue.toDateTime().time().minute(),
1670 attrValue.toDateTime().time().second(),
1673 case QVariant::Invalid:
1677 .arg(
mFields[fldIdx].name() )
1679 .arg( QMetaType::typeName( attrValue.type() ) )
1680 .arg( attrValue.toString() );
1714 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1717 OGR_F_Destroy( poFeature );
1721 OGRErr err = OGR_G_ImportFromWkb( mGeom2, const_cast<unsigned char *>( geom->
asWkb() ), (
int ) geom->
wkbSize() );
1722 if ( err != OGRERR_NONE )
1725 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1728 OGR_F_Destroy( poFeature );
1733 OGR_F_SetGeometryDirectly( poFeature, mGeom2 );
1737 OGRErr err = OGR_G_ImportFromWkb(
mGeom, const_cast<unsigned char *>( geom->
asWkb() ), (
int ) geom->
wkbSize() );
1738 if ( err != OGRERR_NONE )
1741 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1744 OGR_F_Destroy( poFeature );
1749 OGR_F_SetGeometry( poFeature,
mGeom );
1757 if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
1759 mErrorMessage =
QObject::tr(
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1762 OGR_F_Destroy( feature );
1772 OGR_G_DestroyGeometry(
mGeom );
1777 OGR_DS_Destroy(
mDS );
1783 const QString& fileName,
1784 const QString& fileEncoding,
1786 const QString& driverName,
1788 QString *errorMessage,
1789 const QStringList &datasourceOptions,
1790 const QStringList &layerOptions,
1791 bool skipAttributeCreation,
1792 QString *newFilename,
1794 double symbologyScale )
1797 if ( destCRS && layer )
1803 errorMessage, datasourceOptions, layerOptions, skipAttributeCreation, newFilename, symbologyExport, symbologyScale );
1809 const QString& fileName,
1810 const QString& fileEncoding,
1812 const QString& driverName,
1814 QString *errorMessage,
1815 const QStringList &datasourceOptions,
1816 const QStringList &layerOptions,
1817 bool skipAttributeCreation,
1818 QString *newFilename,
1820 double symbologyScale
1828 bool shallTransform =
false;
1833 outputCRS = &( ct->
destCRS() );
1834 shallTransform =
true;
1839 outputCRS = &layer->
crs();
1845 QString srcFileName = theURIParts[0];
1847 if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
1850 *errorMessage =
QObject::tr(
"Cannot overwrite a OGR layer in place" );
1876 errorMessage->clear();
1914 int n = 0, errors = 0;
1926 bool transactionsEnabled =
true;
1928 if ( OGRERR_NONE != OGR_L_StartTransaction( writer->
mLayer ) )
1930 QgsDebugMsg(
"Error when trying to enable transactions on OGRLayer." );
1931 transactionsEnabled =
false;
1937 if ( onlySelected && !ids.contains( fet.
id() ) )
1940 if ( shallTransform )
1954 QString msg =
QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
1955 .arg( fet.
id() ).arg( e.
what() );
1958 *errorMessage = msg;
1963 if ( allAttr.size() < 1 && skipAttributeCreation )
1971 if ( err !=
NoError && errorMessage )
1973 if ( errorMessage->isEmpty() )
1975 *errorMessage =
QObject::tr(
"Feature write errors:" );
1981 if ( errors > 1000 )
1985 *errorMessage +=
QObject::tr(
"Stopping after %1 errors" ).arg( errors );
1995 if ( transactionsEnabled )
1997 if ( OGRERR_NONE != OGR_L_CommitTransaction( writer->
mLayer ) )
1999 QgsDebugMsg(
"Error while committing transaction on OGRLayer." );
2006 if ( errors > 0 && errorMessage && n > 0 )
2008 *errorMessage +=
QObject::tr(
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
2017 QFileInfo fi( theFileName );
2018 QDir dir = fi.dir();
2021 const char *suffixes[] = {
".shp",
".shx",
".dbf",
".prj",
".qix",
".qpj" };
2022 for ( std::size_t i = 0; i <
sizeof( suffixes ) /
sizeof( *suffixes ); i++ )
2024 filter << fi.completeBaseName() + suffixes[i];
2028 foreach ( QString
file, dir.entryList( filter ) )
2030 if ( !QFile::remove( dir.canonicalPath() +
"/" +
file ) )
2042 QMap<QString, QString> resultMap;
2045 int const drvCount = OGRGetDriverCount();
2047 for (
int i = 0; i < drvCount; ++i )
2049 OGRSFDriverH drv = OGRGetDriver( i );
2052 QString drvName = OGR_Dr_GetName( drv );
2053 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2056 if ( filterString.isEmpty() )
2059 resultMap.insert( filterString, drvName );
2069 QMap<QString, QString> resultMap;
2072 int const drvCount = OGRGetDriverCount();
2074 QStringList writableDrivers;
2075 for (
int i = 0; i < drvCount; ++i )
2077 OGRSFDriverH drv = OGRGetDriver( i );
2080 QString drvName = OGR_Dr_GetName( drv );
2081 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2084 if ( drvName ==
"MapInfo File" )
2086 writableDrivers <<
"MapInfo MIF";
2088 else if ( drvName ==
"SQLite" )
2095 QString option =
"SPATIALITE=YES";
2096 char **options =
new char *[2];
2097 options[0] = CPLStrdup( option.toLocal8Bit().data() );
2099 OGRSFDriverH poDriver;
2101 poDriver = OGRGetDriverByName( drvName.toLocal8Bit().data() );
2104 OGRDataSourceH ds = OGR_Dr_CreateDataSource( poDriver,
TO8F( QString(
"/vsimem/spatialitetest.sqlite" ) ), options );
2107 writableDrivers <<
"SpatiaLite";
2108 OGR_Dr_DeleteDataSource( poDriver,
TO8F( QString(
"/vsimem/spatialitetest.sqlite" ) ) );
2109 OGR_DS_Destroy( ds );
2112 CPLFree( options[0] );
2115 else if ( drvName ==
"ESRI Shapefile" )
2117 writableDrivers <<
"DBF file";
2119 writableDrivers << drvName;
2124 foreach ( QString drvName, writableDrivers )
2132 resultMap.insert( trLongName, drvName );
2141 QString filterString;
2143 QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin();
2144 for ( ; it != driverFormatMap.constEnd(); ++it )
2146 if ( filterString.isEmpty() )
2147 filterString +=
";;";
2149 filterString += it.key();
2151 return filterString;
2160 if ( !
driverMetadata( driverName, longName, trLongName, glob, exts ) || trLongName.isEmpty() || glob.isEmpty() )
2163 return trLongName +
" [OGR] (" + glob.toLower() +
" " + glob.toUpper() +
")";
2168 if ( codecName ==
"System" )
2169 return QString(
"LDID/0" );
2171 QRegExp re = QRegExp( QString(
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
2172 if ( re.exactMatch( codecName ) )
2174 QString c = re.cap( 2 ).replace(
"-" ,
"" );
2176 c.toInt( &isNumber );
2185 if ( driverName.startsWith(
"AVCE00" ) )
2187 longName =
"Arc/Info ASCII Coverage";
2188 trLongName =
QObject::tr(
"Arc/Info ASCII Coverage" );
2192 else if ( driverName.startsWith(
"BNA" ) )
2194 longName =
"Atlas BNA";
2199 else if ( driverName.startsWith(
"CSV" ) )
2201 longName =
"Comma Separated Value";
2202 trLongName =
QObject::tr(
"Comma Separated Value" );
2206 else if ( driverName.startsWith(
"ESRI" ) )
2208 longName =
"ESRI Shapefile";
2213 else if ( driverName.startsWith(
"DBF file" ) )
2215 longName =
"DBF File";
2220 else if ( driverName.startsWith(
"FMEObjects Gateway" ) )
2222 longName =
"FMEObjects Gateway";
2227 else if ( driverName.startsWith(
"GeoJSON" ) )
2229 longName =
"GeoJSON";
2234 else if ( driverName.startsWith(
"GeoRSS" ) )
2236 longName =
"GeoRSS";
2241 else if ( driverName.startsWith(
"GML" ) )
2243 longName =
"Geography Markup Language [GML]";
2244 trLongName =
QObject::tr(
"Geography Markup Language [GML]" );
2248 else if ( driverName.startsWith(
"GMT" ) )
2250 longName =
"Generic Mapping Tools [GMT]";
2251 trLongName =
QObject::tr(
"Generic Mapping Tools [GMT]" );
2255 else if ( driverName.startsWith(
"GPX" ) )
2257 longName =
"GPS eXchange Format [GPX]";
2258 trLongName =
QObject::tr(
"GPS eXchange Format [GPX]" );
2262 else if ( driverName.startsWith(
"Interlis 1" ) )
2264 longName =
"INTERLIS 1";
2266 glob =
"*.itf *.xml *.ili";
2269 else if ( driverName.startsWith(
"Interlis 2" ) )
2271 longName =
"INTERLIS 2";
2273 glob =
"*.itf *.xml *.ili";
2276 else if ( driverName.startsWith(
"KML" ) )
2278 longName =
"Keyhole Markup Language [KML]";
2279 trLongName =
QObject::tr(
"Keyhole Markup Language [KML]" );
2283 else if ( driverName.startsWith(
"MapInfo File" ) )
2285 longName =
"Mapinfo TAB";
2291 else if ( driverName.startsWith(
"MapInfo MIF" ) )
2293 longName =
"Mapinfo MIF";
2298 else if ( driverName.startsWith(
"DGN" ) )
2300 longName =
"Microstation DGN";
2305 else if ( driverName.startsWith(
"S57" ) )
2307 longName =
"S-57 Base file";
2312 else if ( driverName.startsWith(
"SDTS" ) )
2314 longName =
"Spatial Data Transfer Standard [SDTS]";
2315 trLongName =
QObject::tr(
"Spatial Data Transfer Standard [SDTS]" );
2319 else if ( driverName.startsWith(
"SQLite" ) )
2321 longName =
"SQLite";
2327 else if ( driverName.startsWith(
"SpatiaLite" ) )
2329 longName =
"SpatiaLite";
2334 else if ( driverName.startsWith(
"DXF" ) )
2336 longName =
"AutoCAD DXF";
2341 else if ( driverName.startsWith(
"Geoconcept" ) )
2343 longName =
"Geoconcept";
2345 glob =
"*.gxt *.txt";
2348 else if ( driverName.startsWith(
"FileGDB" ) )
2350 longName =
"ESRI FileGDB";
2383 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1700
2384 mSymbolLayerTable.clear();
2385 OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
2386 OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
2389 int nTotalLevels = 0;
2391 QgsSymbolV2List::iterator symbolIt = symbolList.begin();
2392 for ( ; symbolIt != symbolList.end(); ++symbolIt )
2397 int nLevels = ( *symbolIt )->symbolLayerCount();
2398 for (
int i = 0; i < nLevels; ++i )
2400 mSymbolLayerTable.insert(( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
2401 OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
2402 ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
2406 OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
2422 QHash< QgsSymbolV2*, QList<QgsFeature> > features;
2451 QString msg =
QObject::tr(
"Failed to transform, writing stopped. (Exception: %1)" )
2455 *errorMessage = msg;
2462 if ( !featureSymbol )
2467 QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
2468 if ( it == features.end() )
2470 it = features.insert( featureSymbol, QList<QgsFeature>() );
2472 it.value().append( fet );
2478 for (
int i = 0; i < symbols.count(); i++ )
2484 if ( level < 0 || level >= 1000 )
2487 while ( level >= levels.count() )
2489 levels[level].append( item );
2494 int nTotalFeatures = 0;
2497 for (
int l = 0; l < levels.count(); l++ )
2500 for (
int i = 0; i < level.count(); i++ )
2503 QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
2504 if ( levelIt == features.end() )
2513 int llayer = item.
layer();
2514 QList<QgsFeature>& featureList = levelIt.value();
2515 QList<QgsFeature>::iterator featureIt = featureList.begin();
2516 for ( ; featureIt != featureList.end(); ++featureIt )
2526 QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
2527 if ( !styleString.isEmpty() )
2529 OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
2535 OGR_F_Destroy( ogrFeature );
2542 if ( nErrors > 0 && errorMessage )
2544 *errorMessage +=
QObject::tr(
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
2561 return 1000 / scaleDenominator;
2578 return scaleDenominator / 1000;
2635 for (
int i = 0; i < rendererAttributes.size(); ++i )
2640 attList.push_back( vl->
fieldNameIndex( rendererAttributes.at( i ) ) );