mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	[processing] Allow empty expressions in refactor fields alg
Fixes #15640
This commit is contained in:
		
							parent
							
								
									2900acef51
								
							
						
					
					
						commit
						cc10bbd950
					
				@ -32,7 +32,8 @@ from qgis.core import (
 | 
			
		||||
    QgsFields,
 | 
			
		||||
    QgsProcessing,
 | 
			
		||||
    QgsProcessingException,
 | 
			
		||||
    QgsProcessingParameterDefinition)
 | 
			
		||||
    QgsProcessingParameterDefinition,
 | 
			
		||||
    NULL)
 | 
			
		||||
 | 
			
		||||
from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm
 | 
			
		||||
 | 
			
		||||
@ -133,17 +134,20 @@ class FieldsMapper(QgisFeatureBasedAlgorithm):
 | 
			
		||||
                                        typeName="",
 | 
			
		||||
                                        len=field_def.get('length', 0),
 | 
			
		||||
                                        prec=field_def.get('precision', 0)))
 | 
			
		||||
            expression = QgsExpression(field_def['expression'])
 | 
			
		||||
            expression.setGeomCalculator(da)
 | 
			
		||||
            expression.setDistanceUnits(context.project().distanceUnits())
 | 
			
		||||
            expression.setAreaUnits(context.project().areaUnits())
 | 
			
		||||
            if expression.hasParserError():
 | 
			
		||||
                feedback.reportError(
 | 
			
		||||
                    self.tr(u'Parser error in expression "{}": {}')
 | 
			
		||||
                    .format(expression.expression(),
 | 
			
		||||
                            expression.parserErrorString()))
 | 
			
		||||
                return False
 | 
			
		||||
            self.expressions.append(expression)
 | 
			
		||||
            if field_def['expression']:
 | 
			
		||||
                expression = QgsExpression(field_def['expression'])
 | 
			
		||||
                expression.setGeomCalculator(da)
 | 
			
		||||
                expression.setDistanceUnits(context.project().distanceUnits())
 | 
			
		||||
                expression.setAreaUnits(context.project().areaUnits())
 | 
			
		||||
                if expression.hasParserError():
 | 
			
		||||
                    feedback.reportError(
 | 
			
		||||
                        self.tr(u'Parser error in expression "{}": {}')
 | 
			
		||||
                        .format(expression.expression(),
 | 
			
		||||
                                expression.parserErrorString()))
 | 
			
		||||
                    return False
 | 
			
		||||
                self.expressions.append(expression)
 | 
			
		||||
            else:
 | 
			
		||||
                self.expressions.append(None)
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def outputFields(self, inputFields):
 | 
			
		||||
@ -151,22 +155,26 @@ class FieldsMapper(QgisFeatureBasedAlgorithm):
 | 
			
		||||
 | 
			
		||||
    def processAlgorithm(self, parameters, context, feeback):
 | 
			
		||||
        for expression in self.expressions:
 | 
			
		||||
            expression.prepare(self.expr_context)
 | 
			
		||||
            if expression is not None:
 | 
			
		||||
                expression.prepare(self.expr_context)
 | 
			
		||||
        self._row_number = 0
 | 
			
		||||
        return super().processAlgorithm(parameters, context, feeback)
 | 
			
		||||
 | 
			
		||||
    def processFeature(self, feature, context, feedback):
 | 
			
		||||
        attributes = []
 | 
			
		||||
        for expression in self.expressions:
 | 
			
		||||
            self.expr_context.setFeature(feature)
 | 
			
		||||
            self.expr_context.lastScope().setVariable("row_number", self._row_number)
 | 
			
		||||
            value = expression.evaluate(self.expr_context)
 | 
			
		||||
            if expression.hasEvalError():
 | 
			
		||||
                raise QgsProcessingException(
 | 
			
		||||
                    self.tr(u'Evaluation error in expression "{}": {}')
 | 
			
		||||
                        .format(expression.expression(),
 | 
			
		||||
                                expression.parserErrorString()))
 | 
			
		||||
            attributes.append(value)
 | 
			
		||||
            if expression is not None:
 | 
			
		||||
                self.expr_context.setFeature(feature)
 | 
			
		||||
                self.expr_context.lastScope().setVariable("row_number", self._row_number)
 | 
			
		||||
                value = expression.evaluate(self.expr_context)
 | 
			
		||||
                if expression.hasEvalError():
 | 
			
		||||
                    raise QgsProcessingException(
 | 
			
		||||
                        self.tr(u'Evaluation error in expression "{}": {}')
 | 
			
		||||
                            .format(expression.expression(),
 | 
			
		||||
                                    expression.parserErrorString()))
 | 
			
		||||
                attributes.append(value)
 | 
			
		||||
            else:
 | 
			
		||||
                attributes.append(NULL)
 | 
			
		||||
        feature.setAttributes(attributes)
 | 
			
		||||
        self._row_number += 1
 | 
			
		||||
        return [feature]
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										77
									
								
								python/plugins/processing/tests/testdata/expected/refactor_fields_null.gml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								python/plugins/processing/tests/testdata/expected/refactor_fields_null.gml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8" ?>
 | 
			
		||||
