Tag Archives: QGIS

Raster Overviews

Overviews GDAL em modo Turbo

Tempo de leitura: 7 min

TLDR: Neste post discutimos formas de acelerar o processo de criação de overviews, e no fim usamos um script que reduz o tempo de processamento em 20%-50%. O script é apresentado abaixo e está no github.

Na visualização de rasters é obrigatório construir as overviews ou pirâmides, para conseguirmos uma visualização rápida.

As overviews são uma série de cópias do nosso raster com resoluções cada vez menores (pixeis maiores), e geralmente cada nível aplica uma redução de 50% na resolução. Por exemplo, numa resolução original de 0,30m/pixel, as overviews são imagens com resoluções de 0,60 – 1,20 – 2,40m/pixel e assim sucessivamente até que não faz sentido reduzir mais a imagem.

Overviews ou pirâmides permitem uma visualização rápida de rasters, através de imagens de resolução reduzida. (Obitdo em: https://eurogeographics.org/wp-content/uploads/2018/04/WCS-NLSS.pdf.)

Em geral, a construção destas pirâmides é feito com o comando gdaladdo, e é o processo mais moroso quando processamos grandes áreas. Nem a conversão com compressão, nem a união de muitos rasters leva tanto tempo.

Actualmente, com discos SSD rapidíssimos e memória super-abundante, e processadores multi-core, o comando gdaladdo que constrói overviews continua a usar apenas 1 core… por outro lado, é mais lento que outros comandos, como o gdal_translate.

Recentemente processei novos mosaicos para o Alentejo, desta vez com ortofotomapas com 0,30m de resolução, rgb+nir. E, claro, construir overviews foi uma tortura… mais de 8h para cada metade (dividi a área em 2 blocos este/oeste). O processador nunca passou dos 17% (i7 de 4 cores/8threads), e o disco SSD nunca passou de uns miseráveis 5MB/s (quando o disco é capaz de 1000MB/s). Muito frustrante…

O processo que uso consiste sempre em manter os ficheiros independentes, e criar um mosaico .vrt. Por hábito não crio mosaicos tif enormes. Este processo é descrito em artigos anteriores.

Depois de pesquisar online, vi 3 sugestões para melhorar o tempo de criar overviews:

Isto ensinou-me uma série de coisas novas:

  1. Os ficheiros .ovr são na verdade ficheiros TIFF multi-página (herança do tempo dos faxes!), onde um tiff é “colado” a outro dentro do mesmo ficheiro. Eu não sabia isto sobre os .ovr. Ou seja, cada resolução é um tiff, dentro do ovr, que é também um tiff (matrioska?).
  2. É possível juntar vários tiff num só tiff multi-página usando o comando “tiffcp tiff1 tiff2 tiffunido”.
  3. O OSGEO4W inclui uma versão “geo-activada” dos comandos tiff, mantendo as características SIG dos ficheiros.
  4. Podemos ter overviews de overviews, juntando a extensão .ovr ao ficheiro .ovr anterior, numa sucessão que funciona em gdal, qgis, e arcgis. Deve funcionar nos restantes programas, como geoserver, mapserver, etc.

Teste

Vamos fazer um teste com uma série mais pequena de ortofotomapas, para vermos qual é a melhoria no tempo de criação de overviews: vamos usar 3 processos simultânos de gdal_translate, onde cada processo constrói um resample diferente (x2, x4, x8), e renomeando-os para terem extensão .ovr acrescida.

A nossa coleção de ortos de testes é constituída por:

  • 29 ficheiros 3 bandas x 8 bit, num total de 276MB, já comprimidos em tiff/jpeg, com 5km de lado, e 0,30m de resolução.
  • Um mosaico virtual .vrt com todos os 29 ortos, “teste_script.vrt”, com dimensão de 166.667 x 100.000 pixeis.
Quadrículas dos 29 ortofotomapas do nosso teste.

O método consiste em executar 3 comandos em simultâneo:

  • Processo 1: resample para 0,6m/pixel
  • Processo 2: resample para 1,2m/pixel
  • Processo 3: resample para 2,4m/pixel, mais construção de pirâmides para este resample apenas

Assim, no processo 1 teremos este comando:

gdal_translate -of gtiff -tr 0.6 0.6 -ro -r average --config GDAL_CACHEMAX 1024 -co photometric=ycbcr -co interleave=pixel -co tiled=yes -co compress=jpeg teste_script.vrt teste_script.vrt.ovr

Ou seja, construimos uma cópia do mosaico, em formato tiff, com 2x o tamanho do pixel original (0,6m/pixel) e damos o nome certo para que seja automaticamente reconhecido como overviews do original -> teste_script.vrt.ovr.

No processo 2, construímos um resample com 4x o tamanho do pixel (1,2m/pixel), e damos o nome que o faz ser reconhecido como overviews do 1º processo:

gdal_translate -of gtiff -tr 1.2 1.2 -ro -r average --config GDAL_CACHEMAX 1024 -co photometric=ycbcr -co interleave=pixel -co tiled=yes -co compress=jpeg teste_script.vrt teste_script.vrt.ovr.ovr  

No processo 3, construímos o 3º nível, com 8x a resolução (2,4m/pixel), e com um nome que o marque como as overviews do 2º nível:

gdal_translate -of gtiff -tr 2.4 2.4 -ro -r average --config GDAL_CACHEMAX 1024 -co photometric=ycbcr -co interleave=pixel -co tiled=yes -co compress=jpeg teste_script.vrt teste_script.vrt.ovr.ovr.ovr

Já que sabemos que este resample é muitíssimo mais rápido que o 1º, terminando por isso muito cedo, podemos aproveitar para criar pirâmides para este 3º nível. Isto permitirá termos a série completa de overviews no final:

gdaladdo -ro -r average --config GDAL_CACHEMAX 1024 --config COMPRESS_OVERVIEW JPEG --config PHOTOMETRIC_OVERVIEW YCBCR --config INTERLEAVE_OVERVIEW PIXEL  teste_script.vrt.ovr.ovr.ovr

O script faz uma série de correções aos nomes dos ficheiros caso detecte uma máscara externa, que é o caso do nosso teste (ficheiro .msk). Ficamos assim com os seguintes ficheiros:

      50 194 teste_script.vrt
  12 434 020 teste_script.vrt.msk
   6 003 920 teste_script.vrt.msk.ovr
   1 525 126 teste_script.vrt.msk.ovr.ovr
     395 087 teste_script.vrt.msk.ovr.ovr.ovr
     267 858 teste_script.vrt.msk.ovr.ovr.ovr.ovr
 466 889 237 teste_script.vrt.ovr
 116 024 726 teste_script.vrt.ovr.ovr
  32 529 152 teste_script.vrt.ovr.ovr.ovr
  11 135 760 teste_script.vrt.ovr.ovr.ovr.ovr
               10 File(s)    647 255 080 bytes

O tempo de execução foi de 06:47,4 min. E podemos ver a ocupação de CPU, disco e memória muito mais altos:

E funciona? Vamos a ver…

gdalinfo teste_script.vrt
 Driver: VRT/Virtual Raster
 Files: teste_script.vrt
        teste_script.vrt.ovr
        teste_script.vrt.ovr.ovr
        teste_script.vrt.ovr.ovr.ovr
        teste_script.vrt.ovr.ovr.ovr.ovr
        teste_script.vrt.msk
        230_060_irg.tif
        230_065_irg.tif
...  ...  ...  ...  ...
Size is 166667, 100000
 Coordinate System is:
... ... ... ... ...
Band 1 Block=128x128 Type=Byte, ColorInterp=Red
   Min=0.000 Max=255.000
   Minimum=0.000, Maximum=255.000, Mean=109.688, StdDev=100.399
   Overviews: 83334x50000, 41667x25000, 20833x12500, 10417x6250, 5209x3125, 2605x1563, 1303x782, 652x391, 326x196, 163x98
   Mask Flags: PER_DATASET
 ...  ...  ...  ...  ... 

O gdalinfo reconhe todas as pirâmides. E o QGIS?

Identificação das overviews pelo QGIS.

Pequeno à parte: Já em artigos anteriores referi que o QGIS tem de ser “convencido” a ler máscaras externas. Isto não causa problemas ao processo. Aparentemente, o GDAL tem um comportamento diferente com máscaras externas, em que as expõe com valores 0/1, em vez de valores 0/255 como acontece com máscaras internas. Sem esta correção a máscara não é detectadas correctamente pelo QGIS, e temos de a ignorar, aparecendo as zonas pretas sem dados. Se corrigirmos editando o vrt, tudo aparece correctamente. Mas em qualquer dos casos as overviews funcionam:

QGIS e overviews em ação, velocidade real.

Com o gdaladdo “normal”

Para compararmos, vamos criar overviews com o processo normal:

timing "gdaladdo --config GDAL_CACHEMAX 1024 --config COMPRESS_OVERVIEW JPEG --config PHOTOMETRIC_OVERVIEW YCBCR --config INTERLEAVE_OVERVIEW PIXEL teste_gdaladdo.vrt"
14:52:45,10
a executar o comando indicado: "gdaladdo --config GDAL_CACHEMAX 1024 --config COMPRESS_OVERVIEW JPEG --config PHOTOMETRIC_OVERVIEW YCBCR --config INTERLEAVE_OVERVIEW PIXEL teste_gdaladdo.vrt"
0…10…20…30…40…50…60…70…80…90…100 - done.
0…10…20…30…40…50…60…70…80…90…100 - done.
15:01:17,19

Assim, o processo normal demorou 08:32,1 min.

E os ficheiros deste processo normal são:

      50 194 teste_gdaladdo.vrt
  23 195 175 teste_gdaladdo.vrt.msk
 827 911 591 teste_gdaladdo.vrt.ovr
  3 File(s)    851 156 960 bytes

Nota: este vrt tem uma máscara externa .msk. Como me esqueci do parâmetro -ro (readonly), as overviews da máscara foram adicionadas ao próprio msk. Também me esqueci do método resample average, que seria mais lento…

Comparação

O processo de construir overviews em paralelo, divido em 3 processos simultâneos, é 20% mais rápido, e ainda com um bónus de ocupar menos 23% em disco! (não sei porquê)

MétodoTempoTamanhoDiscoCPURAM
gdaladdo normal 08:32,1 850MB5MB/s15%1GB
gdal_translate x3 06:47,4 647 MB19MB/s45%3GB

Ou seja, conseguimos subir o uso do CPU para 45%, e o disco para 19MB/s. Nada mau. A memória ocupada pelo processo depende do uso que fizermos da flag –config GDAL_CACHEMAX. No nosso caso, definimo-la como 1GB. Logo 3 processos ocupam obviamente 3x esta quantidade.

O ganho de velocidade resulta do processamento em simultâneo – enquanto se processa o 1º nível, processam-se logo os restantes e as máscaras também desses níveis caso exista máscara no raster original.

Script

Numa tentativa de automatizar o processo, criei um script bat para windows. Pode ser obtido aqui: https://github.com/dncpax/Turbo_GDAL_Overviews .

Algumas notas interessantes sobre o bat:

  • É possível imitar uma execução em background usando “start /b” dentro do bat.
  • A shell DOS só faz aritmética de inteiros, por isso temos de indicar as 3 resoluções que queremos – x2, x4 e x8 – porque em geral não são inteiros e não os conseguimos calcular no bat.
  • Usamos DELAYEDEXPANSION porque precisamos de mostrar o tempo de execução.
  • Temos de renomear os ficheiros resultantes da máscara externa (.msk) porque ficam com nomes que impedem o seu reconhecimento. O script trata disso com uma série de renames.

A migração para Linux deve ser fácil, porque 80% do script é só validação de argumentos. O que interessa são comandos gdal. Voluntários procuram-se…

Para executar indicamos o raster e as 3 resoluções iniciais das overviews:

turbo_overviews.bat teste_script.vrt 0.6 1.2 2.4  
Inicio em: 13:29:24,69  
Input file size is 166667, 100000  
Input file size is 166667, 100000  00
Input file size is 166667, 100000  
0…10…20…30…40…50….60…70…..80…..9010….100 - done.  
..0…10…20…30….40…50…60…70…80…90.20..100 - done.  
0…10…20…30…40…50…60…70…80…90….100 - done.  
10..30…..40…20..50…..6030…..70…40.80…..90…50.100 - done.  
…60…70…80…90…100 - done.  
Fim em: 13:36:12,07

Conclusões

Se calhar este post é optimista: só fiz 1 teste sério… pode ser o caso de não funcionar mais vez nenhuma ;)…

