QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 }
QgsMapLayerStore::transferLayersFromStore
void transferLayersFromStore(QgsMapLayerStore *other)
Transfers all the map layers contained within another map layer store and adds them to this store.
Definition: qgsmaplayerstore.cpp:207
QgsProcessingContext::asQgisProcessArguments
QStringList asQgisProcessArguments(QgsProcessingContext::ProcessArgumentFlags flags=QgsProcessingContext::ProcessArgumentFlags()) const
Returns list of the equivalent qgis_process arguments representing the settings from the context.
Definition: qgsprocessingcontext.cpp:157
QgsProcessingContext::LayerDetails::setPostProcessor
void setPostProcessor(QgsProcessingLayerPostProcessorInterface *processor)
Sets the layer post-processor.
Definition: qgsprocessingcontext.cpp:220
QgsFeatureRequest::GeometryAbortOnInvalid
@ GeometryAbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
Definition: qgsfeaturerequest.h:126
QgsProcessingContext::~QgsProcessingContext
~QgsProcessingContext()
Definition: qgsprocessingcontext.cpp:36
QgsProcessingContext::distanceUnit
QgsUnitTypes::DistanceUnit distanceUnit() const
Returns the distance unit to use for distance calculations.
Definition: qgsprocessingcontext.cpp:195
QgsProcessingContext::ProcessArgumentFlag::IncludeProjectPath
@ IncludeProjectPath
Include the associated project path argument.
QgsUnitTypes::DistanceUnknownUnit
@ DistanceUnknownUnit
Unknown distance unit.
Definition: qgsunittypes.h:78
QgsProcessingContext::defaultInvalidGeometryCallbackForCheck
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.
Definition: qgsprocessingcontext.cpp:77
QgsProcessingContext::takeResultLayer
QgsMapLayer * takeResultLayer(const QString &id)
Takes the result map layer with matching id from the context and transfers ownership of it back to th...
Definition: qgsprocessingcontext.cpp:127
QgsProcessingContext::setLayersToLoadOnCompletion
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...
Definition: qgsprocessingcontext.cpp:44
QgsFeatureSource
An interface for objects which provide features via a getFeatures method.
Definition: qgsfeaturesource.h:37
QgsProcessingContext::LogLevel
LogLevel
Logging level for algorithms to use when pushing feedback messages.
Definition: qgsprocessingcontext.h:63
QgsFeatureRequest::InvalidGeometryCheck
InvalidGeometryCheck
Handling of features with invalid geometries.
Definition: qgsfeaturerequest.h:122
QgsFeatureRequest::GeometrySkipInvalid
@ GeometrySkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
Definition: qgsfeaturerequest.h:125
QgsUnitTypes::DistanceUnit
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:67
QgsMapLayerStore::mapLayer
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
Definition: qgsmaplayerstore.cpp:49
QgsProcessingContext::setLogLevel
void setLogLevel(LogLevel level)
Sets the logging level for algorithms to use when pushing feedback messages to users.
Definition: qgsprocessingcontext.cpp:137
QgsMapLayer::providerType
QString providerType() const
Returns the provider type (provider key) for this layer.
Definition: qgsmaplayer.cpp:1864
qgsmaplayerlistutils_p.h
QgsProcessingContext::LayerDetails::setOutputLayerName
void setOutputLayerName(QgsMapLayer *layer) const
Sets a layer name to match this output, respecting any local user settings which affect this name.
Definition: qgsprocessingcontext.cpp:228
QgsProcessingContext::setEllipsoid
void setEllipsoid(const QString &ellipsoid)
Sets a specified ellipsoid to use for distance and area calculations.
Definition: qgsprocessingcontext.cpp:190
QgsUnitTypes::encodeUnit
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
Definition: qgsunittypes.cpp:122
QgsProcessingContext::takeResultsFrom
void takeResultsFrom(QgsProcessingContext &context)
Takes the results from another context and merges them with the results currently stored in this cont...
Definition: qgsprocessingcontext.cpp:115
qgsproviderregistry.h
QgsProcessingContext::setCurrentTimeRange
void setCurrentTimeRange(const QgsDateTimeRange &currentTimeRange)
Sets the current time range to use for temporal operations.
Definition: qgsprocessingcontext.cpp:180
QgsFeatureSource::sourceName
virtual QString sourceName() const =0
Returns a friendly display name for the source.
QgsProcessingContext::currentTimeRange
QgsDateTimeRange currentTimeRange() const
Returns the current time range to use for temporal operations.
Definition: qgsprocessingcontext.cpp:175
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:46
QgsProcessingContext::invalidGeometryCallback
std::function< void(const QgsFeature &) > invalidGeometryCallback(QgsFeatureSource *source=nullptr) const
Returns the callback function to use when encountering an invalid geometry and invalidGeometryCheck()...
Definition: qgsprocessingcontext.cpp:69
QgsProcessingUtils
Utility functions for use with processing classes.
Definition: qgsprocessingutils.h:53
QgsProcessingContext::ellipsoid
QString ellipsoid() const
Returns the ellipsoid to use for distance and area calculations.
Definition: qgsprocessingcontext.cpp:185
QgsProcessingContext::setInvalidGeometryCheck
void setInvalidGeometryCheck(QgsFeatureRequest::InvalidGeometryCheck check)
Sets the behavior used for checking invalid geometries in input layers.
Definition: qgsprocessingcontext.cpp:62
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:555
QgsProcessingContext::exportToMap
QVariantMap exportToMap() const
Exports the context's settings to a variant map.
Definition: qgsprocessingcontext.cpp:142
QgsUnitTypes::AreaUnit
AreaUnit
Units of area.
Definition: qgsunittypes.h:93
QgsProcessingLayerPostProcessorInterface
An interface for layer post-processing handlers for execution following a processing algorithm operat...
Definition: qgsprocessingcontext.h:737
QgsProcessingContext::LayerDetails::postProcessor
QgsProcessingLayerPostProcessorInterface * postProcessor() const
Layer post-processor.
Definition: qgsprocessingcontext.cpp:215
QgsProcessingContext::setAreaUnit
void setAreaUnit(QgsUnitTypes::AreaUnit areaUnit)
Sets the unit to use for area calculations.
Definition: qgsprocessingcontext.cpp:210
QgsProcessingContext::setDistanceUnit
void setDistanceUnit(QgsUnitTypes::DistanceUnit unit)
Sets the unit to use for distance calculations.
Definition: qgsprocessingcontext.cpp:200
QgsProcessingContext::LayerDetails
Details for layers to load into projects.
Definition: qgsprocessingcontext.h:262
QgsMapLayerStore::takeMapLayer
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the store.
Definition: qgsmaplayerstore.cpp:177
QgsProcessingContext::getMapLayer
QgsMapLayer * getMapLayer(const QString &identifier)
Returns a map layer from the context with a matching identifier.
Definition: qgsprocessingcontext.cpp:122
QgsProcessingContext::temporaryLayerStore
QgsMapLayerStore * temporaryLayerStore()
Returns a reference to the layer store used for storing temporary layers during algorithm execution.
Definition: qgsprocessingcontext.h:255
QgsProcessingContext::QgsProcessingContext
QgsProcessingContext()
Constructor for QgsProcessingContext.
Definition: qgsprocessingcontext.cpp:24
QgsMapLayer::isTemporary
virtual bool isTemporary() const
Returns true if the layer is considered a temporary layer.
Definition: qgsmaplayer.cpp:2036
qgsprocessingutils.h
QgsMapLayer::source
QString source() const
Returns the source for the layer.
Definition: qgsmaplayer.cpp:300
QgsProcessingContext::addLayerToLoadOnCompletion
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.
Definition: qgsprocessingcontext.cpp:54
QgsProcessingContext::areaUnit
QgsUnitTypes::AreaUnit areaUnit() const
Returns the area unit to use for area calculations.
Definition: qgsprocessingcontext.cpp:205
QgsMapLayer::setName
void setName(const QString &name)
Set the display name of the layer.
Definition: qgsmaplayer.cpp:174
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
qgssettings.h
QgsProcessingContext::flags
QgsProcessingContext::Flags flags() const
Returns any flags set in the context.
Definition: qgsprocessingcontext.h:109
QgsFeatureRequest::GeometryNoCheck
@ GeometryNoCheck
No invalid geometry checking.
Definition: qgsfeaturerequest.h:124
qgsprocessingcontext.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:376
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsProcessing::settingsPreferFilenameAsLayerName
static const QgsSettingsEntryBool settingsPreferFilenameAsLayerName
Settings entry prefer filename as layer name.
Definition: qgsprocessing.h:113
QgsProviderRegistry::instance
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Definition: qgsproviderregistry.cpp:73
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:82
QgsUnitTypes::AreaUnknownUnit
@ AreaUnknownUnit
Unknown areal unit.
Definition: qgsunittypes.h:106
QgsSettingsEntryByValue::value
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
Definition: qgssettingsentry.h:520
QgsProcessingContext::logLevel
LogLevel logLevel() const
Returns the logging level for algorithms to use when pushing feedback messages to users.
Definition: qgsprocessingcontext.cpp:132