Skip to content

Commit 9a05951

Browse files
authoredApr 5, 2017
Merge pull request #4331 from nyalldawson/dataobjects
Port some processing dataobjects routines to c++
2 parents d5f930a + 8ffdb36 commit 9a05951

19 files changed

+455
-117
lines changed
 

‎python/core/core.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@
277277
%Include processing/qgsprocessingfeedback.sip
278278
%Include processing/qgsprocessingprovider.sip
279279
%Include processing/qgsprocessingregistry.sip
280+
%Include processing/qgsprocessingutils.sip
280281

281282
%Include raster/qgsbilinearrasterresampler.sip
282283
%Include raster/qgsbrightnesscontrastfilter.sip
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/processing/qgsprocessingutils.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
13+
14+
15+
class QgsProcessingUtils
16+
{
17+
%Docstring
18+
Utility functions for use with processing classes.
19+
.. versionadded:: 3.0
20+
%End
21+
22+
%TypeHeaderCode
23+
#include "qgsprocessingutils.h"
24+
%End
25+
26+
public:
27+
28+
static QList< QgsRasterLayer * > compatibleRasterLayers( QgsProject *project, bool sort = true );
29+
%Docstring
30+
Returns a list of raster layers from a project which are compatible with the processing
31+
framework.
32+
33+
If the sort argument is true then the layers will be sorted by their QgsMapLayer.name()
34+
value.
35+
\see compatibleVectorLayers()
36+
\see compatibleLayers()
37+
%End
38+
39+
static QList< QgsVectorLayer * > compatibleVectorLayers( QgsProject *project,
40+
const QList< QgsWkbTypes::GeometryType > &geometryTypes = QList< QgsWkbTypes::GeometryType >(),
41+
bool sort = true );
42+
%Docstring
43+
Returns a list of vector layers from a project which are compatible with the processing
44+
framework.
45+
46+
If the geometryTypes list is non-empty then the layers will be sorted so that only
47+
layers with geometry types included in the list will be returned. Leaving the geometryTypes
48+
list empty will cause all vector layers, regardless of their geometry type, to be returned.
49+
50+
If the sort argument is true then the layers will be sorted by their QgsMapLayer.name()
51+
value.
52+
\see compatibleRasterLayers()
53+
\see compatibleLayers()
54+
%End
55+
56+
static QList< QgsMapLayer * > compatibleLayers( QgsProject *project, bool sort = true );
57+
%Docstring
58+
Returns a list of map layers from a project which are compatible with the processing
59+
framework.
60+
61+
If the sort argument is true then the layers will be sorted by their QgsMapLayer.name()
62+
value.
63+
\see compatibleRasterLayers()
64+
\see compatibleVectorLayers()
65+
%End
66+
67+
};
68+
69+
70+
71+
/************************************************************************
72+
* This file has been generated automatically from *
73+
* *
74+
* src/core/processing/qgsprocessingutils.h *
75+
* *
76+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
77+
************************************************************************/

‎python/plugins/processing/algs/gdal/GdalAlgorithm.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
from qgis.PyQt.QtCore import QUrl
3232

3333
from qgis.core import (QgsApplication,
34-
QgsVectorFileWriter)
34+
QgsVectorFileWriter,
35+
QgsProcessingUtils,
36+
QgsProject)
3537

3638
from processing.core.GeoAlgorithm import GeoAlgorithm
3739
from processing.algs.gdal.GdalAlgorithmDialog import GdalAlgorithmDialog
@@ -58,7 +60,7 @@ def getCustomParametersDialog(self):
5860

5961
def processAlgorithm(self, feedback):
6062
commands = self.getConsoleCommands()
61-
layers = dataobjects.getVectorLayers()
63+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
6264
supported = QgsVectorFileWriter.supportedFormatExtensions()
6365
for i, c in enumerate(commands):
6466
for layer in layers:

‎python/plugins/processing/algs/qgis/RasterCalculator.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
from processing.tools import dataobjects
3535
from processing.algs.gdal.GdalUtils import GdalUtils
3636
from qgis.core import (QgsApplication,
37-
QgsRectangle)
37+
QgsRectangle,
38+
QgsProcessingUtils,
39+
QgsProject)
3840
from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry
3941
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
4042
from processing.algs.qgis.ui.RasterCalculatorWidgets import LayersListWidgetWrapper, ExpressionWidgetWrapper
@@ -108,7 +110,7 @@ def processAlgorithm(self, feedback):
108110
layers = [dataobjects.getObjectFromUri(f) for f in layersValue.split(";")]
109111
layersDict = {os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers}
110112

