QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsprocessingutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingutils.cpp
3  ------------------------
4  begin : April 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot 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 #include "qgsprocessingutils.h"
19 #include "qgsproject.h"
20 #include "qgssettings.h"
21 #include "qgsexception.h"
22 #include "qgsprocessingcontext.h"
23 #include "qgsvectorlayerexporter.h"
24 #include "qgsvectorfilewriter.h"
25 #include "qgsmemoryproviderutils.h"
27 #include "qgsprocessingalgorithm.h"
30 #include "qgsfileutils.h"
31 #include "qgsvectorlayer.h"
32 #include "qgsproviderregistry.h"
33 #include "qgsmeshlayer.h"
34 #include "qgsreferencedgeometry.h"
35 #include "qgsrasterfilewriter.h"
36 #include "qgsvectortilelayer.h"
37 
38 QList<QgsRasterLayer *> QgsProcessingUtils::compatibleRasterLayers( QgsProject *project, bool sort )
39 {
40  if ( !project )
41  return QList<QgsRasterLayer *>();
42 
43  QList<QgsRasterLayer *> layers;
44 
45  const auto rasterLayers = project->layers<QgsRasterLayer *>();
46  for ( QgsRasterLayer *l : rasterLayers )
47  {
48  if ( canUseLayer( l ) )
49  layers << l;
50  }
51 
52  if ( sort )
53  {
54  std::sort( layers.begin(), layers.end(), []( const QgsRasterLayer * a, const QgsRasterLayer * b ) -> bool
55  {
56  return QString::localeAwareCompare( a->name(), b->name() ) < 0;
57  } );
58  }
59  return layers;
60 }
61 
62 QList<QgsVectorLayer *> QgsProcessingUtils::compatibleVectorLayers( QgsProject *project, const QList<int> &geometryTypes, bool sort )
63 {
64  if ( !project )
65  return QList<QgsVectorLayer *>();
66 
67  QList<QgsVectorLayer *> layers;
68  const auto vectorLayers = project->layers<QgsVectorLayer *>();
69  for ( QgsVectorLayer *l : vectorLayers )
70  {
71  if ( canUseLayer( l, geometryTypes ) )
72  layers << l;
73  }
74 
75  if ( sort )
76  {
77  std::sort( layers.begin(), layers.end(), []( const QgsVectorLayer * a, const QgsVectorLayer * b ) -> bool
78  {
79  return QString::localeAwareCompare( a->name(), b->name() ) < 0;
80  } );
81  }
82  return layers;
83 }
84 
85 QList<QgsMeshLayer *> QgsProcessingUtils::compatibleMeshLayers( QgsProject *project, bool sort )
86 {
87  if ( !project )
88  return QList<QgsMeshLayer *>();
89 
90  QList<QgsMeshLayer *> layers;
91  const auto meshLayers = project->layers<QgsMeshLayer *>();
92  for ( QgsMeshLayer *l : meshLayers )
93  {
94  if ( canUseLayer( l ) )
95  layers << l;
96  }
97 
98  if ( sort )
99  {
100  std::sort( layers.begin(), layers.end(), []( const QgsMeshLayer * a, const QgsMeshLayer * b ) -> bool
101  {
102  return QString::localeAwareCompare( a->name(), b->name() ) < 0;
103  } );
104  }
105  return layers;
106 }
107 
108 QList<QgsMapLayer *> QgsProcessingUtils::compatibleLayers( QgsProject *project, bool sort )
109 {
110  if ( !project )
111  return QList<QgsMapLayer *>();
112 
113  QList<QgsMapLayer *> layers;
114 
115  const auto rasterLayers = compatibleRasterLayers( project, false );
116  for ( QgsRasterLayer *rl : rasterLayers )
117  layers << rl;
118 
119  const auto vectorLayers = compatibleVectorLayers( project, QList< int >(), false );
120  for ( QgsVectorLayer *vl : vectorLayers )
121  layers << vl;
122 
123  const auto meshLayers = compatibleMeshLayers( project, false );
124  for ( QgsMeshLayer *vl : meshLayers )
125  layers << vl;
126 
127  if ( sort )
128  {
129  std::sort( layers.begin(), layers.end(), []( const QgsMapLayer * a, const QgsMapLayer * b ) -> bool
130  {
131  return QString::localeAwareCompare( a->name(), b->name() ) < 0;
132  } );
133  }
134  return layers;
135 }
136 
137 QString QgsProcessingUtils::encodeProviderKeyAndUri( const QString &providerKey, const QString &uri )
138 {
139  return QStringLiteral( "%1://%2" ).arg( providerKey, uri );
140 }
141 
142 bool QgsProcessingUtils::decodeProviderKeyAndUri( const QString &string, QString &providerKey, QString &uri )
143 {
144  QRegularExpression re( QStringLiteral( "^(\\w+?):\\/\\/(.+)$" ) );
145  const QRegularExpressionMatch match = re.match( string );
146  if ( !match.hasMatch() )
147  return false;
148 
149  providerKey = match.captured( 1 );
150  uri = match.captured( 2 );
151 
152  // double check that provider is valid
153  return QgsProviderRegistry::instance()->providerMetadata( providerKey );
154 }
155 
156 QgsMapLayer *QgsProcessingUtils::mapLayerFromStore( const QString &string, QgsMapLayerStore *store, QgsProcessingUtils::LayerHint typeHint )
157 {
158  if ( !store || string.isEmpty() )
159  return nullptr;
160 
161  QList< QgsMapLayer * > layers = store->mapLayers().values();
162 
163  layers.erase( std::remove_if( layers.begin(), layers.end(), []( QgsMapLayer * layer )
164  {
165  switch ( layer->type() )
166  {
167  case QgsMapLayerType::VectorLayer:
168  return !canUseLayer( qobject_cast< QgsVectorLayer * >( layer ) );
169  case QgsMapLayerType::RasterLayer:
170  return !canUseLayer( qobject_cast< QgsRasterLayer * >( layer ) );
171  case QgsMapLayerType::PluginLayer:
172  return true;
173  case QgsMapLayerType::MeshLayer:
174  return !canUseLayer( qobject_cast< QgsMeshLayer * >( layer ) );
175  case QgsMapLayerType::VectorTileLayer:
176  return !canUseLayer( qobject_cast< QgsVectorTileLayer * >( layer ) );
177  }
178  return true;
179  } ), layers.end() );
180 
181  auto isCompatibleType = [typeHint]( QgsMapLayer * l ) -> bool
182  {
183  switch ( typeHint )
184  {
185  case LayerHint::UnknownType:
186  return true;
187 
188  case LayerHint::Vector:
189  return l->type() == QgsMapLayerType::VectorLayer;
190 
191  case LayerHint::Raster:
192  return l->type() == QgsMapLayerType::RasterLayer;
193 
194  case LayerHint::Mesh:
195  return l->type() == QgsMapLayerType::MeshLayer;
196  }
197  return true;
198  };
199 
200  for ( QgsMapLayer *l : qgis::as_const( layers ) )
201  {
202  if ( isCompatibleType( l ) && l->id() == string )
203  return l;
204  }
205  for ( QgsMapLayer *l : qgis::as_const( layers ) )
206  {
207  if ( isCompatibleType( l ) && l->name() == string )
208  return l;
209  }
210  for ( QgsMapLayer *l : qgis::as_const( layers ) )
211  {
212  if ( isCompatibleType( l ) && normalizeLayerSource( l->source() ) == normalizeLayerSource( string ) )
213  return l;
214  }
215  return nullptr;
216 }
217 
218 QgsMapLayer *QgsProcessingUtils::loadMapLayerFromString( const QString &string, const QgsCoordinateTransformContext &transformContext, LayerHint typeHint )
219 {
220  QString provider;
221  QString uri;
222  const bool useProvider = decodeProviderKeyAndUri( string, provider, uri );
223  if ( !useProvider )
224  uri = string;
225 
226  QString name;
227  // for disk based sources, we use the filename to determine a layer name
228  if ( !useProvider || ( provider == QLatin1String( "ogr" ) || provider == QLatin1String( "gdal" ) || provider == QLatin1String( "mdal" ) ) )
229  {
230  QStringList components = uri.split( '|' );
231  if ( components.isEmpty() )
232  return nullptr;
233 
234  QFileInfo fi;
235  if ( QFileInfo::exists( uri ) )
236  fi = QFileInfo( uri );
237  else if ( QFileInfo::exists( components.at( 0 ) ) )
238  fi = QFileInfo( components.at( 0 ) );
239  else
240  return nullptr;
241  name = fi.baseName();
242  }
243  else
244  {
245  name = QgsDataSourceUri( uri ).table();
246  }
247 
248  // brute force attempt to load a matching layer
249  if ( typeHint == LayerHint::UnknownType || typeHint == LayerHint::Vector )
250  {
251  QgsVectorLayer::LayerOptions options { transformContext };
252  options.loadDefaultStyle = false;
253  options.skipCrsValidation = true;
254 
255  std::unique_ptr< QgsVectorLayer > layer;
256  if ( useProvider )
257  {
258  layer = qgis::make_unique<QgsVectorLayer>( uri, name, provider, options );
259  }
260  else
261  {
262  // fallback to ogr
263  layer = qgis::make_unique<QgsVectorLayer>( uri, name, QStringLiteral( "ogr" ), options );
264  }
265  if ( layer->isValid() )
266  {
267  return layer.release();
268  }
269  }
270  if ( typeHint == LayerHint::UnknownType || typeHint == LayerHint::Raster )
271  {
272  QgsRasterLayer::LayerOptions rasterOptions;
273  rasterOptions.loadDefaultStyle = false;
274  rasterOptions.skipCrsValidation = true;
275 
276  std::unique_ptr< QgsRasterLayer > rasterLayer;
277  if ( useProvider )
278  {
279  rasterLayer = qgis::make_unique< QgsRasterLayer >( uri, name, provider, rasterOptions );
280  }
281  else
282  {
283  // fallback to gdal
284  rasterLayer = qgis::make_unique< QgsRasterLayer >( uri, name, QStringLiteral( "gdal" ), rasterOptions );
285  }
286 
287  if ( rasterLayer->isValid() )
288  {
289  return rasterLayer.release();
290  }
291  }
292  if ( typeHint == LayerHint::UnknownType || typeHint == LayerHint::Mesh )
293  {
294  QgsMeshLayer::LayerOptions meshOptions;
295  meshOptions.skipCrsValidation = true;
296 
297  std::unique_ptr< QgsMeshLayer > meshLayer;
298  if ( useProvider )
299  {
300  meshLayer = qgis::make_unique< QgsMeshLayer >( uri, name, provider, meshOptions );
301  }
302  else
303  {
304  meshLayer = qgis::make_unique< QgsMeshLayer >( uri, name, QStringLiteral( "mdal" ), meshOptions );
305  }
306  if ( meshLayer->isValid() )
307  {
308  return meshLayer.release();
309  }
310  }
311  return nullptr;
312 }
313 
314 QgsMapLayer *QgsProcessingUtils::mapLayerFromString( const QString &string, QgsProcessingContext &context, bool allowLoadingNewLayers, LayerHint typeHint )
315 {
316  if ( string.isEmpty() )
317  return nullptr;
318 
319  // prefer project layers
320  QgsMapLayer *layer = nullptr;
321  if ( context.project() )
322  {
323  QgsMapLayer *layer = mapLayerFromStore( string, context.project()->layerStore(), typeHint );
324  if ( layer )
325  return layer;
326  }
327 
328  layer = mapLayerFromStore( string, context.temporaryLayerStore(), typeHint );
329  if ( layer )
330  return layer;
331 
332  if ( !allowLoadingNewLayers )
333  return nullptr;
334 
335  layer = loadMapLayerFromString( string, context.transformContext(), typeHint );
336  if ( layer )
337  {
338  context.temporaryLayerStore()->addMapLayer( layer );
339  return layer;
340  }
341  else
342  {
343  return nullptr;
344  }
345 }
346 
347 QgsProcessingFeatureSource *QgsProcessingUtils::variantToSource( const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue )
348 {
349  QVariant val = value;
350  bool selectedFeaturesOnly = false;
351  long long featureLimit = -1;
352  bool overrideGeometryCheck = false;
354  if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
355  {
356  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
357  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
358  selectedFeaturesOnly = fromVar.selectedFeaturesOnly;
359  featureLimit = fromVar.featureLimit;
360  val = fromVar.source;
361  overrideGeometryCheck = fromVar.flags & QgsProcessingFeatureSourceDefinition::Flag::FlagOverrideDefaultGeometryCheck;
362  geometryCheck = fromVar.geometryCheck;
363  }
364  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
365  {
366  // input is a QgsProcessingOutputLayerDefinition (e.g. an output from earlier in a model) - get extra properties from it
367  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
368  val = fromVar.sink;
369  }
370 
371  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( val ) ) )
372  {
373  std::unique_ptr< QgsProcessingFeatureSource> source = qgis::make_unique< QgsProcessingFeatureSource >( layer, context, false, featureLimit );
374  if ( overrideGeometryCheck )
375  source->setInvalidGeometryCheck( geometryCheck );
376  return source.release();
377  }
378 
379  QString layerRef;
380  if ( val.canConvert<QgsProperty>() )
381  {
382  layerRef = val.value< QgsProperty >().valueAsString( context.expressionContext(), fallbackValue.toString() );
383  }
384  else if ( !val.isValid() || val.toString().isEmpty() )
385  {
386  // fall back to default
387  if ( QgsVectorLayer *layer = qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( fallbackValue ) ) )
388  {
389  std::unique_ptr< QgsProcessingFeatureSource> source = qgis::make_unique< QgsProcessingFeatureSource >( layer, context, false, featureLimit );
390  if ( overrideGeometryCheck )
391  source->setInvalidGeometryCheck( geometryCheck );
392  return source.release();
393  }
394 
395  layerRef = fallbackValue.toString();
396  }
397  else
398  {
399  layerRef = val.toString();
400  }
401 
402  if ( layerRef.isEmpty() )
403  return nullptr;
404 
405  QgsVectorLayer *vl = qobject_cast< QgsVectorLayer *>( QgsProcessingUtils::mapLayerFromString( layerRef, context, true, LayerHint::Vector ) );
406  if ( !vl )
407  return nullptr;
408 
409  std::unique_ptr< QgsProcessingFeatureSource> source;
410  if ( selectedFeaturesOnly )
411  {
412  source = qgis::make_unique< QgsProcessingFeatureSource>( new QgsVectorLayerSelectedFeatureSource( vl ), context, true, featureLimit );
413  }
414  else
415  {
416  source = qgis::make_unique< QgsProcessingFeatureSource >( vl, context, false, featureLimit );
417  }
418 
419  if ( overrideGeometryCheck )
420  source->setInvalidGeometryCheck( geometryCheck );
421  return source.release();
422 }
423 
424 QgsCoordinateReferenceSystem QgsProcessingUtils::variantToCrs( const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue )
425 {
426  QVariant val = value;
427 
428  if ( val.canConvert<QgsCoordinateReferenceSystem>() )
429  {
430  // input is a QgsCoordinateReferenceSystem - done!
431  return val.value< QgsCoordinateReferenceSystem >();
432  }
433  else if ( val.canConvert<QgsProcessingFeatureSourceDefinition>() )
434  {
435  // input is a QgsProcessingFeatureSourceDefinition - get extra properties from it
436  QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( val );
437  val = fromVar.source;
438  }
439  else if ( val.canConvert<QgsProcessingOutputLayerDefinition>() )
440  {
441  // input is a QgsProcessingOutputLayerDefinition - get extra properties from it
442  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( val );
443  val = fromVar.sink;
444  }
445 
446  if ( val.canConvert<QgsProperty>() && val.value< QgsProperty >().propertyType() == QgsProperty::StaticProperty )
447  {
448  val = val.value< QgsProperty >().staticValue();
449  }
450 
451  // maybe a map layer
452  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( qvariant_cast<QObject *>( val ) ) )
453  return layer->crs();
454 
455  if ( val.canConvert<QgsProperty>() )
456  val = val.value< QgsProperty >().valueAsString( context.expressionContext(), fallbackValue.toString() );
457 
458  if ( !val.isValid() )
459  {
460  // fall back to default
461  val = fallbackValue;
462  }
463 
464  QString crsText = val.toString();
465  if ( crsText.isEmpty() )
466  crsText = fallbackValue.toString();
467 
468  if ( crsText.isEmpty() )
470 
471  // maybe special string
472  if ( context.project() && crsText.compare( QLatin1String( "ProjectCrs" ), Qt::CaseInsensitive ) == 0 )
473  return context.project()->crs();
474 
475  // maybe a map layer reference
476  if ( QgsMapLayer *layer = QgsProcessingUtils::mapLayerFromString( crsText, context ) )
477  return layer->crs();
478 
479  // else CRS from string
481  crs.createFromString( crsText );
482  return crs;
483 }
484 
485 bool QgsProcessingUtils::canUseLayer( const QgsMeshLayer *layer )
486 {
487  return layer && layer->dataProvider();
488 }
489 
490 bool QgsProcessingUtils::canUseLayer( const QgsVectorTileLayer *layer )
491 {
492  return layer && layer->isValid();
493 }
494 
495 bool QgsProcessingUtils::canUseLayer( const QgsRasterLayer *layer )
496 {
497  return layer && layer->isValid();
498 }
499 
500 bool QgsProcessingUtils::canUseLayer( const QgsVectorLayer *layer, const QList<int> &sourceTypes )
501 {
502  return layer && layer->isValid() &&
503  ( sourceTypes.isEmpty()
504  || ( sourceTypes.contains( QgsProcessing::TypeVectorPoint ) && layer->geometryType() == QgsWkbTypes::PointGeometry )
505  || ( sourceTypes.contains( QgsProcessing::TypeVectorLine ) && layer->geometryType() == QgsWkbTypes::LineGeometry )
506  || ( sourceTypes.contains( QgsProcessing::TypeVectorPolygon ) && layer->geometryType() == QgsWkbTypes::PolygonGeometry )
507  || ( sourceTypes.contains( QgsProcessing::TypeVectorAnyGeometry ) && layer->isSpatial() )
508  || sourceTypes.contains( QgsProcessing::TypeVector )
509  );
510 }
511 
512 QString QgsProcessingUtils::normalizeLayerSource( const QString &source )
513 {
514  QString normalized = source;
515  normalized.replace( '\\', '/' );
516  return normalized.trimmed();
517 }
518 
519 QString QgsProcessingUtils::variantToPythonLiteral( const QVariant &value )
520 {
521  if ( !value.isValid() )
522  return QStringLiteral( "None" );
523 
524  if ( value.canConvert<QgsProperty>() )
525  return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
526  else if ( value.canConvert<QgsCoordinateReferenceSystem>() )
527  {
528  if ( !value.value< QgsCoordinateReferenceSystem >().isValid() )
529  return QStringLiteral( "QgsCoordinateReferenceSystem()" );
530  else
531  return QStringLiteral( "QgsCoordinateReferenceSystem('%1')" ).arg( value.value< QgsCoordinateReferenceSystem >().authid() );
532  }
533  else if ( value.canConvert< QgsRectangle >() )
534  {
535  QgsRectangle r = value.value<QgsRectangle>();
536  return QStringLiteral( "'%1, %3, %2, %4'" ).arg( qgsDoubleToString( r.xMinimum() ),
539  qgsDoubleToString( r.yMaximum() ) );
540  }
541  else if ( value.canConvert< QgsReferencedRectangle >() )
542  {
544  return QStringLiteral( "'%1, %3, %2, %4 [%5]'" ).arg( qgsDoubleToString( r.xMinimum() ),
547  qgsDoubleToString( r.yMaximum() ), r.crs().authid() );
548  }
549  else if ( value.canConvert< QgsPointXY >() )
550  {
551  QgsPointXY r = value.value<QgsPointXY>();
552  return QStringLiteral( "'%1,%2'" ).arg( qgsDoubleToString( r.x() ),
553  qgsDoubleToString( r.y() ) );
554  }
555  else if ( value.canConvert< QgsReferencedPointXY >() )
556  {
557  QgsReferencedPointXY r = value.value<QgsReferencedPointXY>();
558  return QStringLiteral( "'%1,%2 [%3]'" ).arg( qgsDoubleToString( r.x() ),
559  qgsDoubleToString( r.y() ),
560  r.crs().authid() );
561  }
562 
563  switch ( value.type() )
564  {
565  case QVariant::Bool:
566  return value.toBool() ? QStringLiteral( "True" ) : QStringLiteral( "False" );
567 
568  case QVariant::Double:
569  return QString::number( value.toDouble() );
570 
571  case QVariant::Int:
572  case QVariant::UInt:
573  return QString::number( value.toInt() );
574 
575  case QVariant::LongLong:
576  case QVariant::ULongLong:
577  return QString::number( value.toLongLong() );
578 
579  case QVariant::List:
580  {
581  QStringList parts;
582  const QVariantList vl = value.toList();
583  for ( const QVariant &v : vl )
584  {
585  parts << variantToPythonLiteral( v );
586  }
587  return parts.join( ',' ).prepend( '[' ).append( ']' );
588  }
589 
590  case QVariant::Map:
591  {
592  const QVariantMap map = value.toMap();
593  QStringList parts;
594  parts.reserve( map.size() );
595  for ( auto it = map.constBegin(); it != map.constEnd(); ++it )
596  {
597  parts << QStringLiteral( "%1: %2" ).arg( stringToPythonLiteral( it.key() ), variantToPythonLiteral( it.value() ) );
598  }
599  return parts.join( ',' ).prepend( '{' ).append( '}' );
600  }
601 
602  default:
603  break;
604  }
605 
606  return QgsProcessingUtils::stringToPythonLiteral( value.toString() );
607 }
608 
609 QString QgsProcessingUtils::stringToPythonLiteral( const QString &string )
610 {
611  QString s = string;
612  s.replace( '\\', QStringLiteral( "\\\\" ) );
613  s.replace( '\n', QStringLiteral( "\\n" ) );
614  s.replace( '\r', QStringLiteral( "\\r" ) );
615  s.replace( '\t', QStringLiteral( "\\t" ) );
616  s.replace( '"', QStringLiteral( "\\\"" ) );
617  s.replace( '\'', QStringLiteral( "\\\'" ) );
618  s = s.prepend( '\'' ).append( '\'' );
619  return s;
620 }
621 
622 void QgsProcessingUtils::parseDestinationString( QString &destination, QString &providerKey, QString &uri, QString &layerName, QString &format, QMap<QString, QVariant> &options, bool &useWriter, QString &extension )
623 {
624  extension.clear();
625  bool matched = decodeProviderKeyAndUri( destination, providerKey, uri );
626 
627  if ( !matched )
628  {
629  QRegularExpression splitRx( QStringLiteral( "^(.{3,}?):(.*)$" ) );
630  QRegularExpressionMatch match = splitRx.match( destination );
631  if ( match.hasMatch() )
632  {
633  providerKey = match.captured( 1 );
634  uri = match.captured( 2 );
635  matched = true;
636  }
637  }
638 
639  if ( matched )
640  {
641  if ( providerKey == QStringLiteral( "postgis" ) ) // older processing used "postgis" instead of "postgres"
642  {
643  providerKey = QStringLiteral( "postgres" );
644  }
645  if ( providerKey == QLatin1String( "ogr" ) )
646  {
647  QgsDataSourceUri dsUri( uri );
648  if ( !dsUri.database().isEmpty() )
649  {
650  if ( !dsUri.table().isEmpty() )
651  {
652  layerName = dsUri.table();
653  options.insert( QStringLiteral( "layerName" ), layerName );
654  }
655  uri = dsUri.database();
656  extension = QFileInfo( uri ).completeSuffix();
657  format = QgsVectorFileWriter::driverForExtension( extension );
658  }
659  else
660  {
661  extension = QFileInfo( uri ).completeSuffix();
662  }
663  options.insert( QStringLiteral( "update" ), true );
664  }
665  useWriter = false;
666  }
667  else
668  {
669  useWriter = true;
670  providerKey = QStringLiteral( "ogr" );
671  QRegularExpression splitRx( QStringLiteral( "^(.*)\\.(.*?)$" ) );
672  QRegularExpressionMatch match = splitRx.match( destination );
673  if ( match.hasMatch() )
674  {
675  extension = match.captured( 2 );
676  format = QgsVectorFileWriter::driverForExtension( extension );
677  }
678 
679  if ( format.isEmpty() )
680  {
681  format = QStringLiteral( "GPKG" );
682  destination = destination + QStringLiteral( ".gpkg" );
683  }
684 
685  options.insert( QStringLiteral( "driverName" ), format );
686  uri = destination;
687  }
688 }
689 
690 QgsFeatureSink *QgsProcessingUtils::createFeatureSink( QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions, QgsFeatureSink::SinkFlags sinkFlags, QgsRemappingSinkDefinition *remappingDefinition )
691 {
692  QVariantMap options = createOptions;
693  if ( !options.contains( QStringLiteral( "fileEncoding" ) ) )
694  {
695  // no destination encoding specified, use default
696  options.insert( QStringLiteral( "fileEncoding" ), context.defaultEncoding().isEmpty() ? QStringLiteral( "system" ) : context.defaultEncoding() );
697  }
698 
699  if ( destination.isEmpty() || destination.startsWith( QLatin1String( "memory:" ) ) )
700  {
701  // strip "memory:" from start of destination
702  if ( destination.startsWith( QLatin1String( "memory:" ) ) )
703  destination = destination.mid( 7 );
704 
705  if ( destination.isEmpty() )
706  destination = QStringLiteral( "output" );
707 
708  // memory provider cannot be used with QgsVectorLayerImport - so create layer manually
709  std::unique_ptr< QgsVectorLayer > layer( QgsMemoryProviderUtils::createMemoryLayer( destination, fields, geometryType, crs ) );
710  if ( !layer || !layer->isValid() )
711  {
712  throw QgsProcessingException( QObject::tr( "Could not create memory layer" ) );
713  }
714 
715  // update destination to layer ID
716  destination = layer->id();
717 
718  // this is a factory, so we need to return a proxy
719  std::unique_ptr< QgsProcessingFeatureSink > sink( new QgsProcessingFeatureSink( layer->dataProvider(), destination, context ) );
720  context.temporaryLayerStore()->addMapLayer( layer.release() );
721 
722  return sink.release();
723  }
724  else
725  {
726  QString providerKey;
727  QString uri;
728  QString layerName;
729  QString format;
730  QString extension;
731  bool useWriter = false;
732  parseDestinationString( destination, providerKey, uri, layerName, format, options, useWriter, extension );
733 
734  QgsFields newFields = fields;
735  if ( useWriter && providerKey == QLatin1String( "ogr" ) )
736  {
737  // use QgsVectorFileWriter for OGR destinations instead of QgsVectorLayerImport, as that allows
738  // us to use any OGR format which supports feature addition
739  QString finalFileName;
741  saveOptions.fileEncoding = options.value( QStringLiteral( "fileEncoding" ) ).toString();
742  saveOptions.driverName = format;
746  if ( remappingDefinition )
747  {
749  // sniff destination file to get correct wkb type and crs
750  std::unique_ptr< QgsVectorLayer > vl = qgis::make_unique< QgsVectorLayer >( destination );
751  if ( vl->isValid() )
752  {
753  remappingDefinition->setDestinationWkbType( vl->wkbType() );
754  remappingDefinition->setDestinationCrs( vl->crs() );
755  newFields = vl->fields();
756  remappingDefinition->setDestinationFields( newFields );
757  }
758  context.expressionContext().setFields( fields );
759  }
760  else
761  {
763  }
764  std::unique_ptr< QgsVectorFileWriter > writer( QgsVectorFileWriter::create( destination, newFields, geometryType, crs, context.transformContext(), saveOptions, sinkFlags, &finalFileName ) );
765  if ( writer->hasError() )
766  {
767  throw QgsProcessingException( QObject::tr( "Could not create layer %1: %2" ).arg( destination, writer->errorMessage() ) );
768  }
769  destination = finalFileName;
770  if ( remappingDefinition )
771  {
772  std::unique_ptr< QgsRemappingProxyFeatureSink > remapSink = qgis::make_unique< QgsRemappingProxyFeatureSink >( *remappingDefinition, writer.release(), true );
773  remapSink->setExpressionContext( context.expressionContext() );
774  remapSink->setTransformContext( context.transformContext() );
775  return new QgsProcessingFeatureSink( remapSink.release(), destination, context, true );
776  }
777  else
778  return new QgsProcessingFeatureSink( writer.release(), destination, context, true );
779  }
780  else
781  {
782  const QgsVectorLayer::LayerOptions layerOptions { context.transformContext() };
783  if ( remappingDefinition )
784  {
785  //write to existing layer
786 
787  // use destination string as layer name (eg "postgis:..." )
788  if ( !layerName.isEmpty() )
789  uri += QStringLiteral( "|layername=%1" ).arg( layerName );
790 
791  std::unique_ptr< QgsVectorLayer > layer = qgis::make_unique<QgsVectorLayer>( uri, destination, providerKey, layerOptions );
792  // update destination to layer ID
793  destination = layer->id();
794  if ( layer->isValid() )
795  {
796  remappingDefinition->setDestinationWkbType( layer->wkbType() );
797  remappingDefinition->setDestinationCrs( layer->crs() );
798  remappingDefinition->setDestinationFields( layer->fields() );
799  }
800 
801  std::unique_ptr< QgsRemappingProxyFeatureSink > remapSink = qgis::make_unique< QgsRemappingProxyFeatureSink >( *remappingDefinition, layer->dataProvider(), false );
802  context.temporaryLayerStore()->addMapLayer( layer.release() );
803  remapSink->setExpressionContext( context.expressionContext() );
804  remapSink->setTransformContext( context.transformContext() );
805  context.expressionContext().setFields( fields );
806  return new QgsProcessingFeatureSink( remapSink.release(), destination, context, true );
807  }
808  else
809  {
810  //create empty layer
811  std::unique_ptr< QgsVectorLayerExporter > exporter = qgis::make_unique<QgsVectorLayerExporter>( uri, providerKey, newFields, geometryType, crs, true, options, sinkFlags );
812  if ( exporter->errorCode() )
813  {
814  throw QgsProcessingException( QObject::tr( "Could not create layer %1: %2" ).arg( destination, exporter->errorMessage() ) );
815  }
816 
817  // use destination string as layer name (eg "postgis:..." )
818  if ( !layerName.isEmpty() )
819  uri += QStringLiteral( "|layername=%1" ).arg( layerName );
820  std::unique_ptr< QgsVectorLayer > layer = qgis::make_unique<QgsVectorLayer>( uri, destination, providerKey, layerOptions );
821  // update destination to layer ID
822  destination = layer->id();
823 
824  context.temporaryLayerStore()->addMapLayer( layer.release() );
825  return new QgsProcessingFeatureSink( exporter.release(), destination, context, true );
826  }
827  }
828  }
829 }
830 
831 void QgsProcessingUtils::createFeatureSinkPython( QgsFeatureSink **sink, QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &options )
832 {
833  *sink = createFeatureSink( destination, context, fields, geometryType, crs, options );
834 }
835 
836 
838 {
839  QgsRectangle extent;
840  for ( const QgsMapLayer *layer : layers )
841  {
842  if ( !layer )
843  continue;
844 
845  if ( crs.isValid() )
846  {
847  //transform layer extent to target CRS
848  QgsCoordinateTransform ct( layer->crs(), crs, context.transformContext() );
849  try
850  {
851  QgsRectangle reprojExtent = ct.transformBoundingBox( layer->extent() );
852  extent.combineExtentWith( reprojExtent );
853  }
854  catch ( QgsCsException & )
855  {
856  // can't reproject... what to do here? hmmm?
857  // let's ignore this layer for now, but maybe we should just use the original extent?
858  }
859  }
860  else
861  {
862  extent.combineExtentWith( layer->extent() );
863  }
864 
865  }
866  return extent;
867 }
868 
869 // Deprecated
871 {
872  QgsProcessingContext context;
873  return QgsProcessingUtils::combineLayerExtents( layers, crs, context );
874 }
875 
876 QVariant QgsProcessingUtils::generateIteratingDestination( const QVariant &input, const QVariant &id, QgsProcessingContext &context )
877 {
878  if ( !input.isValid() )
879  return QStringLiteral( "memory:%1" ).arg( id.toString() );
880 
881  if ( input.canConvert<QgsProcessingOutputLayerDefinition>() )
882  {
883  QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( input );
884  QVariant newSink = generateIteratingDestination( fromVar.sink, id, context );
885  fromVar.sink = QgsProperty::fromValue( newSink );
886  return fromVar;
887  }
888  else if ( input.canConvert<QgsProperty>() )
889  {
890  QString res = input.value< QgsProperty>().valueAsString( context.expressionContext() );
891  return generateIteratingDestination( res, id, context );
892  }
893  else
894  {
895  QString res = input.toString();
896  if ( res == QgsProcessing::TEMPORARY_OUTPUT )
897  {
898  // temporary outputs map to temporary outputs!
900  }
901  else if ( res.startsWith( QLatin1String( "memory:" ) ) )
902  {
903  return res + '_' + id.toString();
904  }
905  else
906  {
907  // assume a filename type output for now
908  // TODO - uris?
909  int lastIndex = res.lastIndexOf( '.' );
910  return res.left( lastIndex ) + '_' + id.toString() + res.mid( lastIndex );
911  }
912  }
913 }
914 
916 {
917  // we maintain a list of temporary folders -- this allows us to append additional
918  // folders when a setting change causes the base temp folder to change, while deferring
919  // cleanup of ALL these temp folders until session end (we can't cleanup older folders immediately,
920  // because we don't know whether they have data in them which is still wanted)
921  static std::vector< std::unique_ptr< QTemporaryDir > > sTempFolders;
922  static QString sFolder;
923  static QMutex sMutex;
924  QMutexLocker locker( &sMutex );
925  const QString basePath = QgsSettings().value( QStringLiteral( "Processing/Configuration/TEMP_PATH2" ) ).toString();
926  if ( basePath.isEmpty() )
927  {
928  // default setting -- automatically create a temp folder
929  if ( sTempFolders.empty() )
930  {
931  const QString templatePath = QStringLiteral( "%1/processing_XXXXXX" ).arg( QDir::tempPath() );
932  std::unique_ptr< QTemporaryDir > tempFolder = qgis::make_unique< QTemporaryDir >( templatePath );
933  sFolder = tempFolder->path();
934  sTempFolders.emplace_back( std::move( tempFolder ) );
935  }
936  }
937  else if ( sFolder.isEmpty() || !sFolder.startsWith( basePath ) || sTempFolders.empty() )
938  {
939  if ( !QDir().exists( basePath ) )
940  QDir().mkpath( basePath );
941 
942  const QString templatePath = QStringLiteral( "%1/processing_XXXXXX" ).arg( basePath );
943  std::unique_ptr< QTemporaryDir > tempFolder = qgis::make_unique< QTemporaryDir >( templatePath );
944  sFolder = tempFolder->path();
945  sTempFolders.emplace_back( std::move( tempFolder ) );
946  }
947  return sFolder;
948 }
949 
950 QString QgsProcessingUtils::generateTempFilename( const QString &basename )
951 {
952  QString subPath = QUuid::createUuid().toString().remove( '-' ).remove( '{' ).remove( '}' );
953  QString path = tempFolder() + '/' + subPath;
954  if ( !QDir( path ).exists() ) //make sure the directory exists - it shouldn't, but lets be safe...
955  {
956  QDir tmpDir;
957  tmpDir.mkdir( path );
958  }
959  return path + '/' + QgsFileUtils::stringToSafeFilename( basename );
960 }
961 
963 {
964  auto getText = [map]( const QString & key )->QString
965  {
966  if ( map.contains( key ) )
967  return map.value( key ).toString();
968  return QString();
969  };
970 
971  QString s = QObject::tr( "<html><body><h2>Algorithm description</h2>\n" );
972  s += QStringLiteral( "<p>" ) + getText( QStringLiteral( "ALG_DESC" ) ) + QStringLiteral( "</p>\n" );
973 
974  QString inputs;
975 
976  const auto parameterDefinitions = algorithm->parameterDefinitions();
977  for ( const QgsProcessingParameterDefinition *def : parameterDefinitions )
978  {
979  inputs += QStringLiteral( "<h3>" ) + def->description() + QStringLiteral( "</h3>\n" );
980  inputs += QStringLiteral( "<p>" ) + getText( def->name() ) + QStringLiteral( "</p>\n" );
981  }
982  if ( !inputs.isEmpty() )
983  s += QObject::tr( "<h2>Input parameters</h2>\n" ) + inputs;
984 
985  QString outputs;
986  const auto outputDefinitions = algorithm->outputDefinitions();
987  for ( const QgsProcessingOutputDefinition *def : outputDefinitions )
988  {
989  outputs += QStringLiteral( "<h3>" ) + def->description() + QStringLiteral( "</h3>\n" );
990  outputs += QStringLiteral( "<p>" ) + getText( def->name() ) + QStringLiteral( "</p>\n" );
991  }
992  if ( !outputs.isEmpty() )
993  s += QObject::tr( "<h2>Outputs</h2>\n" ) + outputs;
994 
995  s += QLatin1String( "<br>" );
996  if ( !map.value( QStringLiteral( "ALG_CREATOR" ) ).toString().isEmpty() )
997  s += QObject::tr( "<p align=\"right\">Algorithm author: %1</p>" ).arg( getText( QStringLiteral( "ALG_CREATOR" ) ) );
998  if ( !map.value( QStringLiteral( "ALG_HELP_CREATOR" ) ).toString().isEmpty() )
999  s += QObject::tr( "<p align=\"right\">Help author: %1</p>" ).arg( getText( QStringLiteral( "ALG_HELP_CREATOR" ) ) );
1000  if ( !map.value( QStringLiteral( "ALG_VERSION" ) ).toString().isEmpty() )
1001  s += QObject::tr( "<p align=\"right\">Algorithm version: %1</p>" ).arg( getText( QStringLiteral( "ALG_VERSION" ) ) );
1002 
1003  s += QStringLiteral( "</body></html>" );
1004  return s;
1005 }
1006 
1007 QString convertToCompatibleFormatInternal( const QgsVectorLayer *vl, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, QString *layerName,
1008  long long featureLimit )
1009 {
1010  bool requiresTranslation = false;
1011 
1012  // if we are only looking for selected features then we have to export back to disk,
1013  // as we need to subset only selected features, a concept which doesn't exist outside QGIS!
1014  requiresTranslation = requiresTranslation || selectedFeaturesOnly;
1015 
1016  // if we are limiting the feature count, we better export
1017  requiresTranslation = requiresTranslation || featureLimit != -1;
1018 
1019  // if the data provider is NOT ogr, then we HAVE to convert. Otherwise we run into
1020  // issues with data providers like spatialite, delimited text where the format can be
1021  // opened outside of QGIS, but with potentially very different behavior!
1022  requiresTranslation = requiresTranslation || vl->providerType() != QLatin1String( "ogr" );
1023 
1024  // if the layer has a feature filter set, then we HAVE to convert. Feature filters are
1025  // a purely QGIS concept.
1026  requiresTranslation = requiresTranslation || !vl->subsetString().isEmpty();
1027 
1028  // if the layer opened using GDAL's virtual I/O mechanism (/vsizip/, etc.), then
1029  // we HAVE to convert as other tools may not work with it
1030  requiresTranslation = requiresTranslation || vl->source().startsWith( QLatin1String( "/vsi" ) );
1031 
1032  // Check if layer is a disk based format and if so if the layer's path has a compatible filename suffix
1033  QString diskPath;
1034  if ( !requiresTranslation )
1035  {
1036  const QVariantMap parts = QgsProviderRegistry::instance()->decodeUri( vl->providerType(), vl->source() );
1037  if ( parts.contains( QStringLiteral( "path" ) ) )
1038  {
1039  diskPath = parts.value( QStringLiteral( "path" ) ).toString();
1040  QFileInfo fi( diskPath );
1041  requiresTranslation = !compatibleFormats.contains( fi.suffix(), Qt::CaseInsensitive );
1042 
1043  // if the layer name doesn't match the filename, we need to convert the layer. This method can only return
1044  // a filename, and cannot handle layernames as well as file paths
1045  const QString srcLayerName = parts.value( QStringLiteral( "layerName" ) ).toString();
1046  if ( layerName )
1047  {
1048  // differing layer names are acceptable
1049  *layerName = srcLayerName;
1050  }
1051  else
1052  {
1053  // differing layer names are NOT acceptable
1054  requiresTranslation = requiresTranslation || ( !srcLayerName.isEmpty() && srcLayerName != fi.baseName() );
1055  }
1056  }
1057  else
1058  {
1059  requiresTranslation = true; // not a disk-based format
1060  }
1061  }
1062 
1063  if ( requiresTranslation )
1064  {
1065  QString temp = QgsProcessingUtils::generateTempFilename( baseName + '.' + preferredFormat );
1066 
1068  saveOptions.fileEncoding = context.defaultEncoding();
1069  saveOptions.driverName = QgsVectorFileWriter::driverForExtension( preferredFormat );
1070  std::unique_ptr< QgsVectorFileWriter > writer( QgsVectorFileWriter::create( temp, vl->fields(), vl->wkbType(), vl->crs(), context.transformContext(), saveOptions ) );
1071  QgsFeature f;
1072  QgsFeatureIterator it;
1073  if ( featureLimit != -1 )
1074  {
1075  if ( selectedFeaturesOnly )
1076  it = vl->getSelectedFeatures( QgsFeatureRequest().setLimit( featureLimit ) );
1077  else
1078  it = vl->getFeatures( QgsFeatureRequest().setLimit( featureLimit ) );
1079  }
1080  else
1081  {
1082  if ( selectedFeaturesOnly )
1083  it = vl->getSelectedFeatures( QgsFeatureRequest().setLimit( featureLimit ) );
1084  else
1085  it = vl->getFeatures();
1086  }
1087 
1088  while ( it.nextFeature( f ) )
1089  {
1090  if ( feedback->isCanceled() )
1091  return QString();
1092  writer->addFeature( f, QgsFeatureSink::FastInsert );
1093  }
1094  return temp;
1095  }
1096  else
1097  {
1098  return diskPath;
1099  }
1100 }
1101 
1102 QString QgsProcessingUtils::convertToCompatibleFormat( const QgsVectorLayer *vl, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, long long featureLimit )
1103 {
1104  return convertToCompatibleFormatInternal( vl, selectedFeaturesOnly, baseName, compatibleFormats, preferredFormat, context, feedback, nullptr, featureLimit );
1105 }
1106 
1107 QString QgsProcessingUtils::convertToCompatibleFormatAndLayerName( const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, QString &layerName, long long featureLimit )
1108 {
1109  layerName.clear();
1110  return convertToCompatibleFormatInternal( layer, selectedFeaturesOnly, baseName, compatibleFormats, preferredFormat, context, feedback, &layerName, featureLimit );
1111 }
1112 
1113 QgsFields QgsProcessingUtils::combineFields( const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix )
1114 {
1115  QgsFields outFields = fieldsA;
1116  QSet< QString > usedNames;
1117  for ( const QgsField &f : fieldsA )
1118  {
1119  usedNames.insert( f.name().toLower() );
1120  }
1121 
1122  for ( const QgsField &f : fieldsB )
1123  {
1124  QgsField newField = f;
1125  newField.setName( fieldsBPrefix + f.name() );
1126  if ( usedNames.contains( newField.name().toLower() ) )
1127  {
1128  int idx = 2;
1129  QString newName = newField.name() + '_' + QString::number( idx );
1130  while ( usedNames.contains( newName.toLower() ) )
1131  {
1132  idx++;
1133  newName = newField.name() + '_' + QString::number( idx );
1134  }
1135  newField.setName( newName );
1136  outFields.append( newField );
1137  }
1138  else
1139  {
1140  outFields.append( newField );
1141  }
1142  usedNames.insert( newField.name() );
1143  }
1144 
1145  return outFields;
1146 }
1147 
1148 
1149 QList<int> QgsProcessingUtils::fieldNamesToIndices( const QStringList &fieldNames, const QgsFields &fields )
1150 {
1151  QList<int> indices;
1152  if ( !fieldNames.isEmpty() )
1153  {
1154  indices.reserve( fieldNames.count() );
1155  for ( const QString &f : fieldNames )
1156  {
1157  int idx = fields.lookupField( f );
1158  if ( idx >= 0 )
1159  indices.append( idx );
1160  }
1161  }
1162  else
1163  {
1164  indices.reserve( fields.count() );
1165  for ( int i = 0; i < fields.count(); ++i )
1166  indices.append( i );
1167  }
1168  return indices;
1169 }
1170 
1171 
1172 QgsFields QgsProcessingUtils::indicesToFields( const QList<int> &indices, const QgsFields &fields )
1173 {
1174  QgsFields fieldsSubset;
1175  for ( int i : indices )
1176  fieldsSubset.append( fields.at( i ) );
1177  return fieldsSubset;
1178 }
1179 
1181 {
1182  QgsSettings settings;
1183  const int setting = settings.value( QStringLiteral( "Processing/Configuration/DefaultOutputVectorLayerExt" ), -1 ).toInt();
1184  if ( setting == -1 )
1185  return QStringLiteral( "gpkg" );
1186  return QgsVectorFileWriter::supportedFormatExtensions().value( setting, QStringLiteral( "gpkg" ) );
1187 }
1188 
1190 {
1191  QgsSettings settings;
1192  const int setting = settings.value( QStringLiteral( "Processing/Configuration/DefaultOutputRasterLayerExt" ), -1 ).toInt();
1193  if ( setting == -1 )
1194  return QStringLiteral( "tif" );
1195  return QgsRasterFileWriter::supportedFormatExtensions().value( setting, QStringLiteral( "tif" ) );
1196 }
1197 
1198 //
1199 // QgsProcessingFeatureSource
1200 //
1201 
1202 QgsProcessingFeatureSource::QgsProcessingFeatureSource( QgsFeatureSource *originalSource, const QgsProcessingContext &context, bool ownsOriginalSource, long long featureLimit )
1203  : mSource( originalSource )
1204  , mOwnsSource( ownsOriginalSource )
1205  , mInvalidGeometryCheck( QgsWkbTypes::geometryType( mSource->wkbType() ) == QgsWkbTypes::PointGeometry
1206  ? QgsFeatureRequest::GeometryNoCheck // never run geometry validity checks for point layers!
1207  : context.invalidGeometryCheck() )
1208  , mInvalidGeometryCallback( context.invalidGeometryCallback() )
1209  , mTransformErrorCallback( context.transformErrorCallback() )
1210  , mInvalidGeometryCallbackSkip( context.defaultInvalidGeometryCallbackForCheck( QgsFeatureRequest::GeometrySkipInvalid ) )
1211  , mInvalidGeometryCallbackAbort( context.defaultInvalidGeometryCallbackForCheck( QgsFeatureRequest::GeometryAbortOnInvalid ) )
1212  , mFeatureLimit( featureLimit )
1213 {}
1214 
1216 {
1217  if ( mOwnsSource )
1218  delete mSource;
1219 }
1220 
1222 {
1223  QgsFeatureRequest req( request );
1224  req.setTransformErrorCallback( mTransformErrorCallback );
1225 
1226  if ( flags & FlagSkipGeometryValidityChecks )
1228  else
1229  {
1230  req.setInvalidGeometryCheck( mInvalidGeometryCheck );
1231  req.setInvalidGeometryCallback( mInvalidGeometryCallback );
1232  }
1233 
1234  if ( mFeatureLimit != -1 && req.limit() != -1 )
1235  req.setLimit( std::min( static_cast< long long >( req.limit() ), mFeatureLimit ) );
1236  else if ( mFeatureLimit != -1 )
1237  req.setLimit( mFeatureLimit );
1238 
1239  return mSource->getFeatures( req );
1240 }
1241 
1243 {
1244  FeatureAvailability sourceAvailability = mSource->hasFeatures();
1245  if ( sourceAvailability == NoFeaturesAvailable )
1246  return NoFeaturesAvailable; // never going to be features if underlying source has no features
1247  else if ( mInvalidGeometryCheck == QgsFeatureRequest::GeometryNoCheck )
1248  return sourceAvailability;
1249  else
1250  // we don't know... source has features, but these may be filtered out by invalid geometry check
1251  return FeaturesMaybeAvailable;
1252 }
1253 
1255 {
1256  QgsFeatureRequest req( request );
1257  req.setInvalidGeometryCheck( mInvalidGeometryCheck );
1258  req.setInvalidGeometryCallback( mInvalidGeometryCallback );
1259  req.setTransformErrorCallback( mTransformErrorCallback );
1260 
1261  if ( mFeatureLimit != -1 && req.limit() != -1 )
1262  req.setLimit( std::min( static_cast< long long >( req.limit() ), mFeatureLimit ) );
1263  else if ( mFeatureLimit != -1 )
1264  req.setLimit( mFeatureLimit );
1265 
1266  return mSource->getFeatures( req );
1267 }
1268 
1270 {
1271  return mSource->sourceCrs();
1272 }
1273 
1275 {
1276  return mSource->fields();
1277 }
1278 
1280 {
1281  return mSource->wkbType();
1282 }
1283 
1285 {
1286  if ( mFeatureLimit == -1 )
1287  return mSource->featureCount();
1288  else
1289  return std::min( mFeatureLimit, static_cast< long long >( mSource->featureCount() ) );
1290 }
1291 
1293 {
1294  return mSource->sourceName();
1295 
1296 }
1297 
1298 QSet<QVariant> QgsProcessingFeatureSource::uniqueValues( int fieldIndex, int limit ) const
1299 {
1300  return mSource->uniqueValues( fieldIndex, limit );
1301 }
1302 
1303 QVariant QgsProcessingFeatureSource::minimumValue( int fieldIndex ) const
1304 {
1305  return mSource->minimumValue( fieldIndex );
1306 }
1307 
1308 QVariant QgsProcessingFeatureSource::maximumValue( int fieldIndex ) const
1309 {
1310  return mSource->maximumValue( fieldIndex );
1311 }
1312 
1314 {
1315  return mSource->sourceExtent();
1316 }
1317 
1319 {
1320  return mSource->allFeatureIds();
1321 }
1322 
1324 {
1325  return mSource->hasSpatialIndex();
1326 }
1327 
1329 {
1330  QgsExpressionContextScope *expressionContextScope = nullptr;
1331  QgsExpressionContextScopeGenerator *generator = dynamic_cast<QgsExpressionContextScopeGenerator *>( mSource );
1332  if ( generator )
1333  {
1334  expressionContextScope = generator->createExpressionContextScope();
1335  }
1336  return expressionContextScope;
1337 }
1338 
1340 {
1341  mInvalidGeometryCheck = method;
1342  switch ( mInvalidGeometryCheck )
1343  {
1345  mInvalidGeometryCallback = nullptr;
1346  break;
1347 
1349  mInvalidGeometryCallback = mInvalidGeometryCallbackSkip;
1350  break;
1351 
1353  mInvalidGeometryCallback = mInvalidGeometryCallbackAbort;
1354  break;
1355 
1356  }
1357 }
1358 
1359 
1360 //
1361 // QgsProcessingFeatureSink
1362 //
1363 QgsProcessingFeatureSink::QgsProcessingFeatureSink( QgsFeatureSink *originalSink, const QString &sinkName, QgsProcessingContext &context, bool ownsOriginalSink )
1364  : QgsProxyFeatureSink( originalSink )
1365  , mContext( context )
1366  , mSinkName( sinkName )
1367  , mOwnsSink( ownsOriginalSink )
1368 {}
1369 
1371 {
1372  if ( mOwnsSink )
1373  delete destinationSink();
1374 }
1375 
1376 bool QgsProcessingFeatureSink::addFeature( QgsFeature &feature, QgsFeatureSink::Flags flags )
1377 {
1378  bool result = QgsProxyFeatureSink::addFeature( feature, flags );
1379  if ( !result )
1380  mContext.feedback()->reportError( QObject::tr( "Feature could not be written to %1" ).arg( mSinkName ) );
1381  return result;
1382 }
1383 
1384 bool QgsProcessingFeatureSink::addFeatures( QgsFeatureList &features, QgsFeatureSink::Flags flags )
1385 {
1386  bool result = QgsProxyFeatureSink::addFeatures( features, flags );
1387  if ( !result )
1388  mContext.feedback()->reportError( QObject::tr( "%1 feature(s) could not be written to %2" ).arg( features.count() ).arg( mSinkName ) );
1389  return result;
1390 }
1391 
1392 bool QgsProcessingFeatureSink::addFeatures( QgsFeatureIterator &iterator, QgsFeatureSink::Flags flags )
1393 {
1394  bool result = QgsProxyFeatureSink::addFeatures( iterator, flags );
1395  if ( !result )
1396  mContext.feedback()->reportError( QObject::tr( "Features could not be written to %1" ).arg( mSinkName ) );
1397  return result;
1398 }
QgsProcessingFeatureSourceDefinition::selectedFeaturesOnly
bool selectedFeaturesOnly
true if only selected features in the source should be used by algorithms.
Definition: qgsprocessingparameters.h:122
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:993
QgsProcessingFeatureSource::~QgsProcessingFeatureSource
~QgsProcessingFeatureSource() override
Definition: qgsprocessingutils.cpp:1215
QgsProcessingFeatureSource::uniqueValues
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const override
Returns the set of unique values contained within the specified fieldIndex from this source.
Definition: qgsprocessingutils.cpp:1298
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:88
QgsVectorFileWriter::create
static QgsVectorFileWriter * create(const QString &fileName, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &srs, const QgsCoordinateTransformContext &transformContext, const QgsVectorFileWriter::SaveVectorOptions &options, QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags(), QString *newFilename=nullptr, QString *newLayer=nullptr)
Create a new vector file writer.
Definition: qgsvectorfilewriter.cpp:148
QgsProcessingFeatureSource::minimumValue
QVariant minimumValue(int fieldIndex) const override
Returns the minimum value for an attribute column or an invalid variant in case of error.
Definition: qgsprocessingutils.cpp:1303
QgsFeatureSource::minimumValue
virtual QVariant minimumValue(int fieldIndex) const
Returns the minimum value for an attribute column or an invalid variant in case of error.
Definition: qgsfeaturesource.cpp:52
QgsProcessingUtils::compatibleMeshLayers
static QList< QgsMeshLayer * > compatibleMeshLayers(QgsProject *project, bool sort=true)
Returns a list of mesh layers from a project which are compatible with the processing framework.
Definition: qgsprocessingutils.cpp:85
QgsProject::layerStore
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
Definition: qgsproject.cpp:1757
QgsFeatureSource::hasSpatialIndex
virtual SpatialIndexPresence hasSpatialIndex() const
Returns an enum value representing the presence of a valid spatial index on the source,...
Definition: qgsfeaturesource.cpp:190
QgsProject::layers
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
Definition: qgsproject.h:979
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsProcessingUtils::defaultVectorExtension
static QString defaultVectorExtension()
Returns the default vector extension to use, in the absence of all other constraints (e....
Definition: qgsprocessingutils.cpp:1180
QgsDataSourceUri
Definition: qgsdatasourceuri.h:35
QgsFeatureSource::sourceCrs
virtual QgsCoordinateReferenceSystem sourceCrs() const =0
Returns the coordinate reference system for features in the source.
QgsFeatureRequest::setInvalidGeometryCheck
QgsFeatureRequest & setInvalidGeometryCheck(InvalidGeometryCheck check)
Sets invalid geometry checking behavior.
Definition: qgsfeaturerequest.cpp:117
QgsVectorTileLayer
Definition: qgsvectortilelayer.h:83
QgsCoordinateTransformContext
Definition: qgscoordinatetransformcontext.h:57
QgsVectorLayer::wkbType
Q_INVOKABLE QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Definition: qgsvectorlayer.cpp:664
QgsRemappingSinkDefinition::setDestinationWkbType
void setDestinationWkbType(QgsWkbTypes::Type type)
Sets the WKB geometry type for the destination.
Definition: qgsremappingproxyfeaturesink.h:116
QgsVectorFileWriter::SaveVectorOptions
Definition: qgsvectorfilewriter.h:443
QgsProperty
A store for object properties.
Definition: qgsproperty.h:231
QgsMapLayerStore::addMapLayer
QgsMapLayer * addMapLayer(QgsMapLayer *layer, bool takeOwnership=true)
Add a layer to the store.
Definition: qgsmaplayerstore.cpp:105
QgsFeatureRequest::GeometryAbortOnInvalid
@ GeometryAbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
Definition: qgsfeaturerequest.h:116
QgsProcessingUtils::variantToSource
static QgsProcessingFeatureSource * variantToSource(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a new feature source.
Definition: qgsprocessingutils.cpp:347
QgsRectangle::combineExtentWith
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:359
QgsVectorFileWriter::CreateOrOverwriteFile
@ CreateOrOverwriteFile
Create or overwrite file.
Definition: qgsvectorfilewriter.h:264
QgsProcessingUtils::compatibleRasterLayers
static QList< QgsRasterLayer * > compatibleRasterLayers(QgsProject *project, bool sort=true)
Returns a list of raster layers from a project which are compatible with the processing framework.
Definition: qgsprocessingutils.cpp:38
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsMapLayerType::MeshLayer
@ MeshLayer
Added in 3.2.
QgsRemappingSinkDefinition::setDestinationCrs
void setDestinationCrs(const QgsCoordinateReferenceSystem &destination)
Sets the destination crs used for reprojecting incoming features to the sink's destination CRS.
Definition: qgsremappingproxyfeaturesink.h:102
QgsRemappingSinkDefinition
Definition: qgsremappingproxyfeaturesink.h:37
QgsProcessingContext::project
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Definition: qgsprocessingcontext.h:99
QgsMapLayerType::VectorLayer
@ VectorLayer
QgsReferencedRectangle
Definition: qgsreferencedgeometry.h:72
QgsProcessingFeedback
Definition: qgsprocessingfeedback.h:37
QgsMapLayer::isValid
bool isValid() const
Returns the status of the layer.
Definition: qgsmaplayer.cpp:656
QgsProcessingFeatureSource::sourceExtent
QgsRectangle sourceExtent() const override
Returns the extent of all geometries from the source.
Definition: qgsprocessingutils.cpp:1313
algorithm
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 allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
QgsProxyFeatureSink::destinationSink
QgsFeatureSink * destinationSink()
Returns the destination QgsFeatureSink which the proxy will forward features to.
Definition: qgsproxyfeaturesink.h:54
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsRasterLayer::LayerOptions::skipCrsValidation
bool skipCrsValidation
Controls whether the layer is allowed to have an invalid/unknown CRS.
Definition: qgsrasterlayer.h:139
QgsProcessingFeedback::reportError
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
Definition: qgsprocessingfeedback.cpp:39
QgsProxyFeatureSink
Definition: qgsproxyfeaturesink.h:39
QgsRectangle::xMaximum
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
QgsProcessingUtils::convertToCompatibleFormatAndLayerName
static QString convertToCompatibleFormatAndLayerName(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, QString &layerName, long long featureLimit=-1)
Converts a source vector layer to a file path and layer name of a vector layer of compatible format.
Definition: qgsprocessingutils.cpp:1107
QgsProcessing::TypeVectorPolygon
@ TypeVectorPolygon
Vector polygon layers.
Definition: qgsprocessing.h:50
QgsProcessingFeatureSource::QgsProcessingFeatureSource
QgsProcessingFeatureSource(QgsFeatureSource *originalSource, const QgsProcessingContext &context, bool ownsOriginalSource=false, long long featureLimit=-1)
Constructor for QgsProcessingFeatureSource, accepting an original feature source originalSource and p...
Definition: qgsprocessingutils.cpp:1202
QgsProcessingUtils::normalizeLayerSource
static QString normalizeLayerSource(const QString &source)
Normalizes a layer source string for safe comparison across different operating system environments.
Definition: qgsprocessingutils.cpp:512
QgsProcessingFeatureSource::createExpressionContextScope
QgsExpressionContextScope * createExpressionContextScope() const
Returns an expression context scope suitable for this source.
Definition: qgsprocessingutils.cpp:1328
QgsFields::count
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsFields
Definition: qgsfields.h:44
QgsProperty::asExpression
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
Definition: qgsproperty.cpp:332
QgsProcessingUtils::indicesToFields
static QgsFields indicesToFields(const QList< int > &indices, const QgsFields &fields)
Returns a subset of fields based on the indices of desired fields.
Definition: qgsprocessingutils.cpp:1172
QgsFeatureSource
Definition: qgsfeaturesource.h:37
QgsVectorLayer::isSpatial
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
Definition: qgsvectorlayer.cpp:3591
QgsProcessingFeatureSourceDefinition::flags
Flags flags
Flags which dictate source behavior.
Definition: qgsprocessingparameters.h:137
QgsFeatureRequest::setInvalidGeometryCallback
QgsFeatureRequest & setInvalidGeometryCallback(const std::function< void(const QgsFeature &)> &callback)
Sets a callback function to use when encountering an invalid geometry and invalidGeometryCheck() is s...
Definition: qgsfeaturerequest.cpp:123
QgsProcessingParameterDefinition
Definition: qgsprocessingparameters.h:330
QgsProcessing::TypeVectorLine
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:49
QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition: qgsprocessingutils.h:475
QgsSettings
Definition: qgssettings.h:61
QgsExpressionContext::setFields
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
Definition: qgsexpressioncontext.cpp:553
QgsProcessingOutputLayerDefinition
Definition: qgsprocessingparameters.h:199
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:68
QgsFeatureSource::uniqueValues
virtual QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const
Returns the set of unique values contained within the specified fieldIndex from this source.
Definition: qgsfeaturesource.cpp:31
QgsProcessingFeatureSource::maximumValue
QVariant maximumValue(int fieldIndex) const override
Returns the maximum value for an attribute column or an invalid variant in case of error.
Definition: qgsprocessingutils.cpp:1308
QgsExpressionContextScopeGenerator
Definition: qgsexpressioncontextscopegenerator.h:28
QgsProcessingFeatureSourceDefinition::geometryCheck
QgsFeatureRequest::InvalidGeometryCheck geometryCheck
Geometry check method to apply to this source.
Definition: qgsprocessingparameters.h:147
QgsProcessingUtils::LayerHint
LayerHint
Layer type hints.
Definition: qgsprocessingutils.h:136
QgsFeatureRequest::InvalidGeometryCheck
InvalidGeometryCheck
Handling of features with invalid geometries.
Definition: qgsfeaturerequest.h:112
QgsVectorFileWriter::NoSymbology
@ NoSymbology
Definition: qgsvectorfilewriter.h:183
QgsFeatureRequest::GeometrySkipInvalid
@ GeometrySkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
Definition: qgsfeaturerequest.h:115
QgsProperty::propertyType
Type propertyType() const
Returns the property type.
Definition: qgsproperty.cpp:261
QgsProcessingUtils::encodeProviderKeyAndUri
static QString encodeProviderKeyAndUri(const QString &providerKey, const QString &uri)
Encodes a provider key and layer uri to a single string, for use with decodeProviderKeyAndUri()
Definition: qgsprocessingutils.cpp:137
QgsFields::append
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
QgsProcessingFeatureSink::~QgsProcessingFeatureSink
~QgsProcessingFeatureSink() override
Definition: qgsprocessingutils.cpp:1370
QgsProcessing::TypeVectorPoint
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:48
QgsProcessingUtils::stringToPythonLiteral
static QString stringToPythonLiteral(const QString &string)
Converts a string to a Python string literal.
Definition: qgsprocessingutils.cpp:609
QgsProcessingFeatureSourceDefinition::source
QgsProperty source
Source definition.
Definition: qgsprocessingparameters.h:117
QgsField::name
QString name
Definition: qgsfield.h:59
QgsRectangle
Definition: qgsrectangle.h:41
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:143
QgsProperty::value
QVariant value(const QgsExpressionContext &context, const QVariant &defaultValue=QVariant(), bool *ok=nullptr) const
Calculates the current value of the property, including any transforms which are set for the property...
Definition: qgsproperty.cpp:519
QgsProcessingUtils::combineFields
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
Definition: qgsprocessingutils.cpp:1113
QgsCoordinateTransform::transformBoundingBox
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, TransformDirection direction=ForwardTransform, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
Definition: qgscoordinatetransform.cpp:511
qgsDoubleToString
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Definition: qgis.h:275
QgsProject
Definition: qgsproject.h:92
QgsProcessingUtils::LayerHint::Raster
@ Raster
Raster layer type.
QgsMeshLayer::LayerOptions
Setting options for loading mesh layers.
Definition: qgsmeshlayer.h:102
QgsProcessingUtils::generateIteratingDestination
static QVariant generateIteratingDestination(const QVariant &input, const QVariant &id, QgsProcessingContext &context)
Converts an input parameter value for use in source iterating mode, where one individual sink is crea...
Definition: qgsprocessingutils.cpp:876
QgsProcessingUtils::LayerHint::Mesh
@ Mesh
Mesh layer type, since QGIS 3.6.
qgsrasterfilewriter.h
QgsMapLayer::providerType
QString providerType() const
Returns the provider type (provider key) for this layer.
Definition: qgsmaplayer.cpp:1614
QgsProcessingFeatureSource::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request, Flags flags) const
Returns an iterator for the features in the source, respecting the supplied feature flags.
Definition: qgsprocessingutils.cpp:1221
QgsMapLayerStore::mapLayers
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all layers by layer ID.
Definition: qgsmaplayerstore.cpp:235
QgsFeatureSource::allFeatureIds
virtual QgsFeatureIds allFeatureIds() const
Returns a list of all feature IDs for features present in the source.
Definition: qgsfeaturesource.cpp:115
QgsProperty::fromValue
static QgsProperty fromValue(const QVariant &value, bool isActive=true)
Returns a new StaticProperty created from the specified value.
Definition: qgsproperty.cpp:228
qgsvectortilelayer.h
QgsProxyFeatureSink::addFeature
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
Definition: qgsproxyfeaturesink.h:47
QgsFeatureSource::hasFeatures
virtual FeatureAvailability hasFeatures() const
Determines if there are any features available in the source.
Definition: qgsfeaturesource.cpp:26
QgsProcessingAlgorithm::outputDefinitions
QgsProcessingOutputDefinitions outputDefinitions() const
Returns an ordered list of output definitions utilized by the algorithm.
Definition: qgsprocessingalgorithm.h:304
QgsProcessingOutputDefinition
Definition: qgsprocessingoutputs.h:41
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3280
QgsProcessingFeatureSourceDefinition
Definition: qgsprocessingparameters.h:55
QgsMapLayerStore
Definition: qgsmaplayerstore.h:35
QgsFeatureRequest
Definition: qgsfeaturerequest.h:75
QgsCsException
Definition: qgsexception.h:65
QgsMemoryProviderUtils::createMemoryLayer
static QgsVectorLayer * createMemoryLayer(const QString &name, const QgsFields &fields, QgsWkbTypes::Type geometryType=QgsWkbTypes::NoGeometry, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem())
Creates a new memory layer using the specified parameters.
Definition: qgsmemoryproviderutils.cpp:59
QgsFeatureSource::maximumValue
virtual QVariant maximumValue(int fieldIndex) const
Returns the maximum value for an attribute column or an invalid variant in case of error.
Definition: qgsfeaturesource.cpp:75
QgsVectorLayerSelectedFeatureSource
Definition: qgsvectorlayerfeatureiterator.h:301
QgsProcessing::TypeVector
@ TypeVector
Tables (i.e. vector layers with or without geometry). When used for a sink this indicates the sink ha...
Definition: qgsprocessing.h:53
QgsRasterFileWriter::supportedFormatExtensions
static QStringList supportedFormatExtensions(RasterFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats.
Definition: qgsrasterfilewriter.cpp:1189
QgsProcessingFeatureSink::addFeatures
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Definition: qgsprocessingutils.cpp:1384
qgsproviderregistry.h
QgsProcessingFeatureSource::hasFeatures
QgsFeatureSource::FeatureAvailability hasFeatures() const override
Determines if there are any features available in the source.
Definition: qgsprocessingutils.cpp:1242
QgsProcessingUtils::convertToCompatibleFormat
static QString convertToCompatibleFormat(const QgsVectorLayer *layer, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, long long featureLimit=-1)
Converts a source vector layer to a file path of a vector layer of compatible format.
Definition: qgsprocessingutils.cpp:1102
QgsFeatureSource::sourceName
virtual QString sourceName() const =0
Returns a friendly display name for the source.
QgsProcessingFeatureSource::fields
QgsFields fields() const override
Returns the fields associated with features in the source.
Definition: qgsprocessingutils.cpp:1274
QgsProcessingContext
Definition: qgsprocessingcontext.h:43
QgsProxyFeatureSink::addFeatures
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
Definition: qgsproxyfeaturesink.h:48
QgsFeatureRequest::setTransformErrorCallback
QgsFeatureRequest & setTransformErrorCallback(const std::function< void(const QgsFeature &)> &callback)
Sets a callback function to use when encountering a transform error when iterating features and a des...
Definition: qgsfeaturerequest.cpp:270
QgsProcessingUtils::fieldNamesToIndices
static QList< int > fieldNamesToIndices(const QStringList &fieldNames, const QgsFields &fields)
Returns a list of field indices parsed from the given list of field names.
Definition: qgsprocessingutils.cpp:1149
QgsVectorFileWriter::SaveVectorOptions::fileEncoding
QString fileEncoding
Encoding to use.
Definition: qgsvectorfilewriter.h:461
QgsRemappingSinkDefinition::setDestinationFields
void setDestinationFields(const QgsFields &fields)
Sets the fields for the destination sink.
Definition: qgsremappingproxyfeaturesink.h:130
QgsProcessingContext::defaultEncoding
QString defaultEncoding() const
Returns the default encoding to use for newly created files.
Definition: qgsprocessingcontext.h:385
qgsprocessingalgorithm.h
QgsMeshLayer
Definition: qgsmeshlayer.h:94
QgsMapLayerType::RasterLayer
@ RasterLayer
QgsFeatureSource::SpatialIndexPresence
SpatialIndexPresence
Enumeration of spatial index presence states.
Definition: qgsfeaturesource.h:187
QgsProcessing::TypeVectorAnyGeometry
@ TypeVectorAnyGeometry
Any vector layer with geometry.
Definition: qgsprocessing.h:47
QgsCoordinateReferenceSystem::authid
QString authid() const
Returns the authority identifier for the CRS.
Definition: qgscoordinatereferencesystem.cpp:1299
QgsMeshLayer::LayerOptions::skipCrsValidation
bool skipCrsValidation
Controls whether the layer is allowed to have an invalid/unknown CRS.
Definition: qgsmeshlayer.h:128
QgsFeatureSource::getFeatures
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source.
convertToCompatibleFormatInternal
QString convertToCompatibleFormatInternal(const QgsVectorLayer *vl, bool selectedFeaturesOnly, const QString &baseName, const QStringList &compatibleFormats, const QString &preferredFormat, QgsProcessingContext &context, QgsProcessingFeedback *feedback, QString *layerName, long long featureLimit)
Definition: qgsprocessingutils.cpp:1007
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:572
QgsProcessingFeatureSource::featureCount
long featureCount() const override
Returns the number of features contained in the source, or -1 if the feature count is unknown.
Definition: qgsprocessingutils.cpp:1284
QgsCoordinateReferenceSystem::isValid
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Definition: qgscoordinatereferencesystem.cpp:902
QgsFeatureSource::NoFeaturesAvailable
@ NoFeaturesAvailable
There are certainly no features available in this source.
Definition: qgsfeaturesource.h:52
QgsProviderRegistry::decodeUri
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
Definition: qgsproviderregistry.cpp:431
QgsVectorFileWriter::supportedFormatExtensions
static QStringList supportedFormatExtensions(VectorFormatOptions options=SortRecommended)
Returns a list of file extensions for supported formats, e.g "shp", "gpkg".
Definition: qgsvectorfilewriter.cpp:3277
QgsProcessing::TEMPORARY_OUTPUT
static const QString TEMPORARY_OUTPUT
Constant used to indicate that a Processing algorithm output should be a temporary layer/file.
Definition: qgsprocessing.h:99
qgsvectorlayerfeatureiterator.h
QgsProcessingUtils::decodeProviderKeyAndUri
static bool decodeProviderKeyAndUri(const QString &string, QString &providerKey, QString &uri)
Decodes a provider key and layer uri from an encoded string, for use with encodeProviderKeyAndUri()
Definition: qgsprocessingutils.cpp:142
QgsProcessingUtils::createFeatureSinkPython
static void createFeatureSinkPython(QgsFeatureSink **sink, QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions=QVariantMap()) SIP_THROW(QgsProcessingException)
Creates a feature sink ready for adding features.
Definition: qgsprocessingutils.cpp:831
QgsVectorFileWriter::defaultLayerOptions
static QStringList defaultLayerOptions(const QString &driverName)
Returns a list of the default layer options for a specified driver.
Definition: qgsvectorfilewriter.cpp:2252
QgsProcessingContext::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context.
Definition: qgsprocessingcontext.h:135
QgsProviderRegistry::providerMetadata
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
Definition: qgsproviderregistry.cpp:722
QgsVectorFileWriter::driverForExtension
static QString driverForExtension(const QString &extension)
Returns the OGR driver name for a specified file extension.
Definition: qgsvectorfilewriter.cpp:3413
QgsVectorFileWriter::SaveVectorOptions::actionOnExistingFile
QgsVectorFileWriter::ActionOnExistingFile actionOnExistingFile
Action on existing file.
Definition: qgsvectorfilewriter.h:458
QgsRasterLayer
Definition: qgsrasterlayer.h:72
QgsFeatureSource::sourceExtent
virtual QgsRectangle sourceExtent() const
Returns the extent of all geometries from the source.
Definition: qgsfeaturesource.cpp:98
QgsMapLayer::setTransformContext
virtual void setTransformContext(const QgsCoordinateTransformContext &transformContext)=0
Sets the coordinate transform context to transformContext.
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:34
qgsfileutils.h
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
QgsFeatureSource::fields
virtual QgsFields fields() const =0
Returns the fields associated with features in the source.
QgsProcessingContext::temporaryLayerStore
QgsMapLayerStore * temporaryLayerStore()
Returns a reference to the layer store used for storing temporary layers during algorithm execution.
Definition: qgsprocessingcontext.h:151
QgsRectangle::yMaximum
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
QgsReferencedPointXY
Definition: qgsreferencedgeometry.h:113
QgsExpressionContextScope
Single scope for storing variables and functions for use within a QgsExpressionContext....
Definition: qgsexpressioncontext.h:111
QgsVectorFileWriter::SaveVectorOptions::datasourceOptions
QStringList datasourceOptions
List of OGR data source creation options.
Definition: qgsvectorfilewriter.h:472
QgsVectorLayer::extent
QgsRectangle extent() const FINAL
Returns the extent of the layer.
Definition: qgsvectorlayer.cpp:833
QgsProcessingContext::feedback
QgsProcessingFeedback * feedback()
Returns the associated feedback object.
Definition: qgsprocessingcontext.h:397
QgsFeatureSource::featureCount
virtual long featureCount() const =0
Returns the number of features contained in the source, or -1 if the feature count is unknown.
QgsCoordinateReferenceSystem::createFromString
bool createFromString(const QString &definition)
Set up this CRS from a string definition.
Definition: qgscoordinatereferencesystem.cpp:272
qgsmeshlayer.h
qgsvectorlayer.h
QgsPointXY
Definition: qgspointxy.h:43
QgsProcessingFeatureSource::setInvalidGeometryCheck
void setInvalidGeometryCheck(QgsFeatureRequest::InvalidGeometryCheck method)
Overrides the default geometry check method for the source.
Definition: qgsprocessingutils.cpp:1339
QgsProcessingFeatureSink
Definition: qgsprocessingutils.h:552
QgsVectorLayer::getSelectedFeatures
QgsFeatureIterator getSelectedFeatures(QgsFeatureRequest request=QgsFeatureRequest()) const
Returns an iterator of the selected features.
Definition: qgsvectorlayer.cpp:3468
QgsFeedback::isCanceled
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition: qgsfeedback.h:66
QgsVectorFileWriter::AppendToLayerNoNewFields
@ AppendToLayerNoNewFields
Append features to existing layer, but do not create new fields.
Definition: qgsvectorfilewriter.h:270
QgsVectorLayer::LayerOptions
Setting options for loading vector layers.
Definition: qgsvectorlayer.h:423
qgsprocessingutils.h
qgsprocessingparameters.h
QgsFeatureSource::FeatureAvailability
FeatureAvailability
Possible return value for hasFeatures() to determine if a source is empty.
Definition: qgsfeaturesource.h:50
QgsReferencedGeometryBase::crs
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
Definition: qgsreferencedgeometry.h:52
QgsMapLayer::source
QString source() const
Returns the source for the layer.
Definition: qgsmaplayer.cpp:192
QgsProcessingUtils::LayerHint::Vector
@ Vector
Vector layer type.
qgsreferencedgeometry.h
QgsProcessingFeatureSourceDefinition::featureLimit
long long featureLimit
If set to a value > 0, places a limit on the maximum number of features which will be read from the s...
Definition: qgsprocessingparameters.h:130
QgsRasterLayer::LayerOptions
Setting options for loading raster layers.
Definition: qgsrasterlayer.h:105
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:142
QgsRasterLayer::LayerOptions::loadDefaultStyle
bool loadDefaultStyle
Sets to true if the default layer style should be loaded.
Definition: qgsrasterlayer.h:118
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:141
QgsProcessingUtils::generateTempFilename
static QString generateTempFilename(const QString &basename)
Returns a temporary filename for a given file, putting it into a temporary folder (creating that fold...
Definition: qgsprocessingutils.cpp:950
QgsProcessingAlgorithm
Definition: qgsprocessingalgorithm.h:51
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:373
QgsProcessingUtils::tempFolder
static QString tempFolder()
Returns a session specific processing temporary folder for use in processing algorithms.
Definition: qgsprocessingutils.cpp:915
QgsFeatureSource::wkbType
virtual QgsWkbTypes::Type wkbType() const =0
Returns the geometry type for features returned by this source.
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsProcessingUtils::variantToPythonLiteral
static QString variantToPythonLiteral(const QVariant &value)
Converts a variant to a Python literal.
Definition: qgsprocessingutils.cpp:519
QgsFeatureRequest::setLimit
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
Definition: qgsfeaturerequest.cpp:178
QgsProcessingUtils::compatibleVectorLayers
static QList< QgsVectorLayer * > compatibleVectorLayers(QgsProject *project, const QList< int > &sourceTypes=QList< int >(), bool sort=true)
Returns a list of vector layers from a project which are compatible with the processing framework.
Definition: qgsprocessingutils.cpp:62
qgsvectorlayerexporter.h
QgsMapLayer
Definition: qgsmaplayer.h:81
QgsProcessingUtils::formatHelpMapAsHtml
static QString formatHelpMapAsHtml(const QVariantMap &map, const QgsProcessingAlgorithm *algorithm)
Returns a HTML formatted version of the help text encoded in a variant map for a specified algorithm.
Definition: qgsprocessingutils.cpp:962
QgsProcessingContext::expressionContext
QgsExpressionContext & expressionContext()
Returns the expression context.
Definition: qgsprocessingcontext.h:119
QgsProcessingUtils::variantToCrs
static QgsCoordinateReferenceSystem variantToCrs(const QVariant &value, QgsProcessingContext &context, const QVariant &fallbackValue=QVariant())
Converts a variant value to a coordinate reference system.
Definition: qgsprocessingutils.cpp:424
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsProcessingFeatureSource
Definition: qgsprocessingutils.h:468
qgssettings.h
QgsProcessingFeatureSource::hasSpatialIndex
SpatialIndexPresence hasSpatialIndex() const override
Returns an enum value representing the presence of a valid spatial index on the source,...
Definition: qgsprocessingutils.cpp:1323
QgsRectangle::yMinimum
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsFeatureSource::FeaturesMaybeAvailable
@ FeaturesMaybeAvailable
There may be features available in this source.
Definition: qgsfeaturesource.h:54
QgsFeatureRequest::GeometryNoCheck
@ GeometryNoCheck
No invalid geometry checking.
Definition: qgsfeaturerequest.h:114
qgsprocessingcontext.h
QgsProcessingUtils::combineLayerExtents
static QgsRectangle combineLayerExtents(const QList< QgsMapLayer * > &layers, const QgsCoordinateReferenceSystem &crs, QgsProcessingContext &context)
Combines the extent of several map layers.
Definition: qgsprocessingutils.cpp:837
QgsVectorLayer::subsetString
QString subsetString
Definition: qgsvectorlayer.h:389
QgsProcessingAlgorithm::parameterDefinitions
QgsProcessingParameterDefinitions parameterDefinitions() const
Returns an ordered list of parameter definitions utilized by the algorithm.
Definition: qgsprocessingalgorithm.h:277
qgsexception.h
QgsProcessingUtils::mapLayerFromString
static QgsMapLayer * mapLayerFromString(const QString &string, QgsProcessingContext &context, bool allowLoadingNewLayers=true, QgsProcessingUtils::LayerHint typeHint=QgsProcessingUtils::LayerHint::UnknownType)
Interprets a string as a map layer within the supplied context.
Definition: qgsprocessingutils.cpp:314
qgsexpressioncontextscopegenerator.h
QgsFeature
Definition: qgsfeature.h:55
QgsProcessingFeatureSink::QgsProcessingFeatureSink
QgsProcessingFeatureSink(QgsFeatureSink *originalSink, const QString &sinkName, QgsProcessingContext &context, bool ownsOriginalSink=false)
Constructor for QgsProcessingFeatureSink, accepting an original feature sink originalSink and process...
Definition: qgsprocessingutils.cpp:1363
QgsWkbTypes
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:40
qgsmemoryproviderutils.h
QgsProcessingUtils::createFeatureSink
static QgsFeatureSink * createFeatureSink(QString &destination, QgsProcessingContext &context, const QgsFields &fields, QgsWkbTypes::Type geometryType, const QgsCoordinateReferenceSystem &crs, const QVariantMap &createOptions=QVariantMap(), QgsFeatureSink::SinkFlags sinkFlags=QgsFeatureSink::SinkFlags(), QgsRemappingSinkDefinition *remappingDefinition=nullptr)
Creates a feature sink ready for adding features.
Definition: qgsprocessingutils.cpp:690
QgsProcessingFeatureSource::allFeatureIds
QgsFeatureIds allFeatureIds() const override
Returns a list of all feature IDs for features present in the source.
Definition: qgsprocessingutils.cpp:1318
QgsProcessingOutputLayerDefinition::sink
QgsProperty sink
Sink/layer definition.
Definition: qgsprocessingparameters.h:226
QgsVectorFileWriter::SaveVectorOptions::symbologyExport
QgsVectorFileWriter::SymbologyExport symbologyExport
Symbology to export.
Definition: qgsvectorfilewriter.h:484
qgsvectorfilewriter.h
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:324
QgsVectorFileWriter::SaveVectorOptions::layerOptions
QStringList layerOptions
List of OGR layer creation options.
Definition: qgsvectorfilewriter.h:475
QgsFields::at
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:163
QgsDataSourceUri::table
QString table() const
Returns the table name stored in the URI.
Definition: qgsdatasourceuri.cpp:314
QgsProperty::StaticProperty
@ StaticProperty
Static property (QgsStaticProperty)
Definition: qgsproperty.h:239
QgsCoordinateTransform
Definition: qgscoordinatetransform.h:52
QgsVectorFileWriter::SaveVectorOptions::driverName
QString driverName
OGR driver to use.
Definition: qgsvectorfilewriter.h:452
QgsFeatureIterator
Definition: qgsfeatureiterator.h:263
QgsVectorLayer::geometryType
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Definition: qgsvectorlayer.cpp:659
QgsProcessingFeatureSource::sourceCrs
QgsCoordinateReferenceSystem sourceCrs() const override
Returns the coordinate reference system for features in the source.
Definition: qgsprocessingutils.cpp:1269
QgsProcessingFeatureSink::addFeature
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a single feature to the sink.
Definition: qgsprocessingutils.cpp:1376
QgsProcessingFeatureSource::sourceName
QString sourceName() const override
Returns a friendly display name for the source.
Definition: qgsprocessingutils.cpp:1292
QgsProviderRegistry::instance
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Definition: qgsproviderregistry.cpp:48
QgsVectorFileWriter::defaultDatasetOptions
static QStringList defaultDatasetOptions(const QString &driverName)
Returns a list of the default dataset options for a specified driver.
Definition: qgsvectorfilewriter.cpp:2243
QgsProcessingUtils::defaultRasterExtension
static QString defaultRasterExtension()
Returns the default raster extension to use, in the absence of all other constraints (e....
Definition: qgsprocessingutils.cpp:1189
QgsProcessingFeatureSource::wkbType
QgsWkbTypes::Type wkbType() const override
Returns the geometry type for features returned by this source.
Definition: qgsprocessingutils.cpp:1279
QgsProject::crs
QgsCoordinateReferenceSystem crs
Definition: qgsproject.h:98
QgsProcessingException
Definition: qgsexception.h:82
QgsMeshLayer::dataProvider
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
Definition: qgsmeshlayer.cpp:147
qgsproject.h
QgsExpressionContextScopeGenerator::createExpressionContextScope
virtual QgsExpressionContextScope * createExpressionContextScope() const =0
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QgsFeatureSink
Definition: qgsfeaturesink.h:33
QgsField::setName
void setName(const QString &name)
Set the field name.
Definition: qgsfield.cpp:175
QgsRectangle::xMinimum
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsFileUtils::stringToSafeFilename
static QString stringToSafeFilename(const QString &string)
Converts a string to a safe filename, replacing characters which are not safe for filenames with an '...
Definition: qgsfileutils.cpp:92
QgsFeatureSink::FastInsert
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
Definition: qgsfeaturesink.h:70
QgsProcessingUtils::LayerHint::UnknownType
@ UnknownType
Unknown layer type.
QgsProcessingUtils::compatibleLayers
static QList< QgsMapLayer * > compatibleLayers(QgsProject *project, bool sort=true)
Returns a list of map layers from a project which are compatible with the processing framework.
Definition: qgsprocessingutils.cpp:108
QgsFeatureRequest::limit
long limit() const
Returns the maximum number of features to request, or -1 if no limit set.
Definition: qgsfeaturerequest.h:512
QgsField
Definition: qgsfield.h:49