Disparador (trigger) para actualizar automaticamente a área e o perímetro de geometrias em PostgreSQL

Nesta entrada vou explicar como criar um disparador para actualizar automaticamente a área e perímetro das geometrias de uma tabela em PostgreSQL. Para tal, vão-se utilizar as funções ST_Area() e ST_Perimeter() de PostGIS.

Nota: Onde está esquema deve ir o nome do esquema, onde está tabela o nome da tabela e onde está geom o nome do campo com a geometria.

As seguintes linhas são para criar os campos area e perimetro e preencher os campos. Utilizar uma das opções: UTM ou Geográficas, dependendo do sistema de coordenadas do tema.

Decidi utilizar o tipo bigint porque considero que os valores decimais não aportam informação útil para pequenas escalas e iriam ocupar mais espaço na tabela. No entanto, para escalas maiores e se interessa a exactidão, basta com mudar bigint por float.

Agora criamos a função que preenche automáticamente os campos area e perimetro cada vez que uma geometria é inserida ou modificada. Se anteriormente alteraste bigint por float, elimina ‘::bigint’ nas linhas 5 e 6. O resultado por defeito é do tipo float e já não é necessário fazer um cast.

O exemplo dado é para temas com sistemas de coordenadas em metros, como UTM. Se o tema está em geográficas e também se pretende o resultado em metros, deve ir assim:

Eliminamos o disparador no caso de que já exista um com o mesmo nome. Para passar a criar o disparador e indicar quando se deve executar e sobre que tabela.

Agora os valores de área e perímetro da tabela estarão sempre de acordo com a geometria.

Conversão de graus a metros

Um método simples e bastante preciso para converter graus a metros é conseguido utilizando uma consulta SQL em PostgreSQL + PostGIS. Como podemos ver nas seguintes consultas para distintas latitudes:

Etiquetar geometrias de parte simples poligonais em PostGIS

Se temos um tema com geometrias de parte simples (single part) poligonais, como por exemplo o tema países. Ao etiquetar surgirá uma etiqueta por cada elemento geométrico quando queremos apenas uma etiqueta para todos os elementos pertencentes ao mesmo grupo, neste caso país.

Antes.

Esta foi uma solução simples e rápida que encontrei. Criar um novo campo com geometria para pontos e ai calcular o centroide da geometria poligonoal com maior superfície do grupo, neste caso país. Código SQL:

Agora para o mesmo tema existem duas geometrias, uma poligonal e outra de pontos, esta ultima servirá apenas para etiquetar.

Depois.

Análise espacial com PostGIS V

Nesta entrada vamos ver como seleccionar os países que se encontram no hemisfério Norte, Sul e os que estão em cima do equador (ou em ambos hemisférios). Para tal vamos usar três funções de PostGIS:

ST_UNION() para juntar as geometrias de um mesmo país, temos como exemplo os polígonos que conformam Portugal continental e os arquipélagos dos Açores e Madeira, em apenas um registo. Algo como ‘Single parte to multipart’.

ST_YMIN() para obter o mínimo valor de latitude de toda a geometria.

ST_YMAX() para obter o máximo valor de latitude de toda a geometria.

Sendo ‘sch_cartobase’ o nome do esquema, ‘wd_paises’ o nome da tabela com a geometria dos países do mundo, ‘iso3166_2’ o campo com os códigos de países e ‘geom’ o campo com a geometria. Executamos as seguintes consultas SQL:

Instalação de PostgreSQL + PostGIS em Ubuntu 10.4

Partindo do principio que temos adicionado às nossas fontes de software o repositório de UbuntuGIS (ver entrada anterior), procedemos à instalação de PostgreSQL 8.4, PostGIS 1.5 e pgAdmin III.

Mudamos a senha do utilizador postgres no gestor de base de dados. Este utilizador tem todos os privilégios para administrar a base de dados.

Mudamos novamente a senha do utilizador postgres no sistema operativo, para que sejam iguais.

Criamos outro utilizador, com o mesmo nome que usamos no sistema operativo, no meu caso eloi, mudar pelo vosso utilizador. Este utilizador será para um uso corrente da base de dados e assim evitar o uso do utilizador postgres (superuser) para as tarefas comuns.

Executamos o script adminpack.sql para adicionar novas funcionalidades a pgAdmin III.

Agora vamos criar uma base de dados espacial como modelo, com o nome de postgis, para a partir de esta poder criar outras bases de dados espaciais mais facilmente. Vamos adicionar-lhe a linguagem de programação plpgsql e executar dois scripts: postgis.sql que vai criar todas as funções de PostGIS e spatial_ref_sys.sql que criará a tabela spatial_ref_sys no esquema public com todos os Sistemas de Coordenados suportados.

Finalmente criamos a base de dados que vamos dar uso, a partir da base de dados modelo (postgis), que criamos no passo anterior. Com a opção -U definimos o dono e com -T (de template) definimos a base de dados modelo seguido do nome da nova base de dados, por exemplo geodatabase.

Instalação de gvSIG 1.9 em Ubuntu 9.10

