Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[processing] Allow empty expressions in refactor fields alg #6457

Merged
merged 2 commits into from Feb 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 30 additions & 21 deletions python/plugins/processing/algs/qgis/FieldsMapper.py
Expand Up @@ -32,7 +32,8 @@
QgsFields,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterDefinition)
QgsProcessingParameterDefinition,
NULL)

from processing.algs.qgis.QgisAlgorithm import QgisFeatureBasedAlgorithm

Expand Down Expand Up @@ -133,39 +134,47 @@ def prepareAlgorithm(self, parameters, context, feedback):
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():
raise QgsProcessingException(
self.tr(u'Parser error in expression "{}": {}')
.format(expression.expression(),
expression.parserErrorString()))
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):
return self.fields

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]
@@ -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>
@@ -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>
32 changes: 32 additions & 0 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions src/core/processing/qgsprocessingalgrunnertask.cpp
Expand Up @@ -41,10 +41,14 @@ QgsProcessingAlgRunnerTask::QgsProcessingAlgRunnerTask( const QgsProcessingAlgor
void QgsProcessingAlgRunnerTask::cancel()
{
mFeedback->cancel();
QgsTask::cancel();
}

bool QgsProcessingAlgRunnerTask::run()
{
if ( isCanceled() )
return false;

connect( mFeedback, &QgsFeedback::progressChanged, this, &QgsProcessingAlgRunnerTask::setProgress );
bool ok = false;
try
Expand Down