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 the 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(
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();
1559 QString styleString;
1560 QString currentStyle;
1562 QgsSymbolV2List::const_iterator symbolIt = symbols.constBegin();
1563 for ( ; symbolIt != symbols.constEnd(); ++symbolIt )
1565 int nSymbolLayers = ( *symbolIt )->symbolLayerCount();
1566 for (
int i = 0; i < nSymbolLayers; ++i )
1569 QMap< QgsSymbolLayerV2*, QString >::const_iterator it = mSymbolLayerTable.find(( *symbolIt )->symbolLayer( i ) );
1570 if ( it == mSymbolLayerTable.constEnd() )
1578 currentStyle = ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf );
1582 if ( symbolIt != symbols.constBegin() || i != 0 )
1584 styleString.append(
";" );
1586 styleString.append( currentStyle );
1590 OGR_F_SetStyleString( poFeature, currentStyle.toLocal8Bit().data() );
1598 OGR_F_SetStyleString( poFeature, styleString.toLocal8Bit().data() );
1609 OGR_F_Destroy( poFeature );
1615 OGRFeatureH poFeature = OGR_F_Create( OGR_L_GetLayerDefn(
mLayer ) );
1620 QgsDebugMsg( QString(
"feature id %1 too large." ).arg( fid ) );
1621 OGRErr err = OGR_F_SetFID( poFeature, static_cast<long>( fid ) );
1622 if ( err != OGRERR_NONE )
1624 QgsDebugMsg( QString(
"Failed to set feature id to %1: %2 (OGR error: %3)" )
1625 .arg( feature.
id() )
1626 .arg( err ).arg( CPLGetLastErrorMsg() )
1632 for (
int fldIdx = 0; fldIdx <
mFields.
count(); ++fldIdx )
1636 QgsDebugMsg( QString(
"no ogr field for field %1" ).arg( fldIdx ) );
1640 const QVariant& attrValue = feature.
attribute( fldIdx );
1643 if ( !attrValue.isValid() || attrValue.isNull() )
1646 switch ( attrValue.type() )
1649 OGR_F_SetFieldInteger( poFeature, ogrField, attrValue.toInt() );
1651 case QVariant::Double:
1652 OGR_F_SetFieldDouble( poFeature, ogrField, attrValue.toDouble() );
1654 case QVariant::LongLong:
1655 case QVariant::String:
1656 OGR_F_SetFieldString( poFeature, ogrField,
mCodec->fromUnicode( attrValue.toString() ).data() );
1658 case QVariant::Date:
1659 OGR_F_SetFieldDateTime( poFeature, ogrField,
1660 attrValue.toDate().year(),
1661 attrValue.toDate().month(),
1662 attrValue.toDate().day(),
1665 case QVariant::DateTime:
1666 OGR_F_SetFieldDateTime( poFeature, ogrField,
1667 attrValue.toDateTime().date().year(),
1668 attrValue.toDateTime().date().month(),
1669 attrValue.toDateTime().date().day(),
1670 attrValue.toDateTime().time().hour(),
1671 attrValue.toDateTime().time().minute(),
1672 attrValue.toDateTime().time().second(),
1675 case QVariant::Invalid:
1679 .arg(
mFields[fldIdx].name() )
1681 .arg( QMetaType::typeName( attrValue.type() ) )
1682 .arg( attrValue.toString() );
1716 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1719 OGR_F_Destroy( poFeature );
1723 OGRErr err = OGR_G_ImportFromWkb( mGeom2, const_cast<unsigned char *>( geom->
asWkb() ), (
int ) geom->
wkbSize() );
1724 if ( err != OGRERR_NONE )
1727 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1730 OGR_F_Destroy( poFeature );
1735 OGR_F_SetGeometryDirectly( poFeature, mGeom2 );
1739 OGRErr err = OGR_G_ImportFromWkb(
mGeom, const_cast<unsigned char *>( geom->
asWkb() ), (
int ) geom->
wkbSize() );
1740 if ( err != OGRERR_NONE )
1743 .arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1746 OGR_F_Destroy( poFeature );
1751 OGR_F_SetGeometry( poFeature,
mGeom );
1759 if ( OGR_L_CreateFeature( layer, feature ) != OGRERR_NONE )
1761 mErrorMessage =
QObject::tr(
"Feature creation error (OGR error: %1)" ).arg( QString::fromUtf8( CPLGetLastErrorMsg() ) );
1764 OGR_F_Destroy( feature );
1774 OGR_G_DestroyGeometry(
mGeom );
1779 OGR_DS_Destroy(
mDS );
1785 const QString& fileName,
1786 const QString& fileEncoding,
1788 const QString& driverName,
1790 QString *errorMessage,
1791 const QStringList &datasourceOptions,
1792 const QStringList &layerOptions,
1793 bool skipAttributeCreation,
1794 QString *newFilename,
1796 double symbologyScale,
1800 if ( destCRS && layer )
1806 errorMessage, datasourceOptions, layerOptions, skipAttributeCreation, newFilename, symbologyExport, symbologyScale, filterExtent );
1812 const QString& fileName,
1813 const QString& fileEncoding,
1815 const QString& driverName,
1817 QString *errorMessage,
1818 const QStringList &datasourceOptions,
1819 const QStringList &layerOptions,
1820 bool skipAttributeCreation,
1821 QString *newFilename,
1823 double symbologyScale,
1831 bool shallTransform =
false;
1836 outputCRS = &( ct->
destCRS() );
1837 shallTransform =
true;
1842 outputCRS = &layer->
crs();
1848 QString srcFileName = theURIParts[0];
1850 if ( QFile::exists( srcFileName ) && QFileInfo( fileName ).canonicalFilePath() == QFileInfo( srcFileName ).canonicalFilePath() )
1853 *errorMessage =
QObject::tr(
"Cannot overwrite a OGR layer in place" );
1879 errorMessage->clear();
1917 int n = 0, errors = 0;
1929 bool transactionsEnabled =
true;
1931 if ( OGRERR_NONE != OGR_L_StartTransaction( writer->
mLayer ) )
1933 QgsDebugMsg(
"Error when trying to enable transactions on OGRLayer." );
1934 transactionsEnabled =
false;
1940 if ( onlySelected && !ids.contains( fet.
id() ) )
1943 if ( shallTransform )
1957 QString msg =
QObject::tr(
"Failed to transform a point while drawing a feature with ID '%1'. Writing stopped. (Exception: %2)" )
1958 .arg( fet.
id() ).arg( e.
what() );
1961 *errorMessage = msg;
1970 if ( allAttr.size() < 1 && skipAttributeCreation )
1978 if ( err !=
NoError && errorMessage )
1980 if ( errorMessage->isEmpty() )
1982 *errorMessage =
QObject::tr(
"Feature write errors:" );
1988 if ( errors > 1000 )
1992 *errorMessage +=
QObject::tr(
"Stopping after %1 errors" ).arg( errors );
2002 if ( transactionsEnabled )
2004 if ( OGRERR_NONE != OGR_L_CommitTransaction( writer->
mLayer ) )
2006 QgsDebugMsg(
"Error while committing transaction on OGRLayer." );
2013 if ( errors > 0 && errorMessage && n > 0 )
2015 *errorMessage +=
QObject::tr(
"\nOnly %1 of %2 features written." ).arg( n - errors ).arg( n );
2024 QFileInfo fi( theFileName );
2025 QDir dir = fi.dir();
2028 const char *suffixes[] = {
".shp",
".shx",
".dbf",
".prj",
".qix",
".qpj" };
2029 for ( std::size_t i = 0; i <
sizeof( suffixes ) /
sizeof( *suffixes ); i++ )
2031 filter << fi.completeBaseName() + suffixes[i];
2035 foreach ( QString
file, dir.entryList( filter ) )
2037 if ( !QFile::remove( dir.canonicalPath() +
"/" +
file ) )
2049 QMap<QString, QString> resultMap;
2052 int const drvCount = OGRGetDriverCount();
2054 for (
int i = 0; i < drvCount; ++i )
2056 OGRSFDriverH drv = OGRGetDriver( i );
2059 QString drvName = OGR_Dr_GetName( drv );
2060 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2063 if ( filterString.isEmpty() )
2066 resultMap.insert( filterString, drvName );
2076 QMap<QString, QString> resultMap;
2079 int const drvCount = OGRGetDriverCount();
2081 QStringList writableDrivers;
2082 for (
int i = 0; i < drvCount; ++i )
2084 OGRSFDriverH drv = OGRGetDriver( i );
2087 QString drvName = OGR_Dr_GetName( drv );
2088 if ( OGR_Dr_TestCapability( drv,
"CreateDataSource" ) != 0 )
2091 if ( drvName ==
"MapInfo File" )
2093 writableDrivers <<
"MapInfo MIF";
2095 else if ( drvName ==
"SQLite" )
2102 QString option =
"SPATIALITE=YES";
2103 char **options =
new char *[2];
2104 options[0] = CPLStrdup( option.toLocal8Bit().data() );
2106 OGRSFDriverH poDriver;
2108 poDriver = OGRGetDriverByName( drvName.toLocal8Bit().data() );
2111 OGRDataSourceH ds = OGR_Dr_CreateDataSource( poDriver,
TO8F( QString(
"/vsimem/spatialitetest.sqlite" ) ), options );
2114 writableDrivers <<
"SpatiaLite";
2115 OGR_Dr_DeleteDataSource( poDriver,
TO8F( QString(
"/vsimem/spatialitetest.sqlite" ) ) );
2116 OGR_DS_Destroy( ds );
2119 CPLFree( options[0] );
2122 else if ( drvName ==
"ESRI Shapefile" )
2124 writableDrivers <<
"DBF file";
2126 writableDrivers << drvName;
2131 foreach ( QString drvName, writableDrivers )
2139 resultMap.insert( trLongName, drvName );
2148 QString filterString;
2150 QMap< QString, QString>::const_iterator it = driverFormatMap.constBegin();
2151 for ( ; it != driverFormatMap.constEnd(); ++it )
2153 if ( filterString.isEmpty() )
2154 filterString +=
";;";
2156 filterString += it.key();
2158 return filterString;
2167 if ( !
driverMetadata( driverName, longName, trLongName, glob, exts ) || trLongName.isEmpty() || glob.isEmpty() )
2170 return trLongName +
" [OGR] (" + glob.toLower() +
" " + glob.toUpper() +
")";
2175 if ( codecName ==
"System" )
2176 return QString(
"LDID/0" );
2178 QRegExp re = QRegExp( QString(
"(CP|windows-|ISO[ -])(.+)" ), Qt::CaseInsensitive );
2179 if ( re.exactMatch( codecName ) )
2181 QString c = re.cap( 2 ).replace(
"-" ,
"" );
2183 c.toInt( &isNumber );
2192 if ( driverName.startsWith(
"AVCE00" ) )
2194 longName =
"Arc/Info ASCII Coverage";
2195 trLongName =
QObject::tr(
"Arc/Info ASCII Coverage" );
2199 else if ( driverName.startsWith(
"BNA" ) )
2201 longName =
"Atlas BNA";
2206 else if ( driverName.startsWith(
"CSV" ) )
2208 longName =
"Comma Separated Value";
2209 trLongName =
QObject::tr(
"Comma Separated Value" );
2213 else if ( driverName.startsWith(
"ESRI" ) )
2215 longName =
"ESRI Shapefile";
2220 else if ( driverName.startsWith(
"DBF file" ) )
2222 longName =
"DBF File";
2227 else if ( driverName.startsWith(
"FMEObjects Gateway" ) )
2229 longName =
"FMEObjects Gateway";
2234 else if ( driverName.startsWith(
"GeoJSON" ) )
2236 longName =
"GeoJSON";
2241 else if ( driverName.startsWith(
"GeoRSS" ) )
2243 longName =
"GeoRSS";
2248 else if ( driverName.startsWith(
"GML" ) )
2250 longName =
"Geography Markup Language [GML]";
2251 trLongName =
QObject::tr(
"Geography Markup Language [GML]" );
2255 else if ( driverName.startsWith(
"GMT" ) )
2257 longName =
"Generic Mapping Tools [GMT]";
2258 trLongName =
QObject::tr(
"Generic Mapping Tools [GMT]" );
2262 else if ( driverName.startsWith(
"GPX" ) )
2264 longName =
"GPS eXchange Format [GPX]";
2265 trLongName =
QObject::tr(
"GPS eXchange Format [GPX]" );
2269 else if ( driverName.startsWith(
"Interlis 1" ) )
2271 longName =
"INTERLIS 1";
2273 glob =
"*.itf *.xml *.ili";
2276 else if ( driverName.startsWith(
"Interlis 2" ) )
2278 longName =
"INTERLIS 2";
2280 glob =
"*.itf *.xml *.ili";
2283 else if ( driverName.startsWith(
"KML" ) )
2285 longName =
"Keyhole Markup Language [KML]";
2286 trLongName =
QObject::tr(
"Keyhole Markup Language [KML]" );
2290 else if ( driverName.startsWith(
"MapInfo File" ) )
2292 longName =
"Mapinfo TAB";
2298 else if ( driverName.startsWith(
"MapInfo MIF" ) )
2300 longName =
"Mapinfo MIF";
2305 else if ( driverName.startsWith(
"DGN" ) )
2307 longName =
"Microstation DGN";
2312 else if ( driverName.startsWith(
"S57" ) )
2314 longName =
"S-57 Base file";
2319 else if ( driverName.startsWith(
"SDTS" ) )
2321 longName =
"Spatial Data Transfer Standard [SDTS]";
2322 trLongName =
QObject::tr(
"Spatial Data Transfer Standard [SDTS]" );
2326 else if ( driverName.startsWith(
"SQLite" ) )
2328 longName =
"SQLite";
2334 else if ( driverName.startsWith(
"SpatiaLite" ) )
2336 longName =
"SpatiaLite";
2341 else if ( driverName.startsWith(
"DXF" ) )
2343 longName =
"AutoCAD DXF";
2348 else if ( driverName.startsWith(
"Geoconcept" ) )
2350 longName =
"Geoconcept";
2352 glob =
"*.gxt *.txt";
2355 else if ( driverName.startsWith(
"FileGDB" ) )
2357 longName =
"ESRI FileGDB";
2390 #if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1700
2391 mSymbolLayerTable.clear();
2392 OGRStyleTableH ogrStyleTable = OGR_STBL_Create();
2393 OGRStyleMgrH styleManager = OGR_SM_Create( ogrStyleTable );
2396 int nTotalLevels = 0;
2398 QgsSymbolV2List::iterator symbolIt = symbolList.begin();
2399 for ( ; symbolIt != symbolList.end(); ++symbolIt )
2404 int nLevels = ( *symbolIt )->symbolLayerCount();
2405 for (
int i = 0; i < nLevels; ++i )
2407 mSymbolLayerTable.insert(( *symbolIt )->symbolLayer( i ), QString::number( nTotalLevels ) );
2408 OGR_SM_AddStyle( styleManager, QString::number( nTotalLevels ).toLocal8Bit(),
2409 ( *symbolIt )->symbolLayer( i )->ogrFeatureStyle( mmsf, musf ).toLocal8Bit() );
2413 OGR_DS_SetStyleTableDirectly( ds, ogrStyleTable );
2429 QHash< QgsSymbolV2*, QList<QgsFeature> > features;
2458 QString msg =
QObject::tr(
"Failed to transform, writing stopped. (Exception: %1)" )
2462 *errorMessage = msg;
2469 if ( !featureSymbol )
2474 QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
2475 if ( it == features.end() )
2477 it = features.insert( featureSymbol, QList<QgsFeature>() );
2479 it.value().append( fet );
2485 for (
int i = 0; i < symbols.count(); i++ )
2491 if ( level < 0 || level >= 1000 )
2494 while ( level >= levels.count() )
2496 levels[level].append( item );
2501 int nTotalFeatures = 0;
2504 for (
int l = 0; l < levels.count(); l++ )
2507 for (
int i = 0; i < level.count(); i++ )
2510 QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator levelIt = features.find( item.
symbol() );
2511 if ( levelIt == features.end() )
2520 int llayer = item.
layer();
2521 QList<QgsFeature>& featureList = levelIt.value();
2522 QList<QgsFeature>::iterator featureIt = featureList.begin();
2523 for ( ; featureIt != featureList.end(); ++featureIt )
2533 QString styleString = levelIt.key()->symbolLayer( llayer )->ogrFeatureStyle( mmsf, musf );
2534 if ( !styleString.isEmpty() )
2536 OGR_F_SetStyleString( ogrFeature, styleString.toLocal8Bit().data() );
2542 OGR_F_Destroy( ogrFeature );
2549 if ( nErrors > 0 && errorMessage )
2551 *errorMessage +=
QObject::tr(
"\nOnly %1 of %2 features written." ).arg( nTotalFeatures - nErrors ).arg( nTotalFeatures );
2568 return 1000 / scaleDenominator;
2585 return scaleDenominator / 1000;
2642 for (
int i = 0; i < rendererAttributes.size(); ++i )
2647 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
void createSymbolLayerTable(QgsVectorLayer *vl, const QgsCoordinateTransform *ct, OGRDataSourceH ds)
bool writeFeature(OGRLayerH layer, OGRFeatureH feature)
WriterError mError
contains error value if construction was not successful
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.
double mmScaleFactor(double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits)
void addRendererAttributes(QgsVectorLayer *vl, QgsAttributeList &attList)
Adds attributes needed for classification.
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...
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
double ANALYSIS_EXPORT max(double x, double y)
returns the maximum of two doubles or the first argument if both are equal
virtual QgsSymbolV2List symbols()=0
for symbol levels
double mapUnitScaleFactor(double scaleDenominator, QgsSymbolV2::OutputUnit symbolUnits, QGis::UnitType mapUnits)
void startRender(QgsVectorLayer *vl) const
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
OGRFeatureH createFeature(QgsFeature &feature)
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.)
void stopRender(QgsVectorLayer *vl) const
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
WriterError exportFeaturesSymbolLevels(QgsVectorLayer *layer, QgsFeatureIterator &fit, const QgsCoordinateTransform *ct, QString *errorMessage=0)
Writes features considering symbol level order.
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
QgsRenderContext renderContext() const
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
static QMap< QString, MetaData > initMetaData()
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 CoordinateTranasform 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)
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.
QgsFeatureRendererV2 * symbologyRenderer(QgsVectorLayer *vl) const
OGRGeometryH createEmptyGeometry(QGis::WkbType wkbType)
static QMap< QString, MetaData > sDriverMetadata
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.
void * OGRSpatialReferenceH
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)
QGis::UnitType mapUnits() const