Para mim é realmente estranho a falta de processamento multi-core no GDAL. Talvez seja uma questão de tempo, mas já se sente a falta. O que existe é muito incipiente e apenas funciona em cenários que não me são aplicáveis (e.g. compressão DEFLATE).

Há mais alternativas a este processo, mas nos testes que fiz não tive tão bons resultados.

Há outros programas que podem fazer resample de imagens e com processamento multi-core, como o imagemagick. Isto obrigará a copiar a georeferenciação para as imagens resultantes porque estes programas não reconhecem a componente SIG das imagens. Mas pode ser interessante.

De qualquer forma, por agora, este processo parece funcionar bem. Falta testar com um mosaico “à séria”. Pode ser que os 20% de maior rapidez se confirmem!

Até breve!

Adenda

Teste com um mosaico um pouco maior…

Este mosaico é similar mas maior: tem uma dimensão de 233.334 x 383.334 pixeis, em 258 ficheiros, num total de 10,3GB. Demorou 41:38,2 min, em vez de 01:35 h com o GDAL v.3.0.4 (na v2.3.0 tinha demorado 08:42:33 h) do gdaladdo… Ou seja, um ganho de 56%!

Observámos uma ocupação do disco interessante: mais de 60MB/s…

Mosaico maior em construção…

Os tamanhos foram similares: 4.4GB vs 4.9GB.

