Você está na página 1de 164

Automatização SIG

voltada às aplicações ambientais

PPGSEA EESC USP - 2019


Automatização SIG voltada às aplicações ambientais
SEA 5923

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:

Frederico Fábio Mauad


Possui graduação em Engenharia Agrícola (1990), Especialização em Projeto e
Construção de Pequenas Centrais Hidrelétricas - Eletrobrás/UNIFEI, Mestrado em
Engenharia Mecânica- Energia pela Universidade Federal de Itajubá (1995), PDEE Junto
ao Instituto Superior Técnico - Lisboa 1998 e doutorado em Planejamento de Sistemas
Energéticos pela Universidade Estadual de Campinas (2000). Livre-Docente pela
Universidade de São Paulo na área de conhecimento de planejamento de sistemas
hidroenergéticos (2013). Atualmente é Professor Associado da Universidade de São Paulo.
Membro do Comitê Cientifíco do Simpósio da ABRH a partir de 2005 - atual e do Simpósio
do ENES a partir de 2007. Coordenador de Projetos de P&D com o setor Elétrico (ANEEL),
CNPq, FAPESP, FINEP, FEHIDRO e CAPES. Tem experiência na área de Engenharia
Civil, com ênfase em Hidrologia, atuando principalmente nos seguintes temas: Estudo de
Assoreamento de Grandes Reservatórios, Hidrometria Aplicada, Equipamentos para
Análise Quantitativa, Qualitativa e Sedimentometrica, Planejamento e Gerenciamento de
Recursos Hídricos, Aporte de Sedimentos, Recursos Hídricos (Quantitativo e Qualitativo),
Simulação Computacional e Usos Múltiplos da Água.

Cláudio Bielenki Junior


Graduado em Engenharia Cartográfica pela Universidade Federal do Rio Grande do Sul
(2002), Especialista em Geoprocessamento pela Universidade Federal de São Carlos
(2007). Mestre em Engenharia de Transportes pela Escola de Engenharia de São Carlos
da USP (2008). Doutor em Ciências da Engenharia Ambiental na EESC USP (2018).
Desde 2003 é especialista em geoprocessamento da Agência Nacional de Águas.
Atualmente integra a equipe de pesquisadores do Departamento de Hidrobiologia da
UFSCar. Possui experiência na área de Geociências, com ênfase em Geoprocessamento,
Geodésia Geométrica e Espacial, atuando principalmente nos seguintes temas: Recursos
Hídricos, sensoriamento remoto, geoprocessamento, cartografia. Adicionalmente atua na
área de desenvolvimento e otimização de sistemas geo e modelagem hidrológica.
Adaptado por Cláudio Bielenki Jr. do material do Instituto de Educação Eletrônica John A. Dutton,
Faculdade de Ciências Minerais e Terrestres da Penn State University
Quinn, S.; Detwiler, J.; Hardsty, F.; O’Brien, J.
GIS programming and software development. 2018.

Agosto, 2019
Este material está dividido em 4 etapas:

Etapa 1: Introdução à modelagem SIG e Python


A etapa 1 começa explicando como a automação pode tornar o trabalho de um analista
de SIG mais fácil, rápido e preciso. A primeira metade apresenta algumas das ferramentas
de análise SIG disponíveis no ArcGIS e como acessá-las em um contexto não-Python,
especificamente as janelas de diálogos do ArcToolbox, a janela do Python e a interface do
ModelBuilder. No ModelBuilder, você aprenderá como as ferramentas individuais podem ser
“encadeadas” em uma ordem designada para executar tarefas de análise complexas.
A segunda parte apresenta-se a linguagem de script Python, o ambiente de
desenvolvimento PythonWin e a programação orientada a objetos em geral. A lição é
concluída com alguns exemplos simples de scripts, projetados para mostrar como o Python
se conecta ao ArcGIS e como você pode escrever um script Python usando as mesmas
ferramentas que se acessa no ArcToolbox.
Esboço da etapa 1:
• A necessidade de automação SIG
• Explorando uma caixa de ferramentas
• Ambientes para acessar ferramentas
o Executando uma ferramenta do ArcToolbox pela sua caixa de diálogo
o Modelagem com ferramentas
• Por que aprender ModelBuilder?
o Abrindo e explorando ModelBuilder
o Parâmetros do modelo
o Conceitos avançados de geoprocessamento e ModelBuilder
o Executar uma ferramenta na janela da linha de comando
• Apresentando o Python
o O que é o Python?
o Instalando o Python e o PythonWin
o Explorando o PythonWin
• Começando a programação com Python
o Trabalhando com variáveis
o Objetos e programação orientada a objetos
o Classes
o Herança
o Sintaxe Python
• Exemplos introdutórios do Python
o Exemplo: Imprimindo a referência espacial de uma classe de feições
o Exemplo: Realizando álgebra de mapas em uma imagem raster
o Exemplo: Criando Buffers
• Fazendo uma ferramenta de script
• Projeto 1: Modelagem de zonas de precipitação (exercício ModelBuilder)
• Tarefa 1: Criando contornos para um MNT (exercício em Python)

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

Etapa 3: Acesso e manipulação de dados SIG com Python


Uma grande vantagem do script é a capacidade de ler, atualizar e adicionar dados
automaticamente. Na etapa 3 mostra-se como acessar dados vetoriais e rasterizados no
ArcGIS usando o Python. Os dados são recuperados por meio de consultas espaciais e de
atributos. A lição mostra como subconjuntos de registros podem ser atualizados com base
em determinados critérios (como por meio de uma operação de “localizar e substituir”). A
ênfase é tratamento de dados vetoriais trabalhando com as tabelas de atributos, embora
ferramentas para trabalhar com dados raster também sejam discutidas.
Esboço da etapa 3:
• Armazenamento e recuperação de dados no ArcGIS
• Lendo dados de atributos de vetores
o Acessando s campos da tabela de atributo
o Lendo registros
o Recuperando registros usando uma consulta de atributo
o Recuperando registros usando uma consulta espacial
• Escrevendo dados de atributo de vetores
o Atualizando registros existentes
o Inserindo novos registros
• Trabalhando com rasters
• Projeto 3

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

No final desta etapa, você deve:


• Ser capaz de criar fluxos de trabalho automatizados no ArcGIS ModelBuilder;
• Estar familiarizado com o ambiente de desenvolvimento do Python;
• Conhecer alguns dos tipos de dados básicos mais importantes do Python e
como usar variáveis em scripts Python;
• Estar familiarizado com os conceitos básicos de programação orientada a
objetos (por exemplo, classes e herança);
• Ser capaz de usar funções de ferramentas do Arcpy para realizar tarefas
básicas de análise espacial; e
• Saber como criar uma ferramenta de script simples e passar um parâmetro
para um script.

A necessidade de automação SIG


Um sistema de informação geográfica (SIG) pode manipular e analisar conjuntos de
dados espaciais com o objetivo de resolver problemas geográficos. Os analistas de SIG
realizam todos os tipos de operações em dados para torná-lo útil para resolver um problema
localizado. Isso inclui recorte, reprojeção, buffer, mesclagem, mosaicagem, extração de
subconjuntos dos dados e centenas de outras operações. No software ArcGIS utilizado neste
curso, essas operações são conhecidas como geoprocessamento e são realizadas por meio
de ferramentas.
Uma análise SIG bem-sucedida requer a seleção das ferramentas mais apropriadas
para operar sobre os seus dados. O ArcGIS usa uma metáfora de caixa de ferramentas para
organizar seu conjunto de ferramentas. Você escolhe as ferramentas necessárias e as
executa na ordem correta para ter um resultado esperado.
Suponha que você seja responsável por selecionar locais para um aterro sanitário.
Você pode usar uma ferramenta para selecionar lotes de terra ao longo de uma via de
acesso, outra ferramenta para selecionar parcelas não menores que uma determinada área
e outras ferramentas para outros critérios de seleção, como distância a mananciais, tipo de
solo entre outros. Se esse processo de seleção fosse limitado a uma única área,
provavelmente faria sentido executar o trabalho manualmente.
No entanto, vamos supor que você seja responsável por realizar a mesma análise para
várias cidades. Como esse cenário envolve a execução da mesma sequência de
ferramentas para várias áreas, é uma tarefa que se presta bem à automação. Existem vários
benefícios importantes para automatizar tarefas como esta:

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.

Explorando uma caixa de ferramentas


