QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
qgsprocessingcontext.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprocessingcontext.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 "qgsprocessingcontext.h"
19 #include "qgsprocessingutils.h"
20 #include "qgsproviderregistry.h"
21 #include "qgssettings.h"
22 
24  : mPreferredVectorFormat( QgsProcessingUtils::defaultVectorExtension() )
25  , mPreferredRasterFormat( QgsProcessingUtils::defaultRasterExtension() )
26 {
27  auto callback = [ = ]( const QgsFeature & feature )
28  {
29  if ( mFeedback )
30  mFeedback->reportError( QObject::tr( "Encountered a transform error when reprojecting feature with id %1." ).arg( feature.id() ) );
31  };
32  mTransformErrorCallback = callback;
33 }
34 
36 {
37  for ( auto it = mLayersToLoadOnCompletion.constBegin(); it != mLayersToLoadOnCompletion.constEnd(); ++it )
38  {
39  delete it.value().postProcessor();
40  }
41 }
42 
43 void QgsProcessingContext::setLayersToLoadOnCompletion( const QMap<QString, QgsProcessingContext::LayerDetails> &layers )
44 {
45  for ( auto it = mLayersToLoadOnCompletion.constBegin(); it != mLayersToLoadOnCompletion.constEnd(); ++it )
46  {
47  if ( !layers.contains( it.key() ) || layers.value( it.key() ).postProcessor() != it.value().postProcessor() )
48  delete it.value().postProcessor();
49  }
50  mLayersToLoadOnCompletion = layers;
51 }
52 
54 {
55  if ( mLayersToLoadOnCompletion.contains( layer ) && mLayersToLoadOnCompletion.value( layer ).postProcessor() != details.postProcessor() )
56  delete mLayersToLoadOnCompletion.value( layer ).postProcessor();
57 
58  mLayersToLoadOnCompletion.insert( layer, details );
59 }
60 
62 {
63  mInvalidGeometryCheck = check;
64 
65  switch ( mInvalidGeometryCheck )
66  {
68  {
69  auto callback = []( const QgsFeature & feature )
70  {
71  throw QgsProcessingException( QObject::tr( "Feature (%1) has invalid geometry. Please fix the geometry or change the Processing setting to the \"Ignore invalid input features\" option." ).arg( feature.id() ) );
72  };
73  mInvalidGeometryCallback = callback;
74  break;
75  }
76 
78  {
79  auto callback = [ = ]( const QgsFeature & feature )
80  {
81  if ( mFeedback )
82  mFeedback->reportError( QObject::tr( "Feature (%1) has invalid geometry and has been skipped. Please fix the geometry or change the Processing setting to the \"Ignore invalid input features\" option." ).arg( feature.id() ) );
83  };
84  mInvalidGeometryCallback = callback;
85  break;
86  }
87 
88  default:
89  break;
90  }
91 }
92 
94 {
95  setLayersToLoadOnCompletion( context.mLayersToLoadOnCompletion );
96  context.mLayersToLoadOnCompletion.clear();
97  tempLayerStore.transferLayersFromStore( context.temporaryLayerStore() );
98 }
99 
100 QgsMapLayer *QgsProcessingContext::getMapLayer( const QString &identifier )
101 {
102  return QgsProcessingUtils::mapLayerFromString( identifier, *this, false );
103 }
104 
106 {
107  return tempLayerStore.takeMapLayer( tempLayerStore.mapLayer( id ) );
108 }
109 
110 
111 
113 {
114  return mPostProcessor;
115 }
116 
118 {
119  if ( mPostProcessor && mPostProcessor != processor )
120  delete mPostProcessor;
121 
122  mPostProcessor = processor;
123 }
124 
126 {
127  if ( !layer )
128  return;
129 
130  const bool preferFilenameAsLayerName = QgsSettings().value( QStringLiteral( "Processing/Configuration/PREFER_FILENAME_AS_LAYER_NAME" ), true ).toBool();
131 
132  // note - for temporary layers, we don't use the filename, regardless of user setting (it will be meaningless!)
133  if ( ( preferFilenameAsLayerName && !layer->isTemporary() ) || name.isEmpty() )
134  {
135  const QVariantMap sourceParts = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->source() );
136  const QString layerName = sourceParts.value( QStringLiteral( "layerName" ) ).toString();
137  // if output layer name exists, use that!
138  if ( !layerName.isEmpty() )
139  layer->setName( layerName );
140  else
141  {
142  const QString path = sourceParts.value( QStringLiteral( "path" ) ).toString();
143  if ( !path.isEmpty() )
144  {
145  const QFileInfo fi( path );
146  layer->setName( fi.baseName() );
147  }
148  else if ( !name.isEmpty() )
149  {
150  // fallback to parameter's name -- shouldn't happen!
151  layer->setName( name );
152  }
153  }
154  }
155  else
156  {
157  layer->setName( name );
158  }
159 }
Base class for all map layer types.
Definition: qgsmaplayer.h:79
void setLayersToLoadOnCompletion(const QMap< QString, QgsProcessingContext::LayerDetails > &layers)
Sets the map of layers (by ID or datasource) to LayerDetails, to load into the canvas upon completion...
An interface for layer post-processing handlers for execution following a processing algorithm operat...
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
QString providerType() const
Returns the provider type (provider key) for this layer.
void setPostProcessor(QgsProcessingLayerPostProcessorInterface *processor)
Sets the layer post-processor.
QgsMapLayer * takeResultLayer(const QString &id)
Takes the result map layer with matching id from the context and transfers ownership of it back to th...
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the store.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
InvalidGeometryCheck
Handling of features with invalid geometries.
Utility functions for use with processing classes.
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.
QgsProcessingLayerPostProcessorInterface * postProcessor() const
Layer post-processor.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsMapLayerStore * temporaryLayerStore()
Returns a reference to the layer store used for storing temporary layers during algorithm execution...
void takeResultsFrom(QgsProcessingContext &context)
Takes the results from another context and merges them with the results currently stored in this cont...
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
QgsMapLayer * getMapLayer(const QString &identifier)
Returns a map layer from the context with a matching identifier.
void setInvalidGeometryCheck(QgsFeatureRequest::InvalidGeometryCheck check)
Sets the behavior used for checking invalid geometries in input layers.
void setName(const QString &name)
Set the display name of the layer.
Details for layers to load into projects.
void setOutputLayerName(QgsMapLayer *layer) const
Sets a layer name to match this output, respecting any local user settings which affect this name...
QgsProcessingContext()
Constructor for QgsProcessingContext.
void addLayerToLoadOnCompletion(const QString &layer, const QgsProcessingContext::LayerDetails &details)
Adds a layer to load (by ID or datasource) into the canvas upon completion of the algorithm or model...
QString source() const
Returns the source for the layer.
void transferLayersFromStore(QgsMapLayerStore *other)
Transfers all the map layers contained within another map layer store and adds them to this store...
virtual bool isTemporary() const
Returns true if the layer is considered a temporary layer.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
Contains information about the context in which a processing algorithm is executed.
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...