Skip to content

Commit f1511a2

Browse files
committedJun 6, 2017
Port clip algorithm to new API
1 parent 9038872 commit f1511a2

File tree

3 files changed

+116
-106
lines changed

3 files changed

+116
-106
lines changed
 

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

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,14 @@
3434
QgsFeatureRequest,
3535
QgsWkbTypes,
3636
QgsMessageLog,
37-
QgsProcessingUtils)
37+
QgsProcessingUtils,
38+
QgsProcessingParameterFeatureSource,
39+
QgsProcessingParameterFeatureSink,
40+
QgsProcessingOutputVectorLayer,
41+
QgsProcessingParameterDefinition
42+
)
3843

3944
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
40-
from processing.core.parameters import ParameterVector
41-
from processing.core.outputs import OutputVector
4245
from processing.tools import dataobjects
4346

4447
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
@@ -58,11 +61,12 @@ def group(self):
5861

5962
def __init__(self):
6063
super().__init__()
61-
self.addParameter(ParameterVector(Clip.INPUT,
62-
self.tr('Input layer')))
63-
self.addParameter(ParameterVector(Clip.OVERLAY,
64-
self.tr('Clip layer'), [dataobjects.TYPE_VECTOR_POLYGON]))
65-
self.addOutput(OutputVector(Clip.OUTPUT, self.tr('Clipped')))
64+
65+
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Input layer')))
66+
self.addParameter(QgsProcessingParameterFeatureSource(self.OVERLAY, self.tr('Clip layer'), [QgsProcessingParameterDefinition.TypeVectorPolygon]))
67+
68+
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Clipped')))
69+
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Clipped")))
6670

6771
def name(self):
6872
return 'clip'
@@ -71,17 +75,17 @@ def displayName(self):
7175
return self.tr('Clip')
7276

7377
def processAlgorithm(self, parameters, context, feedback):
74-
source_layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Clip.INPUT), context)
75-
mask_layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Clip.OVERLAY), context)
7678

77-
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(source_layer.fields(),
78-
QgsWkbTypes.multiType(source_layer.wkbType()),
79-
source_layer.crs(), context)
79+
feature_source = self.parameterAsSource(parameters, self.INPUT, context)
80+
mask_source = self.parameterAsSource(parameters, self.OVERLAY, context)
81+
82+
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
83+
feature_source.fields(), QgsWkbTypes.multiType(feature_source.wkbType()), feature_source.sourceCrs())
8084

8185
# first build up a list of clip geometries
8286
clip_geoms = []
83-
for maskFeat in QgsProcessingUtils.getFeatures(mask_layer, context, QgsFeatureRequest().setSubsetOfAttributes([])):
84-
clip_geoms.append(maskFeat.geometry())
87+
for mask_feature in mask_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([])):
88+
clip_geoms.append(mask_feature.geometry())
8589

8690
# are we clipping against a single feature? if so, we can show finer progress reports
8791
if len(clip_geoms) > 1:
@@ -98,8 +102,10 @@ def processAlgorithm(self, parameters, context, feedback):
98102
tested_feature_ids = set()
99103

100104
for i, clip_geom in enumerate(clip_geoms):
101-
input_features = [f for f in QgsProcessingUtils.getFeatures(source_layer, context,
102-
QgsFeatureRequest().setFilterRect(clip_geom.boundingBox()))]
105+
if feedback.isCanceled():
106+
break
107+
108+
input_features = [f for f in feature_source.getFeatures(QgsFeatureRequest().setFilterRect(clip_geom.boundingBox()))]
103109

104110
if not input_features:
105111
continue
@@ -110,6 +116,9 @@ def processAlgorithm(self, parameters, context, feedback):
110116
total = 0
111117

112118
for current, in_feat in enumerate(input_features):
119+
if feedback.isCanceled():
120+
break
121+
113122
if not in_feat.geometry():
114123
continue
115124

@@ -137,7 +146,7 @@ def processAlgorithm(self, parameters, context, feedback):
137146
out_feat = QgsFeature()
138147
out_feat.setGeometry(new_geom)
139148
out_feat.setAttributes(in_feat.attributes())
140-
writer.addFeature(out_feat)
149+
sink.addFeature(out_feat)
141150
except:
142151
QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more '
143152
'output features ignored due to '
@@ -151,4 +160,4 @@ def processAlgorithm(self, parameters, context, feedback):
151160
# coarse progress report for multiple clip geometries
152161
feedback.setProgress(100.0 * i / len(clip_geoms))
153162

154-
del writer
163+
return {self.OUTPUT: dest_id}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
# from .ConvexHull import ConvexHull
7676
# from .FixedDistanceBuffer import FixedDistanceBuffer
7777
# from .VariableDistanceBuffer import VariableDistanceBuffer
78-
# from .Clip import Clip
78+
from .Clip import Clip
7979
# from .Difference import Difference
8080
# from .Dissolve import Dissolve
8181
# from .Intersection import Intersection
@@ -210,7 +210,7 @@ def getAlgs(self):
210210
# PolygonsToLines(), LinesToPolygons(), ExtractNodes(),
211211
# ConvexHull(), FixedDistanceBuffer(),
212212
# VariableDistanceBuffer(), Dissolve(), Difference(),
213-
# Intersection(), Union(), Clip(), ExtentFromLayer(),
213+
# Intersection(), Union(), ExtentFromLayer(),
214214
# RandomSelection(), RandomSelectionWithinSubsets(),
215215
# SelectByLocation(), RandomExtract(), DeleteHoles(),
216216
# RandomExtractWithinSubsets(), ExtractByLocation(),
@@ -263,7 +263,8 @@ def getAlgs(self):
263263
Aspect(),
264264
AutoincrementalField(),
265265
Boundary(),
266-
BoundingBox()]
266+
BoundingBox(),
267+
Clip()]
267268