111-
for lyr in dataobjects.getRasterLayers():
113+
for lyr in QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance()):
112114
name = lyr.name()
113115
if (name + "@") in expression:
114116
layersDict[name] = lyr

‎python/plugins/processing/algs/qgis/ui/FieldsCalculatorDialog.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
from qgis.PyQt.QtGui import QCursor
3636
from qgis.core import (QgsExpressionContextUtils,
3737
QgsProcessingFeedback,
38-
QgsSettings)
38+
QgsSettings,
39+
QgsProcessingUtils,
40+
QgsProject)
3941
from qgis.gui import QgsEncodingFileDialog
4042

4143
from processing.core.ProcessingConfig import ProcessingConfig
@@ -101,7 +103,7 @@ def manageGui(self):
101103
self.mOutputFieldTypeComboBox.blockSignals(False)
102104

103105
self.cmbInputLayer.blockSignals(True)
104-
layers = dataobjects.getVectorLayers()
106+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
105107
for layer in layers:
106108
self.cmbInputLayer.addItem(layer.name())
107109
self.cmbInputLayer.blockSignals(False)

‎python/plugins/processing/algs/qgis/ui/FieldsMappingPanel.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@
3535
from qgis.PyQt.QtWidgets import QComboBox, QHeaderView, QLineEdit, QSpacerItem, QMessageBox, QSpinBox, QStyledItemDelegate
3636
from qgis.PyQt.QtCore import QItemSelectionModel, QAbstractTableModel, QModelIndex, QVariant, Qt, pyqtSlot
3737

38-
from qgis.core import QgsExpression, QgsProject, QgsApplication
38+
from qgis.core import (QgsExpression,
39+
QgsProject,
40+
QgsApplication,
41+
QgsProcessingUtils)
3942
from qgis.gui import QgsFieldExpressionWidget
4043

4144
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER
@@ -473,8 +476,7 @@ def on_model_rowsInserted(self, parent, start, end):
473476
self.model.index(end, self.model.columnCount() - 1))
474477

475478
def updateLayerCombo(self):
476-
layers = dataobjects.getTables()
477-
layers.sort(key=lambda lay: lay.name())
479+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
478480
for layer in layers:
479481
self.layerCombo.addItem(layer.name(), layer)
480482

@@ -496,7 +498,7 @@ def postInitialize(self, wrappers):
496498
if wrapper.param.name == self.param.parent:
497499
wrapper.widgetValueHasChanged.connect(self.parentLayerChanged)
498500
break
499-
layers = dataobjects.getTables()
501+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
500502
if len(layers) > 0:
501503
# as first item in combobox is already selected
502504
self.widget.setLayer(layers[0])

‎python/plugins/processing/algs/qgis/ui/RasterCalculatorWidgets.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from qgis.core import (QgsProcessingUtils,
2+
QgsProject)
13
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_BATCH
24
from processing.tools import dataobjects
35
from processing.tools.system import userFolder
@@ -170,7 +172,7 @@ def _panel(self, options):
170172

171173
def createWidget(self):
172174
if self.dialogType == DIALOG_STANDARD:
173-
layers = dataobjects.getRasterLayers(sorting=False)
175+
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
174176
options = {}
175177
for lyr in layers:
176178
for n in range(lyr.bandCount()):
@@ -185,7 +187,7 @@ def createWidget(self):
185187
return self._panel(options)
186188

187189
def refresh(self):
188-
layers = dataobjects.getRasterLayers()
190+
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
189191
options = {}
190192
for lyr in layers:
191193
for n in range(lyr.bandCount()):
@@ -229,11 +231,11 @@ def value(self):
229231
return self.param.setValue(self.widget.selectedoptions)
230232
else:
231233
if self.param.datatype == dataobjects.TYPE_RASTER:
232-
options = dataobjects.getRasterLayers(sorting=False)
234+
options = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
233235
elif self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
234-
options = dataobjects.getVectorLayers(sorting=False)
236+
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
235237
else:
236-
options = dataobjects.getVectorLayers([self.param.datatype], sorting=False)
238+
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.param.datatype], False)
237239
return [options[i] for i in self.widget.selectedoptions]
238240
elif self.dialogType == DIALOG_BATCH:
239241
return self.widget.getText()

‎python/plugins/processing/core/GeoAlgorithm.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
from qgis.core import (QgsApplication,
3636
QgsProcessingFeedback,
3737
QgsSettings,
38-
QgsProcessingAlgorithm)
38+
QgsProcessingAlgorithm,
39+
QgsProject,
40+
QgsProcessingUtils)
3941