O software ArcGIS que você utiliza neste curso contém centenas de ferramentas que
você pode usar para manipular e analisar dados SIG. Antes que o ArcGIS tivesse uma
interface gráfica de usuário (GUI), as pessoas acessavam essas ferramentas digitando
comandos. Hoje em dia, você pode apontar e clicar em seu caminho por toda uma hierarquia
de caixas de ferramentas usando o ArcCatalog ou a janela Catálogo no ArcMap.
Embora você possa tê-los visto antes, vamos dar uma olhada rápida nas caixas de
ferramentas:
• Abra o ArcMap.
• Se a janela Catálogo não estiver visível, clique no menu Windows e, em
seguida, clique em Catalog. Se você passar o mouse sobre ou clicar no item Catálogo
no lado direito da tela, poderá fazer com que a janela Catálogo apareça. Opcionalmente,
você pode "fixá-lo" para que ele não se esconda.
• No Catálogo, expanda os nós Toolboxes> System Toolboxes e continue
expandindo as caixas de ferramentas de sua escolha até ver algumas das ferramentas
disponíveis. Observe que eles estão organizados em caixas de ferramentas e conjuntos
de ferramentas. Às vezes, é mais rápido usar a janela Search (Geoprocessing> Search
For Tools) para encontrar a ferramenta de que você precisa, em vez de navegar nesta
árvore.
• Vamos examinar uma ferramenta. Expanda AnalisysTools> Proximity>
Buffer e clique duas vezes na ferramenta Buffer para abri-la.
• Preste atenção aos componentes que compõem a interface do usuário.
Especificamente, você está olhando para uma caixa de diálogo com muitos campos.
Cada ferramenta de geoprocessamento exige parâmetros de entradas e saídas. Estes
são indicados pelos pontos verdes. Eles representam a quantidade mínima de
informações que você precisa fornecer para executar uma ferramenta. Para a ferramenta
Buffer, é necessário fornecer um local que indica o arquivo de entrada (as feições que

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.

Ambientes para acessar ferramentas


Você pode acessar as ferramentas de geoprocessamento do ArcGIS de várias
maneiras diferentes:
• Às vezes, você só precisa executar uma ferramenta uma única vez ou testar
uma ferramenta e seus parâmetros. Neste caso, você pode abrir a ferramenta

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.

Executando uma ferramenta a partir de sua caixa de diálogo


Vamos começar abrindo uma ferramenta a partir da janela Catálogo e executando-a
usando sua interface gráfica do usuário (GUI).
• Se por acaso você ainda tiver a ferramenta Buffer aberta da seção anterior,
feche-a por enquanto para adicionar alguns dados.
• Crie uma pasta na sua máquina em C:\SEA5923. Se você usar um caminho
diferente, substitua seu caminho nos exemplos a seguir.
• Extraia os dados de Dados.zip para sua nova pasta, de modo que os dados
fiquem no caminho C:\SEA5923\Dados\. Esta pasta contém uma variedade de conjuntos
de dados que você usará ao longo da lição.
• Abra o ArcMap e crie um novo mapa.

• 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.

Captura da tela Results mostrando a ferramenta Buffer e todas as mensagens.

Modelando com ferramentas


Quando você trabalha com geoprocessamento, muitas vezes você vai querer usar a
saída de uma ferramenta como entrada para outra ferramenta. Por exemplo, suponha que
você queira encontrar todos os hidrantes a menos de 200 metros de um prédio. Você
realizaria primeiro o buffer de 200 metros e, em seguida, usaria o buffer de saída como uma
restrição espacial para selecionar hidrantes. A saída da ferramenta Buffer seria usada como
uma entrada para a ferramenta Select by Location.

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.

Por que aprender ModelBuilder?


ModelBuilder é a interface gráfica da ESRI para fazer modelos. Você pode arrastar e
soltar ferramentas da janela Catálogo para o modelo e “conectá-las”, especificando a ordem
na qual elas devem ser executadas.
Embora este seja basicamente um curso sobre scripts, passaremos algum tempo no
ModelBuilder durante a primeira lição por dois motivos:
O ModelBuilder é um ambiente agradável para explorar as ferramentas do ArcGIS,
aprender como as entradas e saídas da ferramenta são usadas e entender visualmente
como a modelagem do SIG funciona. Quando você começar a usar o Python, você não terá
a mesma assistência visual para ver como as ferramentas que você está usando estão
conectadas, mas você ainda pode querer desenhar seu modelo em um quadro de forma
semelhante ao que você viu no ModelBuilder.
ModelBuilder pode frequentemente reduzir a quantidade de codificação Python que
você precisa fazer. Se o seu problema de SIG não requer uma lógica condicional e iterativa
avançada, você poderá executar seu trabalho no ModelBuilder sem escrever um script.
ModelBuilder também permite que você exporte qualquer modelo para código Python, então
se você ficar preso implementando algumas ferramentas dentro de um script, pode ser útil
criar um modelo de trabalho simples em ModelBuilder e exportá-lo para Python para ver
como o ArcGIS construiria o código. (A exportação de um modelo complexo não é
recomendada para iniciantes devido à quantidade detalhada de código que o ModelBuilder
tende a criar ao exportar o Python).

Abrindo e explorando ModelBuilder


Vamos praticar um pouco com o ModelBuilder para resolver um cenário real. Suponha
que você esteja trabalhando em um problema de seleção de locais (áreas com aptidão a
determinado uso, por exemplo), no qual você precisa selecionar todas as áreas que caem
dentro de 5 km de uma rodovia principal e 5 km de uma cidade. A área selecionada não
pode ficar no oceano ou fora de um limite definido. Resolver o problema exige que você faça
buffers em torno das estradas e das cidades, cruze os buffers e, em seguida, limite-os ao
contorno determinado. Em vez de abrir manualmente a ferramenta Buffer duas vezes,

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:

A aparência do modelo seguindo o passo acima.


• A etapa final é recortar os buffers interceptados no contorno dos Estados
Unidos. Isso impede que qualquer área selecionada caia fora do limite. Na janela

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.

O modelo completo com a ferramenta de clipe incluída.


• Clique duas vezes no elemento de saída final (chamado "Área de Aptidão" na
imagem acima) e defina o caminho para C:\SEA5923\Dados\AreaAptidao.shp.
• Clique com o botão direito do mouse em "Área de Aptidão" e clique em Add to
display.
• Salve seu modelo novamente.

• Teste o modelo clicando no botão Executar. . O ModelBuilder também


fornece uma indicação visual de qual ferramenta está sendo executada, tornando a
ferramenta em execução vermelha.
• Quando o modelo terminar de rodar (pode demorar um pouco), examine a
saída no ArcMap. Amplie para verificar se o Clip funcionou nas áreas costeiras. A saída
deve ser semelhante a isso.

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.

Execução de modelo sem parâmetros

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:

A interface do modelo, ou diálogo da ferramenta, para o modelo "Localizar áreas de


aptidão com parâmetros"
• As pessoas que executam esse modelo poderão navegar em quaisquer
conjuntos de dados de cidades, rodovias e limites e poderão controlar a distância do
buffer. Os pontos verdes indicam parâmetros que devem ser fornecidos com valores
válidos antes que o modelo possa ser executado.

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.

Conceitos avançados de geoprocessamento e ModelBuilder


Até agora você já teve alguma prática com o ModelBuilder e está pronto para começar
a usar o Python. Esta parte da lição contém algum material avançado que você pode ler
sobre o ModelBuilder. Isso é particularmente útil se você faz uso do ModelBuilder com
frequência no seu trabalho. Alguns dos itens são comuns à estrutura de geoprocessamento
do ArcGIS, o que significa que eles também se aplicam ao escrever scripts Python com o
ArcGIS.
Gerenciando dados intermediários
A análise em SIG às vezes é extensa confusa. A maioria das ferramentas que você
executa produz um conjunto de dados de saída e, ao encadear várias ferramentas, esses
conjuntos de dados começam a se acumular no disco. Mesmo que você seja diligente em
nomear intuitivamente seus conjuntos de dados, é fácil acabar com uma pasta cheia de
conjuntos de dados com nomes como buffers1, clippedbuffers1,
intersectedandclippedbuffers1, raster2reclassificados, etc.
Na maioria dos casos, você está preocupado apenas com o conjunto de dados de saída
final. Os dados intermediários são apenas temporários; você só precisa mantê-lo durante o
tempo necessário para executar o modelo e, depois, ele pode ser excluído.
O ModelBuilder pode gerenciar seus dados intermediários para você, colocando-os em
um diretório temporário chamado de scratch workspace (área de trabalho de rascunho). Por
padrão, a área de trabalho de rascunho é o diretório temporário de seu sistema operacional,
mas você pode configurá-lo para existir em outro local.
Você pode forçar os dados a entrarem na área de trabalho de rascunho usando a
variável %SCRATCHWORKSPACE% no caminho. Por
exemplo:%SCRATCHWORKSPACE%\myOutput.shp
Você também pode marcar qualquer elemento no ModelBuilder como Intermediário e
ele será excluído depois que o modelo for executado. Por padrão, todos os dados derivados
são intermediários.
Os tópicos a seguir da ajuda da ESRI entram em mais detalhes sobre dados
intermediários e são importantes para entender quando você trabalha com o framework de
geoprocessamento. Eu sugiro lê-los uma vez agora e retornar a eles ocasionalmente durante

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.

Introduzindo o Python usando a janela do Python no ArcGIS


A melhor maneira de introduzir o Python pode ser olhar um pouco de código. Vamos
pegar a ferramenta Buffer que você executou recentemente na GUI do ArcToolbox e
executá-la na janela de Comandos Python do ArcGIS. Esta janela permite que você digite
uma simples série de comandos Python sem escrever scripts completos. A janela do Python
é uma ótima maneira de ter um primeiro contato com o Python.
Desta vez, faremos buffers de 10 Km ao redor das cidades.
• Abra o ArcMap para um novo mapa.
• Adicione o conjunto de dados Sedes_Municipais.shp do diretório de dados.

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.

A janela interativa no PythonWin


Para realmente escrever um novo script, clique em File> New e escolha Python Script.
Observe uma página em branco se abre que parece muito com o Bloco de Notas. No entanto,
o interessante dessa interface é que o código é codificado por cores e a fonte padrão,
Courier, é aquela normalmente usada pelos programadores. O espaçamento e o recuo, que
são importantes no Python, também são fáceis de acompanhar nessa interface.

A barra de ferramentas Standard

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.

Trabalhando com variáveis


É hora de praticar um pouco com alguns conceitos de programação iniciais que
ajudarão você a escrever scripts simples em Python até o final da Aula 1. Vamos começar
examinando as variáveis.
Lembre-se da sua primeira aula introdutória de álgebra, onde você aprendeu que um
caractere poderia representar qualquer número, como na declaração x + 3. Esta pode ter
sido sua primeira exposição a variáveis. Na ciência da computação, as variáveis
representam valores ou objetos que você deseja que o computador armazene em sua
memória para uso posterior no programa.
Variáveis são frequentemente usadas para representar não apenas números, mas
também valores de texto e “booleanos” ('true' ou 'false'). Uma variável pode ser usada para
armazenar uma entrada do usuário do programa, para armazenar valores retornados de
outro programa, para representar valores constantes e assim por diante.
Variáveis tornam seu código legível e flexível. Se você codificar seus valores, o que
significa que você sempre usa o valor literal, seu código é útil somente em um cenário
específico. Você pode alterar manualmente os valores em seu código para ajustar-se a um
cenário diferente, mas isso é entediante e expõe a um risco maior de cometer um erro
(suponha que você tenha se esquecido de alterar algum valor). As variáveis, por outro lado,
permitem que seu código seja útil em muitos cenários e sejam fáceis de parametrizar, o que
significa que você pode permitir que os usuários alterem os seus valores para o que
precisarem.
Para ver algumas variáveis em ação, abra o PythonWin e digite isso na Janela
Interativa:
>>> x = 2

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.

Objetos e programação orientada a objetos


As variáveis numéricas e de string com as quais trabalhamos anteriormente
representam tipos de dados que são construídos no Python. As variáveis também podem
representar outras coisas, como conjuntos de dados SIG, tabelas, linhas e o geoprocessador
que vimos anteriormente que podem executar ferramentas. Todas essas coisas são objetos
que você usa quando trabalha com o ArcGIS em Python.
Em Python, tudo é um objeto. Todos os objetos possuem:
• Um ID único ou localização na memória do computador
• Um conjunto de propriedades que descrevem o objeto
• Um conjunto de métodos ou coisas que o objeto pode fazer
Uma maneira de entender objetos é comparar a execução de uma operação em uma
linguagem procedural (como FORTRAN) para executar a mesma operação em uma
linguagem orientada a objetos. Vamos fingir que estamos escrevendo um programa para
fazer um sanduíche de manteiga de amendoim e geleia. Se fôssemos escrever o programa
em uma linguagem procedural, fluiria algo assim:
• Vá até a geladeira e pegue a geleia e o pão.
• Vá até o armário e pegue a manteiga de amendoim.
• Retire duas fatias de pão.
• Abra os frascos.
• Pegue uma faca.

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.

Exemplo: Imprimindo a referência espacial de uma classe de


feições
Este primeiro script de exemplo retorna a referência espacial (sistema de coordenadas)
de uma classe de feições armazenada em um geodatabase:
1 # Abre uma feature class de um geodatabase e retorna a sua
2 # referência espacial
3
4 import arcpy
5
6 featureClass = "C:/SEA5923/Dados/BaseDados.gdb/Limite"
7
8 # O comando Describe aponta para as propriedades da fc
9 desc = arcpy.Describe(featureClass)

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.

Exemplo: Realizando álgebra de mapas com um raster


Aqui está outro script simples que localiza todas as células acima de 750 metros em
um MDT e que codifica todas essas células como 1. Os valores restantes são codificados

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.

1 # Este script usa algebra de mapa para encontrar valores


2 # em um raster maiores que 750 metros
3
4 import arcpy
5 from arcpy.sa import *
6
7 # Especifica o dado raster de entrada
8 rasterEntrada = "C:/SEA5923/Dados/MDE_500m.tiff"
9 elevacaoCorte = 750
10
11 # Realiza a algebra de mapa e salva o resultado
12 rasterSaida = Raster(rasterEntrada) > elevacaoCorte
13 rasterSaida.save("C:/SEA5923/Dados/MDE_Alt750")
Comece examinando esse script e tentando descobrir o máximo que puder com base
no que você lembra dos scripts anteriores que viu.
Os principais pontos a serem lembrados neste script são:
• rasterEntrada começa como uma string, mas depois é usado para criar um
objeto Raster quando você executa Raster(rasterEntrada). Um objeto Raster é um objeto
especial usado para trabalhar com conjuntos de dados tipo imagem ou modelos
numéricos no ArcGIS. Ele não está disponível em nenhum script Python: você pode usá-
lo somente se importar o módulo arcpy na parte superior do script.
• elevacaoCorte é uma variável numérica que você declara no início do seu script
e depois usa quando você cria a expressão de álgebra do mapa para sua rasterSaida.
• A expressão rasterSaida = Raster (rasterEntrada)> elevacaoCorte está
dizendo, em termos simples, "Crie uma nova imagem e chame-a de rasterSaida. Faça
isso tomando todas as células do conjunto de dados raster no caminho de rasterEntrada
que são maiores que o número I atribuído à variável elevacaoCorte".
• rasterSaida também é um objeto Raster, mas você deve chamar o método
rasterSaida.save() para torná-lo permanente no disco. O método save() recebe um
argumento, que é o caminho para o qual você deseja salvar.
• Agora tente executar o script usando o modelo de elevação digital (DEM)
MDE_500m.tiff de sua pasta de dados. Se não funcionar na primeira vez, verifique se:

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.

Exemplo: Criando buffers


Pense no exemplo anterior em que você executou alguma álgebra de mapa em um
modelo de elevação. Se você quisesse alterar o valor de sua elevação de corte para 1000
em vez de 750, você teria que abrir o script em si e alterar o valor da variável elevacaoCorte
diretamente no código.
Este terceiro exemplo é um pouco diferente. Em vez de codificar os valores necessários
para a ferramenta (em outras palavras, incluir literalmente os valores no script), usaremos
algumas variáveis ou parâmetros de entrada do usuário. Isso permite que as pessoas
experimentem valores diferentes no script sem alterar o próprio código. Assim como no
ModelBuilder, os parâmetros disponibilizam seu script para um público mais amplo.
O exemplo simples abaixo apenas executa a ferramenta Buffer, mas permite que o
usuário insira o caminho dos conjuntos de dados de entrada e saída, bem como a distância
do buffer. Os parâmetros fornecidos pelo usuário entram no script com o método
arcpy.GetParameterAsText().
Examine cuidadosamente o script abaixo, mas não tente executá-lo ainda. Você fará
isso na próxima parte da lição.

1 # Este script executa a ferramenta Buffer. O usuário indica


2 # os caminhos de entrada e saída, e a distância do buffer.
3
4 import arcpy
5 arcpy.env.overwriteOutput = True

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.

Fazendo uma ferramenta de script


As variáveis de entrada do usuário que você recupera por meio do comando
GetParameterAsText() facilitam muito a conversão de seu script em uma ferramenta no
ArcGIS.
Algumas poucas pessoas sabem como alterar um código Python, outras poucas sabem
executar um script Python e fornecer as variáveis de entrada do script, mas quase todos os
usuários do ArcGIS sabem como abrir o ArcToolbox e executar uma ferramenta. Para
terminar esta lição, vamos pegar o script anterior e transformá-lo em uma ferramenta que
pode ser facilmente executada no ArcGIS.
Antes de começar este exercício, eu recomendo fortemente que você verifique o tópico
de ajuda do ArcGIS Adicionando uma ferramenta de script. Você provavelmente não
entenderá todas as partes deste tópico ainda, mas lhe dará alguma familiaridade com as
ferramentas de script que serão úteis durante o exercício.
Siga estas etapas para criar uma ferramenta de script:
• Copie o código da tarefa "Exemplo: Criando Buffers" em um novo script
PythonWin e salve-o como buffer_user_input.py.

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:

Inserindo informações para sua ferramenta de script.


• Clique em Avançar (Next) e forneça o arquivo de script. Para fazer isso,
clique no ícone da pasta e navegue até o arquivo buffer_user_input.py.
• Clique em Avançar (Next) e examine a caixa de diálogo exibida. É aqui que
você pode especificar os parâmetros do seu script. Os parâmetros são os valores para
os quais você usou arcpy.GetParameterAsText() no seu script, ou seja, entrada, saida e
distanciaBuffer. Você usará essa caixa de diálogo para listar esses parâmetros na
mesma ordem, exceto que você pode fornecer aos parâmetros nomes mais fáceis de
entender.
• Na coluna Display Name que você vê na parte superior deste assistente, clique
na primeira célula vazia e digite “Classe de feições de entrada”.
• Imediatamente à direita, clique na primeira célula vazia na coluna Data Type e
escolha Feature Class. Aqui está uma das grandes vantagens de criar uma ferramenta

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).

