Explorar E-books
Categorias
Explorar Audiolivros
Categorias
Explorar Revistas
Categorias
Explorar Documentos
Categorias
OBJETIVOS DA DISCIPLINA:
A disciplina visa abordar os conceitos básicos da linguagem de programação Python e
utilizá-la de forma integrada em ambiente de geoprocessamento como o ArcGIS.
JUSTIFICATIVA:
Os profissionais que trabalham na área de meio ambiente geralmente possuem
conhecimento e já estão familiarizados com os conceitos de SIG e geoprocessamento sem
que, contudo, trabalhem com uma linguagem de programação. Muitas vezes os usuários
apenas fazem uso de interfaces gráficas (GUI) por meio das ferramentas já disponíveis nos
softwares SIG, mas em algum momento se faz necessário estender os recursos, automatizar
processos, ou apenas trabalhar de forma mais eficiente para completar os objetivos
primários para responder a perguntas baseadas no espaço geográfico. Desta maneira, a
disciplina busca ensinar os alunos a desenvolver scripts para que este possa incorporá-los
ao fluxo de seu trabalho.
CONTEÚDO:
Introdução ao Python e ArcPy. Uso ferramentas de geoprocessamento de forma
automatizada. Trabalho com feições e geometrias em formato vetorial. Trabalho com
arquivos rasters. Criação de Python toolboxes e add-ins.
BIBLIOGRAFIA:
Bielenki, C. Jr; Barbassa, A. P. Geoprocessamento e Recursos Hídricos: Aplicações
Práticas. EDUFSCar, São Carlos, 2012.
Paul A. Zandbergen, Python Scripting for ArcGIS, ESRI Press, Califórnia, 2013.
Docentes responsáveis:
Agosto, 2019
Este material está dividido em 4 etapas:
5
Etapa 2: Fundamentos de Programação com Python
Na etapa 2 trabalhamos com conceitos fundamentais de programação e técnicas de
solução de problemas que são comuns à maioria das linguagens de programação. O objetivo
desta etapa é prepará-lo para aprender qualquer linguagem de programação que possa ser
exigida em seu trabalho. A lição também mostra como sintetizar esses fundamentos para
abordar problemas de programação. Você é orientado sobre onde procurar ajuda para se
tornar um programador autossuficiente.
Esboço da etapa 2:
• Mais fundamentos do Python
o Listas
o Loopings
o Estruturas de decisão
o Manipulação de strings
o Colocando tudo junto
• Solução de problemas e obtenção de ajuda
o Problemas potenciais e diagnóstico rápido
o Usando o depurador do PythonWin
o Imprimindo mensagens do geoprocessador
o Outras fontes de ajuda
• Projeto 2: Reprojeção em lote de conjuntos de dados vetoriais
6
Etapa 4: Python Prático para o Analista de SIG
Nesta etapa abordam-se conceitos relativamente avançados que ajudarão você a se
tornar um programador SIG especialmente útil. Isso inclui a criação de código reutilizável por
meio de funções e módulos, análise de texto e gravação de feições geométricas em
conjuntos de dados vetoriais no ArcGIS. Na lição discute-se como usar arquivos em lote e
os utilitários de agendamento do sistema operacional para automatizar a execução de
scripts. Também se explica como automatizar algumas funções para layouts de mapas no
ArcMap usando Python.
As seções desta lição são mais longas e contêm exemplos de código mais complexos
do que as lições anteriores. Nesse ponto do curso, você deve ter conhecimento para
entender esses exemplos. O objetivo é que você se sinta confiante o suficiente para ler
qualquer script não familiar depois de concluir esta lição. Você também deve sentir que tem
conhecimento adquirido suficiente para abordar a maioria dos desafios de automação por
meio de scripts.
Esboço da etapa 4:
• Funções e módulos
• Leitura e análise de texto
• Geometrias de feições
• Automação com arquivos em lote e tarefas de agendamento
• Executando qualquer ferramenta da caixa de ferramentas
• Trabalhando com documentos de mapas
• Limitações do script Python no ArcGIS
• Projeto 4
Projeto Final
No final do curso, você é obrigado a concluir um projeto de script individual que aplica
o conhecimento que você adquiriu ao longo do curso. Você é encorajado a escolher um
projeto que seja útil para a sua pesquisa atual, se possível.
7
Etapa 1: Introdução à modelagem SIG e Python
Objetivos da etapa 1
8
• Automação torna o trabalho mais fácil. Depois de automatizar um processo,
você não precisa se esforçar tanto para lembrar quais ferramentas usar ou a sequência
correta em que elas devem ser executadas.
• Automação torna o trabalho mais rápido. Um computador pode abrir e
executar ferramentas em sequência muito mais rápido do que você pode realizar a
mesma tarefa apontando e clicando.
• A automação torna o trabalho mais preciso. Toda vez que você executa uma
tarefa manual em um computador, há uma chance de erro. A chance se multiplica com
o número e a complexidade das etapas em sua análise, bem como o cansaço incorrido
pela repetição da tarefa várias vezes. Em contraste, uma vez que uma tarefa
automatizada é configurada, um computador é confiável para executar a mesma
sequência de etapas a cada vez, para um número potencialmente infinito de ciclos.
O ArcGIS oferece três maneiras para os usuários automatizarem suas tarefas de
geoprocessamento. Essas três opções diferem na quantidade de habilidade necessária para
produzir a solução automatizada e na variedade de cenários que cada uma pode endereçar.
A primeira opção é construir um modelo usando o Model Builder. O Model Builder é um
programa interativo que permite ao usuário “encadear” ferramentas, usando a saída de uma
ferramenta como entrada em outra. Talvez o recurso mais atrativo do Model Builder seja que
os usuários podem automatizar fluxos de trabalho SIG bastante complexos sem a
necessidade de programação. Você aprenderá a usar o Model Builder no início deste curso.
Algumas tarefas de automação exigem maior flexibilidade do que a oferecida pelo
Model Builder e, para esses cenários, é recomendável que você escreva programas de
computador ou scripts curtos. A maior parte deste curso está relacionada com a escrita de
scripts.
Um script geralmente executa alguns procedimentos sequenciais de etapas. Dentro de
um script, você pode executar ferramentas SIG individualmente ou encadeá-las. Você pode
inserir lógica condicional em seu script para lidar com casos em que diferentes ferramentas
devem ser executadas, dependendo da saída da operação anterior. Você também pode
incluir iterações ou loops em um script para repetir uma única ação quantas vezes forem
necessárias para realizar uma tarefa.
Existem linguagens de script especiais para escrever scripts, incluindo Python, JScript
e Perl. Geralmente, essas linguagens têm uma sintaxe mais básica e são mais fáceis de
aprender do que outras linguagens, como C, Java ou Visual Basic.
Embora o ArcGIS suporte várias linguagens de script para trabalhar com suas
ferramentas, a ESRI enfatiza o Python em sua documentação e inclui o Python com a
instalação do ArcGIS. Neste curso, trabalharemos estritamente com o Python por esse
motivo, bem como o fato de que o Python pode ser usado para muitas outras tarefas de
manipulação de arquivos e dados fora do ArcGIS. Você aprenderá o básico sobre a
linguagem Python, como escrever um script e como manipular e analisar dados SIG usando
scripts. Por fim, você aplicará seu novo conhecimento em Python a um projeto final, no qual
escreverá um script de sua escolha que poderá aplicar diretamente ao seu trabalho.
Uma terceira opção disponível para os usuários do ArcGIS que procuram automatizar
o geoprocessamento é construir uma solução usando ArcObjects, os blocos de construção
de programação usados pelos próprios desenvolvedores da Esri para produzir os produtos
de desktop do ArcGIS. Com o ArcObjects, é possível customizar a interface do usuário para
incluir comandos e ferramentas específicas que extrapolam a capacidade das ferramentas
9
do ArcGIS prontas para uso ou as modificam para trabalhar de maneira mais focada. A
programação de ArcObjects e personalização de interface estão fora do escopo deste curso.
A customização SIG com ArcObjects pode ser um avanço, e aprender uma linguagem de
script como Python é uma boa maneira de se preparar aprendendo conceitos básicos de
programação.
As ferramentas que você executa no ModelBuilder e Python realmente usam
ArcObjects como base para executar as funções do SIG; No entanto, a vantagem do script
Python com o ArcGIS é que você não precisa aprender toda a lógica ArcObjects por trás das
ferramentas. Seu trabalho é apenas aprender as ferramentas e executá-las na ordem
apropriada para realizar sua tarefa.
Esta primeira lição apresentará conceitos de construção de modelo e redação de
scripts. Começaremos familiarizando-nos apenas com o modo como as ferramentas são
executadas no ArcGIS e como você pode usar essas ferramentas na interface do
ModelBuilder. Em seguida, abordaremos alguns dos princípios básicos do Python e veremos
como as ferramentas podem ser executadas nos scripts.
10
serão utilizadas para o buffer) e uma distância de buffer. Você também é obrigado a
indicar um local para o arquivo de saída (para o novo arquivo com o resultado da
operação de buffer).
• Muitas ferramentas também possuem parâmetros opcionais. Você pode
modificá-los se quiser, mas se não os fornecer, a ferramenta ainda será executada
usando os valores padrão. Para a ferramenta Buffer, os parâmetros opcionais são Side
Type, End Type, Dissolve Type e Dissolve Fields. Parâmetros opcionais são
normalmente especificados após os parâmetros requeridos.
• Clique no botão Show Help no canto inferior direito da ferramenta (se ele
mostrar Hide Help, você já estará visualizando a ajuda). Agora você pode clicar em
qualquer parâmetro na caixa de diálogo para ver uma explicação desse parâmetro na
janela da direita.
• Se você não tiver certeza do significado de um parâmetro, essa é uma boa
maneira de aprender. Por exemplo, com a ajuda ainda aberta, clique na caixa de entrada
Side Type na ferramenta Buffer (exatamente onde diz "FULL"). A Ajuda explica o que
significa o parâmetro Side Type e lista as diferentes opções: FULL, LEFT, RIGHT e
OUTSIDE_ONLY.
Se você precisar de mais ajuda, cada ferramenta é mais amplamente documentada na
Ajuda do ArcGIS Desktop (com exemplos do Python!). Você pode ir diretamente para a ajuda
da ferramenta Buffer clicando no botão Tool Help na caixa de diálogo da ferramenta, mas
você frequentemente desejará acessar essas páginas de ajuda sem abrir a própria
ferramenta. Abaixo estão os passos para fazer isso.
• No menu principal do ArcMap, clique em Help> ArcGIS Desktop Help.
Opcionalmente, para a ajuda mais atualizada, você pode usar a ajuda da Esri na Web.
• Na guia Sumário do sistema de Ajuda, expanda Tools> Tools Reference.
Observe que os tópicos de ajuda nesta seção estão organizados em caixas de
ferramentas e conjuntos de ferramentas, em paralelo ao layout das caixas de ferramentas
do sistema ArcGIS.
• Continue navegando no índice de ajuda para a Analisys toolbox> Proximity
toolset> Buffer. Percorra todo o tópico examinando todas as informações fornecidas
sobre a ferramenta Buffer. Aqui você obtém dicas sobre o que a ferramenta Buffer faz,
como usá-la e como fornecer todos os seus parâmetros.
• Ainda no tópico Buffer, role até a seção marcada Code sample. O tópico de
ajuda de cada ferramenta possui exemplos de programação que mostram maneiras de
executar a ferramenta automaticamente. Esses exemplos são escritos em Python e
serão extremamente valiosos para você conforme você conclui as tarefas neste curso.
Sempre verifique a Referência da Ferramenta de Geoprocessamento na Ajuda se estiver
com problemas para executar uma ferramenta em Python.
11
diretamente do Catálogo e usar a interface gráfica do usuário da ferramenta (GUI,
Graphic Unit Interface) para preencher os parâmetros.
• O ModelBuilder também é um aplicativo GUI no qual você pode configurar
ferramentas para executar em uma determinada sequência, usando a saída de uma
ferramenta como entrada para outra ferramenta.
• Se você estiver familiarizado com a ferramenta e quiser usá-la rapidamente no
ArcMap, talvez prefira a abordagem da janela de comandos Python. Você digita o nome
da ferramenta e os parâmetros necessários em uma janela de comando. Você pode usar
essa janela para executar várias ferramentas em uma linha e declarar variáveis,
efetivamente fazendo scripts simples.
• Se você quiser executar a ferramenta automaticamente, repetidamente ou
como parte de uma sequência lógica maior de ferramentas, poderá executá-la a partir de
um script. Executar uma ferramenta a partir de um script é a opção mais poderosa e
flexível.
Começaremos com o mais simples desses casos, executando uma ferramenta a partir
de sua GUI e indo para o script.
• Clique no botão Add data e navegue até os dados que você acabou de
extrair. Adicione os arquivos Limite e Sedes_Municipais.
• Abra a janela Catálogo, se necessário, e navegue até a ferramenta Buffer,
como fez na seção anterior.
• Clique duas vezes na ferramenta Buffer para abri-la.
• Examine o primeiro parâmetro necessário: Input features. Clique no botão
Browse e navegue até o caminho do conjunto de dados de cidades
C:\SEA5923\Dados\Sedes_Municipais.shp. Observe que, quando você fizer isso, um
caminho será fornecido automaticamente para a classe de feições de saída. O software
faz isso apenas para sua conveniência e você pode alterar o caminho se quiser.
• Uma maneira mais conveniente de fornecer os parâmetros de entrada é
apenas selecionar a camada de mapa de cidades no menu suspenso. Esta lista
suspensa contém automaticamente todas as camadas no seu documento de mapa. No
12
entanto, neste exemplo, navegamos para o caminho dos dados porque é
conceitualmente semelhante a como forneceremos os caminhos na linha de comando e
nos ambientes de script.
• Agora você precisa fornecer o parâmetro Distance para o buffer. Para esta
execução da ferramenta, defina uma unidade linear (Linear Unit) de 5 Km. Quando
executamos a ferramenta a partir dos outros ambientes, aumentaremos ligeiramente a
distância do buffer, por isso sabemos que temos saídas distintas.
• O restante dos parâmetros é opcional. Os parâmetros Side Type e End Type
aplicam-se somente a linhas e polígonos, portanto, eles nem estão disponíveis para
configuração no ambiente da GUI ao trabalhar com pontos das cidades. No entanto,
altere o Dissolve Type para ALL. Isso combina buffers sobrepostos em um único
polígono.
• Clique em OK para executar a ferramenta.
• A ferramenta deve levar apenas alguns segundos para ser concluída. Examine
a saída que aparece no mapa e faça uma “verificação” para se certificar de que os buffers
apareçam ao redor das cidades e eles parecem ter cerca de 5 quilômetros de raio. Você
pode precisar aumentar o zoom para ver os buffers.
• Clique no menu Geoprocessing e clique em Results. Esta janela lista
mensagens sobre sucessos ou falhas de todas as ferramentas recentes que você
executou.
• Expanda a ferramenta Buffer até que você possa ver todas as mensagens. Eles
listam os parâmetros da ferramenta, o tempo de conclusão e quaisquer problemas que
ocorreram durante a execução da ferramenta. (veja a figura) Essas mensagens podem
ser de grande ajuda mais tarde, quando você soluciona problemas de seus scripts
Python. O texto dessas mensagens está disponível se você executar a ferramenta a partir
da GUI, da janela do Python no ArcMap ou de scripts.
13
Um conjunto de ferramentas encadeadas dessa maneira é chamado de modelo. Os
modelos podem ser simples, consistindo em apenas algumas ferramentas, ou complexos,
consistindo em muitas ferramentas e parâmetros e, ocasionalmente, em alguma lógica
iterativa. Seja grande ou pequeno, o benefício de um modelo é que ele resolve um problema
geográfico único que não pode ser resolvido por uma das ferramentas “out-of-the-box”.
No ArcGIS, a modelagem pode ser feita através da interface gráfica do usuário
ModelBuilder (GUI) ou através de código, usando Python. Para manter nossos termos claros,
vamos nos referir a qualquer coisa construída no ModelBuilder como um “modelo” e qualquer
coisa construída através do Python como um “script”. No entanto, é importante lembrar que
ambas as coisas estão fazendo modelagem.
14
seguida pela ferramenta Intersect e, em seguida, pela ferramenta Clip, você pode configurá-
las no ModelBuilder para serem executadas como um processo.
• Crie um novo documento de mapa no ArcMap e adicione os shapefiles
Sedes_Municipais, Rodovias e Limite da pasta de dados que você configurou
anteriormente nesta lição. Salve seu documento de mapa como
C:\SEA5923\Modelos.mxd.
• No ArcGIS, todos os modelos são armazenados em caixas de ferramentas. A
primeira coisa que você precisa fazer é criar uma caixa de ferramentas para armazenar
seu novo modelo. Se a janela Catálogo já não estiver visível, exiba-a clicando no item de
menu Windows> Catalog.
• Na janela Catálogo, expanda os nós até ver as Toolboxes> My Tollboxes.
• Clique com o botão direito em My Toolboxes e clique em New> Toolbox.
Nomeie-o como SEA5923. (O software pode adicionar .tbx, o que é bom)
• Clique com o botão direito do mouse na caixa de ferramentas SEA5923.tbx e
clique em New> Model. Você verá o ModelBuilder aparecer.
• No ModelBuilder, clique em Model> Model Properties.
• Para o Name, digite “Aptidao” e, para o Label, digite “Localizar áreas com
aptidão”. O rótulo é o que todos verão quando abrirem sua ferramenta no catálogo. É por
isso que pode conter espaços. O nome é o que as pessoas usarão se alguma vez
executarem seu modelo a partir do Python. É por isso que não pode conter espaços.
• Clique em OK para descartar a caixa de diálogo Propriedades do modelo.
Agora você tem uma tela em branco na qual você pode arrastar e soltar as
ferramentas. Ao criar um modelo (e ao escrever scripts em Python), é melhor dividir
seu problema em partes gerenciáveis. O problema simples de seleção de “sites”
aqui pode ser considerado como quatro etapas:
• Buffer para as cidades
• Buffer para as estradas
• Intersectar os buffers
• Clipe para a região de limite
Vamos abordar esses itens um de cada vez, começando com o buffer das cidades.
• Com o ModelBuilder ainda aberto, vá para a janela Catálogo e navegue até
Toolboxes > System Toolboxes > Analysis Tools > Proximity.
• Clique na ferramenta Buffer e arraste-a para a tela ModelBuilder. Você verá
uma caixa retangular branca representando a ferramenta de buffer e uma forma oval
branca representando os buffers de saída. Eles estão conectados a uma linha,
mostrando que a ferramenta Buffer sempre produzirá um conjunto de dados de saída.
No ModelBuilder, as ferramentas são representadas com caixas e as variáveis são
representadas com ovais. No momento, a ferramenta Buffer, no centro, é branca
porque você ainda não forneceu os parâmetros necessários. Depois de fazer isso,
a ferramenta e a variável serão preenchidas com cor.
15
• Na janela ModelBuilder, clique duas vezes na caixa Buffer. O diálogo da
ferramenta aqui é o mesmo que se você tivesse aberto o Buffer diretamente do
ArcToolbox. É aqui que você pode fornecer parâmetros para a ferramenta.
• Para Input Features, navegue até o caminho do arquivo shape
Sedes_Municipais. A classe de feições de saída será preenchida automaticamente.
• Para Distance [value or field], insira 5 Kilometer.
• Para Dissolve Type, selecione ALL e clique em OK para fechar a caixa de
diálogo Buffer. Os elementos do modelo (ferramentas e variáveis) devem ser
preenchidos com cor e você deve ver um novo elemento à esquerda da ferramenta que
representa a classe de feições de cidades como entrada.
• Uma parte importante do trabalho com o ModelBuilder é fornecer rótulos claros
para todos os elementos. Dessa forma, se você compartilhar seu modelo, os outros
poderão entender facilmente o que acontecerá quando for executado. Fornecer rótulos
claros também ajuda você a lembrar o que o modelo faz, especialmente se você não
trabalhar com o modelo por algum tempo.
• No ModelBuilder, clique com o botão direito do mouse no elemento
Sedes_Municipais.shp (oval azul, à esquerda) e clique em Rename. Nomeie esse
elemento como "Cidades".
• Clique com o botão direito na ferramenta Buffer (caixa amarelo-laranja, no
centro) e clique em Rename. Nomeie isso "Buffer das cidades".
• Clique com o botão direito do mouse no elemento
Sedes_MuniciapaisBuffer1.shp (oval verde, à direita) e clique em Rename. Nomeie isso
como "Cidades com buffer". Seu modelo deve se parecer com isso.
A aparência do modelo.
• Salve seu modelo (Model> Save). Este é o tipo de atividade em que você
deseja salvar com frequência.
• Pratique o que você acabou de aprender adicionando outra ferramenta Buffer
ao seu modelo. Desta vez, configure a ferramenta para que ela armazene o arquivo
shape Rodovias com 20 km. Lembre-se de definir o tipo Dissolve para ALL e adicionar
rótulos significativos. Seu modelo deve agora se parecer com isso.
16
A aparência do modelo após o passo acima.
• A próxima tarefa é interceptar os buffers. Na lista de caixas de ferramentas da
janela Catálogo, navegue até Analysis Tools> Overlay e arraste a ferramenta Intersect
para o seu modelo. Posicione-o à direita das ferramentas do Buffer existentes.
• Aqui está o momento crucial em que você encadeia as ferramentas, definindo
as saídas de suas ferramentas Buffer como entradas da ferramenta Intersect. Clique na
ferramenta Connect e , em seguida, clique no elemento Cidades com buffer seguido
pelo elemento Intersect. Se você vir um pequeno menu, clique em Input Features para
indicar que as cidades em buffer agem como entradas para a ferramenta Intersect. Uma
seta agora apontará do elemento Cidades com buffer para o elemento Intersect.
• Use o mesmo processo para conectar as Rodovias com buffer ao elemento
Intersect. Novamente, se solicitado, clique em Input Features.
• Renomeie a saída da operação Intersect como "Intersected buffers". Se o texto
for executado em várias linhas, você poderá clicar e arrastar as bordas do elemento para
redimensioná-lo. Você também pode reorganizar os elementos na página da forma que
desejar. Como os modelos podem ficar grandes, o ModelBuilder contém vários botões
de navegação para ampliar e aplicar zoom em toda a extensão do modelo.
Seu modelo deve estar assim:
17
Catálogo, navegue até Analysis Tools> Extract e arraste a ferramenta Clip para o
ModelBuilder. Posicione essa ferramenta à direita de suas ferramentas existentes.
• Use a ferramenta Connect novamente para definir os buffers interceptados
como uma entrada para a ferramenta Clip, escolhendo Input Features quando solicitado.
Observe que, mesmo quando você faz isso, a ferramenta Clip não está pronta para ser
executada (ela ainda é mostrada como um retângulo branco, localizado à direita). Você
precisa fornecer o parâmetro de recorte, que é o contorno para a qual os buffers serão
cortados.
• No ModelBuilder (não na janela Catálogo), clique duas vezes na ferramenta
Clip. Defina o parâmetro navegando até o caminho de Limite.shp e clique em OK para
fechar a caixa de diálogo. Você notará que um oval azul apareceu representando a Clip
Features (Limite).
• Defina rótulos significativos para as ferramentas restantes, conforme mostrado
o exemplo abaixo de como você pode rotular e organizar os elementos do modelo.
18
A saída do modelo no ArcMap.
É isso aí! Você acabou de usar o ModelBuilder para encadear várias ferramentas e
resolver um problema de SIG.
Você pode clicar duas vezes nesse modelo a qualquer momento na janela Catálogo e
executá-lo como faria com uma ferramenta. Se você fizer isso, notará que o modelo não
possui parâmetros; você não pode alterar a distância do buffer ou os recursos de entrada. A
verdade é que nosso modelo é útil para resolver esse problema específico de seleção de
sites com esses conjuntos de dados específicos, mas não é muito flexível. Na próxima seção
da lição, tornaremos esse modelo mais versátil, configurando algumas das variáveis como
parâmetros de entrada e saída.
Parâmetros do modelo
A maioria das ferramentas, modelos e scripts criados com o ArcGIS possuem
parâmetros. Parâmetros de entrada são valores com os quais a ferramenta (ou modelo ou
script) inicia seu trabalho e os parâmetros de saída representam o que a ferramenta fornece
como resultado após o término de sua execução.
Uma ferramenta, modelo ou script sem parâmetros só serve em um cenário específico.
Considere o modelo que você acabou de criar que usava as ferramentas Buffer, Intersect e
Clip. Esse modelo foi codificado para usar os arquivos shapefiles Sedes_Municipais,
Rodovias e Limite e gerar um shapefile chamado AreaAptidao. Em outras palavras, se você
quisesse executar o modelo com outros conjuntos de dados, teria que abrir o ModelBuilder,
clicar duas vezes em cada elemento (Cidades, Rodovias, Limite e Área de Aptidão) e alterar
19
os caminhos que foram gravados diretamente no modelo. Você teria que seguir um processo
semelhante se também quisesse alterar as distâncias de buffer, já que elas eram codificadas
a 5 quilômetros.
Vamos modificar esse modelo para usar alguns parâmetros, para que você possa
executá-lo facilmente com diferentes conjuntos de dados e distâncias de buffer.
• Se ainda não estiver aberto, abra o documento do mapa
C:\SEA5923\Modelos.mxd no ArcMap.
• Na janela Catalog, encontre o modelo criado na lição anterior, que deve estar
em Toolboxes> My Toolboxes> SEA5923> Localizar áreas de aptidão.
• Clique com o botão direito no modelo Localizar áreas de aptidão e clique em
Copy. Agora clique com o botão direito do mouse na caixa de ferramentas SEA5923 e
clique em Paste. Isso cria uma nova cópia do seu modelo com a qual você pode trabalhar
para criar parâmetros de modelo. Usando uma cópia do modelo como este permite que
você facilmente comece de novo se você cometer um erro.
• Renomeie a cópia do seu modelo Localizar áreas de aptidão com
parâmetros ou algo similar.
• Na sua caixa de ferramentas SEA5923, clique com o botão direito do mouse
em Localizar áreas de aptidão com parâmetros e clique em Edit. Você verá o modelo
aparecer no ModelBuilder.
• Clique com o botão direito do mouse no elemento Cidades (deve ser um oval
azul) e clique em Model Parameter. Isso significa que quem quer que execute o modelo
deve especificar o conjunto de dados de cidade a ser usado antes que o modelo possa
ser executado.
• Mesmo que você tenha "parametrizado" as cidades, seu modelo ainda usa o
conjunto de dados C:\SEA5923\Dados\Sedes_Municipais.shp. Isso não fará muito
sentido se você compartilhar seu modelo ou caixa de ferramentas com outras pessoas,
pois elas podem não ter o mesmo arquivo shape e, mesmo se o tenham, provavelmente
não estarão no mesmo caminho em suas máquinas.
• Para remover o conjunto de dados padrão, clique duas vezes no elemento
Cidades, exclua o caminho e clique em OK. Alguns dos elementos do seu modelo podem
ficar brancos. Isso significa que um valor deve ser fornecido antes que o modelo possa
ser executado com sucesso.
• Agora você precisa criar um parâmetro para a distância do buffer a ser criado
em torno das cidades. Clique com o botão direito do mouse no elemento que você
chamou de "Buffer das cidades" e clique em Make Variable> From Parameter>
Distance [value or field].
• A etapa anterior criou um novo elemento Distance. Renomeie este elemento
para "Distância" e torne-o um parâmetro de modelo. (Revise as etapas acima se não tiver
certeza sobre como renomear um elemento ou torná-lo um parâmetro de modelo.) Para
este elemento, você pode deixar o padrão em 5 quilômetros.
• Repetindo o que você aprendeu acima, altere o elemento Rodovias, torne-o um
parâmetro de modelo e remova o valor padrão.
• Repetindo o que você aprendeu acima, crie um parâmetro para a distância do
buffer de rodovias. Deixe o padrão em 5 quilômetros.
20
• Repetindo o que você aprendeu acima, altere o elemento Limite, torne-o um
parâmetro de modelo e remova o valor padrão. Seu modelo deve ficar assim (observe
os cinco parâmetros indicados por "P" s):
O modelo "Localizar áreas de aptidão com parâmetros " seguindo o passo acima, e
mostrando cinco parâmetros.
• Salve seu modelo e feche o ModelBuilder.
• Clique duas vezes no modelo SEA5923> Localizar áreas de aptidão com
parâmetros e examine o diálogo da ferramenta. Deve ser semelhante a isto:
21
• Teste seu modelo fornecendo os arquivos Sedes_Municipais, Rodovias e
Limite para os parâmetros do modelo. Se você quiser, você pode tentar mudar a distância
do buffer.
Note que às vezes o resultado não se adiciona ao display como deveria. Você deve
ser capaz de adicioná-lo ao display usando o botão Add Data e navegando até o
local AreaAptidao.shp.
O exercício acima demonstrou como você pode expor valores como parâmetros
usando o ModelBuilder. Você precisa decidir quais valores deseja que o usuário possa
alterar e designar esses como parâmetros. Quando você escreve scripts em Python, também
é necessário identificar e expor parâmetros de maneira semelhante.
22
o curso. Alguns dos conceitos neles são mais fáceis de entender uma vez que você tenha
trabalhado com geoprocessamento por um tempo.
Um tour rápido pelo gerenciamento de dados intermediários
(http://desktop.arcgis.com/en/arcmap/latest/analyze/modelbuilder/a-quick-tour-of-managing-
intermediate-data.htm)
Usando os ambientes de espaço de trabalho atual e de rascunho
(http://desktop.arcgis.com/en/arcmap/latest/analyze/executing-tools/using-the-current-and-scratch-
workspace-environments.htm)
Gerenciando dados intermediários (scratch) no modelo compartilhado e nas
ferramentas de script (http://desktop.arcgis.com/en/arcmap/latest/analyze/sharing-
workflows/managing-intermediate-data-in-models-and-scripts.htm)
Looping no ModelBuilder
Loop, ou iteração, é o ato de repetir um processo. Um dos principais benefícios dos
computadores é sua capacidade de repetir rapidamente tarefas que, de outra forma, seriam
rotineiras, incômodas ou passíveis de erros para um ser humano repetir e gravar. O looping
é um conceito-chave em programação de computadores e você o usará com frequência ao
escrever scripts em Python para esse curso.
O ModelBuilder contém um número de elementos chamados Iteradores que podem
fazer looping de várias maneiras. Os nomes desses iteradores, como For e While, na
verdade, imitam os tipos de loop que você pode programar em Python ou em outras
linguagens. Neste curso, vamos nos concentrar em aprender iteração em Python, o que
pode ser tão fácil quanto aprender como usar um iterador ModelBuilder.
Para dar uma olhada em como a iteração funciona no ModelBuilder, você pode visitar
o manual de ajuda do ArcGIS Desktop para iteração de modelo
(http://desktop.arcgis.com/en/arcmap/latest/analyze/modelbuilder/a-quick-tour-of-using-
iterators-for-iteration-looping-.htm). Se você tiver problemas para entender o loop em lições
posteriores, o ModelBuilder pode ser um bom ambiente para visualizar o que um loop faz.
Você pode voltar e visitar a ajuda conforme necessário.
Leituras
Leia Zandbergen Chapter 2.1 - 2.9 para reforçar o que você aprendeu sobre
geoprocessamento e ModelBuilder.
23
• Na barra de ferramentas Standard, clique no botão Python Windows.
Quando a janela aparecer, arraste-a para o lado ou para baixo da tela para encaixá-la.
• Digite o seguinte na janela do Python (Não digite o >>>. Eles são incluídos
apenas para mostrar onde as novas linhas começam na janela do Python.)
>>> import arcpy
>>> arcpy.Buffer_analysis ("Sedes_Municipais", "Cidades_buffer_15km",
"15 kilometers", "", "", "ALL")
• Amplie e examine os buffers criados.
Você acabou de executar seu primeiro comando de Python. Você não precisa
entender tudo sobre o código que escreveu nesta janela, mas aqui estão algumas
coisas importantes a serem observadas.
A primeira linha do script “Import arcpy” informa ao interpretador Python (que foi
instalado quando você instalou o ArcGIS) que você irá trabalhar com algumas funções e
ferramentas especiais de script incluídas no ArcGIS. Sem essa linha de código, o Python
não sabe nada sobre o ArcGIS, então você o colocará no topo de todos os códigos
relacionados ao ArcGIS que você escreverá nesta classe. Você tecnicamente não precisa
desta linha quando você trabalha com a janela do Python no ArcMap porque o arcpy já é
importado, mas eu queria mostrar esse padrão antes; você vai usá-lo em todos os scripts
que você escrever fora da janela do Python.
A segunda linha do script, na verdade, executa a ferramenta. Você pode digitar arcpy,
acompanhado de um ponto, além de qualquer nome de ferramenta do ArcGIS para executá-
la no Python. Observe aqui que você também coloca um underscore seguido pelo nome da
caixa de ferramentas que inclui a ferramenta que irá utilizar. Isso é necessário porque
algumas ferramentas em diferentes caixas de ferramentas realmente têm o mesmo nome
(como o Clip, que é uma ferramenta para recortar vetores na caixa de ferramentas Analysis
ou ferramenta para recorte de rasters na caixa de ferramentas Data Management).
Depois de digitar arcpy.Buffer_analysis, você digitou todos os parâmetros para a
ferramenta. Cada parâmetro foi separado por uma vírgula e toda a lista de parâmetros foi
colocada entre parênteses. Acostume-se com esse padrão, já que você o seguirá com todas
as ferramentas executadas neste curso.
Nesse código, também fornecemos alguns parâmetros opcionais, deixando aspas
vazias onde queríamos obter os valores padrão e truncando a lista de parâmetros no
parâmetro opcional final que queríamos definir.
Como você conhece a sintaxe ou estrutura dos parâmetros a serem inseridos? Por
exemplo, para a distância do buffer, você deve inserir 15KILOMETERS, '15Kilometers', 15
Km ou '15 kilometers'? A melhor maneira de responder a perguntas como essas é retornar
ao tópico da ajuda de referência da ferramenta Geoprocessing para a ferramenta Buffer.
Todos os tópicos nesta seção de referência possuem uma seção de uso e exemplo de linha
de comando para ajudá-lo a entender como estruturar os parâmetros. Parâmetros opcionais
são colocados entre chaves, enquanto os parâmetros necessários não são. Do exemplo
neste tópico, você pode ver que a distância do buffer deve ser especificada como '15
kilometers'. Como há um espaço nesse texto ou string, você precisa cercá-lo com aspas.
Você deve ter notado que a janela do Python ajuda a mostrar diferentes opções que
você pode digitar para cada parâmetro. Isso é chamado de autocompletar, e pode ser muito
útil se você estiver tentando executar uma ferramenta pela primeira vez e não souber
exatamente como digitar os parâmetros.
24
Existem algumas diferenças entre escrever código na janela do Python e escrever
código em algum outro programa, como o Notepad ou o Python Scripter. Na janela do
Python, você pode fazer referência a camadas no documento do mapa apenas por seus
nomes, em vez de seus caminhos de arquivo. Assim, conseguimos digitar
"Sedes_Municipais" em vez de algo como "C:\\SEA5923\\Dados\\Sedes_Municipais.shp".
Também conseguimos criar o nome de uma nova camada "Cidades_buffer_15km" e incluí-
la no mapa por padrão após a execução do código. Se você for usar seu código fora da
janela do Python, certifique-se de usar os caminhos completos.
Quando você escreve scripts mais complexos, será útil usar um ambiente de
desenvolvimento integrado (IDE), ou seja, um programa projetado especificamente para
ajudá-lo a escrever e testar o código Python. Mais adiante neste curso, exploraremos o IDE
do PythonWin.
Anteriormente nesta lição você viu como as ferramentas podem ser encadeadas para
resolver um problema usando o ModelBuilder. O mesmo pode ser feito em Python, mas será
necessário um pouco de trabalho para chegar a esse ponto. Por esse motivo, passaremos
o restante da Aula 1 cobrindo alguns dos princípios básicos do Python.
Leituras
Reserve alguns minutos para ler o capítulo 3 de Zandbergen, um capítulo relativamente
curto, onde ele explica a janela do Python e algumas coisas que você pode fazer com ela.
O que é o Python?
Python é uma linguagem usada para automatizar tarefas de computação por meio de
programas chamados scripts. Na introdução desta lição, você aprendeu que a automação
torna o trabalho mais fácil, mais rápido e mais preciso. Isso se aplica ao SIG e muitas outras
áreas da ciência da computação. O aprendizado de Python fará de você um analista GIS
mais eficaz, mas a programação em Python é uma habilidade técnica que pode ser benéfica
para você mesmo fora do campo de SIG.
O Python é uma boa linguagem para iniciar a programação. O Python é uma linguagem
de alto nível, o que significa que você não precisa entender como os computadores
funcionam para usá-la. A sintaxe do Python (como as instruções de código são construídas)
é relativamente simples de ler e entender. Por fim, o Python requer muito pouco para colocar
um programa em funcionamento.
O Python é uma linguagem de código aberto e não há custos para usá-la ou implantar
programas nela. O Python pode ser executado nos sistemas operacionais Windows, Linux
e Unix.
No ArcGIS, o Python pode ser usado praticamente como um atalho, o que significa que
você pode usá-lo para executar facilmente ferramentas de geoprocessamento como a
ferramenta Buffer com a qual trabalhamos. Você poderia codificar toda a lógica do buffer,
usando uma programação mais detalhada com o ArcObjects, mas isso seria demorado e
desnecessário na maioria dos cenários; sendo mais fácil apenas chamar a ferramenta Buffer
de um script Python usando uma linha de código.
25
Além da ajuda ESRI que descreve todos os parâmetros de uma função e como acessá-
los a partir do Python, você também pode obter a sintaxe Python (a estrutura da linguagem)
para uma ferramenta da seguinte forma:
• Execute a ferramenta interativamente (por exemplo, buffer) com seus dados de
entrada, dados de saída e quaisquer outros parâmetros relevantes (por exemplo,
distância ao buffer)
• Vá para a janela Geoprocessing -> Results e clique com o botão direito do
mouse na execução da ferramenta concluída.
• Escolha "Copy as Python Snippet"
• Cole o código no PythonWin ou na janela de código Python para ver como você
codificaria a mesma operação que você acabou de executar no Desktop no Python.
Instalando o PythonWin
Se você instalou uma versão do ArcGIS, você já deve ter o Python em seu computador,
normalmente em uma pasta chamada algo como C:\Python27\ArcGIS10.x\. Você pode
escrever código Python a qualquer momento no Bloco de Notas ou em outros editores e
salvá-lo como um arquivo .py, mas é necessário ter o Python instalado para que seu
computador possa entender e executar o programa.
Neste curso, estaremos trabalhando com o Python versão 2.7.x. Se você verificar a
página de download do Python em sua home page em www.python.org (novamente, você
não precisará baixar o Python, apenas dê uma olhada!), Você verá que existem versões
realmente superiores do Python acessível. As versões 3 e superiores do Python contêm
algumas mudanças importantes que levaram algum tempo para a comunidade de usuários
do Python e a ESRI adotarem.
O Python vem com um editor padrão simples chamado IDLE; no entanto, neste curso,
você usará o ambiente de desenvolvimento integrado (IDE) do PythonWin para ajudá-lo a
escrever código.
O PythonWin é gratuito, tem recursos básicos de depuração. Nós aqui iremos baixar e
instalar a versão do PythonWin do repositório PythonWin GitHub em
https://github.com/mhammond/pywin32/releases . É importante que você use a versão
"win32" para Python 2.7 e não os executáveis “amd64" que são para instalar a versão de 64
bits do PythonWin, que é compatível apenas com o ArcGIS for Server, não com o ArcGIS
for Desktop.
Por favor siga as instruções abaixo:
• Baixe o arquivo de instalação do PythonWin neste link:
https://github.com/mhammond/pywin32/releases/download/b224/pywin32-224.win32-
py2.7.exe
• Inicie a instalação iniciando o arquivo baixado pywin32-2xx.win32-py2.7.exe.
(Se você estiver usando o Windows Vista ou o Windows 7, clique com o botão direito do
mouse nesse arquivo e escolha Executar como administrador e, quando solicitado,
escolha Permitir que ele seja executado.)
26
• Clique em Avançar através do assistente para instalar o PythonWin.
• O PythonWin não coloca um atalho do Windows em lugar algum, então você
pode fazer um você mesmo. Quando a instalação estiver concluída, use Meu
Computador (ou "Computador") para procurar o local onde você instalou o PythonWin.
Provavelmente está em C:\Python27\ArcGIS10.x\Lib\site-packages\pythonwin.
• Clique com o botão direito do mouse no item PythonWin.exe e clique em Criar
atalho. Você deve ver um atalho do Windows aparecer imediatamente abaixo do item
PythonWin.
• Arraste e solte o atalho na sua área de trabalho ou onde quer que você queira
colocá-lo.
No Windows Vista ou Windows 7, se você vir mensagens de erro durante a instalação,
é provável que você não tenha executado a instalação como um Administrador. Ao iniciar a
instalação, clique com o botão direito do mouse e escolha Executar como administrador.
Explorando o PythonWin
Aqui está uma breve explicação das principais partes do PythonWin. Antes de começar
a ler, abra o PythonWin para que você possa acompanhar.
Quando o PythonWin abrir, você verá o que é conhecido como a Janela Interativa. Você
pode digitar uma linha de Python no prompt >>> e ela imediatamente executará e imprimirá
o resultado, se houver um resultado imprimível. A Janela Interativa pode ser um bom lugar
para praticar com o Python neste curso, e sempre que você vir algum código Python ao lado
do prompt >>> nos materiais da lição, isso significa que você pode digitá-lo na Janela
Interativa para acompanhar. Desta forma, a Janela Interativa é muito semelhante à janela
do Python no ArcGIS.
27
contém ferramentas para carregar, executar e salvar scripts. Esta barra de ferramentas
é visível por padrão. Observe os botões Undo / Redo , que podem ser úteis para
você como programador se você começar a codificar algo e perceber que percorreu o
caminho errado, ou se você excluir uma linha de código e quiser recuperá-la. Observe
também o botão Execute , que parece uma pequena pessoa correndo. Essa é uma boa
maneira de testar seus scripts sem precisar clicar duas vezes no arquivo no Windows
Explorer.
A barra de ferramentas de Debugging
contém ferramentas para revisar cuidadosamente seu código linha por linha para
ajudá-lo a detectar erros. Esta barra de ferramentas é visível clicando em View > Toolbar >
Debugging. A barra de ferramentas Depuração é extremamente valiosa para você como
programador e você aprenderá a usá-la posteriormente neste curso. Essa barra de
ferramentas é um dos principais motivos para usar um Ambiente de Desenvolvimento
Integrado (IDE) em vez de gravar seu código em um editor de texto simples como o Bloco
de Notas.
28
Você acabou de criar ou declarou uma variável x e definir seu valor como 2. Em
algumas linguagens de programação fortemente tipificadas, como Java, você precisaria
informar ao programa que estava criando uma variável numérica, mas o Python assume isso
quando você digita o 2.
Quando você aperta Enter, nada acontece, mas o programa agora tem essa variável
na memória. Para provar isso, digite:
>>> x + 3
Você vê a resposta desta expressão matemática, 5, aparecer imediatamente na Janela
Interativa, provando que sua variável foi lembrada e usada.
Você também pode usar o comando print para gravar os resultados das operações.
Nós vamos usar muito isso quando praticar e testar código.
>>> print (x + 3)
5
Variáveis também podem representar palavras ou cadeias de caracteres, como são
referidas pelos programadores. Tente digitá-lo na janela interativa:
>>> meuTime = "Time do bairro"
>>> print (meuTime)
Time do bairro
Neste exemplo, as aspas informam ao Python que você está declarando uma variável
de string. Python é uma linguagem poderosa para trabalhar com strings. Um exemplo muito
simples de manipulação de strings é adicionar ou concatenar duas strings, desta forma:
>>> string1 = "Nós Somos"
>>> string2 = "EESC USP!"
>>> print (string1 + string2)
Nós somos EESC USP!
Você pode incluir um número em uma variável de string colocando-o entre aspas, mas
depois deve tratá-lo como uma string; você não pode tratá-lo como um número. Por exemplo,
isso resulta em um erro:
>>> meuValor = "3"
>>> print (meuValor + 2)
Nestes exemplos você viu o uso do sinal = para atribuir o valor da variável. Você
sempre pode reatribuir a variável. Por exemplo:
>>> x = 5
>>> x = x - 2
>>> print (x)
3
Ao nomear suas variáveis, as dicas a seguir ajudarão você a evitar erros.
• Nomes de variáveis diferenciam maiúsculas de minúsculas. minhaVariavel é
uma variável diferente do MinhaVariavel.
29
• Nomes de variáveis não podem conter espaços.
• Nomes variáveis não podem começar com um número.
• Uma prática recomendada para variáveis Python é nomear a variável
começando com uma letra minúscula e, em seguida, começar cada palavra subseqüente
com uma letra maiúscula. Isso às vezes é conhecido como invólucro de camelo. Por
exemplo: minhaVariavel, minhaSegundaVariavel, tabelaRodovias, campoBuffer1, etc.
• As variáveis não podem ser nenhuma das palavras reservadas especiais do
Python, como "import" ou "print".
Torne os nomes das variáveis significativos para que os outros possam ler facilmente
o seu código. Isso também ajudará você a ler seu código e evitar cometer erros.
Você terá muita experiência trabalhando com variáveis ao longo deste curso e
aprenderá mais em lições futuras.
Leituras
Leia o capítulo 4.5 de Zandbergen (Variables and naming).
O Capítulo 4 aborda os fundamentos da sintaxe Python, loops, strings e outras coisas
que veremos mais detalhadamente adiante, mas sinta-se à vontade para ler um pouco agora
se tiver tempo.
30
• Coloque um pouco de manteiga de amendoim na faca.
• etc.
• etc.
Se fôssemos escrever o programa em uma linguagem orientada a objeto, poderia ser
assim:
• mySandwich = Sandwich.Make
• mySandwich.pão = Trigo
• mySandwich.Adiciona (manteiga de amendoim)
• mySandwich.Adiciona (geleia)
No exemplo orientado a objetos, a maior parte das etapas foi eliminada. O objeto
sanduíche "sabe como" se construir, dado apenas algumas informações. Esse é um recurso
importante de linguagens orientadas a objetos conhecidas como encapsulamento.
Observe que você pode definir as propriedades do sanduíche (como o tipo de pão) e
executar métodos (lembre-se de que são ações) no sanduíche, como adicionar a manteiga
de amendoim e a geleia.
Classes
A razão pela qual é tão fácil "fazer um sanduíche" em uma linguagem orientada a
objetos é que algum programador, em algum lugar, já fez o trabalho para definir o que é um
sanduíche e o que você pode fazer com ele. Ele ou ela fez isso usando uma Classe. Uma
classe define como criar um objeto, as propriedades e os métodos disponíveis para esse
objeto, como as propriedades são definidas e usadas e o que cada método faz.
Uma classe pode ser considerada como uma planta para criar objetos. O blueprint
determina quais propriedades e métodos um objeto dessa classe terá. Uma analogia comum
é a de uma fábrica de automóveis. Uma fábrica de carros produz milhares de carros do
mesmo modelo, todos construídos no mesmo modelo básico. Da mesma forma, uma classe
produz objetos que possuem as mesmas propriedades e métodos predefinidos.
Em Python, as classes são agrupadas em módulos. Você importa módulos em seu
código para dizer ao seu programa com quais objetos você estará trabalhando. Você mesmo
pode escrever módulos, mas provavelmente você os importará de outras partes ou pacotes
de software. Por exemplo, a primeira linha da maioria dos scripts que você escreve neste
curso será:
import arcpy
Aqui você está usando a palavra-chave import para dizer ao seu script que você estará
trabalhando com o módulo arcpy, que é fornecido como parte do ArcGIS. Depois de importar
este módulo, você pode criar objetos que alavancam o ArcGIS em seus scripts.
Outros módulos que você pode importar neste curso são OS (permite que você trabalhe
com o sistema operacional), Randon (permite a geração de números aleatórios), CSV
(permite a leitura e gravação de arquivos de planilha em formato de valor separado por
vírgula), e Math (permite que você trabalhe com operações matemáticas avançadas). Esses
31
módulos estão incluídos no Python, mas não são importados por padrão. Uma prática
recomendada para manter seus scripts rápidos é importar apenas os módulos necessários
para esse script específico. Por exemplo, embora possa não causar erros no seu script, você
não incluiria a importação arcpy em um script que não requer nenhuma função do ArcGIS.
Leituras
Leia o capítulo 5.8 (Classes) de Zandbergen para mais informações sobre classes.
Herança
Outra característica importante das linguagens orientadas a objetos é a herança. As
classes são organizadas em um relacionamento hierárquico, de modo que cada classe herda
suas propriedades e métodos da classe acima na hierarquia (sua classe pai ou superclasse).
Uma classe também passa suas propriedades e métodos para a classe abaixo dela (sua
classe filha ou subclasse).
Uma analogia do mundo real envolve a classificação de espécies animais. Como
espécie, temos muitas características exclusivas dos seres humanos. No entanto, também
herdamos muitas características de classes superiores na hierarquia de classes. Temos
algumas características como resultado de sermos vertebrados. Temos outras
características como resultado de sermos mamíferos. Para ilustrar o ponto, pense na
capacidade dos humanos de correr. Nossos corpos respondem ao nosso comando de correr
não porque pertencemos à classe "humana", mas porque herdamos essa característica de
alguma classe superior na hierarquia de classes.
De volta ao contexto de programação, a lição a ser aprendida é que vale a pena saber
onde uma classe se encaixa na hierarquia de classes. Sem essa informação, você não terá
conhecimento de todas as operações disponíveis para você. Essas informações sobre
heranças podem ser encontradas em pôsteres informativos chamados diagramas de
modelos de objetos.
Aqui está um exemplo de uma parte do diagrama de modelo de objeto para o ArcGIS
Python Geoprocessor em 10.x.
32
Diagrama de modelo de objeto para o ArcGIS Python Geoprocessor
Dê uma olhada na caixa verde intitulada FeatureClass Properties e observe na coluna
do meio, segundo a partir do topo, Propriedades do Dataset. Isso ocorre porque
FeatureClass herda todas as propriedades do DataSet. Portanto, quaisquer propriedades
em um objeto DataSet, como Extent ou SpatialReference, também podem ser obtidas se
você criar um objeto FeatureClass. Além de todas as propriedades que ele herda do Dataset,
o FeatureClass tem suas próprias propriedades especializadas, como FeatureType e
ShapeType (na caixa superior, na coluna da esquerda).
Sintaxe do Python
Toda linguagem de programação tem regras sobre capitalização, espaço em branco,
como separar linhas de código e procedimentos, e assim por diante. Aqui estão algumas
regras básicas de sintaxe para lembrar do Python:
• O Python diferencia maiúsculas de minúsculas nos nomes de variáveis e
palavras reservadas. Isso significa que é importante se você usa letras maiúsculas ou
minúsculas. A minúscula "print" é uma palavra reservada no Python que imprimirá um
valor, enquanto "Print" não é reconhecido pelo Python e retornará um erro. Da mesma
33
forma, o módulo arcpy é muito sensível a sintaxe e retornará um erro se você tentar
executar uma ferramenta sem capitalizar o nome da ferramenta.
• Você finaliza uma instrução Python pressionando Enter e iniciando literalmente
uma nova linha. (Em algumas outras linguagens, um caractere especial, como um ponto-
e-vírgula, indica o final de uma instrução.) Não há problema em adicionar linhas vazias
para dividir seu código em seções lógicas.
• Se você tiver uma instrução longa que deseja exibir em várias linhas para
facilitar a leitura, será necessário usar um caractere de continuação de linha, que em
Python é uma barra invertida (\). Você pode continuar digitando na linha abaixo e o
Python interpretará a sequência de linhas como uma instrução. Uma exceção é se você
estiver no meio de parênteses () ou colchetes [], o Python entende que você está
continuando as linhas e que nenhuma barra invertida é necessária.
• A indentação é necessária no Python para agrupar logicamente determinadas
linhas ou blocos de código. Você deve recuar seu código em quatro espaços dentro de
loops, if / then statements e try / except statements. Na maioria das linguagens de
programação, os desenvolvedores são encorajados a usar o recuo para agrupar
logicamente blocos de código; no entanto, no Python, o recuo dessas construções de
linguagem não é apenas incentivado, mas necessário. Embora esse requisito possa
parecer pesado, ele resulta em maior legibilidade.
• Você pode adicionar um comentário ao seu código iniciando a linha com um
sinal de libra (#). Comentários são linhas que você inclui para explicar o que o código
está fazendo. Comentários são ignorados pelo Python quando ele executa o script, para
que você possa adicioná-los em qualquer lugar em seu código sem se preocupar com o
efeito deles. Os comentários ajudam outras pessoas que podem ter que trabalhar com
seu código no futuro; e eles podem até ajudá-lo a lembrar o que o código faz no caso de
você precisar alterá-lo.
34
10 referenciaEspacial = desc.spatialReference
11
12 # Retorna o nome da referência espacial
13 print (referenciaEspacial.Name)
Isso pode parecer intimidador no início, então vamos ver o que está acontecendo neste
script, linha por linha.
Nas linhas 1, 2, 8 e 12 são utilizados comentários que tentam elucidar as operações
que seguem após os comentários, é importante que o analista se acostume em comentar o
código de forma que outros usuários possam ter o real entendimento do que o script está
realizando.
Na linha 4 importamos o módulo arcpy, de forma que o IDE tenha acesso às classes
de códigos das ferramentas de geoprocessamento da ESRI.
Na linha 6 é criada uma variável chamada featureClass, do tipo string, pois recebe um
valor entre aspas, que armazena o endereço de uma feature class (Limite) armazenada
dentro de um geodatabase (BaseDados.gdb).
Na linha 9, nós realmente chamamos um método do arcpy. O método Describe nos
devolve um objeto de descrição da feature class. Nós mencionamos no material do curso
que tudo em Python é um objeto. Objetos têm propriedades que os descrevem e métodos
que são coisas que eles podem fazer.
Se você quiser aprender mais sobre o objeto de descrição. Você pode procurar na
ajuda da ESRI.
Em nosso caso, o objeto de descrição terá uma referência espacial. Agora, antes de
sairmos da linha 9, precisamos ter atenção aos parênteses. Então, quando você chama o
método arcpy.Describe. você precisa colocar algo dentro desses parênteses, que é o
caminho da classe de feições que você deseja descrever. Agora não precisamos digitar o
caminho completo novamente porque criamos uma variável anteriormente para representar
isso. Então é aqui que você pode colocar o nome da variável da classe de feição e o Python
lerá como o caminho real.
Então, depois da linha 9, temos um objeto de descrição. Esse objeto descrito possui
uma propriedade que é a referência espacial. Então, na linha 10, é isso que conseguimos.
"desc" é o nome do nosso objeto de descrição e .spatialReference nos fornece um objeto de
referência espacial.
Agora não podemos imprimir um objeto, se você tentar imprimir um objeto na janela
interativa, você vai ter um monte de texto que é difícil de entender, então nós realmente
precisamos obter uma propriedade fora deste objeto de referência espacial e esta
propriedade é o nome da referência espacial. Então é por isso que na linha 13 nós usamos
spatialRef.name.
A essa altura, fomos longe o suficiente para chegarmos a uma string,
referenciaEspacial.name apenas retorna uma string com a referência espacial e é imprimível
na janela interativa. Como resultado obtemos: “GCS_SIRGAS_2000”.
Mais uma vez, observe que:
• Um comentário começa o script para explicar o que vai acontecer.
35
• A diferenciação de maiúsculas e minúsculas é aplicada no código. "import" é
tudo em minúsculas. Então é "imprimir". O nome do módulo "arcpy" é sempre referido
como "arcpy", não "ARCPY" ou "Arcpy". Da mesma forma, "Describe" é capitalizado em
arcpy.Describe.
• Os nomes das variáveis featureClass, desc e referenciaEspacial que o
programador atribuiu são curtos, mas intuitivos. Ao olhar para o nome da variável, você
pode adivinhar rapidamente o que ela representa.
• O script cria objetos e usa uma combinação de propriedades e métodos nesses
objetos para realizar o trabalho. É assim que funciona a programação orientada a
objetos.
Tentando o exemplo por si mesmo
A melhor maneira de se familiarizar com uma nova linguagem de programação é
examinar o código de exemplo e praticar com você mesmo. Veja se você pode modificar o
script acima para relatar a referência espacial de uma classe de feições existente em seu
computador. No exemplo, a classe de feições está em um arquivo geodatabase; você
precisará modificar a estrutura do caminho featureClass se estiver usando um shapefile (por
exemplo, você colocará .shp no final do nome do arquivo e não terá .gdb no caminho).
Siga este padrão para experimentar o exemplo:
• Abra o PythonWin e clique em File> New.
• Escolha Python script e clique em OK.
• Escreva o código acima e modifique-o para ajustar seus dados (mude o
caminho se for necessário).
• Salve seu script como um arquivo .py.
• Clique no botão Execute para executar o script. Certifique-se de que a Janela
Interativa esteja visível quando você fizer isso, porque é onde você verá a saída da
palavra-chave de impressão.
Leituras
Se você é novo em script Python, pode ser útil ver os conceitos de outro ponto de vista.
Leia as partes dos capítulos 4 e 5 de Zandbergen. Esta será uma introdução valiosa
ao Python no ArcGIS, sobre como trabalhar com ferramentas e caixas de ferramentas e
também sobre alguns conceitos que serão revisitados posteriormente.
O Capítulo 4 trata dos fundamentos do Python. Vamos precisar de alguns deles para
começar e vamos revisitar este capítulo a frente. Por enquanto, leia as seções 4.1-4.7
revisando o que lemos em 4.5 anteriormente.
O Capítulo 5 fala sobre o trabalho com o arcpy e suas funções - leia as seções 5.1-5.6.
36
como 0. Esse tipo de operação de “álgebra de mapa” é comum em seleção de áreas e outros
cenários de SIG.
Algo que você pode não reconhecer no script abaixo é a expressão Raster (inRaster).
Esta função apenas diz ao ArcGIS que ele precisa tratar sua variável inRaster como um
conjunto de dados raster para que você possa executar a álgebra de mapa a partir dela. Se
você não fizer isso, o script tratará inRaster como apenas uma sequência literal de caracteres
(o caminho) em vez de um conjunto de dados raster.
37
• Você forneceu os caminhos corretos de entrada e saída.
• O nome do caminho contém barras (/) ou barras invertidas duplas (\\), não
barras invertidas simples (\).
• Você tem o Spatial Analyst Extension instalado e habilitado. Para verificar isso,
abra o ArcMap, clique em Cutomize > Extensions... e verifique se Spatial Analyst está
marcado.
• Você não tem nenhum dos conjuntos de dados abertos no ArcMap.
• Os dados de saída ainda não existem. Se você quiser sobrescrever a saída,
você precisa adicionar a linha arcpy.env.overwriteOutput = True. Esta linha pode ser
colocada imediatamente após a importação do módulo arcpy.
Você pode experimentar esse script usando valores diferentes na expressão de álgebra
do mapa (tente 1000 por exemplo).
Leituras
Leia as seções do Capítulo 5 que falam sobre variáveis de ambiente e licenças (5.9 e
5.11) que abordamos nesta parte da lição.
38
6
7 try:
8 # inserção dos parâmetros
9 entrada = arcpy.GetParameterAsText(0)
10 saida = arcpy.GetParameterAsText(1)
11 distanciaBuffer = arcpy.GetParameterAsText(2)
12
13 # execução da ferramenta
14 arcpy.Buffer_analysis(entrada, saida, distanciaBuffer)
15
16 # Mensagem de sucesso
17 arcpy.AddMessage("Tudo certo!")
18
19 except:
20 # Mensaem de erro
21 arcpy.AddError("Não foi possível completar o buffer")
22
23 # Adiciona mensagens fornecidas da própria ferramenta
24 arcpy.AddMessage(arcpy.GetMessages())
Novamente, examine o código acima linha por linha e descubra o máximo possível
sobre o que o código faz. Se necessário escreva notas ao lado de cada linha. Aqui estão
alguns dos principais pontos a serem entendidos:
• GetParameterAsText() é uma função do módulo arcpy. Observe que é
necessário um inteiro (0, 1, 2, 3, etc.) como um argumento. Se você for seguir em frente
e criar uma ferramenta a partir desse script, como faremos na próxima parte desta lição,
é importante definir os parâmetros na mesma ordem em que você deseja que eles
apareçam na caixa de diálogo da ferramenta.
• Quando chamamos a ferramenta Buffer nesse script, fornecemos apenas três
parâmetros. Por não fornecer mais, aceitamos os valores padrão para o restante dos
parâmetros da ferramenta.
• Os blocos de código try/except são uma maneira de evitar que o script falhe
se houver algum um erro. Seu script tenta executar todo o código no bloco try. Se o script
não puder continuar por algum motivo, ele pula e executa o código no bloco except.
Inserir blocos try/except como aqui é uma boa prática de código quando você acha que
tirou todos os erros do seu script, ou quando quer ter certeza de que seu código irá
executar uma certa quantidade de linhas, não importa o que aconteça.
Quando você está escrevendo e depurando seu script pelas primeiras vezes, é mais
útil deixar de lado os blocos try/except e deixar o código travar, porque as mensagens de
erro (vermelhas) informadas na Janela Interativa às vezes fornecem melhores dicas sobre
39
como diagnosticar o problema de seu código. Suponha que você coloque uma declaração
de impressão em seu bloco, except dizendo "Houve um erro. Por favor, tente novamente."
Para o usuário final do seu script, isso é melhor do que ver uma mensagem de erro
desagradável (vermelha); no entanto, como um programador depurando o script, você
deseja ver a mensagem de erro (vermelha) para obter informações sobre o que deu errado.
• Os métodos arcpy.AddMessage() e arcpy.AddError() são formas de adicionar
mensagens adicionais ao usuário da ferramenta. Sempre que você executa uma
ferramenta, o geoprocessador imprime mensagens, as quais você provavelmente já viu
antes (por exemplo, “Executed (Buffer) successfully. End time: Sat Jun 22 07:37:31
2019”). Você tem o poder de adicionar mais mensagens por meio desses métodos.
Quando você usa arcpy.GetMessages(), você obtém todas as mensagens geradas
pela própria ferramenta. Estes lhe dirão coisas como se o usuário inseriu parâmetros
inválidos. Observe neste script a sintaxe um pouco complexa que você precisa usar para
primeiro obter as mensagens e, em seguida, adicione-as:
arcpy.AddMessage(arcpy.GetMessages()) . Se essa linha de código for confusa para
entender, lembre-se de que a ordem das funções funciona como operações matemáticas:
você começa trabalhando dentro dos parênteses primeiro para obter as mensagens e depois
as adiciona.
Os métodos AddError e addMessage são utilizados apenas quando fazemos
ferramentas de script para rodar no ArcMap. Quando você está apenas executando um script
no PythonWin (não fazendo uma ferramenta de script), você ainda pode obter as mensagens
usando uma instrução print com GetMessages(), assim: print arcpy.GetMessages().
Leituras
Leia as seções do Capítulo 5 que fala sobre como trabalhar com mensagens de
ferramenta (5.10) para outra perspectiva sobre como lidar com a saída da ferramenta.
40
• Abra o ArcMap e exiba a janela Catalog.
• Expanda os nós Toolboxes> My Tollboxes.
• Clique com o botão direito em My Toolboxes e clique em New> Toolbox.
• Dê um nome à sua caixa de ferramentas, como "MyScriptTools".
• Clique com o botão direito na sua nova caixa de ferramentas e clique em Add>
Script.
• Preencha as propriedades Name, Label e Description para sua ferramenta
Script, conforme mostrado abaixo:
41
de script. Em vez de aceitar qualquer string como entrada (que pode conter um erro), sua
ferramenta agora aplicará o requisito de que uma classe de feições seja usada como
entrada. O ArcGIS irá ajudá-lo, confirmando que o valor inserido é um caminho para uma
classe de feições válida. Ele até fornecerá aos usuários da sua ferramenta um botão de
navegação para que eles possam navegar até a classe de recursos.
Adicionando parâmetros
• Assim como você fez na etapa anterior, adicione um segundo parâmetro
denominado “Classe de feições de saída”. O tipo de dados deve ser novamente Feature
Class.
• Com o parâmetro de Classe de feições de saída ainda realçado, olhe para
baixo na parte Parameter Properties da caixa de diálogo. Altere a propriedade de
direção (Direction) para saída (Output).
42
• Com o parâmetro Distância do Buffer ainda destacado, olhe novamente para
a seção Parameter Properties. Defina a propriedade Default como "5 Kilometers" (não
inclua as aspas). Sua caixa de diálogo deve se parecer com o que você vê abaixo:
43
Resultado após a execução
• Este é um exemplo muito simples e, obviamente, você poderia simplesmente
executar a ferramenta Buffer out-of-the-box com resultados semelhantes. Normalmente,
quando você cria uma ferramenta de script, ela é apoiada por um script que executa uma
combinação de ferramentas e aplica alguma lógica que torna essas ferramentas
especialmente úteis.
• Há outro benefício para este exemplo. Observe a simplicidade da nossa caixa
de diálogo da ferramenta de script em comparação com a ferramenta principal Buffer:
44
Leituras
Leia Zandbergen 2.10 - 2.13 para reforçar o que você aprendeu durante esta lição
sobre scripts e ferramentas de script.
45
Mapeando os dados
É muito possível que você queira repetir o processo acima para testar diferentes
parâmetros de interpolação do IDW ou fazer mapas semelhantes com outros conjuntos de
dados (como os dados de precipitação de outros anos, por exemplo). Portanto, a série de
46
tarefas acima é bem adequada ao uso do ModelBuilder. Seu trabalho é criar um modelo que
possa completar a série de etapas acima sem precisar abrir manualmente quatro
ferramentas diferentes.
Parâmetros do modelo
Seu modelo deve ter estes (e somente estes) parâmetros:
• Dados de precipitação de entrada - Esta é a localização dos dados dos
pontos de leitura da precipitação. Esse é um parâmetro do modelo para que o modelo
possa ser facilmente executado novamente com outros conjuntos de dados.
• Power - Uma configuração do interppolador IDW que especifica a rapidez com
que a influência dos pontos ao redor diminui à medida que você se afasta do ponto a ser
interpolado.
• Raio de busca - Uma configuração do interpolador IDW que determina quantos
pontos ao redor estão incluídos na interpolação de um ponto. O raio de busca pode ser
fixado a uma certa distância, incluindo qualquer número de pontos que caiam dentro, ou
sua distância pode variar para que ele sempre inclua um número mínimo de pontos.
Quando você usa o ModelBuilder, não precisa configurar nenhuma dessas opções;
ModelBuilder faz isso para você quando você define o Raio de Pesquisa como um
parâmetro de modelo.
• Limites das zonas - Esta é uma tabela que permite ao usuário do modelo
especificar os limites das zonas para a classificação. Por exemplo, você poderia
configurar valores de precipitação de 1050 - 1295 para resultar em uma classificação de
1 (para corresponder à Zona 1), 1295 - 1480 poderia resultar em uma classificação de 2
(para corresponder à Zona 2) e assim por diante. A maneira de obter esta tabela é fazer
uma variável do parâmetro Reclassification da ferramenta Reclassify e defini-lo como
um parâmetro de modelo.
• Zonas de precipitação de saída - Esse é o local onde você deseja que o
conjunto de dados de saída de zonas de precipitação já recortado seja colocado no disco.
Ao construir seu modelo, você precisará definir algumas configurações que não serão
expostas como parâmetros. Estes incluem a feição de clipe, que é a região da bacia
hidrográfica, que corresponde ao arquivo Bacia_Hidrografica.shp na sua pasta de dados.
Há muitas outras configurações e parâmetros das ferramentas, como "Z Value field" e
"Input barrier polyline features" (para IDW) ou "Reclass field" (para Reclassify) que não
precisam ser expostos. Você deve definir esses valores apenas uma vez ao criar seu
modelo. Se você alguma vez pedir a alguém para executar este modelo, você não quer que
eles sejam carregados com escolhas diferentes; você deve apenas expor as coisas
essenciais que eles podem mudar.
Para esse modelo específico, você deve assumir que qualquer conjunto de dados de
entrada estará em conformidade com o mesmo esquema da classe de feições de
Plu_Total_Anual.shp. Por exemplo, um analista deve poder enviar um outro conjunto de
dados semelhante com os mesmos campos, nomes de campo e tipos de dados. No entanto,
manipular todos os tipos de esquemas de classe de feições tornaria seu modelo mais
complexo do que queremos para essa tarefa.
Quando você clica duas vezes no modelo para executá-lo, a interface deve se parecer
com o seguinte:
47
A interface do modelo
Executar o modelo com os parâmetros listados acima deve resultar no seguinte (eu
simbolizei as zonas no ArcMap com cores diferentes para ajudar a distingui-las). Esta é uma
maneira de verificar seu trabalho:
48
Dicas
As dicas a seguir podem ajudá-lo a construir seu modelo:
• Seu modelo precisa incluir as seguintes ferramentas nesta ordem: IDW (da
caixa de ferramentas do Spatial Analyst), Reclassify, Raster to Polygon, Clip (da caixa
de ferramentas Analysis).
• Uma maneira fácil de encontrar as ferramentas necessárias no ArcMap é clicar
em Windows > Search e digitar o nome da ferramenta desejada na caixa de pesquisa.
Tenha cuidado quando várias ferramentas tiverem o mesmo nome. Você normalmente
estará usando ferramentas da caixa de ferramentas do Spatial Analyst nesta tarefa.
• Depois de arrastar e soltar uma ferramenta na tela do ModelBuilder, clique duas
vezes nela e defina todos os parâmetros da maneira que desejar. Estas serão as
configurações padrão para o seu modelo.
• Se houver um determinado parâmetro para uma ferramenta que você deseja
expor como um parâmetro do modelo, clique com o botão direito do mouse na ferramenta
na tela ModelBuilder, em seguida, clique em Make variable > From parameter e escolha
o parâmetro. Quando o objeto oval aparecer para a variável, clique com o botão direito e
clique em Model Parameter.
• Se você receber erros que uma ferramenta não é capaz de executar ou que
não há nenhuma extensão do Spatial Analyst instalada, talvez seja necessário ativar a
extensão. No ArcMap, clique em Customize > Extensions e marque a caixa de seleção
Spatial Analyst.
49
• Consequentemente, você não é obrigado a criar uma ferramenta de script para
este exercício.
• Seu código deve ser executado corretamente no PythonWin. Para crédito total,
ele também deve conter comentários, tentar manipular erros e usar nomes de variáveis
intuitivas.
Entregas
As entregas para avaliação desta aula são:
• O arquivo .tbx da caixa de ferramentas que contém seu modelo de zonas de
precipitação. A maneira mais fácil de encontrá-lo é clicar com o botão direito do mouse
na caixa de ferramentas na janela Catalog, clicar em Propriedades e anotar o local. Se
você não puder navegar para esse caminho no Windows Explorer, precisará ativar a
opção Windows para mostrar arquivos e pastas ocultos.
• O arquivo .py contendo seu script para criar as curvas de nível.
• Um curto resumo (cerca de 400 palavras) descrevendo como você abordou os
dois problemas, quaisquer contratempos enfrentados e como lidou com eles.
50
Etapa 2: Fundamentos de Python e Programação
Objetivos da etapa 2
No final desta etapa, você deve:
• Entender a sintaxe básica do Python para instruções condicionais e controle
de fluxo de programa (if-else, operadores de comparação, for loop, while loop)
• Familiarize-se com tipos de dados mais avançados (strings, listas),
manipulação de strings e conversão entre diferentes tipos
• Sabar como depurar código e como usar o depurador
• Ser capaz de programar scripts básicos que usam instruções condicionais e
loops para automatizar tarefas
51
em determinada entrada do usuário. Se você souber como fazer cada uma dessas coisas
individualmente, poderá encaixar as peças, mesmo que a tarefa necessária pareça
assustadora.
Listas
Na etapa 1, você aprendeu sobre alguns tipos de dados comuns no Python, como
strings e inteiros. Às vezes, você precisa de um tipo que possa armazenar vários valores
relacionados juntos. O Python oferece várias maneiras de fazer isso, e a primeira sobre a
qual aprenderemos é a lista.
Aqui está um exemplo simples de uma lista. Você pode digitar isso na Janela Interativa
do PythonWin para acompanhar:
>>> Naipes = ['Espadas', 'Paus', 'Ouros', Copas]
Esta lista chamada 'Naipes' armazena quatro valores relacionados representando os
naipes em um baralho de cartas. Em muitas linguagens de programação, armazenar um
grupo de objetos em sequência como esse é feito com matrizes. Embora a lista do Python
possa ser considerada como uma matriz, ela é um pouco mais flexível do que a matriz típica
de outras linguagens de programação. Isso porque você pode colocar vários tipos de dados
em uma lista.
Por exemplo, suponha que quiséssemos criar uma lista para os valores das cartas que
você poderia desenhar. A lista pode ser assim:
>>> valores = ['Ás', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'Valete', 'Dama', 'Rei']
Observe que você acabou de misturar valores de strings e inteiros na lista. Python. No
entanto, cada item na lista ainda tem um índice, significando um inteiro que indica o lugar de
cada item na lista. A lista começa com o índice 0 e, para cada item da lista, o índice é
incrementado em um. Tente isto:
>>> print (Naipes[0])
Espadas
>>> print (valores[12])
Rei
Nas linhas acima, você apenas solicitou o item com o índice 0 na lista de Naipes e
obteve 'Espadas'. Da mesma forma, você solicitou o item com índice 12 na lista de valores
e obteve 'King'.
Pode levar algum tempo inicialmente para lembrar que suas listas começam com um
índice 0. Testar seus scripts pode ajudar a evitar erros "off-by-one" que podem resultar do
esquecimento de que as listas são indexadas com zero. Por exemplo, você pode configurar
um script para crias 100 cartas aleatórias e imprimir os valores. Se nenhuma delas é um Ás,
você provavelmente criou o baralho fazendo os índices começarem em 1.
Lembre-se que você aprendeu que tudo é um objeto em Python. Isso também se aplica
às listas. Na verdade, as listas têm muitos métodos úteis que você pode usar para alterar a
ordem dos itens, inserir itens, classificar a lista e assim por diante. Tente isto:
52
>>> Naipes = ['Espadas', 'Paus', 'Ouros', 'Copas']
>>> Naipes.sort ()
>>> print (Naipes)
['Copas', 'Espadas', 'Ouros', 'Paus']
Observe que os itens na lista estão agora em ordem alfabética. Você também deve ter
notado que, quando você digitou "Naipes", recebeu ajuda para ver quais métodos estavam
disponíveis para a lista. Isso é chamado de autocompletar, e pode ser uma grande ajuda
quando você está escrevendo um código. Você quer verificar o que você pode fazer e não
pode fazer. Também pode ser uma maneira de evitar erros de digitação, pois você pode
descer a seta e pressionar Tab para inserir o método desejado. O autocompletar é um
recurso do PythonWin, mas esse tipo de ajuda pode ser encontrado em outros ambientes
de desenvolvimento integrados (IDEs), como o Microsoft Visual Studio.
O método sort() que você usou acima permitiu que você fizesse algo em uma linha de
código que, de outra forma, teria usado muitas linhas. Outro método útil como esse é o
reverse(), que permite classificar uma lista em ordem alfabética inversa:
>>> Naipes.reverse ()
>>> print (Naipes)
['Paus', ' Ouros ', 'Espadas', 'Copas']
Antes de tentar escrever um código de manipulação de listas, verifique a documentação
de referência da lista do Python para ver se existe um método existente que possa simplificar
seu trabalho.
Inserindo itens e combinando listas
O que acontece quando você quer combinar duas listas? Digite isto na janela interativa:
>>> lista1 = [101,102,103]
>>> lista2 = [104,105,106]
>>> lista3 = lista1 + lista2
>>> print (lista3)
[101, 102, 103, 104, 105, 106]
Observe que você não conseguiu [205,207,209]; em vez disso, o Python trata a adição
como acrescentando lista2 a lista1 . Em seguida, tente estas outras maneiras de adicionar
itens à lista:
>>> lista3 + = [107]
>>> print (lista3)
[101, 102, 103, 104, 105, 106, 107]
>>> lista3.append (108)
>>> print (lista3)
[101, 102, 103, 104, 105, 106, 107, 108]
53
Para colocar um item no final da lista, você pode adicionar uma lista de um item (como
adicionamos 107 à lista) ou usar o método append() na lista (como adicionamos 108 à lista).
Observe que lista3 + = [107] é uma forma abreviada de dizer lista3 = lista3 + [107].
Se você precisar inserir alguns itens no meio da lista, você pode usar o método insert():
>>> lista3.insert (4, 999)
>>> print (lista3)
[101, 102, 103, 104, 999, 105, 106, 107, 108]
Observe que o método insert() acima usou dois parâmetros. Você pode até ter notado
uma dica de ferramenta que mostra o que os parâmetros significam.
O primeiro parâmetro é a posição do índice que o novo item terá. Essa chamada de
método insere 999 entre 104 e 105. Agora, 999 está no índice 4.
Obtendo o tamanho de uma lista
Às vezes, você precisará descobrir quantos itens estão em uma lista, principalmente
quando estiver em um loop. Veja como você pode obter o tamanho de uma lista:
>>> minhaLista = [4,9,12,3,56,133,27,3]
>>> print (len(minhaLista))
8
Observe que len() fornece o número exato de itens na lista. Para obter o índice do item
final, você precisaria usar len(minhaLista) - 1. Novamente, essa distinção pode levar a erros
"off-by-one" se você não for cuidadoso.
Outras maneiras de armazenar coleções de dados
As listas não são a única maneira de armazenar coleções ordenadas de itens em
Python; você também pode usar tuplas e dicionários. As tuplas são como listas, mas você
não pode alterar os objetos dentro de uma tupla ao longo do tempo. Em alguns casos, uma
tupla pode, na verdade, ser uma estrutura melhor para armazenar valores como os naipes
em um baralho de cartas, porque essa é uma lista fixa que você não deseja que seu
programa mude acidentalmente.
Os dicionários diferem das listas uma vez que que os itens não são indexados; em vez
disso, cada item é armazenado com um valor de chave que pode ser usado para recuperar
o item. Usaremos os dicionários mais adiante no curso e sua tarefa de leitura desta lição
abordará o básico sobre dicionário de dados. A melhor maneira de entender como os
dicionários funcionam é brincar com alguns dos exemplos didáticos do livro na Janela
Interativa (ver Zandbergen 6.8).
Loops
Um loop é uma seção de código que repete uma ação. Lembre-se, o poder do script (e
computação em geral) é a capacidade de repetir rapidamente uma tarefa que pode ser
demorada ou propensa a erros para um ser humano. Looping é como você repete tarefas
54
com código; se está lendo um arquivo, procurando um valor ou executando a mesma ação
em cada item de uma lista.
Loop FOR
Um loop for faz algo com cada item em uma lista. Digite isso na Janela Interativa do
PythonWin para ver como funciona um loop simples:
>>> for nome in ["Lula", "Itamar", "Collor"]:
print (nome + "era um presidente do Brasil")
Depois de digitar isso, você terá que apertar Enter duas vezes seguidas para dizer ao
PythonWin que acabou de trabalhar no loop e que o loop deve ser executado. Você deveria
ver:
Lula era um presidente do Brasil
Itamar era um presidente do Brasil
Collor era um presidente do Brasil
Observe algumas coisas importantes sobre o loop acima. Primeiro, você declarou uma
nova variável, "nome", para representar cada item da lista à medida que você iterava. Tudo
bem fazer isso; na verdade, espera-se que você faça isso no início do loop for.
A segunda coisa a notar é que, após a condição, ou a primeira linha do loop, você
digitou dois pontos (:) e, em seguida, iniciou o recuo das linhas subseqüentes. Algumas
linguagens de programação requerem que você digite algum tipo de linha ou caractere
especial no final do loop (por exemplo, "Next" no Visual Basic ou "}" em JavaScript), mas o
Python procura apenas o local em que você usou um recuo. Ao pressionar Enter duas vezes,
você disse ao Python para parar o recuo e que estava pronto para executar o loop.
For Loops também pode trabalhar com listas de números. Experimente este na janela
interativa:
>>> x = 2
>>> multiplicadores = [1,2,3,4]
>>> for num in multiplicadores:
print (x * num)
2
4
6
8
No loop acima, você multiplicou cada item na lista por 2. Observe que você pode
configurar sua lista antes de começar a codificar o loop.
Você também poderia ter feito o seguinte com o mesmo resultado:
>>> multiplicadores = [1,2,3,4]
>>> for num in multiplicadores:
x = 2
55
print (x * num)
O código acima, no entanto, é menos eficiente do que o que fizemos inicialmente. Você
pode ver por quê? Desta vez você está declarando e configurando a variável x = 2 dentro do
loop. O interpretador Python agora terá que ler e executar essa linha de código quatro vezes
em vez de uma. Você pode pensar que essa é uma quantidade trivial de trabalho, mas se
sua lista continha milhares ou milhões de itens, a diferença no tempo de execução se tornaria
perceptível. Declarar e definir variáveis fora de um loop, sempre que possível, é uma prática
recomendada na programação.
Enquanto estamos no assunto, o que você faria se quisesse multiplicar 2 por cada
número de 1 a 1000? Definitivamente seria muita digitação para configurar manualmente
uma lista de multiplicadores como no exemplo anterior. Nesse caso, você pode usar a função
de intervalo interna do Python (Range). Tente isto:
>>> x = 2
>>> for num in range(1,1001):
print (x * num)
A função range é sua maneira de dizer ao Python: "Comece aqui e pare aí". Usamos
1001 porque o loop para um item antes do segundo argumento da função (os argumentos
são os valores que você coloca entre parênteses para dizer à função como executar). Se
você precisar da função para multiplicar por 0 no começo também, você pode até usar um
só argumento:
>>> x = 2
>>> for num in range(1001):
print (x * num)
A função range tem muitos usos interessantes que são detalhados em Zandbergen.
Loops WHILE
Um loop while é executado até que alguma condição seja atendida. Veja como codificar
nosso exemplo acima usando um loop while:
>>> x = 0
>>> while x <1001:
... print (x * 2)
... x + = 1
Loops while geralmente envolvem o uso de algum contador que monitora quantas
vezes o loop foi executado. Às vezes, você executará operações com o contador. Por
exemplo, no loop acima, x era o contador, e também multiplicamos o contador por 2 cada
vez durante o loop. Para incrementar o contador, usamos x + = 1, que é a abreviação de x
= x + 1, ou "add one to x".
Loops encadeados
Algumas situações exigem colocar um loop dentro de outro, uma prática chamada
nesting. Loops aninhados podem ajudá-lo a imprimir cada carta em um baralho (menos os
coringas):
>>> Naipes = ['Espadas', 'Paus', 'Ouros', 'Copas']
56
>>> valores = ['Ás', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'Valete', 'Dama', 'Rei']
>>> for naipe in Naipes:
for valor em valores:
print (str(valor) + "de" + str(naipe))
No exemplo acima, você começa com um naipe e, em seguida, percorre cada valor da
ação, imprimindo o nome da carta. Quando você atinge o final da lista de valores, você pula
para fora do loop aninhado e volta para o primeiro loop para obter o próximo naipe. Então
você percorre todos os valores no segundo naipe e imprime os nomes das cartas. Este
processo continua até que todas as ações e valores tenham sido passados.
Looping em modelos SIG
Você usará loop repetidamente ao escrever scripts SIG em Python. Muitas vezes, você
precisará fazer uma iteração em todas as linhas de uma tabela, em todos os campos de uma
tabela ou em todas as classes de feições de uma pasta ou geodatabase. Você pode até
precisar percorrer os vértices de uma feição geográfica.
Você viu acima que os loops funcionam particularmente bem com listas. O arcpy possui
alguns métodos que podem ajudá-lo a criar listas. Aqui está um exemplo que você pode
tentar que usa arcpy.ListFeatureClasses() . Primeiro, crie manualmente uma nova pasta
C:\SEA5923\Dados2 . Em seguida, copie o código abaixo em um novo script no PythonWin
e execute o script. O script copia todos os dados da pasta Dados para a nova pasta que
você acabou de criar.
try:
arcpy.env.workspace = "C:/SEA5923/Dados"
except:
print ("O script falhou")
print (arcpy.GetMessages(2))
57
Observe acima que, uma vez que você tenha uma lista de classes de feições do Python
(fcList), é muito fácil configurar a condição de loop (for featureClass in fcList :).
Outra operação comum em scripts SIG é fazer um loop através de tabelas. Na verdade,
o módulo arcpy contém alguns objetos especiais chamados cursores que ajudam você a
fazer isso. Aqui está um pequeno script mostrando como um cursor pode percorrer cada
linha em uma classe de feições e imprimir o nome. Nós abordaremos os cursores em
detalhes adiante, então não se preocupe se algum código parecer confuso agora. O
importante é notar como um loop é usado para percorrer cada registro:
import arcpy
tabelaEntrada = "C:/SEA5923/Dados/Municipios.shp"
campo = "NOME"
linhas = arcpy.SearchCursor(tabelaEntrada)
58
...
Maior do que dois
No exemplo acima, a palavra-chave "if" indica que algum teste condicional está prestes
a ser executado. Nesse caso, a condição de x sendo maior que dois foi atendida, portanto,
o script imprimiu "Maior que dois". Observe que você é obrigado a colocar dois pontos (:)
após a condição e recuar qualquer código a ser executado por causa da condição. Para
consistência nesta classe, todo recuo é feito usando quatro espaços.
Usar "else" é uma maneira de executar o código se a condição não for atendida. Tente
isto:
>>> x = 1
>>> if x > 2:
... print ("Maior que dois")
... else:
... print ("Menor ou igual a dois")
...
Menor ou igual a dois
Observe que você não precisa colocar nenhuma condição depois de "else". É uma
maneira de pegar todos os outros casos. Novamente, o código condicional é recuado em
quatro espaços, o que torna o código muito fácil de ser entendido. O recuo é necessário
porque o Python não requer nenhum tipo de instrução "end if" (como muitas outras
linguagens) para indicar o final do código que você deseja executar.
Se você deseja executar várias condições, use "elif", que é a abreviação do Python
para "else if":
>>> x = 2
>>> if x > 2:
... print ("Maior que dois")
... elif x == 2:
... print ("Igual a dois")
... else:
... print ("Menor que dois")
...
Igual a dois
No código acima, elif x == 2: testa se x é igual a dois. O == é uma maneira de testar
se dois valores são iguais. Usar um único = nesse caso resultaria em um erro porque = é
usado para atribuir valores a variáveis. No código acima, você não está tentando atribuir a
“x” o valor de 2, você quer verificar se “x” é igual a 2, daí você usa ==.
Cuidado: Usar = em vez de == para verificar a equivalência é um erro muito comum no
Python, especialmente se você usou outras linguagens onde = é permitido para verificações
de equivalência.
59
Você também pode usar if, elif e else para lidar com várias possibilidades em um
conjunto. O código abaixo pega uma escola aleatória de uma lista (note que tivemos que
importar o módulo randon para fazer isso e chamar um método especial random.randrange()
). Depois que a escola é selecionada e seu nome é impresso, uma série de declarações if /
elif / else é exibida para lidar com cada possibilidade. Observe que a instrução else é deixada
como manipulador de erro; você não deve se deparar com essa linha se seu código funcionar
corretamente, mas você pode deixar a linha lá para se algo der errado.
import random
Manipulação de strings
Você já aprendeu como a variável de string (cadeias de caracteres) pode conter
números e letras e representar quase tudo. Ao usar o Python com o ArcGIS, sequências de
caracteres podem ser úteis para armazenar caminhos para dados e imprimir mensagens
para o usuário. Existem também alguns parâmetros da ferramenta de geoprocessamento
que você precisará fornecer como strings.
60
O Python possui algumas habilidades de manipulação de strings muito úteis. Não
entraremos em todos eles neste curso, mas seguiremos algumas técnicas que você precisa
conhecer.
Concatenando strings
Para concatenar duas strings, que significa anexar ou adicionar uma string ao final de
outra string. Por exemplo, você poderia concatenar as strings "Python is" e "uma linguagem
de script" para fazer a frase completa "Python é uma linguagem de script". Como você está
adicionando uma string a outra, é intuitivo que em Python você possa usar o sinal + para
concatenar strings.
Talvez seja necessário concatenar strings ao trabalhar com os nomes de caminho dos
arquivos. Às vezes é útil ou necessário armazenar uma string representando um diretório ou
geodatabase a partir da qual você está obtendo conjuntos de dados e uma segunda string
representando o próprio nome do conjunto de dados. Você coloca os dois juntos para ter o
caminho completo.
O exemplo a seguir, modificado da Ajuda do ArcGIS, demonstra esse conceito.
Suponha que você já tenha uma lista de strings representando as classes de feições que
você deseja recortar. A lista é representada por "featureClassList" neste script:
pastaEntrada = "c:\\SEA5923\\Dados\\FC\\"
pastaResultados = "c:\\SEA5923\\FC\\resultados\\"
clipFeature = "c:\\SEA5923\\Dados\\Consorcio_mun.shp"
61
fosse "Hintegrada.shp", a cadeia de saída resultante seria
"C:\\SEA5923\\Dados\\FC\\resultados\\Hintegrada.shp"
O exemplo acima mostra que a concatenação de strings pode ser útil em looping.
Construir o caminho de saída usando um espaço de trabalho (workspace) do conjunto de
dados ou o nome de pasta seguido por um nome da classe de feições de uma lista fornece
muito mais flexibilidade do que tentar criar cadeias de caminho de saída para cada conjunto
de dados individualmente. Você pode não saber quantas classes de recursos estão na lista
ou quais são seus nomes. Você pode contornar isso se construir os caminhos de saída
através da concatenação de strings.
Casting para uma string
Às vezes, em programação, você tem uma variável de um tipo que precisa ser tratada
como outro tipo. Por exemplo, 5 pode ser representado como um número ou uma string. O
Python só pode executar cálculos matemáticos com o valor 5 se este for tratado como um
número e só pode concatenar o valor 5 em uma string existente se for tratada como uma
string.
O Casting é uma forma de forçar seu programa a pensar em uma variável como um
tipo diferente. Crie um novo script no PythonWin e digite ou cole o seguinte código:
x = 0
while x < 10:
print (x)
x += 1
print ("Você executou o loop " + x + " vezes.")
Agora tente executá-lo. O script tenta concatenar cadeias com a variável x para imprimir
quantas vezes você executou um loop, mas resulta em um erro: "TypeError: pois não é
possível concatenar objetos 'str' e 'int'." O Python não tem problema quando você deseja
imprimir a variável x por conta própria, mas o Python não pode misturar strings e variáveis
inteiras em uma instrução de impressão. Para rodar o código, você tem que converter a
variável x em uma sequência de caracteres quando você tenta imprimi-lo.
x = 0
while x < 10:
print (x)
x += 1
print ("Você executou o loop " + str(x) + " vezes.")
Você pode forçar o Python a pensar em x como uma string usando str(x). O Python tem
outras funções de conversão, como int() e float(), que você pode usar se precisar ir de uma
string para um número. Use int() para inteiros e float() para decimais.
Leituras
É hora de fazer uma pausa e fazer algumas leituras de outra fonte. Se você é novo
com script Python, isso ajudará você a ver os conceitos de um outro ângulo.
Leia os capítulos 4 - 6 de Zandbergen (pule as partes do Capítulo 5 que você já leu na
etapa 1).
62
• O Capítulo 4 aborda os fundamentos da sintaxe Python, loops, strings e outras
coisas que acabamos de aprender.
• O capítulo 5 fala sobre geoprocessamento com arcpy. Leia as seções que
pulamos na etapa 1 - 5.7, 5.8
• O Capítulo 6 fornece algumas instruções específicas sobre como trabalhar com
os conjuntos de dados do ArcGIS.
63
• Cachorro visita seu balde de cerejas (Adicione 2 cerejas)
• Balde derramado (Coloque as 10 cerejas de volta na sua árvore)
Os jogadores continuam se revezando até que algum tenha 0 cerejas na sua árvore, e
nesse ponto será o ganhador do jogo. Seu objetivo aqui é escrever um script que simula o
jogo (e por simplificação adotaremos que você está jogando sozinho), imprimindo o seguinte:
• O resultado de cada rodada
• O número de cerejas na sua árvore após cada jogada. Isso deve estar sempre
entre 0 e 10.
• O número final de jogadas necessárias para ganhar o jogo.
Aproximando-se de um problema de programação
Embora este exemplo possa parecer juvenil, é uma excelente maneira de praticar tudo
o que você acabou de aprender. Como iniciante, você pode parecer intimidado pelo
problema acima. Uma pergunta comum é: "Por onde começo?" A melhor abordagem é dividir
o problema em pedaços menores de coisas que você sabe fazer.
Uma das habilidades de programação mais importantes que você pode adquirir é a
capacidade de verbalizar um problema e traduzi-lo em uma série de pequenas etapas de
programação (construção do algoritmo). Aqui está uma lista de coisas que você precisa fazer
neste script. Os programadores chamam esse pseudocódigo porque ele não está escrito em
código, mas segue a sequência que o código precisará tomar.
• Gire a roleta
• Imprima o resultado da roleta
• Adicione ou remova cerejas com base no resultado
• Certifique-se de que o número de cerejas esteja entre 0 e 10
• Imprima o número de cerejas na árvore
• Vá para a próxima rodada ou imprima o número de jogadas que levou para
ganhar o jogo
Também ajuda listar as variáveis que você precisará:
• Número de cerejas atualmente na árvore (começa em 10)
• Número de jogadas realizadas (começa em 0)
• Valor da roleta (Aleatório)
Vamos tentar abordar cada uma das etapas do pseudocódigo. Não se preocupe com
o fluxo total do script ainda. Em vez disso, tente entender como cada etapa do problema
deve ser resolvido com o código. Montar os blocos de código no final é relativamente trivial.
Gire a roleta
Como você simula um giro aleatório? Em um dos nossos exemplos anteriores, usamos
o módulo aleatório para gerar um número aleatório dentro de um intervalo de inteiros; no
entanto, as escolhas nesta roleta não são lineares. Uma boa abordagem aqui é armazenar
todas as possibilidades em uma lista e usar o gerador de números aleatórios para escolher
o índice para uma das possibilidades. Por si só, o código ficaria assim:
64
import random
valoresRoleta = [-1, -2, -3, -4, 2, 2, 10]
roletaIndex = random.randrange(0, 7)
resultadoRoleta = valoresRoleta[roletaIndex]
A lista valoresRoleta contém todos os resultados possíveis de uma rodada (remova 1
cereja, remova 2 cerejas, etc.). O valor final 10 representa o balde derramado (colocando
todas as cerejas de volta na árvore).
Você precisa escolher um valor aleatório fora desta lista para simular um giro. A variável
roletaIndex representa um inteiro aleatório de 0 a 6, que é o índice do item que você retirará
da lista. Por exemplo, se roletaIndex for 2, seu resultado da roleta é -3 (remova 3 cerejas da
árvore). O valor é atribuído a variável resultadoRoleta.
O método random.randrange() é usado para selecionar os números aleatórios. No
início do seu script, você precisa importar o módulo random para usar esse método.
Imprima o resultado da roleta
Depois de obter um resultado, basta uma linha de código para imprimi-lo. Você terá
que usar o método str() para convertê-lo em uma string.
print ("Você tirou" + str(resultadoRoleta) + ".")
Adicione ou remova cerejas com base no resultado
Como mencionado acima, você precisa ter alguma variável para acompanhar o número
de cerejas na sua árvore. Essa é uma daquelas variáveis que o nome precisa ser intuitivo:
cerejasNaArvore = 10
Depois de completar um “giro” da roleta, você precisa modificar essa variável com base
no resultado. Lembre-se de que o resultado é mantido na variável resultadoRoleta e que um
resultado negativo remove as cerejas da sua árvore. Então, seu código para modificar o
número de cerejas na árvore seria semelhante a:
cerejasNaArvore + = resultadoRoleta
Certifique-se de que o número de cerejas esteja entre 0 e 10
Se você ganhar o jogo você tem 0 cerejas. Você não precisa atingir exatamente 0, mas
não faz sentido dizer que você tem cerejas negativas. Da mesma forma, você pode tirar na
roleta o balde derramado, que por simplicidade representamos com 10 positivos em
valoresRoleta. Você não tem permissão para ter mais de 10 cerejas na árvore.
Uma simples estrutura de decisão if / elif pode ajudá-lo a manter o valor de
cerejasNaArvore entre 0 e 10:
if cerejasNaArvore > 10:
cerejasNaArvore = 10
elif cerejasNaArvore <0:
cerejasNaArvore = 0
Isso significa que, se você acabar com mais de 10 cerejas na árvore, defina
cerejasNaArvore de volta para 10. Se você acabar com menos de 0 cerejas, defina
cerejasNaArvore como 0.
65
Imprima o número de cerejas na árvore
Tudo o que você precisa fazer para essa etapa é imprimir sua variável
cerejasNaArvore, convertendo-a em uma string para que ela possa ser inserida em uma
frase.
print ("Você tem" + str (cerejasNaArvore) + "cerejas na sua árvore.")
Jogue outra vez ou imprima o número de jogadas que levou para ganhar o jogo
Você provavelmente previu que teria que descobrir uma maneira de fazer várias
jogadas. Este é o cenário perfeito para um loop.
Qual é a condição do loop? Tem que haver algumas cerejas na árvore para começar
outra jogada, então você pode começar o loop desta maneira:
while cerejasNaArvore > 0:
Muito do código que escrevemos acima entraria no loop para simular uma jogada.
Como precisamos acompanhar o número de jogadas realizadas, no final do loop, precisamos
incrementar um contador:
jogadas + = 1
Essa variável teria que ser inicializada no início do script, antes do loop.
Este código pode imprimir o número de jogadas ao final do jogo:
print ("Demorou" + str (jogadas) + " para ganhar o jogo.")
Código final
Sua única tarefa restante é reunir os códigos acima em um script. Abaixo está um
exemplo de como o script final ficaria. Copie isso em um novo script PythonWin e tente
executá-lo:
66
# Adicione ou remova cerejas com base no resultado
cerejasNaArvore += resultadoRoleta
# Número de cerejas deve estar entre 0 e 10
if cerejasNaArvore > 10:
cerejasNaArvore = 10
elif cerejasNaArvore < 0:
cerejasNaArvore = 0
# Print o número de cerejas na árvore
print ("Você tem " + str(cerejasNaArvore) + " cerejas.")
jogadas += 1
# Print o número de jogadas para vencer o jogo
print ("Você precisou de " + str(jogadas) + " para vencer.")
lastline = raw_input(">")
Análise do código final
Revise o código final de perto e considere as seguintes coisas.
A primeira coisa que você faz é importar os módulos de suporte necessários, neste
caso, o módulo random.
Em seguida, você declara as variáveis que você usará ao longo do script. Cada variável
tem um escopo, que determina o quanto ela é amplamente usada em todo o script. As
variáveis valoresRoleta, jogadas e cerejasNaArvore são necessárias no script inteiro,
portanto, elas são declaradas no início, fora do loop. As variáveis usadas em todo o seu
programa como esse têm escopo global. Por outro lado, as variáveis roletaIndex e
resultadoRoleta têm escopo local porque são usadas apenas dentro do loop. Cada vez que
o loop é executado, essas variáveis são reinicializadas e seus valores mudam.
Você poderia declarar a variável valoresRoleta dentro do loop e obter o mesmo
resultado final, mas o desempenho seria mais lento porque a variável teria que ser
reinicializada toda vez que você executasse o loop. Quando possível, você deve declarar
variáveis fora dos loops por esse motivo.
Se você tivesse declarado as variáveis jogadas ou cerejasNaArvore dentro do loop,
seu código teria erros lógicos. Você estaria essencialmente começando o jogo novamente
em cada jogada com 10 cerejas na sua árvore, tendo tomado 0 jogadas. Na verdade, você
criaria um loop infinito porque não há como remover 10 cerejas durante uma jogada, e a
condição de loop sempre seria avaliada como verdadeira. Novamente, tenha muito cuidado
com o local em que você declara suas variáveis quando o script contém loops.
Observe que o número total de jogadas é impresso fora do loop quando o jogo termina.
A linha final lastline = raw_input (">") lhe retorna um cursor vazio solicitando uma entrada
e é apenas um truque para garantir que o aplicativo não desapareça quando terminar (se
você executar o script a partir de um console de comando).
Resumo
67
No exemplo acima, você viu como listas, loops, estruturas de decisão e conversão de
variáveis podem trabalhar juntos para ajudá-lo a resolver um desafio de programação. Você
também aprendeu como abordar um problema de analisando uma tarefa de cada vez para
depois montá-las em um script.
Atividade de desafio
Se a atividade acima fez você se entusiasmar em escrever algum programa, pegue o
script acima e tente encontrar o número médio de jogadas necessárias para vencer um jogo
de Hi-Ho! Cherry-O. Para fazer isso, adicione outro loop que execute o jogo um grande
número de vezes, digamos 10000. Você precisará registrar o número total de turnos
necessários para vencer todos os jogos e dividir pelo número de jogos (use "/" para a
divisão). Você também poderia incluir outros jogadores e alternar as jogadas entre eles.
68
Problemas potenciais e diagnóstico rápido
O segredo da programação bem-sucedida é a experiência e não ter medo de errar
quando você executa o código pela primeira vez. Depurar, ou encontrar erros no código, faz
parte da vida dos programadores. Aqui estão algumas coisas que podem acontecer:
• Seu código não roda, geralmente por causa de um erro de sintaxe (você digitou
algum código ilegal do Python).
• Seu código é executado, mas o script não é concluído e relata um erro.
• Seu código é executado, mas o script nunca é concluído. Muitas vezes isso
ocorre quando você criou um loop infinito.
• Seu código é executado e o script é concluído, mas não fornece o resultado
esperado. Isso é chamado de erro lógico e geralmente é o tipo de erro que exige mais
esforço para depurar.
Não tenha medo de erros
Erros acontecem. Existem muito poucos programadores que podem se sentar e, acima
de tudo, escrever dezenas de linhas de código livre de bugs. Isso significa algumas coisas
para você:
• Espere gastar algum tempo lidando com erros durante o processo de
construção de scripts. Os programadores iniciantes às vezes subestimam quanto tempo
isso leva. Para obter uma estimativa inicial, você pode considerar o tempo necessário
para elaborar suas linhas de código, duplicá-lo ou triplicá-lo para acomodar o tratamento
de erros e o polimento final do script e da ferramenta.
• Não tenha medo de executar seu script e consertar os erros. Uma boa
estratégia é escrever uma pequena parte da funcionalidade, executá-la para garantir que
ela funcione e, em seguida, adicionar a próxima peça. Por uma questão de discussão,
vamos supor que, como um novo programador, você introduza um novo bug uma vez a
cada 10 linhas de código. É muito mais fácil encontrar um único bug em 10 novas linhas
de código do que encontrar 5 bugs em 50 novas linhas de código. Se você estiver
construindo seu script bloco por bloco e depurando com frequência, poderá fazer uma
avaliação mais rápida e precisa de onde introduziu novos erros.
Captura de erros de sintaxe
Erros de sintaxe ocorrem quando você digita algo incorretamente e seu código se
recusa a executar. Erros comuns de sintaxe incluem o esquecimento de dois pontos ao
definir um loop ou uma condição if, usando barras invertidas simples em um nome de
arquivo, fornecendo o número errado de argumentos a uma função ou tentando misturar
tipos de variáveis incorretamente, como dividir um número por uma string.
Quando você tenta executar código com um erro de sintaxe no PythonWin, talvez não
perceba nada acontecer. Na parte inferior da janela, procure uma mensagem como "Falha
ao executar script - erro de sintaxe - sintaxe inválida" ("Failed to run script - syntax error -
invalid syntax").
Às vezes a mensagem é mais clara. Por exemplo, se você recuar uma linha apenas
três espaços em vez de quatro, verá: "Falha ao executar script - erro de sintaxe - recuo
inesperado" ("Failed to run script - syntax error - unexpected indent").
69
Você pode verificar erros de sintaxe antes de executar seu código usando o botão
Check na barra de ferramentas Standard do PythonWin. Esse botão verifica se há erros
e os relata em uma pequena mensagem na parte inferior da janela, assim como você veria
se tentasse executar seu código com um erro de sintaxe. Se não houver erros, você verá
uma mensagem como "O Python e o TabNanny verificaram com êxito o arquivo
'myScript.py'" (O TabNanny é um módulo que o PythonWin usa para verificar a identação
correta).
Lidando com falhas
Se o seu código falhar, você poderá ver uma mensagem de erro na Janela Interativa
ou no console. Em vez de bater a cabeça contra a mesa, você deve se alegrar com o fato
de que o software possivelmente relatou a você exatamente o que deu errado! Vasculhe a
mensagem em busca de pistas sobre qual linha de código causou o erro e qual foi o
problema. Faça isso mesmo se a mensagem parecer intimidante. Por exemplo, veja se você
consegue entender o que causou essa mensagem de erro:
Traceback (most recent call last):
File "C:\Python27\Lib\site-
packages\pythonwin\pywin\framework\scriptutils.py", line 310, in
RunScript
exec codeObject in __main__.__dict__
File "C:\PSU_Python_Practice\syntax_error_practice.py", line 4, in
<module>
x = x / 0
ZeroDivisionError: integer division or modulo by zero
Embora a mensagem comece com algum conteúdo que você provavelmente não
entende, é possível verificar que o erro foi causado na Linha 4: x = x / 0. A divisão por 0 não
é possível e o computador não poderá fazê-lo.
É mais fácil interpretar mensagens como essa se você exibiu números de linha para o
seu código no PythonWin. Para obter os números de linha:
• No PythonWin, clique em View > Options.
• Clique na guia Editor.
• Defina a propriedade de números de linha (Line Numbers) para um número
maior, como 30.
Os números de linha também são úteis se você fizer um e-mail ou postar em algum
fórum sobre seu código e incluir o script. Você pode apontar imediatamente a linha erro para
seus colegas.
Depuração Ad-hoc
Às vezes é fácil incluir algumas instruções de 'print' em todo o código para descobrir
até onde ele executou ou para verificar o que está acontecendo com certos valores no script
enquanto ele é executado. Isso também pode ser útil para verificar se seus loops estão
fazendo o que você espera e se está evitando erros "off-by-one".
Suponha que você esteja tentando encontrar o valor médio (médio) dos itens em uma
lista com o código abaixo.
70
# Encontre a média dos itens numa lista
lista = [22,343,73,464,90]
for item in lista:
total = 0
total += item
media = total / len(lista)
print ("A média é " + str(media))
O script informa "A média é 18", o que não parece correto. A partir de uma rápida
verificação visual dessa lista, você poderia imaginar que a média seria maior que 100. O
script não está pegando erroneamente o número 18 da lista; não é um dos valores. Então,
de onde vem isso? Você pode colocar algumas instruções estratégicas de impressão no
script para obter um relatório melhor sobre o que está acontecendo:
# Encontre a média dos itens numa lista
lista = [22,343,73,464,90]
for item in lista:
print ("Processando o loop...")
total = 0
total += item
print (total)
print (len(lista))
media = total / len(lista)
print ("Executando a divisão...")
print ("A média é " + str(media))
Agora, quando você executa o script, você vê.
Processando o loop ...
22
Processando o loop ...
343
Processando o loop ...
73
Processando o loop ...
464
Processando o loop ...
90
5
Executando divisão ...
Média é 18
O erro agora se torna mais claro. O total em execução não está sendo mantido com
sucesso; em vez disso, ele é redefinido toda vez que o loop é executado. Isso faz com que
o último valor, 90, seja dividido por 5, gerando uma resposta de 18. Você precisa inicializar
71
a variável para o total fora do loop para evitar que isso aconteça. Depois de corrigir o código
e remover as instruções de impressão, você obtém:
# Encontre a média dos itens numa lista
lista = [22,343,73,464,90]
total = 0
for item in lista:
total += item
media = total / len(lista)
print ("A média é " + str(media))
O resultado "A média é 198" parece muito melhor. Você corrigiu um erro lógico no seu
código: um erro que não faz o seu script falhar, mas produz o resultado errado.
Embora a depuração com instruções de impressão seja rápida e fácil, você precisa ser
cuidadoso com ela. Depois de corrigir seu código, lembre-se de remover as instruções para
tornar seu código mais rápido e menos confuso. Além disso, adicionar instruções de
impressão se torna impraticável para scripts longos ou complexos. Você pode identificar os
problemas mais rapidamente e rastrear muitas variáveis ao mesmo tempo usando o
depurador do PythonWin, que é abordado na próxima seção.
72
print (numero)
Mesmo que você consiga identificar o erro, siga os passos abaixo para ter uma idéia
do processo de depuração e da barra de ferramentas Debugging do PythonWin.
• Abra o PythonWin e copie o código acima em um novo script.
• Salve seu script como fatorial.py. Você pode, opcionalmente, executar o
script, mas não obterá um resultado e poderá ter que fechar o PythonWin para voltar ao
local onde estava.
• Clique em View > Toolbar e verifique se a opção Debugging está marcada.
Muitos IDEs têm barras de ferramentas de depuração como essa, e as ferramentas que
elas contêm são bastante padronizadas: uma maneira de executar o código, uma
maneira de definir pontos de interrupção, uma maneira de percorrer o código linha por
linha e uma maneira de observar o valor das variáveis enquanto percorre-se o código.
Vamos analisar cada uma delas nas etapas abaixo.
• Defina o seu cursor na linha (numero = 5) e clique no botão Toggle Breakpoint
. Um ponto de interrupção é um local onde você deseja que seu código pare de ser
executado para que você possa examiná-lo linha por linha usando o depurador. Muitas
vezes, você definirá um ponto de interrupção no meio do script para não precisar
examinar cada linha de código. Neste exemplo, o script é muito curto, então estamos
colocando o ponto de interrupção no começo. O ponto de interrupção é representado por
um círculo ao lado da linha de código e isso é comum em outros depuradores também.
• Clique no botão Step . Isso executa uma linha do seu código. Observe na
sua janela de observação que a variável "numero" agora tem um valor de 5.
• Clique no botão Step novamente. Desta vez, a variável "multiplicador" foi
atribuída a um valor.
• Clique no botão Step mais algumas vezes para percorrer o loop. Vá devagar e
use a janela de observação para entender o efeito que cada linha tem nas duas variáveis.
73
• Percorra o loop até que "multiplicador" atinja um valor de 10. Deve ficar óbvio,
neste ponto, que o loop não saiu no ponto desejado. Nossa intenção era que ele
desistisse quando "numero" chegasse a 120.
• Você consegue identificar o erro agora? O fato de o loop não ter saído deve
chamar sua atenção para a condição de loop. O loop só sairá quando "multiplicador" for
maior que ou igual a "numero". Obviamente, isso nunca acontecerá, já que "numero"
continua ficando maior e maior à medida que é multiplicado a cada vez por meio do loop.
Neste exemplo, o código continha um erro lógico. Ele reutilizou a variável para a qual
desejamos encontrar o fatorial (5) como uma variável na condição de loop, sem considerar
que o número seria repetidamente aumentado dentro do loop. Alterar a condição de loop
para o seguinte faria com que o script funcionasse:
while multiplicador <5:
Melhor ainda do que codificar o valor 5 nessa linha seria inicializar uma variável inicial
e configurá-la como igual ao número cujo fatorial queremos localizar. O número pode então
ser multiplicado independentemente da variável de condição de loop.
• Feche o PythonWin e abra novamente para um novo script. Cole o código
abaixo e salve o script como fatorial2.py.
# Este script calcula o fatorial de um número
# inteiro, que é o produto desse inteiro e de
# todos os inteiros positivos menores que ele
number = 5
loopStop = numero
multiplicador = 1
while multiplicador < loopStop:
numero *= multiplicador
multiplicador += 1
print (numero)
• Exiba a barra de ferramentas Debugging e percorra o loop algumas vezes,
como fez anteriormente. Observe os valores das variáveis "numero" e "multiplicador",
mas, desta vez, adicione também a variável "loopStop". Essa variável permite que a
condição de loop permaneça constante enquanto "numero" é multiplicado. Na verdade,
você deve ver "loopStop" permanecer fixo em 5, enquanto "numero" aumenta para 120.
• Continue avançando até que "numero" atinja 120 e você atinja a linha
"print(numero)". Nesta linha, não pressione o botão Step; em vez disso, basta pressionar
Go para finalizar o script. (Você não quer percorrer todo o código Python interno
necessário para imprimir a variável.) Nesse ponto, o valor de "numero" deve ser 120, que
é 5 fatorial. Se você quiser, você pode tentar substituir outros inteiros como o valor de
"numero" para encontrar seus fatoriais.
No exemplo acima, você usou a barra de ferramentas Depuração para localizar um erro
lógico que causou um loop infinito em seu código. As ferramentas de depuração geralmente
são seu melhor recurso para localizar erros sutis em seu código.
Se você acessar uma função interna do Python, como “print”, enquanto estiver usando
o Debug, o depurador irá adentrar diretamente em todo o código Python necessário para
executar a função. Você saberá quando isso acontecer, porque você verá uma ou mais
janelas abertas com códigos difíceis de entender. Este também é o caso, por vezes, quando
você executa funções arcpy. O problema é agravado porque esse tipo de código tende a
chamar outras funções, o que acaba abrindo muitas janelas.
74
Se você não quiser ver todo esse código, pode tentar o atalho usando o botão Steo
Over para pular uma função complexa ou Step Out para sair da função. Se
percorrer todo esse código é muito confuso, você pode definir outro ponto de interrupção
uma ou duas linhas além da linha com a função e apenas pressionar o botão Go novamente
para executar até o próximo ponto de interrupção. Quando você pressiona o botão Go, o
depurador não pára até atingir o próximo ponto de interrupção.
Você pode e deve praticar usando a barra de ferramentas de depuração nas tarefas
que você recebe neste curso. Você pode economizar muito tempo dessa forma.
Leituras
Leia Zandbergen 11.1 - 11.5 para obter dicas para depuração. Em seguida, leia 11.11
e consulte na seção sobre depuração uma lista de verificação para revisar toda vez que você
encontrar um problema em seu código.
75
arcpy.GetMessages(2) retornaria apenas as mensagens com uma gravidade de "Erro".
Mensagens de erro e aviso às vezes incluem um código exclusivo que você pode usar para
procurar mais informações sobre a mensagem. A Ajuda do ArcGIS Desktop contém tópicos
que listam os códigos de mensagem e fornecem detalhes sobre cada um deles. Algumas
das entradas têm dicas para corrigir o problema.
Try / except pode ser usado de várias maneiras e em diferentes níveis de identação
em um script. Por exemplo, você pode ter um único try / except como no exemplo acima,
onde o try-block contém toda a funcionalidade do seu programa. Se algo der errado, o script
exibirá uma mensagem de erro e será encerrado. Em outras situações, convém dividir o
código principal em partes diferentes, cada uma contida por sua própria try / except para
lidar com os problemas específicos que podem ocorrer nessa parte do código. Por exemplo,
a seguinte estrutura pode ser usada em um script em lote que realiza duas operações de
geoprocessamento diferentes em um conjunto de shapefiles quando uma tentativa deve ser
feita para executar a segunda operação, mesmo se a primeira falhar.
for featureClass in fcList:
try:
. . . # realizar operação de geoprocessamento 1
except:
. . . # lidar com falha de operação de geoprocessamento 1
try:
. . . # realizar operação de geoprocessamento 2
except:
. . . # lidar com falha de operação de geoprocessamento 2
Vamos supor que a primeira operação de geoprocessamento falhe para o primeiro
shapefile em fcList. Como resultado, a execução do programa irá para o primeiro bloco
except que contém o código para lidar com esta situação de erro. No caso mais simples,
apenas produzirá algumas mensagens de saída. Depois que o bloco-except foi executado,
a execução do programa continuará normal ao passar para a segunda instrução try / except
e tentar executar a segunda operação de geoprocessamento. Ou este é bem-sucedido ou
falha também, caso em que o segundo bloco except será executado. A última coisa a notar
é que, já que ambas as instruções try / except estão contidas no corpo do loop for, a instrução
segue pelos diferentes shapefiles da lista, mesmo que ambas as operações falhem em um
dos arquivos.
Leitura adicional
Dê uma olhada na documentação oficial do ArcGIS para mais detalhes sobre
mensagens de geoprocessamento. Não deixe de ler estes tópicos:
Entendendo os tipos e a gravidade das mensagens
(http://desktop.arcgis.com/en/arcmap/latest/analyze/python/message-types-and-
severity.htm)
Entendendo os erros e avisos da ferramenta de geoprocessamento
(https://pro.arcgis.com/en/pro-app/tool-reference/appendices/understanding-
geoprocessing-tool-errors-and-warnings.htm)
Este é o gateway na seção de referência de erro e aviso da ajuda que explica todos os
códigos de erro. Às vezes, você verá esses códigos nas mensagens recebidas e o tópico de
ajuda específico do código pode ajudá-lo a entender o que deu errado. O artigo também fala
76
sobre como você pode capturar determinadas condições em seus próprios scripts e fazer
com que códigos de erro específicos apareçam.
77
um bom lugar para aprender sobre os módulos do Python, como "os", "csv", "math" ou
"random".
Livros impressos
O livro texto Python Scripting for ArcGIS é uma introdução bem escrita para o que o
título diz: trabalhar com o ArcGIS usando Python. Existem alguns outros livros que
começaram a aparecer sobre este assunto e eu antecipo que haverá mais.
Uma boa referência geral do Python é o Learning Python, de Mark Lutz. Ele cobre
tópicos iniciantes e avançados, então não se preocupe se algumas partes dele parecerem
intimidadoras.
Fóruns ESRI e outros fóruns online
Os fóruns Esri são um lugar onde você pode fazer perguntas para outros usuários de
software ESRI, ou ler sobre problemas encontrados por outros usuários que podem ser
semelhantes aos seus. Existe um fórum do ESRI sobre Python relacionado a scripts com o
ArcGIS, e também um fórum mais geral de Geoprocessamento que você pode achar útil.
https://community.esri.com/community/developers/gis-developers/python
https://community.esri.com/community/gis/analysis/geoprocessing
Antes de postar uma pergunta nos fóruns da ESRI, faça uma pequena pesquisa para
se certificar de que a pergunta ainda não foi respondida, pelo menos recentemente.
Existem muitos outros fóruns on-line que abordam questões de programação ou SIG.
Você os verá por toda a Internet se fizer uma pesquisa no Google sobre como fazer algo no
Python. O Stack Exchange é um exemplo de um fórum técnico bem explorado, leve em
anúncios, que permite aos leitores promover ou rebaixar respostas, dependendo de sua
utilidade. Um de seus sites filho, o GIS Stack Exchange, trata especificamente de problemas
de SIG e cartografia.
http://gis.stackexchange.com/
Se você postar em fóruns on-line, forneça informações detalhadas sobre o problema e
liste o que já experimentou. Declare o problema em um sentido geral e foque no código do
problema.
78
Exercício 1: Encontrar os espaços em uma lista de nomes
Os objetos String do Python têm um método de índice que permite encontrar uma
substring na string maior. Por exemplo, se eu tivesse uma variável definida como nome =
"Joe Paterno" e se guisse com a expressão nome.index ("Pa") , ela retornaria o valor 4
porque a substring "Pa" começa no caractere 4 no string mantida em nome. (O primeiro
caractere em uma string está na posição 0.)
Para este exercício prático, comece criando uma lista de nomes como o seguinte:
beatles = ["John Lennon", "Paul McCartney", "Ringo Starr", "George
Harrison"]
Em seguida, escreva um código que percorrerá todos os itens da lista, imprimindo uma
mensagem como a seguinte:
"Há um espaço no nome de ________ na posição ____." onde o primeiro espaço em
branco é preenchido com o nome atualmente sendo processado pelo loop e o segundo
espaço em branco é preenchido com a posição do primeiro espaço no nome conforme
retornado pelo método de índice. (Você deve obter valores de 4, 4, 5 e 6, respectivamente,
para os itens da lista acima.)
Você pode começar configurando um loop e simplesmente imprimindo cada nome. Se
você fizer isso funcionar, veja se consegue simplesmente imprimir as posições do espaço.
Depois de conseguir isso, tente colocar o nome e as posições de espaço na mensagem
maior.
79
A:90-100
B:80-89
C:70-79
D:60-69
F:<60
80
Projeto 2: Ferramenta para reprojetar conjuntos de dados
vetoriais em lote (batch)
Alguns órgãos que trabalham com SIG determinaram um único sistema de referência
padrão para seus dados de origem. Os conjuntos de dados brutos, no entanto, podem ser
obtidos de terceiros em outros sistemas de referência. Esses conjuntos de dados precisam
então ser reprojetados para a projeção padrão. Reprojetar arquivos em lote, ou reprojetar
muitos conjuntos de dados de uma só vez, é uma tarefa adequada para a criação de scripts.
Neste projeto você irá praticar os fundamentos do Python escrevendo um script que
reprojetará os conjuntos de dados vetoriais de uma pasta. A partir desse script, você criará
uma ferramenta de script que pode ser facilmente compartilhada com outras pessoas.
A ferramenta que você irá desenvolver deve se parecer com a figura abaixo. Ela possui
dois parâmetros de entrada e nenhum parâmetro de saída. Os dois parâmetros de entrada
são:
• Uma pasta no disco contendo os conjuntos de dados vetoriais a serem
reprojetados.
• O caminho para um conjunto de dados vetoriais cuja referência espacial será
usada como padrão. Por exemplo, se você quiser reprojetar SIRGAS2000 UTM Zona 23,
você procuraria algum conjunto de dados vetoriais com este sistema de projeção. Este
poderia ser um dos conjuntos de dados na pasta que você forneceu no primeiro
parâmetro, ou poderia existir em outro lugar no disco.
81
mensagem, não uma mensagem por conjunto de dados reprojetado. Observe um
exemplo desse tipo de mensagem personalizada abaixo na linha "Reprojetados...":
Seu script deve relatar uma mensagem de geoprocessamento informando quais conjuntos de
dados foram projetados
• Não deve conter nenhum valor codificado diretamente no script, como nomes
de conjunto de dados, nomes de caminho ou nomes de projeção.
• Deve ser disponibilizado como uma ferramenta de script que pode ser
facilmente executada a partir do ArcToolbox por alguém sem conhecimento de scripts.
Esforços adicionais poderiam incluir o seguinte:
• Sua mensagem de geoprocessamento de conjuntos de dados projetados
contém vírgulas entre os nomes dos conjuntos de dados, sem nenhuma vírgula "final" no
final.
• A documentação de ajuda do painel lateral é fornecida para sua ferramenta de
script. Isso significa que quando você abre a caixa de diálogo da ferramenta e clica em
Mostrar Ajuda, as instruções para cada parâmetro aparecem ao lado. A Ajuda do ArcGIS
Desktop pode te ensinar como fazer isso.
• Sua ferramenta de script usa caminhos relativos ao arquivo .py e é facilmente
implantada sem ter que "reorientar" a caixa de ferramentas para o script.
Não vamos manipular transformações de datum neste script. Assume-se que cada
conjunto de dados na pasta usa o mesmo datum, embora os conjuntos de dados possam
estar em projeções diferentes. O tratamento de datum faria com que você tivesse que
adicionar um parâmetro adicional na ferramenta.
Dados para o projeto
A pasta de dados contém um conjunto de shapefiles vetoriais para você trabalhar neste
projeto e encontra-se no diretório c:\SEA5923\Dados\Shapefiles. Para o propósito deste
projeto esses conjuntos de dados estão com os sistemas de referência
GCS_Corrego_Alegre ou Corrego_Alegre_UTM_Zone_23S. Esses sistemas compartilham
o mesmo datum (Córrego Alegre) para que você não tenha que lidar com transformações de
datum. Os dados reprojetados devem ser salvos
O conjunto de dados vetoriais cuja referência espacial será usada como padrão estará
em C:\SEA5923\Dados\Shapefiles\Projetados. Esta classe de feições é um shapefile
Bacia_Onca.shp com o sistema de referência Corrego_Alegre_UTM_Zone_23S. Este
diretório também pode ser utilizado para armazenar os resultados.
Entregas
82
Entregas para este projeto são as seguintes:
O arquivo .py de origem contendo seu script
O arquivo .tbx contendo sua ferramenta de script
Um curto resumo (cerca de 300 palavras) descrevendo como você abordou o projeto,
como você lidou com os obstáculos e com o que aprendeu ao longo da tarefa.
Dicas
As dicas a seguir podem ajudar a melhorar sua possibilidade de sucesso com este
projeto:
• Não use a ferramenta ESRI Batch Project neste projeto. Em essência, você é
obrigado a fazer sua própria variação de uma ferramenta de projeção em lote neste
projeto, executando a ferramenta Project dentro de um loop. Sua ferramenta será mais
fácil de usar porque é personalizada para a tarefa em questão.
• Existem várias maneiras de inserir "_projetado" no nome de um conjunto de
dados, mas você pode achar útil começar removendo temporariamente a extensão ".shp"
e adicioná-lo novamente mais tarde. Para fazer seu código funcionar tanto para um
shapefile (que possui a extensão .shp) quanto para uma classe de feições em um
geodatabase (que não possui a extensão .shp), você pode usar o seguinte:
nomeOriginal = fc
if nomeOriginal.endswith (".Shp"):
nomeOriginal = nomeOriginal.replace (".Shp", "")
No código acima, “fc” é o nome da sua classe de feições. Se for o nome de um
shapefile, ele incluirá o .shp. A função replace procura por qualquer string ".shp" (o primeiro
parâmetro) no nome do arquivo e a substitui por nada (simbolizado no segundo parâmetro
por aspas vazias ""). Portanto, após executar este código, a variável “nomeOriginal” conterá
o nome da classe de feições sem o ".shp". Como a função replace(..) não muda nada se a
string dada como o primeiro parâmetro não ocorrer em fc, o código acima pode ser
substituído por apenas uma única linha:
nomeOriginal = fc.replace (".shp", "")
Você também pode potencialmente cortar os últimos quatro caracteres usando algo
como
nomeOriginal = fc[: -4]
mas os números de código diferentes de 0 ou 1 em seu script podem tornar o código
menos legível para outra pessoa. Ver uma função como substituir é muito mais fácil para
alguém interpretar do que ver -4 e tentar descobrir por que esse número foi escolhido.
Portanto, você deve usar replace(..) em sua solução.
• Para verificar se um conjunto de dados já está na projeção padrão, você precisará obter
um objeto de Referência Espacial para cada conjunto de dados (o conjunto de dados a
ser reprojetado e o conjunto de dados padrão). Você precisará comparar os nomes de
referência espacial desses dois conjuntos de dados. Não deixe de comparar a
propriedade Name das referências espaciais; não compare os próprios objetos de
referência espacial. Isso ocorre porque você pode ter dois objetos de referência espacial
que são entidades diferentes (e, portanto, "não iguais"), mas possuem a mesma
propriedade de nome.
Você deve acabar com uma linha semelhante a esta:
83
if fcSR.Name != srPadrao.Name:
em que fcSR é a referência espacial da classe de feições a ser projetada e srPadrao é
a referência espacial padrão obtida do arquivo indicado nos parâmetros da ferramenta.
• Se você quiser mostrar todas as mensagens de cada execução da ferramenta Project,
adicione a linha: arcpy.AddMessage (arcpy.GetMessages()) imediatamente após a linha
na qual você executa a ferramenta Project. Cada vez que o loop é executado, ele
adicionará as mensagens da execução atual da ferramenta Project na janela de
resultados. Tem sido minha experiência que, se você esperar para adicionar esta linha
até o final do seu script, você só receberá as mensagens da última execução da
ferramenta, por isso é importante colocar a linha dentro do loop. Lembre-se de que,
enquanto você escreve seu script pela primeira vez, é possível usar instruções de
impressão para depuração e, em seguida, alternar para arcpy.AddMessage() quando
verificar que o script funciona e está pronto para criar uma ferramenta de script.
• Se você precisar de ajuda extra para criar a ferramenta de script, leia Zandbergen 13.1 -
13.10.
• Se, após todos os seus esforços, você ficar sem tempo e não puder atender a um dos
requisitos, comente no código que não está funcionando (usando um sinal # no início de
cada linha) e envie o código mesmo assim. Em seguida, explique em sua breve descrição
qual seção não está funcionando e quais problemas você encontrou.
84
Etapa 3: Acesso e manipulação de dados SIG com o Python
Uma parte essencial de um SIG são os dados que representam a geometria
(localizações) de feições geográficas e os atributos dessas feições. Essa combinação de
feições e atributos é o que faz o SIG ser mais do que um simples "mapeamento". Muito do
seu trabalho como um analista SIG envolve adicionar, modificar e excluir feições e seus
atributos em um SIG.
Além da manutenção os dados, você também precisa saber como consultar e
selecionar dados mais importantes para seus projetos. Às vezes, você desejará consultar
um conjunto de dados para localizar somente os registros que correspondem a um
determinado critério (por exemplo, setores censitários com renda per capita abaixo de
determinado valor) e calcular algumas estatísticas com base apenas nos registros
selecionados (por exemplo, porcentagem desses setores com coleta de esgoto sanitário).
Todas as tarefas acima de manutenção, consulta e estatística de dados podem se
tornar tediosas e propensas a erros se executadas manualmente. O script em Python
geralmente é uma maneira mais rápida e precisa de ler e gravar grandes quantidades de
dados. Já existem muitas ferramentas para seleção e gerenciamento de dados no
ArcToolbox. Qualquer uma dessas pode ser usada em um script Python. Para cenários mais
personalizados em que você deseja ler uma tabela por conta própria e modificar registros
um a um, o arquivo arcpy contém objetos especiais, chamados cursores, que você pode
usar para examinar cada registro em uma tabela. Você verá rapidamente como a lógica de
loop que você aprendeu na etapa 2 se torna útil quando você percorre tabelas usando
cursores.
Usar um script para trabalhar com seus dados apresenta algumas outras vantagens
sutis sobre a entrada manual de dados. Por exemplo, em um script, você pode adicionar
verificações para garantir que os dados inseridos estejam em conformidade com um
determinado formato. Você também pode encadear várias etapas da lógica de seleção que
seriam demoradas para serem executadas no ArcMap.
Esta etapa explica maneiras de ler e gravar dados SIG usando o Python. Começaremos
analisando como você pode criar e abrir conjuntos de dados em um script. Em seguida,
praticaremos a leitura e a gravação de dados usando ferramentas de geoprocessamento e
objetos de cursor. Embora isso seja mais aplicável a conjuntos de dados vetoriais, também
veremos algumas maneiras de manipular rasters com o Python. Uma vez que você esteja
familiarizado com esses conceitos, o Projeto 3 lhe dará a chance de praticar o que você
aprendeu.
Objetivos da etapa 3
85
• Entender o conceito de layers, como as eles podem ser criados e como realizar a seleção
por local com layers
• Ser capaz de escrever scripts ArcGIS que resolvam tarefas comuns com dados vetoriais,
combinando seleção por atributo, seleção por localização e manipulação de tabelas de
atributos via cursores
86
em conjuntos de dados de feições (Feature Datasets). Conjuntos de dados raster também
podem ser armazenados em geodatabases.
Conjuntos de dados independentes
Embora os bancos de dados geográficos sejam essenciais para o armazenamento e a
organização de dados a longo prazo, às vezes é conveniente acessar conjuntos de dados
em um formato "independente" no sistema de arquivos local. O shapefile da ESRI é
provavelmente o formato de dados vetoriais mais onipresente e autônomo. Um shapefile na
verdade consiste em vários arquivos que trabalham juntos para armazenar geometrias e
atributos vetoriais. Todos os arquivos têm o mesmo nome raiz, mas usam extensões
diferentes. Você pode compactar os arquivos juntos e enviá-los por e-mail facilmente ou
publicá-los em uma pasta para download. Nos navegadores de arquivos ESRI no ArcCatalog
ou no ArcMap, os shapefiles aparecem apenas como um arquivo.
Nota:
Às vezes, na documentação da ESRI shapefiles também são chamados de "classes
de feições". Quando você vê o termo "classe de feições", considere que isso significa um
conjunto de dados vetoriais que pode ser usado no ArcGIS.
Outro tipo de conjunto de dados independente que remonta aos primórdios do ArcGIS
é a coverage do ArcInfo. Como o shapefile, a coverage consiste em vários arquivos que
funcionam juntos. As coverages estão se tornando cada vez mais raras, mas você pode
encontrá-las se sua organização tiver usado (ou ainda usar!) Workstagion ArcInfo.
Conjuntos de dados raster também são frequentemente armazenados em formato
independente, em vez de serem carregados em um geodatabase. Um conjunto de dados
rasterizados pode ser um único arquivo, como JPEG ou TIFF, ou, como um shapefile, pode
consistir em vários arquivos que funcionam juntos.
Fornecendo caminhos em scripts do Python
Muitas vezes, em um script, você precisará fornecer o caminho para um conjunto de
dados. Conhecer a sintaxe para especificar o caminho às vezes é um desafio por causa das
muitas maneiras diferentes de armazenar os dados listados acima. Por exemplo, abaixo está
um exemplo de como um arquivo geodatabase se parece se você simplesmente navega
pelo sistema de arquivos do Windows Explorer. Como você especifica o caminho para o
conjunto de dados necessário? Esse mesmo desafio pode ocorrer com um shapefile, que,
embora tenha um nome mais intuitivo, possui três ou mais arquivos participantes.
87
caminho destacado mostra como você se referiria a uma classe de feições dentro do
geodatabase.
88
Aqui está um código que filtra cada classe de feição em um arquivo geodatabase para
o limite de estado do Alabama e coloca a saída em um arquivo geodatabase diferente.
Observe como as cinco linhas de código após a importação correspondem às cinco etapas
listadas acima.
import arcpy
arcpy.env.workspace = "C:\\SEA5923\\Dados\\FC\\FC.gdb"
featureClassList = arcpy.ListFeatureClasses()
clipFC = "
C:\\SEA5923\\Dados\\FC\\Resultados\\FC_Clip.gdb\\Consorcio_mun"
for fc in fcList:
arcpy.Clip_analysis(fc, clipFC,
"C:\\SEA5923\\Dados\\FC\\Resultados\\FC_Clip.gdb" + fc)
No exemplo acima, o método arcpy.ListFeatureClasses() foi a chave para fazer a lista.
Esse método examina um local de trabalho e cria uma lista Python de cada classe de feições
nesse local de trabalho. Depois de ter essa lista, você pode configurar facilmente um loop
para agir em cada item.
Observe que você designou o caminho para o espaço de trabalho usando o local do
arquivo geodatabase. Se você estivesse trabalhando com shapefiles, usaria apenas o
caminho para a pasta como o local de trabalho.
Se você estivesse trabalhando com o ArcSDE, usaria o caminho para o arquivo de
conexão .sde ao criar seu local de trabalho. Este é um arquivo que é criado quando você se
conecta ao ArcSDE no ArcCatalog e é colocado em seu diretório de perfil local. Nós não
estaremos acessando os dados em ArcSDE neste curso.
89
Acessando campos da tabela de atributos
Antes de nos aprofundarmos no acesso a dados vetoriais, será útil revisar rapidamente
como os dados vetoriais são armazenados no software. As feições de vetor nas classes de
feições do ArcGIS (usando este termo para incluir shapefiles) são armazenados em uma
tabela. A tabela possui linhas (registros) e colunas (campos).
Campos da tabela de atributos
Os campos na tabela armazenam as informações de geometria e atributos para as
feições.
Existem dois campos na tabela que você não pode excluir. Um dos campos
(geralmente chamado de Shape) contém as informações de geometria para as feições. Isso
inclui as coordenadas de cada vértice da feição e permite que ela seja desenhada na tela. A
geometria é armazenada em formato binário; se você fosse vê-lo impresso na tela, não faria
sentido para você. No entanto, você pode ler e trabalhar com as geometrias usando objetos
que são fornecidos com o arcpy.
O outro campo incluído em cada classe de feições é um campo de ID de objeto
(OBJECTID ou FID). Contém um número único ou identificador para cada registro que é
usado pelo ArcGIS para rastrear as feições. O ID do objeto ajuda a evitar confusão ao
trabalhar com dados. Às vezes, os registros possuem os mesmos atributos. Por exemplo,
São Paulo e São Carlos podem ter um atributo Estado = "SP" ou um conjunto de dados de
cidades no Brasil pode mais de uma cidade com o atributo NOME = "São Carlos". no entanto,
o campo OBJECTID nunca pode ter o mesmo valor para dois registros.
O restante dos campos contém informações sobre atributos que descrevem a feição.
Esses atributos geralmente são armazenados como números ou texto.
Descobrindo os nomes dos campos
Quando você escreve um script, você precisa fornecer os nomes dos campos
específicos que deseja ler ou escrever. Você pode obter uma lista Python de nomes de
campos usando arcpy.ListFields().
# Lendo os nomes dos campos da tabela de atributos de uma FC
import arcpy
featureClass = "C:\SEA5923\Dados\BaseDados.gdb\Municipios"
fieldList = arcpy.ListFields(featureClass)
# Percorrendo a lista de campos da TA e escrevendo o nome de cada campo
for field in fieldList:
print (field.name)
O texto acima produziria uma lista dos campos da classe de feições Cidades em um
arquivo geodatabase chamado USA.gdb. Se você executou este script no PythonWin
(experimente com outras classes de feições!), você verá algo como o seguinte na Janela
Interativa.
>>> OBJECTID
Shape
GEOCODIGO
NOME
UF
REGIAO
MESOREGIAO
AREA_KM²
90
Shape_Length
Shape_Area
Observe os dois campos especiais sobre os quais já falamos: “OBJECTID”, que contém
o número de identificação exclusivo de cada registro, e “Shape”, que contém a geometria do
registro. Além disso, essa classe de feições possui campos que contêm o nome (NOME), o
estado (UF), o geocódigo do IBGE (GEOCODIGO) e assim por diante.
arcpy trata o campo como um objeto, portanto, Field tem propriedades que o
descrevem. É por isso que você pode imprimir field.name. O tópico de referência de ajuda
Usando campos e índices (http://desktop.arcgis.com/en/arcmap/latest/analyze/python/fields-
and-indexes.htm) lista todas as propriedades que você pode ler em um campo. Estes
incluem AliasName, Lenght, Type, Scale, e outros.
As propriedades de um campo são somente leitura, o que significa que você pode
descobrir quais são as propriedades do campo, mas não é possível alterar essas
propriedades em um script usando o objeto Field. Se você quisesse alterar a escala e a
precisão de um campo, por exemplo, teria que adicionar programaticamente um novo
campo.
91
• Use o código SearchCursor.next() para ler a primeira linha.
• Inicie um loop que sairá quando não houver mais linhas disponíveis para leitura.
• Faça algo com os valores na linha atual.
• Use o código SearchCursor.next() para ir para a próxima linha. Como você criou um loop,
isso o coloca de volta na etapa anterior, se houver outra linha disponível para leitura. Se
não houver mais linhas, a condição de loop não será atendida e o loop será finalizado.
Quando você tenta primeiro entender os cursores, pode ajudar a visualizar a tabela de
atributos com uma seta apontando para a "linha atual". Quando o cursor é criado pela
primeira vez, essa seta está apontando logo acima da primeira linha da tabela. Na primeira
vez que o método next() é chamado, a seta se move para a primeira linha (e retorna uma
referência a essa linha). Cada vez que next() é chamado, a seta desce uma linha. Se next()
for chamado quando a seta estiver apontando para a última linha, um tipo de dado especial
chamado None será retornado.
Aqui está um exemplo muito simples de um cursor de pesquisa que lê um conjunto de
dados de pontos que correspondem aos postos pluviométricos e imprime o nome de cada
um deles.
# Imprime o nome de cada feature class
import arcpy
featureClass = "C:\\SEA5923\\Dados\\Plu_Total_Anual.shp"
linhas = arcpy.SearchCursor(featureClass)
linha = linhas.next()
while linha:
print (linha.NAME)
linha = linhas.next()
As últimas cinco linhas do script acima correspondem às cinco etapas do fluxo de
trabalho acima. Cursores podem ser difíceis de entender no início, então vamos olhar para
essas linhas mais de perto. Abaixo estão as cinco linhas novamente com comentários para
que você possa ver exatamente o que está acontecendo:
# Imprime o nome de cada feature class
import arcpy
featureClass = "C:\\SEA5923\\Dados\\Plu_Total_Anual.shp"
# Cria o cursor de pesquisa
linhas = arcpy.SearchCursor(featureClass)
# Usa o searchCursor.next() para ler a primeira linha
linha = linhas.next()
# Inicia o loop que irá terminar quando não tivermos mais linhas
while linha:
# Faz alguma coisa com o valor da linha atual
print (linha.Nome)
# Usa o searchCursor.next() para mover para a próxima linha
linha = linhas.next()
Observe algumas outras coisas importantes antes de prosseguir:
• A condição de loop "while row:" é uma maneira booleana simples de especificar se o loop
deve continuar. Se um objeto de linha existir, a instrução será avaliada como verdadeira
e o loop continuará. Se um objeto de linha não existir, a instrução será avaliada como
falsa e o loop será finalizado.
92
• Você pode ler um valor de campo como uma propriedade de uma linha. Por exemplo,
linha.Nome forneceu o valor no campo Nome. Se sua tabela tivesse um campo Codigo,
você poderia usar linha.Codigo para obter o código.
• Os nomes "linhas" e "linha" são apenas nomes de variáveis que representam os objetos
SearchCursor e Row, respectivamente. Nós poderíamos nomear com qualquer termo.
Os exemplos ESRI tendem a nomeá-los como Rows e Row, e faremos o mesmo. No
entanto, se você precisasse usar dois cursores de pesquisa ao mesmo tempo, teria que
criar alguns nomes adicionais.
Aqui está outro exemplo em que algo mais complexo é feito com os valores da linha.
Este script encontra a precipitação média em um conjunto de dados. Para encontrar a média,
você precisa dividir a precipitação total pelo número de postos pluviométricos. O código
abaixo percorre cada registro e mantém um total da precipitação e o número de registros
contados. Uma vez que todos os registros foram lidos, apenas uma linha de divisão é
necessária para encontrar a média.
# Encontra a precipitação média em um conjunto de postos pluviométricos
import arcpy
postosPlu = "C:\\SEA5923\\Dados\\Plu_Total_Anual.shp"
linhas = arcpy.SearchCursor(postosPlu)
linha = linhas.next()
media = 0
precipitacaoTotal = 0
contador = 0
# Loop pelos registros e cálculo do total precipitado e contador
while linha:
precipitacaoTotal += linha.Total_2018
contador += 1
linha = linhas.next()
media = precipitacaoTotal / contador
print ("Média da precipitação " + str(media))
Embora o script acima seja maior do que o primeiro, ele ainda segue o padrão geral de
criação de um cursor de pesquisa, avançando para a primeira linha, fazendo algo com a
linha e repetindo o processo até que não haja registros restantes.
Lendo valores quando o nome do campo é uma variável
No script anterior, a precipitação de um registro era referenciada como
linha.Total_2018, em que o nome do campo de precipitação é Total_2018. Esta é uma
maneira muito fácil de obter um valor de campo, mas o que acontece se você quiser obter
dados para 2019 em um campo chamado Total_2019 e quiser executar o script novamente?
E se você tiver muitos scripts longos que sempre fazem referência ao campo precipitação
dessa maneira? Você teria que pesquisar cuidadosamente cada script para linha.Total_2018
e substituí-lo por linha.Total_2019 . Isso pode ser tedioso e propenso a erros.
Você pode tornar seus scripts mais versáteis usando variáveis para representar nomes
de campos. Você pode declarar uma variável, como campoPrecipitacao, para fazer
referência ao nome do campo da precipitação, seja Total_2018, Total_2019 ou
simplesmente PRECIPITACAO. O interpretador Python não irá reconhecer
linha.campoPrecipitacao, então você precisa usar linha.getValue() e passar a variável
como um parâmetro.
93
O script abaixo usa um nome de variável para obter a precipitação de cada registro. As
linhas alteradas do script acima têm um comentário acima delas "# Esta linha abaixo é nova".
Observe como uma variável denominada campoPrecpitacao é criada e o método chama
linha.getValue(campoPrecpitacao)que recupera a precipitação de cada registro.
94
media = precipitacaoTotal / contador
print ("Média da precipitação " + str(media))
Veja como você pode executar o script acima em PythonWin, fornecendo o nome do
caminho e o campo de precipitação como os argumentos.
95
Se você estiver usando o ArcGIS 10.1 ou superior, você pode usar o código acima para
cursores de busca, ou você pode usar um novo módulo de acesso a dados que foi
introduzido no arcpy. Essas funções de acesso a dados são prefixadas com arcpy.da e
oferecem um desempenho mais rápido, juntamente com um comportamento mais robusto,
quando falhas ou erros são encontrados no cursor.
O módulo de acesso a dados arcpy.da permite que você crie objetos de cursor, assim
como o arcpy, mas você os cria de forma um pouco diferente. Observe atentamente o código
de exemplo a seguir, que repete o cenário acima para calcular a precipitação média.
# coding: utf-8
# Encontra a precipitação média em um conjunto de postos pluviométricos
import arcpy
postosPlu = arcpy.GetParameterAsText(0)
campoPrecipitacao = arcpy.GetParameterAsText(1)
media = 0
precipitacaoTotal = 0
contador = 0
with arcpy.da.SearchCursor(postosPlu, (campoPrecipitacao,)) as cursor:
for linha in cursor:
precipitacaoTotal += linha[0]
contador += 1
media = precipitacaoTotal / contador
print ("Média da precipitação " + str(media))
Este exemplo usa a mesma estrutura básica que a anterior, com algumas alterações
importantes. Uma coisa que você provavelmente notou é que o cursor é criado usando uma
instrução "with". Embora a explicação de "with" seja um pouco técnica, a principal coisa a
ser entendida é que ela permite que o cursor saia do conjunto de dados normalmente,
independentemente de travar ou concluir seu trabalho com êxito.
A instrução "with" requer que você indente todo o código abaixo dela. Depois de criar
o cursor em sua instrução "with", você iniciará um loop for para percorrer todas as linhas da
tabela. Isso requer recuo adicional.
Observe que essa instrução "with" cria um objeto SearchCursor e declara que ele será
nomeado "cursor" em qualquer código subseqüente. Os cursores de busca criados com o
arcpy.da possuem alguns parâmetros de inicialização diferentes dos cursores de pesquisa
criados com o arcpy. A maior diferença é que quando você cria um cursor com arcpy.da,
você precisa fornecer uma tupla de nomes de campos que serão retornados pelo cursor.
Lembre-se de que uma tupla é uma estrutura de dados do Python muito parecida com uma
lista, exceto que ela é colocada entre parênteses e seu conteúdo não pode ser modificado.
Fornecer essa tupla acelera o trabalho do cursor porque ele não precisa lidar com as
potencialmente dezenas de campos incluídos em seu conjunto de dados. No exemplo acima,
a tupla contém apenas um campo, campoPrecipitacao. Uma tupla com apenas um item
contém uma vírgula após o item, portanto, nossa tupla acima é semelhante a:
(campoPrecipitacao,). Se a tupla tivesse vários itens, poderíamos ver algo como:
(campoPrecipitacao, campoNome).
Observe que com arcpy.da, você usa objetos de linha como com arcpy; no entanto,
você não usa o método getValue para recuperar valores das linhas. Em vez disso, você usa
a posição do índice do nome do campo na tupla que você enviou quando criou o objeto.
Como o exemplo acima submete apenas um item na tupla, a posição do índice de
campoPrecipitacao dentro dessa tupla é 0 (lembre-se de que começamos a contar a partir
96
de 0 no Python). Portanto, você pode usar linha[0] para obter o valor de campoPrecipitacao
para uma linha específica.
Como a maioria dos estudantes atualmente usa o ArcGIS versões superiores a10.1, os
exemplos deste ponto em diante usam o módulo arcpy de acesso a dados. Vale a pena
concentrar-se nas funções do arcpy.da porque ele tornará seu código mais rápido, mais
compacto e mais robusto. Você é obrigado a usar o arcpy.da em seu código de projeto da
etapa 3.
97
Depois de recuperar o subconjunto de registros, você pode seguir o mesmo padrão de
iteração através deles usando um loop for.
with arcpy.da.SearchCursor(postosPlu, (campoPrecipitacao,), '"Total_2018"
> 1000') as cursor:
for linha in cursor:
print (str(linha[0]))
Manipulando as aspas
Quando você inclui uma expressão SQL em seu construtor SearchCursor, deve
fornecê-la como uma string. É aqui que as coisas podem ficar complicadas com as aspas.
O SQL exige aspas simples e duplas em locais específicos, mas também é necessário incluir
a expressão inteira entre aspas, porque é uma string. Como você evita ficar confuso?
No Python, você pode usar aspas simples ou aspas duplas para incluir uma string.
Você deve ter notado que no exemplo acima, coloquei a expressão SQL entre aspas simples,
e não aspas duplas: '"Total_2018">1000'. Como eu sabia que as aspas duplas seriam
necessárias na instrução SQL (para cercar o nome do campo), usei aspas simples para
cercar a string inteira. Isto não é apenas para manter as coisas fáceis de ler; se eu tivesse
usado duas aspas duplas em uma linha, o interpretador Python ficaria confuso e pensaria
que eu estava criando uma string vazia. Portanto, não foi uma opção usar
""Total_2018">1000".
A situação fica mais difícil quando sua expressão SQL deve usar aspas simples e
duplas, por exemplo, quando você consulta uma variável de string. Suponha que seu script
permita que o usuário insira o ID de um posto Plu e você precise encontrá-lo com um cursor
de pesquisa. \supondo que alguns dos IDs dos postos incluem letras e outros não, portanto,
você precisa sempre tratar o ID dos postos como uma string. Sua expressão SQL
provavelmente ficaria assim: "codigo" = 'PLU0001'. Essa expressão começa com aspas
duplas e termina com aspas simples, portanto, qual estilo de aspas você usa para delimitar
toda a expressão?
Nesse caso, você não pode simplesmente colocar a expressão inteira em um estilo de
aspas; você precisa dividir a expressão em strings separadas. Veja de perto este exemplo:
ID = arcpy.GetParameterAsText(0)
expressaoSQL = '"codigo"' + " = '" + str(ID) + "'"
with arcpy.da.SearchCursor(postosPlu, (campoCodigo,), expressaoSQL) as
cursor:
...
No código acima, a variável expressaoSQL, ou a expressão SQL, é criado em partes
gerenciáveis que não misturam aspas simples e duplas. Se a parte da expressão contiver
aspas duplas, como "codigo", ela estará entre aspas simples. Se a parte da expressão
contiver aspas simples, como = ' ou apenas ', ela estará entre aspas duplas. Esse tipo de
situação é onde pode ser útil incluir temporariamente uma instrução print em seu código ou
usar as ferramentas de depuração para garantir que a variável expressaoSQL seja
construída corretamente. Pode ser útil se você puder treinar seu olho para se concentrar no
sinal + como um separador entre todas as partes independentes da sequência que você está
construindo.
Delimitadores de campo
Nos exemplos acima, os nomes de campo estão entre aspas duplas (por exemplo,
"codigo"). Esta é a sintaxe correta para shapefiles e file geodatabases, que são os únicos
tipos de dados que usaremos neste curso. Se você usa personal geodatabases em seu
98
trabalho diário, existem diferentes maneiras de delimitar o nome do campo. Se você estiver
interessado na sintaxe correta para diferentes tipos de dados, ou em maneiras de tornar seu
script flexível para qualquer tipo de dados, dê uma olhada no tópico Referência SQL para
expressões de consulta usadas no ArcGIS na Ajuda do ArcGIS Desktop.
http://desktop.arcgis.com/en/arcmap/latest/map/working-with-layers/sql-reference-for-
query-expressions-used-in-arcgis.htm
99
• Abra um cursor de pesquisa na camada todosEstados. O cursor incluirá apenas São
Paulo e os estados que o tocam, porque há uma seleção aplicada à essa camada.
Lembre-se de que a camada de feição é apenas um conjunto de registros mantidos na
memória. Mesmo se você chamar a camada todosEstados, ela não incluirá mais todos
os estados depois que você aplicar uma seleção.
arcpy.SelectLayerByLocation_management("todosEstados","BOUNDARY_TOUCHES",
"layerSelEstados")
# Abre um search cursor
with arcpy.da.SearchCursor("todosEstados", (nomeCampo,)) as cursor:
for linha in cursor:
# Print o nome de todos os estados da seleção
print (linha[0])
except:
print (arcpy.GetMessages())
finally:
# Limpa as camadas de feições e o cursor
arcpy.Delete_management("todosEstados")
arcpy.Delete_management("layerSelEstados")
del cursor
Você pode escolher entre vários operadores espaciais ao executar o
SelectLayerByLocation. O código acima usa "BOUNDARY_TOUCHES". Outros
relacionamentos disponíveis são "INTERSECT", "WITHIN A DISTANCE" (você pode salvar
uma etapa de armazenamento em buffer), "CONTAINS", "CONTAINED_BY" e outros.
Observe que o objeto Row "linha" retorna apenas um campo ("NOME"), que é
acessado usando sua posição de índice na lista de campos. Como há apenas um campo,
esse índice é 0 e a sintaxe é semelhante a: linha[0]. Depois de abrir o cursor de pesquisa
nos registros selecionados, você poderá executar qualquer ação que desejar. O código
acima apenas imprime o nome do estado, mas é mais provável que você queira resumir ou
atualizar os valores dos atributos. Você aprenderá a escrever valores de atributos
posteriormente nesta lição.
100
Limpando camadas de feições e cursores
Observe que as camadas de feições são excluídas usando a ferramenta Delete. Isso
ocorre porque as camadas de feições podem ocacionar bloqueios em seus dados,
impedindo que outros aplicativos usem os dados até que seu script seja concluído. O Arcpy
deve limpar as camadas de feições no final do script, mas é uma boa idéia excluí-las você
mesmo, caso isso não aconteça ou caso ocorra uma falha. Nos exemplos acima, o bloco
except é acionado no caso de uma falha, então o script continuará e executará a ferramenta
Delete.
Cursores também podem manter bloqueios nos dados. Como mencionado
anteriormente, a instrução "with" deve limpar o cursor automaticamente para você. No
entanto, descobrimos que nem sempre, uma observação que parece ser apoiada por esta
sinopse da documentação da ESRI da classe arcpy.da.SearchCursor.
http://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy-data-access/searchcursor-
class.htm
Os cursores de pesquisa também suportam instruções para redefinir a iteração e
ajudam na remoção de bloqueios. No entanto, usar uma instrução del para excluir o objeto
ou envolver o cursor em uma função para que o objeto do cursor fique fora de escopo deve
ser considerado para proteger contra todos os casos de bloqueio.
Um último ponto a relatar sobre este código que limpa as camadas de feições e o cursor
é que ele é incorporado dentro de um bloco finally. Essa é uma construção que é usada
ocasionalmente com try e except para definir o código que deve ser executado,
independentemente de as instruções no bloco try serem executadas com êxito. Para
entender a utilidade do bloco finally, imagine se você tivesse colocado essas instruções de
limpeza no final do bloco try. Se um erro ocorrer em algum lugar acima desse ponto no bloco
try - não é difícil imaginar, certo? - o restante do bloco try não seria executado, deixando as
camadas de feições e o cursor na memória. Uma execução subseqüente do script, após
corrigir o erro, encontraria um novo problema: o script não poderia criar a camada de feições
chamada "todosEstados" porque ela já existiria. Em outras palavras, as instruções de
limpeza só seriam executadas se o restante do script fosse executado com êxito.
Esta situação é onde a declaração finally é especialmente útil. O código em um bloco
finally será executado independentemente de algo no bloco try disparar uma falha. (No caso
de um erro ser encontrado, o código final será executado após o bloco except.) Assim,
conforme você desenvolve seu próprio código utilizando camadas de feição e / ou cursores,
é uma boa idéia incluir essas instruções de limpeza em um bloco finally.
Leitura obrigatória
Examine as seguintes páginas de referência de ferramentas. Você pode ignorar a
seção Sintaxe da Linha de Comando, mas preste atenção particular às Dicas de Uso e aos
Exemplos de Script.
• Make a Feature Layer
http://desktop.arcgis.com/en/arcmap/latest/tools/data-management-toolbox/make-
feature-layer.htm
• Select Layer By Location
http://desktop.arcgis.com/en/arcmap/latest/tools/data-management-toolbox/select-layer-
by-location.htm
• Select Layer By Attribute
101
• http://desktop.arcgis.com/en/arcmap/latest/tools/data-management-toolbox/select-layer-
by-attribute.htm
102
• Modifique os valores do campo na linha que precisam de atualização (veja abaixo).
• Chame UpdateCursor.updateRow() para finalizar a edição.
103
de campoAfetado), portanto, sua posição de índice é 0 na tupla. Portanto, você define esse
valor de campo usando linha[0] = valorNovo . A limpeza do cursor não é necessária no final
do script porque isso é realizado por meio da instrução "with".
A última linha com updateRow(..) é necessária para garantir que a linha modificada
seja realmente gravada de volta na tabela de atributos. Por favor, note que a linha variável
precisa ser passada como um parâmetro para updateRow(linha).
Para testar este script utilize a classe de feições de postos pluviométricos, o campo
“orgao” e substitua o valor de “ANA” para “SANEPAR” por exemplo.
C:\SEA5923\Dados\PostosPLU.shp
Bloqueio do conjunto de dados
Como mencionamos, o ArcGIS às vezes bloqueia os conjuntos de dados para evitar a
possibilidade de conflitos entre dois usuários. Se por algum motivo você acha que um
bloqueio do seu script está afetando seu conjunto de dados (impedindo que você o visualize,
fazendo com que pareça que todas as linhas foram excluídas etc.), é necessário fechar o
PythonWin para remover o bloqueio. Se você acha que o ArcGIS tem um bloqueio em seus
dados, verifique se o ArcMap ou o ArcCatalog estão usando os dados de alguma forma. Isso
pode ocorrer por meio de uma sessão de edição aberta nos dados, com os dados abertos
na guia Visualizar no ArcCatalog ou com a camada selecionada em um documento de mapa
aberto (MXD).
Como dissemos, a limpeza do cursor deve acontecer através da criação do cursor
dentro de uma instrução "with", mas adicionar linhas para excluir os objetos de linha e cursor
fará com que bloqueios com certeza sejam liberados.
Para entender como o bloqueio funciona, você pode revisar a seção "Cursores e
bloqueio" no tópico “Acessando dados usando cursores” na Ajuda do ArcGIS Desktop.
https://pro.arcgis.com/en/pro-app/arcpy/get-started/data-access-using-cursors.htm
104
with arcpy.da.InsertCursor (fc, ("Nome", "Sobrenome")) as cursor:
você adicionaria uma nova linha com os valores "Fulano" para "Nome" e "Sicrano" para
"Sobrenome" pelo seguinte comando:
cursor.insertRow(("Fulano", "Sicrano"))
Por favor, note que os parênteses internos são necessários para transformar os valores
em uma tupla que é passada para insertRow(). Escrevendo cursor.insertRow("Fulano",
"Sicrano") resultaria em um erro.
Exemplo
O exemplo abaixo usa um cursor de inserção para criar um novo ponto em um conjunto
de dados e atribuir um atributo a ele: uma descrição de string. Esse script poderia ser usado
por trás de um aplicativo no qual pessoas poderiam indicar as coordenadas e digitar uma
descrição de um incidente que precisa ser resolvido pelo município, como uma iluminação
quebrada, por exemplo.
# Adiciona um ponto e a sua descrição
import arcpy
# Valores de entrada
coorX = arcpy.GetParameterAsText(0)
coorY = arcpy.GetParameterAsText(1)
descricao = arcpy.GetParameterAsText(2)
# Parâmetros fixos, que o usuário não pode alterar
notificacaoFC = "C:/SEA5923/Dados/notificacoes.shp"
campoDescricao = "DESCR"
# Criando a tupla com os campos
camposAfetados = ("SHAPE@XY", campoDescricao)
# Criando o cursor
with arcpy.da.InsertCursor(notificacaoFC, camposAtefatos) as cursor:
# Inserindo a linha e informando a tupla de campos afetados
cursor.insertRow(((float(coorX),float(coorY)), descricao))
del cursor
Reserve um momento para garantir que você saiba exatamente como o seguinte é feito
no código:
• A criação do cursor de inserção com uma tupla de campos afetados armazenados na
variável campoAfetados
• A inserção da linha pelo método insertRow() usando variáveis que contêm os valores de
campo da nova linha
Se esse script estivesse realmente alimentando um aplicativo interativo, os valores X e
Y poderiam ser derivados de um ponto em que um usuário clicou em um mapa da Web, e
não como parâmetros, como feito no script.
Uma coisa que você deve ter notado é que a string "SHAPE@XY" é usada para
especificar o campo Shape. Você poderia esperar que isso fosse realizado apenas com
"Shape", mas o arcpy.da fornece uma lista de "tokens" que você pode usar se o campo for
especificado de uma determinada maneira. No nosso caso, seria muito conveniente apenas
fornecer os valores X e Y dos pontos usando uma tupla de coordenadas. Acontece que o
token "SHAPE@XY" permite que você faça exatamente isso. Veja o tópico de ajuda do
InsertCursor para aprender sobre outros tokens que você pode usar.
105
http://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy-data-access/insertcursor-
class.htm
Colocando tudo isso junto, o exemplo cria uma tupla de campos afetados:
("SHAPE@XY", "DESCR"). Observe que, usamos realmente a variável campoDescricao
que contém o nome da segunda coluna "DESCR" para o segundo elemento da tupla. Usar
uma variável para armazenar o nome da coluna que nos interessa nos permite adaptar
facilmente o script mais tarde, por exemplo, a um conjunto de dados em que a coluna tem
um nome diferente. Quando a linha é inserida, os valores para esses itens são fornecidos
na mesma ordem: cursor.insertRow(((float(coorX), float(coorY)), descricao)). O
argumento passado para insertRow () é uma tupla que possui outra tupla (coorX, coorY), ou
seja, as coordenadas dos pontos, como o primeiro elemento e o texto para o campo
"DESCR" como o segundo elemento.
Leituras
Reserve alguns minutos para ler o Zandbergen 7.1 - 7.3 para reforçar seu aprendizado
sobre cursores.
106
desafio mesmo no ModelBuilder construir uma expressão flexível nas ferramentas de
álgebra do mapa. Com o Python, você pode manipular a expressão tanto quanto precisar.
Exemplo
Examine o exemplo a seguir, que recebe um valor mínimo e máximo de elevação como
parâmetros e faz alguma álgebra de mapa com esses valores. A expressão isola áreas em
que a elevação é maior que o parâmetro mínimo e menor que o parâmetro máximo. As
células que satisfazem a expressão recebem um valor de 1 pelo software e as células que
não satisfazem a expressão recebem um valor de 0.
Mas e se você não quiser que esses 0 valores bagunçam sua imagem? Este script
elimina os 0s executando a ferramenta Reclassify com uma tabela de remapeamento
simples informando que os valores de rasterização de entrada de 1 devem permanecer 1.
Como 0 é deixado de fora da tabela de remapeamento, ele é reclassificado como NoData:
# Este script pega um MNT e reclassifica as áreas entre uma
# valor min e max
import arcpy
from arcpy.sa import *
arcpy.env.overwriteOutput = True
arcpy.env.workspace = "C:/SEA5923/Dados"
# Parâmetros de elevação min e max
min = arcpy.GetParameterAsText(0)
max = arcpy.GetParameterAsText(1)
arcpy.CheckOutExtension("Spatial")
# Realiza a álgebra de mapa e cria um raster temporário
MDE = Raster("MDE_onca.tiff")
tempRaster = (MDE > int(min)) & (MDE < int(max))
# Configura a tabela de remapeamento e chama Reclassify, deixando todos
# os valores diferentes 1 como NODATA
tabela = RemapValue([[1,1]])
novoRaster = Reclassify(tempRaster, "Value", tabela, "NODATA")
# Salva o raster reclassificado no disco
novoRaster.save("MDE_onca_recl.tiff")
arcpy.CheckInExtension("Spatial")
Leia o exemplo acima cuidadosamente, quantas vezes forem necessárias para você
entender o que está ocorrendo em cada linha. Observe as seguintes coisas:
• Existe uma rasterização intermediária (em outras palavras, não a saída final) que você
não deseja ter no diretório de saída. Isso é chamado de tempRaster no script.
• Observe que a expressão contém sinais > e <, assim como o operador &. Você tem que
colocar cada lado da expressão entre parênteses para evitar confundir o operador &.
• Como temos arcpy.GetParameterAsText() para obter os parâmetros de entrada, é
necessário converter essas entradas em um inteiros antes de poder fazer a álgebra do
mapa com ela. Se usássemos apenas o min, o software veria "700", por exemplo, e
tentaria interpretá-lo como uma string. Para fazer a comparação numérica, temos que
usar int(min). Então o software vê o número 700 em vez da string "700".
• A álgebra de mapas pode executar muitos tipos de matemática e operações em rasters,
não limitadas a "maior que" ou "menor que". Por exemplo, você pode usar a álgebra de
mapa para encontrar o cosseno de um raster.
• Observe que o script não chama as funções de análise espacial usando arcpy. Em vez
disso, ele importa funções do módulo Spatial Analyst (arcpy.sa import *) e chama as
107
funções diretamente. Por exemplo, não vemos arcpy.Reclassify() ; em vez disso,
apenas chamamos Reclassify() diretamente.
• Consulte o tópico Remapear Classes na ajuda para entender como a tabela de
remapeamento neste exemplo foi criada. Sempre que você executar o Reclassify, será
necessário criar uma tabela de remapeamento indicando como os valores antigos devem
ser reclassificados para novos valores. Este exemplo tem a mais simples tabela de
remapeamento possível, mas se você quiser uma tabela de remapeamento mais
complexa, precisará estudar a documentação.
http://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy-spatial-analyst/an-overview-
of-remap-classes.htm
Exercício 1
Neste exercício prático, você selecionará feições por localização e atualizará um
campo para as feições selecionados. Você também usará sua seleção para realizar um
cálculo.
Na sua pasta de dados, você tem um geodatabase BD.gdb com duas classes de
feições:
• Cidades - Contém os limites de polígonos das cidades do estado do ES.
• EstacoesFlu - contém feições de pontos que representam postos Fluviométricos.
O objetivo
Você quer descobrir quais cidades contêm postos fluviométricos e qual porcentagem
de cidades tem pelo menos um posto.
108
• A classe de feições Cidades tem um campo "estFlu", que é definido como “Falso” por
padrão. Seu trabalho é marcar esse campo como “Verdadeiro” para todas as cidades
que contenham pelo menos um posto fluviométrico dentro de seus limites.
• Seu script também deve calcular a porcentagem de cidades que têm postos
fluviométricos e imprimir esse número para o usuário.
Você não precisa criar uma ferramenta de script para essa atribuição. Você pode
codificar os valores das variáveis. Tente agrupar as variáveis de string codificadas no início
do script.
Dicas
Você pode pular para a tarefa neste momento ou ler as dicas a seguir para fornecer
algumas orientações.
• Crie duas camadas de feições: "cidadesLayer" e "postosFluLayer".
• Use SelectLayerByLocation com um tipo de relacionamento "CONTAINS" para restringir
a lista de camadas de feições de suas cidades a apenas as cidades que contêm postos
fluviométricos.
• Crie um cursor de atualização para "cidadesLayer" reduzido e faça um loop em cada
registro, configurando o campo estFlu para “Verdadeiro”.
• Para calcular a porcentagem de cidades com postos, você precisa saber o número total
de cidades. Você pode usar a ferramenta GetCount para obter um total sem escrever um
loop. Cuidado, você pode ter que mexer com a saída um pouco para obtê-la em um
formato que você possa usar. Veja o exemplo na documentação da ESRI que converte
o resultado GetCount em um inteiro.
Exercício 2
Na sua pasta de dados, você tem um geodatab