Use contextGenerator in refactor fields algorithm

This commit is contained in:
arnaud.morvan@camptocamp.com 2016-09-08 18:31:51 +02:00
parent a8d9dea1fb
commit 78236c0be1
2 changed files with 25 additions and 25 deletions

View File

@ -78,10 +78,7 @@ class FieldsMapper(GeoAlgorithm):
da.setEllipsoid(QgsProject.instance().readEntry(
'Measure', '/Ellipsoid', GEO_NONE)[0])
exp_context = QgsExpressionContext()
exp_context.appendScope(QgsExpressionContextUtils.globalScope())
exp_context.appendScope(QgsExpressionContextUtils.projectScope())
exp_context.appendScope(QgsExpressionContextUtils.layerScope(layer))
exp_context = layer.createExpressionContext()
for field_def in mapping:
fields.append(QgsField(name=field_def['name'],
@ -93,18 +90,12 @@ class FieldsMapper(GeoAlgorithm):
expression.setGeomCalculator(da)
expression.setDistanceUnits(QgsProject.instance().distanceUnits())
expression.setAreaUnits(QgsProject.instance().areaUnits())
expression.prepare(exp_context)
if expression.hasParserError():
raise GeoAlgorithmExecutionException(
self.tr(u'Parser error in expression "{}": {}')
.format(str(field_def['expression']),
str(expression.parserErrorString())))
expression.prepare(exp_context)
if expression.hasEvalError():
raise GeoAlgorithmExecutionException(
self.tr(u'Evaluation error in expression "{}": {}')
.format(str(field_def['expression']),
str(expression.evalErrorString())))
.format(unicode(expression.expression()),
unicode(expression.parserErrorString())))
expressions.append(expression)
writer = output.getVectorWriter(fields,
@ -112,8 +103,7 @@ class FieldsMapper(GeoAlgorithm):
layer.crs())
# Create output vector layer with new attributes
error = ''
calculationSuccess = True
error_exp = None
inFeat = QgsFeature()
outFeat = QgsFeature()
features = vector.features(layer)
@ -132,8 +122,7 @@ class FieldsMapper(GeoAlgorithm):
exp_context.lastScope().setVariable("row_number", rownum)
value = expression.evaluate(exp_context)
if expression.hasEvalError():
calculationSuccess = False
error = expression.evalErrorString()
error_exp = expression
break
attrs.append(value)
@ -145,7 +134,8 @@ class FieldsMapper(GeoAlgorithm):
del writer
if not calculationSuccess:
if error_exp is not None:
raise GeoAlgorithmExecutionException(
self.tr('An error occurred while evaluating the calculation'
' string:\n') + error)
self.tr(u'Evaluation error in expression "{}": {}')
.format(unicode(error_exp.expression()),
unicode(error_exp.parserErrorString())))

View File

@ -35,7 +35,7 @@ from qgis.PyQt.QtGui import QBrush, QIcon, QSpacerItem
from qgis.PyQt.QtWidgets import QComboBox, QHeaderView, QLineEdit, QMessageBox, QSpinBox, QStyledItemDelegate
from qgis.PyQt.QtCore import QItemSelectionModel, QAbstractTableModel, QModelIndex, QVariant, Qt, pyqtSlot
from qgis.core import QgsExpression, QgsExpressionContextUtils, QgsApplication, QgsFeature
from qgis.core import QgsExpression, QgsProject, QgsApplication
from qgis.gui import QgsFieldExpressionWidget
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_MODELER
@ -87,21 +87,30 @@ class FieldsMappingModel(QAbstractTableModel):
def testExpression(self, row):
self._errors[row] = None
field = self._mapping[row]
exp_context = self.contextGenerator().createExpressionContext()
expression = QgsExpression(field['expression'])
expression.prepare(exp_context)
if expression.hasParserError():
self._errors[row] = expression.parserErrorString()
return
# test evaluation on the first feature
if self._layer is None:
return
context = QgsExpressionContextUtils.createFeatureBasedContext(QgsFeature(), self._layer.fields())
for feature in self._layer.getFeatures():
context.setFeature(feature)
expression.evaluate(context)
exp_context.setFeature(feature)
exp_context.lastScope().setVariable("row_number", 1)
expression.evaluate(exp_context)
if expression.hasEvalError():
self._errors[row] = expression.evalErrorString()
return
break
def contextGenerator(self):
if self._layer:
return self._layer
return QgsProject.instance()
def layer(self):
return self._layer
@ -254,6 +263,7 @@ class FieldDelegate(QStyledItemDelegate):
elif fieldType == QgsExpression:
editor = QgsFieldExpressionWidget(parent)
editor.setLayer(index.model().layer())
editor.registerExpressionContextGenerator(index.model().contextGenerator())
editor.fieldChanged.connect(self.on_expression_fieldChange)
else: