Enregistrer la fonction qgs personnalisée dans pyqgis

9

J'utilise pyqgis dans une application autonome. Maintenant, je voulais créer une expression personnalisée à utiliser comme expression de filtre dans la règle de ruleBasedRendererV2. (J'ai déjà essayé le moteur de rendu avec les fonctions existantes et tout fonctionnait bien!)

Personnalisé qgisfunction(fonction AND au niveau du bit - car il n'existe pas encore de telle fonction) ressemble à ceci:

from qgis.utils import qgsfunction

@qgsfunction(args="auto", group='Python')
def bitwise_and(value1, value2, feature, parent):
    return value1 & value2

J'ai également essayé de l'enregistrer, via:

from qgis.core import QgsExpression
QgsExpression.registerFunction(bitwise_and) 

Test de l'expression via:

expressionString = 'bitwise_and(2, 2) = 2'
exp = QgsExpression(expressionString)
if exp.hasParserError():
    print(exp.parserErrorString())

(Donner 2=2si toujours True) fonctionne après l'enregistrement de la fonction et échoue sinon. Mais quand même, je ne peux pas utiliser l'expression dans une règle ...

En ce moment, le fichier contenant la fonction se trouve en haut dans mon dossier de projet, qui est automatiquement inclus dans PATH, n'est-ce pas?! (Selon Nathan Woodrow, le fichier peut être placé n'importe où dans PATH - voir https://nathanw.net/2012/11/10/user-defined-expression-functions-for-qgis/ ).

MISE À JOUR: L' enregistrement de la fonction fonctionne jusqu'à présent, avec le code ci-dessus - maintenant le problème réside dans la fonction elle-même ...

MISE À JOUR # 2:

Très étrange! Une fonction simple do_nothingobtenant deux arguments fonctionne très bien dans mon code:

@qgsfunction(args="auto", group='Python')
def do_nothing(value1, value2, feature, parent):
    return value1

Utiliser l'expression expString = 'do_nothing(2, 2) = 2'

MISE À JOUR # 3:

Le simple changement de do_nothingen add_onene fonctionne plus:

@qgsfunction(args="auto", group='Python')
def add_one(value1, value2, feature, parent):
    return value1 + 1

appeler via expString = 'add_one(2, 2) = 3'. C'est pourquoi je pense que cela a quelque chose à voir avec le retour du type?!

Henhuy
la source
1
Copiez votre fichier ~/.qgis2/python/expressions/puis rechargez QGIS et la fonction est disponible dans la section générateur d'expression python
ThomasG77
Suivant vos conseils, la fonction apparaît dans l'éditeur de fonctions QGIS et je peux l'utiliser comme prévu. Mais lorsque j'essaie de l'utiliser dans mon application autonome, la fonction ne fonctionne pas! - Je pense que lorsque QGIS démarre, il enregistre en quelque sorte tous les fichiers dans le dossier d'expression, mais je me demande comment?!
Henhuy
Utilisez-vous la @qgsfunctionfonction dans votre code, comme dans vous définissez la fonction dans le code. Vous pouvez ignorer le expressionsdossier si vous créez votre propre script uniquement pour l'application principale
Nathan W
Vous avez raison - lorsque l'enregistrement de la fonction fonctionne comme décrit ci-dessus (par exemple do_nothing). Mais ma fonction d'origine bitwise_andne fonctionne toujours pas. Maintenant, je pense qu'il a quelque chose à voir avec le type de retour de la fonction, puisque do_nothing works, mais add_onene fait pas!
Henhuy

Réponses:

8

J'ai finalement résolu le problème!

C'était vraiment un problème de type, car les valeurs d'entrée sont définies comme à l' QVariantintérieur @qgsfunction. Donc, pour que mon code fonctionne, je devais d'abord les convertir en entiers. Apparemment, QGIS s'occupe lui-même des conversions de types ...

La fonction ressemble à ceci maintenant:

@qgsfunction(args="auto", group='Python')
def bitwise_and(value1, value2, feature, parent):
    return value1.toInt()[0] & value2.toInt()[0]

Et si vous avez placé la fonction dans votre dossier de projet, n'oubliez pas de l'enregistrer d'abord:

from qgis.core import QgsExpression
QgsExpression.registerFunction(bitwise_and) 
Henhuy
la source