Acções Em Python No QGIS

18 de Junho, 2014

Este artigo demonstra como se podem rapidamente usar Acções para criar um projecto com tarefas desenvolvidas à medida em Python.

Introdução às Acçções em Python

Acções no QGIS permitem que o utilizador defina, para um tema, tarefas que serão despoletadas pelo utilizador. A grande utilidade das acções é que usam os valores dos atributos dos vectores desse tema para executar a tarefa. Assim, podemos definir uma acção que abre um documento cujo nome é obtido de um atributo. Podemos, por exemplo, abrir a fotografia de uma caixa de visita numa rede de águas. As acções podem ser despoletadas quando o utilizador usa a janela de identificação, a tabela de atributos, ou o botão de acções. Mais informação pode ser obtida no manual de utilizador.

Este artigo não é um tutorial aprofundado sobre acções do QGIS, pretende apenas demonstrar um caso de utilização de acções programadas em Python. Acções em Python são apenas uma das formas de criar acções. Outros tipos de acções que não usam programação são também possíveis.

Para começar a explorar a forma de criar acções, pode ver um conjunto de acções pré-definidas que estão incluídas no QGIS. Para isso, basta abrir as propriedades de um tema, e clicar na secção Acções. Aqui, pode clicar no botão “Adicionar acções pré-definidas”.

Criação de novas acções

Esta é uma forma de aprender rapidamente como se criam acções. Uma das acções permite abrir uma página na web com o endereço criado a partir de um campo da tabela de atributos. Outra, mais interessante para o nosso artigo, é composta por uma linha de código Python que mostra o número do registo automático ao clicar sobre um elemento desse tema:

Acção para obter o ID do registo

Como em todas as acções, esta estará disponível em 3 locais: janela de identificação, janela de atributos, e ao clicar no mapa quando activamos a acção no menu de acções. Esta última possibilidade é a mais útil neste caso, porque permite ao clicar no mapa obter uma janela com apenas a informação que precisamos, ao invés da janela de identificação genérica com todos os atributos.

Caso Prático

Avançando… o problema que se pretende resolver é o seguinte: tendo um tema de cadastro e uma tabela de proprietários, como selecionar na tabela um proprietário e visualizar os seus prédios no tema, de forma simples para utilizadores que não conhecem QGIS?

Claro que o QGIS é mais que capaz de resolver esta questão, usando as funções de selecção por atributo e até a fantástica nova capacidade de definir relações de 1 para muitos. Mais informação pode ser obtida aqui:

Mas estes mecanismos exigem conhecimento de utilização de QGIS e até de SIG, pelo que não serviam ao nosso propósito. Era necessário criar mecanismos simples de pesquisa e cruzar resultados entre uma tabela e um tema.

Primeira acção Python

A primeira acção que se criou permitia ao utilizador clicar sobre uma linha na tabela de proprietários e selecionar todos os registos com o mesmo proprietário. É preciso explicar que esta tabela continha linhas para todos os prédios de cada proprietário. Ou seja, o mesmo proprietário surge tantas vezes quantos os prédios que este detém.

Nas propriedades da tabela de proprietários, na secção de Acções, vamos adicionar uma nova acção Python, e adicionar o código mostrado na imagem seguinte.

Acçção para seleccionar todos os registos com o mesmo proprietário

Naturalmente, o código é um pouco difícil de ler… e a sintaxe é um pouco diferente - é necessário terminar cada linha com “;”.

Mas o mais interessante é que quando o utilizador abrir a tabela de atributos e clicar com o botão direito sobre um registo vai ter agora uma nova opção chamada “Seleciona NIFs como este”. O QGIS irá passar o valor do campo “NumContrib” para este código e executá-lo. O código irá selecionar todos os registos da tabela com este NIF, permitindo ao utilizador executar uma selecção sem ter de conhecer a sintaxe de selecção do QGIS, nem qual o campo a usar… passa a ser uma ferramenta rápida e de uso imediato:

Acção para selecionar todos os atributos com um determinado NIF a partir da tabela de atributos

E ao clicar na opção, vamos ver todos os registos com o mesmo NIF serem selecionados:

Resultado da acção para selecção de registos com um mesmo NIF

