1 /*************************************************************************** 2 qgsvectorlayerexporter.h 3 ------------------- 4 begin : Thu Aug 25 2011 5 copyright : (C) 2011 by Giuseppe Sucameli 6 email : brush.tyler at gmail.com 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 18 #ifndef QGSVECTORLAYEREXPORTER_H 19 #define QGSVECTORLAYEREXPORTER_H 20 21 #include "qgis_core.h" 22 #include "qgis_sip.h" 23 #include "qgsfeature.h" 24 #include "qgsfeaturesink.h" 25 #include "qgstaskmanager.h" 26 #include "qgsfeedback.h" 27 #include "qgsvectorlayer.h" 28 29 class QProgressDialog; 30 class QgsVectorDataProvider; 31 class QgsFields; 32 33 /** 34 * \class QgsVectorLayerExporter 35 * \ingroup core 36 * \brief A convenience class for exporting vector layers to a destination data provider. 37 * 38 * QgsVectorLayerExporter can be used in two ways: 39 * 40 * # Using a static call to QgsVectorLayerExporter::exportLayer(...) which exports the 41 * entire layer to the destination provider. 42 * # Create an instance of the class and issue calls to addFeature(...) 43 * 44 * \since QGIS 3.0 45 */ 46 class CORE_EXPORT QgsVectorLayerExporter : public QgsFeatureSink 47 { 48 public: 49 50 //! Error codes 51 enum ExportError 52 { 53 NoError = 0, //!< No errors were encountered 54 ErrCreateDataSource, //!< Could not create the destination data source 55 ErrCreateLayer, //!< Could not create destination layer 56 ErrAttributeTypeUnsupported, //!< Source layer has an attribute type which could not be handled by destination 57 ErrAttributeCreationFailed, //!< Destination provider was unable to create an attribute 58 ErrProjection, //!< An error occurred while reprojecting features to destination CRS 59 ErrFeatureWriteFailed, //!< An error occurred while writing a feature to the destination 60 ErrInvalidLayer, //!< Could not access newly created destination layer 61 ErrInvalidProvider, //!< Could not find a matching provider key 62 ErrProviderUnsupportedFeature, //!< Provider does not support creation of empty layers 63 ErrConnectionFailed, //!< Could not connect to destination 64 ErrUserCanceled, //!< User canceled the export 65 }; 66 67 /** 68 * Writes the contents of vector layer to a different datasource. 69 * \param layer source layer 70 * \param uri URI for destination data source 71 * \param providerKey string key for destination data provider 72 * \param destCRS destination CRS, or an invalid (default constructed) CRS if 73 * not available 74 * \param onlySelected set to TRUE to export only selected features 75 * \param errorMessage if non-null, will be set to any error messages 76 * \param options optional provider dataset options 77 * \param feedback optional feedback object to show progress and cancellation of export 78 * \returns NoError for a successful export, or encountered error 79 */ 80 static ExportError exportLayer( QgsVectorLayer *layer, 81 const QString &uri, 82 const QString &providerKey, 83 const QgsCoordinateReferenceSystem &destCRS, 84 bool onlySelected = false, 85 QString *errorMessage SIP_OUT = nullptr, 86 const QMap<QString, QVariant> &options = QMap<QString, QVariant>(), 87 QgsFeedback *feedback = nullptr 88 ); 89 90 /** 91 * Constructor for QgsVectorLayerExporter. 92 * \param uri URI for destination data source 93 * \param provider string key for destination data provider 94 * \param fields fields to include in created layer 95 * \param geometryType destination geometry type 96 * \param crs desired CRS, or an invalid (default constructed) CRS if 97 * not available 98 * \param overwrite set to TRUE to overwrite any existing data source 99 * \param options optional provider dataset options 100 * \param sinkFlags for how to add features 101 */ 102 QgsVectorLayerExporter( const QString &uri, 103 const QString &provider, 104 const QgsFields &fields, 105 QgsWkbTypes::Type geometryType, 106 const QgsCoordinateReferenceSystem &crs, 107 bool overwrite = false, 108 const QMap<QString, QVariant> &options = QMap<QString, QVariant>(), 109 QgsFeatureSink::SinkFlags sinkFlags = QgsFeatureSink::SinkFlags() ); 110 111 //! QgsVectorLayerExporter cannot be copied 112 QgsVectorLayerExporter( const QgsVectorLayerExporter &rh ) = delete; 113 //! QgsVectorLayerExporter cannot be copied 114 QgsVectorLayerExporter &operator=( const QgsVectorLayerExporter &rh ) = delete; 115 116 /** 117 * Returns any encountered error code, or FALSE if no error was encountered. 118 * \see errorMessage() 119 * \see errorCount() 120 */ 121 ExportError errorCode() const; 122 123 /** 124 * Returns any error message encountered during the export. 125 * \see errorCount() 126 * \see errorCode() 127 */ 128 QString errorMessage() const; 129 130 /** 131 * Returns the number of error messages encountered during the export. 132 * \see errorMessage() 133 * \see errorCode() 134 */ errorCount()135 int errorCount() const { return mErrorCount; } 136 137 bool addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override; 138 bool addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags = QgsFeatureSink::Flags() ) override; 139 QString lastError() const override; 140 141 /** 142 * Finalizes the export and closes the new created layer. 143 */ 144 ~QgsVectorLayerExporter() override; 145 146 bool flushBuffer() override; 147 148 private: 149 150 //! Create index 151 bool createSpatialIndex(); 152 153 //! Contains error value 154 ExportError mError; 155 QString mErrorMessage; 156 157 int mErrorCount; 158 159 QgsVectorDataProvider *mProvider = nullptr; 160 161 //! Map attribute indexes to new field indexes 162 QMap<int, int> mOldToNewAttrIdx; 163 int mAttributeCount; 164 165 QgsFeatureList mFeatureBuffer; 166 int mFeatureBufferMemoryUsage = 0; 167 168 bool mCreateSpatialIndex = true; 169 170 #ifdef SIP_RUN 171 QgsVectorLayerExporter( const QgsVectorLayerExporter &rh ); 172 #endif 173 174 }; 175 176 177 /** 178 * \class QgsVectorLayerExporterTask 179 * \ingroup core 180 * \brief QgsTask task which performs a QgsVectorLayerExporter layer export operation as a background 181 * task. This can be used to export a vector layer out to a provider without blocking the 182 * QGIS interface. 183 * \see QgsVectorFileWriterTask 184 * \see QgsRasterFileWriterTask 185 * \since QGIS 3.0 186 */ 187 class CORE_EXPORT QgsVectorLayerExporterTask : public QgsTask 188 { 189 Q_OBJECT 190 191 public: 192 193 /** 194 * Constructor for QgsVectorLayerExporterTask. Takes a source \a layer, destination \a uri 195 * and \a providerKey, and various export related parameters such as destination CRS 196 * and export \a options. \a ownsLayer has to be set to TRUE if the task should take ownership 197 * of the layer and delete it after export. 198 */ 199 QgsVectorLayerExporterTask( QgsVectorLayer *layer, 200 const QString &uri, 201 const QString &providerKey, 202 const QgsCoordinateReferenceSystem &destinationCrs, 203 const QMap<QString, QVariant> &options = QMap<QString, QVariant>(), 204 bool ownsLayer = false ); 205 206 /** 207 * Creates a new QgsVectorLayerExporterTask which has ownership over a source \a layer. 208 * When the export task has completed (successfully or otherwise) \a layer will be 209 * deleted. The destination \a uri and \a providerKey, and various export related parameters such as destination CRS 210 * and export \a options must be specified. 211 */ 212 static QgsVectorLayerExporterTask *withLayerOwnership( QgsVectorLayer *layer SIP_TRANSFER, 213 const QString &uri, 214 const QString &providerKey, 215 const QgsCoordinateReferenceSystem &destinationCrs, 216 const QMap<QString, QVariant> &options = QMap<QString, QVariant>() ) SIP_FACTORY; 217 218 void cancel() override; 219 220 signals: 221 222 /** 223 * Emitted when exporting the layer is successfully completed. 224 */ 225 void exportComplete(); 226 227 /** 228 * Emitted when an error occurs which prevented the layer being exported (or if 229 * the task is canceled). The export \a error and \a errorMessage will be reported. 230 */ 231 void errorOccurred( int error, const QString &errorMessage ); 232 233 protected: 234 235 bool run() override; 236 void finished( bool result ) override; 237 238 private: 239 240 QPointer< QgsVectorLayer > mLayer = nullptr; 241 bool mOwnsLayer = false; 242 243 QString mDestUri; 244 QString mDestProviderKey; 245 QgsCoordinateReferenceSystem mDestCrs; 246 QMap<QString, QVariant> mOptions; 247 248 std::unique_ptr< QgsFeedback > mOwnedFeedback; 249 250 QgsVectorLayerExporter::ExportError mError = QgsVectorLayerExporter::NoError; 251 QString mErrorMessage; 252 253 }; 254 255 #endif // QGSVECTORLAYEREXPORTER_H 256