Alterando as propriedades de um parâmetro


• Adicione uma terceira propriedade chamada “Distância do buffer”. Escolha
Linear Unit como o tipo de dados. Esse tipo de dados permitirá que o usuário da
ferramenta selecione o valor da distância e as unidades (por exemplo, milhas,
quilômetros, etc.).

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:

Inserindo valores de entrada padrão em um parâmetro


• Clique em Finish e, na janela Catalog, abra sua nova ferramenta de script
clicando duas vezes nela.

Ferramenta completa pronta para rodar


• Experimente a sua ferramenta colocando em buffer qualquer classe de feições
de seu computador. Observe que, uma vez que você fornece a classe de feições de
entrada, um caminho da classe de feições de saída é sugerido para você. Isso ocorre
porque você define especificamente a Classe de Recurso de Saída como um parâmetro
de saída. Além disso, quando a ferramenta estiver concluída, examine a janela
Resultados da mensagem personalizada "Tudo certo!" que você adicionou em seu
código.

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:

Comparação da nossa ferramenta de script com a principal ferramenta de buffer


• Em algum momento, você pode precisar projetar um conjunto de ferramentas
para usuários de SIG iniciantes, onde apenas os parâmetros mais necessários são
expostos. Você também pode fazer isso para impor o controle de qualidade se souber
que alguns dos parâmetros devem sempre ser definidos para determinados padrões e
se deseja evitar o cenário em que um usuário inexperiente (ou um usuário não
autorizado) possa alterar os valores necessários. Uma ferramenta de script simples é
eficaz para simplificar o diálogo da ferramenta dessa maneira.

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.

Projeto 1: Modelagem de zonas de precipitação


