Registrieren Sie eine benutzerdefinierte qgs-Funktion in pyqgis

9

Ich verwende Pyqgis in einer eigenständigen Anwendung. Jetzt wollte ich einen benutzerdefinierten Ausdruck erstellen, der in der Regel als filterExpression verwendet werden soll ruleBasedRendererV2. (Ich habe den Renderer mit vorhandenen Funktionen ausprobiert und alles hat gut funktioniert!)

Benutzerdefiniert qgisfunction(bitweise UND-Funktion - da es noch keine solche Funktion gibt) sieht folgendermaßen aus:

from qgis.utils import qgsfunction

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

Ich habe auch versucht, es zu registrieren, über:

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

Testen des Ausdrucks über:

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

( 2=2Immer so geben True) funktioniert nach der Registrierung der Funktion und schlägt fehl, wenn nicht. Trotzdem kann ich den Ausdruck nicht innerhalb einer Regel verwenden ...

Im Moment befindet sich die Datei mit der Funktion oben in meinem Projektordner, der automatisch in PATH aufgenommen wird, nicht wahr?! (Laut Nathan Woodrow kann die Datei an einer beliebigen Stelle in PATH abgelegt werden - siehe https://nathanw.net/2012/11/10/user-defined-expression-functions-for-qgis/ ).

UPDATE: Die Registrierung der Funktion funktioniert bisher mit Code von oben - jetzt liegt das Problem in der Funktion selbst ...

UPDATE 2:

Sehr eigenartig! Die einfache Funktion zum do_nothingAbrufen von zwei Argumenten funktioniert in meinem Code einwandfrei:

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

Ausdruck verwenden expString = 'do_nothing(2, 2) = 2'

UPDATE 3:

Ein einfacher Wechsel von do_nothingzu add_onefunktioniert nicht mehr:

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

Aufruf über expString = 'add_one(2, 2) = 3'. Deshalb denke ich, dass es etwas mit der Rückgabe von Typ zu tun hat?!

Henhuy
quelle
1
Kopieren Sie Ihre Datei in ~/.qgis2/python/expressions/und laden Sie QGIS neu. Die Funktion ist im Abschnitt Python des Ausdrucksgenerators verfügbar
ThomasG77
Nach Ihrem Rat wird die Funktion im QGIS-Funktionseditor angezeigt und ich kann sie wie erwartet verwenden. Aber wenn ich versuche, es in meiner eigenständigen Anwendung zu verwenden, funktioniert die Funktion nicht! - Ich denke, wenn QGIS gestartet wird, werden irgendwie alle Dateien im Ausdrucksordner registriert, aber ich frage mich, wie?!
Henhuy
Verwenden Sie die @qgsfunctionFunktion in Ihrem Code, wie Sie die Funktion im Code definieren ? Sie können den expressionsOrdner ignorieren, wenn Sie Ihr eigenes Skript
Nathan W
Sie haben Recht - wenn die Registrierung der Funktion wie oben beschrieben funktioniert (zum Beispiel do_nothing). Aber meine ursprüngliche Funktion bitwise_andfunktioniert immer noch nicht. Nun, ich denke, es hat etwas mit dem Rückgabetyp der Funktion zu tun, da do_nothing works, aber add_onenicht!
Henhuy

Antworten:

7

Ich habe das Problem endlich gelöst!

Es war wirklich ein Typproblem, da Eingabewerte wie QVariantinnen definiert sind @qgsfunction. Um meinen Code zum Laufen zu bringen, musste ich sie zuerst in ganze Zahlen konvertieren. Anscheinend kümmert sich QGIS selbst um die Typkonvertierung ...

Die Funktion sieht jetzt so aus:

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

Und wenn Sie die Funktion in Ihrem Projektordner abgelegt haben, vergessen Sie nicht, sie zuerst zu registrieren:

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