domingo, 23 de agosto de 2009

#Python: parte 2 e 1/2

Bom dia pessoal,

No post #python parte 2, eu deixei como exercício para vocês uma pequena tarefa. Como podemos perguntar ao usuário qual é pasta que ele quer projetar e qual a projeção. Existem duas maneiras, uma delas é criar o script para rodar somente dentro do ArcGIS ou utilizar algum tipo de manipulação dentro do script, que roda em DOS/Python.
Vou mostrar a segunda maneira. Os scripts criados pelo ArcGIS são bastante simples, mas é preciso um pouco mais de base teórica, então fica pra depois.

Bem, para isso precisamos utilizar umas manhazinhas. Esta solução vai em duas partes, e poderia ser muito mais complexa, mas o Python vai nos ajudar.

Primeiramente, como perguntar qualquer coisa ao usuário? O Python tem uma pequena função chamada raw_input.

A função raw_input tem como único argumento opcional uma mensagem à ser passada ao seu usuário, mostrando a ele o que ele tem de digitar:

pasta = raw_input("Digite a pasta onde se encontram os shapefiles. ")
#funciona
pasta2 = raw_input()
#funciona também, mas sem mensagem

Bem, antes do script rodar e começar a tentar processar as pastas, é bom testar se o valor que o usuário digitou é válido. Existem diversas validações que poderiam ser executadas, mas vamos usar uma em especial.

#lembre-se que cada - equivale à um espaço e um conjunto com ---- equivale à uma tabulacao.

import sys, os, arcgisscripting

pasta = raw_input("Digite a pasta que deseja projetar. Lembre-se de duplicar as barras \\ senão não acho o caminho. ")

if os.path.isdir(pasta) == true:
----#é uma pasta válida e existe.
----#processe
else:
----#não é uma pasta válida.
----#imprima uma mensagem de erro e saia do script.
----print "Erro, a pasta indicada não é válida."
----exit

Bem pessoal, esse é o começo de tudo. Não repetirei os processamentos com o arcgisscripting, e isso é pra vocês estudarem e tentarem por aí.

Não se esqueçam, o F1 do Python traz a ajuda da versão utilizada, que contém as assinaturas de funções (quais são os paramêtros de entrada e qual é a saída), notas importantes e exemplos de como usá-las.

Agora, como permitir o usuário escolher o datum? Essa é um pouco mais difícil. Teremos de usar um outro tipo de dados do Python, chamado dicionário, que é tão poderoso quanto as listas, mas existem algumas diferenças sobre ele. O dicionário não suporta aquela maravilha de "for x in lista:", pois ele é um...dicionário, e não uma lista.

Os dicionários tem alguns métodos que nos ajudam a achar o que queremos:

a = {'SAD6922SUL':'\\Coordinate Systems\\Projected Coordinate Systems\\Utm\\Other GCS\\South American 1969 UTM Zone 22S.prj'}

Este é um dicionário com somente uma entrada. Enquanto as listas utilizam a posição de cada item (de 0 à n), os dicionários utlizam as keys. No caso supracitado, a key para este endereço monstro é SAD6922SUL, ou seja, ela armazena um valor, que é o diretório para este datum.

Métodos:
len(dicionario) retorna o tamanho do dicionario.
k in dicionario. Verdadeiro se a chave k está presente no dicionario dicionario.
k not in dicionario. Verdadeiro se a chave k NÃO está presente em dicionario.
dicionario.has_key(k). Mesmo que k in dicionario. Versão nova da função.
dicionario.keys(). Copia as keys para uma lista.
dicionario.values(). Copia os valores para uma lista.
dicionario[k] = v. Adiciona uma chave k com o valor de v no dicionario.

Existem outros métodos, mas estes são os mais básicos e necessários para começar.

Imagine o seguinte dicionario:

dicionarioDatums = {'sad69utm22s':\\Coordinate Systems\\Projected Coordinate Systems\\Utm\\Other GCS\\South American 1969 UTM Zone 22S.prj',
'sad69utm23s':'\\Coordinate Systems\\Projected Coordinate Systems\\Utm\\Other GCS\\South American 1969 UTM Zone 23S.prj',
'sad69utm24s':'\\Coordinate Systems\\Projected Coordinate Systems\\Utm\\Other GCS\\South American 1969 UTM Zone 24S.prj'}

e o código a seguir:

chaveDatums = dicionarioDatums.keys()

for chave in chaveDatums:
----print chave

datumEscolhido = raw_input("Digite o datum de sua escolha. ")

if datumDicionario.has_key(datumEscolhido):
----#processo
else:
----print "Você não escolheu um datum válido. Reinicie e tente novamente."

Bem, veja que hoje apenas estruturei a solução. Quero ver algum código aí nos comentários. Alguém tem uma outra idéia para fazer isso?

É bom notar que existem melhoras a serem feitas neste script, por exemplo, forçar o usuário a digitar algo correto no último raw_input, e software não sair daí enquanto ele não o fizer. Existe também a possibilidade de se mapear a pasta Coordinate System automaticamente, sem a necessidade de sempre que precisarmos de um datum novo, que não está na lista, reescrever o código. Deem suas sugestões e espero ter ajudado.

Abraço

George

2 comentários:

  1. Uma opção que pode ser utilizada, para responder a primeira pergunta é passar os parâmetros na chamada do script. Ficaria assim:

    c:\>python projetaShp.py c:\\dados sad69utm22s

    No código do script então deveria começar assim:

    #Script para reprojetar
    import sys, os, arcgisscripting
    pasta = sys.argv[1]
    datun = sys.argv[2]
    ...
    ...
    ...

    ResponderExcluir
  2. Olá Fabiano,

    Os scripts realmente poderiam começar assim, mas quis priorizar uma educação dos usuários em Python, antes de começar a jogar métodos atualmente utilizados em programação script para o ArcGIS, para a maioria das pessoas entenderem como o Python funciona.

    Alguns artigos e posts estão programados à esta direção especifica a isto.

    Muito obrigado pelos comentários,

    George

    ResponderExcluir