domingo, 6 de maio de 2018

ATUALIZAÇÃO COM RELAÇÃO ESPACIAL NO QGIS

Quando for necessário atualizar um dado baseado em uma relação espacial no QGIS (por exemplo, os trechos de uma rodovia que interceptam Áreas de Proteção Ambiental), podemos utilizar o Editor de Funções do mesmo. Para isso:
1) Selecione a camada (com um clique do botão esquerdo sobre seu nome) a partir da qual se quer selecionar os dados (de acordo com o exemplo, os trechos de uma rodovia);
2) Abra a "Calculadora de campos" e clique na aba "Editor de funções";
3) Clique em "Novo arquivo", dê um nome (por exemplo, "consulta_espacial") e clique em "OK";
4) Substitua o texto que aparece na parte do editor de funções (ao lado direito) por:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Personalizado')
def intersection_field_update(layername, column, feature, parent):
    layer = QgsMapLayerRegistry.instance().mapLayersByName(layername)[0]
    for feat in layer.getFeatures():
        if feature.geometry().intersects(feat.geometry()):
            return feat[column]

5) Clique em "Carregar";
Nesse momento, você criou uma função chamada intersection_field_update no grupo "Personalizado";
6) Volte para a aba "Expressão" e perceba que agora no conjunto de funções existe um grupo "Personalizado" com a função intersection_field_update. Use ela para atualizar ou criar um campo com dados de outra camada que possua relação de interceptar com a camada em uso - Será necessário passar dois parâmetros: a tabela e o campo (nessa ordem).

Considerando o exemplo, imaginemos um projeto com duas tabelas: trecho_rodovia e apa, e que na tabela apa exista um campo nome (com o nome da APA). Se utilizarmos a função para criar um campo virtual chamado apa na tabela trecho_rodovia, com o nome da APA que o trecho intercepta, teríamos o seguinte:


Obs.: O texto da expressão nesse caso é intersection_field_update('apa','nome') 

Ao clicar em OK será criado um campo virtual com o nome apa na tabela trecho_rodovia, onde estará o nome da APA que o trecho intercepta (ou nulo, se ele não intercepta nenhuma APA).

Após criar a função não é mais necessário fazer as etapas 3 a 5 para utilizá-la novamente, pois ela já estará criada. Essa função inclusive pode ser alterada para atingir outros objetivos (por exemplo, substituindo  o "intersects" por "within" é possível estabelecer uma relação de um elemento "estar contido" em outro - Como consta na postagem cujo link está nos agradecimentos).

Agradecimentos a Alexandre Miguel Freitas da Silva e Ciro Borges de Oliveira, que incentivaram essa pesquisa, e a Detlev (https://gis.stackexchange.com/users/45346/detlev), cuja resposta em (https://gis.stackexchange.com/questions/178522/update-field-based-on-spatial-query-qgis?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa) possibilitou o embasamento para essa postagem.