Usando os algoritmos do processamento a partir da consola

A consola permite que utilizadores avançados aumentem a sua produtividade e executar operações complexas que não podem ser executadas usando quaisquer outros elementos da infraestrutura do processamento GUI. Os modelos envolvendo vários algoritmos podem ser definidos usando a interface da linha de comandos, e operações adicionais tais como ciclos e instâncias condicionais podem ser adicionadas para criar fluxos de trabalhos mais poderosos e flexíveis.

Não existe uma consola de processamento no QGIS, mas em vez disso todos os comandos do processamento estão disponível a partir da consola Python embutida. Isso significa que pode incorporar esse comando na seu trabalho da consola e ligar os algoritmos do processamento a todos os outros elementos (incluindo os métodos provenientes da API do QGIS) disponíveis.

O código que pode executar a partir da consola Python, mesmo quando não chama nenhum método específico do processamento, pode ser convertido num novo algoritmo que pode mais tarde chamar da caixa de ferramentas, o modelador gráfico ou qualquer outro componente, como faz para outro algoritmo. De facto, alguns algoritmos que encontra na caixa de ferramentas são scripts simples.

Neste capítulo iremos ver como usar os algoritmos do processamento a partir da consola Python QGIS, e também escrever os seus próprios algoritmos usando o Python.

Chamando os algoritmos a partir da consola Python

A primeira coisa que tem de fazer é importar as funções do processamento com a seguinte linha:

>>> import processing

Agora, basicamente é uma coisa (interessante) que pode fazer com isto a partir da consola: executar um algoritmo. Isso é feito usando o método runalg(), que toma o nome do algoritmo a ser executado como o seu primeiro parâmetro, e de seguida o número da variável de um parâmetro adicional que depende dos requisitos do algoritmo. Portanto a primeira coisa que necessita de saber é o nome do algoritmo a executar. Não será o nome que vê na caixa de ferramentas, mas um único nome da linha de comando. Para encontrar o nome correcto do seu algoritmo, pode usar o método alslist(). Introduza a seguinte linha na sua consola:

>>> processing.alglist()

Irá ver algo como isto.

Accumulated Cost (Anisotropic)---------------->saga:accumulatedcost(anisotropic)
Accumulated Cost (Isotropic)------------------>saga:accumulatedcost(isotropic)
Add Coordinates to points--------------------->saga:addcoordinatestopoints
Add Grid Values to Points--------------------->saga:addgridvaluestopoints
Add Grid Values to Shapes--------------------->saga:addgridvaluestoshapes
Add Polygon Attributes to Points-------------->saga:addpolygonattributestopoints
Aggregate------------------------------------->saga:aggregate
Aggregate Point Observations------------------>saga:aggregatepointobservations
Aggregation Index----------------------------->saga:aggregationindex
Analytical Hierarchy Process------------------>saga:analyticalhierarchyprocess
Analytical Hillshading------------------------>saga:analyticalhillshading
Average With Mask 1--------------------------->saga:averagewithmask1
Average With Mask 2--------------------------->saga:averagewithmask2
Average With Thereshold 1--------------------->saga:averagewiththereshold1
Average With Thereshold 2--------------------->saga:averagewiththereshold2
Average With Thereshold 3--------------------->saga:averagewiththereshold3
B-Spline Approximation------------------------>saga:b-splineapproximation
...

Esta é a lista de todos os algoritmos disponíveis, ordenados alfabeticamente, juntamente com os seus nomes da linha de comandos correspondentes.

Pode usar uma cadeia de texto como parâmetro para este método. Em vez de retornar uma lista completa do algoritmo, apenas irá aparecer aqueles que incluem essa cadeia de texto. Se, por um instante, estiver à procura de um algoritmo para calcular o declive de um MDE, introduza alglist("slope") para obter o seguinte resultado:

