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