E correctamente visualizado em QGIS:

Mosaico de 10GB com overviews criadas em 40min…

Neste mosaico mais encorpado, a melhoria é enorme… Curioso em ver a aplicação em mosaicos muito maiores.

Medir o desempenho do PostGIS

Tempo de leitura: 6 minUma das formas de medir o desempenho do PostgreSQL no nosso servidor, é usar o pgbench, a ferramenta padrão incluída com a instalação do pgsql. Há tempos fiz uns testes de comparação de 2 servidores que publiquei aqui: http://blog.viasig.com/2014/08/medir-o-desempenho-do-postgresql/.

Ora, esses testes usam dados alfanuméricos e queries “normais”, de escrita e leitura, usando tabelas relacionadas. Ou seja, o pgbench tenta simular uma utilização usual do pgsql.

No nosso caso, SIGianos, a utilização usual não tem nada a haver – usamos dados espaciais e queries muito próprias. Este artigo mostra uma forma de medirmos o desempenho do PostGIS, usando também a ferramenta pgbench.

Uso “normal” de SIG

Quando um programa “normal”, não geográfico, consulta uma base de dados, em geral, obtém alguns registos, e pode até cruzá-los, para dar um resultado final. Provavelmente, apresenta uma tabela de resultados, paginados, com algumas colunas (menos de 10?). Um bom exemplo, é um programa de facturação ou de gestão de stocks. É este tipo de programas que o pgbench tenta simular.

Há uma enorme diferença para o uso que um programa de SIG faz de uma base de dados. O uso normal SIG é visualizar um mapa. E isso faz toda a diferença.