4042
from builtins import str
4143
from builtins import object
@@ -339,7 +341,7 @@ def resolveOutputs(self):
339341
raise GeoAlgorithmExecutionException(str(e))
340342

341343
def setOutputCRS(self):
342-
layers = dataobjects.getAllLayers()
344+
layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance())
343345
for param in self.parameters:
344346
if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
345347
if param.value:
@@ -365,7 +367,7 @@ def setOutputCRS(self):
365367
pass
366368

367369
def resolveDataObjects(self):
368-
layers = dataobjects.getAllLayers()
370+
layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance())
369371
for param in self.parameters:
370372
if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable,
371373
ParameterMultipleInput)):

‎python/plugins/processing/core/outputs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ def __init__(self, name='', description='', hidden=False, base_input=None, datat
319319
def hasGeometry(self):
320320
if self.base_layer is None:
321321
return True
322-
return dataobjects.canUseVectorLayer(self.base_layer, [-1])
322+
return self.base_layer.hasGeometryType()
323323

324324
def getSupportedOutputVectorLayerExtensions(self):
325325
exts = QgsVectorFileWriter.supportedFormatExtensions()

‎python/plugins/processing/core/parameters.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from copy import deepcopy
3737
import numbers
3838

39+
from qgis.core import QgsProcessingUtils
3940
from qgis.utils import iface
4041
from qgis.PyQt.QtCore import QCoreApplication
4142
from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinateReferenceSystem,
@@ -90,7 +91,7 @@ def _expressionContext():
9091

9192

9293
def _resolveLayers(value):
93-
layers = dataobjects.getAllLayers()
94+
layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance())
9495
if value:
9596
inputlayers = value.split(';')
9697
for i, inputlayer in enumerate(inputlayers):
@@ -727,7 +728,7 @@ def getAsString(self, value):
727728
return str(value.dataProvider().dataSourceUri())
728729
else:
729730
s = str(value)
730-
layers = dataobjects.getRasterLayers()
731+
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
731732
for layer in layers:
732733
if layer.name() == s:
733734
return str(layer.dataProvider().dataSourceUri())
@@ -740,7 +741,10 @@ def getAsString(self, value):
740741
return str(value.source())
741742
else:
742743
s = str(value)
743-
layers = dataobjects.getVectorLayers([self.datatype])
744+
if self.datatype != dataobjects.TYPE_VECTOR_ANY:
745+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.datatype], False)
746+
else:
747+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
744748
for layer in layers:
745749
if layer.name() == s:
746750
return str(layer.source())
@@ -1317,7 +1321,7 @@ def setValue(self, obj):
13171321
return True
13181322
else:
13191323
self.value = str(obj)
1320-
layers = dataobjects.getTables()
1324+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
13211325
for layer in layers:
13221326
if layer.name() == self.value or layer.source() == self.value:
13231327
source = str(layer.source())

‎python/plugins/processing/gui/AlgorithmDialog.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QPushButton, QWidget, QVBoxLayout, QSizePolicy
3131
from qgis.PyQt.QtGui import QCursor, QColor, QPalette
3232

33-
from qgis.core import QgsProject
33+
from qgis.core import (QgsProject,
34+
QgsProcessingUtils)
3435
from qgis.gui import QgsMessageBar
3536
from qgis.utils import iface
3637

@@ -113,7 +114,7 @@ def checkExtentCRS(self):
113114
unmatchingCRS = False
114115
hasExtent = False
115116
projectCRS = iface.mapCanvas().mapSettings().destinationCrs()
116-
layers = dataobjects.getAllLayers()
117+
layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance())
117118
for param in self.alg.parameters:
118119
if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
119120
if param.value:

‎python/plugins/processing/gui/BatchInputSelectionPanel.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@
3333
from qgis.PyQt.QtWidgets import QWidget, QHBoxLayout, QMenu, QPushButton, QLineEdit, QSizePolicy, QAction, QFileDialog
3434
from qgis.PyQt.QtGui import QCursor
3535

36-
from qgis.core import QgsMapLayer, QgsSettings
36+
from qgis.core import (QgsMapLayer,
37+
QgsSettings,
38+
QgsProject,
39+
QgsProcessingUtils)
3740

3841
from processing.gui.MultipleInputDialog import MultipleInputDialog
3942

