QGIS API Documentation 4.3.0-Master (16649ce5cc6)
Loading...
Searching...
No Matches
qgsprocessingguiutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprocessingguiutils.cpp
3 ------------------------
4 Date : June 2025
5 Copyright : (C) 2025 Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include <optional>
19
20#include "qgslayertree.h"
21#include "qgslayertreelayer.h"
23#include "qgslayertreeview.h"
24
25#include <QString>
26
27using namespace Qt::StringLiterals;
28
30{
31 const QgsMapLayer *layer = layerTreeLayer->layer();
32 if ( layer && layer->type() == Qgis::LayerType::Vector )
33 {
34 // post-process vector layer
35 QgsSettings settings;
36 if ( settings.value( u"Processing/Configuration/VECTOR_FEATURE_COUNT"_s, false ).toBool() )
37 {
38 layerTreeLayer->setCustomProperty( u"showFeatureCount"_s, true );
39 }
40 }
41}
42
44{
45 QgsProject *destinationProject = layerDetails.project ? layerDetails.project : context.project();
46 if ( !destinationProject )
47 return nullptr;
48
49 QgsLayerTreeGroup *resultsGroup = nullptr;
50
51 // if a specific results group is specified in Processing settings,
52 // respect it (and create if necessary)
53 QgsSettings settings;
54 const QString resultsGroupName = settings.value( u"Processing/Configuration/RESULTS_GROUP_NAME"_s, QString() ).toString();
55
56 if ( !resultsGroupName.isEmpty() )
57 {
58 resultsGroup = destinationProject->layerTreeRoot()->findGroup( resultsGroupName );
59 if ( !resultsGroup )
60 {
61 resultsGroup = destinationProject->layerTreeRoot()->insertGroup( 0, resultsGroupName );
62 resultsGroup->setExpanded( true );
63 }
64 }
65
66 // if this particular output layer has a specific output group assigned,
67 // find or create it now
68 QgsLayerTreeGroup *group = nullptr;
69 if ( !layerDetails.groupName.isEmpty() )
70 {
71 if ( !resultsGroup )
72 {
73 resultsGroup = destinationProject->layerTreeRoot();
74 }
75
76 group = resultsGroup->findGroup( layerDetails.groupName );
77 if ( !group )
78 {
79 group = resultsGroup->insertGroup( 0, layerDetails.groupName );
80 group->setExpanded( true );
81 }
82 }
83 else
84 {
85 group = resultsGroup;
86 }
87
88 return group;
89}
90
91void QgsProcessingGuiUtils::addResultLayers( const QVector<ResultLayerDetails> &layers, const QgsProcessingContext &context, QgsLayerTreeView *view )
92{
93 // sort added layer tree layers
94 QVector<ResultLayerDetails> sortedLayers = layers;
95 std::sort( sortedLayers.begin(), sortedLayers.end(), []( const ResultLayerDetails &a, const ResultLayerDetails &b ) { return a.sortKey < b.sortKey; } );
96
97 bool haveSetActiveLayer = false;
98 QgsLayerTreeNode *currentSelectedNode = nullptr;
99 if ( view )
100 {
101 currentSelectedNode = view->currentNode();
102 }
103 QgsLayerTreeGroup *defaultTargetGroup = nullptr;
104 int defaultTargetGroupIndex = 0;
105 if ( auto currentSelectedLayer = qobject_cast< QgsLayerTreeLayer * >( currentSelectedNode ) )
106 {
107 defaultTargetGroup = qobject_cast< QgsLayerTreeGroup * >( currentSelectedLayer->parent() );
108 if ( defaultTargetGroup )
109 defaultTargetGroupIndex = defaultTargetGroup->children().indexOf( currentSelectedNode );
110 }
111 if ( auto currentSelectedGroup = qobject_cast< QgsLayerTreeGroup * >( currentSelectedNode ) )
112 {
113 defaultTargetGroup = currentSelectedGroup;
114 }
115
116 for ( const ResultLayerDetails &layerDetails : std::as_const( sortedLayers ) )
117 {
118 QgsProject *project = layerDetails.destinationProject;
119 if ( !project )
120 project = context.project();
121
122 // store the current insertion point to restore it later
123 std::optional< QgsLayerTreeRegistryBridge::InsertionPoint > previousInsertionPoint;
124 if ( project )
125 {
126 previousInsertionPoint.emplace( project->layerTreeRegistryBridge()->layerInsertionPoint() );
127 }
128
129 std::optional< QgsLayerTreeRegistryBridge::InsertionPoint > insertionPoint;
130 if ( layerDetails.targetLayerTreeGroup )
131 {
132 insertionPoint.emplace( QgsLayerTreeRegistryBridge::InsertionPoint( layerDetails.targetLayerTreeGroup, 0 ) );
133 }
134 else
135 {
136 // no destination group for this layer, so should be placed
137 // above the current layer if one was selected, or at top of group if a group was selected
138 if ( defaultTargetGroup )
139 {
140 insertionPoint.emplace( QgsLayerTreeRegistryBridge::InsertionPoint( defaultTargetGroup, defaultTargetGroupIndex ) );
141 }
142 else if ( project )
143 {
144 insertionPoint.emplace( QgsLayerTreeRegistryBridge::InsertionPoint( project->layerTreeRoot(), 0 ) );
145 }
146 }
147
148 if ( project && insertionPoint.has_value() )
149 {
150 project->layerTreeRegistryBridge()->setLayerInsertionPoint( *insertionPoint );
151 }
152
153 if ( project )
154 {
155 project->addMapLayer( layerDetails.layer );
156 QgsLayerTreeLayer *layerTreeLayer = project->layerTreeRoot()->findLayer( layerDetails.layer );
157 configureResultLayerTreeLayer( layerTreeLayer );
158 }
159
160 if ( !haveSetActiveLayer && view )
161 {
162 view->setCurrentLayer( layerDetails.layer );
163 haveSetActiveLayer = true;
164 }
165
166 // reset to the previous insertion point
167 if ( project && previousInsertionPoint.has_value() )
168 {
169 project->layerTreeRegistryBridge()->setLayerInsertionPoint( *previousInsertionPoint );
170 }
171 }
172}
173
175{
176 return {
177 { static_cast< int >( Qgis::ProcessingMenu::VectorAnalysis ),
178 { "native:distancematrix",
179 "native:sumlinelengths",
180 "native:countpointsinpolygon",
181 "native:listuniquevalues",
182 "native:basicstatisticsforfields",
183 "native:nearestneighbouranalysis",
184 "native:meancoordinates",
185 "native:lineintersections" } },
186 { static_cast< int >( Qgis::ProcessingMenu::VectorResearch ),
187 { "native:creategrid",
188 "native:randomselection",
189 "native:randomselectionwithinsubsets",
190 "native:randompointsinextent",
191 "qgis:randompointsinlayerbounds",
192 "native:randompointsinpolygons",
193 "qgis:randompointsinsidepolygons",
194 "native:randompointsonlines",
195 "qgis:regularpoints",
196 "native:selectbylocation",
197 "native:selectwithindistance",
198 "native:polygonfromlayerextent" } },
199 { static_cast< int >( Qgis::ProcessingMenu::VectorGeoprocessing ),
200 { "native:buffer", "native:convexhull", "native:intersection", "native:union", "native:symmetricaldifference", "native:clip", "native:difference", "native:dissolve", "qgis:eliminateselectedpolygons" } },
201 { static_cast< int >( Qgis::ProcessingMenu::VectorGeometry ),
202 { "native:checkvalidity",
203 "native:exportaddgeometrycolumns",
204 "native:centroids",
205 "native:delaunaytriangulation",
206 "native:voronoipolygons",
207 "native:simplifygeometries",
208 "native:densifygeometries",
209 "native:multiparttosingleparts",
210 "native:collect",
211 "native:polygonstolines",
212 "qgis:linestopolygons",
213 "native:extractvertices" } },
214 { static_cast< int >( Qgis::ProcessingMenu::VectorDataManagement ),
215 { "native:reprojectlayer", "native:joinattributesbylocation", "native:splitvectorlayer", "native:mergevectorlayers", "native:createspatialindex" } },
216 { static_cast< int >( Qgis::ProcessingMenu::RasterProjections ), { "gdal:warpreproject", "gdal:extractprojection", "gdal:assignprojection" } },
217 { static_cast< int >( Qgis::ProcessingMenu::RasterConversion ), { "gdal:rasterize", "gdal:polygonize", "gdal:translate", "gdal:rgbtopct", "gdal:pcttorgb" } },
218 { static_cast< int >( Qgis::ProcessingMenu::RasterExtraction ), { "gdal:contour", "gdal:cliprasterbyextent", "gdal:cliprasterbymasklayer" } },
219 { static_cast< int >( Qgis::ProcessingMenu::RasterAnalysis ),
220 { "gdal:sieve",
221 "gdal:nearblack",
222 "gdal:fillnodata",
223 "gdal:proximity",
224 "gdal:griddatametrics",
225 "gdal:gridaverage",
226 "gdal:gridinversedistance",
227 "gdal:gridnearestneighbor",
228 "gdal:aspect",
229 "gdal:hillshade",
230 "gdal:roughness",
231 "gdal:slope",
232 "gdal:tpitopographicpositionindex",
233 "gdal:triterrainruggednessindex" } },
234 { static_cast< int >( Qgis::ProcessingMenu::RasterMiscellaneous ), { "gdal:buildvirtualraster", "gdal:merge", "gdal:gdalinfo", "gdal:overviews", "gdal:tileindex" } },
235 { static_cast< int >( Qgis::ProcessingMenu::RasterGeneral ), { "native:alignrasters" } }
236 };
237}
@ RasterExtraction
Raster Extraction menu.
Definition qgis.h:3912
@ VectorAnalysis
Vector Analysis menu.
Definition qgis.h:3904
@ VectorGeometry
Vector Geometry menu.
Definition qgis.h:3907
@ VectorResearch
Vector Research menu.
Definition qgis.h:3905
@ RasterAnalysis
Raster Analysis menu.
Definition qgis.h:3913
@ RasterGeneral
Raster (top-level) menu.
Definition qgis.h:3915
@ RasterConversion
Raster Conversion menu.
Definition qgis.h:3911
@ RasterMiscellaneous
Raster Miscellaneous menu.
Definition qgis.h:3914
@ VectorDataManagement
Vector Data Management menu.
Definition qgis.h:3908
@ RasterProjections
Raster Projections menu.
Definition qgis.h:3910
@ VectorGeoprocessing
Vector Geoprocessing menu.
Definition qgis.h:3906
@ Vector
Vector layer.
Definition qgis.h:207
Layer tree group node serves as a container for layers and further groups.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QgsLayerTreeGroup * insertGroup(int index, const QString &name)
Insert a new group node with given name at specified position.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
Base class for nodes in a layer tree.
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void setExpanded(bool expanded)
Sets whether the node should be shown as expanded or collapsed in GUI.
Q_DECL_DEPRECATED void setLayerInsertionPoint(QgsLayerTreeGroup *parentGroup, int index)
Set where the new layers should be inserted - can be used to follow current selection.
InsertionPoint layerInsertionPoint() const
Returns the insertion point used to add layers to the tree.
QgsLayerTreeNode * currentNode() const
Returns the current node.
void setCurrentLayer(QgsMapLayer *layer)
Sets the currently selected layer.
Extends QTreeView and provides additional functionality when working with a layer tree.
Base class for all map layer types.
Definition qgsmaplayer.h:83
Qgis::LayerType type
Definition qgsmaplayer.h:93
Details for layers to load into projects.
QString groupName
Optional name for a layer tree group under which to place the layer when loading it into a project.
QgsProject * project
Destination project.
Contains information about the context in which a processing algorithm is executed.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
Contains details of a layer result from running an algorithm.
static void addResultLayers(const QVector< QgsProcessingGuiUtils::ResultLayerDetails > &layers, const QgsProcessingContext &context, QgsLayerTreeView *view=nullptr)
Responsible for adding layers created by an algorithm to a project and the project's layer tree in th...
static QMap< int, QStringList > defaultProcessingMenuEntries()
Returns the map of Processing menus to a list of algorithm IDs to include by default in that menu.
static void configureResultLayerTreeLayer(QgsLayerTreeLayer *layerTreeLayer)
Applies post-processing steps to the QgsLayerTreeLayer created for an algorithm's output.
static QgsLayerTreeGroup * layerTreeResultsGroup(const QgsProcessingContext::LayerDetails &layerDetails, const QgsProcessingContext &context)
Returns the destination layer tree group to store results in, or nullptr if there is no specific dest...
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:114
QgsLayerTreeRegistryBridge * layerTreeRegistryBridge() const
Returns pointer to the helper class that synchronizes map layer registry with layer tree.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
QgsMapLayer * addMapLayer(QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
Add a layer to the map of loaded layers.
Stores settings for use within QGIS.
Definition qgssettings.h:68
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
A structure to define the insertion point to the layer tree.