image

Este simples mapa de enquadramento usa 7 tabelas. A área visível usa um total de 618 registos (1+261+177+1+3+29+146). Se visualizarmos o país inteiro, a conta passa para 5841 registos. É muita informação para uma das operações mais básicas – pan e zoom.

Do ponto de vista da base de dados, o uso SIG é diferente:

  • Um mapa é, tipicamente, composto por diversos temas (facilmente mais de 10);
  • Cada tema é uma tabela espacial diferente na base de dados, logo em cada visualização vamos ler uma série de tabelas;
  • Cada tema/tabela pode ser lido na totalidade (não paginado) se visualizarmos toda a área do tema;
  • Cada tema/tabela pode ter aplicada uma selecção (filtro) logo de início com base nos atributos (e.g. para vermos apenas uma categoria de rios ou estradas);
  • Cada tema/tabela pode ainda ter aplicado um filtro espacial se estivermos a visualizar apenas uma área específica (ou seja, são apenas pedidos os dados relativos ao rectângulo visível no mapa);
  • Mas, principalmente, os dados geográficos são muitos mais “pesados” ou “gordos”: têm uma coluna que contém todos os vértices da geometria! (Cada vértice tem 2 números do tipo double, o que equivale a 2 colunas em dados alfanuméricos.)
  • Para agravar a coisa, os utilizadores nunca escolhem os campos que precisam para trabalhar, e assim quando abrem a tabela de atributos todos os campos são lidos.

Usar o pgbench para simular utilizadores SIG

Uma das capacidades do pgbench é que permite testar queries à base de dados feitas por nós, em vez de usar as pré-definidas. Basta criar um ficheiro sql que contém as nossas queries e passá-lo ao pgbench com o parâmetro –f.

É esta capacidade que usamos para simular queries espaciais e medir o desempenho em Transações por Minuto (TPS), tal com se faz para uma base de dados não espacial.

Assim, configuramos o PostgreSQL para que guarde no log todas as queries que recebe. Depois usamos o QGIS com um mapa típico que utilizamos frequentemente, e fazemos zoom a diversos locais e com diferentes escalas. A partir dos logs do PostgreSQL obtemos as queries SQL de cada zoom, e criamos um ficheiro .sql para cada zoom.

Em resumo, no nosso exemplo, obtivemos 10 ficheiros zoomN.sql que correspondem a 10 visualizações no QGIS do mesmo mapa, a escalas diferentes: zoom1.sql, zoom2.sql, … até zoom10.sql. Ou seja, um ficheiro .sql equivale a 1 mapa:

zoom1 – 1:1M                                                        zoom2 – 1:288.000

imageimage

zoom3 – 1:72.000                                                        zoom4 – 1:18.000

imageimage

Cada visualização criou um ficheiro .sql que podemos usar no pgbench, e simular vários utilizadores simultâneos de QGIS. Aqui,há uma simplificação: cada zoom é feito instantaneamente a seguir ao outro. Ou seja, vamos simular super-utilizadores! Piscar de olho que não fazem pausas entre zooms e pans.

O comando para simular 12 super-utilizadores que fazem 10 zooms/pans é o seguinte:

pgbench -f zoom1.sql -f zoom2.sql -f zoom3.sql -f zoom4.sql -f zoom5.sql -f zoom6.sql -f zoom7.sql -f zoom8.sql zoom9.sql zoom10.sql  -h <servidor> –U <user> -n -l -c 12 -j 2 -T 180 postgis

image

Tal como no artigo anterior sobre pgbench, o significado dos parâmetros é:

  • -n = não fazer vacuum aos dados, porque estamos a usar a bd de produção;
  • -l = log de tempos para um ficheiro;
  • -c 12 = simular 12 conexões simultâneas, ou seja, 12 utilizadores de SIG;
  • -j 2 = simular 2 threads por conexão (pouco impacto tem);
  • -T 180 = simular durante 180 segundos (3min);

Os resultados são:

transaction type: Custom query
scaling factor: 1
query mode: simple
number of clients: 12
number of threads: 2
duration: 180 s
number of transactions actually processed: 4004
tps = 22.148347 (including connections establishing)
tps = 22.188888 (excluding connections establishing)

O que quer isto dizer?

O que interessa é o valor final de 22.18 tps. Isto significa que o nosso PostGIS consegue responder a um ritmo de 22,18 mapas por segundo, em média. Ou seja, deviamos dizer 22,18 MPS (maps per second) Piscar de olho

Este valor é a média para todas as escalas que utilizámos no teste. Podemos testar cada escala em separado, e obter desempenhos por escala. Num outro teste usando dados do OpenStreetMap, fizemos este gráfico:

image

Obviamente, quanto maior a escala, maior o detalhe, e, geralmente, menos dados. Logo, à escala 1:1M temos um poder de processamento de 1,51 MPS, e à escala :1:5600 temos 112,92 MPS.

O que interessa nisto tudo é que podemos comparar agora entre servidores diferentes de PostGIS, e entre configurações diferentes num servidor, para determinarmos a melhor configuração.

Notem que este teste elimina o factor QGIS, ou seja, não se considera o desempenho do QGIS a desenhar o mapa. Uma vez que convertemos cada vizualização num ficheiro .sql, ao executar o teste só usamos o ficheiro .sql. Assim, o desempenho do QGIS não entra na equação, o que é necessário se queremos medir o desempenho do servidor PostGIS.

