QGIS API Documentation 3.99.0-Master (21b3aa880ba)
Loading...
Searching...
No Matches
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
20
21#include "qgsabstractgeometry.h"
24#include "qgsexception.h"
25#include "qgsfeature.h"
26#include "qgsfeatureiterator.h"
27#include "qgsfields.h"
28#include "qgsgeometry.h"
30#include "qgslogger.h"
31#include "qgsmessagelog.h"
32#include "qgsproviderregistry.h"
34#include "qgsvectorlayer.h"
35
36#include <QProgressDialog>
37#include <QThread>
38
39#include "moc_qgsvectorlayerexporter.cpp"
40
42 const QString &uri,
43 const QgsFields &fields,
44 Qgis::WkbType geometryType,
45 const QgsCoordinateReferenceSystem &destCRS,
46 bool overwrite,
47 QMap<int, int> *oldToNewAttrIdx,
48 QString *errorMessage,
49 const QMap<QString, QVariant> *options
50);
51
52
53//
54// QgsVectorLayerExporter::ExportOptions
55//
56
58{
59 mTransformContext = context;
60}
61
66
71
76
81
86
88{
89 mFilterExpression = expression;
90}
91
93{
94 return mFilterExpression;
95}
96
98{
99 mExpressionContext = context;
100}
101
103{
104 return mExpressionContext;
105}
106
107QList<QgsVectorLayerExporter::OutputField> QgsVectorLayerExporter::ExportOptions::outputFields() const
108{
109 return mOutputFields;
110}
111
112void QgsVectorLayerExporter::ExportOptions::setOutputFields( const QList<QgsVectorLayerExporter::OutputField> &fields )
113{
114 mOutputFields = fields;
115}
116
117
118//
119// QgsVectorLayerExporter
120//
121
123 const QString &providerKey,
124 const QgsFields &fields,
125 Qgis::WkbType geometryType,
127 bool overwrite,
128 const QMap<QString, QVariant> &options,
129 QgsFeatureSink::SinkFlags sinkFlags )
130{
131 mProvider = nullptr;
132
133 QMap<QString, QVariant> modifiedOptions( options );
134
135 if ( providerKey == QLatin1String( "ogr" ) &&
136 options.contains( QStringLiteral( "driverName" ) ) &&
137 ( options[ QStringLiteral( "driverName" ) ].toString().compare( QLatin1String( "GPKG" ), Qt::CaseInsensitive ) == 0 ||
138 options[ QStringLiteral( "driverName" ) ].toString().compare( QLatin1String( "SQLite" ), Qt::CaseInsensitive ) == 0 ) )
139 {
140 if ( geometryType != Qgis::WkbType::NoGeometry )
141 {
142 // For GPKG/Spatialite, we explicitly ask not to create a spatial index at
143 // layer creation since this would slow down inserts. Defer its creation
144 // to end of exportLayer() or destruction of this object.
145 QStringList modifiedLayerOptions;
146 if ( options.contains( QStringLiteral( "layerOptions" ) ) )
147 {
148 const QStringList layerOptions = options.value( QStringLiteral( "layerOptions" ) ).toStringList();
149 for ( const QString &layerOption : layerOptions )
150 {
151 if ( layerOption.compare( QLatin1String( "SPATIAL_INDEX=YES" ), Qt::CaseInsensitive ) == 0 ||
152 layerOption.compare( QLatin1String( "SPATIAL_INDEX=ON" ), Qt::CaseInsensitive ) == 0 ||
153 layerOption.compare( QLatin1String( "SPATIAL_INDEX=TRUE" ), Qt::CaseInsensitive ) == 0 ||
154 layerOption.compare( QLatin1String( "SPATIAL_INDEX=1" ), Qt::CaseInsensitive ) == 0 )
155 {
156 // do nothing
157 }
158 else if ( layerOption.compare( QLatin1String( "SPATIAL_INDEX=NO" ), Qt::CaseInsensitive ) == 0 ||
159 layerOption.compare( QLatin1String( "SPATIAL_INDEX=OFF" ), Qt::CaseInsensitive ) == 0 ||
160 layerOption.compare( QLatin1String( "SPATIAL_INDEX=FALSE" ), Qt::CaseInsensitive ) == 0 ||
161 layerOption.compare( QLatin1String( "SPATIAL_INDEX=0" ), Qt::CaseInsensitive ) == 0 )
162 {
163 mCreateSpatialIndex = false;
164 }
165 else
166 {
167 modifiedLayerOptions << layerOption;
168 }
169 }
170 }
171 modifiedLayerOptions << QStringLiteral( "SPATIAL_INDEX=FALSE" );
172 modifiedOptions[ QStringLiteral( "layerOptions" ) ] = modifiedLayerOptions;
173 }
174 }
175
176 // create an empty layer
177 QString errMsg;
179 QString uriUpdated;
180 mError = pReg->createEmptyLayer( providerKey, uri, fields, geometryType, crs, overwrite, mOldToNewAttrIdx,
181 errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr, uriUpdated );
182
184 {
185 mErrorMessage = errMsg;
186 return;
187 }
188
189 const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
190 for ( const int idx : constMOldToNewAttrIdx )
191 {
192 if ( idx > mAttributeCount )
193 mAttributeCount = idx;
194 }
195
196 mAttributeCount++;
197
198 QgsDebugMsgLevel( QStringLiteral( "Created empty layer" ), 2 );
199
200 // Oracle specific HACK: we cannot guess the geometry type when there is no rows, so we need
201 // to force it in the uri
202 if ( providerKey == QLatin1String( "oracle" ) )
203 {
204 uriUpdated += QStringLiteral( " type=%1" ).arg( QgsWkbTypes::displayString( geometryType ) );
205 }
206
207 const QgsDataProvider::ProviderOptions providerOptions;
208 QgsVectorDataProvider *vectorProvider = qobject_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) );
209 if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & Qgis::VectorProviderCapability::AddFeatures ) == 0 )
210 {
212 mErrorMessage = QObject::tr( "Loading of layer failed" );
213
214 delete vectorProvider;
215 return;
216 }
217
218 // If the result is a geopackage layer and there is already a field name FID requested which
219 // might contain duplicates, make sure to generate a new field with a unique name instead
220 // that will be filled by ogr with unique values.
221
222 // HACK sorry
223 const QString path = QgsProviderRegistry::instance()->decodeUri( QStringLiteral( "ogr" ), uri ).value( QStringLiteral( "path" ) ).toString();
224 if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( QLatin1String( ".gpkg" ), Qt::CaseInsensitive ) )
225 {
226 const QString fidName = options.value( QStringLiteral( "FID" ), QStringLiteral( "FID" ) ).toString();
227 const int fidIdx = fields.lookupField( fidName );
228 if ( fidIdx != -1 )
229 {
230 mOldToNewAttrIdx.remove( fidIdx );
231 }
232 }
233
234 mProvider = vectorProvider;
236}
237
239{
240 flushBuffer();
241
242 if ( mCreateSpatialIndex )
243 {
244 createSpatialIndex();
245 }
246
247 delete mProvider;
248}
249
254
256{
257 return mErrorMessage;
258}
259
264
266{
267 QgsFeatureList::iterator fIt = features.begin();
268 bool result = true;
269 for ( ; fIt != features.end(); ++fIt )
270 {
271 result = result && addFeature( *fIt, flags );
272 }
273 return result;
274}
275
277{
278 const QgsAttributes attrs = feat.attributes();
279
280 QgsFeature newFeat;
281 if ( feat.hasGeometry() )
282 newFeat.setGeometry( feat.geometry() );
283
284 newFeat.initAttributes( mAttributeCount );
285
286 for ( int i = 0; i < attrs.count(); ++i )
287 {
288 // add only mapped attributes (un-mapped ones will not be present in the
289 // destination layer)
290 const int dstIdx = mOldToNewAttrIdx.value( i, -1 );
291 if ( dstIdx < 0 )
292 continue;
293
294 QgsDebugMsgLevel( QStringLiteral( "moving field from pos %1 to %2" ).arg( i ).arg( dstIdx ), 3 );
295 newFeat.setAttribute( dstIdx, attrs.at( i ) );
296 }
297
298 mFeatureBuffer.append( newFeat );
299 mFeatureBufferMemoryUsage += newFeat.approximateMemoryUsage();
300
301 if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
302 {
303 return flushBuffer();
304 }
305
306 return true;
307}
308
310{
311 return mErrorMessage;
312}
313
315{
316 mFeatureBufferMemoryUsage = 0;
317 if ( mFeatureBuffer.count() <= 0 )
318 return true;
319
320 if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
321 {
322 const QStringList errors = mProvider->errors();
323 mProvider->clearErrors();
324
325 mErrorMessage = QObject::tr( "Creation error for features from #%1 to #%2. Provider errors were: \n%3" )
326 .arg( mFeatureBuffer.first().id() )
327 .arg( mFeatureBuffer.last().id() )
328 .arg( errors.join( QLatin1Char( '\n' ) ) );
329
331 mErrorCount += mFeatureBuffer.count();
332
333 mFeatureBuffer.clear();
334 QgsDebugError( mErrorMessage );
335 return false;
336 }
337
338 mFeatureBuffer.clear();
339 return true;
340}
341
342bool QgsVectorLayerExporter::createSpatialIndex()
343{
344 mCreateSpatialIndex = false;
345 if ( mProvider && ( mProvider->capabilities() & Qgis::VectorProviderCapability::CreateSpatialIndex ) != 0 )
346 {
347 return mProvider->createSpatialIndex();
348 }
349 else
350 {
351 return true;
352 }
353}
354
356 const QString &uri,
357 const QString &providerKey,
358 const QgsCoordinateReferenceSystem &destCRS,
359 bool onlySelected,
360 QString *errorMessage,
361 const QMap<QString, QVariant> &options,
362 QgsFeedback *feedback )
363{
364 ExportOptions exportOptions;
365 exportOptions.setSelectedOnly( onlySelected );
366 exportOptions.setDestinationCrs( destCRS );
367 exportOptions.setTransformContext( layer->transformContext() );
368 return exportLayer( layer, uri, providerKey, exportOptions, errorMessage, options, feedback );
369}
370
371Qgis::VectorExportResult QgsVectorLayerExporter::exportLayer( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const ExportOptions &exportOptions, QString *errorMessage, const QMap<QString, QVariant> &_providerOptions, QgsFeedback *feedback )
372{
373 QgsExpressionContext expressionContext = exportOptions.expressionContext();
374
377 bool shallTransform = false;
378
379 if ( !layer )
381
382 if ( exportOptions.destinationCrs().isValid() )
383 {
384 // This means we should transform
385 outputCRS = exportOptions.destinationCrs();
386 shallTransform = true;
387 }
388 else
389 {
390 // This means we shouldn't transform, use source CRS as output (if defined)
391 outputCRS = layer->crs();
392 }
393
394 QMap<QString, QVariant> providerOptions = _providerOptions;
395 const bool overwrite = providerOptions.take( QStringLiteral( "overwrite" ) ).toBool();
396 const bool forceSinglePartGeom = providerOptions.take( QStringLiteral( "forceSinglePartGeometryType" ) ).toBool();
397
398 QgsFields outputFields;
399 bool useFieldMapping = false;
400 QList<QgsExpression> expressions;
401 if ( exportOptions.outputFields().isEmpty() )
402 {
403 outputFields = layer->fields();
404 }
405 else
406 {
407 useFieldMapping = true;
408 const QList<QgsVectorLayerExporter::OutputField> exportFieldDefinitions = exportOptions.outputFields();
409 for ( const QgsVectorLayerExporter::OutputField &field : exportFieldDefinitions )
410 {
411 outputFields.append( field.field );
412 expressions.append( QgsExpression( field.expression ) );
413 expressions.last().prepare( &expressionContext );
414 if ( expressions.last().hasParserError() )
415 {
416 if ( errorMessage )
417 *errorMessage = QObject::tr( "Parser error for field \"%1\" with expression \"%2\": %3" )
418 .arg(
419 field.field.name(),
420 field.expression,
421 expressions.last().parserErrorString()
422 );
424 }
425 }
426 }
427
428 Qgis::WkbType wkbType = layer->wkbType();
429
430 bool convertGeometryToSinglePart = false;
431 if ( forceSinglePartGeom && QgsWkbTypes::isMultiType( wkbType ) )
432 {
433 wkbType = QgsWkbTypes::singleType( wkbType );
434 convertGeometryToSinglePart = true;
435 }
436
437 auto writer = std::make_unique< QgsVectorLayerExporter >(
438 uri, providerKey, outputFields, wkbType, outputCRS, overwrite, providerOptions );
439
440 // check whether file creation was successful
441 const Qgis::VectorExportResult err = writer->errorCode();
443 {
444 if ( errorMessage )
445 *errorMessage = writer->errorMessage();
446 return err;
447 }
448
449 if ( errorMessage )
450 {
451 errorMessage->clear();
452 }
453
454 // Create our transform
455 if ( exportOptions.destinationCrs().isValid() )
456 {
457 ct = QgsCoordinateTransform( layer->crs(), exportOptions.destinationCrs(), exportOptions.transformContext() );
458 }
459
460 // Check for failure
461 if ( !ct.isValid() )
462 shallTransform = false;
463
465 if ( wkbType == Qgis::WkbType::NoGeometry )
467
468 if ( !exportOptions.extent().isNull() )
469 {
470 QgsCoordinateTransform extentFilterTransform( exportOptions.extent().crs(), layer->crs(), exportOptions.transformContext() );
471 extentFilterTransform.setBallparkTransformsAreAppropriate( true );
472
473 try
474 {
475 const QgsRectangle layerExtent = extentFilterTransform.transformBoundingBox( exportOptions.extent() );
476 req.setFilterRect( layerExtent );
477 }
478 catch ( QgsCsException &e )
479 {
480 QgsDebugError( QStringLiteral( "Could not transform filter extent: %1" ).arg( e.what() ) );
481 }
482 }
483
484 if ( !exportOptions.filterExpression().isEmpty() )
485 {
486 req.setFilterExpression( exportOptions.filterExpression() );
487 req.setExpressionContext( expressionContext );
488 }
489 else if ( exportOptions.selectedOnly() )
490 {
491 req.setFilterFids( layer->selectedFeatureIds() );
492 }
493
494 QgsFeatureIterator fit = layer->getFeatures( req );
495
496 long long n = 0;
497 const long long approxTotal = exportOptions.selectedOnly() ? layer->selectedFeatureCount() : layer->featureCount();
498
499 if ( errorMessage )
500 {
501 *errorMessage = QObject::tr( "Feature write errors:" );
502 }
503
504 bool canceled = false;
505
506 // write all features
507 QgsFeature sourceFeature;
508 while ( fit.nextFeature( sourceFeature ) )
509 {
510 if ( feedback && feedback->isCanceled() )
511 {
512 canceled = true;
513 if ( errorMessage )
514 {
515 *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
516 }
517 break;
518 }
519
520 if ( writer->errorCount() > 1000 )
521 {
522 if ( errorMessage )
523 {
524 *errorMessage += '\n' + QObject::tr( "Stopping after %n error(s)", nullptr, writer->errorCount() );
525 }
526 break;
527 }
528
529 QgsFeature outputFeature( outputFields );
530 outputFeature.setId( sourceFeature.id() );
531 outputFeature.setGeometry( sourceFeature.geometry() );
532
533 if ( shallTransform )
534 {
535 try
536 {
537 if ( outputFeature.hasGeometry() )
538 {
539 QgsGeometry g = outputFeature.geometry();
540 g.transform( ct );
541 outputFeature.setGeometry( g );
542 }
543 }
544 catch ( QgsCsException &e )
545 {
546 const QString msg = QObject::tr( "Failed to transform feature with ID '%1'. Writing stopped. (Exception: %2)" )
547 .arg( sourceFeature.id() ).arg( e.what() );
548 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
549 if ( errorMessage )
550 *errorMessage += '\n' + msg;
551
553 }
554 }
555
556 // Handles conversion to single-part
557 if ( convertGeometryToSinglePart && outputFeature.geometry().isMultipart() )
558 {
559 QgsGeometry singlePartGeometry { outputFeature.geometry() };
560 // We want a failure if the geometry cannot be converted to single-part without data loss!
561 // check if there are more than one part
563 if ( ( c && c->partCount() > 1 ) || ! singlePartGeometry.convertToSingleType() )
564 {
565 const QString msg = QObject::tr( "Failed to transform a feature with ID '%1' to single part. Writing stopped." )
566 .arg( sourceFeature.id() );
567 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
568 if ( errorMessage )
569 *errorMessage += '\n' + msg;
571 }
572 outputFeature.setGeometry( singlePartGeometry );
573 }
574
575 // handle attribute mapping
576 if ( useFieldMapping )
577 {
578 QgsAttributes attributes;
579 attributes.reserve( expressions.size() );
580 for ( auto it = expressions.begin(); it != expressions.end(); ++it )
581 {
582 if ( it->isValid() )
583 {
584 expressionContext.setFeature( sourceFeature );
585 const QVariant value = it->evaluate( &expressionContext );
586 if ( it->hasEvalError() )
587 {
588 const QString msg = QObject::tr( "Evaluation error in expression \"%1\": %2" ).arg( it->expression(), it->evalErrorString() );
589 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
590 if ( errorMessage )
591 *errorMessage += '\n' + msg;
593 }
594 attributes.append( value );
595 }
596 else
597 {
598 attributes.append( QVariant() );
599 }
600 }
601 outputFeature.setAttributes( attributes );
602 }
603 else
604 {
605 outputFeature.setAttributes( sourceFeature.attributes() );
606 }
607
608 if ( !writer->addFeature( outputFeature ) )
609 {
610 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
611 {
612 *errorMessage += '\n' + writer->errorMessage();
613 }
614 }
615 n++;
616
617 if ( feedback )
618 {
619 feedback->setProgress( 100.0 * static_cast< double >( n ) / static_cast< double >( approxTotal ) );
620 }
621
622 }
623
624 // flush the buffer to be sure that all features are written
625 if ( !writer->flushBuffer() )
626 {
627 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
628 {
629 *errorMessage += '\n' + writer->errorMessage();
630 }
631 }
632 const int errors = writer->errorCount();
633
634 if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
635 {
636 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
637 {
638 *errorMessage += '\n' + writer->errorMessage();
639 }
640 }
641
642 writer.reset();
643
644 if ( errorMessage )
645 {
646 if ( errors > 0 )
647 {
648 *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
649 }
650 else
651 {
652 errorMessage->clear();
653 }
654 }
655
656 if ( canceled )
658 else if ( errors > 0 )
660
662}
663
664//
665// QgsVectorLayerExporterTask
666//
667
668QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer )
669 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
670 , mLayer( layer )
671 , mOwnsLayer( ownsLayer )
672 , mDestUri( uri )
673 , mDestProviderKey( providerKey )
674 , mOptions( options )
675 , mOwnedFeedback( new QgsFeedback() )
676{
677 mExportOptions.setDestinationCrs( destinationCrs );
678 mExportOptions.setTransformContext( layer->transformContext() );
679
680 if ( mLayer )
681 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
682}
683
684QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsVectorLayerExporter::ExportOptions &exportOptions, const QMap<QString, QVariant> &providerOptions, bool ownsLayer )
685 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
686 , mLayer( layer )
687 , mOwnsLayer( ownsLayer )
688 , mDestUri( uri )
689 , mDestProviderKey( providerKey )
690 , mExportOptions( exportOptions )
691 , mOptions( providerOptions )
692 , mOwnedFeedback( new QgsFeedback() )
693{
694 if ( mLayer )
695 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
696 if ( mLayer && mOwnsLayer )
697 mLayer->moveToThread( nullptr );
698}
699
700QgsVectorLayerExporterTask *QgsVectorLayerExporterTask::withLayerOwnership( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options )
701{
702 auto newTask = std::make_unique<QgsVectorLayerExporterTask>( layer, uri, providerKey, destinationCrs, options, true );
703 return newTask.release();
704}
705
707{
708 mOwnedFeedback->cancel();
710}
711
713{
714 if ( !mLayer )
715 return false;
716
717 if ( mOwnsLayer )
718 mLayer->moveToThread( QThread::currentThread() );
719
720 connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
721
722
724 mLayer.data(), mDestUri, mDestProviderKey, mExportOptions, &mErrorMessage,
725 mOptions, mOwnedFeedback.get() );
726
727 if ( mOwnsLayer )
728 mLayer->moveToThread( nullptr );
729
730 return mError == Qgis::VectorExportResult::Success;
731}
732
734{
735 if ( mOwnsLayer && mLayer )
736 mLayer->moveToThread( QThread::currentThread() );
737
738 // QgsMapLayer has QTimer member, which must not be destroyed from another thread
739 if ( mOwnsLayer )
740 delete mLayer;
741
742 if ( result )
743 emit exportComplete();
744 else
745 emit errorOccurred( mError, mErrorMessage );
746}
@ AddFeatures
Allows adding features.
Definition qgis.h:501
@ CreateSpatialIndex
Allows creation of spatial index.
Definition qgis.h:506
VectorExportResult
Vector layer export result codes.
Definition qgis.h:1052
@ Success
No errors were encountered.
Definition qgis.h:1053
@ ErrorInvalidLayer
Could not access newly created destination layer.
Definition qgis.h:1060
@ ErrorFeatureWriteFailed
An error occurred while writing a feature to the destination.
Definition qgis.h:1059
@ ErrorAttributeCreationFailed
Destination provider was unable to create an attribute.
Definition qgis.h:1057
@ UserCanceled
User canceled the export.
Definition qgis.h:1064
@ ErrorProjectingFeatures
An error occurred while reprojecting features to destination CRS.
Definition qgis.h:1058
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition qgis.h:2196
QFlags< VectorDataProviderAttributeEditCapability > VectorDataProviderAttributeEditCapabilities
Attribute editing capabilities which may be supported by vector data providers.
Definition qgis.h:602
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:277
@ NoGeometry
No geometry.
Definition qgis.h:294
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:73
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.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool convertToSingleType()
Converts multi type geometry into single type geometry e.g.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsCoordinateReferenceSystem crs
Definition qgsmaplayer.h:87
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.
virtual void cancel()
Notifies the task that it should terminate.
QgsTask(const QString &description=QString(), QgsTask::Flags flags=AllFlags)
Constructor for QgsTask.
@ CanCancel
Task can be canceled.
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).
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
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.
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Q_INVOKABLE Qgis::WkbType wkbType() const final
Returns the WKBType or WKBUnknown in case of error.
Q_INVOKABLE const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
static Q_INVOKABLE 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
static Q_INVOKABLE bool isMultiType(Qgis::WkbType type)
Returns true if the WKB type is a multi type.
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
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QList< QgsFeature > QgsFeatureList
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:61
#define QgsDebugError(str)
Definition qgslogger.h:57
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)
Setting options for creating vector data providers.
Encapsulates output field definition.