Suponha que você esteja trabalhando em um projeto para um Departamento ambiental
e tenha a tarefa de fazer alguns mapas de precipitação para uma determinada região (uma
bacia hidrográfica, por exemplo). Membros do departamento querem ver quais partes desta
região estavam relativamente secas e úmidas no ano de 2018, classificadas em zonas. Tudo
o que você tem é uma série de leituras de estações meteorológicas de precipitação anual
acumulada para 2018 que você obteve para a região de interesse e áreas adjacentes. Este
é um shapefile de pontos chamado Plu_Total_Anual.shp. Está na sua pasta de dados.
Este é um conjunto de dados fictício criado para este projeto. As localizações
correspondem às estações meteorológicas reais. No entanto, as medições são derivadas de
dados aproximados de precipitação de anos anteriores.
Você precisa executar várias tarefas para preparar esses dados para o mapeamento:
• Interpolar uma superfície de precipitação a partir de seus pontos. Isso cria um
conjunto de dados raster com valores estimados de precipitação para toda a sua área de
interesse. Imagine que você já planejou isso, sabendo que vai usar a interpolação de
distância inversa ponderada (IDW). Você também selecionou seus pontos para incluir
algumas áreas ao redor da região de interesse para evitar efeitos de borda na
interpolação.
• Reclassificar a superfície interpolada em uma classificação ordinal de "zonas"
de precipitação que delineiam regiões relativamente secas, médias e úmidas.
• Crie polígonos vetoriais das zonas.
• Recorte os polígonos das zonas de precipitação pelo limite da região de
interesse.

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:

A saída do modelo concluído

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.

Tarefa 1: Script para criar curvas de nível


Este exercício ajudará você a praticar com o Python. Até agora você viu três exemplos
simples de scripts; aqui a sua tarefa é escrever seu próprio script. Esse script criará linhas
de contorno (curvas de nível) de vetor a partir de um conjunto de dados de elevação raster.
Não esqueça que a Ajuda do ArcGIS Desktop pode realmente ser útil se você precisar
descobrir a sintaxe de um comando em particular.
Na pasta de dados está o MNT MDE_Onca.tiff que representa as elevações na região
da bacia hidrográfica do Ribeirão da Onça no município de Itirapina SP. Escreva um script
que use a ferramenta Contour na caixa de ferramentas do Spatial Analyst para criar as
curvas de nível para a região do MNT. O intervalo de contorno deve ser de 20 metros e o
contorno de base deve ser 600. Lembre-se de que as unidades nativas do MMNT são
metros, portanto, não são necessárias conversões de unidades.
A execução do script deve criar imediatamente um shapefile de linhas de contorno no
disco.
Siga estas diretrizes ao escrever o script:
• O objetivo deste exercício é apenas fazer com que você pratique a escrita do
código Python. Portanto, você não é obrigado a usar o arcpy.GetParameterAsText () para
obter os parâmetros de entrada. Vá em frente e codifique os valores (como o nome do
caminho para o conjunto de dados).

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

Mais fundamentos do Python


Até aqui, você aprendeu sobre o ModelBuilder, e isso pode ser suficiente para resolver
muitas das tarefas de SIG que você precisa no seu trabalho. No entanto, por mais útil que
seja o ModelBuilder, você descobrirá que às vezes você precisa do Python para adicionar
inteligência em suas análises de geoprocessamento. Por exemplo, você pode precisar
construir cadeias de consulta complexas ou empregar lógica condicional. Pode ser
necessário ler ou analisar vários tipos de dados de entrada antes de poder enviá-lo para
uma ferramenta como um parâmetro. Ou você pode precisar fazer um loop complexo que,
em algum limite, provavelmente se tornará mais fácil de escrever em Python do que modelar
com o ModelBuilder.
Na etapa 1, você viu seus primeiros scripts Python e foi introduzido ao básico, como
importar módulos, usar arcpy, trabalhar com propriedades e métodos. Nas etapas a seguir,
você aprenderá mais fundamentos da programação Python, como trabalhar com listas,
executar loops, estruturas de decisão if / else, manipular strings e converter variáveis.
Embora isso possa não ser a parte mais interessante do curso, é provavelmente a
seção mais importante para você gastar tempo compreendendo e experimentando por conta
própria, especialmente se você é novo em programação.
A programação é semelhante à prática de esportes: se você dedicar algum tempo para
praticar os fundamentos, terá mais facilidade quando precisar reunir todas as suas
habilidades. Por exemplo, pense nas coisas que você precisa aprender para jogar basquete.
Um jogador de basquete disciplinado pratica dribles, passes, arremessos de longa distância,
tocos, lances livres, defesa e outras habilidades. Se você praticar cada um desses
fundamentos individualmente, você poderá usá-los todos juntos quando for a hora de jogar
um jogo completo.
Aprender uma linguagem de programação é da mesma maneira. Quando confrontado
com um problema, você será forçado a utilizar suas habilidades fundamentais para elaborar
um plano viável. Pode ser necessário incluir um loop em seu programa, armazenar itens em
uma lista ou fazer com que o programa faça uma entre tantas coisas diferentes com base

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.

# Copia todas as classes de feições de uma pasta para outra


import arcpy

try:
arcpy.env.workspace = "C:/SEA5923/Dados"

# Lista as classes de feições da pasta Dados


fcList = arcpy.ListFeatureClasses()

# percorre a lista e copia as fc para a pasta Dados2


for featureClass in fcList:
arcpy.CopyFeatures_management(featureClass, "C:/SEA5923/Dados2/"
+ featureClass)

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)

#Este loop percorre cada linha da tabela de atributos


# e armazena o valor do campo requisitado

for linha in linhas:


nomeCidade = row.getValue(campo)
print (nomeCidade)

No exemplo acima, um cursor de pesquisa denominado “linhas” recupera registros da


tabela. O loop for possibilita executar uma ação em cada registro individual.
Leitura de Ajuda do ArcGIS
Leia o seguinte na Ajuda do ArcGIS Desktop:
http://desktop.arcgis.com/en/arcmap/latest/analyze/python/listing-data.htm

Estruturas de decisão IF - ELSE


Muitos scripts que você escreve precisarão ter lógica condicional que execute um bloco
de código dado uma condição e talvez execute um bloco de código diferente, dada uma
condição diferente. O "if" as instruções "elif" e "else" no Python fornecem essa lógica
condicional. Tente digitar este exemplo na Janela Interativa do PythonWin:
>>> x = 3
>>> if x > 2:
... print ("Maior que dois")

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

# Escolhe uma escola aleatoriamente de uma lista e a imprime


escolas = ["UFSCar", "EESC USP", "UNICEP"]
randomEscolasIndex = random.randrange(0,3)
escolaEscolhida = escolas[randomEscolasIndex]
print (escolaEscolhida)

# dependendo da escola escolhida, imprime o tipo de escola


if escolaEscolhida == "UFSCar":
print ("Universidade Federal")
elif escolaEscolhida == "EESC USP":
print ("Universidade Estadual")
elif escolaEscolhida == "UNICEP":
print ("Universidade Privada")
else:
print ("Este programa apresentou um erro!")
Algumas outras linguagens de programação existem palavras-chave especiais
(comandos) para fazer o mesmo, como switch ou select case. No Python, no entanto,
geralmente é feito apenas com uma longa lista encadeada de "if"s e "elif"s.

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:

# Este script recorta (clip) todos os dados de um diretório


import arcpy

pastaEntrada = "c:\\SEA5923\\Dados\\FC\\"
pastaResultados = "c:\\SEA5923\\FC\\resultados\\"
clipFeature = "c:\\SEA5923\\Dados\\Consorcio_mun.shp"

# Cria a lista das classes de feições no diretório


arcpy.env.workspace = pastaEntrada
listaFC = arcpy.ListFeatureClasses()

# Percorre cada fc da lista e realiza o recorte


for FC in listaFC:

# Escreve o caminho concatenando strings


caminhoSaida = pastaResultados + FC
# Aplica a ferramenta de Clip para a fc
arcpy.Clip_analysis(FC, clipFeature, caminhoSaida)
A concatenação de strings está ocorrendo nesta linha: caminhoSaida =
pastaResultados + FC. A pasta de saída "C:\\SEA5923\\Dados\\FC\\resultados\\" está
recebendo o nome da classe de feição adicionado no final. Se o nome da classe de feição

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.

Colocando tudo junto


Até aqui você aprendeu os conceitos básicos de programação de listas, loops,
estruturas de decisão e manipulação de strings. Você pode se surpreender com o que você
pode fazer apenas com essas habilidades. Nesta seção, praticaremos colocando todos estes
comandos juntos para resolver um desafio.
O cenário que abordaremos é simular um jogo infantil "Hi Ho! Cherry-O" da Hasbro.
Neste simples jogo de azar, o jogador começa com 10 cerejas em uma árvore. Na sua
rodada o jogador gira uma roleta aleatória que informa se o jogador adiciona ou remove
cerejas da árvore.

Tabuleiro do jogo Hi Ho! Cherry-O


Os possíveis resultados da roleta são:
• Remover 1 cereja
• Remover 2 cerejas
• Remover 3 cerejas
• Remover 4 cerejas
• Pássaro visita seu balde de cerejas (Adicione 2 cerejas)

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:

# Simulando o jogo Hi Ho! Cherry-O


import random
valoresRoleta = [-1, -2, -3, -4, 2, 2, 10]
jogadas = 0
cerejasNaArvore = 10
# Realize uma jogada enquanto houver cerejas na árvore
while cerejasNaArvore > 0:
# Rode a roleta
roletaIndex = random.randrange(0, 7)
resultadoRoleta = valoresRoleta[roletaIndex]
# Print o resultado da roleta
print ("Você tirou " + str(resultadoRoleta) + ".")

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.

Solução de problemas e obtenção de ajuda