<ogr:FeatureCollection
 | 
			
		||||
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
     xsi:schemaLocation="http://ogr.maptools.org/ refactor_fields_null.xsd"
 | 
			
		||||
     xmlns:ogr="http://ogr.maptools.org/"
 | 
			
		||||
     xmlns:gml="http://www.opengis.net/gml">
 | 
			
		||||
  <gml:boundedBy>
 | 
			
		||||
    <gml:Box>
 | 
			
		||||
      <gml:coord><gml:X>0</gml:X><gml:Y>-5</gml:Y></gml:coord>
 | 
			
		||||
      <gml:coord><gml:X>8</gml:X><gml:Y>3</gml:Y></gml:coord>
 | 
			
		||||
    </gml:Box>
 | 
			
		||||
  </gml:boundedBy>
 | 
			
		||||
                                                                                                                                                               
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.0">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,1</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>1</ogr:id>
 | 
			
		||||
      <ogr:id2>2</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.1">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,3</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>2</ogr:id>
 | 
			
		||||
      <ogr:id2>1</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.2">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>3</ogr:id>
 | 
			
		||||
      <ogr:id2>0</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.3">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5,2</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>4</ogr:id>
 | 
			
		||||
      <ogr:id2>2</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.4">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>4,1</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>5</ogr:id>
 | 
			
		||||
      <ogr:id2>1</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.5">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0,-5</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>6</ogr:id>
 | 
			
		||||
      <ogr:id2>0</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.6">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>8,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>7</ogr:id>
 | 
			
		||||
      <ogr:id2>0</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.7">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>7,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>8</ogr:id>
 | 
			
		||||
      <ogr:id2>0</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
  <gml:featureMember>
 | 
			
		||||
    <ogr:refactor_fields_null fid="points.8">
 | 
			
		||||
      <ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
 | 
			
		||||
      <ogr:id>9</ogr:id>
 | 
			
		||||
      <ogr:id2>0</ogr:id2>
 | 
			
		||||
    </ogr:refactor_fields_null>
 | 
			
		||||
  </gml:featureMember>
 | 
			
		||||
</ogr:FeatureCollection>
 | 
			
		||||
							
								
								
									
										44
									
								
								python/plugins/processing/tests/testdata/expected/refactor_fields_null.xsd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								python/plugins/processing/tests/testdata/expected/refactor_fields_null.xsd
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<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">
 | 
			
		||||
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
 | 
			
		||||
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
 | 
			
		||||
<xs:complexType name="FeatureCollectionType">
 | 
			
		||||
  <xs:complexContent>
 | 
			
		||||
    <xs:extension base="gml:AbstractFeatureCollectionType">
 | 
			
		||||
      <xs:attribute name="lockId" type="xs:string" use="optional"/>
 | 
			
		||||
      <xs:attribute name="scope" type="xs:string" use="optional"/>
 | 
			
		||||
    </xs:extension>
 | 
			
		||||
  </xs:complexContent>
 | 
			
		||||
