27
27
28
28
from qgis .core import (QgsWkbTypes ,
29
29
QgsExpression ,
30
- QgsFeatureSink ,
31
- QgsExpressionContext ,
32
- QgsExpressionContextUtils ,
33
30
QgsGeometry ,
34
- QgsApplication ,
35
- QgsProcessingUtils )
31
+ QgsProcessingException ,
32
+ QgsProcessingParameterBoolean ,
33
+ QgsProcessingParameterEnum ,
34
+ QgsProcessingParameterExpression )
36
35
37
- from processing .algs .qgis .QgisAlgorithm import QgisAlgorithm
38
- from processing .core .GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
39
- from processing .core .parameters import ParameterVector , ParameterSelection , ParameterBoolean , ParameterExpression
40
- from processing .core .outputs import OutputVector
36
+ from processing .algs .qgis .QgisAlgorithm import QgisFeatureBasedAlgorithm
41
37
42
38
43
- class GeometryByExpression (QgisAlgorithm ):
39
+ class GeometryByExpression (QgisFeatureBasedAlgorithm ):
44
40
45
- INPUT_LAYER = 'INPUT_LAYER'
46
- OUTPUT_LAYER = 'OUTPUT_LAYER'
47
41
OUTPUT_GEOMETRY = 'OUTPUT_GEOMETRY'
48
42
WITH_Z = 'WITH_Z'
49
43
WITH_M = 'WITH_M'
@@ -54,83 +48,75 @@ def group(self):
54
48
55
49
def __init__ (self ):
56
50
super ().__init__ ()
57
-
58
- def initAlgorithm (self , config = None ):
59
- self .addParameter (ParameterVector (self .INPUT_LAYER ,
60
- self .tr ('Input layer' )))
61
-
62
51
self .geometry_types = [self .tr ('Polygon' ),
63
52
'Line' ,
64
53
'Point' ]
65
- self .addParameter (ParameterSelection (
54
+
55
+ def initParameters (self , config = None ):
56
+ self .addParameter (QgsProcessingParameterEnum (
66
57
self .OUTPUT_GEOMETRY ,
67
58
self .tr ('Output geometry type' ),
68
- self .geometry_types , default = 0 ))
69
- self .addParameter (ParameterBoolean (self .WITH_Z ,
70
- self .tr ('Output geometry has z dimension' ), False ))
71
- self .addParameter (ParameterBoolean (self .WITH_M ,
72
- self .tr ('Output geometry has m values' ), False ))
59
+ options = self .geometry_types , defaultValue = 0 ))
60
+ self .addParameter (QgsProcessingParameterBoolean (self .WITH_Z ,
61
+ self .tr ('Output geometry has z dimension' ), defaultValue = False ))
62
+ self .addParameter (QgsProcessingParameterBoolean (self .WITH_M ,
63
+ self .tr ('Output geometry has m values' ), defaultValue = False ))
73
64
74
- self .addParameter (ParameterExpression (self .EXPRESSION ,
75
- self .tr ("Geometry expression" ), '$geometry' , parent_layer = self .INPUT_LAYER ))
76
-
77
- self .addOutput (OutputVector (self .OUTPUT_LAYER , self .tr ('Modified geometry' )))
65
+ self .addParameter (QgsProcessingParameterExpression (self .EXPRESSION ,
66
+ self .tr ("Geometry expression" ), defaultValue = '$geometry' , parentLayerParameterName = 'INPUT' ))
78
67
79
68
def name (self ):
80
69
return 'geometrybyexpression'
81
70
82
71
def displayName (self ):
83
72
return self .tr ('Geometry by expression' )
84
73
85
- def processAlgorithm (self , parameters , context , feedback ):
86
- layer = QgsProcessingUtils . mapLayerFromString ( self .getParameterValue ( self . INPUT_LAYER ), context )
74
+ def outputName (self ):
75
+ return self .tr ( 'Modified geometry' )
87
76
88
- geometry_type = self .getParameterValue (self .OUTPUT_GEOMETRY )
89
- wkb_type = None
90
- if geometry_type == 0 :
91
- wkb_type = QgsWkbTypes .Polygon
92
- elif geometry_type == 1 :
93
- wkb_type = QgsWkbTypes .LineString
77
+ def prepareAlgorithm (self , parameters , context , feedback ):
78
+ self .geometry_type = self .parameterAsEnum (parameters , self .OUTPUT_GEOMETRY , context )
79
+ self .wkb_type = None
80
+ if self .geometry_type == 0 :
81
+ self .wkb_type = QgsWkbTypes .Polygon
82
+ elif self .geometry_type == 1 :
83
+ self .wkb_type = QgsWkbTypes .LineString
84
+ else :
85
+ self .wkb_type = QgsWkbTypes .Point
86
+ if self .parameterAsBool (parameters , self .WITH_Z , context ):
87
+ self .wkb_type = QgsWkbTypes .addZ (self .wkb_type )
88
+ if self .parameterAsBool (parameters , self .WITH_M , context ):
89
+ self .wkb_type = QgsWkbTypes .addM (self .wkb_type )
90
+
91
+ self .expression = QgsExpression (self .parameterAsString (parameters , self .EXPRESSION , context ))
92
+ if self .expression .hasParserError ():
93
+ feedback .reportError (self .expression .parserErrorString ())
94
+ return False
95
+
96
+ self .expression_context = self .createExpressionContext (parameters , context )
97
+
98
+ if not self .expression .prepare (self .expression_context ):
99
+ feedback .reportErro (
100
+ self .tr ('Evaluation error: {0}' ).format (self .expression .evalErrorString ()))
101
+ return False
102
+
103
+ return True
104
+
105
+ def outputWkbType (self , input_wkb_type ):
106
+ return self .wkb_type
107
+
108
+ def processFeature (self , feature , feedback ):
109
+ self .expression_context .setFeature (feature )
110
+ value = self .expression .evaluate (self .expression_context )
111
+ if self .expression .hasEvalError ():
112
+ raise QgsProcessingException (
113
+ self .tr ('Evaluation error: {0}' ).format (self .expression .evalErrorString ()))
114
+
115
+ if not value :
116
+ feature .setGeometry (QgsGeometry ())
94
117
else :
95
- wkb_type = QgsWkbTypes .Point
96
- if self .getParameterValue (self .WITH_Z ):
97
- wkb_type = QgsWkbTypes .addZ (wkb_type )
98
- if self .getParameterValue (self .WITH_M ):
99
- wkb_type = QgsWkbTypes .addM (wkb_type )
100
-
101
- writer = self .getOutputFromName (
102
- self .OUTPUT_LAYER ).getVectorWriter (layer .fields (), wkb_type , layer .crs (), context )
103
-
104
- expression = QgsExpression (self .getParameterValue (self .EXPRESSION ))
105
- if expression .hasParserError ():
106
- raise GeoAlgorithmExecutionException (expression .parserErrorString ())
107
-
108
- exp_context = QgsExpressionContext (QgsExpressionContextUtils .globalProjectLayerScopes (layer ))
109
-
110
- if not expression .prepare (exp_context ):
111
- raise GeoAlgorithmExecutionException (
112
- self .tr ('Evaluation error: {0}' ).format (expression .evalErrorString ()))
113
-
114
- features = QgsProcessingUtils .getFeatures (layer , context )
115
- total = 100.0 / layer .featureCount () if layer .featureCount () else 0
116
- for current , input_feature in enumerate (features ):
117
- output_feature = input_feature
118
-
119
- exp_context .setFeature (input_feature )
120
- value = expression .evaluate (exp_context )
121
- if expression .hasEvalError ():
122
- raise GeoAlgorithmExecutionException (
123
- self .tr ('Evaluation error: {0}' ).format (expression .evalErrorString ()))
124
-
125
- if not value :
126
- output_feature .setGeometry (QgsGeometry ())
127
- else :
128
- if not isinstance (value , QgsGeometry ):
129
- raise GeoAlgorithmExecutionException (
130
- self .tr ('{} is not a geometry' ).format (value ))
131
- output_feature .setGeometry (value )
132
-
133
- writer .addFeature (output_feature , QgsFeatureSink .FastInsert )
134
- feedback .setProgress (int (current * total ))
135
-
136
- del writer
118
+ if not isinstance (value , QgsGeometry ):
119
+ raise QgsProcessingException (
120
+ self .tr ('{} is not a geometry' ).format (value ))
121
+ feature .setGeometry (value )
122
+ return feature
0 commit comments