Função para intersectar geometrias em PostgreSQL + PostGIS

Escrevi esta função para dar resposta a uma operação muito comum em SIG. Intersecção entre geometrias. No entanto, por vezes, as geometrias não se intersectam e nesses casos o que nos gostaria de saber é a que distancia está a geometria mais próxima. Ou mesmo, todas as geometrias que estão dentro uma determinada distancia. Outro fator a ter em conta é a velocidade da consulta. Para acelerar o calculo usa-se o típico a.geom && b.geom e assim a consulta faz uso do bounding box da geometria subjacente. Mas no caso de uma geometria estar fora de todos os bounding box vamos ter como resposta um valor NULL, e isso não é muito informativo. Esta função tentar dar resposta a todas estas questões.

Aspetos a ter em conta.
– Ambas tabelas tem de ter uma PRIMARY KEY.
– Não importa o tipo de geometria (POINT, LINE, POLYGON, …).
– Não importa se as geometrias tem diferentes Sistemas de Coordenadas, a função converte tudo a EPSG:4326 (WGS84) para realizar o calculo.
– Vão ser criados duas colunas, uma para os id‘s da(s) geometria(s) mais próxima(s) e outra para a(s) distancia(s) em metros.
– Se a função se executa mais de uma vez, elimina as colunas anteriores antes de as criar novamente.
– O resultado da distancia é dado em metros.
– O valor de tolerance deve ser dado em metros.
– Se o valor de tolerance é igual a 0, apenas devolve o id de uma geometria, a mais próxima e a sua distancia (0 ou mais).
– Se o valor de tolerance é maior do que 0, devolve uma array com todos os id das geometrias a menor ou igual distancia do valor de tolerance e uma array com as correspondentes distancias. Pela mesma ordem.

Como usar esta função.

SELECT fun_closest_geom(sch_from, table_from, sch_to, table_to, tolerance);

– Caso 1. Queremos saber que geometria da tabela public.tabela2 esta mais próxima das geometrias da tabela public.tabela1. Os resultados escritos na public.tabela1.
SELECT fun_closest_geom(‘public’, ‘tabela1’, ‘public’, ‘tabela2’, 0);

– Caso 2. Queremos saber que geometrias da tabela public.tabela2 estão a <= 1 Km das geometrias da tabela public.tabela1. Os resultados escritos na public.tabela1.
SELECT fun_closest_geom(‘public’, ‘tabela1’, ‘public’, ‘tabela2’, 1000);

Mas antes temos de criar a função, para isso basta executar o seguinte código.