QGIS API Documentation  3.24.2-Tisler (13c1a02865)
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 "qgsmaplayerlistutils_p.h"
22 #include "qgssettings.h"
23 
25  : mPreferredVectorFormat( QgsProcessingUtils::defaultVectorExtension() )
26  , mPreferredRasterFormat( QgsProcessingUtils::defaultRasterExtension() )
27 {
28  auto callback = [ = ]( const QgsFeature & feature )
29  {
30  if ( mFeedback )
31  mFeedback->reportError( QObject::tr( "Encountered a transform error when reprojecting feature with id %1." ).arg( feature.id() ) );
32  };
33  mTransformErrorCallback = callback;
34 }
35 
37 {
38  for ( auto it = mLayersToLoadOnCompletion.constBegin(); it != mLayersToLoadOnCompletion.constEnd(); ++it )
39  {
40  delete it.value().postProcessor();
41  }
42 }
43 
44 void QgsProcessingContext::setLayersToLoadOnCompletion( const QMap<QString, QgsProcessingContext::LayerDetails> &layers )
45 {
46  for ( auto it = mLayersToLoadOnCompletion.constBegin(); it != mLayersToLoadOnCompletion.constEnd(); ++it )
47  {
48  if ( !layers.contains( it.key() ) || layers.value( it.key() ).postProcessor() != it.value().postProcessor() )
49  delete it.value().postProcessor();
50  }
51  mLayersToLoadOnCompletion = layers;
52 }
53 
55 {
56  if ( mLayersToLoadOnCompletion.contains( layer ) && mLayersToLoadOnCompletion.value( layer ).postProcessor() != details.postProcessor() )
57  delete mLayersToLoadOnCompletion.value( layer ).postProcessor();
58 
59  mLayersToLoadOnCompletion.insert( layer, details );
60 }
61 
63 {
64  mInvalidGeometryCheck = check;
65  mUseDefaultInvalidGeometryCallback = true;
66  mInvalidGeometryCallback = defaultInvalidGeometryCallbackForCheck( check );
67 }
68 
69 std::function<void ( const QgsFeature & )> QgsProcessingContext::invalidGeometryCallback( QgsFeatureSource *source ) const
70 {
71  if ( mUseDefaultInvalidGeometryCallback )
72  return defaultInvalidGeometryCallbackForCheck( mInvalidGeometryCheck, source );
73  else
74  return mInvalidGeometryCallback;
75 }
76 
78 {
79  const QString sourceName = source ? source->sourceName() : QString();
80  switch ( check )
81  {
83  {
84  auto callback = [sourceName]( const QgsFeature & feature )
85  {
86  if ( !sourceName.isEmpty() )
87  throw QgsProcessingException( QObject::tr( "Feature (%1) from “%2” has invalid geometry. Please fix the geometry or change the “Invalid features filtering” option for this input or globally in Processing settings." ).arg( feature.id() ).arg( sourceName ) );
88  else
89  throw QgsProcessingException( QObject::tr( "Feature (%1) has invalid geometry. Please fix the geometry or change the “Invalid features filtering” option for input layers or globally in Processing settings." ).arg( feature.id() ) );
90  };
91  return callback;
92  }
93 
95  {
96  auto callback = [ = ]( const QgsFeature & feature )
97  {
98  if ( mFeedback )
99  {
100  if ( !sourceName.isEmpty() )
101  mFeedback->reportError( QObject::tr( "Feature (%1) from “%2” has invalid geometry and has been skipped. Please fix the geometry or change the “Invalid features filtering” option for this input or globally in Processing settings." ).arg( feature.id() ).arg( sourceName ) );
102  else
103  mFeedback->reportError( QObject::tr( "Feature (%1) has invalid geometry and has been skipped. Please fix the geometry or change the “Invalid features filtering” option for input layers or globally in Processing settings." ).arg( feature.id() ) );
104  }
105  };
106  return callback;
107  }
108 
110  return nullptr;
111  }
112  return nullptr;
113 }
114 
116 {
117  setLayersToLoadOnCompletion( context.mLayersToLoadOnCompletion );
118  context.mLayersToLoadOnCompletion.clear();
119  tempLayerStore.transferLayersFromStore( context.temporaryLayerStore() );
120 }
121 
122 QgsMapLayer *QgsProcessingContext::getMapLayer( const QString &identifier )
123 {
124  return QgsProcessingUtils::mapLayerFromString( identifier, *this, false );
125 }
126 
128 {
129  return tempLayerStore.takeMapLayer( tempLayerStore.mapLayer( id ) );
130 }
131 
133 {
134  return mLogLevel;
135 }
136 
138 {
139  mLogLevel = level;
140 }
141 
143 {
144  QVariantMap res;
145  if ( mDistanceUnit != QgsUnitTypes::DistanceUnknownUnit )
146  res.insert( QStringLiteral( "distance_units" ), QgsUnitTypes::encodeUnit( mDistanceUnit ) );
147  if ( mAreaUnit != QgsUnitTypes::AreaUnknownUnit )
148  res.insert( QStringLiteral( "area_units" ), QgsUnitTypes::encodeUnit( mAreaUnit ) );
149  if ( !mEllipsoid.isEmpty() )
150  res.insert( QStringLiteral( "ellipsoid" ), mEllipsoid );
151  if ( mProject )
152  res.insert( QStringLiteral( "project_path" ), mProject->fileName() );
153 
154  return res;
155 }
156 
157 QStringList QgsProcessingContext::asQgisProcessArguments( QgsProcessingContext::ProcessArgumentFlags flags ) const
158 {
159  QStringList res;
160  if ( mDistanceUnit != QgsUnitTypes::DistanceUnknownUnit )
161  res << QStringLiteral( "--distance_units=%1" ).arg( QgsUnitTypes::encodeUnit( mDistanceUnit ) );
162  if ( mAreaUnit != QgsUnitTypes::AreaUnknownUnit )
163  res << QStringLiteral( "--area_units=%1" ).arg( QgsUnitTypes::encodeUnit( mAreaUnit ) );
164  if ( !mEllipsoid.isEmpty() )
165  res << QStringLiteral( "--ellipsoid=%1" ).arg( mEllipsoid );
166 
168  {
169  res << QStringLiteral( "--project_path=%1" ).arg( mProject->fileName() );
170  }
171 
172  return res;
173 }
174 
176 {
177  return mCurrentTimeRange;
178 }
179 
180 void QgsProcessingContext::setCurrentTimeRange( const QgsDateTimeRange &currentTimeRange )
181 {
182  mCurrentTimeRange = currentTimeRange;
183 }
184 
186 {
187  return mEllipsoid;
188 }
189 
190 void QgsProcessingContext::setEllipsoid( const QString &ellipsoid )
191 {
192  mEllipsoid = ellipsoid;
193 }
194 
196 {
197  return mDistanceUnit;
198 }
199 
201 {
202  mDistanceUnit = unit;
203 }
204 
206 {
207  return mAreaUnit;
208 }
209 
211 {
212  mAreaUnit = areaUnit;
213 }
214 
216 {
217  return mPostProcessor;
218 }
219 
221 {
222  if ( mPostProcessor && mPostProcessor != processor )
223  delete mPostProcessor;
224 
225  mPostProcessor = processor;
226 }
227 
229 {
230  if ( !layer )
231  return;
232 
233  const bool preferFilenameAsLayerName = QgsProcessing::settingsPreferFilenameAsLayerName.value();
234 
235  // note - for temporary layers, we don't use the filename, regardless of user setting (it will be meaningless!)
236  if ( ( !forceName && preferFilenameAsLayerName && !layer->isTemporary() ) || name.isEmpty() )
237  {
238  const QVariantMap sourceParts = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->source() );
239  const QString layerName = sourceParts.value( QStringLiteral( "layerName" ) ).toString();
240  // if output layer name exists, use that!
241  if ( !layerName.isEmpty() )
242  layer->setName( layerName );
243  else
244  {
245  const QString path = sourceParts.value( QStringLiteral( "path" ) ).toString();
246  if ( !path.isEmpty() )
247  {
248  const QFileInfo fi( path );
249  layer->setName( fi.baseName() );
250  }
251  else if ( !name.isEmpty() )
252  {
253  // fallback to parameter's name -- shouldn't happen!
254  layer->setName( name );
255  }
256  }
257  }
258  else
259  {
260  layer->setName( name );
261  }
262 }
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 unique ID, geometry and a list of field...
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:73
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.
QgsProcessingContext::Flags flags() const
Returns any flags set in the context.
@ IncludeProjectPath
Include the associated project path argument.
LogLevel
Logging level for algorithms to use when pushing feedback messages.
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...
QVariantMap exportToMap() const
Exports the context's settings to a variant map.
QStringList asQgisProcessArguments(QgsProcessingContext::ProcessArgumentFlags flags=QgsProcessingContext::ProcessArgumentFlags()) const
Returns list of the equivalent qgis_process arguments representing the settings from the context.
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.
void setLogLevel(LogLevel level)
Sets the logging level for algorithms to use when pushing feedback messages to users.
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.
LogLevel logLevel() const
Returns the logging level for algorithms to use when pushing feedback messages to users.
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.
static const QgsSettingsEntryBool settingsPreferFilenameAsLayerName
Settings entry prefer filename as layer name.
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.
bool value(const QString &dynamicKeyPart=QString(), bool useDefaultValueOverride=false, bool defaultValueOverride=false) const
Returns settings value.
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
AreaUnit
Units of area.
Definition: qgsunittypes.h:94
@ AreaUnknownUnit
Unknown areal unit.
Definition: qgsunittypes.h:106