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