Skip to content

Commit cc10bbd

Browse files
committedFeb 25, 2018
[processing] Allow empty expressions in refactor fields alg
Fixes #15640
1 parent 2900ace commit cc10bbd

File tree

4 files changed

+183
-22
lines changed

4 files changed

+183
-22
lines changed
 

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

+30-22
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
QgsFields,
3333
QgsProcessing,
3434
QgsProcessingException,
35-
QgsProcessingParameterDefinition)
35+
QgsProcessingParameterDefinition,
36+
NULL)
3637

3738
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
3839

@@ -133,40 +134,47 @@ def prepareAlgorithm(self, parameters, context, feedback):
133134
typeName="",
134135
len=field_def.get('length', 0),
135136
prec=field_def.get('precision', 0)))
136-
expression = QgsExpression(field_def['expression'])
137-
expression.setGeomCalculator(da)
138-
expression.setDistanceUnits(context.project().distanceUnits())
139-
expression.setAreaUnits(context.project().areaUnits())
140-
if expression.hasParserError():
141-
feedback.reportError(
142-
self.tr(u'Parser error in expression "{}": {}')
143-
.format(expression.expression(),
144-
expression.parserErrorString()))
145-
return False
146-
self.expressions.append(expression)
137+
if field_def['expression']:
138+
expression = QgsExpression(field_def['expression'])
139+
expression.setGeomCalculator(da)
140+
expression.setDistanceUnits(context.project().distanceUnits())
141+
expression.setAreaUnits(context.project().areaUnits())
142+
if expression.hasParserError():
143+
feedback.reportError(
144+
self.tr(u'Parser error in expression "{}": {}')
145+
.format(expression.expression(),
146+
expression.parserErrorString()))
147+
return False
148+
self.expressions.append(expression)
149+
else:
150+
self.expressions.append(None)
147151
return True
148152

149153
def outputFields(self, inputFields):
150154
return self.fields
151155

152156
def processAlgorithm(self, parameters, context, feeback):
153157
for expression in self.expressions:
154-
expression.prepare(self.expr_context)
158+
if expression is not None:
159+
expression.prepare(self.expr_context)
155160
self._row_number = 0
156161
return super().processAlgorithm(parameters, context, feeback)
157162