Outras questões de desempenho

Ao testar o desempenho do PostGIS, acabamos por nos apercebermos de alguns factores que influenciam e muito os resultados e o desempenho observado de um servidor PostGIS.

Por exemplo, se durante o teste verificarmos o que se passa no servidor, podemos ter algumas surpresas:

beja084_2

(Sim, eu sei… é windows…)

O CPU esteve a 91%, para conseguir responder aos nossos 12 QGIS simulados. É perigoso andar tão perto dos 100%, porque o desempenho começa a diminuir. Aqui temos de jogar com o n.º de conexões. Neste caso, baixar de 12 para 10 conexões simultâneas até poderia dar resultados melhores. Cada servidor terá o seu n.º de conexões para o qual se obtém o máximo de tps. Temos de experimentar vários valores e ver o melhor.

Os valores de memória apresentados no Task Manager são inúteis, porque a memória ocupada está sempre perto dos 100%. Teríamos de fazer outro tipo de análise.

Já a ocupação de rede é interessante: é enorme! 769 Mbps! É muito fácil limitar o desempenho do PostGIS por causa de uma má ligação de rede entre o PostGIS e os utilizadores. Se compararmos com o teste de queries “normais” não espaciais, vemos que a ocupação de rede é apenas de 22 Mbps (para o total das 12 conexões simultâneas).

image

Outra questão importante para os resultados dos testes é observar o estado do PC onde corremos o pgbench, principalmente quanto à ocupação do CPU: como o pgbench corre num só processo ocupa só 1 core, e podemos facilmente limitar os resultados porque o nosso CPU não consegue responder. Temos de verificar durante os testes se o processo pgbench.exe ocupa MENOS que 1 core. No meu caso, usei um i5, que tem 4 cores. Logo, o pgbench tinha de ocupar menos de 25% de cpu para que os resultados fossem bem medidos.

Conclusão

Usar o pgbench com dados espaciais dá-nos uma excelente forma de testar o desempenho do PostGIS. Podemos perceber qual o melhor servidor, se físico, se virtual, para o nosso caso particular. Podemos ainda testar configurações alternativas do PostgreSQL e identificar aquela que dá melhores resultados.

Melhor ainda, será criar um pacote de dados OSM e os scripts .sql correspondentes, e usá-los para termos um teste padrão de PostGIS. Se todos usarmos estes dados vamos conseguir partilhar resultados entre toda a comunidade. Hmmm, temos de pensar nisto…

Mosaicos com áreas transparentes

Tempo de leitura: 9 minNeste artigo regresso a um assunto já familiar neste blog – criar mosaicos de ortofotomapas usando o GDAL – (sim eu sei, outra vez?) mas como tenho andado às voltas com as áreas sem informação, que surgem negras nos mosaicos pensei em postar o que acabei por fazer. A solução final é usar máscaras, e não bandas alfa como habitual. Vamos ver como e porquê… assume-se já alguma familiaridade com o GDAL, mas pode sempre saltar as partes teóricas aborrecidas e ver os comandos usados no final do artigo 😉 Ler artigo completo

QGIS – Revisitando ficheiros DXF

Tempo de leitura: 3 minO QGIS há muito tempo que lê ficheiros DXF ASCII, aproveitando sempre os melhoramentos que a biblioteca OGR vai trazendo com as novas versões.

Estando a planear introduzir o QGIS na empresa de forma generalizada, tive que revisitar esta função, dado que ler CAD é uma função essencial para muitos utilizadores.

Update 2013-06-05: O problema já foi resolvido. A versão de desenvolvimento já permite abrir ficheiros dxf e escolher que tipo de geometria queremos carregar. Realmente, trabalhar assim é uma maravilha.
Ler artigo completo

PostgreSQL e ESRI – parte 4

Tempo de leitura: 6 minO subtítulo deste artigo devia ser “O bom, o mau e o péssimo”…

Depois de ter respondido a um comentário que me perguntava sobre a nossa experiência em curso de migrar para PostgreSQL, pensei em melhorar a resposta e fazer um artigo – a maior parte da escrita já estava feita de qualquer forma 😉

Responder ao comentário levou-me a pensar mais um pouco sobre a questão… e uma parte que me parecia pouco clara é o porquê de fazermos a migração para PostgreSQL (pgsql prós amigos) e porquê insistir em usar geometrias PostGIS (geometrias pg)? Só para recordar: a ESRI permite 2 formatos de armazenamento das geometrias nas bases de dados que suporta – ou no formato ESRI (que chamou de ST_Geometry) ou no formato “nativo” da bd.
Ler artigo completo

QGIS e conflitos com DLLs Qt

Tempo de leitura: 2 minEste curto artigo serve como memória para mim e pode ser que seja útil a quem também tenha o mesmo problema…

Como uso o Cartão do Cidadão tenho instalado o software respectivo. Este coloca na pasta \windows\system32 algumas DLLs de Qt que necessita. Inicialmente pensei que seria um bocado desleixado dos autores colocarem aqui e não na pasta do programa, mas hoje penso que será uma necessidade para permitir que o Internet Explorer possa usar a autenticação do CC em sites como os de contratação pública.

