QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 mEllipsoid;
134 }
135 
136 void QgsProcessingContext::setEllipsoid( const QString &ellipsoid )
137 {
138  mEllipsoid = ellipsoid;
139 }
140 
142 {
143  return mDistanceUnit;
144 }
145 
147 {
148  mDistanceUnit = unit;
149 }
150 
152 {
153  return mAreaUnit;
154 }
155 
157 {
158  mAreaUnit = areaUnit;
159 }
160 
162 {
163  return mPostProcessor;
164 }
165 
167 {
168  if ( mPostProcessor && mPostProcessor != processor )
169  delete mPostProcessor;
170 
171  mPostProcessor = processor;
172 }
173 
175 {
176  if ( !layer )
177  return;
178 
179  const bool preferFilenameAsLayerName = QgsSettings().value( QStringLiteral( "Processing/Configuration/PREFER_FILENAME_AS_LAYER_NAME" ), true ).toBool();
180 
181  // note - for temporary layers, we don't use the filename, regardless of user setting (it will be meaningless!)
182  if ( ( !forceName && preferFilenameAsLayerName && !layer->isTemporary() ) || name.isEmpty() )
183  {
184  const QVariantMap sourceParts = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->source() );
185  const QString layerName = sourceParts.value( QStringLiteral( "layerName" ) ).toString();
186  // if output layer name exists, use that!
187  if ( !layerName.isEmpty() )
188  layer->setName( layerName );
189  else
190  {
191  const QString path = sourceParts.value( QStringLiteral( "path" ) ).toString();
192  if ( !path.isEmpty() )
193  {
194  const QFileInfo fi( path );
195  layer->setName( fi.baseName() );
196  }
197  else if ( !name.isEmpty() )
198  {
199  // fallback to parameter's name -- shouldn't happen!
200  layer->setName( name );
201  }
202  }
203  }
204  else
205  {
206  layer->setName( name );
207  }
208 }
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::LayerDetails::setPostProcessor
void setPostProcessor(QgsProcessingLayerPostProcessorInterface *processor)
Sets the layer post-processor.
Definition: qgsprocessingcontext.cpp:166
QgsFeatureRequest::GeometryAbortOnInvalid
@ GeometryAbortOnInvalid
Close iterator on encountering any features with invalid geometry. This requires a slow geometry vali...
Definition: qgsfeaturerequest.h:103
QgsProcessingContext::~QgsProcessingContext
~QgsProcessingContext()
Definition: qgsprocessingcontext.cpp:35
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
QgsProcessingContext::distanceUnit
QgsUnitTypes::DistanceUnit distanceUnit() const
Returns the distance unit to use for distance calculations.
Definition: qgsprocessingcontext.cpp:141
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:76
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:126
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:43
QgsFeatureSource
An interface for objects which provide features via a getFeatures method.
Definition: qgsfeaturesource.h:38
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QgsFeatureRequest::InvalidGeometryCheck
InvalidGeometryCheck
Handling of features with invalid geometries.
Definition: qgsfeaturerequest.h:100
QgsFeatureRequest::GeometrySkipInvalid
@ GeometrySkipInvalid
Skip any features with invalid geometry. This requires a slow geometry validity check for every featu...
Definition: qgsfeaturerequest.h:102
QgsUnitTypes::DistanceUnit
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:68
QgsMapLayerStore::mapLayer
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
Definition: qgsmaplayerstore.cpp:49
QgsMapLayer::providerType
QString providerType() const
Returns the provider type (provider key) for this layer.
Definition: qgsmaplayer.cpp:1617
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:174
QgsProcessingContext::setEllipsoid
void setEllipsoid(const QString &ellipsoid)
Sets a specified ellipsoid to use for distance and area calculations.
Definition: qgsprocessingcontext.cpp:136
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:114
qgsproviderregistry.h
QgsFeatureSource::sourceName
virtual QString sourceName() const =0
Returns a friendly display name for the source.
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
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:68
QgsProcessingUtils
Utility functions for use with processing classes.
Definition: qgsprocessingutils.h:51
QgsProcessingContext::ellipsoid
QString ellipsoid() const
Returns the ellipsoid to use for distance and area calculations.
Definition: qgsprocessingcontext.cpp:131
QgsProcessingContext::setInvalidGeometryCheck
void setInvalidGeometryCheck(QgsFeatureRequest::InvalidGeometryCheck check)
Sets the behavior used for checking invalid geometries in input layers.
Definition: qgsprocessingcontext.cpp:61
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:433
QgsUnitTypes::AreaUnit
AreaUnit
Units of area.
Definition: qgsunittypes.h:94
QgsProcessingLayerPostProcessorInterface
An interface for layer post-processing handlers for execution following a processing algorithm operat...
Definition: qgsprocessingcontext.h:660
QgsProcessingContext::LayerDetails::postProcessor
QgsProcessingLayerPostProcessorInterface * postProcessor() const
Layer post-processor.
Definition: qgsprocessingcontext.cpp:161
QgsProcessingContext::setAreaUnit
void setAreaUnit(QgsUnitTypes::AreaUnit areaUnit)
Sets the unit to use for area calculations.
Definition: qgsprocessingcontext.cpp:156
QgsProcessingContext::setDistanceUnit
void setDistanceUnit(QgsUnitTypes::DistanceUnit unit)
Sets the unit to use for distance calculations.
Definition: qgsprocessingcontext.cpp:146
QgsProcessingContext::LayerDetails
Details for layers to load into projects.
Definition: qgsprocessingcontext.h:231
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:121
QgsProcessingContext::temporaryLayerStore
QgsMapLayerStore * temporaryLayerStore()
Returns a reference to the layer store used for storing temporary layers during algorithm execution.
Definition: qgsprocessingcontext.h:223
QgsProcessingContext::QgsProcessingContext
QgsProcessingContext()
Constructor for QgsProcessingContext.
Definition: qgsprocessingcontext.cpp:23
QgsMapLayer::isTemporary
virtual bool isTemporary() const
Returns true if the layer is considered a temporary layer.
Definition: qgsmaplayer.cpp:1750
qgsprocessingutils.h
QgsMapLayer::source
QString source() const
Returns the source for the layer.
Definition: qgsmaplayer.cpp:192
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:53
QgsProcessingContext::areaUnit
QgsUnitTypes::AreaUnit areaUnit() const
Returns the area unit to use for area calculations.
Definition: qgsprocessingcontext.cpp:151
QgsMapLayer::setName
void setName(const QString &name)
Set the display name of the layer.
Definition: qgsmaplayer.cpp:153
QgsMapLayer
Base class for all map layer types.
Definition: qgsmaplayer.h:83
qgssettings.h
QgsFeatureRequest::GeometryNoCheck
@ GeometryNoCheck
No invalid geometry checking.
Definition: qgsfeaturerequest.h:101
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:316
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsProviderRegistry::instance
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Definition: qgsproviderregistry.cpp:48
QgsProcessingException
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83