Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsvectorfilewriter.h
3 : : generic vector file writer
4 : : -------------------
5 : : begin : Jun 6 2004
6 : : copyright : (C) 2004 by Tim Sutton
7 : : email : tim at linfiniti.com
8 : : ***************************************************************************/
9 : :
10 : : /***************************************************************************
11 : : * *
12 : : * This program is free software; you can redistribute it and/or modify *
13 : : * it under the terms of the GNU General Public License as published by *
14 : : * the Free Software Foundation; either version 2 of the License, or *
15 : : * (at your option) any later version. *
16 : : * *
17 : : ***************************************************************************/
18 : :
19 : : #ifndef QGSVECTORFILEWRITER_H
20 : : #define QGSVECTORFILEWRITER_H
21 : :
22 : : #include "qgis_core.h"
23 : : #include "qgis_sip.h"
24 : : #include "qgsfields.h"
25 : : #include "qgsfeedback.h"
26 : : #include "qgssymbol.h"
27 : : #include "qgstaskmanager.h"
28 : : #include "qgsogrutils.h"
29 : : #include "qgsrenderer.h"
30 : : #include "qgsgeometryengine.h"
31 : : #include "qgsfeaturesink.h"
32 : : #include <ogr_api.h>
33 : :
34 : : class QgsSymbolLayer;
35 : : class QTextCodec;
36 : : class QgsFeatureIterator;
37 : :
38 : : /**
39 : : * \ingroup core
40 : : * \brief A convenience class for writing vector files to disk.
41 : : There are two possibilities how to use this class:
42 : : 1. static call to QgsVectorFileWriter::writeAsVectorFormat(...) which saves the whole vector layer
43 : : 2. create an instance of the class and issue calls to addFeature(...)
44 : : */
45 : : class CORE_EXPORT QgsVectorFileWriter : public QgsFeatureSink
46 : : {
47 : : public:
48 : : enum OptionType
49 : : {
50 : : Set,
51 : : String,
52 : : Int,
53 : : Hidden
54 : : };
55 : :
56 : : /**
57 : : * \ingroup core
58 : : */
59 : : class Option
60 : : {
61 : : public:
62 : 0 : Option( const QString &docString, QgsVectorFileWriter::OptionType type )
63 : 0 : : docString( docString )
64 : 0 : , type( type ) {}
65 : 0 : virtual ~Option() = default;
66 : :
67 : : QString docString;
68 : : QgsVectorFileWriter::OptionType type;
69 : : };
70 : :
71 : : /**
72 : : * \ingroup core
73 : : */
74 : 0 : class SetOption : public QgsVectorFileWriter::Option
75 : : {
76 : : public:
77 : 0 : SetOption( const QString &docString, const QStringList &values, const QString &defaultValue, bool allowNone = false )
78 : 0 : : Option( docString, Set )
79 : 0 : , values( qgis::listToSet( values ) )
80 : 0 : , defaultValue( defaultValue )
81 : 0 : , allowNone( allowNone )
82 : 0 : {}
83 : :
84 : : QSet<QString> values;
85 : : QString defaultValue;
86 : : bool allowNone;
87 : : };
88 : :
89 : : /**
90 : : * \ingroup core
91 : : */
92 : 0 : class StringOption: public QgsVectorFileWriter::Option
93 : : {
94 : : public:
95 : 0 : StringOption( const QString &docString, const QString &defaultValue = QString() )
96 : 0 : : Option( docString, String )
97 : 0 : , defaultValue( defaultValue )
98 : 0 : {}
99 : :
100 : : QString defaultValue;
101 : : };
102 : :
103 : : /**
104 : : * \ingroup core
105 : : */
106 : 0 : class IntOption: public QgsVectorFileWriter::Option
107 : : {
108 : : public:
109 : 0 : IntOption( const QString &docString, int defaultValue )
110 : 0 : : Option( docString, Int )
111 : 0 : , defaultValue( defaultValue )
112 : 0 : {}
113 : :
114 : : int defaultValue;
115 : : };
116 : :
117 : : /**
118 : : * \ingroup core
119 : : */
120 : 0 : class BoolOption : public QgsVectorFileWriter::SetOption
121 : : {
122 : : public:
123 : 0 : BoolOption( const QString &docString, bool defaultValue )
124 : 0 : : SetOption( docString, QStringList() << QStringLiteral( "YES" ) << QStringLiteral( "NO" ), defaultValue ? "YES" : "NO" )
125 : 0 : {}
126 : : };
127 : :
128 : : /**
129 : : * \ingroup core
130 : : */
131 : 0 : class HiddenOption : public QgsVectorFileWriter::Option
132 : : {
133 : : public:
134 : 0 : explicit HiddenOption( const QString &value )
135 : 0 : : Option( QString(), Hidden )
136 : 0 : , mValue( value )
137 : 0 : {}
138 : :
139 : : QString mValue;
140 : : };
141 : :
142 : 0 : struct MetaData
143 : : {
144 : : //! Constructor for MetaData
145 : 0 : MetaData() = default;
146 : :
147 : 0 : MetaData( const QString &longName, const QString &trLongName, const QString &glob, const QString &ext, const QMap<QString, QgsVectorFileWriter::Option *> &driverOptions, const QMap<QString, QgsVectorFileWriter::Option *> &layerOptions, const QString &compulsoryEncoding = QString() )
148 : 0 : : longName( longName )
149 : 0 : , trLongName( trLongName )
150 : 0 : , glob( glob )
151 : 0 : , ext( ext )
152 : 0 : , driverOptions( driverOptions )
153 : 0 : , layerOptions( layerOptions )
154 : 0 : , compulsoryEncoding( compulsoryEncoding )
155 : 0 : {}
156 : :
157 : : QString longName;
158 : : QString trLongName;
159 : : QString glob;
160 : : QString ext;
161 : : QMap<QString, QgsVectorFileWriter::Option *> driverOptions;
162 : : QMap<QString, QgsVectorFileWriter::Option *> layerOptions;
163 : : //! Some formats require a compulsory encoding, typically UTF-8. If no compulsory encoding, empty string
164 : : QString compulsoryEncoding;
165 : : };
166 : :
167 : : enum WriterError
168 : : {
169 : : NoError = 0,
170 : : ErrDriverNotFound,
171 : : ErrCreateDataSource,
172 : : ErrCreateLayer,
173 : : ErrAttributeTypeUnsupported,
174 : : ErrAttributeCreationFailed,
175 : : ErrProjection,
176 : : ErrFeatureWriteFailed,
177 : : ErrInvalidLayer,
178 : : Canceled, //!< Writing was interrupted by manual cancellation
179 : : };
180 : :
181 : : enum SymbologyExport
182 : : {
183 : : NoSymbology = 0, //export only data
184 : : FeatureSymbology, //Keeps the number of features and export symbology per feature
185 : : SymbolLayerSymbology //Exports one feature per symbol layer (considering symbol levels)
186 : : };
187 : :
188 : : /**
189 : : * Source for exported field names.
190 : : *
191 : : * \since QGIS 3.18
192 : : */
193 : : enum FieldNameSource
194 : : {
195 : : Original = 0, //!< Use original field names
196 : : PreferAlias, //!< Use the field alias as the exported field name, wherever one is set. Otherwise use the original field names.
197 : : };
198 : :
199 : : /**
200 : : * Options for sorting and filtering vector formats.
201 : : * \since QGIS 3.0
202 : : */
203 : : enum VectorFormatOption
204 : : {
205 : : SortRecommended = 1 << 1, //!< Use recommended sort order, with extremely commonly used formats listed first
206 : : SkipNonSpatialFormats = 1 << 2, //!< Filter out any formats which do not have spatial support (e.g. those which cannot save geometries)
207 : : };
208 : : Q_DECLARE_FLAGS( VectorFormatOptions, VectorFormatOption )
209 : :
210 : : /**
211 : : * \ingroup core
212 : : * \brief Interface to convert raw field values to their user-friendly value.
213 : : * \since QGIS 2.16
214 : : */
215 : 0 : class CORE_EXPORT FieldValueConverter
216 : : {
217 : : public:
218 : : //! Constructor
219 : 0 : FieldValueConverter() = default;
220 : :
221 : 0 : virtual ~FieldValueConverter() = default;
222 : :
223 : : /**
224 : : * Returns a possibly modified field definition. Default implementation will return provided field unmodified.
225 : : * \param field original field definition
226 : : * \returns possibly modified field definition
227 : : */
228 : : virtual QgsField fieldDefinition( const QgsField &field );
229 : :
230 : : /**
231 : : * Convert the provided value, for field fieldIdxInLayer. Default implementation will return provided value unmodified.
232 : : * \param fieldIdxInLayer field index
233 : : * \param value original raw value
234 : : * \returns possibly modified value.
235 : : */
236 : : virtual QVariant convert( int fieldIdxInLayer, const QVariant &value );
237 : :
238 : : /**
239 : : * Creates a clone of the FieldValueConverter.
240 : : */
241 : : virtual QgsVectorFileWriter::FieldValueConverter *clone() const SIP_FACTORY;
242 : : };
243 : :
244 : : /**
245 : : * Edition capability flags
246 : : * \since QGIS 3.0
247 : : */
248 : : enum EditionCapability
249 : : {
250 : : //! Flag to indicate that a new layer can be added to the dataset
251 : : CanAddNewLayer = 1 << 0,
252 : :
253 : : //! Flag to indicate that new features can be added to an existing layer
254 : : CanAppendToExistingLayer = 1 << 1,
255 : :
256 : : //! Flag to indicate that new fields can be added to an existing layer. Imply CanAppendToExistingLayer
257 : : CanAddNewFieldsToExistingLayer = 1 << 2,
258 : :
259 : : //! Flag to indicate that an existing layer can be deleted
260 : : CanDeleteLayer = 1 << 3
261 : : };
262 : :
263 : : /**
264 : : * Combination of CanAddNewLayer, CanAppendToExistingLayer, CanAddNewFieldsToExistingLayer or CanDeleteLayer
265 : : * \since QGIS 3.0.
266 : : */
267 : : Q_DECLARE_FLAGS( EditionCapabilities, EditionCapability )
268 : :
269 : : /**
270 : : * Enumeration to describe how to handle existing files
271 : : * \since QGIS 3.0
272 : : */
273 : : enum ActionOnExistingFile
274 : : {
275 : : //! Create or overwrite file
276 : : CreateOrOverwriteFile,
277 : :
278 : : //! Create or overwrite layer
279 : : CreateOrOverwriteLayer,
280 : :
281 : : //! Append features to existing layer, but do not create new fields
282 : : AppendToLayerNoNewFields,
283 : :
284 : : //! Append features to existing layer, and create new fields if needed
285 : : AppendToLayerAddFields
286 : : };
287 : :
288 : : #ifndef SIP_RUN
289 : :
290 : : /**
291 : : * Write contents of vector layer to an (OGR supported) vector format
292 : : * \param layer layer to write
293 : : * \param fileName file name to write to
294 : : * \param fileEncoding encoding to use
295 : : * \param destCRS CRS to reproject exported geometries to, or invalid CRS for no reprojection
296 : : * \param driverName OGR driver to use
297 : : * \param onlySelected write only selected features of layer
298 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
299 : : * \param datasourceOptions list of OGR data source creation options
300 : : * \param layerOptions list of OGR layer creation options
301 : : * \param skipAttributeCreation only write geometries
302 : : * \param newFilename QString pointer which will contain the new file name created (in case it is different to fileName).
303 : : * \param symbologyExport symbology to export
304 : : * \param symbologyScale scale of symbology
305 : : * \param filterExtent if not NULLPTR, only features intersecting the extent will be saved (added in QGIS 2.4)
306 : : * \param overrideGeometryType set to a valid geometry type to override the default geometry type for the layer. This parameter
307 : : * allows for conversion of geometryless tables to null geometries, etc (added in QGIS 2.14)
308 : : * \param forceMulti set to TRUE to force creation of multi* geometries (added in QGIS 2.14)
309 : : * \param includeZ set to TRUE to include z dimension in output. This option is only valid if overrideGeometryType is set. (added in QGIS 2.14)
310 : : * \param attributes attributes to export (empty means all unless skipAttributeCreation is set)
311 : : * \param fieldValueConverter field value converter (added in QGIS 2.16)
312 : : * \param newLayer QString pointer which will contain the new layer name created (in case it is different to the provided layer name) (added in QGIS 3.4, not available in python)
313 : : * \deprecated Use writeAsVectorFormatV2() instead.
314 : : */
315 : : #else
316 : :
317 : : /**
318 : : * Write contents of vector layer to an (OGR supported) vector format
319 : : * \param layer layer to write
320 : : * \param fileName file name to write to
321 : : * \param fileEncoding encoding to use
322 : : * \param destCRS CRS to reproject exported geometries to, or invalid CRS for no reprojection
323 : : * \param driverName OGR driver to use
324 : : * \param onlySelected write only selected features of layer
325 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
326 : : * \param datasourceOptions list of OGR data source creation options
327 : : * \param layerOptions list of OGR layer creation options
328 : : * \param skipAttributeCreation only write geometries
329 : : * \param newFilename QString pointer which will contain the new file name created (in case it is different to fileName).
330 : : * \param symbologyExport symbology to export
331 : : * \param symbologyScale scale of symbology
332 : : * \param filterExtent if not NULLPTR, only features intersecting the extent will be saved (added in QGIS 2.4)
333 : : * \param overrideGeometryType set to a valid geometry type to override the default geometry type for the layer. This parameter
334 : : * allows for conversion of geometryless tables to null geometries, etc (added in QGIS 2.14)
335 : : * \param forceMulti set to TRUE to force creation of multi* geometries (added in QGIS 2.14)
336 : : * \param includeZ set to TRUE to include z dimension in output. This option is only valid if overrideGeometryType is set. (added in QGIS 2.14)
337 : : * \param attributes attributes to export (empty means all unless skipAttributeCreation is set)
338 : : * \param fieldValueConverter field value converter (added in QGIS 2.16)
339 : : * \deprecated Use writeAsVectorFormatV2() instead.
340 : : */
341 : : #endif
342 : : Q_DECL_DEPRECATED static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
343 : : const QString &fileName,
344 : : const QString &fileEncoding,
345 : : const QgsCoordinateReferenceSystem &destCRS = QgsCoordinateReferenceSystem(),
346 : : const QString &driverName = "GPKG",
347 : : bool onlySelected = false,
348 : : QString *errorMessage SIP_OUT = nullptr,
349 : : const QStringList &datasourceOptions = QStringList(),
350 : : const QStringList &layerOptions = QStringList(),
351 : : bool skipAttributeCreation = false,
352 : : QString *newFilename = nullptr,
353 : : QgsVectorFileWriter::SymbologyExport symbologyExport = QgsVectorFileWriter::NoSymbology,
354 : : double symbologyScale = 1.0,
355 : : const QgsRectangle *filterExtent = nullptr,
356 : : QgsWkbTypes::Type overrideGeometryType = QgsWkbTypes::Unknown,
357 : : bool forceMulti = false,
358 : : bool includeZ = false,
359 : : const QgsAttributeList &attributes = QgsAttributeList(),
360 : : QgsVectorFileWriter::FieldValueConverter *fieldValueConverter = nullptr
361 : : #ifndef SIP_RUN
362 : : , QString *newLayer = nullptr );
363 : : #else
364 : : ) SIP_DEPRECATED;
365 : : #endif
366 : :
367 : : #ifndef SIP_RUN
368 : :
369 : : /**
370 : : * Writes a layer out to a vector file.
371 : : * \param layer layer to write
372 : : * \param fileName file name to write to
373 : : * \param fileEncoding encoding to use
374 : : * \param ct coordinate transform to reproject exported geometries with, or invalid transform
375 : : * for no transformation
376 : : * \param driverName OGR driver to use
377 : : * \param onlySelected write only selected features of layer
378 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
379 : : * \param datasourceOptions list of OGR data source creation options
380 : : * \param layerOptions list of OGR layer creation options
381 : : * \param skipAttributeCreation only write geometries
382 : : * \param newFilename QString pointer which will contain the new file name created (in case it is different to fileName).
383 : : * \param symbologyExport symbology to export
384 : : * \param symbologyScale scale of symbology
385 : : * \param filterExtent if not NULLPTR, only features intersecting the extent will be saved (added in QGIS 2.4)
386 : : * \param overrideGeometryType set to a valid geometry type to override the default geometry type for the layer. This parameter
387 : : * allows for conversion of geometryless tables to null geometries, etc (added in QGIS 2.14)
388 : : * \param forceMulti set to TRUE to force creation of multi* geometries (added in QGIS 2.14)
389 : : * \param includeZ set to TRUE to include z dimension in output. This option is only valid if overrideGeometryType is set. (added in QGIS 2.14)
390 : : * \param attributes attributes to export (empty means all unless skipAttributeCreation is set)
391 : : * \param fieldValueConverter field value converter (added in QGIS 2.16)
392 : : * \param newLayer QString pointer which will contain the new layer name created (in case it is different to the provided layer name) (added in QGIS 3.4, not available in python)
393 : : * \since QGIS 2.2
394 : : * \deprecated Use writeAsVectorFormatV2() instead.
395 : : */
396 : : #else
397 : :
398 : : /**
399 : : * Writes a layer out to a vector file.
400 : : * \param layer layer to write
401 : : * \param fileName file name to write to
402 : : * \param fileEncoding encoding to use
403 : : * \param ct coordinate transform to reproject exported geometries with, or invalid transform
404 : : * for no transformation
405 : : * \param driverName OGR driver to use
406 : : * \param onlySelected write only selected features of layer
407 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
408 : : * \param datasourceOptions list of OGR data source creation options
409 : : * \param layerOptions list of OGR layer creation options
410 : : * \param skipAttributeCreation only write geometries
411 : : * \param newFilename QString pointer which will contain the new file name created (in case it is different to fileName).
412 : : * \param symbologyExport symbology to export
413 : : * \param symbologyScale scale of symbology
414 : : * \param filterExtent if not NULLPTR, only features intersecting the extent will be saved (added in QGIS 2.4)
415 : : * \param overrideGeometryType set to a valid geometry type to override the default geometry type for the layer. This parameter
416 : : * allows for conversion of geometryless tables to null geometries, etc (added in QGIS 2.14)
417 : : * \param forceMulti set to TRUE to force creation of multi* geometries (added in QGIS 2.14)
418 : : * \param includeZ set to TRUE to include z dimension in output. This option is only valid if overrideGeometryType is set. (added in QGIS 2.14)
419 : : * \param attributes attributes to export (empty means all unless skipAttributeCreation is set)
420 : : * \param fieldValueConverter field value converter (added in QGIS 2.16)
421 : : * \since QGIS 2.2
422 : : * \deprecated Use writeAsVectorFormatV2() instead.
423 : : */
424 : : #endif
425 : : Q_DECL_DEPRECATED static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
426 : : const QString &fileName,
427 : : const QString &fileEncoding,
428 : : const QgsCoordinateTransform &ct,
429 : : const QString &driverName = "GPKG",
430 : : bool onlySelected = false,
431 : : QString *errorMessage SIP_OUT = nullptr,
432 : : const QStringList &datasourceOptions = QStringList(),
433 : : const QStringList &layerOptions = QStringList(),
434 : : bool skipAttributeCreation = false,
435 : : QString *newFilename = nullptr,
436 : : QgsVectorFileWriter::SymbologyExport symbologyExport = QgsVectorFileWriter::NoSymbology,
437 : : double symbologyScale = 1.0,
438 : : const QgsRectangle *filterExtent = nullptr,
439 : : QgsWkbTypes::Type overrideGeometryType = QgsWkbTypes::Unknown,
440 : : bool forceMulti = false,
441 : : bool includeZ = false,
442 : : const QgsAttributeList &attributes = QgsAttributeList(),
443 : : QgsVectorFileWriter::FieldValueConverter *fieldValueConverter = nullptr
444 : : #ifndef SIP_RUN
445 : : , QString *newLayer = nullptr );
446 : : #else
447 : : ) SIP_DEPRECATED;
448 : : #endif
449 : :
450 : : /**
451 : : * \ingroup core
452 : : * \brief Options to pass to writeAsVectorFormat()
453 : : * \since QGIS 3.0
454 : : */
455 : 0 : class CORE_EXPORT SaveVectorOptions
456 : : {
457 : : public:
458 : : //! Constructor
459 : : SaveVectorOptions();
460 : :
461 : 0 : virtual ~SaveVectorOptions() = default;
462 : :
463 : : //! OGR driver to use
464 : : QString driverName;
465 : :
466 : : //! Layer name. If let empty, it will be derived from the filename
467 : : QString layerName;
468 : :
469 : : //! Action on existing file
470 : : QgsVectorFileWriter::ActionOnExistingFile actionOnExistingFile = CreateOrOverwriteFile;
471 : :
472 : : //! Encoding to use
473 : : QString fileEncoding;
474 : :
475 : : /**
476 : : * Transform to reproject exported geometries with, or invalid transform
477 : : * for no transformation
478 : : */
479 : : QgsCoordinateTransform ct;
480 : :
481 : : //! Write only selected features of layer
482 : : bool onlySelectedFeatures = false;
483 : :
484 : : //! List of OGR data source creation options
485 : : QStringList datasourceOptions;
486 : :
487 : : //! List of OGR layer creation options
488 : : QStringList layerOptions;
489 : :
490 : : //! Only write geometries
491 : : bool skipAttributeCreation = false;
492 : :
493 : : //! Attributes to export (empty means all unless skipAttributeCreation is set)
494 : : QgsAttributeList attributes;
495 : :
496 : : //! Symbology to export
497 : : QgsVectorFileWriter::SymbologyExport symbologyExport = NoSymbology;
498 : :
499 : : //! Scale of symbology
500 : : double symbologyScale = 1.0;
501 : :
502 : : //! If not empty, only features intersecting the extent will be saved
503 : : QgsRectangle filterExtent;
504 : :
505 : : /**
506 : : * Set to a valid geometry type to override the default geometry type for the layer. This parameter
507 : : * allows for conversion of geometryless tables to null geometries, etc.
508 : : */
509 : : QgsWkbTypes::Type overrideGeometryType = QgsWkbTypes::Unknown;
510 : :
511 : : //! Sets to TRUE to force creation of multi* geometries
512 : : bool forceMulti = false;
513 : :
514 : : //! Sets to TRUE to include z dimension in output. This option is only valid if overrideGeometryType is set
515 : : bool includeZ = false;
516 : :
517 : : /**
518 : : * Field value converter.
519 : : *
520 : : * Ownership is not transferred and callers must ensure that the lifetime of fieldValueConverter
521 : : * exceeds the lifetime of the QgsVectorFileWriter object.
522 : : */
523 : : QgsVectorFileWriter::FieldValueConverter *fieldValueConverter = nullptr;
524 : :
525 : : //! Optional feedback object allowing cancellation of layer save
526 : : QgsFeedback *feedback = nullptr;
527 : :
528 : : /**
529 : : * Source for exported field names.
530 : : *
531 : : * \since QGIS 3.18
532 : : */
533 : : FieldNameSource fieldNameSource = Original;
534 : : };
535 : :
536 : : #ifndef SIP_RUN
537 : :
538 : : /**
539 : : * Writes a layer out to a vector file.
540 : : * \param layer source layer to write
541 : : * \param fileName file name to write to
542 : : * \param options options.
543 : : * \param newFilename QString pointer which will contain the new file name created (in case it is different to fileName).
544 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
545 : : * \param newLayer QString pointer which will contain the new layer name created (in case it is different to the provided layer name) (added in QGIS 3.4, not available in python)
546 : : * \since QGIS 3.0
547 : : * \deprecated Use writeAsVectorFormatV2() instead.
548 : : */
549 : : #else
550 : :
551 : : /**
552 : : * Writes a layer out to a vector file.
553 : : * \param layer source layer to write
554 : : * \param fileName file name to write to
555 : : * \param options options.
556 : : * \param newFilename QString pointer which will contain the new file name created (in case it is different to fileName).
557 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
558 : : * \since QGIS 3.0
559 : : * \deprecated Use writeAsVectorFormatV2() instead.
560 : : */
561 : : #endif
562 : : Q_DECL_DEPRECATED static QgsVectorFileWriter::WriterError writeAsVectorFormat( QgsVectorLayer *layer,
563 : : const QString &fileName,
564 : : const QgsVectorFileWriter::SaveVectorOptions &options,
565 : : QString *newFilename = nullptr,
566 : : QString *errorMessage SIP_OUT = nullptr
567 : : #ifndef SIP_RUN
568 : : , QString *newLayer = nullptr );
569 : : #else
570 : : ) SIP_DEPRECATED;
571 : : #endif
572 : :
573 : : /**
574 : : * Create a new vector file writer
575 : : * \deprecated Use create() instead.
576 : : */
577 : : Q_DECL_DEPRECATED QgsVectorFileWriter( const QString &vectorFileName,
578 : : const QString &fileEncoding,
579 : : const QgsFields &fields,
580 : : QgsWkbTypes::Type geometryType,
581 : : const QgsCoordinateReferenceSystem &srs = QgsCoordinateReferenceSystem(),
582 : : const QString &driverName = "GPKG",
583 : : const QStringList &datasourceOptions = QStringList(),
584 : : const QStringList &layerOptions = QStringList(),
585 : : QString *newFilename = nullptr,
586 : : QgsVectorFileWriter::SymbologyExport symbologyExport = QgsVectorFileWriter::NoSymbology,
587 : : QgsFeatureSink::SinkFlags sinkFlags = QgsFeatureSink::SinkFlags()
588 : : #ifndef SIP_RUN
589 : : , QString *newLayer = nullptr,
590 : : const QgsCoordinateTransformContext &transformContext = QgsCoordinateTransformContext(),
591 : : FieldNameSource fieldNameSource = Original
592 : : #endif
593 : : ) SIP_DEPRECATED;
594 : :
595 : : /**
596 : : * Create a new vector file writer.
597 : : * \param vectorFileName file name to write to
598 : : * \param fileEncoding encoding to use
599 : : * \param fields fields to write
600 : : * \param geometryType geometry type of output file
601 : : * \param srs spatial reference system of output file
602 : : * \param driverName OGR driver to use
603 : : * \param datasourceOptions list of OGR data source creation options
604 : : * \param layerOptions list of OGR layer creation options
605 : : * \param newFilename potentially modified file name (output parameter)
606 : : * \param symbologyExport symbology to export
607 : : * \param fieldValueConverter field value converter (added in QGIS 2.16)
608 : : * \param layerName layer name. If let empty, it will be derived from the filename (added in QGIS 3.0)
609 : : * \param action action on existing file (added in QGIS 3.0)
610 : : * \param newLayer potentially modified layer name (output parameter) (added in QGIS 3.4)
611 : : * \param transformContext transform context, needed if the output file srs is forced to specific crs (added in QGIS 3.10.3)
612 : : * \param sinkFlags feature sink flags (added in QGIS 3.10.3)
613 : : * \param fieldNameSource source for field names (since QGIS 3.18)
614 : : * \note not available in Python bindings
615 : : * \deprecated Use create() instead.
616 : : */
617 : : Q_DECL_DEPRECATED QgsVectorFileWriter( const QString &vectorFileName,
618 : : const QString &fileEncoding,
619 : : const QgsFields &fields,
620 : : QgsWkbTypes::Type geometryType,
621 : : const QgsCoordinateReferenceSystem &srs,
622 : : const QString &driverName,
623 : : const QStringList &datasourceOptions,
624 : : const QStringList &layerOptions,
625 : : QString *newFilename,
626 : : QgsVectorFileWriter::SymbologyExport symbologyExport,
627 : : QgsVectorFileWriter::FieldValueConverter *fieldValueConverter,
628 : : const QString &layerName,
629 : : QgsVectorFileWriter::ActionOnExistingFile action,
630 : : QString *newLayer = nullptr,
631 : : const QgsCoordinateTransformContext &transformContext = QgsCoordinateTransformContext(),
632 : : QgsFeatureSink::SinkFlags sinkFlags = QgsFeatureSink::SinkFlags(),
633 : : FieldNameSource fieldNameSource = Original
634 : : ) SIP_SKIP;
635 : :
636 : : //! QgsVectorFileWriter cannot be copied.
637 : : QgsVectorFileWriter( const QgsVectorFileWriter &rh ) = delete;
638 : : //! QgsVectorFileWriter cannot be copied.
639 : : QgsVectorFileWriter &operator=( const QgsVectorFileWriter &rh ) = delete;
640 : :
641 : : /**
642 : : * Create a new vector file writer.
643 : : * \param fileName file name to write to
644 : : * \param fields fields to write
645 : : * \param geometryType geometry type of output file
646 : : * \param srs spatial reference system of output file
647 : : * \param transformContext coordinate transform context
648 : : * \param options save options
649 : : * \param sinkFlags feature sink flags
650 : : * \param newFilename potentially modified file name (output parameter)
651 : : * \param newLayer potentially modified layer name (output parameter)
652 : : * \since QGIS 3.10.3
653 : : */
654 : : static QgsVectorFileWriter *create( const QString &fileName,
655 : : const QgsFields &fields,
656 : : QgsWkbTypes::Type geometryType,
657 : : const QgsCoordinateReferenceSystem &srs,
658 : : const QgsCoordinateTransformContext &transformContext,
659 : : const QgsVectorFileWriter::SaveVectorOptions &options,
660 : : QgsFeatureSink::SinkFlags sinkFlags = QgsFeatureSink::SinkFlags(),
661 : : QString *newFilename = nullptr,
662 : : QString *newLayer = nullptr ) SIP_FACTORY;
663 : :
664 : : /**
665 : : * Writes a layer out to a vector file.
666 : : * \param layer source layer to write
667 : : * \param fileName file name to write to
668 : : * \param transformContext coordinate transform context
669 : : * \param options save options
670 : : * \param newFilename potentially modified file name (output parameter)
671 : : * \param newLayer potentially modified layer name (output parameter)
672 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
673 : : * \returns Error message code, or QgsVectorFileWriter.NoError if the write operation was successful
674 : : * \deprecated since QGIS 3.20, use writeAsVectorFormatV3 instead
675 : : */
676 : : Q_DECL_DEPRECATED static QgsVectorFileWriter::WriterError writeAsVectorFormatV2( QgsVectorLayer *layer,
677 : : const QString &fileName,
678 : : const QgsCoordinateTransformContext &transformContext,
679 : : const QgsVectorFileWriter::SaveVectorOptions &options,
680 : : QString *newFilename = nullptr,
681 : : QString *newLayer = nullptr,
682 : : QString *errorMessage SIP_OUT = nullptr ) SIP_DEPRECATED;
683 : :
684 : : /**
685 : : * Writes a layer out to a vector file.
686 : : * \param layer source layer to write
687 : : * \param fileName file name to write to
688 : : * \param transformContext coordinate transform context
689 : : * \param options save options
690 : : * \param newFilename potentially modified file name (output parameter)
691 : : * \param newLayer potentially modified layer name (output parameter)
692 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
693 : : * \returns Error message code, or QgsVectorFileWriter.NoError if the write operation was successful
694 : : * \since QGIS 3.20
695 : : */
696 : : static QgsVectorFileWriter::WriterError writeAsVectorFormatV3( QgsVectorLayer *layer,
697 : : const QString &fileName,
698 : : const QgsCoordinateTransformContext &transformContext,
699 : : const QgsVectorFileWriter::SaveVectorOptions &options,
700 : : QString *errorMessage SIP_OUT = nullptr,
701 : : QString *newFilename SIP_OUT = nullptr,
702 : : QString *newLayer SIP_OUT = nullptr );
703 : :
704 : : /**
705 : : * Details of available filters and formats.
706 : : * \since QGIS 3.0
707 : : */
708 : 0 : struct FilterFormatDetails
709 : : {
710 : : //! Unique driver name
711 : : QString driverName;
712 : :
713 : : //! Filter string for file picker dialogs
714 : : QString filterString;
715 : :
716 : : /**
717 : : * Matching glob patterns for format, e.g. *.shp.
718 : : * \since QGIS 3.2
719 : : */
720 : : QStringList globs;
721 : : };
722 : :
723 : : /**
724 : : * Returns a list or pairs, with format filter string as first element and OGR format key as second element.
725 : : *
726 : : * The \a options argument can be used to control the sorting and filtering of
727 : : * returned formats.
728 : : *
729 : : * \see supportedFormatExtensions()
730 : : */
731 : : static QList< QgsVectorFileWriter::FilterFormatDetails > supportedFiltersAndFormats( VectorFormatOptions options = SortRecommended );
732 : :
733 : : /**
734 : : * Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
735 : : *
736 : : * The \a options argument can be used to control the sorting and filtering of
737 : : * returned formats.
738 : : *
739 : : * \see supportedFiltersAndFormats()
740 : : * \since QGIS 3.0
741 : : */
742 : : static QStringList supportedFormatExtensions( VectorFormatOptions options = SortRecommended );
743 : :
744 : : /**
745 : : * Returns TRUE if the specified \a driverName supports feature styles.
746 : : *
747 : : * The \a driverName argument must be a valid GDAL driver name.
748 : : *
749 : : * \since QGIS 3.0
750 : : */
751 : : static bool supportsFeatureStyles( const QString &driverName );
752 : :
753 : : /**
754 : : * Details of available driver formats.
755 : : * \since QGIS 3.0
756 : : */
757 : 0 : struct DriverDetails
758 : : {
759 : : //! Descriptive, user friendly name for the driver
760 : : QString longName;
761 : :
762 : : //! Unique driver name
763 : : QString driverName;
764 : : };
765 : :
766 : : /**
767 : : * Returns the driver list that can be used for dialogs. It contains all OGR drivers
768 : : * plus some additional internal QGIS driver names to distinguish between more
769 : : * supported formats of the same OGR driver.
770 : : *
771 : : * The returned list consists of structs containing the driver long name (e.g. user-friendly
772 : : * display name for the format) and internal driver short name.
773 : : *
774 : : * The \a options argument can be used to control the sorting and filtering of
775 : : * returned drivers.
776 : : */
777 : : static QList< QgsVectorFileWriter::DriverDetails > ogrDriverList( VectorFormatOptions options = SortRecommended );
778 : :
779 : : /**
780 : : * Returns the OGR driver name for a specified file \a extension. E.g. the
781 : : * driver name for the ".shp" extension is "ESRI Shapefile".
782 : : * If no suitable drivers are found then an empty string is returned.
783 : : * \since QGIS 3.0
784 : : */
785 : : static QString driverForExtension( const QString &extension );
786 : :
787 : : /**
788 : : * Returns filter string that can be used for dialogs.
789 : : *
790 : : * The \a options argument can be used to control the sorting and filtering of
791 : : * returned drivers.
792 : : */
793 : : static QString fileFilterString( VectorFormatOptions options = SortRecommended );
794 : :
795 : : //! Creates a filter for an OGR driver key
796 : : static QString filterForDriver( const QString &driverName );
797 : :
798 : : //! Converts codec name to string passed to ENCODING layer creation option of OGR Shapefile
799 : : static QString convertCodecNameForEncodingOption( const QString &codecName );
800 : :
801 : : //! Checks whether there were any errors in constructor
802 : : QgsVectorFileWriter::WriterError hasError();
803 : :
804 : : //! Retrieves error message
805 : : QString errorMessage();
806 : :
807 : : bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override;
808 : : bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override;
809 : : QString lastError() const override;
810 : :
811 : : /**
812 : : * Adds a \a feature to the currently opened data source, using the style from a specified \a renderer.
813 : : * \since QGIS 3.0
814 : : */
815 : : bool addFeatureWithStyle( QgsFeature &feature, QgsFeatureRenderer *renderer, QgsUnitTypes::DistanceUnit outputUnit = QgsUnitTypes::DistanceMeters );
816 : :
817 : : //! \note not available in Python bindings
818 : 0 : QMap<int, int> attrIdxToOgrIdx() { return mAttrIdxToOgrIdx; } SIP_SKIP
819 : :
820 : : //! Close opened shapefile for writing
821 : : ~QgsVectorFileWriter() override;
822 : :
823 : : /**
824 : : * Delete a shapefile (and its accompanying shx / dbf / prj / qix / qpj / cpg / sbn / sbx / idm / ind)
825 : : * \param fileName /path/to/file.shp
826 : : * \returns bool TRUE if the file was deleted successfully
827 : : */
828 : : static bool deleteShapeFile( const QString &fileName );
829 : :
830 : 0 : QgsVectorFileWriter::SymbologyExport symbologyExport() const { return mSymbologyExport; }
831 : : void setSymbologyExport( QgsVectorFileWriter::SymbologyExport symExport ) { mSymbologyExport = symExport; }
832 : :
833 : : /**
834 : : * Returns the reference scale for output.
835 : : * The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
836 : : * \see setSymbologyScale()
837 : : * \since QGIS 3.0
838 : : */
839 : : double symbologyScale() const { return mSymbologyScale; }
840 : :
841 : : /**
842 : : * Set reference \a scale for output.
843 : : * The \a scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
844 : : * \see symbologyScale()
845 : : * \since QGIS 3.0
846 : : */
847 : : void setSymbologyScale( double scale );
848 : :
849 : : static bool driverMetadata( const QString &driverName, MetaData &driverMetadata );
850 : :
851 : : /**
852 : : * Returns a list of the default dataset options for a specified driver.
853 : : * \param driverName name of OGR driver
854 : : * \see defaultLayerOptions()
855 : : * \since QGIS 3.0
856 : : */
857 : : static QStringList defaultDatasetOptions( const QString &driverName );
858 : :
859 : : /**
860 : : * Returns a list of the default layer options for a specified driver.
861 : : * \param driverName name of OGR driver
862 : : * \see defaultDatasetOptions()
863 : : * \since QGIS 3.0
864 : : */
865 : : static QStringList defaultLayerOptions( const QString &driverName );
866 : :
867 : : /**
868 : : * Gets the ogr geometry type from an internal QGIS wkb type enum.
869 : : *
870 : : * Will drop M values and convert Z to 2.5D where required.
871 : : * \note not available in Python bindings
872 : : */
873 : : static OGRwkbGeometryType ogrTypeFromWkbType( QgsWkbTypes::Type type ) SIP_SKIP;
874 : :
875 : : /**
876 : : * Returns edition capabilities for an existing dataset name.
877 : : * \since QGIS 3.0
878 : : */
879 : : static QgsVectorFileWriter::EditionCapabilities editionCapabilities( const QString &datasetName );
880 : :
881 : : /**
882 : : * Returns whether the target layer already exists.
883 : : * \since QGIS 3.0
884 : : */
885 : : static bool targetLayerExists( const QString &datasetName,
886 : : const QString &layerName );
887 : :
888 : : /**
889 : : * Returns whether there are among the attributes specified some that do not exist yet in the layer
890 : : * \since QGIS 3.0
891 : : */
892 : : static bool areThereNewFieldsToCreate( const QString &datasetName,
893 : : const QString &layerName,
894 : : QgsVectorLayer *layer,
895 : : const QgsAttributeList &attributes );
896 : :
897 : : protected:
898 : : //! \note not available in Python bindings
899 : : OGRGeometryH createEmptyGeometry( QgsWkbTypes::Type wkbType ) SIP_SKIP;
900 : :
901 : : gdal::ogr_datasource_unique_ptr mDS;
902 : : OGRLayerH mLayer = nullptr;
903 : : OGRSpatialReferenceH mOgrRef = nullptr;
904 : :
905 : : QgsFields mFields;
906 : :
907 : : //! Contains error value if construction was not successful
908 : : WriterError mError;
909 : : QString mErrorMessage;
910 : :
911 : : QTextCodec *mCodec = nullptr;
912 : :
913 : : //! Geometry type which is being used
914 : : QgsWkbTypes::Type mWkbType;
915 : :
916 : : //! Map attribute indizes to OGR field indexes
917 : : QMap<int, int> mAttrIdxToOgrIdx;
918 : :
919 : : SymbologyExport mSymbologyExport;
920 : :
921 : : QMap< QgsSymbolLayer *, QString > mSymbolLayerTable;
922 : :
923 : : //! Scale for symbology export (e.g. for symbols units in map units)
924 : : double mSymbologyScale;
925 : :
926 : : QString mOgrDriverName;
927 : :
928 : : //! Field value converter
929 : : FieldValueConverter *mFieldValueConverter = nullptr;
930 : :
931 : : private:
932 : : #ifdef SIP_RUN
933 : : QgsVectorFileWriter( const QgsVectorFileWriter &rh );
934 : : #endif
935 : :
936 : 0 : struct PreparedWriterDetails
937 : : {
938 : : std::unique_ptr< QgsFeatureRenderer > renderer;
939 : : QgsCoordinateReferenceSystem sourceCrs;
940 : 0 : QgsWkbTypes::Type sourceWkbType = QgsWkbTypes::Unknown;
941 : : QgsFields sourceFields;
942 : : QString providerType;
943 : 0 : long featureCount = 0;
944 : : QgsFeatureIds selectedFeatureIds;
945 : : QString dataSourceUri;
946 : : QString storageType;
947 : : QgsFeatureIterator geometryTypeScanIterator;
948 : : QgsExpressionContext expressionContext;
949 : : QSet< int > fieldsToConvertToInt;
950 : : QgsRenderContext renderContext;
951 : 0 : bool shallTransform = false;
952 : : QgsCoordinateReferenceSystem outputCrs;
953 : 0 : QgsWkbTypes::Type destWkbType = QgsWkbTypes::Unknown;
954 : : QgsAttributeList attributes;
955 : : QgsFields outputFields;
956 : : QgsFeatureIterator sourceFeatureIterator;
957 : : QgsGeometry filterRectGeometry;
958 : : std::unique_ptr< QgsGeometryEngine > filterRectEngine;
959 : : QVariantMap providerUriParams;
960 : : };
961 : :
962 : : /**
963 : : * Prepares a write by populating a PreparedWriterDetails object.
964 : : * This MUST be called in the main thread.
965 : : */
966 : : static QgsVectorFileWriter::WriterError prepareWriteAsVectorFormat( QgsVectorLayer *layer,
967 : : const QgsVectorFileWriter::SaveVectorOptions &options,
968 : : PreparedWriterDetails &details );
969 : :
970 : : /**
971 : : * Writes a previously prepared PreparedWriterDetails \a details object.
972 : : * This is safe to call in a background thread.
973 : : * \param details writer details
974 : : * \param fileName file name to write to
975 : : * \param transformContext coordinate transform context
976 : : * \param options save options
977 : : * \param newFilename potentially modified file name (output parameter)
978 : : * \param newLayer potentially modified layer name (output parameter)
979 : : * \param errorMessage will be set to the error message text, if an error occurs while writing the layer
980 : : * \returns Error message code, or QgsVectorFileWriter.NoError if the write operation was successful
981 : : * \since QGIS 3.10.3
982 : : */
983 : : static QgsVectorFileWriter::WriterError writeAsVectorFormatV2( PreparedWriterDetails &details,
984 : : const QString &fileName,
985 : : const QgsCoordinateTransformContext &transformContext,
986 : : const QgsVectorFileWriter::SaveVectorOptions &options,
987 : : QString *newFilename = nullptr,
988 : : QString *newLayer = nullptr,
989 : : QString *errorMessage SIP_OUT = nullptr );
990 : :
991 : : /**
992 : : * Writes a previously prepared PreparedWriterDetails \a details object.
993 : : * This is safe to call in a background thread.
994 : : * \deprecated Use writeAsVectorFormatV2() instead.
995 : : */
996 : : Q_DECL_DEPRECATED static QgsVectorFileWriter::WriterError writeAsVectorFormat( PreparedWriterDetails &details,
997 : : const QString &fileName,
998 : : const QgsVectorFileWriter::SaveVectorOptions &options,
999 : : QString *newFilename = nullptr,
1000 : : QString *errorMessage SIP_OUT = nullptr,
1001 : : QString *newLayer = nullptr ) SIP_DEPRECATED;
1002 : :
1003 : : void init( QString vectorFileName, QString fileEncoding, const QgsFields &fields,
1004 : : QgsWkbTypes::Type geometryType, QgsCoordinateReferenceSystem srs,
1005 : : const QString &driverName, QStringList datasourceOptions,
1006 : : QStringList layerOptions, QString *newFilename,
1007 : : QgsVectorFileWriter::FieldValueConverter *fieldValueConverter,
1008 : : const QString &layerName,
1009 : : QgsVectorFileWriter::ActionOnExistingFile action, QString *newLayer, QgsFeatureSink::SinkFlags sinkFlags,
1010 : : const QgsCoordinateTransformContext &transformContext,
1011 : : FieldNameSource fieldNameSource );
1012 : : void resetMap( const QgsAttributeList &attributes );
1013 : :
1014 : : std::unique_ptr< QgsFeatureRenderer > mRenderer;
1015 : : QgsRenderContext mRenderContext;
1016 : :
1017 : :
1018 : : std::unique_ptr< QgsCoordinateTransform > mCoordinateTransform;
1019 : :
1020 : : bool mUsingTransaction = false;
1021 : : QSet< QVariant::Type > mSupportedListSubTypes;
1022 : :
1023 : : void createSymbolLayerTable( QgsVectorLayer *vl, const QgsCoordinateTransform &ct, OGRDataSourceH ds );
1024 : : gdal::ogr_feature_unique_ptr createFeature( const QgsFeature &feature );
1025 : : bool writeFeature( OGRLayerH layer, OGRFeatureH feature );
1026 : :
1027 : : //! Writes features considering symbol level order
1028 : : QgsVectorFileWriter::WriterError exportFeaturesSymbolLevels( const PreparedWriterDetails &details, QgsFeatureIterator &fit, const QgsCoordinateTransform &ct, QString *errorMessage = nullptr );
1029 : : double mmScaleFactor( double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits );
1030 : : double mapUnitScaleFactor( double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits );
1031 : :
1032 : : void startRender( QgsFeatureRenderer *sourceRenderer, const QgsFields &fields );
1033 : : void stopRender();
1034 : : std::unique_ptr< QgsFeatureRenderer > createSymbologyRenderer( QgsFeatureRenderer *sourceRenderer ) const;
1035 : : //! Adds attributes needed for classification
1036 : : static void addRendererAttributes( QgsFeatureRenderer *renderer, QgsRenderContext &context, const QgsFields &fields, QgsAttributeList &attList );
1037 : :
1038 : : //! Concatenates a list of options using their default values
1039 : : static QStringList concatenateOptions( const QMap<QString, Option *> &options );
1040 : :
1041 : : friend class QgsVectorFileWriterTask;
1042 : : friend class TestQgsVectorFileWriter;
1043 : : };
1044 : :
1045 : : Q_DECLARE_OPERATORS_FOR_FLAGS( QgsVectorFileWriter::EditionCapabilities )
1046 : : Q_DECLARE_OPERATORS_FOR_FLAGS( QgsVectorFileWriter::VectorFormatOptions )
1047 : :
1048 : : // clazy:excludeall=qstring-allocations
1049 : :
1050 : : #endif
|