</xs:complexType>
 | 
			
		||||
<xs:element name="refactor_fields_null" type="ogr:refactor_fields_null_Type" substitutionGroup="gml:_Feature"/>
 | 
			
		||||
<xs:complexType name="refactor_fields_null_Type">
 | 
			
		||||
  <xs:complexContent>
 | 
			
		||||
    <xs:extension base="gml:AbstractFeatureType">
 | 
			
		||||
      <xs:sequence>
 | 
			
		||||
        <xs:element name="geometryProperty" type="gml:PointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
 | 
			
		||||
        <xs:element name="id" nillable="true" minOccurs="0" maxOccurs="1">
 | 
			
		||||
          <xs:simpleType>
 | 
			
		||||
            <xs:restriction base="xs:integer">
 | 
			
		||||
              <xs:totalDigits value="10"/>
 | 
			
		||||
            </xs:restriction>
 | 
			
		||||
          </xs:simpleType>
 | 
			
		||||
        </xs:element>
 | 
			
		||||
        <xs:element name="id2" nillable="true" minOccurs="0" maxOccurs="1">
 | 
			
		||||
          <xs:simpleType>
 | 
			
		||||
            <xs:restriction base="xs:integer">
 | 
			
		||||
              <xs:totalDigits value="10"/>
 | 
			
		||||
            </xs:restriction>
 | 
			
		||||
          </xs:simpleType>
 | 
			
		||||
        </xs:element>
 | 
			
		||||
        <xs:element name="no_exp" nillable="true" minOccurs="0" maxOccurs="1">
 | 
			
		||||
          <xs:simpleType>
 | 
			
		||||
            <xs:restriction base="xs:string">
 | 
			
		||||
              <xs:maxLength value="255"/>
 | 
			
		||||
            </xs:restriction>
 | 
			
		||||
          </xs:simpleType>
 | 
			
		||||
        </xs:element>
 | 
			
		||||
      </xs:sequence>
 | 
			
		||||
    </xs:extension>
 | 
			
		||||
  </xs:complexContent>
 | 
			
		||||
</xs:complexType>
 | 
			
		||||
</xs:schema>
 | 
			
		||||
@ -2482,6 +2482,38 @@ tests:
 | 
			
		||||
        name: expected/refactorfields.gml
 | 
			
		||||
        type: vector
 | 
			
		||||
 | 
			
		||||
  - algorithm: qgis:refactorfields
 | 
			
		||||
    name: Refactor fields, empty expression
 | 
			
		||||
    params:
 | 
			
		||||
      FIELDS_MAPPING:
 | 
			
		||||
      - expression: '"fid"'
 | 
			
		||||
        length: 0
 | 
			
		||||
        name: fid
 | 
			
		||||
        precision: 0
 | 
			
		||||
        type: 10
 | 
			
		||||
      - expression: '"id"'
 | 
			
		||||
        length: 0
 | 
			
		||||
        name: id
 | 
			
		||||
        precision: 0
 | 
			
		||||
        type: 2
 | 
			
		||||
      - expression: '"id2"'
 | 
			
		||||
        length: 0
 | 
			
		||||
        name: id2
 | 
			
		||||
        precision: 0
 | 
			
		||||
        type: 2
 | 
			
		||||
      - expression: ''
 | 
			
		||||
        length: 0
 | 
			
		||||
        name: no_exp
 | 
			
		||||
        precision: 0
 | 
			
		||||
        type: 10
 | 
			
		||||
      INPUT:
 | 
			
		||||
        name: points.gml
 | 
			
		||||
        type: vector
 | 
			
		||||
    results:
 | 
			
		||||
      OUTPUT:
 | 
			
		||||
        name: expected/refactor_fields_null.gml
 | 
			
		||||
        type: vector
 | 
			
		||||
 | 
			
		||||
  - algorithm: native:reprojectlayer
 | 
			
		||||
    name: reproject vector layer
 | 
			
		||||
    params:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user