O problema é que o QGIS usa também o Qt (pacote de programação de interfaces gráficas), e instala de forma bem comportada, as DLLs que precisa na sua própria pasta. Sucede que o Windows carrega primeiro as DLLs que encontra na pasta system32

Como o Windows encontra as mesmas DLL’s na pasta system32 carrega estas, que são de uma versão mais antiga, em vez das que são incluídas no QGIS. O resultado é um erro críptico de “entry point not found”…

 

QGIS: Missing Entry Point
QGIS: Missing Entry Point

A solução que tinha encontrado inicialmente era simples: retirava as DLL’s do CC da pasta system32 sempre que usava o QGIS. E voltava a colocá-las lá quando queria usar o CC… very boring…

Mas há outra solução. O Windows obedece a uma ordem de pesquisa de DLL’s e sucede que a pasta onde se encontra o executável é procurada antes da system32. Assim, no caso do QGIS 1.7  basta copiarmos as DLL’s do Qt da pasta C:\OSGeo4W\bin para a pasta C:\OSGeo4W\apps\qgis\bin. E fica resolvido para todo o sempre, amen.

QGIS e CAD

Tempo de leitura: 9 minOs ficheiros CAD são uma das principais fontes de dados para um SIG.  Este artigo analisa as possibilidades actuais de lidar com CAD no Quantum GIS.

CAD e SIG

Existe uma rivalidade antiga entre quem trabalha com software CAD e quem trabalha com software SIG – é comum ouvirmos dizer coisas como “o CAD é menos avançado”, ou “os tipos do SIG têm a mania de complicar as coisas”, entre outros mimos. Na realidade CAD e SIG são ferramentas usadas para fazer coisas diferentes, com métodos de trabalho diferentes, e que (infelizmente) têm de conviver de forma muito próxima, sem se compreenderem muito bem… (Aviso: tentei ser isento, mas acho que desisti a meio do texto…)

Simbologia é informação

No CAD esta afirmação é verdadeira. No SIG não.

No CAD eu desenho os meus elementos gráficos com o objectivo principal de obter uma visualização – para ver no monitor ou para imprimir. Quanto mais produtivo for a criar a minha visualização melhor técnico CAD serei. Os elementos que crio no ficheiro CAD representam exactamente o que preciso de ver: uma árvore é constituída por uma copa, um poste de iluminação tem um pé e uma lâmpada, uma área ajardinada tem vários pequenos arbustos. Eu posso seleccionar cada um destes elementos e alterá-los para obter a visualização exacta que pretendo. Quando gravo um DWG ou um DGN gravo tudo isto – uma linha com dada cor, espessura, tipo de tracejado – gravo no ficheiro as geometrias que são também a simbologia em simultâneo. A estrutura do meu desenho é constituída pela forma como eu organizo os meus elementos por camadas (layers ou levels), e como crio os meus elementos (blocos ou elementos simples).

No SIG a situação é muito, muito semelhante. Mas 2 ligeiras diferenças são suficientes para tornar o diálogo entre as equipas CAD e SIG difícil e por vezes até antagónico.

1) No SIG eu desenho apenas geometrias. Recolho vértices XY. E recolho características das geometrias, que armazeno em atributos. Todas as geometrias que recolho num ficheiro têm sempre os mesmos atributos, e por isso descrevo-as de forma sistemática, formando uma tabela. Não há simbologia envolvida no processo. Ao gravar o trabalho num ficheiro de dados, guardo apenas vértices XY e atributos, sendo uma das razões por que grande parte do trabalho é focada em organizar informação, em decidir que atributos cada ficheiro terá. Mas esta obsessão organizativa vai mais longe! Cada ficheiro tem apenas um tipo de geometria – ponto, linha ou polígono – que nunca se misturam no mesmo ficheiro.

2) No SIG a simbologia é aplicada por regras a um ficheiro – não se define a simbologia de um só elemento. Usam-se os atributos para seleccionar um conjunto de geometrias a que depois aplicamos uma certa simbologia. Por exemplo, podemos representar especificamente as cidades com população maior que 1 milhão de habitantes como círculos pretos, as restantes cidades com um quadrado.  Se todos os pontos que são as cidades tiverem um atributo com a sua população, o software SIG aplica esta simbologia facilmente. Uma consequência desta abordagem à simbologia é que passa a ser dinâmica. Se quisermos alterar a simbologia, não alteramos as geometrias – alteramos as regras da simbologia. Para guardar a simbologia usam-se ficheiros de projecto, que não têm dados, apenas regras e definições de como representar a informação e como a imprimir (formato da página, orientação, seta do norte, título, ou seja, o layout).

cad_carto_thumb[1] sig_carto_thumb[1]
CAD SIG

Exemplo de informação CAD original, e quando convertida para SIG.

Então qual é o problema?

Como dizem os políticos, ainda bem que fez essa pergunta…

Pois é, o problema é na conversão de CAD para SIG. Este é um assunto muito extenso e interessante, mas como é Verão apetece mais uma bejeca… 🙂 Mas ainda consigo lembrar-me de 3 grandes problemas nesta conversão:

1) Seleccionar num ficheiro CAD elementos que têm o mesmo significado é geralmente difícil. Se todos pontos que são as cidades estiverem num único layer, e nesse layer não existir outro tipo de pontos, então a sua selecção é facílima. Mas isso raramente acontece… geralmente elementos gráficos com diferentes significados coexistem no mesmo layer.

2) Determinar a posição correcta de um elemento é muitas vezes difícil – a cidade está no ponto de inserção do bloco, ou é o ponto central do bloco? O ponto cotado é o ponto de inserção, ou é a virgula decimal do texto da cota? E aqui junta-se a dificuldade de evitar as tramas ou “hatches”. (As tramas são linhas que representam simbologia mas não representam uma entidade no terreno. Geralmente aplicadas a polígonos, servem de arranjo gráfico, e não devem ser convertidas para SIG.) Outro exemplo são marcas quilométricas em eixos de infra-estruturas… no CAD são importantes, no SIG são considerados erros de conversão. Outro grupo de problemas pode ser aqui incluído – questões como converter linhas fechadas do CAD para polígonos no SIG, reconhecer vazios, e outras questões semelhantes…

3) E finalmente, recolher atributos juntamente com as geometrias é muitas vezes… … … difícil (novamente)! e para o SIG os atributos são fundamentais. Por exemplo, qual é a cota de cada ponto cotado ou curva de nível? Ou qual é o nome de cada eixo de rua? A verdade é que já foi feito o trabalho de recolha e digitalização desta informação pela equipa CAD, mas mesmo assim não é possível muitas vezes usá-la num SIG (ou noutro sistema qualquer). No CAD, o texto que mostra o nome de uma rua é uma entidade gráfica  independente da linha, e por isso não existem métodos automáticos fiáveis para associar cada linha a cada texto. A não ser que se crie o ficheiro CAD já com a preocupação de permitir este tipo de interoperabilidade, e assim avançamos para tópicos de CAD avançados que (na minha experiência) escapam à maioria dos desenhadores.

Então e agora?

Pois é… agora estamos todos numa grande alhada. Ao fim de dias a tentar converter ficheiros CAD, o pessoal do SIG está pronto a abraçar uma vida de crime, começando por cometer uma série de homicídios lá para as bandas do CAD.

A única solução é conhecer bem o software que usamos. Com o tempo vamos aprendendo as técnicas que o software suporta para conseguir conversões cada vez mais automáticas. Mas tudo depende dos ficheiros originais CAD. E é muito importante poder contar com alguém no “lado” CAD que possa alterar os ficheiros CAD de forma a facilitar o processo de conversão.

Outra via de facilitar a vida a todos os técnicos envolvidos num processo que passe por CAD e SIG, é estabelecer regras para os ficheiros CAD que facilitem depois um processo menos manual de conversão. E isso novamente vai depender da informação em causa, e do tipo de AutoCAD em uso (“normal”, Map, Civil…). Por exemplo, no AutoCAD Map podemos criar Object Data, Object Class, ou até ligar os nossos elementos gráficos a tabelas de atributos externos, mas em AutoCAD “simples” isso já não é possível…

Portanto, não há regras infalíveis. Cada caso é um caso, como se diz. Mas há regras de bom senso que resultam sempre bem – agrupar elementos gráficos com o mesmo significado num só layer é uma dessas regras: só eixos de via num layer, e todos os eixos de via estão nesse layer (não há outros tantos eixos noutros tantos layers); cada layer tem um nome claro e intuitivo (nada de layers com nomes do tipo “ev_de” – que quereria dizer “eixos de via do distrito de évora”…); para layers de polígonos criar também o respectivo layer de anotação ou blocos de atributos (onde também marcamos os vazios), e outras regras deste género. Bom senso é muito subestimado hoje em dia…

QGIS

E finalmente chegamos à parte principal do artigo, que originou o seu nome…

O QGIS usa como leitor de dados as bibliotecas do GDAL (imagens) e OGR (vectores). Este facto não é muito visível para o utilizador, mas é importante para compreender as capacidades do QGIS. Estas bibliotecas têm drivers que são responsáveis por cada formato que o GDAL/OGR suporta. No caso de ficheiros CAD só 2 formatos são suportados – DXF e DGN. Está já pronto um novo driver para DXF e que lê também DWG, mas ainda não é incluído no QGIS (nem mesmo na versão 1.5 a lançar já em Julho).

O caso DXF

O OGR converte DXF para qualquer outro formato que suporte, como o shapefile. E mantém alguns atributos, como o layer, o que é muitas vezes suficiente para converter e organizar a informação CAD. Mas enquanto o QGIS não usar uma versão de OGR que inclua o driver DXF não vamos conseguir ler estes ficheiros directamente no QGIS. Temos assim de usar comandos de linha…

Assim, para evitar usar a linha de comandos do OGR, podemos fazer esta conversão no QGIS usando o plugin Dxf2Shapefile (incluído na instalação do QGIS). Mas surpreendentemente este plugin não mantém quaisquer atributos quando converte ficheiros DXF, e ficamos com pontos, linhas e polígonos sem sabermos o que representam. O que é muito desapontante.  A sua utilização é muito fácil, mas os resultados são pobres dada a flagrante ausência de atributos.

image

Conversão de DXF para Shapefile no QGIS – perdem-se os atributos.