Se você acha que escrever um código é um processo lento, mistificado e meticuloso,
repleto de todos os tipos de oportunidades para cometer erros, seja bem-vindo ao mundo de
um programador! Talvez para seu desgosto, os programadores passam a maior parte do
tempo procurando e consertando bugs. Os programadores também precisam expandir e
adaptar continuamente suas habilidades para trabalhar com novas linguagens e tecnologias,
o que requer pesquisa, prática e muito tentativa e erro.
Os melhores candidatos para trabalhos de engenharia de software não são aqueles
que listam a maioria das linguagens ou siglas em seus currículos. Em vez disso, os
candidatos mais desejados são os autossuficientes, o que significa que sabem aprender
coisas novas e encontrar respostas para os problemas por conta própria. Isso não significa
que eles nunca peçam ajuda; pelo contrário, um bom programador sabe quando parar de
bater a cabeça contra a parede e consultar os colegas em busca de conselhos. No entanto,
a maioria dos problemas cotidianos pode ser resolvida usando a documentação de ajuda,
exemplos de códigos online, fóruns on-line, códigos existentes que funcionam, livros de
programação e ferramentas de depuração no software.
Suponha que você esteja em uma entrevista de emprego e seu possível empregador
pergunte: "O que você faz quando encontra uma 'parede de tijolos' ao programar? Para quais
fontes você primeiro procura ajuda?" Se você responder "Meu supervisor" ou "Meus colegas
de trabalho", isso é uma bandeira vermelha, significando que você pode representar um
potencial custo de tempo para a equipe de desenvolvimento. Embora os problemas mais
difíceis exijam colaboração em grupo, uma equipe de desenvolvimento de software
competitiva não pode se dar ao luxo de "segurar a mão" de um funcionário em todas as
questões que encontra. Muitos dos candidatos mais convincentes respondem a essa
pergunta: "Google". Eles sabem que a maioria dos problemas de programação, embora
irritantes, são comuns e a resposta pode estar ao alcance dos seus dedos em menos de 30
segundos por meio de uma pesquisa na Internet bem formulada.
Nesta seção, você aprenderá sobre lugares em que pode encontrar ajuda ao trabalhar
com o Python e ao programar em geral. Você terá uma experiência muito mais fácil neste
curso se lembrar desses recursos e usá-los para concluir suas tarefas.

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.

Usando o depurador (debug) do PythonWin


Às vezes, quando outras tentativas rápidas de depuração falham, você precisa dar uma
olhada mais profunda em seu script. A maioria dos ambientes de desenvolvimento
integrados (IDEs), como o PythonWin, inclui algumas ferramentas de depuração que
permitem percorrer o script linha por linha para tentar encontrar um erro. Essas ferramentas
permitem que você “fique de olho” no valor de todas as variáveis em seu script para verificar
como elas reagem a cada linha de código. A barra de ferramentas de depuração pode ser
uma boa maneira de detectar erros lógicos em que uma linha de código incorreta está
impedindo que o seu script retorne o resultado correto. A barra de ferramentas de depuração
também pode ajudá-lo a descobrir qual linha de código está causando uma falha.
A melhor maneira de explicar os aspectos da depuração é trabalhar com um exemplo.
Desta vez, vamos olhar para algum código que tenta calcular o fatorial de um inteiro (o inteiro
é codificado para 5 neste caso). Na matemática, um fatorial é o produto de um inteiro e de
todos os inteiros positivos abaixo dele. Assim, 5! (ou "5 fatorial") deve ser 5 * 4 * 3 * 2 * 1 =
120.
O código abaixo tenta calcular um fatorial através de um loop que incrementa o
multiplicador em 1 até atingir o inteiro original. Esta é uma abordagem válida, pois 1 * 2 * 3
* 4 * 5 também renderia 120.
# Este script calcula o fatorial de um número
# inteiro, que é o produto desse inteiro e de
# todos os inteiros positivos menores que ele
numero = 5
multiplicador = 1
while multiplicador < numero:
numero *= multiplicador
multiplicador += 1

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.

• Pressione o botão Go . Isso executa seu script até o ponto de interrupção.


Agora você tem uma pequena seta amarela indicando qual linha do script você está
prestes a executar.

• Clique no botão Watch . O que é comumente conhecido como janela de


observação é exibido. Isso ajudará você a acompanhar o que acontece com suas
variáveis à medida que você executa o código linha por linha. Antes de executar qualquer
outro código, no entanto, você precisa informar à janela de observação quais variáveis
rastrear.
• Na coluna Expression da janela de observação, clique duas vezes em <New
Item> e digite o nome da sua primeira variável "numero" (omita as aspas). Na coluna
Value, você verá "NameError: name 'numero' is not defined." Isso faz sentido porque
você ainda não executou a linha de código que cria essa variável.
• Semelhante à etapa anterior, clique novamente em <New Item> e configure
para a variável "multiplicador". Você deve obter o mesmo erro sobre a variável ainda não
estar definida.

• 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.

Imprimindo mensagens da estrutura de geoprocessamento


da ESRI
Quando você trabalha com ferramentas de geoprocessamento em Python, às vezes o
script poderá falhar porque algo deu errado com a ferramenta. Pode ser que você tenha
escrito uma sintaxe Python perfeita, mas seu script não funciona como esperado porque as
ferramentas de geoprocessamento da ESRI não conseguem encontrar um conjunto de
dados ou acessar um parâmetro da ferramenta. Você não será capaz de encontrar esses
erros com o depurador, mas poderá obter uma visualização deles imprimindo as mensagens
retornadas da estrutura de geoprocessamento da ESRI.
A ESRI configurou suas ferramentas de geoprocessamento para relatar com frequência
o que estão fazendo. Quando você executa uma ferramenta de geoprocessamento a partir
do ArcMap ou ArcCatalog, você vê uma caixa com essas mensagens, às vezes
acompanhada por uma barra de progresso. Você aprendeu na etapa 1 que pode usar o
arcpy.GetMessages() para acessar essas mensagens no seu script. Se você quiser apenas
ver as mensagens quando algo der errado, você pode incluí-las em um bloco de código,
como este.
try:
. . .
except:
print (arcpy.GetMessages())
Lembre-se que ao usar try / except, no caso normal, o Python executará tudo no try-
block (= tudo seguindo o "try:" que está recuado em relação a ele) e então continuará após
o except-block (= tudo seguindo o "except:" que está recuado em relação a ele). No entanto,
se algum comando no bloco try falhar, a execução do programa salta diretamente para o
início do bloco except e, nesse caso, imprime as mensagens que recebemos de
arcpy.GetMessages(). Depois que o bloco de exceções for executado, o Python continuará
com a próxima instrução após o bloco de exceções.
As mensagens de geoprocessamento têm três níveis de gravidade: Mensagem, Aviso
e Erro. Você pode passar um índice para o método arcpy.GetMessages() para filtrar apenas
as mensagens que atingem um determinado nível de gravidade. Por exemplo,

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.

Outras fontes de ajuda


Além das abordagens acima, existem muitos outros lugares onde você pode obter
ajuda. Alguns deles são descritos abaixo. Se você é iniciante em programação, saber que
esses recursos existem e como usá-los pode ajudá-lo a se sentir mais confiante. Encontre
os que você prefira e retorne a eles com frequência. Esse hábito ajudará você a se tornar
um programador autossuficiente e aprimorará seu potencial para aprender qualquer nova
linguagem de programação ou tecnologia.
Aproveitar os recursos abaixo requer tempo e esforço. Muitas pessoas não gostam de
vasculhar a documentação do computador, e isso é compreensível. No entanto, você pode
economizar tempo se procurar a resposta em vez de esperar que alguém o ajude. Melhor
ainda, você terá aprendido algo novo a partir de sua própria experiência, e as coisas que
aprender dessa maneira serão muito mais fáceis de lembrar no futuro.
Fontes de ajuda
Motores de busca (search engines)
Os mecanismos de pesquisa são úteis para respostas rápidas e problemas obscuros.
Você esqueceu a sintaxe de um loop? A solução mais rápida pode ser o Google, pesquise
"for loop python" ou "while loop python" e examine um dos muitos exemplos de código
retornados. Os mecanismos de pesquisa são extremamente úteis para diagnosticar
mensagens de erro. Pesquise a mensagem de erro entre aspas e você pode ler as
experiências de outras pessoas que tiveram o mesmo problema. Se você não conseguir
respostas suficientes, remova as aspas para ampliar a pesquisa.
Um risco que você corre de pesquisas on-line é encontrar informações irrelevantes.
Ainda mais perigoso é usar estas informações irrelevantes. Pesquise qualquer amostra de
código para se certificar de que é aplicável à versão do Python que você está usando.
Algumas sintaxes no Python 3.x são diferentes do Python 2.x que você está usando neste
curso.
Ajuda on-line da ESRI
A Esri mantém todo o sistema de ajuda on-line e você encontrará a maioria dos tópicos
de script na seção arcpy .
Outra seção, que você deve visitar repetidamente, é a Referência de Ferramentas (tool
Reference), que descreve todas as ferramentas da caixa de ferramentas e contém exemplos
de script Python para cada uma. Se você está tendo problemas para entender quais
parâmetros entram ou saem de uma ferramenta, ou se você está recebendo um erro de volta
da própria estrutura de geoprocessamento, tente a Referência de Ferramenta antes de fazer
uma busca aleatória na Internet.
Ajuda on-line do Python
A documentação oficial do Python está disponível online. Algumas delas são muito
detalhadas e têm o tom de serem escritas por programadores para programadores. A parte
que você provavelmente achará mais útil é a referência da Python Standard Library , que é

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.

Exercícios Práticos – etapa 2


Antes de tentar começar o Projeto 2, você pode tentar alguns exercícios práticos
simples, especialmente se os conceitos desta lição forem novos para você. Lembre-se de
escolher File> New no PythonWin para criar um novo script. Você pode nomear os scripts
como preferir. Para executar um script no PythonWin, clique no ícone "running man".

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.

Exercício 2: Converter os nomes para um formato "Sobrenome, Nome"


Construa um script a partir da lista do exercício anterior que imprima cada nome na
lista no seguinte formato:
Sobrenome, Nome
Para fazer isso, você precisará encontrar a posição do espaço como antes. Para extrair
parte de uma string, você pode especificar o caractere inicial e o caractere final entre
colchetes após o nome da string, como mostrado a seguir:
nome = "Joe Paterno"
print (nome[4:11]) # imprime Paterno
Uma coisa peculiar sobre essa sintaxe é que você precisa especificar o caractere final
como 1 além do que você realmente deseja. O "o" em "Paterno" está realmente na posição
10, mas é necessário especificar um valor de 11.
Um recurso útil da sintaxe é que você pode omitir o índice do caractere final se quiser
tudo após o caractere inicial. Assim, nome[4:] retornará a mesma string como nome[4:11]
neste exemplo. Da mesma forma, o caractere inicial pode ser omitido para obter tudo, desde
o início da string até o caractere final especificado.