Então, o que mais poderemos fazer para ajudar a consultar a informação? Adicionámos as seguintes acções:

  • “”Mostra Prédios” - seleciona no tema de cadastro todos os prédios correspondentes à selecção na tabela de proprietários (note-se que nesta tabela estão listados todos os prédios detidos por todos os proprietários);
  • “Seleciona Nomes como este” - seleciona todos os registos na tabela com o mesmo nome do registo onde se clicou;
  • “Pesquisa NIF” - permitir que o utilizador introduza um NIF para pesquisar na tabela. Pode depois usar a opção para mostrar os prédios correspondentes no mapa;
  • “Pesquisa Nome” - permitir que o utilizador introduza um nome para pesquisar na tabela. Pode depois também ver os prédios correspondentes no mapa;

O resultado de ter estas acções definidas, é que ao clicar na tabela com o botão direito surge-nos este menu:

Várias acções no menu de contexto na tabela de atributos

Uma utilização típica seria pesquisar por nome e ver os prédios no mapa. O código da pesquisa por nome foi feito de forma a pesquisar todos os nomes que incluam o texto introduzido pelo utilizador. Assim, um exemplo de utilização seria começar pela pesquisa de todos os prédios cujo proprietário tem no nome o texto “maria de fátima”:

Acção de selecção de prédios a partir do nome do proprietário

Obtendo-se 57 registos. E depois bastará selecionar a opção “Mostra Prédios” para ver esses prédios no mapa:

Resultado da execução da acção de selecção de prédios pelo nome do proprietário

Como comunicar com o utilizador usando Acções Python

Há alguns truques interessantes nestas acções, sobretudo de como interagir com o utilizador… Como mostrar uma janela com uma mensagem? Podemos usar um widget do Qt, dos mais simples. E a nossa mensagem pode até ser construída com os campos da tabela. Por exemplo:

1
QtGui.QMessageBox.information(None, "Prédio", "O código do prédio é [% Codigo %]")

Como mostrar uma janela para o utilizador introduzir um valor? Podemos usar directamente no código um widget de introdução de texto do Qt:

1
texto,ok = QtGui.QInputDialog.getText(None, "Titulo da janela", "Introduza um valor: ")

Este widget mostra uma janela com o título que indicamos e uma caixa para introdução de texto, com uma mensagem indicada por nós. Note-se que temos de testar se é clicado o botão OK ou o botão de Cancelar…

1
2
3
4
if ok:
    return texto
  else:
    return False

Colocar o código num Módulo Python

Quando o código da acção começa a crescer, a janela de definição da acção torna-se improductiva, e seria preferível usar o nosso editor favorito de Python. É possível criar um ficheiro de Python com todo o código das nossas acções e usá-lo depois no QGIS - em vez de usar todo o código na definição da acção, basta carregar o nosso módulo e invocar uma das suas funções:

Importação de acções programadas num ficheiro externo

Como se pode ver, o código ficou muito simples:

1
import acoes; acoes.selecNomePredio([% Nome %])

Todo o código foi colocado num ficheiro guardado na mesma pasta do nosso projecto. Neste exemplo, o ficheiro chama-se “acoes.py”. Este ficheiro não tem nada de especial, apenas contém funções Python normais, que podemos invocar a partir do QGIS. Apenas temos de importar alguns módulos do QGIS, e se necessário do próprio Qt para podermos usar os seus widgets:

1
2
3
from qgis.core import *
import qgis.utils
from PyQt4 import QtGui

Por outro lado, para garantir que não temos problemas com os caracteres portugueses, será melhor assegurar que o módulo é executado usando a codificação utf-8. Em Windows isto não acontece normalmente, e por isso temos de forçar o uso de utf-8 com o seguinte código logo no topo do ficheiro:

1
2
3
4
5
# -*- coding: UTF-8 -*-
#assegurar que não temos problemas com o encoding de strings
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

E é tudo. Obviamente que a solução mais evoluída é construir um plugin Python que permite usar as nossas funções independentemente do projecto que usamos, e centralizar a sua actualização. Mas para algo rápido e simples, as acções Python têm muito para oferecer.

Bom trabalho!



Categorias: Acções, Desktop, Python


Blog desenvolvido com Octopress