158163
def processFeature(self, feature, context, feedback):
159164
attributes = []
160165
for expression in self.expressions:
161-
self.expr_context.setFeature(feature)
162-
self.expr_context.lastScope().setVariable("row_number", self._row_number)
163-
value = expression.evaluate(self.expr_context)
164-
if expression.hasEvalError():
165-
raise QgsProcessingException(
166-
self.tr(u'Evaluation error in expression "{}": {}')
167-
.format(expression.expression(),
168-
expression.parserErrorString()))
169-
attributes.append(value)
166+
if expression is not None:
167+
self.expr_context.setFeature(feature)
168+
self.expr_context.lastScope().setVariable("row_number", self._row_number)
169+
value = expression.evaluate(self.expr_context)
170+
if expression.hasEvalError():
171+
raise QgsProcessingException(
172+
self.tr(u'Evaluation error in expression "{}": {}')
173+
.format(expression.expression(),
174+
expression.parserErrorString()))
175+
attributes.append(value)
176+
else:
177+
attributes.append(NULL)
170178
feature.setAttributes(attributes)
171179
self._row_number += 1
172180
return [feature]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://ogr.maptools.org/ refactor_fields_null.xsd"
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>0</gml:X><gml:Y>-5</gml:Y></gml:coord>
10+
<gml:coord><gml:X>8</gml:X><gml:Y>3</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:refactor_fields_null fid="points.0">
16+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,1</gml:coordinates></gml:Point></ogr:geometryProperty>
17+
<ogr:id>1</ogr:id>
18+
<ogr:id2>2</ogr:id2>
19+
</ogr:refactor_fields_null>
20+
</gml:featureMember>
21+
<gml:featureMember>
22+
<ogr:refactor_fields_null fid="points.1">
23+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,3</gml:coordinates></gml:Point></ogr:geometryProperty>
24+
<ogr:id>2</ogr:id>
25+
<ogr:id2>1</ogr:id2>
26+
</ogr:refactor_fields_null>
27+
</gml:featureMember>
28+
<gml:featureMember>
29+
<ogr:refactor_fields_null fid="points.2">
30+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
31+
<ogr:id>3</ogr:id>
32+
<ogr:id2>0</ogr:id2>
33+
</ogr:refactor_fields_null>
34+
</gml:featureMember>
35+
<gml:featureMember>
36+
<ogr:refactor_fields_null fid="points.3">
37+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5,2</gml:coordinates></gml:Point></ogr:geometryProperty>
38+
<ogr:id>4</ogr:id>
39+
<ogr:id2>2</ogr:id2>
40+
</ogr:refactor_fields_null>
41+
</gml:featureMember>
42+
<gml:featureMember>
43+
<ogr:refactor_fields_null fid="points.4">
44+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>4,1</gml:coordinates></gml:Point></ogr:geometryProperty>
45+
<ogr:id>5</ogr:id>
46+
<ogr:id2>1</ogr:id2>
47+
</ogr:refactor_fields_null>
48+
</gml:featureMember>
49+
<gml:featureMember>
50+
<ogr:refactor_fields_null fid="points.5">
51+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0,-5</gml:coordinates></gml:Point></ogr:geometryProperty>
52+
<ogr:id>6</ogr:id>
53+
<ogr:id2>0</ogr:id2>
54+
</ogr:refactor_fields_null>
55+
</gml:featureMember>
56+
<gml:featureMember>
57+
<ogr:refactor_fields_null fid="points.6">
58+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>8,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
59+
<ogr:id>7</ogr:id>
60+
<ogr:id2>0</ogr:id2>
61+
</ogr:refactor_fields_null>
62+
</gml:featureMember>
63+
<gml:featureMember>
64+
<ogr:refactor_fields_null fid="points.7">
65+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>7,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
66+
<ogr:id>8</ogr:id>
67+
<ogr:id2>0</ogr:id2>
68+
</ogr:refactor_fields_null>
69+
</gml:featureMember>
70+
<gml:featureMember>
71+
<ogr:refactor_fields_null fid="points.8">
72+
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
73+
<ogr:id>9</ogr:id>
74+
<ogr:id2>0</ogr:id2>
75+
</ogr:refactor_fields_null>
76+
</gml:featureMember>
77+
</ogr:FeatureCollection>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
3+
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
4+
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
5+
<xs:complexType name="FeatureCollectionType">
6+
<xs:complexContent>
7+
<xs:extension base="gml:AbstractFeatureCollectionType">
8+
<xs:attribute name="lockId" type="xs:string" use="optional"/>
9+
<xs:attribute name="scope" type="xs:string" use="optional"/>
10+
</xs:extension>
11+
</xs:complexContent>
12+
</xs:complexType>
13+
<xs:element name="refactor_fields_null" type="ogr:refactor_fields_null_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="refactor_fields_null_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:PointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="id" nillable="true" minOccurs="0" maxOccurs="1">
20+
<xs:simpleType>
21+
<xs:restriction base="xs:integer">
22+
<xs:totalDigits value="10"/>
23+
</xs:restriction>
24+
</xs:simpleType>
25+
</xs:element>
26+
<xs:element name="id2" nillable="true" minOccurs="0" maxOccurs="1">
27+
<xs:simpleType>
28+
<xs:restriction base="xs:integer">
29+
<xs:totalDigits value="10"/>
30+
</xs:restriction>
31+
</xs:simpleType>
32+
</xs:element>
33+
<xs:element name="no_exp" nillable="true" minOccurs="0" maxOccurs="1">
34+
<xs:simpleType>
35+
<xs:restriction base="xs:string">
36+
<xs:maxLength value="255"/>
37+
</xs:restriction>
38+
</xs:simpleType>
39+
</xs:element>
40+
</xs:sequence>
41+
</xs:extension>
42+
</xs:complexContent>
43+
</xs:complexType>
44+
</xs:schema>

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

+32
Original file line numberDiff line numberDiff line change
@@ -2482,6 +2482,38 @@ tests:
24822482
name: expected/refactorfields.gml
24832483
type: vector
24842484

2485+
- algorithm: qgis:refactorfields
2486+
name: Refactor fields, empty expression
2487+
params:
2488+
FIELDS_MAPPING:
2489+
- expression: '"fid"'
2490+
length: 0
2491+
name: fid
2492+
precision: 0
2493+
type: 10
2494+
- expression: '"id"'
2495+
length: 0
2496+
name: id
2497+
precision: 0
2498+
type: 2
2499+
- expression: '"id2"'
2500+
length: 0
2501+
name: id2
2502+
precision: 0
2503+
type: 2
2504+
- expression: ''
2505+
length: 0
2506+
name: no_exp
2507+
precision: 0
2508+
type: 10
2509+
INPUT:
2510+
name: points.gml
2511+
type: vector
2512+
results:
2513+
OUTPUT:
2514+
name: expected/refactor_fields_null.gml
2515+
type: vector
2516+
24852517
- algorithm: native:reprojectlayer
24862518
name: reproject vector layer
24872519
params:

0 commit comments

Comments
 (0)
Please sign in to comment.