QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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  mUseDefaultInvalidGeometryCallback = true;
65  mInvalidGeometryCallback = defaultInvalidGeometryCallbackForCheck( check );
66 }
67 
68 std::function<void ( const QgsFeature & )> QgsProcessingContext::invalidGeometryCallback( QgsFeatureSource *source ) const
69 {
70  if ( mUseDefaultInvalidGeometryCallback )
71  return defaultInvalidGeometryCallbackForCheck( mInvalidGeometryCheck, source );
72  else
73  return mInvalidGeometryCallback;
74 }
75 
77 {
78  const QString sourceName = source ? source->sourceName() : QString();
79  switch ( check )
80  {
82  {
83  auto callback = [sourceName]( const QgsFeature & feature )
84  {
85  if ( !sourceName.isEmpty() )
86  throw QgsProcessingException( QObject::tr( "Feature (%1) from “%2” has invalid geometry. Please fix the geometry or change the Processing setting to the “Ignore invalid input features” option." ).arg( feature.id() ).arg( sourceName ) );
87  else
88  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() ) );
89  };
90  return callback;
91  }
92 
94  {
95  auto callback = [ = ]( const QgsFeature & feature )
96  {
97  if ( mFeedback )
98  {
99  if ( !sourceName.isEmpty() )
100  mFeedback->reportError( QObject::tr( "Feature (%1) from “%2” 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() ).arg( sourceName ) );
101  else
102  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() ) );
103  }
104  };
105  return callback;
106  }
107 
109  return nullptr;
110  }
111  return nullptr;
112 }
113 
115 {
116  setLayersToLoadOnCompletion( context.mLayersToLoadOnCompletion );
117  context.mLayersToLoadOnCompletion.clear();
118  tempLayerStore.transferLayersFromStore( context.temporaryLayerStore() );
119 }
120 
121 QgsMapLayer *QgsProcessingContext::getMapLayer( const QString &identifier )
122 {
123  return QgsProcessingUtils::mapLayerFromString( identifier, *this, false );
124 }
125 
127 {
128  return tempLayerStore.takeMapLayer( tempLayerStore.mapLayer( id ) );
129 }
130 
132 {
133  return mCurrentTimeRange;
134 }
135 
136 void QgsProcessingContext::setCurrentTimeRange( const QgsDateTimeRange &currentTimeRange )
137 {
138  mCurrentTimeRange = currentTimeRange;
139 }
140 
142 {
143  return mEllipsoid;
144 }
145 
146 void QgsProcessingContext::setEllipsoid( const QString &ellipsoid )
147 {
148  mEllipsoid = ellipsoid;
149 }
150 
152 {
153  return mDistanceUnit;
154 }
155 
157 {
158  mDistanceUnit = unit;
159 }
160 
162 {
163  return mAreaUnit;
164 }
165 
167 {
168  mAreaUnit = areaUnit;
169 }
170 
172 {
173  return mPostProcessor;
174 }
175 
177 {
178  if ( mPostProcessor && mPostProcessor != processor )
179  delete mPostProcessor;
180 
181  mPostProcessor = processor;
182 }
183 
185 {
186  if ( !layer )
187  return;
188 
189  const bool preferFilenameAsLayerName = QgsSettings().value( QStringLiteral( "Processing/Configuration/PREFER_FILENAME_AS_LAYER_NAME" ), true ).toBool();
190 
191  // note - for temporary layers, we don't use the filename, regardless of user setting (it will be meaningless!)
192  if ( ( !forceName && preferFilenameAsLayerName && !layer->isTemporary() ) || name.isEmpty() )
193  {
194  const QVariantMap sourceParts = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->source() );
195  const QString layerName = sourceParts.value( QStringLiteral( "layerName" ) ).toString();
196  // if output layer name exists, use that!
197  if ( !layerName.isEmpty() )
198  layer->setName( layerName );
199  else
200  {
201  const QString path = sourceParts.value( QStringLiteral( "path" ) ).toString();
202  if ( !path.isEmpty() )
203  {
204  const QFileInfo fi( path );
205  layer->setName( fi.baseName() );
206  }
207  else if ( !name.isEmpty() )
208  {
209  // fallback to parameter's name -- shouldn't happen!
210  layer->setName( name );
211  }
212  }
213  }
214  else
215  {
216  layer->setName( name );
217  }
218 }
InvalidGeometryCheck
Handling of features with invalid geometries.
@ GeometryNoCheck
No invalid geometry checking.
@ GeometryAbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
@ GeometrySkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
An interface for objects which provide features via a getFeatures method.
virtual QString sourceName() const =0
Returns a friendly display name for the source.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the store.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
void transferLayersFromStore(QgsMapLayerStore *other)
Transfers all the map layers contained within another map layer store and adds them to this store.
Base class for all map layer types.
Definition: qgsmaplayer.h:85
virtual bool isTemporary() const
Returns true if the layer is considered a temporary layer.
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
void setName(const QString &name)
Set the display name of the layer.
Details for layers to load into projects.
QgsProcessingLayerPostProcessorInterface * postProcessor() const
Layer post-processor.
void setPostProcessor(QgsProcessingLayerPostProcessorInterface *processor)
Sets the layer post-processor.
void setOutputLayerName(QgsMapLayer *layer) const
Sets a layer name to match this output, respecting any local user settings which affect this name.
Contains information about the context in which a processing algorithm is executed.
QgsMapLayerStore * temporaryLayerStore()
Returns a reference to the layer store used for storing temporary layers during algorithm execution.
void setAreaUnit(QgsUnitTypes::AreaUnit areaUnit)
Sets the unit to use for area calculations.
QgsDateTimeRange currentTimeRange() const
Returns the current time range to use for temporal operations.
QgsUnitTypes::AreaUnit areaUnit() const
Returns the area unit to use for area calculations.
void takeResultsFrom(QgsProcessingContext &context)
Takes the results from another context and merges them with the results currently stored in this cont...
QgsMapLayer * getMapLayer(const QString &identifier)
Returns a map layer from the context with a matching identifier.
std::function< void(const QgsFeature &) > invalidGeometryCallback(QgsFeatureSource *source=nullptr) const
Returns the callback function to use when encountering an invalid geometry and invalidGeometryCheck()...
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...
QgsMapLayer * takeResultLayer(const QString &id)
Takes the result map layer with matching id from the context and transfers ownership of it back to th...
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.
void setEllipsoid(const QString &ellipsoid)
Sets a specified ellipsoid to use for distance and area calculations.
QgsProcessingContext()
Constructor for QgsProcessingContext.
QgsUnitTypes::DistanceUnit distanceUnit() const
Returns the distance unit to use for distance calculations.
QString ellipsoid() const
Returns the ellipsoid to use for distance and area calculations.
void setInvalidGeometryCheck(QgsFeatureRequest::InvalidGeometryCheck check)
Sets the behavior used for checking invalid geometries in input layers.
std::function< void(const QgsFeature &) > defaultInvalidGeometryCallbackForCheck(QgsFeatureRequest::InvalidGeometryCheck check, QgsFeatureSource *source=nullptr) const
Returns the default callback function to use for a particular invalid geometry check.
void setCurrentTimeRange(const QgsDateTimeRange &currentTimeRange)
Sets the current time range to use for temporal operations.
void setDistanceUnit(QgsUnitTypes::DistanceUnit unit)
Sets the unit to use for distance calculations.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
An interface for layer post-processing handlers for execution following a processing algorithm operat...
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.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
AreaUnit
Units of area.
Definition: qgsunittypes.h:94