O caso DGN

Há uma outra opção – o QGIS lê directamente ficheiros DGN, e carrega-os para o mapa sem ser necessário uma conversão prévia. E melhor ainda, vários atributos são visíveis, e assim, tendo o ficheiro CAD no nosso mapa, podemos aplicar selecções de acordo com o level (equivalente ao layer dos DXF), e gravar para ficheiros shapefile.

image

O QGIS consegue ler DGN directamente e mantém atributos como o level, permitindo fazer selecções e gravar para shapefile.

Uma surpresa é que o DGN é carregado com todas as geometrias misturadas num só tema. O que é invulgar. Temos de nos habituar a esta ideia e encontrar forma de filtrar cada tipo de geometria para as conseguirmos separar e exportar para shapefile. Isto é, vamos criar um filtro (Query) no QGIS para ficar apenas com pontos, e exportá-los para um shapefile. E fazemos o mesmo depois para isolarmos as linhas e os polígonos.

Como o QGIS usa o OGR para ler ficheiros DGN, basta uma consulta à página do driver DGN do OGR, para ficarmos a saber quais os atributos a que temos acesso com ficheiros DGN. E vemos que o atributo “Type” indica o tipo de geometria:
Line (3): Line geometry.
Line String (4): Multi segment line geometry.
Curve (11): Approximated as a line geometry.
B-Spline (21): Treated (inaccurately) as a line geometry.
Arc (16): Approximated as a line geometry.
Ellipse (15): Approximated as a line geometry.
Shape (6): Polygon geometry.
Text (17): Treated as a point geometry.

Ou seja, para no QGIS seleccionar todas as linhas num DGN, podemos usar a seguinte query (usando a opção “Query” no menu de contexto do tema DGN, acedido clicando com o botão direito sobre o tema DGN):

Type = 3 OR Type = 4 OR Type=11 OR Type = 21 OR Type = 16 OR Type = 15

image

No QGIS filtramos o DGN com uma query, para isolar um só tipo de geometria (ponto, linha ou polígono).

Depois de fazer a query todos os elementos que restam visíveis no QGIS serão linhas, e podem ser gravados para um shapefile usando a opção “Save as” do menu de contexto do tema.

Depois de termos a informação dividida por 3 shapefiles, um por tipo de geometria, podemos então fazer selecções por level para tentar isolar objectos com determinados significados.

Na verdade nem é preciso exportar para shapefile. Podemos simplesmente carregar o ficheiro DGN, filtrar as geometrias, e aplicar depois a simbologia que queremos. Será necessário converter quando, por exemplo, quisermos converter uma série de ficheiros DGN  num único shapefile com toda a informação (ou para outro formato como PostGIS ou SpatiaLite).

O caso DWG

Este é o pior formato de informação geográfica do mundo. Ponto.

Além de ser alterado a cada 3 anos, é completamente fechado, isto é, para poder ler e escrever este formato é necessário pagar a terceiros, como a Autodesk ou a Open Design Alliance. A propósito da ODA e da má fama do DWG, podem ler esta novela espantosa relatada pelo 1º presidente desta ilustre fundação. Mas pode ser que as coisas estejam a mudar. Recentemente, a ODA chegou a acordo com a Autodesk e lá resolveram as disputas sobre marcas comerciais, e por coincidência (ou não) em Junho publicaram as especificações actualizadas que desenvolveram para ler e escrever DWG. É melhor aproveitar e fazer o download, não vá a situação alterar-se… Estas especificações têm sido insuficientes para criar programas que consigam escrever ficheiros DWG válidos, mas pelo menos para ler estes ficheiros já foram suficientes. Esta nova actualização não sei se virá alterar esta situação, mas terá nova informação sobre o formato DWG 2010…

Não vou alongar-me mais sobre o formato, interessa apenas frisar que até agora o software Open Source teve de criar bibliotecas para ler (ou escrever) ficheiros DWG fazendo um enorme esforço de “reverse engineering”. Que além de ser um trabalho muito pouco interessante, tem de ser revisto a cada 3 anos.

Assim, o QGIS não lê DWG. É possível que o venha a fazer no futuro próximo, havendo avanços no OGR nesse sentido. A ver vamos…

Mesmo a terminar este assunto, tenho de referir que o gvSIG lê DWG até à versão 2004…

Conclusão

Dadas as dificuldades actuais de interoperabilidade do formato DWG, este não é viável de momento com QGIS.

A opção DGN é muitíssimo funcional, e até muito fácil de trabalhar no QGIS. Para utilizadores de Microstation é óptimo. Para utilizadores de AutoCAD há a possibilidade de exportar para DGN a partir do AutoCAD 2008. Para os outros produtos baseados em DWG/DXF já não se pode dizer o mesmo.

Finalmente, o formato DXF é de momento uma má opção, a não ser que façamos a conversão pela linha de comando do OGR para shapefile ou semelhante. Mas espera-se em breve ter no QGIS um suporte ao nível do DGN. Mesmo assim, também obriga à exportação para DXF (a partir do formato CAD nativo), sendo um passo extra que é mais uma pedra na engrenagem para os técnicos CAD.

Se souberem de outras possibilidades aproveitem a secção de comentários.

Até breve.