News

Montando banco de dados espacial com a GDAL - Parte 3 (Emulação do ambiente UNIX/SHELL no WINDOWS)

>> Emulação do ambiente UNIX/SHELL no WINDOWS <<

O UNIX/SHELL, mas conhecido como SHELL, é um conjunto de programas que acessam o núcleo do sistema operacional UNIX, permitindo obter informações do sistema operacional. Num ambiente UNIX, como exemplo o LINUX, é comum o uso de um terminal, também chamado de console, que é uma janela onde chamamos os programas do SHELL. No caso do Windows acessamos os comandos do MS-DOS (Sistema Operacional da Microsoft) pelo programa "Prompt de Comando".

Nessa parte da postagem, vou mostrar os programas que foram utilizados para a montagem do banco de dados espaciais. Inicialmente vamos ver como podemos emular o SHELL no Windows com a obtenção dos programas pelos pacotes da OSGEO4W e pelo projeto GnuWin32.

1) Pacote da OSGEO4W

Na Parte 2 da postagem foi mostrado a opção de utilizar o instalador da OSGEO para Windows (OSGEO4W) para obter o pacote (conjunto de arquivos) da GDAL.

O OSGEO4W possui um pacote chamado MSYS que contém um conjunto mínimo de programas do SHELL para Windows, logo, deve-se marcar esse opção no instalador da OSGEO4W para termos alguns comandos que iremos utilizar nessa postagem (Figura 1).

Figura 1. Marque a opçção MSYS no instalador da OSGEO4W


O MSYS não possui todos os programas do SHELL que são utilizadas na postagem, assim, precisaremos instalar os pacotes que complementaram os comandos utilizados nessa postagem.

2) Pacote do projeto GnuWin32

Os pacotes do projeto GnuWin32 (http://gnuwin32.sourceforge.net/packages.html) são disponibilizados como arquivos ZIP.

Cada arquivo ZIP, corresponde a um programa do SHELL e deve ser descompactado de forma padronizada no diretório a ser instalado os pacotes do GnuWin32. 

Os pacotes a serem utilizados são:

2.1) coreutils: comandos básicos do SHELL.
2.2) unzip: decompacta arquivos ZIP e
2.3) wget: baixa arquivos da Internet.

A seguir, figura 2, é ilustrado a árvore de diretórios e um exemplo do conteúdo zipado do programa "wget.exe".

Figura 2. Árvore de diretório (clique na figura para ampliar)

Na figura acima, o pacote de comandos do GnuWin32 foi colocado no diretório "C:\_gnu_windows", e nesse diretório é descompactado os arquivos de cada pacote.

Observa-se que no pacote temos os nomes dos diretórios que devem estar na árvore de diretórios da instalação do GnuWin32, logo, percebemos que não temos um SETUP, ou seja, um programa de instalação de pacotes, e sim, simplesmente os arquivos ZIPADOS que tem os programas que queremos ter no nosso ambiente de processamento e seus respectivos arquivos em diretórios padronizados (bin,lib,man, manifest, share, ...).

Para termos um console que emule o SHELL temos que configurar o ambiente de trabalho, assim, é necessário criar um arquivo BAT contendo as definições necessárias.

3) Configuração do ambiente de processamento no Windows

A configuração para processamento consistirá num arquivo BAT que terá todas as definições necessárias para executar os programas do SHELL e dos utilitários da GDAL, ou seja, será nele que iremos rodar scripts e "saborear" o poder do SHELL. Uma vez configurado o arquivo BAT, esse arquivo passará a ser o programa que iremos executar para emular o ambiente SHELL.

O conteúdo do BAT (clique aqui para baixar o BAT - OSGeo4W_PRODES.bat) consiste em:

@echo off
set OSGEO4W_ROOT=C:\OSGeo4W
PATH=%OSGEO4W_ROOT%\bin;%PATH%
for %%f in (%OSGEO4W_ROOT%\etc\ini\*.bat) do call %%f
REM *** // Gnu Windos and Scripts \\ ***
set http_proxy=172.21.12.1:3128
PATH=%path%;C:\_gnu_windows\package\bin;C:\_bd_prodes\sh
REM *** \\ Gnu Windos and Scripts // ***
@echo on

@cmd.exe

A seguir as observações referente as definições contidas no BAT:

3.1) O diretório onde está instalado os pacotes da OSGEO4W é "C:\OSGeo4W", pasta escolhida no momento da instalação da GDAL (veja na Parte 1 dessa postagem).