Exercício 3: Converter pontuações em notas de letra


Escreva um script que aceite uma pontuação de 1-100 como um parâmetro de entrada
e, em seguida, relate o grau da letra correspondente a essa pontuação. Atribuir notas de
letra da seguinte forma:

79
A:90-100
B:80-89
C:70-79
D:60-69
F:<60

Exercício 4: Criar cópias de um shapefile com base em um modelo


Imagine que você esteja novamente trabalhando com os dados de precipitação da
etapa 1 e que você queira criar cópias do arquivo shape PluTotalAnual pelos próximos 4
anos após 2018 (por exemplo, PluTotalAnual_2019, PluTotalAnual_2020, etc.).
Essencialmente, você deseja copiar o esquema de atributos do shapefile inicial, mas não os
próprios dados. Aqueles serão adicionados mais tarde. A ferramenta para automatizar esse
tipo de operação é a ferramenta para criar classe de feições na caixa de ferramentas
Gerenciamento de Dados (Create Feature Class - Data Management toolbox). Procure esta
ferramenta no sistema de Ajuda e examine sua sintaxe e o script de exemplo. Observe o
parâmetro opcional, que permite especificar uma classe de feições cujo esquema de atributo
você deseja copiar.
Para concluir este exercício, você deve invocar a ferramenta
arcpy.CreateFeatureclass_management() dentro de um loop que fará com que a ferramenta
seja executada uma vez para cada ano desejado. A função range(..) pode ser usada para
produzir a lista de anos para o seu loop.

Exercício 5: Recorte todas as classes de feições em um geodatabase


Os dados para este exercício prático consistem em dois arquivos de geodatabases: O
geodatabase FC.gdb contém diversas classes de feições. O geodatabase FC_Clip.gdb está
vazio, exceto por uma classe de feições de limite de uma região para o recorte.
Sua tarefa é escrever um script que recorte todas as classes de feições do geodatabase
FC.gdb ao limite da região contida no geodatabese FC_Clip.gdb. As classes de feições
recortadas devem ser gravadas no geodatabase FC_Clip.gdb. Anexe "Clip" ao final de todos
os nomes de classes de feições cortados.
Seu script deve ser flexível o suficiente para lidar com qualquer número de classes de
feições no geodatabase de entrada. Por exemplo, se houver 15 classes de feições no
geodatabase em vez de 3, seu código final não precisará ser alterado de nenhuma maneira.
C:\SEA5923\Dados\FC\FC.gdb
C:\SEA5923\Dados\FC\Resultados\FC_Clip.gdb.gdb

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.

A ferramenta do Projeto 2 com dois parâmetros de entrada e nenhum parâmetro de saída


A execução da ferramenta faz com que os conjuntos de dados reprojetados sejam
colocados no disco na pasta de destino.
Requisitos
• É necessário reprojetar os conjuntos de dados vetoriais shapefile na pasta para
corresponder à projeção do conjunto de dados escolhido como padrão.
• Deve-se acrescentar "_projetado" ao final de cada nome de conjunto de dados
reprojetado. Por exemplo: Rodovias_projetado.shp.
• Deve-se pular quaisquer conjuntos de dados que já estejam na projeção
padrão.
• Deve relatar uma mensagem de geoprocessamento informando quais
conjuntos de dados foram reprojetados. Nesta mensagem, os nomes dos conjuntos de
dados podem ser separados por espaços. Na mensagem, não inclua conjuntos de dados
que foram ignorados porque já estavam na projeção padrão. Esta deve ser uma única

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

No final desta etapa, você deve:


• Entender o uso de diferentes tipos de workspaces (por exemplo, geodatabases) em
Python
• Ser capaz de usar cursores arcpy para ler e manipular dados de atributos de vetores
(pesquisa de registros, atualização e exclusão)
• Saber como construir strings de consulta SQL para realizar seleção por atributo com
cursores ou MakeFeatureLayer

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

Armazenamento e recuperação de dados no ArcGIS


Antes de entrar nos detalhes de como ler e modificar esses atributos, é útil revisar como
os conjuntos de dados geográficos são armazenados no ArcGIS. Você precisa saber isso
para poder abrir conjuntos de dados em seus scripts e, ocasionalmente, criar novos
conjuntos de dados.
Geodatabases
Ao longo dos anos, a ESRI desenvolveu várias maneiras de armazenar dados
espaciais. Eles incentivam você a colocar seus dados em bancos de dados geográficos, que
são estruturas organizacionais para armazenar conjuntos de dados e definir relacionamentos
entre esses conjuntos de dados. Diferentes tipos de geodatabase são oferecidos para
armazenar diferentes magnitudes de dados.
• Os geodatabases pessoais são uma forma pequena e quase obsoleta de geodatabase
que armazena dados no sistema de arquivos local. Os dados são mantidos em um banco
de dados do Microsoft Access, que limita a quantidade de dados que podem ser
armazenados no geodatabase.
• Os geodatabases de arquivo são uma maneira mais recente de armazenar dados no
sistema de arquivos local. Os dados são armazenados em um formato proprietário
desenvolvido pela ESRI. Um file geodatabase pode conter mais dados do que um
personal geodatabase: até terabytes.
• Os geodatabases ArcSDE ou "enterprise geodatabases" armazenam dados em um
servidor central em um sistema de gerenciamento de banco de dados relacional
(RDBMS), como SQL Server, Oracle ou PostgreSQL. Estes são grandes bancos de
dados projetados para servir dados não apenas para um computador, mas para toda
uma empresa. Como trabalhar com um RDBMS pode ser um trabalho em si, a ESRI
desenvolveu o ArcSDE como um "middleware" que permite configurar e ler seus
conjuntos de dados no ArcCatalog ou no ArcMap sem fazer uso software RDBMS.
Para ações onde o ArcSDE é necessário, mas onde seria muito oneroso comprar e
configurar um RDBMS corporativo, a ESRI desenvolveu uma versão menor de
"workgroup" do ArcSDE que funciona com o banco de dados livre SQL Server Express.
E que pode ser diretamente configurado no Arc Caalog ou na janela no ArcMap.
Nos últimos anos, a ESRI também desenvolveu um novo recurso chamado “camadas de
consulta” (query layers) , que permite extrair dados diretamente de um RDBMS usando
consultas SQL, sem envolver o ArcSDE.

Um único conjunto de dados vetoriais dentro de um geodatabase é chamado de classe


de feições (Feature classes). As classes de feições podem ser organizadas opcionalmente

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.

Um file geodatabese conforme visualizado pelo sistema de arquivos do Windows Explorer


A maneira mais segura de obter os caminhos que você precisa é navegar até o conjunto
de dados no ArcCatalog e pegar o caminho que aparece na barra de ferramentas
Localização. Aqui está o mesmo arquivo geodatabase seria semelhante no ArcCatalog. O

87
caminho destacado mostra como você se referiria a uma classe de feições dentro do
geodatabase.

O mesmo arquivo geodatabase, mostrado no ArcCatalog


Abaixo está um exemplo de como você pode acessar a classe de feições em um script
Python usando esse caminho. Isso é semelhante a um dos exemplos da etapa.
import arcpy
featureClass = "C:\\SEA5923\\Dados\\BaseDados.gdb\\Limite"
desc = arcpy.Describe(featureClass)
spatialRef = desc.SpatialReference
print (spatialRef.Name)
Lembre-se de que a barra invertida (\) é um caractere reservado em Python, portanto,
será necessário usar a barra invertida dupla (\\) ou barra (/) no caminho. Outra técnica que
você pode usar para caminhos é a string raw, que permite colocar barras invertidas e outros
caracteres reservados em sua string, desde que você coloque "r" antes de suas aspas.
featureClass = r "C:\SEA5923\Dados\BaseDados.gdb\Limite"
Workspaces (local de trabalho)
A estrutura de geoprocessamento da ESRI geralmente usa a noção de um local de
trabalho para indicar a pasta ou o geodatabase onde você está trabalhando atualmente.
Quando você especifica um local de trabalho em seu script, não é necessário listar o caminho
completo para cada conjunto de dados. Quando você executa uma ferramenta, o
geoprocessador vê o nome da classe de feição e assume que ele reside no local de trabalho
que você especificou.
Os locais de trabalho são especialmente úteis para processamento em lote, quando
você executa a mesma ação em muitos conjuntos de dados no local de trabalho. Por
exemplo, você pode querer recortar todas as classes de feições em uma pasta para o limite
da região de interesse. O fluxo de trabalho para isso é:
• Definir um local de trabalho.
• Crie uma lista de classes de feições para o local de trabalho.
• Definir uma feição de recorte.
• Configurar um loop para ser executado em cada classe de feições na lista.
• Dentro do loop, executar a ferramenta Clip.

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.

Lendo dados de atributos de vetores


Agora que você sabe como abrir um conjunto de dados, vamos um pouco além e
começaremos a examinar alguns registros de dados individuais. Esta seção da lição discute
como ler e pesquisar tabelas de atributos. Essas tabelas geralmente fornecem os atributos
para feições vetoriais, mas também podem ser independentes em alguns casos. A próxima
sessão abordará como gravar dados nestas tabelas. No final da lição, vamos trabalhar com
os dados rasters.
À medida que trabalhamos com os dados, será útil acompanhar, copiando e colando o
código de exemplo nos scripts de prática. Ao longo da aula, você encontrará exercícios que
você pode praticar o que acabou de aprender. Você não é obrigado a entregar esses
exercícios, mas se você os completar, você terá uma maior familiaridade com o código que
será útil quando você começar a trabalhar no projeto desta etapa. É impossível ler um livro
ou uma lição e logo depois já escrever um código perfeito. Muito do que você aprende vem
através de tentativa e erro e do aprendizado que você faz disso. Portanto, é aconselhável
escrever códigos com frequência.

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.

Leitura através dos registros


