Zarejestruj niestandardową funkcję qgs w pyqgis

9

Używam pyqgis w samodzielnej aplikacji. Teraz chciałem utworzyć niestandardowe wyrażenie do użycia jako filterExpression z reguły ruleBasedRendererV2. (Próbowałem wcześniej renderera z istniejącymi funkcjami i wszystko działało dobrze!)

Niestandardowa qgisfunction(bitowa funkcja AND - ponieważ takiej funkcji jeszcze nie ma) wygląda następująco:

from qgis.utils import qgsfunction

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

Próbowałem go również zarejestrować za pośrednictwem:

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

Testowanie wyrażenia za pomocą:

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

(Podawanie 2=2tak zawsze True) działa po zarejestrowaniu funkcji i kończy się niepowodzeniem, jeśli nie. Ale nadal nie mogę użyć wyrażenia w ramach reguły ...

W tej chwili plik zawierający funkcję znajduje się na wierzchu w folderze mojego projektu, który jest automatycznie dołączany do PATH, prawda ?! (Według Nathana Woodrowa plik można umieścić w dowolnym miejscu w ŚCIEŻCE - patrz https://nathanw.net/2012/11/10/user-defined-expression-functions-for-qgis/ ).

AKTUALIZACJA: Rejestracja funkcji działa do tej pory, z kodem z góry - teraz problem leży w samej funkcji ...

AKTUALIZACJA # 2:

Bardzo dziwny! Prosta funkcja do_nothingotrzymująca dwa argumenty działa dobrze w moim kodzie:

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

Za pomocą wyrażenia expString = 'do_nothing(2, 2) = 2'

AKTUALIZACJA # 3:

Prosta zmiana do_nothingna add_onenie działa już:

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

nazywając to przez expString = 'add_one(2, 2) = 3'. Dlatego myślę, że ma to coś wspólnego z typem zwracanym ?!

Henhuy
źródło
1
Skopiuj plik, ~/.qgis2/python/expressions/a następnie ponownie załaduj QGIS, a funkcja jest dostępna w python w sekcji konstruktora wyrażeń
ThomasG77,
Zgodnie z twoją radą funkcja pojawia się w edytorze funkcji QGIS i mogę jej używać zgodnie z oczekiwaniami. Ale gdy próbuję użyć go w mojej samodzielnej aplikacji, funkcja nie działa! - Myślę, że kiedy QGIS się uruchamia, jakoś rejestruje wszystkie pliki w folderze wyrażeń, ale zastanawiam się jak ?!
Henhuy,
Czy używasz @qgsfunctionfunkcji w kodzie, tak jak definiujesz funkcję w kodzie? Możesz zignorować expressionsfolder, jeśli tworzysz własny skrypt przeznaczony tylko dla głównej aplikacji
Nathan W
Masz rację - podczas rejestracji funkcji działa jak opisano powyżej (na przykład do_nothing). Ale moja pierwotna funkcja bitwise_andwciąż nie działa. Teraz myślę, że ma to coś wspólnego z typem zwracanym funkcji, ponieważ do_nothing works, ale add_onenie!
Henhuy

Odpowiedzi:

8

W końcu rozwiązałem problem!

To był naprawdę problem z typem, ponieważ wartości wejściowe są zdefiniowane jako QVariantwewnątrz @qgsfunction. Aby więc mój kod działał, musiałem najpierw przekonwertować je na liczby całkowite. Najwyraźniej QGIS sam zajmuje się konwersją typów ...

Funkcja wygląda teraz tak:

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

A jeśli masz funkcję umieszczoną w folderze projektu, nie zapomnij najpierw ją zarejestrować:

from qgis.core import QgsExpression
QgsExpression.registerFunction(bitwise_and) 
Henhuy
źródło