@@ -99,15 +102,18 @@ def showLayerSelectionDialog(self):
99102
if (isinstance(self.param, ParameterRaster) or
100103
(isinstance(self.param, ParameterMultipleInput) and
101104
self.param.datatype == dataobjects.TYPE_RASTER)):
102-
layers = dataobjects.getRasterLayers()
105+
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
103106
elif isinstance(self.param, ParameterTable):
104-
layers = dataobjects.getTables()
107+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
105108
else:
106109
if isinstance(self.param, ParameterVector):
107110
datatype = self.param.datatype
108111
else:
109112
datatype = [self.param.datatype]
110-
layers = dataobjects.getVectorLayers(datatype)
113+
if datatype != dataobjects.TYPE_VECTOR_ANY:
114+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [datatype])
115+
else:
116+
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
111117

112118
dlg = MultipleInputDialog([layer.name() for layer in layers])
113119
dlg.exec_()

‎python/plugins/processing/gui/ExtentSelectionPanel.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434

3535
from qgis.gui import QgsMessageBar
3636
from qgis.utils import iface
37-
37+
from qgis.core import (QgsProcessingUtils,
38+
QgsProject)
3839
from processing.gui.RectangleMapTool import RectangleMapTool
3940
from processing.core.ProcessingConfig import ProcessingConfig
4041
from processing.tools import dataobjects
@@ -108,7 +109,7 @@ def useLayerExtent(self):
108109
extentsDict[CANVAS_KEY] = {"extent": iface.mapCanvas().extent(),
109110
"authid": iface.mapCanvas().mapSettings().destinationCrs().authid()}
110111
extents = [CANVAS_KEY]
111-
layers = dataobjects.getAllLayers()
112+
layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance())
112113
for layer in layers:
113114
authid = layer.crs().authid()
114115
if ProcessingConfig.getSetting(ProcessingConfig.SHOW_CRS_DEF) \

‎python/plugins/processing/gui/wrappers.py

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
QgsWkbTypes,
4141
QgsSettings,
4242
QgsProject,
43-
QgsMapLayer
43+
QgsMapLayer,
44+
QgsProcessingUtils
4445
)
4546
from qgis.PyQt.QtWidgets import (
4647
QCheckBox,
@@ -519,13 +520,11 @@ def createWidget(self):
519520
return MultipleInputPanel(datatype=dataobjects.TYPE_FILE)
520521
else:
521522
if self.param.datatype == dataobjects.TYPE_RASTER:
522-
options = dataobjects.getRasterLayers(sorting=False)
523-
elif self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
524-
options = dataobjects.getVectorLayers(sorting=False)
525-
elif self.param.datatype == dataobjects.TYPE_TABLE:
526-
options = dataobjects.getTables(sorting=False)
523+
options = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
524+
elif self.param.datatype in (dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_TABLE):
525+
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
527526
else:
528-
options = dataobjects.getVectorLayers([self.param.datatype], sorting=False)
527+
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.param.datatype], False)
529528
opts = [getExtendedLayerName(opt) for opt in options]
530529
return MultipleInputPanel(opts)
531530
elif self.dialogType == DIALOG_BATCH:
@@ -539,13 +538,11 @@ def createWidget(self):
539538
def refresh(self):
540539
if self.param.datatype != dataobjects.TYPE_FILE:
541540
if self.param.datatype == dataobjects.TYPE_RASTER:
542-
options = dataobjects.getRasterLayers(sorting=False)
543-
elif self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
544-
options = dataobjects.getVectorLayers(sorting=False)
545-
elif self.param.datatype == dataobjects.TYPE_TABLE:
546-
options = dataobjects.getTables(sorting=False)
541+
options = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
542+
elif self.param.datatype in (dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_TABLE):
543+
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
547544
else:
548-
options = dataobjects.getVectorLayers([self.param.datatype], sorting=False)
545+
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.param.datatype], False)
549546
opts = [getExtendedLayerName(opt) for opt in options]
550547
self.widget.updateForOptions(opts)
551548

@@ -568,13 +565,11 @@ def value(self):
568565
return self.param.setValue(self.widget.selectedoptions)
569566
else:
570567
if self.param.datatype == dataobjects.TYPE_RASTER:
571-
options = dataobjects.getRasterLayers(sorting=False)
572-
elif self.param.datatype == dataobjects.TYPE_VECTOR_ANY:
573-
options = dataobjects.getVectorLayers(sorting=False)
574-
elif self.param.datatype == dataobjects.TYPE_TABLE:
575-
options = dataobjects.getTables(sorting=False)
568+
options = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance(), False)
569+
elif self.param.datatype in (dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_TABLE):
570+
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
576571
else:
577-
options = dataobjects.getVectorLayers([self.param.datatype], sorting=False)
572+
options = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.param.datatype], False)
578573
return [options[i] for i in self.widget.selectedoptions]
579574
elif self.dialogType == DIALOG_BATCH:
580575
return self.widget.getText()

