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