DTM Filter (slope-based)---------------------->saga:dtmfilter(slope-based)
Downslope Distance Gradient------------------->saga:downslopedistancegradient
Relative Heights and Slope Positions---------->saga:relativeheightsandslopepositions
Slope Length---------------------------------->saga:slopelength
Slope, Aspect, Curvature---------------------->saga:slopeaspectcurvature
Upslope Area---------------------------------->saga:upslopearea
Vegetation Index[slope based]----------------->saga:vegetationindex[slopebased]

Este resultado pode mudar dependendo dos algoritmos que estão disponíveis.

Agora é mais fácil encontrar o algoritmo que procura e o seu nome da linha de comandos, neste caso saga:slopeaspectcurvature.

Uma vez conhecida no nome da linha de comandos do algoritmo, a próxima coisa a fazer é conhecer a sintaxe correcta para executá-lo. Isto significa saber quais os parâmetros necessários e a ordem que devem passar quando chamado pelo método runalg(). Existe um método para descrever um algoritmo em detalhe, que pode ser usado para obter uma lista de parâmetros que os algoritmos necessitam e os ficheiros de saída que irão gerar. Para fazer isso, pode usar o método alghelp(name_of_the_algorithm). Use o nome do algoritmo na linha de comando, não o nome descritivo completo.

Chamando o método com o saga:slopeaspectcurvature como parâmetro, irá obter a seguinte descrição.

>>> processing.alghelp("saga:slopeaspectcurvature")
ALGORITHM: Slope, Aspect, Curvature
   ELEVATION <ParameterRaster>
   METHOD <ParameterSelection>
   SLOPE <OutputRaster>
   ASPECT <OutputRaster>
   CURV <OutputRaster>
   HCURV <OutputRaster>
   VCURV <OutputRaster>

Agora tem tudo o que necessita de correr qualquer algoritmo. Como já tínhamos mencionado, existe apenas um comando para executar algoritmos: runalg(). A sua síntaxe é como está descrito a seguir:

>>> processing.runalg(name_of_the_algorithm, param1, param2, ..., paramN,
         Output1, Output2, ..., OutputN)

A lista de parâmetros e ficheiros de saída para adicionar dependem do algoritmo que quer correr, e é exactamente a lista que o método alghelp() lhe dá, na mesma ordem que é exibido.

