QGIS API Documentation 3.43.0-Master (b60ef06885e)
qgsvectorlayerexporter.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorlayerexporter.cpp
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
19#include "qgsfields.h"
20#include "qgsfeature.h"
21#include "qgsfeatureiterator.h"
22#include "qgsgeometry.h"
23#include "qgslogger.h"
24#include "qgsmessagelog.h"
28#include "moc_qgsvectorlayerexporter.cpp"
29#include "qgsproviderregistry.h"
30#include "qgsexception.h"
32#include "qgsvectorlayer.h"
33#include "qgsabstractgeometry.h"
35
36#include <QProgressDialog>
37#include <QThread>
38
40 const QString &uri,
41 const QgsFields &fields,
42 Qgis::WkbType geometryType,
43 const QgsCoordinateReferenceSystem &destCRS,
44 bool overwrite,
45 QMap<int, int> *oldToNewAttrIdx,
46 QString *errorMessage,
47 const QMap<QString, QVariant> *options
48);
49
50
51//
52// QgsVectorLayerExporter::ExportOptions
53//
54
56{
57 mTransformContext = context;
58}
59
64
69
74
76{
77 mExtent = extent;
78}
79
84
86{
87 mFilterExpression = expression;
88}
89
91{
92 return mFilterExpression;
93}
94
96{
97 mExpressionContext = context;
98}
99
101{
102 return mExpressionContext;
103}
104
105QList<QgsVectorLayerExporter::OutputField> QgsVectorLayerExporter::ExportOptions::outputFields() const
106{
107 return mOutputFields;
108}
109
110void QgsVectorLayerExporter::ExportOptions::setOutputFields( const QList<QgsVectorLayerExporter::OutputField> &fields )
111{
112 mOutputFields = fields;
113}
114
115
116//
117// QgsVectorLayerExporter
118//
119
121 const QString &providerKey,
122 const QgsFields &fields,
123 Qgis::WkbType geometryType,
125 bool overwrite,
126 const QMap<QString, QVariant> &options,
127 QgsFeatureSink::SinkFlags sinkFlags )
128 : mErrorCount( 0 )
129 , mAttributeCount( -1 )
130
131{
132 mProvider = nullptr;
133
134 QMap<QString, QVariant> modifiedOptions( options );
135
136 if ( providerKey == QLatin1String( "ogr" ) &&
137 options.contains( QStringLiteral( "driverName" ) ) &&
138 ( options[ QStringLiteral( "driverName" ) ].toString().compare( QLatin1String( "GPKG" ), Qt::CaseInsensitive ) == 0 ||
139 options[ QStringLiteral( "driverName" ) ].toString().compare( QLatin1String( "SQLite" ), Qt::CaseInsensitive ) == 0 ) )
140 {
141 if ( geometryType != Qgis::WkbType::NoGeometry )
142 {
143 // For GPKG/Spatialite, we explicitly ask not to create a spatial index at
144 // layer creation since this would slow down inserts. Defer its creation
145 // to end of exportLayer() or destruction of this object.
146 QStringList modifiedLayerOptions;
147 if ( options.contains( QStringLiteral( "layerOptions" ) ) )
148 {
149 const QStringList layerOptions = options.value( QStringLiteral( "layerOptions" ) ).toStringList();
150 for ( const QString &layerOption : layerOptions )
151 {
152 if ( layerOption.compare( QLatin1String( "SPATIAL_INDEX=YES" ), Qt::CaseInsensitive ) == 0 ||
153 layerOption.compare( QLatin1String( "SPATIAL_INDEX=ON" ), Qt::CaseInsensitive ) == 0 ||
154 layerOption.compare( QLatin1String( "SPATIAL_INDEX=TRUE" ), Qt::CaseInsensitive ) == 0 ||
155 layerOption.compare( QLatin1String( "SPATIAL_INDEX=1" ), Qt::CaseInsensitive ) == 0 )
156 {
157 // do nothing
158 }
159 else if ( layerOption.compare( QLatin1String( "SPATIAL_INDEX=NO" ), Qt::CaseInsensitive ) == 0 ||
160 layerOption.compare( QLatin1String( "SPATIAL_INDEX=OFF" ), Qt::CaseInsensitive ) == 0 ||
161 layerOption.compare( QLatin1String( "SPATIAL_INDEX=FALSE" ), Qt::CaseInsensitive ) == 0 ||
162 layerOption.compare( QLatin1String( "SPATIAL_INDEX=0" ), Qt::CaseInsensitive ) == 0 )
163 {
164 mCreateSpatialIndex = false;
165 }
166 else
167 {
168 modifiedLayerOptions << layerOption;
169 }
170 }
171 }
172 modifiedLayerOptions << QStringLiteral( "SPATIAL_INDEX=FALSE" );
173 modifiedOptions[ QStringLiteral( "layerOptions" ) ] = modifiedLayerOptions;
174 }
175 }
176
177 // create an empty layer
178 QString errMsg;
180 QString uriUpdated;
181 mError = pReg->createEmptyLayer( providerKey, uri, fields, geometryType, crs, overwrite, mOldToNewAttrIdx,
182 errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr, uriUpdated );
183
185 {
186 mErrorMessage = errMsg;
187 return;
188 }
189
190 const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
191 for ( const int idx : constMOldToNewAttrIdx )
192 {
193 if ( idx > mAttributeCount )
194 mAttributeCount = idx;
195 }
196
197 mAttributeCount++;
198
199 QgsDebugMsgLevel( QStringLiteral( "Created empty layer" ), 2 );
200
201 // Oracle specific HACK: we cannot guess the geometry type when there is no rows, so we need
202 // to force it in the uri
203 if ( providerKey == QLatin1String( "oracle" ) )
204 {
205 uriUpdated += QStringLiteral( " type=%1" ).arg( QgsWkbTypes::displayString( geometryType ) );
206 }
207
208 const QgsDataProvider::ProviderOptions providerOptions;
209 QgsVectorDataProvider *vectorProvider = qobject_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) );
210 if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & Qgis::VectorProviderCapability::AddFeatures ) == 0 )
211 {
213 mErrorMessage = QObject::tr( "Loading of layer failed" );
214
215 delete vectorProvider;
216 return;
217 }
218
219 // If the result is a geopackage layer and there is already a field name FID requested which
220 // might contain duplicates, make sure to generate a new field with a unique name instead
221 // that will be filled by ogr with unique values.
222
223 // HACK sorry
224 const QString path = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "ogr" ), uri ).value( QStringLiteral( "path" ) ).toString();
225 if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
226 {
227 const QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString();
228 const int fidIdx = fields.lookupField( fidName );
229 if ( fidIdx != -1 )
230 {
231 mOldToNewAttrIdx.remove( fidIdx );
232 }
233 }
234
235 mProvider = vectorProvider;
237}
238
240{
241 flushBuffer();
242
243 if ( mCreateSpatialIndex )
244 {
245 createSpatialIndex();
246 }
247
248 delete mProvider;
249}
250
255
257{
258 return mErrorMessage;
259}
260
265
267{
268 QgsFeatureList::iterator fIt = features.begin();
269 bool result = true;
270 for ( ; fIt != features.end(); ++fIt )
271 {
272 result = result && addFeature( *fIt, flags );
273 }
274 return result;
275}
276
278{
279 const QgsAttributes attrs = feat.attributes();
280
281 QgsFeature newFeat;
282 if ( feat.hasGeometry() )
283 newFeat.setGeometry( feat.geometry() );
284
285 newFeat.initAttributes( mAttributeCount );
286
287 for ( int i = 0; i < attrs.count(); ++i )
288 {
289 // add only mapped attributes (un-mapped ones will not be present in the
290 // destination layer)
291 const int dstIdx = mOldToNewAttrIdx.value( i, -1 );
292 if ( dstIdx < 0 )
293 continue;
294
295 QgsDebugMsgLevel( QStringLiteral( "moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
296 newFeat.setAttribute( dstIdx, attrs.at( i ) );
297 }
298
299 mFeatureBuffer.append( newFeat );
300 mFeatureBufferMemoryUsage += newFeat.approximateMemoryUsage();
301
302 if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
303 {
304 return flushBuffer();
305 }
306
307 return true;
308}
309
311{
312 return mErrorMessage;
313}
314
316{
317 mFeatureBufferMemoryUsage = 0;
318 if ( mFeatureBuffer.count() <= 0 )
319 return true;
320
321 if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
322 {
323 const QStringList errors = mProvider->errors();
324 mProvider->clearErrors();
325
326 mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors were: \n%3" )
327 .arg( mFeatureBuffer.first().id() )
328 .arg( mFeatureBuffer.last().id() )
329 .arg( errors.join( QLatin1Char( '\n' ) ) );
330
332 mErrorCount += mFeatureBuffer.count();
333
334 mFeatureBuffer.clear();
335 QgsDebugError( mErrorMessage );
336 return false;
337 }
338
339 mFeatureBuffer.clear();
340 return true;
341}
342
343bool QgsVectorLayerExporter::createSpatialIndex()
344{
345 mCreateSpatialIndex = false;
346 if ( mProvider && ( mProvider->capabilities() & Qgis::VectorProviderCapability::CreateSpatialIndex ) != 0 )
347 {
348 return mProvider->createSpatialIndex();
349 }
350 else
351 {
352 return true;
353 }
354}
355
357 const QString &uri,
358 const QString &providerKey,
359 const QgsCoordinateReferenceSystem &destCRS,
360 bool onlySelected,
361 QString *errorMessage,
362 const QMap<QString, QVariant> &options,
363 QgsFeedback *feedback )
364{
365 ExportOptions exportOptions;
366 exportOptions.setSelectedOnly( onlySelected );
367 exportOptions.setDestinationCrs( destCRS );
368 exportOptions.setTransformContext( layer->transformContext() );
369 return exportLayer( layer, uri, providerKey, exportOptions, errorMessage, options, feedback );
370}
371
372Qgis::VectorExportResult QgsVectorLayerExporter::exportLayer( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const ExportOptions &exportOptions, QString *errorMessage, const QMap<QString, QVariant> &_providerOptions, QgsFeedback *feedback )
373{
374 QgsExpressionContext expressionContext = exportOptions.expressionContext();
375
378 bool shallTransform = false;
379
380 if ( !layer )
382
383 if ( exportOptions.destinationCrs().isValid() )
384 {
385 // This means we should transform
386 outputCRS = exportOptions.destinationCrs();
387 shallTransform = true;
388 }
389 else
390 {
391 // This means we shouldn't transform, use source CRS as output (if defined)
392 outputCRS = layer->crs();
393 }
394
395 QMap<QString, QVariant> providerOptions = _providerOptions;
396 const bool overwrite = providerOptions.take( QStringLiteral( "overwrite" ) ).toBool();
397 const bool forceSinglePartGeom = providerOptions.take( QStringLiteral( "forceSinglePartGeometryType" ) ).toBool();
398
399 QgsFields outputFields;
400 bool useFieldMapping = false;
401 QList<QgsExpression> expressions;
402 if ( exportOptions.outputFields().isEmpty() )
403 {
404 outputFields = layer->fields();
405 }
406 else
407 {
408 useFieldMapping = true;
409 const QList<QgsVectorLayerExporter::OutputField> exportFieldDefinitions = exportOptions.outputFields();
410 for ( const QgsVectorLayerExporter::OutputField &field : exportFieldDefinitions )
411 {
412 outputFields.append( field.field );
413 expressions.append( QgsExpression( field.expression ) );
414 expressions.last().prepare( &expressionContext );
415 if ( expressions.last().hasParserError() )
416 {
417 if ( errorMessage )
418 *errorMessage = QObject::tr( "Parser error for field \"%1\" with expression \"%2\": %3" )
419 .arg(
420 field.field.name(),
421 field.expression,
422 expressions.last().parserErrorString()
423 );
425 }
426 }
427 }
428
429 Qgis::WkbType wkbType = layer->wkbType();
430
431 bool convertGeometryToSinglePart = false;
432 if ( forceSinglePartGeom && QgsWkbTypes::isMultiType( wkbType ) )
433 {
434 wkbType = QgsWkbTypes::singleType( wkbType );
435 convertGeometryToSinglePart = true;
436 }
437
438 auto writer = std::make_unique< QgsVectorLayerExporter >(
439 uri, providerKey, outputFields, wkbType, outputCRS, overwrite, providerOptions );
440
441 // check whether file creation was successful
442 const Qgis::VectorExportResult err = writer->errorCode();
444 {
445 if ( errorMessage )
446 *errorMessage = writer->errorMessage();
447 return err;
448 }
449
450 if ( errorMessage )
451 {
452 errorMessage->clear();
453 }
454
455 // Create our transform
456 if ( exportOptions.destinationCrs().isValid() )
457 {
458 ct = QgsCoordinateTransform( layer->crs(), exportOptions.destinationCrs(), exportOptions.transformContext() );
459 }
460
461 // Check for failure
462 if ( !ct.isValid() )
463 shallTransform = false;
464
466 if ( wkbType == Qgis::WkbType::NoGeometry )
468
469 if ( !exportOptions.extent().isNull() )
470 {
471 QgsCoordinateTransform extentFilterTransform( exportOptions.extent().crs(), layer->crs(), exportOptions.transformContext() );
472 extentFilterTransform.setBallparkTransformsAreAppropriate( true );
473
474 try
475 {
476 const QgsRectangle layerExtent = extentFilterTransform.transformBoundingBox( exportOptions.extent() );
477 req.setFilterRect( layerExtent );
478 }
479 catch ( QgsCsException &e )
480 {
481 QgsDebugError( QStringLiteral( "Could not transform filter extent: %1" ).arg( e.what() ) );
482 }
483 }
484
485 if ( !exportOptions.filterExpression().isEmpty() )
486 {
487 req.setFilterExpression( exportOptions.filterExpression() );
488 req.setExpressionContext( expressionContext );
489 }
490 else if ( exportOptions.selectedOnly() )
491 {
492 req.setFilterFids( layer->selectedFeatureIds() );
493 }
494
495 QgsFeatureIterator fit = layer->getFeatures( req );
496
497 long long n = 0;
498 const long long approxTotal = exportOptions.selectedOnly() ? layer->selectedFeatureCount() : layer->featureCount();
499
500 if ( errorMessage )
501 {
502 *errorMessage = QObject::tr( "Feature write errors:" );
503 }
504
505 bool canceled = false;
506
507 // write all features
508 QgsFeature sourceFeature;
509 while ( fit.nextFeature( sourceFeature ) )
510 {
511 if ( feedback && feedback->isCanceled() )
512 {
513 canceled = true;
514 if ( errorMessage )
515 {
516 *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
517 }
518 break;
519 }
520
521 if ( writer->errorCount() > 1000 )
522 {
523 if ( errorMessage )
524 {
525 *errorMessage += '\n' + QObject::tr( "Stopping after %n error(s)", nullptr, writer->errorCount() );
526 }
527 break;
528 }
529
530 QgsFeature outputFeature( outputFields );
531 outputFeature.setId( sourceFeature.id() );
532 outputFeature.setGeometry( sourceFeature.geometry() );
533
534 if ( shallTransform )
535 {
536 try
537 {
538 if ( outputFeature.hasGeometry() )
539 {
540 QgsGeometry g = outputFeature.geometry();
541 g.transform( ct );
542 outputFeature.setGeometry( g );
543 }
544 }
545 catch ( QgsCsException &e )
546 {
547 const QString msg = QObject::tr( "Failed to transform feature with ID '%1'. Writing stopped. (Exception: %2)" )
548 .arg( sourceFeature.id() ).arg( e.what() );
549 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
550 if ( errorMessage )
551 *errorMessage += '\n' + msg;
552
554 }
555 }
556
557 // Handles conversion to single-part
558 if ( convertGeometryToSinglePart && outputFeature.geometry().isMultipart() )
559 {
560 QgsGeometry singlePartGeometry { outputFeature.geometry() };
561 // We want a failure if the geometry cannot be converted to single-part without data loss!
562 // check if there are more than one part
563 const QgsGeometryCollection *c = qgsgeometry_cast<const QgsGeometryCollection *>( singlePartGeometry.constGet() );
564 if ( ( c && c->partCount() > 1 ) || ! singlePartGeometry.convertToSingleType() )
565 {
566 const QString msg = QObject::tr( "Failed to transform a feature with ID '%1' to single part. Writing stopped." )
567 .arg( sourceFeature.id() );
568 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
569 if ( errorMessage )
570 *errorMessage += '\n' + msg;
572 }
573 outputFeature.setGeometry( singlePartGeometry );
574 }
575
576 // handle attribute mapping
577 if ( useFieldMapping )
578 {
579 QgsAttributes attributes;
580 attributes.reserve( expressions.size() );
581 for ( auto it = expressions.begin(); it != expressions.end(); ++it )
582 {
583 if ( it->isValid() )
584 {
585 expressionContext.setFeature( sourceFeature );
586 const QVariant value = it->evaluate( &expressionContext );
587 if ( it->hasEvalError() )
588 {
589 const QString msg = QObject::tr( "Evaluation error in expression \"%1\": %2" ).arg( it->expression(), it->evalErrorString() );
590 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
591 if ( errorMessage )
592 *errorMessage += '\n' + msg;
594 }
595 attributes.append( value );
596 }
597 else
598 {
599 attributes.append( QVariant() );
600 }
601 }
602 outputFeature.setAttributes( attributes );
603 }
604 else
605 {
606 outputFeature.setAttributes( sourceFeature.attributes() );
607 }
608
609 if ( !writer->addFeature( outputFeature ) )
610 {
611 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
612 {
613 *errorMessage += '\n' + writer->errorMessage();
614 }
615 }
616 n++;
617
618 if ( feedback )
619 {
620 feedback->setProgress( 100.0 * static_cast< double >( n ) / static_cast< double >( approxTotal ) );
621 }
622
623 }
624
625 // flush the buffer to be sure that all features are written
626 if ( !writer->flushBuffer() )
627 {
628 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
629 {
630 *errorMessage += '\n' + writer->errorMessage();
631 }
632 }
633 const int errors = writer->errorCount();
634
635 if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
636 {
637 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
638 {
639 *errorMessage += '\n' + writer->errorMessage();
640 }
641 }
642
643 writer.reset();
644
645 if ( errorMessage )
646 {
647 if ( errors > 0 )
648 {
649 *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
650 }
651 else
652 {
653 errorMessage->clear();
654 }
655 }
656
657 if ( canceled )
659 else if ( errors > 0 )
661
663}
664
665//
666// QgsVectorLayerExporterTask
667//
668
669QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer )
670 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
671 , mLayer( layer )
672 , mOwnsLayer( ownsLayer )
673 , mDestUri( uri )
674 , mDestProviderKey( providerKey )
675 , mOptions( options )
676 , mOwnedFeedback( new QgsFeedback() )
677{
678 mExportOptions.setDestinationCrs( destinationCrs );
679 mExportOptions.setTransformContext( layer->transformContext() );
680
681 if ( mLayer )
682 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
683}
684
685QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsVectorLayerExporter::ExportOptions &exportOptions, const QMap<QString, QVariant> &providerOptions, bool ownsLayer )
686 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
687 , mLayer( layer )
688 , mOwnsLayer( ownsLayer )
689 , mDestUri( uri )
690 , mDestProviderKey( providerKey )
691 , mExportOptions( exportOptions )
692 , mOptions( providerOptions )
693 , mOwnedFeedback( new QgsFeedback() )
694{
695 if ( mLayer )
696 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
697 if ( mLayer && mOwnsLayer )
698 mLayer->moveToThread( nullptr );
699}
700
701QgsVectorLayerExporterTask *QgsVectorLayerExporterTask::withLayerOwnership( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options )
702{
703 auto newTask = std::make_unique<QgsVectorLayerExporterTask>( layer, uri, providerKey, destinationCrs, options, true );
704 return newTask.release();
705}
706
708{
709 mOwnedFeedback->cancel();
711}
712
714{
715 if ( !mLayer )
716 return false;
717
718 if ( mOwnsLayer )
719 mLayer->moveToThread( QThread::currentThread() );
720
721 connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
722
723
725 mLayer.data(), mDestUri, mDestProviderKey, mExportOptions, &mErrorMessage,
726 mOptions, mOwnedFeedback.get() );
727
728 if ( mOwnsLayer )
729 mLayer->moveToThread( nullptr );
730
731 return mError == Qgis::VectorExportResult::Success;
732}
733
735{
736 if ( mOwnsLayer && mLayer )
737 mLayer->moveToThread( QThread::currentThread() );
738
739 // QgsMapLayer has QTimer member, which must not be destroyed from another thread
740 if ( mOwnsLayer )
741 delete mLayer;
742
743 if ( result )
744 emit exportComplete();
745 else
746 emit errorOccurred( mError, mErrorMessage );
747}
@ AddFeatures
Allows adding features.
@ CreateSpatialIndex
Allows creation of spatial index.
VectorExportResult
Vector layer export result codes.
Definition qgis.h:1016
@ Success
No errors were encountered.
@ ErrorInvalidLayer
Could not access newly created destination layer.
@ ErrorFeatureWriteFailed
An error occurred while writing a feature to the destination.
@ ErrorAttributeCreationFailed
Destination provider was unable to create an attribute.
@ UserCanceled
User canceled the export.
@ ErrorProjectingFeatures
An error occurred while reprojecting features to destination CRS.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QFlags< VectorDataProviderAttributeEditCapability > VectorDataProviderAttributeEditCapabilities
Attribute editing capabilities which may be supported by vector data providers.
Definition qgis.h:566
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
@ NoGeometry
No geometry.
A vector of attributes.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Contains information about the context in which a coordinate transform is executed.
Handles coordinate transforms between two coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const
Transforms a rectangle from the source CRS to the destination CRS.
bool isValid() const
Returns true if the coordinate transform is valid, ie both the source and destination CRS have been s...
Custom exception class for Coordinate Reference System related exceptions.
virtual bool isValid() const =0
Returns true if this is a valid layer.
QString what() const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Handles parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
QFlags< SinkFlag > SinkFlags
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
QFlags< Flag > Flags
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
QgsAttributes attributes
Definition qgsfeature.h:67
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
QgsFeatureId id
Definition qgsfeature.h:66
int approximateMemoryUsage() const
Returns the approximate RAM usage of the feature, in bytes.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setId(QgsFeatureId id)
Sets the feature id for this feature.
QgsGeometry geometry
Definition qgsfeature.h:69
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:53
void progressChanged(double progress)
Emitted when the feedback object reports a progress change.
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition qgsfeedback.h:61
Container of fields for a vector layer.
Definition qgsfields.h:46
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:70
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A geometry is the spatial representation of a feature.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:84
QgsCoordinateTransformContext transformContext() const
Returns the layer data provider coordinate transform context or a default transform context if the la...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
A registry / canonical manager of data providers.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
Qgis::VectorExportResult createEmptyLayer(const QString &providerKey, const QString &uri, const QgsFields &fields, Qgis::WkbType wkbType, const QgsCoordinateReferenceSystem &srs, bool overwrite, QMap< int, int > &oldToNewAttrIdxMap, QString &errorMessage, const QMap< QString, QVariant > *options, QString &createdLayerName)
Creates new empty vector layer.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsDataProvider * createProvider(const QString &providerKey, const QString &dataSource, const QgsDataProvider::ProviderOptions &options=QgsDataProvider::ProviderOptions(), Qgis::DataProviderReadFlags flags=Qgis::DataProviderReadFlags())
Creates a new instance of a provider.
A rectangle specified with double values.
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
A QgsRectangle with associated coordinate reference system.
Abstract base class for long running background tasks.
virtual void cancel()
Notifies the task that it should terminate.
void setDependentLayers(const QList< QgsMapLayer * > &dependentLayers)
Sets a list of layers on which the task depends.
void setProgress(double progress)
Sets the task's current progress.
Base class for vector data providers.
virtual bool createSpatialIndex()
Creates a spatial index on the datasource (if supported by the provider type).
void clearErrors()
Clear recorded errors.
QStringList errors() const
Gets recorded errors.
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
virtual Qgis::VectorDataProviderAttributeEditCapabilities attributeEditCapabilities() const
Returns the provider's supported attribute editing capabilities.
QgsTask task which performs a QgsVectorLayerExporter layer export operation as a background task.
void finished(bool result) override
If the task is managed by a QgsTaskManager, this will be called after the task has finished (whether ...
QgsVectorLayerExporterTask(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), bool ownsLayer=false)
Constructor for QgsVectorLayerExporterTask.
void exportComplete()
Emitted when exporting the layer is successfully completed.
void errorOccurred(Qgis::VectorExportResult error, const QString &errorMessage)
Emitted when an error occurs which prevented the layer being exported (or if the task is canceled).
void cancel() override
Notifies the task that it should terminate.
static QgsVectorLayerExporterTask * withLayerOwnership(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap< QString, QVariant > &options=QMap< QString, QVariant >())
Creates a new QgsVectorLayerExporterTask which has ownership over a source layer.
bool run() override
Performs the task's operation.
Encapsulates options for use with QgsVectorLayerExporter.
QgsReferencedRectangle extent() const
Returns the extent filter for the features to export.
void setExtent(const QgsReferencedRectangle &extent)
Sets an extent filter for the features to export.
void setOutputFields(const QList< QgsVectorLayerExporter::OutputField > &fields)
Sets the output field definitions for the destination table.
void setSelectedOnly(bool selected)
Sets whether the export should only include selected features.
QString filterExpression() const
Returns the filter expression for features to export.
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination coordinate reference system to use for exported features.
const QgsExpressionContext & expressionContext() const
Returns the expression context used when a filterExpression() is set.
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context used when transforming exported features.
void setFilterExpression(const QString &expression)
Set the filter expression for the features to export.
bool selectedOnly() const
Returns whether the export will only include selected features.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context to use when a filterExpression() is set.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the coordinate transform context to use when transforming exported features.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system used for exported features.
QList< QgsVectorLayerExporter::OutputField > outputFields() const
Returns the output field definitions for the destination table.
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
static Qgis::VectorExportResult exportLayer(QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destCRS, bool onlySelected=false, QString *errorMessage=nullptr, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeedback *feedback=nullptr)
Writes the contents of vector layer to a different datasource.
QString errorMessage() const
Returns any error message encountered during the export.
Qgis::VectorDataProviderAttributeEditCapabilities attributeEditCapabilities() const
Returns the attribute capabilities of the exporter.
~QgsVectorLayerExporter() override
Finalizes the export and closes the new created layer.
QString lastError() const override
Returns the most recent error encountered by the sink, e.g.
bool flushBuffer() override
Flushes any internal buffer which may exist in the sink, causing any buffered features to be added to...
Qgis::VectorExportResult errorCode() const
Returns any encountered error code, or false if no error was encountered.
QgsVectorLayerExporter(const QString &uri, const QString &provider, const QgsFields &fields, Qgis::WkbType geometryType, const QgsCoordinateReferenceSystem &crs, bool overwrite=false, const QMap< QString, QVariant > &options=QMap< QString, QVariant >(), QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags())
Constructor for QgsVectorLayerExporter.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
Represents a vector layer which manages a vector based dataset.
long long featureCount(const QString &legendKey) const
Number of features rendered with specified legend key.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
static bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
static QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
static Qgis::WkbType singleType(Qgis::WkbType type)
Returns the single type for a WKB type.
Definition qgswkbtypes.h:53
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
QList< QgsFeature > QgsFeatureList
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:41
#define QgsDebugError(str)
Definition qgslogger.h:40
Qgis::VectorExportResult createEmptyLayer_t(const QString &uri, const QgsFields &fields, Qgis::WkbType geometryType, const QgsCoordinateReferenceSystem &destCRS, bool overwrite, QMap< int, int > *oldToNewAttrIdx, QString *errorMessage, const QMap< QString, QVariant > *options)
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.
Encapsulates output field definition.