Agora que você sabe pesquisar a tabela horizontalmente, lendo os campos que estão
disponíveis, vamos examinar como ler, verticalmente, para cima e para baixo nos registros
da tabela.
O cursor de pesquisa (search cursor)
O módulo arcpy contém alguns objetos chamados cursores que permitem que você
percorra os registros em uma tabela. Cursores não são exclusivos em script para o ArcGIS;
de fato, se você trabalhou com ArcObjects antes, este conceito de cursor provavelmente é
familiar para você.
Algumas alterações foram implementadas em como os cursores podem ser usados nas
diferentes versões do ArcGIS. Como versões mais antigas ainda estão sendo amplamente
usadas, primeiro ilustramos o uso de cursores de uma maneira que funciona tanto para
versões antigas como novas do ArcGIS. Em seguida, descrevemos as alterações
introduzidas nas versões 10.0 e superiores, que tornam o uso de cursores mais fácil, mais
robusto e exigem menos código. Nos exemplos restantes do curso, sempre começaremos
com uma versão para 10. ou superior.
O primeiro código que analisaremos é com o cursor de pesquisa, já que foi projetado
para uma leitura simples de dados. Vamos começar com o uso tradicional do cursor de
pesquisa usado principalmente em versões anteriores do ArcGIS (e ainda trabalhando hoje
para pessoas que estão reutilizando código antigo). Embora você venha a aprender que
esse código é mais detalhado do que o que você usa nas versões mais recentes do ArcGIS,
ele fornece uma compreensão mais fundamental do que o cursor de pesquisa está fazendo.
O fluxo de trabalho comum é:
• Crie o cursor de pesquisa. Isso é feito através do método arcpy.SearchCursor(). Esse
método usa vários parâmetros nos quais você especifica qual conjunto de dados e, como
opção, quais linhas específicas deseja ler.

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.

# Encontra a precipitação média em um conjunto de postos pluviométricos


import arcpy
postosPlu = "C:\\SEA5923\\Dados\\Plu_Total_Anual.shp"
# Esta linha abaixo é nova
campoPrecipitacao = "Total_2018"
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:
# Esta linha abaixo é nova
precipitacaoTotal += linha.getValue(campoPrecipitacao)
contador += 1
linha = linhas.next()
media = precipitacaoTotal / contador
print ("Média da precipitação " + str(media))
Para atualizar o script acima, você teria que definir campoPrecipitacao = "Total_2019"
próximo ao topo do script. Isso é certamente mais fácil do que pesquisar no corpo do script
para linha.Total_2018 ; no entanto, você pode ir além e permitir que o usuário insira qualquer
nome de campo que ele queira como argumento ao executar o script.
Lembre-se na etapa 1 como você aprendeu que o arcpy.GetParameterAsText() permite
que o usuário do script forneça um valor para a variável. Usar essa técnica para o caminho
da classe de feição e o nome do campo de precipitação torna o script muito flexível. Observe
que o código abaixo não contém nomes de caminhos codificados, nomes de campos ou
números além de 0 e 1. Isso significa que você pode executar o script com qualquer classe
de feições contendo qualquer nome para seu campo de precipitação sem modificar o código.
Na verdade, você pode usar código semelhante a esse para encontrar a média de qualquer
campo numérico.
# Encontra a precipitação média em um conjunto de postos pluviométricos
import arcpy
postosPlu = arcpy.GetParameterAsText(0)
# Esta linha abaixo é nova
campoPrecipitacao = arcpy.GetParameterAsText(1)
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:
# Esta linha abaixo é nova
precipitacaoTotal += linha.getValue(campoPrecipitacao)
contador += 1
linha = linhas.next()

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.

Executando o script acima no PythonWin


Usando um loop for com um cursor (introduzido no ArcGIS 10.0)
Embora os exemplos acima usem um loop while em conjunto com o método next() para
avançar o cursor, geralmente é mais fácil iterar em cada registro usando um loop for. Isso
se tornou possível a partir do ArcGIS 10.0. Veja como o exemplo acima pode ser modificado
para usar um loop for.
# Encontra a precipitação média em um conjunto de postos pluviométricos
import arcpy
postosPlu = arcpy.GetParameterAsText(0)
campoPrecipitacao = arcpy.GetParameterAsText(1)
linhas = arcpy.SearchCursor(postosPlu)
media = 0
precipitacaoTotal = 0
contador = 0
# Loop pelos registros e cálculo do total precipitado e contador
for linha in linhas:
precipitacaoTotal += linha.getValue(campoPrecipitacao)
contador += 1
media = precipitacaoTotal / contador
print ("Média da precipitação " + str(media))
Neste exemplo, o método next() nem sequer é necessário porque está implícito no loop
for que o script irá iterar em cada registro. O objeto chamado linha é declarado quando o
loop for é declarado.
Embora essa sintaxe seja mais compacta do que usar um loop while, há algum
benefício em ver como o método next() funciona, especialmente se você já trabalhou com
scripts Python do ArcGIS 9.3.x ou se usa cursores em ArcObjects (que tem conceito
semelhante para avançar um cursor linha por linha). No entanto, quando você se acostumar
a usar um loop for para percorrer uma tabela, é improvável que você deseje voltar a usar
loops while.
O módulo de acesso de dados arcpy (introduzido no ArcGIS 10.1)

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.

Recuperando registros usando uma consulta de atributo


Os exemplos anteriores usavam o objeto SearchCursor para ler cada registro em um
conjunto de dados. Você pode ser mais específico com o cursor de pesquisa instruindo-o a
recuperar apenas um subconjunto de registros cujos atributos atendem a alguns critérios,
por exemplo, "somente registros com uma precipitação maior que 1000" ou "todos os
registros que começam com as letras P - Z "
Revisando, é assim que você constrói um cursor de pesquisa para operar em cada
registro de um conjunto de dados usando o módulo arcpy.da:
with arcpy.da.SearchCursor (fc, (campo,)) as cursor:
Se você quiser que o cursor de pesquisa recupere apenas um subconjunto dos
registros com base em alguns critérios, é possível fornecer uma expressão SQL como o
terceiro argumento no construtor (o construtor é o método que cria o SearchCursor). Por
exemplo:
with arcpy.da.SearchCursor (fc, (campo,), 'Campo1 "> 1000') as cursor:
O exemplo acima usa a expressão SQL "Campo1"> 1000 para recuperar somente os
registros cuja Campo1 é maior que 1000. SQL significa "Structured Query Language" e é
uma sintaxe especial usada para consultar conjuntos de dados. Se você já usou uma
consulta para filtrar dados no ArcMap, então você teve alguma exposição a esses tipos de
consultas SQL. Se o SQL é novo para você, por favor, dedique alguns minutos para ler
Construindo uma expressão de consulta na Ajuda do ArcGIS Desktop. Este tópico é uma
introdução simples ao SQL no contexto do ArcGIS.
http://desktop.arcgis.com/en/arcmap/latest/map/working-with-layers/building-a-query-
expression.htm
Expressões SQL podem conter uma combinação de critérios que permitem identificar
um subconjunto de registros muito específicos. A complexidade da sua consulta é limitada
apenas pelos seus dados disponíveis. Por exemplo, você poderia usar uma expressão SQL
para localizar apenas cidades com uma densidade populacional superior a 100 pessoas por
km quadrado, que começam com a letra M e foram criadas após 1950.
Observe que a expressão SQL que você fornece para um cursor de pesquisa é para
consultas de atributo, não para consultas espaciais. Você não pode usar uma expressão
SQL para selecionar registros que caiam "a oeste do rio Tietê" ou "dentro do limite do estado
de SP", a menos que você tenha adicionado e preenchido algum atributo afirmando se essa
condição era verdadeira. Mais adiante nesta lição, falaremos sobre como fazer consultas
espaciais usando a ferramenta de geoprocessamento Select By Location.

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

Recuperando registros usando uma consulta espacial


A aplicação de uma expressão SQL ao cursor de pesquisa é útil apenas para consultas
de atributos, não para consultas espaciais. Por exemplo, você pode facilmente abrir um
cursor de pesquisa para todos os setores censitários de um determinado município pelo
atributo de código do município usando uma expressão SQL, mas encontrar todos os
municípios que tocam ou incluem o rio Tietê, por exemplo, requer uma abordagem diferente.
Para obter um subconjunto de registros com base em um critério espacial, é necessário usar
uma ferramenta de geoprocessamento chamada de “Select Layer By Location”.
Nota:
Alguns bancos de dados relacionais, como o SQL Server 2008, podem incluir tipos de
dados espaciais que podem ser consultados espacialmente com o SQL. O suporte para
esses tipos espaciais no ArcGIS ainda está amadurecendo e, neste curso, vamos supor que
a maneira de fazer uma consulta espacial é através da ferramenta apresentada. Como não
estamos usando o ArcSDE, isso é realmente verdade.
Aqui você precisa entender um pouco sobre como o ArcGIS trabalha com layers e
seleções. Suponha que você queira selecionar todos os estados cujos limites tocam em São
Paulo. Na maioria dos casos, você não precisará criar uma classe de feições totalmente
nova para manter esses estados específicos; você provavelmente só precisará manter esses
registros de estado específicos na memória do computador por um curto período de tempo
enquanto atualiza algum atributo. O ArcGIS usa o conceito de camadas de feições (feature
layers) para representar conjuntos de registros em memória de uma classe de feições.
A ferramenta Make Feature Layer cria uma camada de feição a partir de alguns ou de
todos os registros em uma classe de feição. Você pode aplicar uma expressão SQL ao
executar a opção Make Feature Layer para restringir os registros incluídos na camada de
feição com base nos atributos. Posteriormente, você pode usar Select Layer By Location
para restringir os registros na camada de feição com base em alguns critérios espaciais.
Abrir um cursor de pesquisa estado de São Paulo e em todos os estados que fazem
fronteira com ele levaria quatro etapas:
• Use a ferramenta Make Feature Layer para criar uma camada de feição de todos os
estados. Vamos chamar isso de camada “todosEstados”.
• Use a opção Make Feature Layer para criar uma segunda camada de feições apenas de
São Paulo. (Para obter São Paulo sozinho, você aplicaria uma expressão SQL ao criar a
camada de feição.) Vamos chamar isso de “layerSelEstados”.
• Use a ferramenta Select Layer By Location para restringir a camada todosEstados (a
camada criada anteriormente) para apenas os estados que tocam em layerSelEstados.

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.