268269
if hasPlotly:
269270
# from .VectorLayerHistogram import VectorLayerHistogram

‎python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

Lines changed: 84 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -25,90 +25,90 @@ tests:
2525
# name: expected/polys_deleteholes.gml
2626
# type: vector
2727
#
28-
# - algorithm: qgis:clip
29-
# name: Clip lines by polygons
30-
# params:
31-
# INPUT:
32-
# name: custom/lines2.gml
33-
# type: vector
34-
# OVERLAY:
35-
# name: polys.gml
36-
# type: vector
37-
# results:
38-
# OUTPUT:
39-
# name: expected/clip_lines_by_polygon.gml
40-
# type: vector
41-
#
42-
# - algorithm: qgis:clip
43-
# name: Clip lines by multipolygon
44-
# params:
45-
# INPUT:
46-
# name: lines.gml
47-
# type: vector
48-
# OVERLAY:
49-
# name: multipolys.gml
50-
# type: vector
51-
# results:
52-
# OUTPUT:
53-
# name: expected/clip_lines_by_multipolygon.gml
54-
# type: vector
55-
#
56-
# - algorithm: qgis:clip
57-
# name: Clip polygons by multipolygons
58-
# params:
59-
# INPUT:
60-
# name: polys.gml
61-
# type: vector
62-
# OVERLAY:
63-
# name: multipolys.gml
64-
# type: vector
65-
# results:
66-
# OUTPUT:
67-
# name: expected/clip_polys_by_multipolygon.gml
68-
# type: vector
69-
#
70-
# - algorithm: qgis:clip
71-
# name: Clip multipolygons by polygons
72-
# params:
73-
# INPUT:
74-
# name: multipolys.gml
75-
# type: vector
76-
# OVERLAY:
77-
# name: polys.gml
78-
# type: vector
79-
# results:
80-
# OUTPUT:
81-
# name: expected/clip_multipolygons_by_polygons.gml
82-
# type: vector
83-
#
84-
# - algorithm: qgis:clip
85-
# name: Clip points by polygons
86-
# params:
87-
# INPUT:
88-
# name: points.gml
89-
# type: vector
90-
# OVERLAY:
91-
# name: polys.gml
92-
# type: vector
93-
# results:
94-
# OUTPUT:
95-
# name: expected/clip_points_by_polygons.gml
96-
# type: vector
97-
#
98-
# - algorithm: qgis:clip
99-
# name: Clip points by multipolygons
100-
# params:
101-
# INPUT:
102-
# name: points.gml
103-
# type: vector
104-
# OVERLAY:
105-
# name: multipolys.gml
106-
# type: vector
107-
# results:
108-
# OUTPUT:
109-
# name: expected/clip_points_by_multipolygons.gml
110-
# type: vector
111-
#
28+
- algorithm: qgis:clip
29+
name: Clip lines by polygons
30+
params:
31+
INPUT:
32+
name: custom/lines2.gml
33+
type: vector
34+
OVERLAY:
35+
name: polys.gml
36+
type: vector
37+
results:
38+
OUTPUT:
39+
name: expected/clip_lines_by_polygon.gml
40+
type: vector
41+
42+
- algorithm: qgis:clip
43+
name: Clip lines by multipolygon
44+
params:
45+
INPUT:
46+
name: lines.gml
47+
type: vector
48+
OVERLAY:
49+
name: multipolys.gml
50+
type: vector
51+
results:
52+
OUTPUT:
53+
name: expected/clip_lines_by_multipolygon.gml
54+
type: vector
55+
56+
- algorithm: qgis:clip
57+
name: Clip polygons by multipolygons
58+
params:
59+
INPUT:
60+
name: polys.gml
61+
type: vector
62+
OVERLAY:
63+
name: multipolys.gml
64+
type: vector
65+
results:
66+
OUTPUT:
67+
name: expected/clip_polys_by_multipolygon.gml
68+
type: vector
69+
70+
- algorithm: qgis:clip
71+
name: Clip multipolygons by polygons
72+
params:
73+
INPUT:
74+
name: multipolys.gml
75+
type: vector
76+
OVERLAY:
77+
name: polys.gml
78+
type: vector
79+
results:
80+
OUTPUT:
81+
name: expected/clip_multipolygons_by_polygons.gml
82+
type: vector
83+
84+
- algorithm: qgis:clip
85+
name: Clip points by polygons
86+
params:
87+
INPUT:
88+
name: points.gml
89+
type: vector
90+
OVERLAY:
91+
name: polys.gml
92+
type: vector
93+
results:
94+
OUTPUT:
95+
name: expected/clip_points_by_polygons.gml
96+
type: vector
97+
98+
- algorithm: qgis:clip
99+
name: Clip points by multipolygons
100+
params:
101+
INPUT:
102+
name: points.gml
103+
type: vector
104+
OVERLAY:
105+
name: multipolys.gml
106+
type: vector
107+
results:
108+
OUTPUT:
109+
name: expected/clip_points_by_multipolygons.gml
110+
type: vector
111+
112112
# # These datasets should produce a geometry collection and not a polygon only
113113
# # dataset. If the algorithm is fixed, a new test should be introduced to
114114
# # check this behavior.

0 commit comments

Comments
 (0)
Please sign in to comment.