‎python/plugins/processing/tools/dataobjects.py

Lines changed: 4 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
QgsVectorLayer,
3838
QgsProject,
3939
QgsCoordinateReferenceSystem,
40-
QgsSettings)
40+
QgsSettings,
41+
QgsProcessingUtils)
4142
from qgis.gui import QgsSublayersDialog
4243

4344
from processing.core.ProcessingConfig import ProcessingConfig
@@ -76,60 +77,6 @@ def getSupportedOutputRasterLayerExtensions():
7677
return allexts
7778

7879

79-
def getRasterLayers(sorting=True):
80-
layers = QgsProject.instance().layerTreeRoot().findLayers()
81-
raster = [lay.layer() for lay in layers if lay.layer() is not None and canUseRasterLayer(lay.layer())]
82-
if sorting:
83-
return sorted(raster, key=lambda layer: layer.name().lower())
84-
else:
85-
return raster
86-
87-
88-
def getVectorLayers(shapetype=[-1], sorting=True):
89-
layers = QgsProject.instance().layerTreeRoot().findLayers()
90-
vector = [lay.layer() for lay in layers if canUseVectorLayer(lay.layer(), shapetype)]
91-
if sorting:
92-
return sorted(vector, key=lambda layer: layer.name().lower())
93-
else:
94-
return vector
95-
96-
97-
def canUseVectorLayer(layer, shapetype):
98-
if layer.type() == QgsMapLayer.VectorLayer and layer.dataProvider().name() != "grass":
99-
if (layer.hasGeometryType() and
100-
(shapetype == ALL_TYPES or layer.geometryType() in shapetype)):
101-
return True
102-
return False
103-
104-
105-
def canUseRasterLayer(layer):
106-
if layer.type() == QgsMapLayer.RasterLayer:
107-
if layer.providerType() == 'gdal': # only gdal file-based layers
108-
return True
109-
110-
return False
111-
112-
113-
def getAllLayers():
114-
layers = []
115-
layers += getRasterLayers()
116-
layers += getVectorLayers()
117-
return sorted(layers, key=lambda layer: layer.name().lower())
118-
119-
120-
def getTables(sorting=True):
121-
layers = QgsProject.instance().layerTreeRoot().findLayers()
122-
tables = []
123-
for layer in layers:
124-
mapLayer = layer.layer()
125-
if mapLayer.type() == QgsMapLayer.VectorLayer:
126-
tables.append(mapLayer)
127-
if sorting:
128-
return sorted(tables, key=lambda table: table.name().lower())
129-
else:
130-
return tables
131-
132-
13380
def extent(layers):
13481
first = True
13582
for layer in layers:
@@ -206,7 +153,7 @@ def load(fileName, name=None, crs=None, style=None):
206153

207154

208155
def getObjectFromName(name):
209-
layers = getAllLayers()
156+
layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance(), False)
210157
for layer in layers:
211158
if layer.name() == name:
212159
return layer
@@ -237,18 +184,10 @@ def getObjectFromUri(uri, forceLoad=True):
237184
return None
238185
if uri in _loadedLayers:
239186
return _loadedLayers[uri]
240-
layers = getRasterLayers()
241-
for layer in layers:
242-
if normalizeLayerSource(layer.source()) == normalizeLayerSource(uri):
243-
return layer
244-
layers = getVectorLayers()
187+
layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance(), False)
245188
for layer in layers:
246189
if normalizeLayerSource(layer.source()) == normalizeLayerSource(uri):
247190
return layer
248-
tables = getTables()
249-
for table in tables:
250-
if normalizeLayerSource(table.source()) == normalizeLayerSource(uri):
251-
return table
252191
if forceLoad and os.path.exists(uri):
253192
settings = QgsSettings()
254193
prjSetting = settings.value('/Projections/defaultBehavior')

