<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog Geo.NET &#187; geoprocessing</title>
	<atom:link href="http://blog.geoprocessamento.net/tag/geoprocessing/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.geoprocessamento.net</link>
	<description>Geoprocessamento, SIG e Sensoriamento Remoto</description>
	<lastBuildDate>Wed, 21 Sep 2011 12:00:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Diquinhas de ArcGIS #3</title>
		<link>http://blog.geoprocessamento.net/2011/07/diquinhas-de-arcgis-3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=diquinhas-de-arcgis-3</link>
		<comments>http://blog.geoprocessamento.net/2011/07/diquinhas-de-arcgis-3/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 13:05:27 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[ArcGIS]]></category>
		<category><![CDATA[arctoolbox]]></category>
		<category><![CDATA[Geoprocessamento]]></category>
		<category><![CDATA[geoprocessing]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=1329</guid>
		<description><![CDATA[


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/07/diquinhas-de-arcgis-1/' rel='bookmark' title='Permanent Link: Diquinhas de ArcGIS #1'>Diquinhas de ArcGIS #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/07/diquinhas-de-arcgis-2/' rel='bookmark' title='Permanent Link: Diquinhas de ArcGIS #2'>Diquinhas de ArcGIS #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/05/arcgis-com-lancado/' rel='bookmark' title='Permanent Link: ArcGIS.com lançado'>ArcGIS.com lançado</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal,</p>
<p>Continuando a série de diquinhas de ArcGIS!</p>
<p>Algumas pessoas fazem bastante uso de ferramentas de geoprocessamento, especialmente para análise espacial. Neste quesito, a ferramenta mais utilizada do ArcMap é o ArcToolbox.</p>
<p>Existem processos, que invariavelmente são: rodar ferramenta de geoprocessing, conferir resultados, refinar análise, etc. São tantos arquivos gerados que podemos ficar facilmente perdidos.</p>
<p>Uma das coisas legais que temos no ArcToolbox (acho que a partir da versão 9.3) é o histórico de ferramentas (tanto no ArcMap, quanto no ArcCatalog). Podemos precisar de um processo de foi rodado à algumas horas e onde está o tal arquivo?</p>
<p>Bem, para acabar com os problemas, o histórico vem ao resgate.</p>
<div id="attachment_1330" class="wp-caption aligncenter" style="width: 130px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2011/07/screen2.png"><img class="size-medium wp-image-1330" title="Aba Results no ArcToolbox" src="http://blog.geoprocessamento.net/wp-content/uploads/2011/07/screen2-120x300.png" alt="Aba Results no ArcToolbox" width="120" height="300" /></a><p class="wp-caption-text">Aba Results no ArcToolbox</p></div>
<p>Para cada processo que rodamos, ele guarda um registro da entrada, dos parâmetros e da saída. Através disso é possível re-rodar o processo ou então arrastar o resultado (desde que não tenha sido fisicamente deletado do PC!) par ao mapa novamente e pronto. Está lá denovo.</p>
<p>O post de hoje foi patrocionado pelo...silêncio.</p>
<p>Abraços</p>
<p>George Rodrigues da Cunha Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/07/diquinhas-de-arcgis-1/' rel='bookmark' title='Permanent Link: Diquinhas de ArcGIS #1'>Diquinhas de ArcGIS #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/07/diquinhas-de-arcgis-2/' rel='bookmark' title='Permanent Link: Diquinhas de ArcGIS #2'>Diquinhas de ArcGIS #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/05/arcgis-com-lancado/' rel='bookmark' title='Permanent Link: ArcGIS.com lançado'>ArcGIS.com lançado</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2011/07/diquinhas-de-arcgis-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Usando Python e o Geoprocessing Framework #1</title>
		<link>http://blog.geoprocessamento.net/2010/06/python-geoprocessing-framework1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=python-geoprocessing-framework1</link>
		<comments>http://blog.geoprocessamento.net/2010/06/python-geoprocessing-framework1/#comments</comments>
		<pubDate>Sun, 27 Jun 2010 15:07:34 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[ArcGIS]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[geoprocessing]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=866</guid>
		<description><![CDATA[Boa noite pessoal, Hoje quero falar um pouquinho do framework de geoprocessamento do ArcGIS, disponível em Python. Python, como sabem, é uma linguagem de alto nível, orientada à objetos e muito - mas muito fácil de se aprender. Existem tarefas extremamente repetitivas que podem ser facilmente automatizadas com um pouquinho de Python e o tal [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/07/usando-python-e-o-geoprocessing-framework-2/' rel='bookmark' title='Permanent Link: Usando Python e o geoprocessing framework #2'>Usando Python e o geoprocessing framework #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/06/configure-o-terralib-3-3-no-visual-studio-2003/' rel='bookmark' title='Permanent Link: Configure o TerraLib no Visual Studio 2003'>Configure o TerraLib no Visual Studio 2003</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/03/oopython/' rel='bookmark' title='Permanent Link: OOP com python &#8211; Uma breve introdução.'>OOP com python &#8211; Uma breve introdução.</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Boa noite pessoal,</p>
<p>Hoje quero falar um pouquinho do framework de geoprocessamento do ArcGIS, disponível em Python. Python, como sabem, é uma linguagem de alto nível, orientada à objetos e muito - mas muito fácil de se aprender.</p>
<p>Existem tarefas extremamente repetitivas que podem ser facilmente automatizadas com um pouquinho de Python e o tal Geoprocessing. O ArcGIS, basicamente faz uso do Python em toda a command-line e em algumas ferramentas da toolbox. Tudo que é feito no ModelBuilder é convertido em código Python.</p>
<p>Bem, vamos à proposta: imagine que você tenha necessidade de atualizar dados disponibilizados como shapefiles, por um órgão do governo, de forma periódica e em um banco de dados (ArcSDE, Personal GDB, File GDB, etc.). Será possível?</p>
<p>Bem, isto é possível pois o Python conta com milhares de bibliotecas para acesso à páginas da web, compressão/descompressão de arquivos .zip, entre outras. Este foi um requerimento real de um trabalho antigo.</p>
<p>Bem, imaginemos o site do DNPM, que disponibiliza shapefiles dos direitos minerários, de tempos em tempos (o DNPM também publica um serviço web, mas nem sempre é um bom caminho). No site <a rel="nofollow" target="_blank" title="SIGMINE" href="http://sigmine.dnpm.gov.br/" target="_blank">SIGMINE</a> você pode puxar separado por estados o shape atualizado e alimentar um banco. Mas é muito trampo para ser feito toda semana. Ainda mais se tua base não for centralizada. Todo mundo tem atualizar milhares de mxds, mapas, etc.</p>
<p>Quais são nossos passos?</p>
<ul>
<li>Fazer o download do shapefile em .zip</li>
<li>Descompactar nosso arquivo em disco</li>
<li>Atualizar o banco de dados</li>
</ul>
<p>Podemos realizar o passo número 3 de várias formas, deletando a Feature Class antiga ou então atualizando registro por registro. Para nosso exercício, vamos deletar todos os registros e inseri-los novamente. Em ambientes mais controlados, com outras necessidades, talvez isto não seja o ideal.</p>
<p>Para contemplar nosso objetivo, iremos criar algumas classes:</p>
<ul>
<li>leecherHandler - responsável pelo download de arquivos da web;</li>
<li>folderHandler - responsável pela criação/deleção de pastas;</li>
<li>zipHandler - responsável pela compressão/descompressão de arquivos .zip;</li>
<li>logger - responsável por guardar mensagens importantes para controle do que está acontecendo;</li>
<li>geoprocessor - responsável por realizar as operações e interfaces com o ArcGIS;</li>
</ul>
<p>Vamos começar pela classe leecherHandler, que é o coração de nosso pequeno sistema:</p>
<pre>import sys, urllib2, logHandler

class leecherHandlerClass():

    def __init__(self,webAddress,tempFolder):
        self.logs = logHandler.logHandlerClass()
        # Startup the log object.

        self.webAddress = webAddress
        self.tempFolder = tempFolder
        self.localFile = self.buildLocalFile(self.downloadWebFile())

    def buildFileName(self,webAddress):
        fileName = "\\" + webAddress.split(r"/")[-1]
        return fileName

    def downloadWebFile(self):
        try:
            self.logs.newLogMessage(self,"Starting download...","Information")
            # @eventoLogged: Start download.
            webFile = urllib2.urlopen(self.webAddress)
            # Opening the URL chosen.
            self.logs.newLogMessage(self,"Finished download.","Information")
            # @eventLogged: Download finished. Return a file object type.
            return webFile
        except:
            self.logs.newLogMessage(self,"It was not possible to download file.\n" + str( sys.exc_info()[0]),"Error")
            # @eventLogged: Error downloading file from URL

    def buildLocalFile(self,webFile):
        try:
            self.logs.newLogMessage(self,"Writing file to disk...","Information")
            # @eventLogged: Start writing to a local file.
            fileName = self.buildFileName(self.webAddress)
            localFile = open(self.tempFolder + fileName,"wb")
            # Get the filename and open a localfile.

            localFile.write(webFile.read())
            # Write to brand new file.
            # @todo: find a better way to write the file to disk

            webFile.close()
            localFile.close()
            # Close both files. Clean-up action.
</pre>
<p>Esta classe é bastante simples. Ela usa o módulo urllib2 para fazer os downloads, além de construir um novo arquivo em disco, na pasta especificada. Vejam que o código da função downloadWebFile é muito simples. Apenas precisamos apontar qual é o arquivo que queremos puxar e ela já o constrói em disco, com um nome alterado com data - para não nos perdemos.</p>
<p>Você não precisa fazer mais nada, pois no construtor da classe, ela já dispara todas as ações de download e construção de arquivo em disco. Pode levar um tempo para puxar os arquivos, mas em geral é bastante rápido. Caso seja necessário, você terá de montar e inicializar um proxy - que também será mostrado.</p>
<p>A forma de uso é bastante simples:</p>
<pre>    shapeLeecher = leecherHandler.leecherHandlerClass('endereco do arquivo web','pasta temporaria de destino')
    # para acessarmos o arquivo local em disco, utilzamos a seguinte sintaxe:
    # shapeLeecher.localFile
</pre>
<p>Teremos agora um arquivo .zip em disco. Precisamos descompactá-lo. Crie uma nova classe, com a seguinte definição:</p>
<pre>import sys, zipfile, logHandler

class zipHandlerClass():

    def __init__(self,tempFolder,zipFilePathname,watchFileFormat="shp"):
        self.logs = logHandler.logHandlerClass()
        # Startup the log object

        self.tempFolder = tempFolder
        self.zipFilePathname = zipFilePathname
        self.watchFileFormat = watchFileFormat
        # Basic properties

        self.containedFiles = []
        # Generated file list inside zip archive
        self.outputWatchFile = watchFileFormat
        # outputInformation

    def testZipFile(self):
        if self.zipFilePathname == None or zipfile.is_zipfile == False:
            self.logs.newLogMessage(self,"File pointed is not a valid zipfile" + str(sys.exc_info()[0]),"Error")
            return False
        else:
            return True

    def readContainedFiles(self,zipFile):
            return zipFile.namelist()

    def extractFiles(self):
        try:
            if self.testZipFile()== True:
                extractingFile = zipfile.ZipFile(self.zipFilePathname,"r")
                self.containedFiles = self.readContainedFiles(extractingFile)
                # Defines a zipFile object using pathname for further manipulation. Read the files inside archive.
                for zippedFile in self.containedFiles:
                    unpackedFile = open(self.tempFolder + "\\" + zippedFile, "wb")
                    unpackedFile.write(extractingFile.read(zippedFile))
                    unpackedFile.close()
                    # Unpack and write file to disk
                    self.logs.newLogMessage(self,"File " + zippedFile + " unpacked and written to disk.","Information")
                    # @eventLogged: Zip file unpacked and written in disk with success.

                    if zippedFile[-3:] == self.watchFileFormat:
                        self.outputWatchFile = zippedFile
                    else:
                        self.outputWatchFile = self.tempFolder
                    # Test to see if any of these files is of type watched.
                    # @todo: make this classe output a list of watched files.
                extractingFile.close()
                # close extracted file. CleanUp.
                return True
            else:
                return False
            # Test to see if it is a valid zipfile. If not, return false.
        except zipfile.BadZipfile:
            self.logs.newLogMessage(self,"Corrupted zipfile. Please download it again.","Error")
            return False
</pre>
<p>Esta classe é um pouco mais complicada. Temos de monitorar um arquivo mestre (em nosso caso, um shapefile) para que possamos iniciar os próximos passos. Olhem a definição da classe - ela pede uma pasta temporária (a mesma que você usou com o leecher), uma localização do arquivo .zip e um formato. Este formato, tem como default a extensão .shp, mas você pode especificar outro.</p>
<pre>    # a idéia é que se use os resultados armazenados na classe leecher para alimentar
    # o construtor da classe zipHandler, criando um processo encadeado
    zipH = zipHandler.zipHandlerClass('pasta temporaria','arquivo.zip');
    zipH.extractFiles()
</pre>
<p>No frigir dos ovos, esta classe testa o arquivo zip, confere se o mesmo é válido, extrai os arquivos para a pasta selecionada, e guarda uma referência ao arquivo com a extensão escolhida.</p>
<p>Vamos mostrar agora a clase folderHandler. Ela irá criar nossas pastas para nós:</p>
<pre>import sys, os,datetime, shutil, logHandler

class folderHandlerClass():
    def __init__(self,tempFolder):
        self.logs = logHandler.logHandlerClass()
        self.tempFolder = tempFolder

    def generateTempFolderName(self):
        dataHora = datetime.date.today()
        folderName = self.tempZipFile[:-4] + "_" + str(dataHora)
        return folderName

    def createTempFolder(self):
        try:
            if os.path.exists(self.tempFolder):
                if os.path.isdir(self.tempFolder):
                    return True
                else:
                    self.logs.newLogMessage(self,"The specified folder is not a valid folder.","Error")
                    # @eventLogged: Folder is not valid.
                    return False
            else:
                os.mkdir(self.tempFolder,222)
                self.logs.newLogMessage(self,"Folder " + self.tempFolder + " created with success.","Information")
                # @eventLogged: Folder create with success.
                return True
        except:
            self.logs.newLogMessage(self,"An unexpected error occurred while creating the specified folder.\n" + str(sys.exc_info()[0]),"Error")
            # @eventLogged: Error while creating folder. More info on sys.exc_info()

    def deleteTempFolder(self):
        try:
            shutil.rmtree(self.tempFolder)
        except:
            self.logs.newLogMessage(self,"An unexpected error occurred while deleting the specified folder.\n" + str(sys.exc_info()[0]),"Error")
            # @eventLogged: Error while deleting folder. More info on sys.exc_info()
</pre>
<p style="text-align: justify;">
<p style="text-align: justify;">Esta classe tem dois métodos principais: um para criar pastas e outro para deletá-las. A classe executa uma verificação básica para saber se a pasta existe ou é uma pasta. Em caso de positivo a pasta não é criada, apenas usada como destino dos arquivos. Caso ela não exista, a classe tenta criá-la. Isto é feito para economizarmos uma operação e evitar de criar uma pasta com um nome já existente, o que nos daria um erro.</p>
<p style="text-align: justify;">O método que deleta a pasta é radical. Ele remove tudo que existe dentro da pasta. Sub-pastas, arquivos, não importa. Ele irá deletar tudo. Cuidado ao usá-lo com outros arquivos. O ideal para se trabalhar com este script é uma pasta separada só para ele. Para usar esta classe, faça assim:</p>
<p style="text-align: justify;">
<pre>    # como usar:
    folderH = folderHandler.folderHandlerClass('pasta temporaria')
    folderH.createTempFolder()
    # ele irá tentar criar a pasta
    folderH.deleteTempFolder()
    # ele irá tentar deletar a pasta e seu conteúdo
</pre>
<p style="text-align: justify;">
<p style="text-align: justify;">Bem, com estas classes conseguimos construir um pequeno framework para atualizarmos os dados em um banco do ArcGIS. São coisas simples, mas que ajudam bastante. No próximo post, teremos a classe que cuida das operações de geoprocessamento, interfaceando com o ArcGIS - e uma classe "mestra" que faz todas estas classes conversarem.</p>
<p>Como utilizar as três classes juntas?</p>
<pre>import sys,folderHandler,zipHandler,leecherHandler

    # primeiro tentamos acessar/criar a pasta que queremos
    # lembrem-se que um r antes de uma string, significa raw
    # não sendo necessário escapar os caracteres \
    folderH = folderHandler.folderHandlerClass(r"C:\temporario")
    folderH.createTempFolder()

    # é só inicializar o leecher Handler. seu construtor cuida do restante para nós
    shpLeecher = leecherHandler.leecherHandlerClass("ftp://sigmine.dnpm.gov.br/Brasil.zip",folderH.tempFolder)

    # podemos inicializar o zipHandler de duas maneiras
    # com uma chamada explícita
    zipH = zipHandler.zipHandlerClass(folderH.tempFolder,shpLeecher.localFile,"shp")

    # ou implicita, caso a extensao seja shapefile - pois é um parametro com uma entrada
    # default. se nada for especificado, .shp irá cair em seu lugar
    # zipH = zipHandler.zipHandlerClass(folderH.tempFolder,shpLeecher.localFile)
    zipH.extractFiles()
</pre>
<p style="text-align: justify;">
<p style="text-align: justify;">Com o código acima e as três classes descritas,  já conseguimos puxar um arquivo da web e descompactá-lo para uma pasta qualquer.</p>
<p style="text-align: justify;">Vocês podem notar que existem outras classes envolvidas aqui, especialmente o tal de LogHandler. Irei disponibilizar todo o projeto no próximo post <img src='http://blog.geoprocessamento.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align: justify;">Quaisquer dúvidas, estou à disposição!</p>
<p style="text-align: justify;">Abraços</p>
<p style="text-align: justify;">George</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/07/usando-python-e-o-geoprocessing-framework-2/' rel='bookmark' title='Permanent Link: Usando Python e o geoprocessing framework #2'>Usando Python e o geoprocessing framework #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/06/configure-o-terralib-3-3-no-visual-studio-2003/' rel='bookmark' title='Permanent Link: Configure o TerraLib no Visual Studio 2003'>Configure o TerraLib no Visual Studio 2003</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/03/oopython/' rel='bookmark' title='Permanent Link: OOP com python &#8211; Uma breve introdução.'>OOP com python &#8211; Uma breve introdução.</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2010/06/python-geoprocessing-framework1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

