quarta-feira, 30 de dezembro de 2009

PyDev e QGIS

Bom, continuando os estudos com o PyDev, recentemente descobri como fazer para o PyDev debugar plugins do QGIS.
A teoria que viabiliza isso é o Remote Debugger. O PyDev inicia um servidor de debug. O seu plugin deve então se conectar ao servidor de debug e avisá-lo que está pronto para ser debugado. O resto é com o PyDev.

Vamos ao passo-a-passo. Primeiramente, vamos fazer o nosso código passar a avisar o servidor de debug do eclipse. Na linha 3 inserimos o plugin do pydev (onde está o arquivo "pydevd.py" no pythonpath para poder ser importado pelo script. Caso sua instalação não esteja no mesmo lugar, deve-se alterar essa linha.
No restante do código chamamos o servidor de debug e dizemos para ele ficar observando este código.



Agora toda vez que executarmos nosso script python o próprio script irá procurar o servidor de debug do eclipse e avisar que ele está sendo executado e que deseja ser debugado.Note que se o servidor não estiver ligado seu programa não funcionará.
Para podermos acompanhar do eclipse o nosso script, abrimos o Eclipse, vamos a perspectiva de DEBUG,e apertar o botão de iniciar o Debug Server.

A partir deste instante, quando o nosso script tentar achar o debug server, ele vai reconhecer aqui tudo que está acontecendo. Pode-se então definir breakpoints e testar passo a passo, observando o comportamento de cada variável.

Espero que seja útil.

sábado, 26 de dezembro de 2009

E viva o PyDev

Continuando o assunto do último post, reporto minhas recentes experiências com o Eclipse PyDev.

Ressaltei que a flexibilidade de interpretadores do PyDev era uma característica muito forte. Ele independe completamente de instalação do Python, portanto você pode escolher qual vai usar em cada projeto. Isso se faz particularmente útil com instalações do Osgeo4W.
Este instalador se encarrega de facilitar a instalação de grande parte dos softwares livres para geociências. Com ele é fácil manter seu Quantum GIS e GRASS atualizados. Uma grande dificuldade, porém, é controlar a diferença entre o Python que vem com o Osgeo4W e os outros Pythons que instalamos. O ideal, na maioria dos casos, é utilizar o Python do Osgeo4W.

Bom, para o usuário final, basta criar um arquivo ".bat" que chame as variáveis de ambiente do Osgeo4W. O script "C:\OSGeo4W\bin\o4w_env.bat" já faz isso. Portanto, para o usuário final basta que o desenvolvedor crie um segundo arquivo bat que chama esse arquivo e depois chama o seu próprio script. Solução simples.

Porém, para utilizar um debugger é preciso explicitar para ele exatamente a mesma coisa que o o4w_env.bat explicita para o interpretador. As duas imagens abaixo exibem como fazer isso no menu Window-> Preferences do Eclipse PyDev. Basicamente definimos um novo interpretador chamado "osgeo" que é o executável "C:\OSGeo4W\bin\python.exe". Depois explicamos os paths nativos (lib), importados (sip) e do qgis para o interpretador "osgeo". Esses arquivos em questão são os ".py" e ".pyd" de cada biblioteca.

Por fim dizemos ao interpretador onde encontrar os arquivos ".dll" que essas bibliotecas acessam. Essa informação vai na variável de ambiente "PATH".

Assim nosso eclipse se encarregará de definir o PATH onde os ".dll" se encontram e incluir no PythonPath nossos ".py" e ".pyd" toda vez que o debugger rodar. Agora podemos debugar inclusive plugins de qgis utilizando PyDev.

domingo, 29 de novembro de 2009

Eclipse PyDev

Sempre recomendei o ERIC Python IDE para todos que estão iniciando em python.
Recentemente testei o Eclipse PyDev. Ele tem tudo que o ERIC tem e mais algumas coisinhas.
Exemplos:
-A completação de código do eclipse constrói a API sem você obrigatoriamente mandar.
-O eclipse reconhece todos interpretadores que você colocar disponíveis e define módulos disponíveis para cada um. Ou seja, você pode ter tantas versões do python na mesma máquina quanto queira.

Ainda tem o básico, que todas IDE tem: cores no código, interpretador, debugger, etc.
Ainda testei pouco, mas promete muito. Recomendo a todos pelo menos uma boa olhada.

Terralib, windows e MS Visual C++ Express 2008

Terralib é uma biblioteca geográfica nacional. Isso por si só já é motivo para interesse de toda a comunidade de desenvolvedores. Adicione o fato de ser mantida pelo INPE, estar em constante desenvolvimento e possuir uma excelente quantidade de algoritmos implementados dentro dela. A pergunta obvia é: Como faço para fazer isso funcionar?

Neste sentido, encontrei um problema quando me pediram para compilar um código escrito utilizando-a na plataforma windows 32bits. Os tutoriais do site do projeto são superficiais e não explicam exatamente como fazer para incluir as dependências. Para piorar tudo, só explica com visual studio 2003. Então aqui vai o tema do post: Compilar programas que usam a terralib com o Microsoft Visual C++ Express 2008 (MSVC 2008, que é grátis!).

Primeiro passo: Descarregue a terralib.

Segundo passo: Descarregue o MSVC 2008.

Bom, agora começaremos a parte complicada.
O processo vai seguir as seguintes etapas:
1- Compilar a terralib importando os arquivos de projeto que vem com ela;
2- Criar um novo projeto para o programa que quero compilar;
3- Configurar esse novo projeto para achar a compilação da terralib; (arquivos .h e .lib)
4- Compilar o projeto.
5- Copiar as DLLs para fazerem o projeto rodar.
Mãos a obra.

1- Compilar a terralib importando os arquivos de projeto que vem com ela;
Chamaremos durante o artigo a pasta de instalação de C:\TERRALIBDIR.
Instale o MSVC 2008.
Pegue o arquivo zipado da terralib e extraia-o em C:\TERRALIBDIR.

Procure (utilizando o "Encontrar" do Windows) arquivos com a extensão ".vcproj"
Ele deve listar os seguintes arquivos:
shapelib.vcproj
libjpeg.vcproj
tiff.vcproj
libspl.vcproj
terralibpdi.vcproj
terralibdtm.vcproj
terralib.vcproj

qwt.vcproj é um arquivo que depende da biblioteca QT que serve para gráficos e plotagens. Eu não consegui compilar essa parte da lib pois não compilei a QT. Uma sugestão é utilizar o QT SDK que instala tudo. Não fiz esses testes.

Abra os arquivos na ordem que estão escritos com o MSVC 2008. Ele irá pedir para importar o arquivo. Claro, pois os desenvolvedores do terralib só prepararam eles com Visual Studio 2003.
No menu Build-> Build Solution. Quando terminar ele vai mostrar se teve sucesso ou não. Caso algum falhe, toda a compilação vai falhar. É o caso de olhar com calma.

2- Criar um novo projeto para o programa que quero compilar;
Primeiramente, abra o MSVC 2008, crie um novo projeto e adicione os arquivos que queremos utilizar.
Lembrando que o nome do projeto amarra qual será o arquivo principal que o MSVC vai chamar. Durante a criação será perguntado se deseja utilizar cabeçalhos précompilados (precompiled headers). Desmarque essa opção conforme a imagem abaixo.



Agora insira os outros arquivos do seu projeto nas pastar headers (.h) e sources (.cpp).

3- Configurar esse novo projeto para achar a compilação da terralib; (arquivos .h e .lib)
Com o botão direito no nome do projeto na barra "Solution Explorer", acesse "Properties"->"Configuration Properties"->"C/C++"
No tópico: "Additional Include Directories" devem ser adicionados todos os diretórios que contém arquivos ".h" da terralib. No nosso caso, procure os diretórios na pasta: "C:\TERRALIBDIR\src\terralib\"
O mínimo que deve-se inserir nesta lista é a pasta: "C:\TERRALIBDIR\src\terralib\kernel" que conté o núcleo da terralib.

Ainda nas propriedades do projeto "Configuration Properties"->"Linker"->"General"
No tópico: "Additional Library Directories" devem ser adicionados todos os diretórios que contém arquivos ".lib" da terralib. No nosso caso, procure os diretórios na pasta: "C:\TERRALIBDIR\Debug\"
O mínimo que deve-se inserir nesta lista é a pasta: "C:\TERRALIBDIR\Debug\terralib" que contém arquivo "terralib.lib".
Por fim, no tópico "Configuration Properties"->"Linker"->"Input"->"Aditional Dependencies", insira o nome "terralib.lib"

4- Compilar o projeto.
E pronto. Seu programa estará pronto para compilar apertando F7.

5- Copiar as DLLs para fazerem o projeto rodar.
Para rodar o programa, será necessário procurar quais DLL ele usa. O jeito simples de fazer isso é rodar o programa várias vezes e cada vez que o windows reclamar de falta de DLL faça a procura da DLL na pasta "C:\TERRALIBDIR\Debug\".

Compacte todos eles juntos (exe e dlls) e mande para o seu amigo mais interessado!
Abraços e até o próximo.

sexta-feira, 28 de agosto de 2009

TK e Python

Uma das grandes vantagens do Python é ser multiplataforma. Desta forma, tudo que você escreve em Python é multiplataforma também, sem nenhuma alteração no código.
Isso torna o Python uma excelente linguagem para controlar coisas do dia-a-dia, substituindo o bash (linux), vbscript (windows), bat (dos) entre outros.

Mas sempre falta alguma coisa: a interface gráfica.

Imagine se você tivesse a força do bash e a facilidade de trabalhar com o sistema do vbscript? Bom, python tem.

A tk é um dos vários frameworks gráficos do python. É provavelmente o mais simples e o que vem instalado por padrão em todas instalações de python. Alguns exemplos de tarefas simples com a TK:

Insira este pedaço para poder usar a Tk. Este código inicializa uma janela principal da TK mas a recolhe. Fiz isso para que o nosso script não tenha uma janela constante e sim pergunte ao usuário as informações quando precisar, usando as caixas de seleção da TK:
import Tkinter
root = Tkinter.Tk()
root.withdraw()


Pedindo ao o usuário abrir um arquivo. Note que os formatos são configurados por pares de strings.
import tkFileDialog
myFormats = [('JPEG / JFIF','*.jpg')]
filename = tkFileDialog.askopenfilename(parent=root,title='Escolha um arquivo',filetypes=myFormats)
if len(filename) >0:
print "Abrindo arquivo ",filename


Pedindo ao usuário para escolher uma pasta. Aqui usamos os.getcwd() para começar na pasta onde o programa estiver rodando.
import tkFileDialog, os
dirname = tkFileDialog.askdirectory(parent=root,initialdir=os.getcwd(),title='Escolha um diretorio')
if len(dirname ) > 0:
print "Abrindo diretorio ", dirname 


Exibindo uma mensagem para o usuário:
import tkMessageBox
tkMessageBox.showinfo(parent=root,title="Meu Programa" ,message="Pressione Enter para continuar.")


Finalizando, faremos um exemplo simples de um programa que pede um arquivo, lê ele, troca a palavra "blz" por "beleza" e salva onde você escolher. (exemplo inútil, mas já fiz isso pra consertar tabelas em HTML.
import os, sys, Tkinter, tkMessageBox, tkFileDialog #importa todos os modulos necessarios

#solicitando o arquivo de entrada:
myFormats = [('Text files','*.txt')] #define os tipos de arquivos 
filename = tkFileDialog.askopenfilename(parent=root,title='Escolha um arquivo de texto',filetypes=myFormats)
if len(filename) >0:
print "Abrindo arquivo ",filename
else: sys.exit(0) #Termina o programa

#solicitando o arquivo de saida:
outfilename = tkFileDialog.asksaveasfilename(parent=root,filetypes=myFormats ,title="Guardar alteracoes em...")
if len(outfilename ) > 0:
print "Guardando alteracoes em ", outfilename
else: sys.exit(0)

#executando as trocas
f=open(filename) #abrindo o arquivo
lines=f.readlines() #lendo todas as linhas
f.close() #fechando o arquivo pois jah armazenei as linhas
outf=open(outfilename,'w') #abre o arquivo de saida para escrita
for line in lines: #para cada linha lida
line=line.replace("blz","beleza") #troca naquela linha as palavras que eu quero trocar
outf.write(line)
outf.close()

tkMessageBox.showinfo(parent=root,title="Trocador de Linhas" ,message="Trocas efetuadas.")


Com isto podemos observar a Tk funcionando. Como escondemos o "root" (que era a janela principal), nosso programa será puramente linha de comando com algumas solicitações visuais. Para fazer um programa inteiro em Tk recomenda-se utilizar melhor o "root".

Bom, até a próxima.

terça-feira, 11 de agosto de 2009

GDAL e Sistemas de Coordenadas

Como vimos anteriormente, uma das grandes aplicações da GDAL é na conversão de coordenadas. Esta semana me peguei querendo uma transformação rápida de coordenadas e utilizei uma sequência de comandos Python no terminal interativo para resolver esse problema.

Uma das vantagens do Python é que no terminal interativo pode-se acompanhar os resultados conforme eles aparecem.




Neste exemplo cada sistema de coordenadas é definido por um objeto da classe "osr.SpatialReference" (Referência Espacial). Para definir os sistemas de coordenadas novamente utilizamos a referência EPSG de cada um destes no método "osr.SpatialReference.ImportFromEPSG()".

Por fim, é criado um objeto "osr.CoordinateTransformation" (Transformação de Coordenadas) partindo de srE para srS. Este objeto vai ser o responsável por transformar todos pares (ou triplas) de coordenadas que eu passar para ele através do método "osr.CoordinateTransformation.TransformPoint(x,y,z)" Repetindo esse comando várias vezes pode-se transformar várias coordenadas. É uma calculadora rápida e precisa de coordenadas. E serve como exemplo de como definir sistemas de referência na GDAL em Python.

Espero que seja útil.
E até o próximo post.

terça-feira, 4 de agosto de 2009

Reprojetando todo o servidor Raster

function teste {
}
import sys, os
try:
import gdal #gdal <1.6
except:
from osgeo import gdal #gdal >1.6
import os, sys
gdalwarp=r"gdalwarp.exe" #Para funcionar, coloque o gdalwarp dentro do path usando o script set_fw.bat
lista = []

#-->procurando os fotolitos dentro da estrutura de diretorios - inicio
for root, dirs, file in os.walk(os.getcwd()):
for i in file:
if (i[-4:]==".cit" ) or (i[-4:]==".tif"):
if ("Georreferenciados" in root):
lista.append(os.path.join(os.getcwd(),root,i))
#-->procurando os fotolitos dentro da estrutura de diretorios - fim

def corrigeGeo(arquivo): #transforma de centimetros para metro
ds=gdal.Open(arquivo)
georef=ds.GetGeoTransform()
a=[]
for i in range(0,len(georef)):
a.append(georef[i]*0.01)
georef=ds.SetGeoTransform(a)
del ds

print "Iniciando conversoes"
for i in lista:
print i
corrigeGeo(i) #transforma de centimetros para metro
#converte os arquivos listados do fuso 22 Corrego Alegre para fuso 22 WGS e salva em imagens de 1 bit
os.system(gdalwarp+" "+i+" "+i.split(".")[0]+'_WGS.tif'+' -s_srs EPSG:22522 -t_srs EPSG:32722 -co "NBITS=1"')
print "Terminado"

GDAL, Corrego Alegre e definições de DATUM

No Brasil vivemos uma transição de datum geodésico. Devemos converter os dados de SAD 69 e Córrego Alegre (em diversas materializações) para o SIRGAS 2000. Aqui no Rio Grande do Sul todo o mapeamento é em Córrego Alegre na escala 1:50.000. Então surge um problema: Utilizando as resoluções Resolução 1/2005 e Resolução 23/1989, a transformação de Córrego Alegre para SIRGAS 2000 pode ser feita somando as coordenadas de transformação geocêntrica utilizando a transformação de Molodensky com os parâmetros X=-206,048m Y=168,279m Z=-3,823m.

Porém, no site do IBGE foi dada uma nova forma de transformar. O programa PROGRID utiliza grades de valores e efetua transformações que difereriram em alguns metros das coordenadas calculadas com os parâmetros previstos nas resoluções. Perguntei a um professor meu da graduação e ele me orientou que o PROGRID foi uma solução que buscava obter melhor coerência entre as transformações de coordenadas.

Apesar disso, nenhum software de GIS atualmente adotou essa transformação e não achei nenhuma referência no IBGE falando sobre alguma resolução que oficialize esse método de transformação. Como estou trabalhando com cartas 1:100.000, os 5m de erro absoluto não são relevantes durante a conversão de dados analógicos para digitais.

Depois de contar a história triste que motivou esse estudo, vamos pra parte prática: Tínhamos em torno de 50 arquivos TIF para converter para esta semana e mais uns 500 no servidor aguardando oportunidade. Decidimos automatizar a conversão.

Como prefiro, optamos por utilizar tecnologia aberta, escolhendo a GDAL. Para quem não conhece, esta é a biblioteca principal de programas C/C++ e python para dados geográficos matriciais e vetoriais. Ela vem com diversos programas auxiliares, entre eles, um programa de reprojeção de arquivos matriciais ("gdalwarp"). Utilizei o pacote pré-compilado FWTools em Windows XP durante os testes.

Para definir os parâmetros corretos, deve-se alterar arquivos na pasta "data" da instalação da gdal (no meu caso "C:\Program Files\FWTools2.4.2\data"). O arquivo "data\coordinate_operation.csv" guarda o nome das transformações, o identificador delas e os identificadores dos sistemas de coordenadas (referentes à EPSG). Procurando por "rrego" neste arquivo achei a linha:

1132,Corrego Alegre to WGS 84 (1),transformation,4225,4326,...

Que representa exatamente a transformação pré-definida na GDAL.

Dentro do arquivo "data\coordinate_operation_parameter_value.csv" procurei o identificador 1132 e achei as linhas:

1132,9603,8605,-206,,9001
1132,9603,8606,172,,9001
1132,9603,8607,-6,,9001

Que eu troquei para:

1132,9603,8605,-206.048,,9001
1132,9603,8606,168.279,,9001
1132,9603,8607,-3.823,,9001

E desta forma, minha instalação da GDAL passou a seguir os parâmetros previstos nas resoluções.

Agora meu gdalwarp já fazia as transformações corretamente, mas queríamos transformar muitos arquivos. No próximo post comento o código que eu e César Soares escrevemos para fazer isso em toda a estrutura.

Novamente, agradeço a todos que se interessaram pelas informações aqui postadas pois é esse o objetivo.
Até a próxima!

quinta-feira, 5 de março de 2009

Qt, Postgis e QGIS

O Quantum GIS (QGIS) é um software com características promissoras. Primeiramente, é software livre, o que permite muita inovação nele. É escrito em C++, o que o faz superior à maioria dos outros softwares livres de processamento pesado em Java. E por fim, possui uma API aberta ao público em C++ e Python.

Atualmente estou trabalhando em um plugin para o QGIS cujo objetivo é melhorar a automação de Queries do Postgis através da geração de uma interface gráfica para elas automaticamente. A idéia veio de tentar dar ao Postgis algo como o Model Builder do ArcGIS, para gravar rapidamente os processamentos feitos e poder reaproveitá-los.

A idéia é guardar em um XML as informações de parâmetros necessários para um processo que será definido por uma query de PostgreSQL. O resto o script faz. Gera um botão no menu pro proceso, gera uma interface gráfica com campos para os parâmetros e apresenta os resultados em uma caixa de texto.

Dessa forma pode-se resolver problemas como: "Quais os nomes das cidades que tocam o polígono que eu acabei de desenhar?" com um único botão de menu já pronto pra isso.

Ainda falta um bocado de desenvolvimento, mas estarei trabalhando nisso por alguns dias.
Espero que fique bom o resultado. Com sorte resolverei meu problema de "como é que eu fiz daquela vez que eu fiz touch com select name from..." :D

sábado, 7 de fevereiro de 2009

Nota de abertura

Eu nunca entendi exatamente o objetivo de um blog mas recentemente senti a necessidade de utilizar alguma ferramenta para publicar informações na internet. As opções seriam:
1- criar um site (que seria bem mais útil mas me peguei sendo exigente demais com as hospedagens gratis. "Como assim eles não deixam eu usar postgresql e pmapper? Nem python?")
2- criar um site não tão requintado (que tiraria toda a graça da coisa)
3- criar um blog simples com textos corridos das coisas que eu realmente queria documentar.

No momento me veio à cabeça o problema da língua. Meu público-alvo são as pessoas que trabalham comigo ou que tem interesse pelo meu trabalho. Por isso, português. Para quem não sabe sou Engenheiro Cartógrafo formado no Instituto Militar de Engenharia e trabalho com mapeamento sistemático e desenvolvimento de software para cartografia.

Então aqui estarei escrevendo tudo que achar relevante e muito provavelmente como todo blog, serei redundante pois estas informações estão disponíveis em vários lugares da internet. As vantagens são que o conteúdo será em português e que refletirão experiências que eu vivi, ou seja, estarei disposto a explicá-las.

Agradeço a todos que tiverem interesse em passar por aqui e espero que eu faça algo útil para a comunidade.

Atenciosamente,
Maurício de Paulo