Dependendo do tipo de parâmetro, os valores são introduzidos de forma diferente. A próxima explicação é uma rápida revisão de como introduzir valores para cada tipo de parâmetro de entrada:

  • Camada Raster, camada Vectorial ou Tabela. Simplesmente usa uma cadeia de texto com nome que identifica o objecto de dados a usar ( o nome está na Tabela de Conteúdos do QGIS) ou o nome do ficheiro (se a camada correspondente não for aberta, mas não adicionada no enquadramento do mapa). Se tiver uma instância do objecto QGIS representado na camada, pode também passá-lo como um parâmetro. Se o ficheiro de entrada é opcional e não quer usá-lo como qualquer tipo de objecto de dados, use Nenhum.

  • Selecção. Se algum algoritmo tiver um parâmetro de selecção, o valor desse parâmetro deve ser introduzido usando um valor inteiro. Para saber as opções disponíveis, pode usar o comando algoptions(), como é exibido no seguinte exemplo:

    >>> processing.algoptions("saga:slopeaspectcurvature")
    METHOD(Method)
        0 - [0] Maximum Slope (Travis et al. 1975)
        1 - [1] Maximum Triangle Slope (Tarboton 1997)
        2 - [2] Least Squares Fitted Plane (Horn 1981, Costa-Cabral & Burgess 1996)
        3 - [3] Fit 2.Degree Polynom (Bauer, Rohdenburg, Bork 1985)
        4 - [4] Fit 2.Degree Polynom (Heerdegen & Beran 1982)
        5 - [5] Fit 2.Degree Polynom (Zevenbergen & Thorne 1987)
        6 - [6] Fit 3.Degree Polynom (Haralick 1983)
    

    Neste caso, o algoritmo tem um desses parâmetros, com 7 opções. Tenha em atenção que a ordenação baseia-se no zero.

  • Múltiplas entradas. O valor é uma cadeia de texto com descritores de entrada separados por ponto e vírgula (;). Tal como no caso das camadas ou tabelas únicas, cada descritor de entrada pode ser o nome do objecto, ou o caminho do ficheiro.

  • Campo da Tabela de XXX. Use uma cadeia de texto com o nome do campo a usar. O parâmetro é caso sensitivo.

  • Tabela Fixa. Escreva a lista de todos os valores da tabela separadas por vírgulas (,) e feche entre aspas ("). Os valores começam na linha de cima e vai da esquerda para a direita. Pode também usar um array 2D de valores que representam a tabela.

  • SRC. Introduza o número do código ESPG do SRC desejado.

  • Extensão. Deve usar uma cadeia de texto com xmin, xmax, ymin e ymax valores separados por vírgulas (,).

Os parâmetros booleanos, de ficheiro, cadeia de texto e númericos não necessitam de explicações adicionais.

Os parâmetros de entrada tais como as cadeias de texto booleanas ou valor numéricos têm valores padrão. Para usá-los, use Nenhum na entrada de parâmetro correspondente.

Para objectos de dados de saída, introduza o caminho do ficheiro que será usado e guarde-o, como é feito a partir da caixa de ferramentas. Se quiser guardar o resultado para um ficheiro temporário, use Nenhum. A extensão do ficheiro determina o formato do ficheiro. Se introduzir um ficheiro com uma extensão que não está suportado pelo o algoritmo, o formato de ficheiro padrão para o ficheiro de saída será usado e a correspondente extensão adicionada ao caminho do ficheiro dado.

Contrariamente, quando o algoritmo é executado a partir da caixa de ferramentas,os ficheiros de saída não são adicionados ao enquadramento do mapa se executar o mesmo algoritmo a partir da Consola Python. Se quiser adicionar um ficheiro de saída, você tem de adicioná-lo depois de correr o algoritmo, Para o fazer, pode usar os comandos do API QGIS, ou, mais fácil, use um dos métodos úteis para esta tarefa.

O método runalg retorna um dicionário com os nomes de saída (os que são exibidos na descrição do algoritmo) como chaves ou caminhos de ficheiro dessas saídas como valores. Pode carregar essas camadas passando o seu caminho de ficheiro pelo método load().

Funções adicionais para a manipulação dos dados

Além das funções usadas para chamar os algoritmos, importar o pacote processamento irá também importar algumas funções adicionais que facilitará o trabalho dos dados, particularmente os dados vectoriais. Estas funções de conveniência que envolvem alguma funcionalidade a partir da API do QGIS, usualmente com uma sintaxe menos complexa. Estas funções devem ser usadas quando são programados novos algoritmos, para tornar mais fácil a operação com o os dados de entrada.

Abaixo está uma lista de algum dos comandos. Pode encontrar mais informação nas classes no pacote processing/tools, e também nos exemplos de script fornecidos no QGIS.

  • getobject(obj): Retorna um objecto|qg| (uma camada ou tabela) a partir de um objecto que passou, que pode ser um nome de ficheiro ou o nome do objecto na Tabela de Conteúdos do QGIS.

  • values(layer,fields): Retorna os valores da tabela de atributos de uma camada vectorial, para os campos validados. Os campos podem ser validados como nomes de campos ou índices baseados em zero. Retorna um dicionário de listas, com campos de indentificadores validados como chaves. Considera a selecção existente.

  • getfeatures(layer): Retorna um iterador sobre os elementos da camada vectorial, considerando a selecção existente.

  • uniquelabels(layer, field): Retorna a lista de valores únicos de um dado atributo. O atributo pode passar como um nome de campo ou um campo de índice baseado em zero. Considera uma selecção existente

Criando scripts e correndo-os a partir da caixa de ferramentas

Pode criar os seus próprios algoritmos através da escrita do código Python correspondente e adicionando novas linhas para fornecer informação adicional necessária para definir as semânticas do algoritmo. Pode encontrar o menu Criar novo script no grupo das Ferramentas no bloco de algoritmos Script da caixa de ferramentas. Faça duplo clique nele e irá abrir um diálogo de edição do script. É aí que deve introduzir o código. Guarde o script na pasta scripts (a pasta padrão quando abre o diálogo de guardar ficheiro), com a extensão .py, irá automaticamente criar o algoritmo correspondente.

O nome do algoritmo (aquele que irá ver na caixa de ferramentas) é criado a partir do nome do ficheiro, removendo a extensão e substituindo os hífens inferiores com espaços em branco.

Vamos ter o seguinte código, que calcula o Índice Topográfico de Humidade (ITH) directamente do MDE

##dem=raster
##twi=output
ret_slope = processing.runalg("saga:slopeaspectcurvature", dem, 0, None,
                None, None, None, None)
ret_area = processing.runalg("saga:catchmentarea(mass-fluxmethod)", dem,
                0, False, False, False, False, None, None, None, None, None)
processing.runalg("saga:topographicwetnessindex(twi), ret_slope['SLOPE'],
                ret_area['AREA'], None, 1, 0, twi)

Como pode ver, isto envolve 3 algoritmos, todos eles provêem do SAGA. O último deles calcula o ITH, mas necessita da camada do declive e uma camada de acumulação de escoamento. Nós não necessitamos destes, mas uma vez que temos o MDE, podemos calcula-los chamando os algoritmos SAGA correspondentes.

A parte do código onde este processamento tem lugar não é difícil de perceber se leu-o as secções anteriores deste capítulo. Contudo, as primeiras linhas, necessitam de uma explicação adicional. Eles fornecem a informação que é necessária para tornar o código num algortimo que possa ser corrido a partir qualquer componente do GUI, como por exemplo a caixa de ferramentas ou o modelador gráfico.

Estas linhas começam com o símbolo duplo de comentário Python (##) e tem a seguinte estrutura

[parameter_name]=[parameter_type] [optional_values]

Aqui está uma lista de todos os tipos de parâmetros que são suportados nos scripts do processamento, a sua sintaxe e alguns exemplos.

  • raster. Uma camada raster

  • vector. Uma camada vectorial

  • table. Uma tabela

  • number. Um valor numérico. Deverá ser fornecido um valor padrão. Por exemplo, depth=number 2.4

  • string. Uma cadeia de texto. Como no caso dos valores numéricos, o valor padrão deve ser adicionado. Por exemplo, name=string Victor

  • boolean. Um valor booleano. Adicione True ou False depois de definir o valor padrão. Por exemplo, verbose=boolean True

  • múltiplos raster. Um conjunto de camadas rasters de entrada.

  • vectores múltiplos. Um conjunto de camadas vectoriais de entrada.

  • campo. Um campo da tabela de atributos de uma camada vectorial. O nome da camada tem de ser adicionada depois da etiqueta campo. Por exemplo, se declarou um ficheiro de entrada vectorial com mylayer=vector, poderá usar myfield=field mylayer para adicionar o campo a partir dessa camada como parâmetro.

  • pasta. Uma pasta

  • ficheiro. Um nome de ficheiro

O nome do parâmetro é o nome que será exibido ao utilizador quando executa o algoritmo, e também o nome da variável a usar no código do script. O valor introduzido pelo utilizador para esse parâmetro será atibuído à variável com esse nome.

Quando é exibido o nome do parâmetro ao utilizador, o nome irá ser editado para melhorar a aparência, substituindo o hífen inferior com espaços. Portanto, por exemplo, se quer que o utilizador veja o parâmetro chamado Um valor numérico, pode usar o nome da variável A_numerical_value.

Os valores das camadas e tabelas são cadeias de texto que contêm caminhos de ficheiro para o objecto correspondente. Para torná-los em objectos QGIS, pode usar a função processing.getObjectFromUri(). Os múltiplos dados de entrada também têm um valor de cadeia de texto, que contêm caminhos de ficheiros para todos os objectos seleccionados, separado por ponto e vírgulas (;).

Os ficheiros de saída são definidos numa maneira semelhante, usando as seguintes etiquetas:

  • raster de saída

  • vector de saída

  • tabela de saída

  • html de saída

  • ficheiro de saída

  • número de saída

  • cadeia de texto de saída

O valor atribuído às variáveis de saída são sempre uma cadeia de texto com um caminho de ficheiro. Irá corresponder a um caminho de ficheiro temporário no caso do utilizador não introduzir qualquer nome de ficheiro de saída.

Quando declara um ficheiro de saída, o algoritmo irá tentar adicioná-lo no QGIS uma vez finalizado. Isto é a razão porque, embora o método runalg() não carrega camadas quando as produz, a camada TWI final será carregadas, uma vez guardada no ficheiro introduzida pelo utilizador, que é o valor do ficheiro de saída correspondente.

Não use o método load() no seu script do algoritmo, mas apenas quando trabalha com a linha de comandos. Se a camada é criada com um ficheiro de saída de um algoritmo, deve ser declarada como tal. Caso contrário, não irá usar de forma correcta o algoritmo no modelador, uma vez que a sua sintaxe (como é definido pela explicação das etiquetas acima) não irá coincidir com o que o algoritmo realmente cria.

Ficheiro de saída escondidos (números e cadeias de texto) que não têm valor. Em vez disso, é você que define o valor deles. Para o fazer, apenas configure o valor da variável com o nome que usou para declarar o ficheiro de saída. Por exemplo, se tiver usado esta declaração,

##average=output number

a linha seguinte irá configurar o valor de saída para 5:

average = 5

Em adição às etiquetas para os parâmetros e ficheiros de saída, pode também definir o grupo onde o algoritmo será exibido, usando a etiqueta group.

Se o seu algortimo demora muito tempo a processar, é boa ideia informar o utilizador. Tem uma variável global chamada de progresso disponível, com dois métodos disponíveis: setText(text) e ``setPercentage(percent) para modificar o texto do progresso e a barra de progresso.

Vários exemplos são fornecidos. Por favor, verifique-os para ver exemplos reais de como criar algoritmos usando as classes da infraestrutura do processamento. Pode clicar com o direito do rato em qualquer script do algortimo e seleccionar Editar script para editar o seu código ou apenas para vê-lo.

Documentando os seus scripts

Como no caso dos modelos, você pode criar documentação adicional para o seu script, para explicar o que fazem e como são usados. No diálogo de edição do script irá encontrar um botão [Editar ajuda do script]. Clique nele e irá levá-lo para o diálogo de edição da ajuda. Verifique o capítulo sobre o modelador gráfico para saber mais sobre este diálogo e como usá-lo.

Os ficheiros da ajuda são guardados na mesma pasta como o próprio script, adicionando a extensão .help ao nome do ficheiro. Note que, você pode editar a ajuda do seu script antes de guardá-lo pela primeira vez. Se fechar mais tarde o diálogo de ajuda do script sem guardar o script (ex.: rejeitá-lo) o conteúdo da ajuda que escreveu será perdido. Se o seu script estiver já guardado e associado ao nome do ficheiro, será guardado automaticamente.

Pré- e pós-execução de encaixe da script

Os scripts podem também ser usados para definir um encaixe de pré- e pós-execução que correm antes e depois do algoritmo correr. Isto pode ser usado para automatizar tarefas que serão executados quando qualquer algoritmo é executado.

A sintaxe é identica à sintaxe explicada em cima, mas uma variável global alg está disponível, representando o algoritmo que foi (ou está prestes a ser) executado.

No grupo Geral do diálogo de configuração do processamento irá encontrar duas entradas denominados de Pré-execução do ficheiro script e Pós-execução do ficheiro script onde os nomes do ficheiro dos scripts serão executados no caso de serem introduzidos.