Antes de proceder com a instalação de gvSIG verifica se existem versões mais recentes das extensões nesta pagina. As que de seguida menciono (Remote Sensing, Redes, Sextante, Topology e NavTable) são as mais actualizadas para a data de hoje (2010-02-19).

Descarga da aplicação e extensões.

Atribuir privilégios de execução aos ficheiros descarregados.

Instalar aplicação e extensões.

Instalar navTable.

Para criar um icon para arrancar gvSIG damos com o botão direito no fundo do escritório e escolhemos ‘Criar iniciador…’, preenchemos os campos Nome: gvSIG, Comando: /home/eloi/.gvSIG_1.9/bin/gvSIG.sh e Comentario: gvSIG 1.9. Para alterar o icon pulsamos na imagem da esquerda e pomos /home/eloi/.gvSIG_1.9/bin/ico-gvSIG.png. Alterar, convenientemente, a rota da pasta (/home/eloi/.gvSIG_1.9) onde foi instalada a aplicação.

Se usas Compiz, ou seja, os efeitos especiais de escritório, deves fazer a seguinte alteração.

E no fim do documento, numa nova linha, adiciona: export AWT_TOOLKIT=MToolkit
Guarda o ficheiro, reinicia a sessão e resolvido o problema.

Se desejas ajudar na tradução de gvSIG para o português de Portugal abre este documento de Google docs e edita-o livremente. Cerca de 67% das linhas já estão traduzidas, mesmo assim são bem-vindos colaboradores para terminar a tradução. Passa pelo glossário SIG de OSGEO se tens duvidas na tradução de alguma palavra.

Coverter imagens 0º 360º a -180 180º com GDAL

Um dia de estes estava a procurar dados para um trabalho que temos entre-mãos e deparei-me com umas imagens, as que necessitava, com os dados de 0º a 360º. Assim à primeira parece que está tudo bem e com lógica, o problema está em que por aqui gostamos de pôr a Europa no centro do mapa com os dados de -180º a 180º. Então seria necessário cortar a imagem pelo meio e a segunda metade mover-la para o lado esquerdo da primeira metade e voltar a juntar as duas partes. Parecia complicado, mas depois de googlear um pouco dei com a solução e deixo-vos aqui por se alguma vez vos passa o mesmo.

Screenshot1b

Supondo que GDAL está instalado vamos usar gdalinfo para conhecer o numero de colunas que a imagem tem.

Agora já sabemos que a imagem tem 144 colunas por 73 filas. Com gdal_translate cortamos e georeferênciamos a parte direita (este) e repetimos o processo para a parte esquerda (oeste) da imagem. Com o parâmetro -srcwin indicamos por onde cortamos imagem (coluna 72=144/2) e com o parâmetro -a_ullr a posição que queremos. No final juntamos as duas imagens com gdal_merge.py.

Este é o resultado.

Screenshot2b

Análise espacial com PostGIS IV

Por vezes temos tabelas com informação passível de ser georeferenciada, inclusivo com campos com as coordenadas, mas que carecem de geometria. Para criar um tema de pontos a partir das coordenadas da tabela (event layer) usamos a função MakePoint(x, y) de PostGIS. Da seguinte maneira.

Agora já podemos usar a tabela inicial como um tema numa aplicação SIG como gvSIG ou QGIS.

Análise espacial com PostGIS III

Uma das análises mais comuns em SIG é a intersecção entre temas e calcular a área resultante desta operação. Aqui deixo um exemplo de como o fazer com PostGIS. Neste exemplo temos os temas de Províncias (cartobase.es_ct_lim_admin_provincias) e Clima (restauracion.es_clima_allue) e queremos saber a superfície em Ha de cada uma as distintas classes de Clima por Província. O tema resultante será teste.allue_prov que no final exportamos para um ficheiro de texto plano separado por virgulas que poderemos abrir com Calc de OpenOffice ou outros programas do género. Por último apagamos o tema teste.allue_prov.

Análise espacial com PostGIS II

Outra análise que tive de efectuar com PostGIS foi a de calcular o vizinho mais próximo (nearest neighbor) de cada um dos municípios, mais concretamente, enumerar os municípios contíguos para a cada dos municípios.

Depois de googlear sobre o assunto encontrei mais de uma solução, faltava saber qual a que respondia exactamente ao que pretendia.

Com esta consulta apenas conseguia o primeiro dos municípios mais próximos, assim que foi descartada.

Esta consulta devolve todos os mais próximos para cada um dos municípios, até aqui tudo bem. Mas esta distância é calculada com base no bounding box (ou o menor rectângulo onde pode caber determinado polígono) de cada um dos polígonos. Isto significa que dois bounding box podem-se sobrepor ou ser contíguos mesmo quando os dois respectivos polígonos não o são. Descartado.

Esta consulta devolve os municípios com uma proximidade inferior a 100 m de um determinado município, apenas um. Devolvendo também a distancia (em metros) que os separa, quando esta é zero significa que são contíguos. A resposta é bastante rápida.

Único senão da anterior consulta é que a temos de repetir para cada um dos municípios. Com um pouco de Python automatizamos o procedimento.

Já temos o que pretendia na tabela public.municipios_vecinos. Agora só falta exportar os dados e eliminar a tabela.