QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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 mProvider = nullptr;
137
138 QMap<QString, QVariant> modifiedOptions( options );
139
140 if ( providerKey == "ogr"_L1
141 && options.contains( u"driverName"_s )
142 && ( options[u"driverName"_s].toString().compare( "GPKG"_L1, Qt::CaseInsensitive ) == 0 || options[u"driverName"_s].toString().compare( "SQLite"_L1, Qt::CaseInsensitive ) == 0 ) )
143 {
144 if ( geometryType != Qgis::WkbType::NoGeometry )
145 {
146 // For GPKG/Spatialite, we explicitly ask not to create a spatial index at
147 // layer creation since this would slow down inserts. Defer its creation
148 // to end of exportLayer() or destruction of this object.
149 QStringList modifiedLayerOptions;
150 if ( options.contains( u"layerOptions"_s ) )
151 {
152 const QStringList layerOptions = options.value( u"layerOptions"_s ).toStringList();
153 for ( const QString &layerOption : layerOptions )
154 {
155 if ( layerOption.compare( "SPATIAL_INDEX=YES"_L1, Qt::CaseInsensitive ) == 0
156 || layerOption.compare( "SPATIAL_INDEX=ON"_L1, Qt::CaseInsensitive ) == 0
157 || layerOption.compare( "SPATIAL_INDEX=TRUE"_L1, Qt::CaseInsensitive ) == 0
158 || layerOption.compare( "SPATIAL_INDEX=1"_L1, Qt::CaseInsensitive ) == 0 )
159 {
160 // do nothing
161 }
162 else if ( layerOption.compare( "SPATIAL_INDEX=NO"_L1, Qt::CaseInsensitive ) == 0
163 || layerOption.compare( "SPATIAL_INDEX=OFF"_L1, Qt::CaseInsensitive ) == 0
164 || layerOption.compare( "SPATIAL_INDEX=FALSE"_L1, Qt::CaseInsensitive ) == 0
165 || layerOption.compare( "SPATIAL_INDEX=0"_L1, Qt::CaseInsensitive ) == 0 )
166 {
167 mCreateSpatialIndex = false;
168 }
169 else
170 {
171 modifiedLayerOptions << layerOption;
172 }
173 }
174 }
175 modifiedLayerOptions << u"SPATIAL_INDEX=FALSE"_s;
176 modifiedOptions[u"layerOptions"_s] = modifiedLayerOptions;
177 }
178 }
179
180 // create an empty layer
181 QString errMsg;
183 QString uriUpdated;
184 mError = pReg->createEmptyLayer( providerKey, uri, fields, geometryType, crs, overwrite, mOldToNewAttrIdx, errMsg, !modifiedOptions.isEmpty() ? &modifiedOptions : nullptr, uriUpdated );
185
187 {
188 mErrorMessage = errMsg;
189 return;
190 }
191
192 const auto constMOldToNewAttrIdx = mOldToNewAttrIdx;
193 for ( const int idx : constMOldToNewAttrIdx )
194 {
195 if ( idx > mAttributeCount )
196 mAttributeCount = idx;
197 }
198
199 mAttributeCount++;
200
201 QgsDebugMsgLevel( u"Created empty layer"_s, 2 );
202
203 // Oracle specific HACK: we cannot guess the geometry type when there is no rows, so we need
204 // to force it in the uri
205 if ( providerKey == "oracle"_L1 )
206 {
207 uriUpdated += u" type=%1"_s.arg( QgsWkbTypes::displayString( geometryType ) );
208 }
209
210 const QgsDataProvider::ProviderOptions providerOptions;
211 QgsVectorDataProvider *vectorProvider = qobject_cast< QgsVectorDataProvider * >( pReg->createProvider( providerKey, uriUpdated, providerOptions ) );
212 if ( !vectorProvider || !vectorProvider->isValid() || ( vectorProvider->capabilities() & Qgis::VectorProviderCapability::AddFeatures ) == 0 )
213 {
215 mErrorMessage = QObject::tr( "Loading of layer failed" );
216
217 delete vectorProvider;
218 return;
219 }
220
221 // If the result is a geopackage layer and there is already a field name FID requested which
222 // might contain duplicates, make sure to generate a new field with a unique name instead
223 // that will be filled by ogr with unique values.
224
225 // HACK sorry
226 const QString path = QgsProviderRegistry::instance()->decodeUri( u"ogr"_s, uri ).value( u"path"_s ).toString();
227 if ( sinkFlags.testFlag( QgsFeatureSink::SinkFlag::RegeneratePrimaryKey ) && path.endsWith( ".gpkg"_L1, Qt::CaseInsensitive ) )
228 {
229 const QString fidName = options.value( u"FID"_s, u"FID"_s ).toString();
230 const int fidIdx = fields.lookupField( fidName );
231 if ( fidIdx != -1 )
232 {
233 mOldToNewAttrIdx.remove( fidIdx );
234 }
235 }
236
237 mProvider = vectorProvider;
239}
240
242{
243 flushBuffer();
244
245 if ( mCreateSpatialIndex )
246 {
247 createSpatialIndex();
248 }
249
250 delete mProvider;
251}
252
257
259{
260 return mErrorMessage;
261}
262
267
269{
270 QgsFeatureList::iterator fIt = features.begin();
271 bool result = true;
272 for ( ; fIt != features.end(); ++fIt )
273 {
274 result = result && addFeature( *fIt, flags );
275 }
276 return result;
277}
278
280{
281 const QgsAttributes attrs = feat.attributes();
282
283 QgsFeature newFeat;
284 if ( feat.hasGeometry() )
285 newFeat.setGeometry( feat.geometry() );
286
287 newFeat.initAttributes( mAttributeCount );
288
289 for ( int i = 0; i < attrs.count(); ++i )
290 {
291 // add only mapped attributes (un-mapped ones will not be present in the
292 // destination layer)
293 const int dstIdx = mOldToNewAttrIdx.value( i, -1 );
294 if ( dstIdx < 0 )
295 continue;
296
297 QgsDebugMsgLevel( u"moving field from pos %1 to %2"_s.arg( i ).arg( dstIdx ), 3 );
298 newFeat.setAttribute( dstIdx, attrs.at( i ) );
299 }
300
301 mFeatureBuffer.append( newFeat );
302 mFeatureBufferMemoryUsage += newFeat.approximateMemoryUsage();
303
304 if ( mFeatureBufferMemoryUsage >= 100 * 1000 * 1000 )
305 {
306 return flushBuffer();
307 }
308
309 return true;
310}
311
313{
314 return mErrorMessage;
315}
316
318{
319 mFeatureBufferMemoryUsage = 0;
320 if ( mFeatureBuffer.count() <= 0 )
321 return true;
322
323 if ( !mProvider->addFeatures( mFeatureBuffer, QgsFeatureSink::FastInsert ) )
324 {
325 const QStringList errors = mProvider->errors();
326 mProvider->clearErrors();
327
328 mErrorMessage
329 = 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' ) ) );
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 QgsVectorLayer *layer,
358 const QString &uri,
359 const QString &providerKey,
360 const QgsCoordinateReferenceSystem &destCRS,
361 bool onlySelected,
362 QString *errorMessage,
363 const QMap<QString, QVariant> &options,
364 QgsFeedback *feedback
365)
366{
367 ExportOptions exportOptions;
368 exportOptions.setSelectedOnly( onlySelected );
369 exportOptions.setDestinationCrs( destCRS );
370 exportOptions.setTransformContext( layer->transformContext() );
371 return exportLayer( layer, uri, providerKey, exportOptions, errorMessage, options, feedback );
372}
373
375 QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const ExportOptions &exportOptions, QString *errorMessage, const QMap<QString, QVariant> &_providerOptions, QgsFeedback *feedback
376)
377{
378 QgsExpressionContext expressionContext = exportOptions.expressionContext();
379
382 bool shallTransform = false;
383
384 if ( !layer )
386
387 if ( exportOptions.destinationCrs().isValid() )
388 {
389 // This means we should transform
390 outputCRS = exportOptions.destinationCrs();
391 shallTransform = true;
392 }
393 else
394 {
395 // This means we shouldn't transform, use source CRS as output (if defined)
396 outputCRS = layer->crs();
397 }
398
399 QMap<QString, QVariant> providerOptions = _providerOptions;
400 const bool overwrite = providerOptions.take( u"overwrite"_s ).toBool();
401 const bool forceSinglePartGeom = providerOptions.take( u"forceSinglePartGeometryType"_s ).toBool();
402
403 QgsFields outputFields;
404 bool useFieldMapping = false;
405 QList<QgsExpression> expressions;
406 if ( exportOptions.outputFields().isEmpty() )
407 {
408 outputFields = layer->fields();
409 }
410 else
411 {
412 useFieldMapping = true;
413 const QList<QgsVectorLayerExporter::OutputField> exportFieldDefinitions = exportOptions.outputFields();
414 for ( const QgsVectorLayerExporter::OutputField &field : exportFieldDefinitions )
415 {
416 outputFields.append( field.field );
417 expressions.append( QgsExpression( field.expression ) );
418 expressions.last().prepare( &expressionContext );
419 if ( expressions.last().hasParserError() )
420 {
421 if ( errorMessage )
422 *errorMessage = QObject::tr( "Parser error for field \"%1\" with expression \"%2\": %3" ).arg( field.field.name(), field.expression, expressions.last().parserErrorString() );
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 >( uri, providerKey, outputFields, wkbType, outputCRS, overwrite, providerOptions );
438
439 // check whether file creation was successful
440 const Qgis::VectorExportResult err = writer->errorCode();
442 {
443 if ( errorMessage )
444 *errorMessage = writer->errorMessage();
445 return err;
446 }
447
448 if ( errorMessage )
449 {
450 errorMessage->clear();
451 }
452
453 // Create our transform
454 if ( exportOptions.destinationCrs().isValid() )
455 {
456 ct = QgsCoordinateTransform( layer->crs(), exportOptions.destinationCrs(), exportOptions.transformContext() );
457 }
458
459 // Check for failure
460 if ( !ct.isValid() )
461 shallTransform = false;
462
464 if ( wkbType == Qgis::WkbType::NoGeometry )
466
467 if ( !exportOptions.extent().isNull() )
468 {
469 QgsCoordinateTransform extentFilterTransform( exportOptions.extent().crs(), layer->crs(), exportOptions.transformContext() );
470 extentFilterTransform.setBallparkTransformsAreAppropriate( true );
471
472 try
473 {
474 const QgsRectangle layerExtent = extentFilterTransform.transformBoundingBox( exportOptions.extent() );
475 req.setFilterRect( layerExtent );
476 }
477 catch ( QgsCsException &e )
478 {
479 QgsDebugError( u"Could not transform filter extent: %1"_s.arg( e.what() ) );
480 }
481 }
482
483 if ( !exportOptions.filterExpression().isEmpty() )
484 {
485 req.setFilterExpression( exportOptions.filterExpression() );
486 req.setExpressionContext( expressionContext );
487 }
488 else if ( exportOptions.selectedOnly() )
489 {
490 req.setFilterFids( layer->selectedFeatureIds() );
491 }
492
493 QgsFeatureIterator fit = layer->getFeatures( req );
494
495 long long n = 0;
496 const long long approxTotal = exportOptions.selectedOnly() ? layer->selectedFeatureCount() : layer->featureCount();
497
498 if ( errorMessage )
499 {
500 *errorMessage = QObject::tr( "Feature write errors:" );
501 }
502
503 bool canceled = false;
504
505 // write all features
506 QgsFeature sourceFeature;
507 while ( fit.nextFeature( sourceFeature ) )
508 {
509 if ( feedback && feedback->isCanceled() )
510 {
511 canceled = true;
512 if ( errorMessage )
513 {
514 *errorMessage += '\n' + QObject::tr( "Import was canceled at %1 of %2" ).arg( n ).arg( approxTotal );
515 }
516 break;
517 }
518
519 if ( writer->errorCount() > 1000 )
520 {
521 if ( errorMessage )
522 {
523 *errorMessage += '\n' + QObject::tr( "Stopping after %n error(s)", nullptr, writer->errorCount() );
524 }
525 break;
526 }
527
528 QgsFeature outputFeature( outputFields );
529 outputFeature.setId( sourceFeature.id() );
530 outputFeature.setGeometry( sourceFeature.geometry() );
531
532 if ( shallTransform )
533 {
534 try
535 {
536 if ( outputFeature.hasGeometry() )
537 {
538 QgsGeometry g = outputFeature.geometry();
539 g.transform( ct );
540 outputFeature.setGeometry( g );
541 }
542 }
543 catch ( QgsCsException &e )
544 {
545 const QString msg = QObject::tr( "Failed to transform feature with ID '%1'. Writing stopped. (Exception: %2)" ).arg( sourceFeature.id() ).arg( e.what() );
546 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
547 if ( errorMessage )
548 *errorMessage += '\n' + msg;
549
551 }
552 }
553
554 // Handles conversion to single-part
555 if ( convertGeometryToSinglePart && outputFeature.geometry().isMultipart() )
556 {
557 QgsGeometry singlePartGeometry { outputFeature.geometry() };
558 // We want a failure if the geometry cannot be converted to single-part without data loss!
559 // check if there are more than one part
561 if ( ( c && c->partCount() > 1 ) || !singlePartGeometry.convertToSingleType() )
562 {
563 const QString msg = QObject::tr( "Failed to transform a feature with ID '%1' to single part. Writing stopped." ).arg( sourceFeature.id() );
564 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
565 if ( errorMessage )
566 *errorMessage += '\n' + msg;
568 }
569 outputFeature.setGeometry( singlePartGeometry );
570 }
571
572 // handle attribute mapping
573 if ( useFieldMapping )
574 {
575 QgsAttributes attributes;
576 attributes.reserve( expressions.size() );
577 for ( auto it = expressions.begin(); it != expressions.end(); ++it )
578 {
579 if ( it->isValid() )
580 {
581 expressionContext.setFeature( sourceFeature );
582 const QVariant value = it->evaluate( &expressionContext );
583 if ( it->hasEvalError() )
584 {
585 const QString msg = QObject::tr( "Evaluation error in expression \"%1\": %2" ).arg( it->expression(), it->evalErrorString() );
586 QgsMessageLog::logMessage( msg, QObject::tr( "Vector import" ) );
587 if ( errorMessage )
588 *errorMessage += '\n' + msg;
590 }
591 attributes.append( value );
592 }
593 else
594 {
595 attributes.append( QVariant() );
596 }
597 }
598 outputFeature.setAttributes( attributes );
599 }
600 else
601 {
602 outputFeature.setAttributes( sourceFeature.attributes() );
603 }
604
605 if ( !writer->addFeature( outputFeature ) )
606 {
607 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
608 {
609 *errorMessage += '\n' + writer->errorMessage();
610 }
611 }
612 n++;
613
614 if ( feedback )
615 {
616 feedback->setProgress( 100.0 * static_cast< double >( n ) / static_cast< double >( approxTotal ) );
617 }
618 }
619
620 // flush the buffer to be sure that all features are written
621 if ( !writer->flushBuffer() )
622 {
623 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
624 {
625 *errorMessage += '\n' + writer->errorMessage();
626 }
627 }
628 const int errors = writer->errorCount();
629
630 if ( writer->mCreateSpatialIndex && !writer->createSpatialIndex() )
631 {
632 if ( writer->errorCode() != Qgis::VectorExportResult::Success && errorMessage )
633 {
634 *errorMessage += '\n' + writer->errorMessage();
635 }
636 }
637
638 writer.reset();
639
640 if ( errorMessage )
641 {
642 if ( errors > 0 )
643 {
644 *errorMessage += '\n' + QObject::tr( "Only %1 of %2 features written." ).arg( n - errors ).arg( n );
645 }
646 else
647 {
648 errorMessage->clear();
649 }
650 }
651
652 if ( canceled )
654 else if ( errors > 0 )
656
658}
659
660//
661// QgsVectorLayerExporterTask
662//
663
665 QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options, bool ownsLayer
666)
667 : QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
668 , mLayer( layer )
669 , mOwnsLayer( ownsLayer )
670 , mDestUri( uri )
671 , mDestProviderKey( providerKey )
672 , mOptions( options )
673 , mOwnedFeedback( new QgsFeedback() )
674{
675 mExportOptions.setDestinationCrs( destinationCrs );
676 mExportOptions.setTransformContext( layer->transformContext() );
677
678 if ( mLayer )
679 setDependentLayers( QList< QgsMapLayer * >() << mLayer );
680}
681
683 QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsVectorLayerExporter::ExportOptions &exportOptions, const QMap<QString, QVariant> &providerOptions, bool ownsLayer
684)
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
701 QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, const QMap<QString, QVariant> &options
702)
703{
704 auto newTask = std::make_unique<QgsVectorLayerExporterTask>( layer, uri, providerKey, destinationCrs, options, true );
705 return newTask.release();
706}
707
709{
710 mOwnedFeedback->cancel();
712}
713
715{
716 if ( !mLayer )
717 return false;
718
719 if ( mOwnsLayer )
720 mLayer->moveToThread( QThread::currentThread() );
721
722 connect( mOwnedFeedback.get(), &QgsFeedback::progressChanged, this, &QgsVectorLayerExporterTask::setProgress );
723
724
725 mError = QgsVectorLayerExporter::exportLayer( mLayer.data(), mDestUri, mDestProviderKey, mExportOptions, &mErrorMessage, 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:527
@ CreateSpatialIndex
Allows creation of spatial index.
Definition qgis.h:532
VectorExportResult
Vector layer export result codes.
Definition qgis.h:1078
@ Success
No errors were encountered.
Definition qgis.h:1079
@ ErrorInvalidLayer
Could not access newly created destination layer.
Definition qgis.h:1086
@ ErrorFeatureWriteFailed
An error occurred while writing a feature to the destination.
Definition qgis.h:1085
@ ErrorAttributeCreationFailed
Destination provider was unable to create an attribute.
Definition qgis.h:1083
@ UserCanceled
User canceled the export.
Definition qgis.h:1090
@ ErrorProjectingFeatures
An error occurred while reprojecting features to destination CRS.
Definition qgis.h:1084
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition qgis.h:2276
QFlags< VectorDataProviderAttributeEditCapability > VectorDataProviderAttributeEditCapabilities
Attribute editing capabilities which may be supported by vector data providers.
Definition qgis.h:628
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.
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:60
Q_INVOKABLE bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
QgsAttributes attributes
Definition qgsfeature.h:69
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
QgsFeatureId id
Definition qgsfeature.h:68
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:71
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.
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:63
#define QgsDebugError(str)
Definition qgslogger.h:59
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.