def _expressionValues(self, text): strings = self.dialog.getAvailableValuesOfType( [QgsProcessingParameterString, QgsProcessingParameterNumber], []) model_params = [(self.dialog.resolveValueDescription(s), s) for s in strings] variables = QgsExpression.referencedVariables(text) # replace description by parameter's name (diverging after model save) descriptions = QgsExpression.referencedVariables(text) for k, v in model_params: if k in descriptions: text = text.replace('[% @{} %]'.format(k), '[% @{} %]'.format(v.parameterName())) src = QgsProcessingModelChildParameterSource.fromExpressionText(text) # add parameters currently used by the expression expression_values = [] expression_values.append(src) for k, v in model_params: if k in variables: expression_values.append(v) return expression_values
def setValue(self, value): text = value if self.dialogType == DIALOG_MODELER: if isinstance(value, list): for v in value: if isinstance(v, QgsProcessingModelChildParameterSource) \ and v.source() == QgsProcessingModelChildParameterSource.ExpressionText: text = v.expressionText() # replace parameter's name by expression (diverging after model save) names = QgsExpression.referencedVariables(text) strings = self.dialog.getAvailableValuesOfType([ QgsProcessingParameterString, QgsProcessingParameterNumber ], []) model_params = [ (self.dialog.resolveValueDescription(s), s) for s in strings ] for k, v in model_params: if v.parameterName() in names: text = text.replace( '[% @{} %]'.format(v.parameterName()), '[% @{} %]'.format(k)) self.mText.setPlainText(text)
def getItemsFromParamValue(self, value, child_id, context): items = [] if isinstance(value, list): for v in value: items.extend(self.getItemsFromParamValue(v, child_id, context)) elif isinstance(value, QgsProcessingModelChildParameterSource): if value.source( ) == QgsProcessingModelChildParameterSource.ModelParameter: items.append((self.paramItems[value.parameterName()], 0)) elif value.source( ) == QgsProcessingModelChildParameterSource.ChildOutput: outputs = self.model.childAlgorithm( value.outputChildId()).algorithm().outputDefinitions() for i, out in enumerate(outputs): if out.name() == value.outputName(): break if value.outputChildId() in self.algItems: items.append((self.algItems[value.outputChildId()], i)) elif value.source( ) == QgsProcessingModelChildParameterSource.Expression: variables = self.model.variablesForChildAlgorithm( child_id, context) exp = QgsExpression(value.expression()) for v in exp.referencedVariables(): if v in variables: items.extend( self.getItemsFromParamValue( variables[v].source, child_id, context)) return items
def _expressionValues(self, text): strings = self.dialog.getAvailableValuesOfType( [QgsProcessingParameterString, QgsProcessingParameterNumber], []) model_params = [(self.dialog.resolveValueDescription(s), s) for s in strings] variables = QgsExpression.referencedVariables(text) expression_values = [] expression_values.append(QgsProcessingModelChildParameterSource.fromExpressionText(text)) for k, v in model_params: if k in variables: expression_values.append(v) return expression_values
def getItemsFromParamValue(self, value, child_id, context): items = [] if isinstance(value, list): for v in value: items.extend(self.getItemsFromParamValue(v, child_id, context)) elif isinstance(value, QgsProcessingModelChildParameterSource): if value.source() == QgsProcessingModelChildParameterSource.ModelParameter: items.append((self.paramItems[value.parameterName()], 0)) elif value.source() == QgsProcessingModelChildParameterSource.ChildOutput: outputs = self.model.childAlgorithm(value.outputChildId()).algorithm().outputDefinitions() for i, out in enumerate(outputs): if out.name() == value.outputName(): break if value.outputChildId() in self.algItems: items.append((self.algItems[value.outputChildId()], i)) elif value.source() == QgsProcessingModelChildParameterSource.Expression: variables = self.model.variablesForChildAlgorithm(child_id, context) exp = QgsExpression(value.expression()) for v in exp.referencedVariables(): if v in variables: items.extend(self.getItemsFromParamValue(variables[v].source, child_id, context)) return items
def setValue(self, value): text = value if self.dialogType == DIALOG_MODELER: if isinstance(value, list): for v in value: if isinstance(v, QgsProcessingModelChildParameterSource) \ and v.source() == QgsProcessingModelChildParameterSource.ExpressionText: text = v.expressionText() # replace parameter's name by expression (diverging after model save) names = QgsExpression.referencedVariables(text) strings = self.dialog.getAvailableValuesOfType( [QgsProcessingParameterString, QgsProcessingParameterNumber], []) model_params = [(self.dialog.resolveValueDescription(s), s) for s in strings] for k, v in model_params: if v.parameterName() in names: text = text.replace('[% @{} %]'.format(v.parameterName()), '[% @{} %]'.format(k)) self.mText.setPlainText(text)
def expression_eval(expression_text, project_id=None, qgs_layer_id=None, form_data=None, formatter=0): """Evaluates a QgsExpression and returns the result :param expression_text: The QgsExpression text :type expression_text: str :param project_id: ID of the qdjango project, defaults to None :type project_id: int, optional :param qgs_layer_id: ID of the QGIS Layer, defaults to None :type qgslayer_id: str, optional :param form_data: A dictionary that maps to a GeoJSON representation of the feature currently edited in the form :type form_data: dict, optional :param formatter: Indicate if form_data values contains formatter values or original features value. :type formatter: int, optional """ expression = QgsExpression(expression_text) expression_context = QgsExpressionContext() layer = None for func_name in expression.referencedFunctions(): if func_name in FORBIDDEN_FUNCTIONS: raise ExpressionForbiddenError( _('Function "{}" is not allowed for security reasons!').format( func_name)) for var_name in expression.referencedVariables(): if var_name in FORBIDDEN_VARIABLES: raise ExpressionForbiddenError( _('Variable "{}" is not allowed for security reasons!').format( var_name)) if project_id is not None: try: project = Project.objects.get(pk=project_id) if qgs_layer_id is not None: try: layer = project.layer_set.get(qgs_layer_id=qgs_layer_id) except Layer.DoesNotExist: raise ExpressionLayerError( _('QGIS layer with id "{}" could not be found!'). format(qgs_layer_id)) expression_contex = QgsExpressionContextUtils.globalProjectLayerScopes( layer.qgis_layer) else: expression_contex = QgsExpressionContextUtils.globalScope() expression_context.appendScope( QgsExpressionContextUtils.projectScope( project.qgis_project)) except Project.DoesNotExist: raise ExpressionProjectError( _('QDjango project with id "{}" could not be found!').format( project_id)) else: expression_contex = QgsExpressionContextUtils.globalScope() if form_data is not None: if layer is None: raise ExpressionLayerError( _('A valid QGIS layer is required to process form data!')) try: # Case by formatter # formatter == 1 : get featureid from layer, usually must be used with formatter form_data # formatter == 0 : default behavior if formatter == 0: fields = layer.qgis_layer.fields() form_feature = QgsJsonUtils.stringToFeatureList( json.dumps(form_data), fields, None)[0] # Set attributes manually because QgsJsonUtils does not respect order for k, v in form_data['properties'].items(): form_feature.setAttribute(k, v) else: qgis_feature_request = QgsFeatureRequest() exp = expression_from_server_fids( [form_data['id']], layer.qgis_layer.dataProvider()) qgis_feature_request.combineFilterExpression(exp) form_feature = get_qgis_features(layer.qgis_layer, qgis_feature_request)[0] expression_context.appendScope( QgsExpressionContextUtils.formScope(form_feature)) expression_context.setFeature(form_feature) except: raise ExpressionFormDataError() valid, errors = expression.checkExpression(expression_text, expression_context) if not valid: raise ExpressionParseError(errors) result = expression.evaluate(expression_context) if expression.hasEvalError(): raise ExpressionEvalError(expression.evalErrorString()) return result