Abaixo está um código que aplica as etapas acima.


# Seleciona todos estados que fazem fronteira com um estado selecionado
import arcpy
# Recupera o layer de estados, e o nome do campo para o nome dos estados
estadosLayer = "C:\SEA5923\Dados\Estados\Estados.shp"
estado = "São Paulo"
nomeCampo = "Nome"
try:
# Make a feature layer com todos os estados
arcpy.MakeFeatureLayer_management(estadosLayer, "todosEstados")

# Make a feature layer contend somente São Paulo


arcpy.MakeFeatureLayer_management(estadosLayer, "layerSelEstados",
'"' + str(nomeCampo) + '" =' + "'" + str(estado) + "'")

# Aplica a seleção para o layer dos estados

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

Escrevendo atributos em dados de vetores


Da mesma forma que você usa cursores para ler dados de atributos de vetores, você
também usa cursores para gravar dados. Dois tipos de cursores são fornecidos para gravar
dados:
• Update cursor - este cursor edita valores em registros existentes ou exclui registros
• Insert cursor - este cursor insere novos registros
Nas seções a seguir, você aprenderá sobre esses dois cursores e obterá algumas dicas
para usá-los.
Leitura obrigatória
A Ajuda do ArcGIS Desktop tem alguma explicação sobre os cursores. Familiarize-se
com essa ajuda, pois ela o preparará para as próximas seções da lição. Você também achará
útil retornar aos exemplos de código enquanto trabalha no Projeto 3:
Acessando dados usando cursores
http://desktop.arcgis.com/en/arcmap/latest/analyze/python/data-access-using-
cursors.htm
Siga também os três links da tabela no início do tópico acima. Estes explicam
brevemente o InsertCursor, SearchCursor e UpdateCursor e fornecem um exemplo de
código para cada um. Você já trabalhou com o SearchCursor, mas examine atentamente os
exemplos de código para os três tipos de cursor e veja se consegue determinar o que está
acontecendo em cada um deles.
http://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy-data-access/insertcursor-
class.htm
http://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy-data-access/searchcursor-
class.htm
http://desktop.arcgis.com/en/arcmap/latest/analyze/arcpy-data-access/updatecursor-
class.htm

Atualizando registros existentes


Use o cursor de atualização para modificar os registros existentes em um conjunto de
dados. Aqui estão os passos gerais para usar o cursor de atualização:
• Crie o cursor de atualização chamando arcpy.da.UpdateCursor(). Você pode,
opcionalmente, passar uma expressão SQL como um argumento para esse método.
Essa é uma boa maneira de restringir as linhas que você deseja editar se você não estiver
interessado em modificar todas as linhas da tabela.
• Use um loop for para percorrer as linhas e para cada linha ...

102
• Modifique os valores do campo na linha que precisam de atualização (veja abaixo).
• Chame UpdateCursor.updateRow() para finalizar a edição.

Modificando valores de campo


Quando você cria um UpdateCursor e percorre as linhas usando uma variável chamada
“linha”, é possível modificar os valores do campo fazendo atribuições usando a sintaxe
linha[<index do campo que deseja alterar>] = <o novo valor> . Por exemplo:
linha[0] = "Fulano de Tal"
É importante observar que o índice que ocorre para determinar [...] qual campo será
alterado é dado com relação à tupla de campos fornecidos quando o UpdateCursor é criado.
Por exemplo, se criarmos o cursor usando o seguinte comando
with arcpy.da.UpdateCursor (fc, ("empresa", "proprietario")) as cursor:
linha [0] refere-se ao campo denominado "empresa" e a linha [1] refere-se ao campo
que possui o nome "proprietario".
Exemplo
O script abaixo executa uma operação de "pesquisa e substituição" em uma tabela de
atributos. Por exemplo, suponha que você tenha um conjunto de dados representando
postos pluviométricos. Existe um campo da tabela de atributos que indica o órgão
responsável pela manutenção do posto. Imagine que um destes órgãos foi substituido. Você
precisa encontrar todas as instâncias respectivas ao órgão substituído e alterá-las pelo novo
nome do órgão substituto. Esse script pode executar essa tarefa automaticamente.

# Exemplo de script de pesquisa e substituição


import arcpy
# Parâmetros de entrada: a classe de feição, o campo afetado
# pela pesquisa e substituição, o termo de pesquisa e o termo de
# substituição.
fc = arcpy.GetParameterAsText(0)
campoAfetado = arcpy.GetParameterAsText(1)
valorAntigo = arcpy.GetParameterAsText(2)
valorNovo = arcpy.GetParameterAsText(3)
# Criando a expressão SQL para o update cursor
expressaoSQL = '"' + campoAfetado + '" = ' + "'" + valorAntigo + "'"
# Cria update cursor e atualiza cada linha retornada pela expressão SQL
with arcpy.da.UpdateCursor(fc, (campoAfetado,), expressaoSQL) as cursor:
for linha in cursor:
linha[0] = valorNovo
cursor.updateRow(linha)
del linha, cursor
Observe que esse script é relativamente flexível porque recebe todos os parâmetros
como texto. No entanto, esse script pode ser executado apenas em variáveis de string devido
à maneira como a string de consulta é configurada. Observe que o valor antigo é colocado
entre aspas, assim: "'" + valorAntigo + "'". O manuseio de outros tipos de variáveis, como
inteiros, teria tornado o exemplo mais longo.
Novamente, é essencial entender a tupla dos campos afetados que você passa quando
cria o cursor de atualização. Neste exemplo, há apenas um campo afetado (que chamamos

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

Inserindo novos registros


Ao adicionar um novo registro a uma tabela, você deve usar o cursor de inserção. Aqui
está o fluxo de trabalho para cursores de inserção:
• Crie o cursor de inserção usando arcpy.da.InsertCursor() .
• Chame InsertCursor.insertRow() para adicionar uma nova linha ao conjunto de dados.
Como com o cursor de pesquisa e atualização, você pode usar um cursor de inserção
junto com a instrução "with" para evitar problemas de bloqueio.
Os cursores de inserção diferem dos cursores de pesquisa e atualização, pois você
não pode fornecer uma expressão SQL ao criar o cursor de inserção. Isso faz sentido porque
um cursor de inserção está preocupado apenas em adicionar registros à tabela. Não precisa
"saber" sobre os registros existentes ou qualquer subconjunto deles.
Quando você insere uma linha usando InsertCursor.insertRow (), você fornece uma
tupla de valores separados por vírgulas para os campos da nova linha. A ordem desses
valores deve corresponder à ordem de valores da tupla de campos afetados que você
forneceu quando criou o cursor. Por exemplo, se você criar o cursor usando

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.

Trabalhando com rasters


Até agora, nesta lição, seus scripts apenas leram e editaram conjuntos de dados
vetoriais. Este trabalho consiste, em grande parte, em percorrer tabelas de registros e ler e
escrever valores em determinados campos. Os dados rasterizados são muito diferentes e
consistem apenas em uma série de células, cada uma com seu próprio valor. Então, como
você acessa e manipula dados raster usando o Python?
É improvável que você precise percorrer célula por célula usando o Python, e essa
técnica está fora do escopo deste curso. Em vez disso, você geralmente usa ferramentas
predefinidas para ler e manipular rasters. Essas ferramentas foram projetadas para operar
em vários tipos de rasters e executar os cálculos célula por célula para que você não precise.
No ArcGIS, a maioria das ferramentas que você usará ao trabalhar com rasters estará
no conjunto de ferramentas Data Management> Raster ou na caixa de ferramentas do
Spatial Analyst. Essas ferramentas podem reprojetar, recortar, mosaicar e reclassificar
rasters.
A caixa de ferramentas do Spatial Analyst também contém ferramentas para executar
álgebra de mapas em rasters. Multiplicar ou adicionar muitos rasters juntos usando a álgebra
de mapas é importante para cenários de seleção de locais em SIG. Por exemplo, você pode
estar tentando encontrar a melhor localização para um novo aterro sanitário e tem sete
critérios que devem ser atendidos. Se você pode criar uma varredura booleana (contendo 1
para adequado, 0 para inadequado) para cada critério, você pode usar a álgebra de mapa
para multiplicar os rasters e determinar quais células recebem uma pontuação de 1,
atendendo a todos os critérios. (Alternativamente, você pode adicionar os rasters e
determinar quais áreas receberam um valor de 7).
A parte complicada da álgebra do mapa é a construção da expressão, que é uma string
que indica o que a operação de álgebra do mapa deve fazer. O ArcGIS Desktop contém
interfaces para construir uma expressão para execuções únicas da ferramenta. Mas e se
você quiser executar a análise várias vezes ou com diferentes conjuntos de dados? É um

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

Rasters e extensões de arquivo


O script de exemplo acima usa a extensão de arquivo para os rasters .tif. Ocorre que
os rasters que não usam extensões são atribuidos o formato ESRI GRID. Se você tiver
rasters em outro formato, como .jpg, será necessário adicionar a extensão de arquivo
correta. Se você não tiver certeza da sintaxe a ser usada ao fornecer um nome de arquivo
raster, destaque o raster no ArcCatalog e observe como o caminho aparece na barra
Location.
Se você observar rasters como o ESRI GRID no Windows Explorer, poderá ver que
eles consistem em vários arquivos de suporte com diferentes extensões, às vezes até
contidos em uma série de pastas. Não tente adivinhar um dos arquivos para referência; em
vez disso, use o ArcCatalog para obter o caminho para o raster. Quando você usa esse
caminho, os arquivos e pastas de suporte funcionarão juntos automaticamente.
Leituras
O capítulo 9 de Zandbergen cobre muitas funções adicionais que você pode executar
com rasters e tem alguns bons exemplos de código.

Exercícios Práticos – etapa 3

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