3.2) Foi definido a variável de ambiente http_proxy, com o valor do IP da maquina de PROXY na rede (valor = 172.21.12.1) e a porta do PROXY (valor = 3128). Essa variável só deve ser definida se o seu computador estiver numa rede corporativa, onde geralmente tem PROXY (veja com o administrador da rede os valores do seu PROXY), caso contrário, elimine ou faça um comentário, escrevendo REM no início da linha.

3.3) O pacote GnuWin32 foi instalado no diretório "C:\_gnu_windows".

3.4) Os Scripts criados para fazer o banco de dados espacial (clique aqui para baixar os Scripts - PRODES_sh.zip) estão no diretório "C:\_bd_prodes\sh", e podem ser chamado no terminal por estarem na variável PATH.

O BAT para configurar o console de processamento pode ser colocado em qualquer local, como sugestão, coloque no diretório "C:\_bd_prodes\bat".

Para facilitar o uso do terminal, você pode criar um atalho no seu Desktop apontado para esse arquivo (Figura 3).
Figura 3. Criar atalho em seu Desktop (clique na figura para ampliar)

Depois desse esforço todo está na hora de saborearmos o SHELL, assim, tome um cafezinho e volte animado para proximo ítem.

4) Saboreando o SHELL

Antes de colocar a mão na massa, gostaria de avisar que usei termo SHELL de forma simplista, para maior clareza deve-se consultar as referências sobre UNIX/LINUX. Nessa postagem preferi não aprofundar no UNIX/LINUX, e sim, mostrar uma estação de processamento GIS onde são manipulados dados via terminal.

Os programas do SHELL, também conhecidos como comandos, possui alguns conceitos, e para facilitar vamos explicar sucintamente o que é argumento de um comando.

Os comandos do SHELL podem conter argumentos, que são os parâmetros passados em sua chamada, fazendo uma analogia a uma função listar (x), x é o argumento da função, assim, a chamada para o comando 'listar' seria escrito no terminal como, "listar x".

Existem argumentos obrigatórios e opcionais, onde os argumentos opcionais são identificados com um prefixo de hífem ('-').

Para maior entendimento sobre o uso de um comando utilizamos o argumento de 'help', que mostra as informações sobre o comando, exemplo, "cp --help". Observa-se que o argumento 'help' possui no prefixo dois hífens ('--')

Agora vamos mostrar os scripts mais utilizados nessa postagem.

4.1) Baixando dados na Internet - wget

O 'wget' permite baixar conteúdos da Internet nos protocolos HTTP, HTTPS e FTP, e é por meio deles que vamos obter os dados do PRODES. O uso 'wget' em redes com PROXY necessita da definição da variável 'http_proxy' (ver item 3.2).

Para maiores informações sobre o 'wget' consulte o manual do comando utilizando o argumento padrão '--help', exemplo, 'wget --help'.

Vamos baixar os dados de PRODES do ano de 2010, para isso execute no seu terminal de processamento (OSGeo4W_PRODES.bat).

A seguir a sequência de comandos para 1) ir até o diretório de trabalho, 2) criar o diretório zip, 3) ir para diretório zip dentro do diretório atual e 4)fazer o download da página dos dados:

cd /home/lmotta/_work_2011/blog_lopes/banco_dados_prodes
mkdir zip
cd zip
wget http://www.dpi.inpe.br/prodesdigital/dadosn/2010

O 'wget' baixa o arquivo com o conteúdo da página. No Windows a implementação do 'wget' cria o arquivo index.html, no Linux/Ubuntu foi criado o arquivo '2010', logo, o comportamento do 'wget' pode variar conforme o sistema operacional (Macintosh, Distribuições LINUX,...).

Podemos dar uma rápida olhada no arquivo gerado utilizando o comando 'head', que permite ver as primeiras linhas de um arquivo.

head -n 20 2010

O comando acima exibe as 20 primeiras linhas do arquivo 2010. Observa-se o uso do argumento opcional '-n 20', para definir a quantidade de linhas a serem mostradas.

Podemos verificar que temos os endereços dos shapefiles que queremos baixar, como exemplo, HREF="PDigital2010_00265_shp.zip".

O endereço do arquivo 'PDigital2010_00265_shp.zip' ficará:

O 'wget' pode baixar vários arquivos em um só comando, para isso devemos ter uma listagem dos endereços de cada shapefile. Exemplo do conteúdo do arquivo(exemplo list_shapefile.txt):
...