‎src/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ SET(QGIS_CORE_SRCS
8787
processing/qgsprocessingalgorithm.cpp
8888
processing/qgsprocessingprovider.cpp
8989
processing/qgsprocessingregistry.cpp
90+
processing/qgsprocessingutils.cpp
9091

9192
qgis.cpp
9293
qgsapplication.cpp
@@ -838,6 +839,7 @@ SET(QGIS_CORE_HDRS
838839

839840
processing/qgsprocessingalgorithm.h
840841
processing/qgsprocessingprovider.h
842+
processing/qgsprocessingutils.h
841843

842844
raster/qgsbilinearrasterresampler.h
843845
raster/qgsbrightnesscontrastfilter.h
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/***************************************************************************
2+
qgsprocessingutils.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 "qgsprocessingutils.h"
19+
#include "qgsproject.h"
20+
21+
QList<QgsRasterLayer *> QgsProcessingUtils::compatibleRasterLayers( QgsProject *project, bool sort )
22+
{
23+
if ( !project )
24+
return QList<QgsRasterLayer *>();
25+
26+
QList<QgsRasterLayer *> layers;
27+
Q_FOREACH ( QgsRasterLayer *l, project->layers<QgsRasterLayer *>() )
28+
{
29+
if ( canUseLayer( l ) )
30+
layers << l;
31+
}
32+
33+
if ( sort )
34+
{
35+
std::sort( layers.begin(), layers.end(), []( const QgsRasterLayer * a, const QgsRasterLayer * b ) -> bool
36+
{
37+
return QString::localeAwareCompare( a->name(), b->name() ) < 0;
38+
} );
39+
}
40+
return layers;
41+
}
42+
43+
QList<QgsVectorLayer *> QgsProcessingUtils::compatibleVectorLayers( QgsProject *project, const QList<QgsWkbTypes::GeometryType> &geometryTypes, bool sort )
44+
{
45+
if ( !project )
46+
return QList<QgsVectorLayer *>();
47+
48+
QList<QgsVectorLayer *> layers;
49+
Q_FOREACH ( QgsVectorLayer *l, project->layers<QgsVectorLayer *>() )
50+
{
51+
if ( canUseLayer( l, geometryTypes ) )
52+
layers << l;
53+
}
54+
55+
if ( sort )
56+
{
57+
std::sort( layers.begin(), layers.end(), []( const QgsVectorLayer * a, const QgsVectorLayer * b ) -> bool
58+
{
59+
return QString::localeAwareCompare( a->name(), b->name() ) < 0;
60+
} );
61+
}
62+
return layers;
63+
}
64+
65+
QList<QgsMapLayer *> QgsProcessingUtils::compatibleLayers( QgsProject *project, bool sort )
66+
{
67+
if ( !project )
68+
return QList<QgsMapLayer *>();
69+
70+
QList<QgsMapLayer *> layers;
71+
Q_FOREACH ( QgsRasterLayer *rl, compatibleRasterLayers( project, false ) )
72+
layers << rl;
73+
Q_FOREACH ( QgsVectorLayer *vl, compatibleVectorLayers( project, QList< QgsWkbTypes::GeometryType >(), false ) )
74+
layers << vl;
75+
76+
if ( sort )
77+
{
78+
std::sort( layers.begin(), layers.end(), []( const QgsMapLayer * a, const QgsMapLayer * b ) -> bool
79+
{
80+
return QString::localeAwareCompare( a->name(), b->name() ) < 0;
81+
} );
82+
}
83+
return layers;
84+
}
85+
86+
bool QgsProcessingUtils::canUseLayer( const QgsRasterLayer *layer )
87+
{
88+
// only gdal file-based layers
89+
return layer && layer->providerType() == QStringLiteral( "gdal" );
90+
}
91+
92+
bool QgsProcessingUtils::canUseLayer( const QgsVectorLayer *layer, const QList<QgsWkbTypes::GeometryType> &geometryTypes )
93+
{
94+
return layer &&
95+
( geometryTypes.isEmpty() || geometryTypes.contains( layer->geometryType() ) );
96+
}
97+
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/***************************************************************************
2+
qgsprocessingutils.h
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+
#ifndef QGSPROCESSINGUTILS_H
19+
#define QGSPROCESSINGUTILS_H
20+
21+
#include "qgis_core.h"
22+
23+
#include "qgsrasterlayer.h"
24+
#include "qgsvectorlayer.h"
25+
26+
class QgsProject;
27+
28+
#include <QString>
29+
30+
/**
31+
* \class QgsProcessingUtils
32+
* \ingroup core
33+
* Utility functions for use with processing classes.
34+
* \since QGIS 3.0
35+
*/
36+
class CORE_EXPORT QgsProcessingUtils
37+
{
38+
39+
public:
40+
41+
/**
42+
* Returns a list of raster layers from a \a project which are compatible with the processing
43+
* framework.
44+
*
45+
* If the \a sort argument is true then the layers will be sorted by their QgsMapLayer::name()
46+
* value.
47+
* \see compatibleVectorLayers()
48+
* \see compatibleLayers()
49+
*/
50+
static QList< QgsRasterLayer * > compatibleRasterLayers( QgsProject *project, bool sort = true );
51+
52+
/**
53+
* Returns a list of vector layers from a \a project which are compatible with the processing
54+
* framework.
55+
*
56+
* If the \a geometryTypes list is non-empty then the layers will be sorted so that only
57+
* layers with geometry types included in the list will be returned. Leaving the \a geometryTypes
58+
* list empty will cause all vector layers, regardless of their geometry type, to be returned.
59+
*
60+
* If the \a sort argument is true then the layers will be sorted by their QgsMapLayer::name()
61+
* value.
62+
* \see compatibleRasterLayers()
63+
* \see compatibleLayers()
64+
*/
65+
static QList< QgsVectorLayer * > compatibleVectorLayers( QgsProject *project,
66+
const QList< QgsWkbTypes::GeometryType > &geometryTypes = QList< QgsWkbTypes::GeometryType >(),
67+
bool sort = true );
68+
69+
/**
70+
* Returns a list of map layers from a \a project which are compatible with the processing
71+
* framework.
72+
*
73+
* If the \a sort argument is true then the layers will be sorted by their QgsMapLayer::name()
74+
* value.
75+
* \see compatibleRasterLayers()
76+
* \see compatibleVectorLayers()
77+
*/
78+
static QList< QgsMapLayer * > compatibleLayers( QgsProject *project, bool sort = true );
79+
80+
private:
81+
82+
static bool canUseLayer( const QgsRasterLayer *layer );
83+
static bool canUseLayer( const QgsVectorLayer *layer,
84+
const QList< QgsWkbTypes::GeometryType > &geometryTypes );
85+
86+
};
87+
88+
#endif // QGSPROCESSINGUTILS_H
89+
90+

‎tests/src/core/testqgsprocessing.cpp

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717

1818
#include "qgsprocessingregistry.h"
1919
#include "qgsprocessingprovider.h"
20+
#include "qgsprocessingutils.h"
2021
#include <QObject>
2122
#include "qgstest.h"
23+
#include "qgsrasterlayer.h"
24+
#include "qgsproject.h"
2225

2326
//dummy provider for testing
2427
class DummyProvider : public QgsProcessingProvider
@@ -40,19 +43,31 @@ class TestQgsProcessing: public QObject
4043
Q_OBJECT
4144

4245
private slots:
43-
void initTestCase() {}// will be called before the first testfunction is executed.
44-
void cleanupTestCase() {}// will be called after the last testfunction was executed.
46+
void initTestCase();// will be called before the first testfunction is executed.
47+
void cleanupTestCase(); // will be called after the last testfunction was executed.
4548
void init() {} // will be called before each testfunction is executed.
4649
void cleanup() {} // will be called after every testfunction.
4750
void instance();
4851
void addProvider();
4952
void providerById();
5053
void removeProvider();
54+
void compatibleLayers();
5155

5256
private:
5357

5458
};
5559

60+
void TestQgsProcessing::initTestCase()
61+
{
62+
QgsApplication::init();
63+
QgsApplication::initQgis();
64+
}
65+
66+
void TestQgsProcessing::cleanupTestCase()
67+
{
68+
QgsApplication::exitQgis();
69+
}
70+
5671
void TestQgsProcessing::instance()
5772
{
5873
// test that application has a registry instance
@@ -144,5 +159,103 @@ void TestQgsProcessing::removeProvider()
144159
QVERIFY( r.providers().isEmpty() );
145160
}
146161

162+
void TestQgsProcessing::compatibleLayers()
163+
{
164+
QgsProject p;
165+
166+
// add a bunch of layers to a project
167+
QString testDataDir = QStringLiteral( TEST_DATA_DIR ) + '/'; //defined in CmakeLists.txt
168+
QString raster1 = testDataDir + "tenbytenraster.asc";
169+
QString raster2 = testDataDir + "landsat.tif";
170+
QString raster3 = testDataDir + "/raster/band1_float32_noct_epsg4326.tif";
171+
QFileInfo fi1( raster1 );
172+
QgsRasterLayer *r1 = new QgsRasterLayer( fi1.filePath(), "R1" );
173+
QVERIFY( r1->isValid() );
174+
QFileInfo fi2( raster2 );
175+
QgsRasterLayer *r2 = new QgsRasterLayer( fi2.filePath(), "ar2" );
176+
QVERIFY( r2->isValid() );
177+
QFileInfo fi3( raster3 );
178+
QgsRasterLayer *r3 = new QgsRasterLayer( fi3.filePath(), "zz" );
179+
QVERIFY( r3->isValid() );
180+
181+
QgsVectorLayer *v1 = new QgsVectorLayer( "Polygon", "V4", "memory" );
182+
QgsVectorLayer *v2 = new QgsVectorLayer( "Point", "v1", "memory" );
183+
QgsVectorLayer *v3 = new QgsVectorLayer( "LineString", "v3", "memory" );
184+
QgsVectorLayer *v4 = new QgsVectorLayer( "none", "vvvv4", "memory" );
185+
186+
p.addMapLayers( QList<QgsMapLayer *>() << r1 << r2 << r3 << v1 << v2 << v3 << v4 );
187+
188+
// compatibleRasterLayers
189+
QVERIFY( QgsProcessingUtils::compatibleRasterLayers( nullptr ).isEmpty() );
190+
191+
// sorted
192+
QStringList lIds;
193+
Q_FOREACH ( QgsRasterLayer *rl, QgsProcessingUtils::compatibleRasterLayers( &p ) )
194+
lIds << rl->name();
195+
QCOMPARE( lIds, QStringList() << "ar2" << "R1" << "zz" );
196+
197+
// unsorted
198+
lIds.clear();
199+
Q_FOREACH ( QgsRasterLayer *rl, QgsProcessingUtils::compatibleRasterLayers( &p, false ) )
200+
lIds << rl->name();
201+
QCOMPARE( lIds, QStringList() << "R1" << "ar2" << "zz" );
202+
203+
204+
// compatibleVectorLayers
205+
QVERIFY( QgsProcessingUtils::compatibleVectorLayers( nullptr ).isEmpty() );
206+
207+
// sorted
208+
lIds.clear();
209+
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p ) )
210+
lIds << vl->name();
211+
QCOMPARE( lIds, QStringList() << "v1" << "v3" << "V4" << "vvvv4" );
212+
213+
// unsorted
214+
lIds.clear();
215+
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>(), false ) )
216+
lIds << vl->name();
217+
QCOMPARE( lIds, QStringList() << "V4" << "v1" << "v3" << "vvvv4" );
218+
219+
// point only
220+
lIds.clear();
221+
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>() << QgsWkbTypes::PointGeometry ) )
222+
lIds << vl->name();
223+
QCOMPARE( lIds, QStringList() << "v1" );
224+
225+
// polygon only
226+
lIds.clear();
227+
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>() << QgsWkbTypes::PolygonGeometry ) )
228+
lIds << vl->name();
229+
QCOMPARE( lIds, QStringList() << "V4" );
230+
231+
// line only
232+
lIds.clear();
233+
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>() << QgsWkbTypes::LineGeometry ) )
234+
lIds << vl->name();
235+
QCOMPARE( lIds, QStringList() << "v3" );
236+
237+
// point and line only
238+
lIds.clear();
239+
Q_FOREACH ( QgsVectorLayer *vl, QgsProcessingUtils::compatibleVectorLayers( &p, QList<QgsWkbTypes::GeometryType>() << QgsWkbTypes::PointGeometry << QgsWkbTypes::LineGeometry ) )
240+
lIds << vl->name();
241+
QCOMPARE( lIds, QStringList() << "v1" << "v3" );
242+
243+
244+
// all layers
245+
QVERIFY( QgsProcessingUtils::compatibleLayers( nullptr ).isEmpty() );
246+
247+
// sorted
248+
lIds.clear();
249+
Q_FOREACH ( QgsMapLayer *l, QgsProcessingUtils::compatibleLayers( &p ) )
250+
lIds << l->name();
251+
QCOMPARE( lIds, QStringList() << "ar2" << "R1" << "v1" << "v3" << "V4" << "vvvv4" << "zz" );
252+
253+
// unsorted
254+
lIds.clear();
255+
Q_FOREACH ( QgsMapLayer *l, QgsProcessingUtils::compatibleLayers( &p, false ) )
256+
lIds << l->name();
257+
QCOMPARE( lIds, QStringList() << "R1" << "ar2" << "zz" << "V4" << "v1" << "v3" << "vvvv4" );
258+
}
259+
147260
QGSTEST_MAIN( TestQgsProcessing )
148261
#include "testqgsprocessing.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.