Example #1
0
    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
Example #2
0
    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
Example #3
0
    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)
Example #4
0
 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
Example #5
0
    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
Example #6
0
    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
Example #7
0
 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
Example #8
0
    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)
Example #9
0
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