Vamos executar um comando (composto de uma sequência de comandos) para termos os arquivos a serem utilizados nessa postagem.

4.1.1) Comando para ter a listagem dos endereços dos shapefiles

grep _shp.zip 2010 | cut -d= -f4 | cut -d'"' -f2 | sed 's/PDi/http:\/\wwww.dpi.inpe.br\/prodesdigital\/dadosn\/2010\/PDi/g' > list_shapefile.txt

Observações:
- Posteriormente será explicado os comandos utilizados (grep, cut e sed).
- Foi utilizado o recurso de 'pipe' (ver detalhes no próximo item).
- Foi utilizado o recurso de canalização, caracter '>', onde a saída passa a ser um arquivo (no caso foi o arquivo list_shapefile.txt), em vez da saída padrão (o terminal).
- 2010 é o nome do arquivo baixado pelo wget ao passar o endereço dos dados de 2010 do PRODES.

4.1.2) Comando para obter os shapefiles:

wget -i list_shapefile.txt

Obs.: o argumento '-i' define o uso do arquivo de leitura com os endereços.

Depois de baixar os arquivos zipados, crie um diretório, e descompacte os mesmos no diretório criado.

4.1.3) Comando para descompactar os shapefiles
cd ..
mkdir shp
cd shp
ls -1 ../zip/*.zip | sed 's/\.\./unzip -j \.\./g' > unzip_shp.sh
sh unzip_shp.sh

Observação: Primeiro criamos o diretório 'shp' dentro do diretorio 'banco_dados_prodes' e descompactamos todos os ZIP's.

A seguir são mostrados os comandos de forma mais didática utilizados nessa postagem.

4.2) Listar o conteúdo do diretório - 'ls'

O 'ls' lista as informações dos arquivos, para saber como formatar a saída e os tipos de informações, veja as opções do comando digitando 'ls --help'.

Geralmente, queremos aproveitar a lista (saída do comando ls) para extrair informações, para isso, existe uma forma de aproveitar a saída do comando como entrada para outro comando. Isso se chame 'pipe' , logo, vou mostrar a seguir um exemplo do comando 'ls' com o comando de contador de palavras ('wc').

4.3) Contar palavras -'wc'

Naturalmente, devemos dar uma olhada sobre o comando, 'wc --help', aqui vou direto a prática! Como contar os arquivos contidos no diretório, mas para ser mais realista contar o numero de shapefiles no diretório corrente do terminal:

ls -1 *.shp | wc -l

Para maior compreensão, execute cada comando, experimente, 'ls ', 'ls -l', 'ls -1', 'ls -1 *.shp', a listagem desses exemplos já mostram a finalidade de cada argumento.

Vamos fazer o papel do SHELL, ou seja, interpretar os comandos. O 'ls -1 *.shp' lista os arquivos shapefiles (por isso o uso do filtro *.shp) linha a linha e apenas o seu nome, comportamento da listagem definido pelo argumento '-1'.

Com a saída da listagem podemos passar como entrada para o comando 'wc -l', onde esse comando vai contar as linhas contidas na entrada, assim, temos o total de shapefiles num diretório. 

Isso está ficando interessante! No Windows eu teria que selecionar apenas os arquivos com extensão 'shp', e olhar lá em baixo o total de arquivos selecionados, fica evidente que o uso do 'ls -1 *.shp | wc -l' é bem mais confiável do que fazer a operação na janela de gerenciador de arquivos do Windows.

O comando 'wc' pode contar outras informações, para saber mais, vc. já deve saber como! Help nele!

4.4) Concatenar e exibir arquivos - cat

O comando 'cat' é usado para mostrar o conteúdo de um ou mais arquivos, se vc. quer mostrar o conteúdo de mais de um arquivo, vc. está "concatenando" os arquivos, ou seja, juntando todos e mostrando de uma só vez.

O mais comum é ver o conteúdo de um arquivo, como exemplo, podemos ver o sistema de referência (SR) de um shapefile exibindo o valor do arquivo PRJ.

cat PDigital2010_00165_pol.prj

4.5) Pesquisando textos - grep

O grep é um poderoso comando, onde podemos fazer uma série buscas de textos em arquivos, ele merece ser pesquisado!

Como exercício vamos verificar se todos os shapefiles possuem o SR geográfico. No item anterior (exemplo de 'cat') você provavelmente viu o a palavra 'GEOGCS' no início da listagem, logo, o shapefile está no SR geográfico.

Para sabermos se todos os shapefiles estão no SR geográfico, vc. primeiro conta quantos arquivos PRJ existem e depois verifique se a contagem é a mesma com o comando:

grep -i "GEOGCS" *.prj | wc -l

No comando 'grep -i -c "GEOGCS" *.prj' fizemos a busca da palavra GEOGCS em todos os arquivos PRJ, e especificamos com o argumento 'i' para ignorar se o termo de busca está maiúscula ou minúscula (GEOGCS ou geogcs), a saída do comando mostra em cada linha o nome do arquivo e o texto com a palavra GEOGCS, como cada linha só aparece se existir a palavra GEOGCS, basta contarmos o número de linha ' | wc -l'.

O resultado é bom, mas não me agradou!

Tenho que usar dois comandos, um para contar o número de arquivos PRJ e o outro para contar se os arquivos PRJ possuem GEOGCS.

E se os resultados forem diferentes?

Vamos mostrar mais comandos e depois mostraremos como melhorar a pesquisa para obter os SR's.

4.6) Cortar texto - cut

O 'cut' permite extrair textos, delimitados pelo número da coluna ou delimitadores, em cada linha de um arquivo de texto.

Aproveitamos e vamos explicar o comando do item 4.1.1.

grep _shp.zip 2010 | cut -d= -f4 | cut -d'"' -f2

O grep filtra do arquivo '2010' (lembre-se no Windows é index.html) as linhas que possuem o texto '_shp.zip'. Essa saída passa para o comando 'cut -d= -f4'. O comando 'cut' usa como delimitador o sinal de igual '=-d' e extrai a informação que esta no 4º campo, ou seja, ele interpreta as linhas como se fossem uma tabela limitada por sinal de '=' e obtém os valores da 4ª coluna.

Como exercício, vamos usar os arquivos shapefiles (o usuário deve estar no diretório 'shp'), e obter uma lista com apenas as datas dos shapefiles (*.shp)

ls -l *.shp | cut -b45-

O 'cut' vai extrair da listagem (comando 'ls -l *.shp') os textos que começam a partir da coluna 45 (opção '-b45-').

4.7) Interpretador de texto - sed

O 'sed' oferece uma série de recursos para trabalhar com textos, o mais comum é a substituição de palavras no texto.

Como exemplo, vamos criar um arquivo texto que contém os comandos para mover arquivos dos shapefiles.

ls -1 *.shp | sed 's/\.shp/\.\* new_dir/g' | sed 's/PDi/mv PDi/g' > mv_shp.sh

O primeiro comando lista apenas os nomes dos arquivos com extensão 'shp', essa saída passa ser entrada para o próximo comando, sed 's/\.shp/\.\* new_dir/g'.

Vamos explicar o primeiro uso do 'sed', o argumento 's/\.shp/\.\* new_dir/g' é interpretado da seguinte forma:

  • o 's/' define o início da palavra a ser substituída, no caso '\.shp'; 
  • o caracter de escape '\' é para evitar a interpretação do '.', ou seja, trocar a palavra '.shp'; 
  • o próximo caracter '/' inicia a palavra que vai ser inserida '\.\* new_dir' ('.* new_dir); e 
  • o caracter /g finaliza a substituição, resultando na substituição de '.shp' por '.* new_dir'. 
O segundo uso do 'sed' substitui 'PDi' por 'mv PDi' e a canalização '>' cria o arquivo mv_shp.sh.

É padrão usarmos a extensão '.sh' para representar script do SHELL. Para mover os arquivos de cada shapefile executamos o script via interpretador do SHELL (comnando 'sh').

sh mv_shp.sh

4.8) Ordenar - sort

O 'sort' ordena as linhas de um texto. Seu uso dispensa exemplo, basta passar o nome de um arquivo 'sort nome_arquivo' ou receber a saída de um comando 'ls -1 | sort'

4.9) Listar apenas valores únicos - uniq

O 'uniq' mostra apenas os valores únicos das linhas de um texto.Um exemplo é verificar as datas que foram gerados os shapefiles de um diretório.

ls -l *.shp | cut -b37-46 | uniq

O primeiro comando lista os arquivos shapefiles com as suas informações, e o próximo comando retira apenas as datas de cada arquivo (colunas 37 à 46), e o 'uniq' mostra os únicos valores. Como resultado do comando temos as datas dos arquivos.

4.10) Descompactar - unzip

O unzip, trabalha com arquivos ZIP, permitindo, testa-los, mostrar os conteúdos e descompactar. Seu uso é bastante intuitivo, como exemplo, para descompactar o comando é 'unzip nome_arquivo'.

4.11) Finalmente vamos fazer a pesquisa sobre os tipos de sistema de referência.

O arquivo PRJ contém uma linha com o SR do shapefile no formato WKT (http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html).

Se usarmos o comando 'cat' para concatenar todos os PRJ, podemos ter um problema, nem sempre o arquivo PRJ possui o carácter 'terminador de linha', assim, ao concatenar todos os PRJ, estaremos juntando todos os SR dos shapefiles numa mesma linha.

A construção de script SHELL pode ser feita numa única linha, e é o que estamos fazendo até agora, dessa forma, criamos o SHELL e executamos direto na linha do terminal.

O SHELL pode utilizar os recursos de programação, como definição de variáveis, interação (loops), condicional, funções e outros.

Nesse item vamos criar um script SHELL como um fonte de um programa e rodá-lo posteriormente. Isso já fizemos, criamos uma listagem de comandos para depois executar via interpretador SHELL (comando 'sh').

A ideia aqui é mostrar que existe esse recurso no seu PC, e para tirar proveito, o usuário avalia se o investimento em entendimento do SHELL pode ser uma boa opção para "domar seus dados espaciais".

Os arquivos PRJ não possui terminador de linha, assim, temos que colocar o terminador de linha para cada SR (conteúdo do PRJ) listado, e depois aplicar o comando 'uniq', assim, teremos a listagem dos SR existente nos shapefile, sendo mais interessante do que ficar comparando totais (exemplo do item 4.5).

Para termos a listagem dos tipos de SR's, vamos criar um arquivo de script SHELL denominado 'uniq_srs.sh'. O arquivo tem que estar no formato texto padrão, para isso use o 'Bloco de Notas' ou outro de sua preferência. A execução do script é feita com o comando 'sh uniq_srs.sh'.

A seguir a listagem do Script:
#!/bin/sh
#
# Return: List of Reference Systems types used by a set shapefiles
#
#
# Remove tempfile if exist
if [ -e "tempfile" ]
then
rm "tempfile"
fi
# Add all reference systems inside tempfile
for file in `ls -1 *.prj`
do
echo "`cat $file`" >> tempfile
done
uniq tempfile
rm tempfile

Descrevendo o script:
  • A linha que inicia com o caracter '# ' não é interpretada, assim, pode ser usada para comentar o script.
  • A 1a linha define para o UNIX que se trata de um script SHELL, assim, se esse arquivo tem permissão de execução, pode ser chamado diretamente. Coisas do mundo UNIX/LINUX!
  • O script verifica se existe o arquivo 'tempfile', se existir, apaga o mesmo.
  • É criado uma lista contendo o nome dos arquivos PRJ, `ls -1 *.prj`. Observa-se o carácter de crase (`) no início e no final do comando ls -1 *.prj, força o comando a ser interpretado 1o, para depois fazer o loop.
  • O loop é feito com a instrução, for file in [Lista de arquivos], onde para cada arquivo PRJ é associado a variável file, e essa é utilizada dentro do loop. O loop está envolvido pelas palavras 'do' e 'done'.
  • Para cada valor de 'file' é executado o comando, echo "`cat $file`" >> tempfile, onde, o comando echo exibe o conteúdo de um texto (definido entre o caracter ") e coloca o final de linha. A saída é adicionada ao arquivo tempfile pelo dupla canalização '>>', logo, cada saída do comando echo é posta como uma nova linha no aquivo. O `cat $file`, é executado primeiro, ou seja, mostra o SR do arquivo, sendo colocado no texto (definido entre o caracter "), o sinal de $ é para ler o valor da variável.
  • Depois do loop, é utilizado o comando 'uniq' com o arquivo tempfile, mostrando apenas os tipo de SR's, depois removemos o tempfile.
Espero que tenha tido uma visão do uso de scripts para investigar grande quantidade de arquivos. Seu uso, passa a ser uma necessidade em ambientes servidores, mas acredito que vale a pena conhecer um pouco desse recurso tão escondido pelas "janelas" do seu Windows.

Até a próxima etapa e aguardo as dúvidas e comentários!

Luiz Motta
--
motta.luiz@gmail.com

Geotecnologias Luís Lopes Designed by Templateism.com Copyright © 2014

Imagens do modelo de Bim. Tecnologia do Blogger.