Registrar qgsfunction customizado no pyqgis

9

Estou usando pyqgis em um aplicativo independente. Agora eu queria criar uma expressão personalizada para usar como filterExpression na regra de ruleBasedRendererV2. (Eu tentei o renderizador com funções existentes antes e tudo funcionou bem!)

Personalizado qgisfunction(função AND bit a bit - como ainda não existe essa função) se parece com isso:

from qgis.utils import qgsfunction

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

Eu também tentei registrá-lo, via:

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

Testando a expressão via:

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

(Dar 2=2sempre True) funciona após o registro da função e falha se não. Mas ainda assim, não posso usar a expressão dentro de uma regra ...

No momento, o arquivo que contém a função está no topo da pasta do meu projeto, que é automaticamente incluída no PATH, não é ?! (De acordo com Nathan Woodrow, o arquivo pode ser colocado em qualquer lugar do PATH - consulte https://nathanw.net/2012/11/10/user-defined-expression-functions-for-qgis/ ).

ATUALIZAÇÃO: O registro da função funciona até agora, com o código acima - agora o problema está na própria função ...

ATUALIZAÇÃO # 2:

Muito estranho! Função simples, do_nothingobtendo dois argumentos, funciona bem no meu código:

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

Usando expressão expString = 'do_nothing(2, 2) = 2'

ATUALIZAÇÃO # 3:

A simples mudança de do_nothingpara add_onenão funciona mais:

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

chamando-o via expString = 'add_one(2, 2) = 3'. É por isso que acho que tem algo a ver com o tipo de retorno ?!

Henhuy
fonte
11
Copie o arquivo no ~/.qgis2/python/expressions/QGIS, em seguida, recarregar e a função está disponível na seção Construtor de expressão python
ThomasG77
Seguindo o seu conselho, a função aparece no editor de funções QGIS e eu posso usá-la conforme o esperado. Mas, ao tentar usá-lo no meu aplicativo independente, a função não funciona! - Acho que, quando o QGIS é iniciado, de alguma forma, ele registra todos os arquivos na pasta de expressões, mas eu me pergunto como ?!
Henhuy
Você está usando a @qgsfunctionfunção no seu código, como define a função no código. Você pode pode ignorar a expressionspasta se você estiver fazendo o seu próprio script que é apenas para o aplicativo principal
Nathan W
Você está certo - ao registrar a função funciona como descrito acima (por exemplo do_nothing). Mas minha função original bitwise_andainda não funciona. Agora, acho que tem algo a ver com o tipo de retorno da função, pois do_nothing works, mas add_onenão tem!
Henhuy 4/06/2016

Respostas:

7

Finalmente resolvi o problema!

Foi realmente um problema de tipo, pois os valores de entrada são definidos como QVariantinternos @qgsfunction. Então, para que meu código funcionasse, tive que convertê-los em números inteiros primeiro. Aparentemente, o QGIS cuida das próprias conversões de tipo ...

A função se parece com isso agora:

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

E se você tiver a função colocada na pasta do projeto, não se esqueça de registrá-la primeiro:

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