<?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; dev</title>
	<atom:link href="http://blog.geoprocessamento.net/tag/dev/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>Jaspa 2.0 disponibilizado</title>
		<link>http://blog.geoprocessamento.net/2011/07/jaspa-2-0-disponibilizado/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=jaspa-2-0-disponibilizado</link>
		<comments>http://blog.geoprocessamento.net/2011/07/jaspa-2-0-disponibilizado/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 13:01:45 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[Jaspa]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[lançamento]]></category>
		<category><![CDATA[OpenSource]]></category>

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


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/' rel='bookmark' title='Permanent Link: Cascading Class Extensions'>Cascading Class Extensions</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>O nosso ecossitemas open-source tem crescido consideravelmente à cada dia. Novos projetos (que até nunca ouvi falar!) estão surgindo e surpreendendo em termos de funcionalidade e implementação.</p>
<div class="wp-caption aligncenter" style="width: 244px"><img title="Jaspa 2.0" src="http://jaspa.upv.es/blog/wp-content/uploads/banner3.png" alt="Java Spatial for PostgreSQL and H2" width="234" height="105" /><p class="wp-caption-text">Java Spatial for PostgreSQL and H2</p></div>
<p>Hoje quero comentar o lançamento do <a rel="nofollow" target="_blank" title="jaspa" href="http://jaspa.upv.es/blog/" target="_blank">Jaspa 2.0</a> (JAva SPAtial for PostgreSQL and H2). O Jaspa é uma extensão espacial para bancos de dados relacionais que introduz diversas funcionalidades que podem existir (ou não nativamente) nestes RDBMS.</p>
<p>O projeto é mantido pelo <a rel="nofollow" target="_blank" title="depengcart" href="http://www.upv.es/entidades/DICGF/index-en.html" target="_blank">Dep. de Engenharia Cartográfica</a> da <a rel="nofollow" target="_blank" title="poli" href="http://www.upv.es/index-en.html" target="_blank">Universidade Politécnica de Valência</a>. Ponto pros caras!</p>
<p>Como diz o nome, é escrito em Java e está disponível para estes RDBMSs que suportam a linguagem. O projeto é bem interessante, especialmente para desenvolvedores. Não <strong>reinvente a roda</strong>. Use uma pronta e mais redonda!</p>
<p>O post de hoje foi patrocionado por Led Zeppelin e Johnny Cash.</p>
<p>Um abraço,</p>
<p>George R. C. Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/' rel='bookmark' title='Permanent Link: Cascading Class Extensions'>Cascading Class Extensions</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2011/07/jaspa-2-0-disponibilizado/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Novas versões disponibilizadas</title>
		<link>http://blog.geoprocessamento.net/2011/07/novas-versoes-disponibilizadas/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=novas-versoes-disponibilizadas</link>
		<comments>http://blog.geoprocessamento.net/2011/07/novas-versoes-disponibilizadas/#comments</comments>
		<pubDate>Wed, 13 Jul 2011 18:16:03 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[GIS]]></category>
		<category><![CDATA[OpenSource]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=1294</guid>
		<description><![CDATA[Bem, esta semana e semana passada foram marcadas pelo lançamento de três novas versões de bibliotecas open-source na web. Estas versões conseguiram ver a luz do dia, após um processo, sempre complicado de bug-tracking, correções, mais bug-tracking e correções até o lançamento. Confira: MapFish 2.2 JTS GeoTools Se você é um geonerd, confira. Todas tem [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/08/udig-1-2-lancado/' rel='bookmark' title='Permanent Link: Udig 1.2 lançado'>Udig 1.2 lançado</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/07/gis-stackexchange-beta-publico/' rel='bookmark' title='Permanent Link: GIS StackExchange Beta público'>GIS StackExchange Beta público</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/10/integracao-cadgis/' rel='bookmark' title='Permanent Link: Integração CAD/GIS'>Integração CAD/GIS</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Bem, esta semana e semana passada foram marcadas pelo lançamento de três novas versões de bibliotecas open-source na web. Estas versões conseguiram ver a luz do dia, após um processo, sempre complicado de <em>bug-tracking, </em>correções, mais <em>bug-tracking </em>e correções até o lançamento.</p>
<p>Confira:</p>
<ul>
<li><a rel="nofollow" target="_blank" title="mapfish" href="http://lists.mapfish.org/pipermail/users/2011-June/003331.html" target="_blank">MapFish 2.2</a></li>
<li><a rel="nofollow" target="_blank" title="jts" href="http://www.vividsolutions.com/jts/" target="_blank">JTS</a></li>
<li><a rel="nofollow" target="_blank" title="geotools" href="http://geotoolsnews.blogspot.com/2011/06/geotools-272-released.html" target="_blank">GeoTools</a></li>
</ul>
<p>Se você é um <em>geonerd</em>, confira. Todas tem código fonte disponível e são extremamente robustas.</p>
<p>Abraços</p>
<p>George R. C. Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/08/udig-1-2-lancado/' rel='bookmark' title='Permanent Link: Udig 1.2 lançado'>Udig 1.2 lançado</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/07/gis-stackexchange-beta-publico/' rel='bookmark' title='Permanent Link: GIS StackExchange Beta público'>GIS StackExchange Beta público</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/10/integracao-cadgis/' rel='bookmark' title='Permanent Link: Integração CAD/GIS'>Integração CAD/GIS</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2011/07/novas-versoes-disponibilizadas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cascading Class Extensions</title>
		<link>http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cascading-class-extensions</link>
		<comments>http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 12:35:31 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[ArcObjects]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[ESRI]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=1299</guid>
		<description><![CDATA[Olá pessoal, este aqui é um post com mais substância que os outros. Hoje estou trabalhando em um projeto comp lexo com requisitos, bem, acima da média. Nosso usuário é bastante exigente e com razão. Há uns milhares de posts atrás, falei sobre class extensions aqui e aqui. Class extensions são uma forma muito poderosa [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #2'>ArcObjects e Class Extensions #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #1'>ArcObjects e Class Extensions #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/02/hello-world-arcgis-style/' rel='bookmark' title='Permanent Link: Hello World, ArcGIS style!'>Hello World, ArcGIS style!</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Olá pessoal, este aqui é um post com mais substância que os outros.</p>
<p style="text-align: justify;">Hoje estou trabalhando em um projeto comp</p>
<p style="text-align: justify;">lexo com requisitos, bem, acima da média. Nosso usuário é bastante exigente e com razão. Há uns milhares de posts atrás, falei sobre class extensions <a title="ce1" href="http://blog.geoprocessamento.net/?p=1029" target="_blank">aqui </a>e <a title="ce2" href="http://blog.geoprocessamento.net/?p=1059" target="_blank">aqui</a>.</p>
<p style="text-align: justify;">Class extensions são uma forma muito poderosa se customizar o comportamente básico do ArcGIS, em qualquer versão ou em qualquer ambiente. Elas funcionam em Java, C#, com server, em desktop e com ArcEngine. São praticamente universais para os produtos ESRI. Além disso, são relativamente fáceis de implementar e não possuem muitos requisitos.</p>
<p style="text-align: justify;">Só possui um único requisito de deploy:</p>
<ul style="text-align: justify;">
<li>O código desenvolvido necessita estar na máquina (cliente, server, ou qualquer coisa que o valha - e claro, não o código, mas sim os binários que foram gerados);</li>
</ul>
<p style="text-align: justify;">E uma limitação:</p>
<ul style="text-align: justify;">
<li>Uma tabela ou feature class, só pode ter uma e somente uma, class extension.</li>
</ul>
<p style="text-align: justify;">Tudo bem até aí. Nos primeiros posts falei de class extensions que poderiam herdar funcionalidade de outras class extensions. Mas o código cresce rapidamente e se temos que cuidar de um ou mais comportamentos na mesma class extension, isso pode ficar simplesmente <strong>insuportável</strong> para o desenvolvedor.</p>
<p style="text-align: justify;">Uma outra maneira de se fazer as coisas é através de composição. Ao invés de criarmos uma hierarquia complexa de class extensions, na qual a CE mais específica deriva da CE mais geral, foi necessário construir uma class extension que fosse extensível, mas <strong>sem recompilar o código</strong> e sem afetar o funcionamento básico de outras funcionalidades.</p>
<p style="text-align: justify;">Uma das partes do problema é que elas são configuráveis através de um conjunto de dados, o objeto IPropertySet. Acessá-lo não é difícil, mas traz uma chateação à mais para o desenvoledor.</p>
<p style="text-align: justify;">Bem, o que fizemos: abstraimos toda a funcionalidade da class extension. A única class extensions verdadeira que temos contém uma referência à um grupo de classes que implementam as funcionalidades, mas <strong>não são registradas</strong> na classe. Isso nos permite adicionar e ou remover uma parte da funcionalidade sem afetar as outras.</p>
<p style="text-align: justify;">Temos basicamente três objetos principais:</p>
<ul style="text-align: justify;">
<li>Uma class extension geral (a quem chamamos de <em>polimórfica</em>);</li>
<li>Um ClassExtensionContainer (que segura referências à outras classes que fazem todo o trabalho);</li>
<li>Uma fábrica de ClassExtensionContainer. Como não queremos que a nossa class extension determine quais serão as funcionalidades que ela executará, não podemos deixar à cargo da mesma a criação do nosso container.</li>
</ul>
<p style="text-align: justify;">Agora, por que separar esses caras assim? Bem, queremos que nossa class extension (que será registrada com nossa feature class ou tabela) consiga ser executada, independente do que existe no container. E não queremos que ela crie o container, pois bem, existem várias maneiras de criá-lo, e.g. chamada direta, lendo um arquivo texto ou até mesmo acessando um banco de dados. Por isso criamos a fábrica. Se quisermos mudar a maneira de como criar o container, só mudamos a fábrica e não nosso projeto completo.</p>
<p style="text-align: justify;">Bem, o projeto é mais ou menos assim:</p>
<p style="text-align: justify;">
<pre name="code" class="c-sharp">
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Core.Model;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Editor;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using log4net;
using ILog = log4net.ILog;

namespace Core.Extension.ModelExtension
{
    [Guid("32f7294c-eaf3-4df1-90aa-03e2828f305e")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("Core.Extension.ModelExtension.PolymorphicExtension")]
    public class PolymorphicExtension :
        BaseClasse,
        IInterfaceCustomizadaQueImplementaInterfacesESRI, // IClassExtension, IObjectClass, etc.
        IObjectInspector
    {

        // código de registro com removido 

        private IClassExtensionContainer _container;

        public override void Initialize()
        {
            var dataset = (IDataset)_helper.Class;
            _elementType = DetermineElementType(dataset);
           // inicializamos o container.
            _container = ClassExtensionContainerFactory.CreateContainer(_elementType);

            // inicializamos outras class extensions, que talvez precisem de serem inicializadas!
            foreach(var ext in _container.Extensions)
            {
                ext.Init(_helper, null);
            }
        }

        public override void Shutdown()
        {

        }

        public override void OnChange(IObject obj)
        {
            foreach (var ext in _container.Extensions)
            {
                _log.InfoFormat("Disparando OnChange de {0}", ext.ExtensionName);
                ext.OnChange(obj);
            }
        }

        public override void OnCreate(IObject obj)
        {
            foreach(var ext in _container.Extensions)
            {
                _log.InfoFormat("Disparando OnCreate de {0}", ext.ExtensionName);
                ext.OnCreate(obj);
            }
        }

        public override void OnDelete(IObject obj)
        {
            foreach(var ext in _container.Extensions)
            {
                _log.InfoFormat("Disparando OnDelete de {0}", ExtensionName);
                ext.OnDelete(obj);
            }
        }

        public override string ValidateField(IRow row, string fieldName)
        {
            _log.InfoFormat("Validando campo {0}",fieldName);

            var sb = new StringBuilder();

            foreach (var ext in _container.Extensions)
            {
                try
                {
                    _log.InfoFormat("Validando extensão {0}", ExtensionName);
                    sb.AppendLine(ext.ValidateField(row, fieldName));
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("Ocorreu um erro ao tentar validar o campo {0} em {1}", fieldName, ExtensionName);
                    _log.Error(ex.Message, ex);
                    continue;
                }
            }

            return sb.ToString();
        }

        public override string ValidateRow(IRow row)
        {
            _log.Info("Validando linha");

            var sb = new StringBuilder();

            foreach (var ext in _container.Extensions)
            {
                try
                {
                    _log.InfoFormat("Validando extensão {0}", ExtensionName);
                    sb.AppendLine(ext.ValidateRow(row));
                }
                catch (Exception ex)
                {
                    _log.ErrorFormat("Ocorreu um erro ao tentar validar a linha em {0}", ExtensionName);
                    _log.Error(ex.Message, ex);
                    continue;
                }
            }

            return sb.ToString();
        }

        public void Inspect(IEnumRow objects, IEditor editor)
        {
            _container.CustomInspector.Inspect(objects, editor);
        }

        public void Clear()
        {
            _container.CustomInspector.Clear();
        }

        public void Copy(IRow srcRow)
        {
            _container.CustomInspector.Copy(srcRow);
        }

        public int HWND
        {
            get { return _container.CustomInspector.HWND; }
        }
    }
}</pre>
<p>A principal sacada neste caso, é o nosso container. Ele contém uma referência para uma interface customizada, que implementa a parte principal dos comportamentos, que são:</p>
<ul>
<li>IObjectClassExtension</li>
<li>IClassExtension</li>
<li>IFeatureExtension</li>
<li>IObjectClassEvents</li>
<li>IObjectClassValidation</li>
<li>IObjectInspector (este cara aqui é para customizarmos o painel de edição default do ArcGIS! nosso container também contém ele!)</li>
</ul>
<p>Estas interfaces da ESRI que vão segurar toda nossas funcionalidades, quaisquer que sejam. Segue nosso container:</p>
<pre name="code" class="c-sharp">
public interface IClassExtensionContainer
 {
 List&lt;ICustomClassExtension&gt; Extensions { get; }
 IObjectInspector AirspaceInspector { get; }
 }</pre>
<p>Ele é só isso. A mágica fica na fábrica, que preenche este camarada e passa ele para nossa extensão de verdade. Depois que o container foi inicializado, durante o método Init() da classe principal - a própria CE inicializa as outras;</p>
<p>Este padrão é seguido nos outros métodos. Ela delega para as classes que contém funcionalidade as ações que devem ser executadas. Desta maneira conseguimos múltiplos comportamentos customizados e uma facilidade enorme para adicionar ou removê-los.</p>
<p>Por isso o nome de Cascading Class Extension. Na realidade, temos única class extension que cuida de tudo para nós, <strong>cascateando</strong> todo o comportamento interessante para nós.</p>
<p>O que acharam? ArcObjects não é complicado, é cheio de manhas. Depois que as conhecemos, fica muito fácil!</p>
<p>Ah, em nota: tenho desenvolvido algum código baseado em ArcObjects que vou disponibilizar em breve. Assim que disponibilizar, você poderá ver esta implementação acima, completa!</p>
<p>Abraços</p>
<p>George R. C. Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #2'>ArcObjects e Class Extensions #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #1'>ArcObjects e Class Extensions #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/02/hello-world-arcgis-style/' rel='bookmark' title='Permanent Link: Hello World, ArcGIS style!'>Hello World, ArcGIS style!</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vaga trabalho Logica</title>
		<link>http://blog.geoprocessamento.net/2011/06/vaga-trabalho-logica/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=vaga-trabalho-logica</link>
		<comments>http://blog.geoprocessamento.net/2011/06/vaga-trabalho-logica/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 01:51:20 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[emprego]]></category>
		<category><![CDATA[Geoprocessamento]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=1285</guid>
		<description><![CDATA[Buenas noches pessoal, Trabalhei durante quase um ano na Logica e tive excelentes momentos. Conheci pessoas muito interessantes, fiz amigos e aprendi muita coisa durante meu período lá. Outros ventos me levaram para outra(s) empresas, mas ainda mantenho contato com o pessoal de lá e aqui vem a boa notícia: eles estão com uma vaga [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/02/mercado-de-trabalho-e-curiosidades/' rel='bookmark' title='Permanent Link: Mercado de Trabalho e curiosidades'>Mercado de Trabalho e curiosidades</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/01/contribuindo-um-pouquinho/' rel='bookmark' title='Permanent Link: Contribuindo um pouquinho&#8230;'>Contribuindo um pouquinho&#8230;</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/03/maquina-virtual-e-desenvolvimento-para-arcobjects/' rel='bookmark' title='Permanent Link: Máquina Virtual e Desenvolvimento para ArcObjects'>Máquina Virtual e Desenvolvimento para ArcObjects</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Buenas noches pessoal,</p>
<p>Trabalhei durante quase um ano na <a rel="nofollow" target="_blank" title="Logica" href="http://www.logica.com.br" target="_blank">Logica</a> e tive excelentes momentos. Conheci pessoas muito interessantes, fiz amigos e aprendi muita coisa durante meu período lá.</p>
<p>Outros ventos me levaram para outra(s) empresas, mas ainda mantenho contato com o pessoal de lá e aqui vem a boa notícia: eles estão com uma vaga aberta para um desenvolvedor ESRI. A empresa é boa, os benefícios espetaculares e os projetos desafiadores.</p>
<p>Segue a descrição da vaga!</p>
<p><strong>Analista GIS Sênior</strong></p>
<p>Þ   Assistência médica e odontológica Care Plus familiar (com apartamento), sem desconto em folha</p>
<p>Þ   Previdência Privada – Itaú Vida e Previdência S/A (com participação da empresa)</p>
<p>Þ   Ticket Refeição de 400,00 mensais (que podem ser convertidos em Ticket alimentação)</p>
<p>Þ   Seguro de Vida Sul América</p>
<p>Þ   Vale transporte na forma da lei</p>
<p>Þ   PLR (Participação nos lucros e resultados) conforme acordo coletivo da categoria</p>
<p>Þ   Auxílio creche (R$ 200 por mês para o primeiro filho e R$ 130 para os demais) até completarem 5 anos de idade</p>
<p>Þ   Celular da empresa</p>
<p>Þ   Férias</p>
<p>Þ   FGTS</p>
<p>Þ   13º</p>
<p>Þ   Dissídio anual</p>
<p>Enviem currículos para:</p>
<p><a rel="nofollow" target="_blank" href="mailto:Hugo.amadeu@logica.com">Hugo.amadeu@logica.com</a></p>
<p><a rel="nofollow" target="_blank" href="mailto:Adriana.hiromi@logica.com">Adriana.hiromi@logica.com</a></p>
<p>Abraços<br />
George</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/02/mercado-de-trabalho-e-curiosidades/' rel='bookmark' title='Permanent Link: Mercado de Trabalho e curiosidades'>Mercado de Trabalho e curiosidades</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/01/contribuindo-um-pouquinho/' rel='bookmark' title='Permanent Link: Contribuindo um pouquinho&#8230;'>Contribuindo um pouquinho&#8230;</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/03/maquina-virtual-e-desenvolvimento-para-arcobjects/' rel='bookmark' title='Permanent Link: Máquina Virtual e Desenvolvimento para ArcObjects'>Máquina Virtual e Desenvolvimento para ArcObjects</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2011/06/vaga-trabalho-logica/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Padr&#227;o de Projeto ActiveRecord e ArcObjects</title>
		<link>http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=padro-de-projeto-activerecord-e-arcobjects</link>
		<comments>http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/#comments</comments>
		<pubDate>Mon, 07 Mar 2011 04:17:57 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[ArcObjects]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[ESRI]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/</guid>
		<description><![CDATA[Boa noite pessoal! Depois de um tempinho apareço denovo! Hoje quero falar um pouco sobre padrões de projeto (Design Patterns) e a como acessar dados via ArcObjects. Como vocês sabem, os objetos da ESRI são bastante chatinhos de se trabalhar. Eles tem peculiaridades incríveis e se nos esquecermos delas vamos acabar nos dando mal! A [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #2'>ArcObjects e Class Extensions #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #1'>ArcObjects e Class Extensions #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/' rel='bookmark' title='Permanent Link: Cascading Class Extensions'>Cascading Class Extensions</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p align="justify">Boa noite pessoal!</p>
<p align="justify">Depois de um tempinho apareço denovo! Hoje quero falar um pouco sobre padrões de projeto (Design Patterns) e a como acessar dados via ArcObjects.</p>
<p align="justify">Como vocês sabem, os objetos da ESRI são bastante chatinhos de se trabalhar. Eles tem peculiaridades incríveis e se nos esquecermos delas vamos acabar nos dando mal! A grande questão estamos falando de uma biblioteca enorme e temos, com certeza, algumas interfaces centrais. Duas delas, com certeza são IObject e IObjectClass.</p>
<p align="justify">Em termos simples, IObject é uma linha de uma tabela, enquanto IObjectClass representa a tabela como um todo. Quase tudo que armazenamos dentro de um geodatabase é uma IObjectClass e seus filhotes, um IObject – até mesmo <em>rasters</em>.</p>
<p align="justify">Mas porque é tão difícil acessar e manipular as informações utilizando a API da ESRI? Bem, não é que é difícil. Para coisas pequenas é bastante tranquilo e simples, exemplo:</p>
<pre class="c#" name="code">public class LeitorValores
{
	// esta classe lê os valores de uma tabela
	// ou feature class e os escreve na console.

	private IWorkspace _Workspace;
	private ITable _Tabela;

	public LeitorValores(IWorkspace workspace,string nomeTabela)
	{
		_Workspace = workspace;
		_Tabela = ((IFeatureWorkspace)workspace).OpenTable(nomeTabela);
	}

	public LerValores()
	{
		// poderiamos ter configurado o filtro como parâmetro

		IQueryFilter filter = new QueryFilterClass();
		filter.WhereClause = &quot;&quot;;
		// a query está vazia, pois queremos ler e escrever todos os valores;

		ICursor cursor = _Tabela.Search(filter,true);

                // aqui poderíamos ter utilizado a interface mãe: IObject
                // IObject tempObject = null;		

                IRow tempRow = null;
		// tempObjectt = cursro.NextRow() as IObject
		while ((tempRow = cursor.NextRow()) != null)
		{
			for (int i = 0; i &lt;= tempRow.Fields.FieldCount -1; i++)
			{
				Console.Write(tempRow.get_Value(i).ToString());
				Console.Write(&quot;\t&quot;);
			}
			Console.WriteLine();
		}
	}
}</pre>
<p>&#160;</p>
<p align="justify">É um classe bem simples, mas repare no seguinte fluxo:</p>
<ol>
<li>
<div align="justify">Construímos uma query vazia (equivalente à “SELECT * FROM TABLE”);</div>
</li>
<li>
<div align="justify">Pedimos um ICursor (o cursor é um objeto que lhe permite navegar por linhas da tabela de forma ordenada, <em>forward only</em>, ou seja, só permite Next, e não Previous);</div>
</li>
<li>
<div align="justify">Iteramos pelo cursor, pegando cada linha da tabela e percorrendo suas colunas, uma à uma para buscar seu valor;</div>
</li>
</ol>
<p align="justify">Note que só temos uma forma de ler o valor de uma coluna: utilizando o método <em>get_Value(int i)</em>;</p>
<p align="justify">Para exemplos simples, não existem problemas, mas porém quando estamos falando de um sistema maior e que necessita de ser bem estruturado, como sabemos em nossos arquivos de código que o campo <em>n</em> é necessariamente, NomeRodovia, por exemplo? Se mudarem o modelo (por qualquer motivo) nosso código vai falhar (ou pior, vai funcionar e vai começar à nos passar valores errados – de coluna).</p>
<p align="justify">Deve existir um jeito mais fácil! Bem, existem algumas alternativas:</p>
<ul>
<li>
<div align="justify">Passar todo o acesso à dados para um <em>framework</em> <em>ORM (Object Relational Mapping)</em>, por exemplo, <a rel="nofollow" target="_blank" href="http://www.nhforge.org">NHibernate</a>, <a rel="nofollow" target="_blank" href="http://fluentnhibernate.org">Fluent NHibernate</a>, <a rel="nofollow" target="_blank" href="http://msdn.microsoft.com/en-us/.../aa697427(v=vs.80).aspx">Entity Framework</a> entre outros;</div>
</li>
<li>
<div align="justify">Utilizar ADO.NET puro;</div>
</li>
<li>
<div align="justify">Ficar maluco tentando escrever ArcObjects esperto o suficiente para dar conta de seus problemas;</div>
</li>
</ul>
<p align="justify">As alternativas, estão em ordem: da melhor para pior. O primeiro caso, de um <em>ORM</em>, teremos maior controle sobre nossas coisas, classes específicas para cada entidade ou para cada punhado de entidades (de acordo com sua necessidade) e teremos uma <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Domain-driven_design">camada de domínio forte</a>.</p>
<p align="justify">Mas <em>ORMs</em> comuns tem um problema: não utilizam as interfaces nativas do ArcObjects para acesso à dados, e nos leva, novamente as famosas gambetas. Exemplo: é ótimo acessar dados diretamente do banco de dados. É, em termos, mais rápido, mais confiável. </p>
<p align="justify">Mas inviabiliza completamente o uso de <strong>versionamento</strong> (pelo menos o nativo do ArcSDE), <strong>topologia, histórico,<em> </em></strong>entre outras coisinhas mais, as quais pagamos à ESRI. Ou seja, estamos <strong>mutilando, para nosso próprio benefício </strong>(como desenvolvedor – facilitar nosso trampo!) o software que nosso cliente comprou.</p>
<p align="justify">Nenhuma das outras alternativas é muito atraente pois incentiva os desenvolvedores à prática feia do Ctrl+C/Ctrl+V – você acaba tendo de repetir querys e regras de negócio por todo o código e você arruina qualquer chance de testabilidade (a capacidade de testar e garantir que seu código funciona!)</p>
<p align="justify">Bem, a outra alternativa, é tentar: olhe bem, eu disse tentar, utilizar um padrão de projeto para dar conta de todos esses problemas que enfrentamos. Criar uma forma de acessar os dados <strong>dentro do geodatabase utilizando as ferramentas nativas</strong>, ou seja, ArcObjects.</p>
<p align="justify">É um desafio e tanto, já que é muito difícil controlar alguns aspectos desses objetos. (maldito erro COM! quem já viu um “COM object that has been separated from it’s underlying RCW cannot be used” sabe do que eu estou falando.)</p>
<p align="justify">Após estudar e fazer diversas tentativas de escrever algo que funcionasse, fosse de certa forma perfomático (pelo menos na mesma velocidade do acesso nativa aos objetos ou até um cadinho mais lento) e trouxesse produtividade, cheguei à um padrão projeto interessante: <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Active_record_pattern">ActiveRecord</a>.</p>
<p align="justify">É um padrão que basicamente tem um objeto vindo do banco de dados e propriedades que expõem comportamentos básicos de acesso e escrita ao objeto. Outro componente essencial é um <a rel="nofollow" target="_blank" href="http://martinfowler.com/eaaCatalog/repository.html">repositório</a> (outro padrão de projeto), que vai ser o responsável por conhecer nossas regras de acesso e como chegar ao banco de dados.</p>
<p align="justify">Um exemplo simples e não completamente estruturado:</p>
<pre class="c#" name="code">public class Lote
{
	private IObject _ObjetoBanco;

	public Lote(IObject lote)
	{
		_ObjectBanco = lote;
	}

	public int IdentidadeLote
	{
		get { return Convert.ToInt32(_ObjetoBanco.get_value(1)); }
		set { _ObjetoBanco.set_Value(1); }
	}

	public string NomeProprietario
	{
		get { return _ObjetoBanco.get_Valeu(2).ToString(); }
		set { _ObjetoBanco.set_Value(2).ToString(); }
	}

	public void Salvar()
	{
		// comando ArcObjects para persistir o objeto na base
		_ObjetoBanco.Store();
	}
}</pre>
<p>&#160;</p>
<p>Veja que conseguimos mapear nossas colunas em único lugar e tratar este objeto por igual em qualquer lugar de nossa aplicação?</p>
<p align="justify">O problema de nosso primeiro exemplo, enquanto ele funciona, misturamos diversas funcionalidades e resposabilidade distintas em um único objeto. Ele sabe como ir ao banco, como mapear as colunas, e como jogá-las na tela. Caso precisássemos de ir ao banco novamente, em outra ocasião, teríamos de escrever a query novamente.</p>
<p align="justify">Existem outros padrões que podem auxiliar na mesma tarefa, mas a grande questão está na presença de código ArcObjects. Sem ele, fica difícil garantir que tudo <strong>funciona</strong>.</p>
<p align="justify">Existem duas implementações .NET para o padrão Active Record:</p>
<ul>
<li>
<div align="justify"><a rel="nofollow" target="_blank" href="http://www.castleproject.org/activerecord/">Castle Active Record</a> (que é construído em cima do NHibernate);</div>
</li>
<li>
<div align="justify"><a rel="nofollow" target="_blank" href="http://www.nhydrate.org/">nHydrate</a></div>
</li>
</ul>
<p align="justify">A grande idéia aqui, é estudar o código de ambos e trazer uma implementação utilizando código ArcObjects. Não sei se é uma grande idéia, ou se não tem absolutamente valor algum (outras alternativas já são melhores).</p>
<p align="justify">Já tenho algo em desenvolvimento e quem tiver interesse, entre em contato que disponibilizo o link para o controle de versão do código.</p>
<p align="justify">E aí pessoal, o que acharam? São tópicos razoavelmente avançados, mas nada muito difícil de compreender. Fiquem à vontade para tecer comentários.</p>
<p align="justify">Abraços</p>
<p align="justify">George R. C. Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #2'>ArcObjects e Class Extensions #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #1'>ArcObjects e Class Extensions #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/' rel='bookmark' title='Permanent Link: Cascading Class Extensions'>Cascading Class Extensions</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mercado de Trabalho e curiosidades</title>
		<link>http://blog.geoprocessamento.net/2011/02/mercado-de-trabalho-e-curiosidades/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mercado-de-trabalho-e-curiosidades</link>
		<comments>http://blog.geoprocessamento.net/2011/02/mercado-de-trabalho-e-curiosidades/#comments</comments>
		<pubDate>Fri, 18 Feb 2011 02:14:47 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[Cartografia]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[GIS]]></category>
		<category><![CDATA[Mercado de Trabalho]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/2011/02/mercado-de-trabalho-e-curiosidades/</guid>
		<description><![CDATA[Olá pessoal, Buenas noches. Estamos aí novamente! Hoje gostaria de falar um cadinho sobre o mercado de trabalho. Não estou precisando de emprego, ainda bem, mas por curiosidade fiz uma pesquisa em um grande site de currículos e encontrei algumas vagas. O termo buscado foi geoprocessamento. Dessa curiosidade, encontrei outras curiosidades! Vamos lá, primeiro a [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/06/vaga-trabalho-logica/' rel='bookmark' title='Permanent Link: Vaga trabalho Logica'>Vaga trabalho Logica</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/01/sql-server-2008-e-o-sistema-de-uma-projecao-so/' rel='bookmark' title='Permanent Link: Sql Server 2008 e o sistema de uma projeção só'>Sql Server 2008 e o sistema de uma projeção só</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/07/geoinfo-2010/' rel='bookmark' title='Permanent Link: GeoInfo 2010'>GeoInfo 2010</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Olá pessoal,</p>
<p>Buenas noches. Estamos aí novamente!</p>
<p align="justify">Hoje gostaria de falar um cadinho sobre o mercado de trabalho. Não estou precisando de emprego, ainda bem, mas por curiosidade fiz uma pesquisa em um grande site de currículos e encontrei algumas vagas. O termo buscado foi geoprocessamento. Dessa curiosidade, encontrei outras curiosidades! </p>
<p align="justify">Vamos lá, primeiro a metodologia: o único termo de busca que usei foi “geoprocessamento” na página inicial, só olhei a primeira página e não adicionei nenhum outro filtro.</p>
<p align="justify">O resultado foi de 27 vagas em 19 anúncios. Tem gente precisando de mais de uma pessoa por aí.</p>
<p align="justify">Por cidade:</p>
<ul>
<li>
<div align="justify">5 vagas para São Paulo;</div>
</li>
<li>
<div align="justify">3 vagas para BH e 3 para PoA;</div>
</li>
<li>
<div align="justify">3 para Angola;</div>
</li>
<li>
<div align="justify">1 vaga para Araraquara</div>
</li>
</ul>
<p align="justify">O mercado está então concentrado em São Paulo? Sim e não. As vagas para São Paulo, 4 são para desenvolvimento e uma para Analista de Inteligência de Mercado (seja lá o que for isto).</p>
<p align="justify">Estas quatro vagas de desenvolvimento são realmente de desenvolvimento. Uma com plataformas mais esotéricas e as outras três para:</p>
<ul>
<ul>
<li>Atuar com análise de sistemas, documentação em UML, programação Visual Basic 6 (VB6), PL/SQL, HTML, .NET, C# e banco de dados Oracle. </li>
<li>Experiência nas atividades citadas. </li>
<li>Ensino Superior em Informática, Engenharia ou Matemática. </li>
<li>Desejável conhecimentos em Map Object, ArcObjects, <b>geoprocessamento</b>, software Arc View, Arc Gis e Arc Gis Server e aplicações em ArcGIS Server utilizando Microsoft .Net. C#. </li>
</ul>
</ul>
<p>Já as vagas de BH e de PoA são para produção.</p>
<p>BH:</p>
<ul>
<ul>
<li>Atuar na conversão de dados para o ambiente geomedia, padronização e organização do banco de dados, análise espacial por agregação das ocorrências em linhas de transmissão, geração de layout e mapas temáticos. </li>
<li>Experiência com ArcGis, Microstation, Cartografia/Geodésia e GeoMedia. </li>
<li>Ensino Superior em Geografia e Pós-graduação em <b>Geoprocessamento</b>, Admistração e TI. </li>
<li>Inglês técnico.        </li>
</ul>
</ul>
<p>Porto Alegre:</p>
<ul>
<ul>
<li>Responsável pelo processamento de imagens de satélite (sensoriamento remoto), processamento de dados cartográficos, integração de dados para geração de mapas e cartas temáticas, estruturação de relatórios técnicos, análise multicriterial e banco de dados geográfico. </li>
<li>Experiência nas atividades relacionadas. </li>
<li>Ensino Superior em Geologia, Engenharia, Análise de Sistemas ou áreas afins. </li>
<li>Cursos de aplicação avançada de softwares de <b>geoprocessamento</b> e sensoriamento remoto.</li>
</ul>
</ul>
<p align="justify">Já as outras vagas sempre misturam “bons conhecimentos de geoprocessamento” com AutoCAD ou Microstation e CorelDraw. Humn, não sei se são muito para profissionais de Geoprocessamento.</p>
<p align="justify">A melhor vaga é a seguinte, para Porto Alegre. Peço de antemão desculpas pelo carnaval que se segue:</p>
<ul>
<ul>
<li><strong><font size="3">Ensino Superior <u>cursando</u></font></strong> em Engenharia Cartográfica de Agrimensura, Agronomia, Geografia ou Tecnologia da Informação. </li>
<li><font size="3"><strong>Realizar conversão de dados</strong></font>, gerados por levantamentos topográficos e GPS, <strong><font size="3">edição e geração de base de dados cartográficos</font></strong> em softwares CAD, edição e estruturação de base de dados para SIG, além de <strong><font size="3"><font color="#000000">eventuais</font> processamentos digitais de imagens</font></strong>. </li>
<li>Desejável <font size="3"><strong>experiência em sistemas de cartão de crédito</strong></font>, convênio ou gestão de frotas, frente de caixa, vivência em sistemas de meios de captura para cartão de crédito (POS, TEF, Webservice, etc), <strong><font size="3">experiência em gestão de projetos e desenvolvimento de software</font></strong> no formato FS, conhecimento nos padrões de intercâmbio de dados geográficos (KML, GML, WMS, WFS, WPS). </li>
<li>Conhecimentos em <strong><font size="3">banco de dados Sybase, Oracle ou SQL Server, banco de dados geográficos, PostgreSQL, PostGIS (Oracle Spatial e MyGIS),</font></strong> <strong><font size="3">especificação de software</font></strong> e <font size="3"><strong>elaboração de casos de teste</strong></font>, <strong><font size="3">modelagem UML, modelagem relacional, modelagem de dados geográficos, Enterprise Architect, projetos de sistemas Web</font></strong> utilizando uma das tecnologias (Java, Coldfusion, PHP ou ASP), <font size="3"><strong>especificação e desenvolvimento em WebGIS</strong></font>, preferencialmente com google Maps API e/ou Bing e OpenLayers; GeoServer, Mapserver ou similares.<font size="3"><strong>conhecimento da ferramenta RPM</strong></font> (Rational Portfólio Manager) de gestão de projetos. conhecimento de <strong><font size="3">ISO 8583</font></strong>. </li>
<li>Deve se parecer com o cara da foto abaixo. (este é por conta do blog)       </li>
</ul>
</ul>
<p align="justify"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2011/02/Superman.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="Superman" border="0" alt="Superman" src="http://blog.geoprocessamento.net/wp-content/uploads/2011/02/Superman_thumb.jpg" width="210" height="260" /></a></p>
<p align="justify">Não alterei nenhuma palavra da descrição da vaga, apenas coloquei o item “Ensino superior cursando” no topo e adicionei o último item. Salário? À combinar.</p>
<p align="justify">Gente, profissional de geoprocessamento (geoprocessadores?) não é faz tudo. É uma área especializada que vem crescendo no Brasil, mas funciona assim: </p>
<ul>
<li>
<div align="justify">Um gerencia;</div>
</li>
<li>
<div align="justify">Um específica;</div>
</li>
<li>
<div align="justify">Dois desenvolvem;</div>
</li>
<li>
<div align="justify">Dois produzem dados;</div>
</li>
</ul>
<p align="justify">Todas as vagas são coerentes, com exceção desta apresentada acima. Mas podemos tirar as seguintes conclusões:</p>
<ol>
<li>
<div align="justify">O mercado para Geoprocessamento está aquecido. Seja para produção de dados ou para desenvolvimento de software;</div>
</li>
<li>
<div align="justify">Geoprocessamento ainda é meio que um mito no meio empresarial/corporativo. Aposto que tem gente aí que nem tem idéia do que seja.</div>
</li>
<li>
<div align="justify">São Paulo e Minas estão bombando (essas são as vagas anunciadas em um único site).</div>
</li>
<li>
<div align="justify">Se você está buscando um emprego, vá em frente, mas <strong>abra o olho</strong>! <strong>Pode ser fria!</strong></div>
</li>
</ol>
<p align="justify">E aí, o que vocês tem achado do mercado de trabalho no Brasil? Pessoal da Terrinha, como andam as coisas por aí? Dê sua opinião!<strong>     <br /></strong></p>
<p>Um abraço pessoal,</p>
<p>George R. C. Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/06/vaga-trabalho-logica/' rel='bookmark' title='Permanent Link: Vaga trabalho Logica'>Vaga trabalho Logica</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/01/sql-server-2008-e-o-sistema-de-uma-projecao-so/' rel='bookmark' title='Permanent Link: Sql Server 2008 e o sistema de uma projeção só'>Sql Server 2008 e o sistema de uma projeção só</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/07/geoinfo-2010/' rel='bookmark' title='Permanent Link: GeoInfo 2010'>GeoInfo 2010</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2011/02/mercado-de-trabalho-e-curiosidades/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>ArcObjects e Class Extensions #2</title>
		<link>http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arcobjects-e-class-extensions-2</link>
		<comments>http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/#comments</comments>
		<pubDate>Sun, 06 Feb 2011 22:18:36 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[ArcObjects]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[ESRI]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/</guid>
		<description><![CDATA[Boa tarde pessoal, Lembram do artigo #1 sobre as class extensions? Falei um pouco sobre como as CEs funcionam? Dê lida aqui antes de ler este aqui. Bem, as class extensions são um pouco difíceis de se manter, pois elas geram muito código, são controladas de forma esotérica (através de IPropertySet’s) e podem controlar alguns [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/' rel='bookmark' title='Permanent Link: Cascading Class Extensions'>Cascading Class Extensions</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #1'>ArcObjects e Class Extensions #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/' rel='bookmark' title='Permanent Link: Padr&atilde;o de Projeto ActiveRecord e ArcObjects'>Padr&atilde;o de Projeto ActiveRecord e ArcObjects</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p align="justify">Boa tarde pessoal,</p>
<p align="justify">Lembram do artigo #1 sobre as class extensions? Falei um pouco sobre como as <em>CEs</em> funcionam? Dê lida <a rel="nofollow" target="_blank" href="blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/">aqui</a> antes de ler este aqui.</p>
<p align="justify">Bem, as <em>class extensions</em> são um pouco difíceis de se manter, pois elas geram muito código, são controladas de forma esotérica (através de <em>IPropertySet’s</em>) e podem controlar alguns eventos importantes, como <em>OnChange, OnCreate </em>e <em>OnDelete</em> bem como as validações de uma feição.</p>
<p align="justify">Portanto, qual é uma maneira um pouco mais sã de construí-las? Uma primeira tentativa que fiz, foi utilizar herança para construí-las. Uma classe base com algumas funcionalidades era herdada por classes mais “abaixo” na cadeia e ia herdando funcionalidade. Mas como dizem por aí, composição é melhor que herança para extensão de função.</p>
<p align="justify"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2011/02/ClassDiagram1.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Diagrama de classes (herança)" border="0" alt="Diagrama de classes (herança)" src="http://blog.geoprocessamento.net/wp-content/uploads/2011/02/ClassDiagram1_thumb.png" width="467" height="500" /></a> </p>
<p align="justify">Na figura acima, percebemos que toda a funcionalidade é herdada através de herança. Todas as operações em OldBaseClassExtension (a mãe de todas) são marcadas como <em>virtual</em>, dando a possibilidade de sobreescrevemos o método pela classe filha.</p>
<p align="justify">Em código temos algo assim:</p>
<pre class="c#" name="code">    public interface IOldClassExtension : IClassExtension, IObjectClassExtension, IObjectClassValidation, IObjectClassEvents
    {
        // aqui dizemos que todas as classes derivadas de IOldClassExtension
        // devem implementar os métodos das interfaces correspondentes.
    }

    public class OldBaseClassExtension:IOldClassExtension
    {
        public virtual void Init(IClassHelper ClassHelper, ESRI.ArcGIS.esriSystem.IPropertySet ExtensionProperties)
        {
            throw new NotImplementedException();
        }

        public virtual void Shutdown()
        {
            throw new NotImplementedException();
        }

        public virtual string ValidateField(IRow Row, string FieldName)
        {
            throw new NotImplementedException();
        }

        public virtual string ValidateRow(IRow Row)
        {
            throw new NotImplementedException();
        }

        public virtual void OnChange(IObject obj)
        {
            throw new NotImplementedException();
        }

        public virtual void OnCreate(IObject obj)
        {
            throw new NotImplementedException();
        }

        public virtual void OnDelete(IObject obj)
        {
            throw new NotImplementedException();
        }
    }

    public class OldConcreteClassExtensionA : OldBaseClassExtension
    {
        public override void Init(IClassHelper ClassHelper, ESRI.ArcGIS.esriSystem.IPropertySet ExtensionProperties)
        {
            base.Init(ClassHelper, ExtensionProperties);
            // nova funcionalidade customizada
        }

        public override void Shutdown()
        {
            base.Shutdown();
            // nova funcionalidade customizada
        }

        public override string ValidateField(IRow Row, string FieldName)
        {
            base.ValidateField(Row, FieldName);
            // nova funcionalidade customizada
            return &quot;resultado de nova validação de campo&quot;;
        }

        public override string ValidateRow(IRow Row)
        {
            base.ValidateRow(Row);
            // nova funcionalidade customizada
            return &quot;resultado de nova validação de linha&quot;;
        }

        public override void OnChange(IObject obj)
        {
            base.OnChange(obj);
            // nova funcionalidade customizada
        }

        public override void OnCreate(IObject obj)
        {
            base.OnCreate(obj);
            // nova funcionalidade customizada
        }

        public override void OnDelete(IObject obj)
        {
            base.OnDelete(obj);
            // nova funcionalidade customizada
        }
    }

    public class OldConcreteClassExtensionB : OldBaseClassExtension
    {
        public override void Init(IClassHelper ClassHelper, ESRI.ArcGIS.esriSystem.IPropertySet ExtensionProperties)
        {
            base.Init(ClassHelper, ExtensionProperties);
            // nova funcionalidade customizada
        }

        public override void Shutdown()
        {
            base.Shutdown();
            // nova funcionalidade customizada
        }

        public override string ValidateField(IRow Row, string FieldName)
        {
            base.ValidateField(Row, FieldName);
            // nova funcionalidade customizada
            return &quot;resultado de nova validação de campo&quot;;
        }

        public override string ValidateRow(IRow Row)
        {
            base.ValidateRow(Row);
            // nova funcionalidade customizada
            return &quot;resultado de nova validação de linha&quot;;
        }

        public override void OnChange(IObject obj)
        {
            base.OnChange(obj);
            // nova funcionalidade customizada
        }

        public override void OnCreate(IObject obj)
        {
            base.OnCreate(obj);
            // nova funcionalidade customizada
        }

        public override void OnDelete(IObject obj)
        {
            base.OnDelete(obj);
            // nova funcionalidade customizada
        }
    }

    public class OldConcreteClassExtensionC : OldConcreteClassExtensionA
    {
        public override void Init(IClassHelper ClassHelper, ESRI.ArcGIS.esriSystem.IPropertySet ExtensionProperties)
        {
            base.Init(ClassHelper, ExtensionProperties);
            // nova funcionalidade customizada
        }

        public override void Shutdown()
        {
            base.Shutdown();
            // nova funcionalidade customizada
        }

        public override string ValidateField(IRow Row, string FieldName)
        {
            base.ValidateField(Row, FieldName);
            // nova funcionalidade customizada
            return &quot;resultado de nova validação de campo&quot;;
        }

        public override string ValidateRow(IRow Row)
        {
            base.ValidateRow(Row);
            // nova funcionalidade customizada
            return &quot;resultado de nova validação de linha&quot;;
        }

        public override void OnChange(IObject obj)
        {
            base.OnChange(obj);
            // nova funcionalidade customizada
        }

        public override void OnCreate(IObject obj)
        {
            base.OnCreate(obj);
            // nova funcionalidade customizada
        }

        public override void OnDelete(IObject obj)
        {
            base.OnDelete(obj);
            // nova funcionalidade customizada
        }
    }</pre>
<p>&#160;</p>
<p align="justify">Perceba como determinamos a funcionalidade nas classes filhas: além de herdarmos e sobreescrevermos o método, chamamos também o método base, através de base.OnChange(obj), por exemplo.</p>
<p align="justify">Ok, funciona, mas quando temos algumas <em>Class Extensions</em> e uma hierarquia com dois ou três níveis já se torna impossível de manter e <em>debugar</em> o código. Demora-se muito para atingir um resultado razoável.</p>
<p align="justify">Como faríamos se usássemos composição? Bem, vamos imaginar o seguinte: temos algumas tabelas que descrevem as <em>class extensions </em>de <strong>acordo com sua funcionalidade básica </strong>(nem todas as <em>CEs</em> precisam implementar IObjectClassValidation, caso não às usem) e uma forma de ler e instanciar estas <em>CEs</em> de acordo com esta tabela. O diagrama de classes seria basicamente este aqui:</p>
<p><a href="http://blog.geoprocessamento.net/wp-content/uploads/2011/02/ClassDiagram2.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Diagrama de CEs utilizando composição" border="0" alt="Diagrama de CEs utilizando composição" src="http://blog.geoprocessamento.net/wp-content/uploads/2011/02/ClassDiagram2_thumb.png" width="529" height="500" /></a> </p>
<p align="justify">Desta maneira temos um código muito mais simples e nenhuma dependência entre cada <em>ClassExtension</em>. Todas as <em>CEs</em> implementariam ICustomClassExtension, pois esta dá visibilidade para todos os eventos / validações (poderíiamos até ter implementado IObjectInspector para dar formas diferentes de edição à cada <em>CE</em>) que precisamos e o sistema faria o restante, consultado o banco de dados (poderia esta dentro de um próprio FileGeodatabase/ArcSDE) e descobrindo à ordem e quais <em>CEs</em> devem ser instanciadas.</p>
<p align="justify">O esquema em SQL ficaria parecido com:</p>
<pre class="sql" name="code">CREATE TABLE ENTIDADES
(
  -- conterá uma lista de feature classes ou de tabelas do ArcGIS
  nome_entidade varchar(128) NOT NULL, -- Lote
  nome_feature_dataset varchar(128) NOT NULL DEFAULT '', -- nome do feature dataset, caso exista
  nome_feature_class varchar(128) NOT NULL, -- nome da feature class, ex: FLTE_LOTES
  CONSTRAINT entidades_pk PRIMARY KEY (nome_entidade)
)

CREATE TABLE CLASS_EXTENSIONS
(
  -- conterá uma lista das class extensions disponíveis em determinada assembly.
  nome_class_extension varchar(128) NOT NULL, -- Validar Geometria de Lote
  descricao_namespace varchar(128) NOT NULL, -- ValidateParcelGeometryExtensions
  CONSTRAINT class_extensions_pk PRIMARY KEY (nome_class_extension),
  CONSTRAINT descricao_namespace_un UNIQUE (descricao_namespace)
)

-- tabela de relacionamento entre entidades e class extensions
-- é um relacionamento M:N
CREATE TABLE ENTIDADE_POSSUI_CLASS_EXTENSION
(
  nome_entidade varchar(128) NOT NULL REFERENCES ENTIDADES on (nome_entidade),
  nome_class_extension varchar(128) NOT NULL REFERENCES CLASS_EXTENSIONS on (nome_class_extension),
  ordem_criacao integer NOT NULL DEFAULT 0,
  CONSTRAINT epc_pk PRIMARY KEY (nome_entidade,nome_class_extension,ordem_criacao)
)</pre>
<p align="justify">&#160;</p>
<p align="justify">Através de um pouco de código C#, podemos descobrir se a classe implementada está disponível, instanciá-la dinamicamente e adicioná-la à uma lista de ClassExtensions (propriedade extensions em ICustomClassExtension). Aqui segue um pouco de código para vocês verem a diferença. Dessa forma cada classe cuida só do que ela precisa e podemos compor dinamicamente <em>class extensions </em>poderosas, apenas alterando os registros presentes no banco de dados e contando que os campos manipulados por cada uma exista na <em>feature class</em>.</p>
<pre class="c#" name="code">    public interface ICustomClassExtension:IClassExtension,IObjectClassExtension,IObjectClassEvents,IObjectClassValidation
    {
        List<iclassextension> extensions { get; set; }
        void CreateExtensions();
    }

    // esta é a classe mais importante. ela provê toda a funcionalidade
    // básica de buscar o banco de dados e encontrar quem são as extensões para
    // cada feature class e como usá-las
    public class CustomClassExtension:ICustomClassExtension
    {
        public List<iclassextension> extensions
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public void CreateExtensions()
        {
            // vá ao banco de dados e descubra quem são as class extensions aplicáveis à esta classe
            /*
             * foreach (Record r in Query)
             * {
             *      Type t = Type.GetType(r.ClassExtensionAssemblyName) // ValidateParcelGeometry
             *      extensions.Add(Activator.CreateInstance(t));
             * }
            */
        }

        public void Init(IClassHelper ClassHelper, ESRI.ArcGIS.esriSystem.IPropertySet ExtensionProperties)
        {
            foreach (IClassExtension classEx in this.extensions)
            {
                // todas as classes implementam init
                classEx.Init(ClassHelper,ExtensionProperties);
            }
        }

        public void Shutdown()
        {
            foreach (IClassExtension classEx in this.extensions)
            {
                classEx.Shutdown();
            }
        }

        public void OnChange(IObject obj)
        {
            // so vou conseguir iterar sobre as classes que implementam IObjectClassEvents
            foreach (IObjectClassEvents classEvents in this.extensions)
            {
                classEvents.OnChange(obj);
            }
        }

        public void OnCreate(IObject obj)
        {
            // so vou conseguir iterar sobre as classes que implementam IObjectClassEvents
            foreach (IObjectClassEvents classEvents in this.extensions)
            {
                classEvents.OnCreate(obj);
            }
        }

        public void OnDelete(IObject obj)
        {
            // so vou conseguir iterar sobre as classes que implementam IObjectClassEvents
            foreach (IObjectClassEvents classEvents in this.extensions)
            {
                classEvents.OnDelete(obj);
            }
        }

        public string ValidateField(IRow Row, string FieldName)
        {
            string result = String.Empty;
            // so vou conseguir iterar sobre as classes que implementam IObjectClassValidation
            foreach (IObjectClassValidation validation in this.extensions)
            {
                result += validation.ValidateField(Row, FieldName);
            }

            return result;
        }

        public string ValidateRow(IRow Row)
        {
            string result = String.Empty;
            // so vou conseguir iterar sobre as classes que implementam IObjectClassValidation
            foreach (IObjectClassValidation validation in this.extensions)
            {
                result += validation.ValidateRow(Row);
            }

            return result;
        }
    }

    public class ValidateParcelGeometryExtensions : IClassExtension, IObjectClassExtension, IObjectClassValidation
    {
        public void Init(IClassHelper ClassHelper, ESRI.ArcGIS.esriSystem.IPropertySet ExtensionProperties)
        {
            throw new NotImplementedException();
        }

        public void Shutdown()
        {
            throw new NotImplementedException();
        }

        public string ValidateField(IRow Row, string FieldName)
        {
            throw new NotImplementedException();
        }

        public string ValidateRow(IRow Row)
        {
            throw new NotImplementedException();
        }
    }

    public class OnParcelEvents : IClassExtension, IObjectClassExtension, IObjectClassEvents
    {
        public void Init(IClassHelper ClassHelper, ESRI.ArcGIS.esriSystem.IPropertySet ExtensionProperties)
        {
            throw new NotImplementedException();
        }

        public void Shutdown()
        {
            throw new NotImplementedException();
        }

        public void OnChange(IObject obj)
        {
            throw new NotImplementedException();
        }

        public void OnCreate(IObject obj)
        {
            throw new NotImplementedException();
        }

        public void OnDelete(IObject obj)
        {
            throw new NotImplementedException();
        }
    }

    public class ValidateDwgFile : IClassExtension, IObjectClassExtension, IObjectClassValidation
    {
        public void Init(IClassHelper ClassHelper, ESRI.ArcGIS.esriSystem.IPropertySet ExtensionProperties)
        {
            throw new NotImplementedException();
        }

        public void Shutdown()
        {
            throw new NotImplementedException();
        }

        public string ValidateField(IRow Row, string FieldName)
        {
            throw new NotImplementedException();
        }

        public string ValidateRow(IRow Row)
        {
            throw new NotImplementedException();
        }
    }</pre>
<p align="justify">As vantagens de algo assim são enormes do ponto de vista de manutenção. São três simples tabelas e uma mudança simples de estrutura de código que vai dar muito mais liberdade para os desenvolvedores e usuários. No momento em que construirmos uma nova extensão, se todos os usuários tiverem à mesma instalada no PC, é só associarmos a mesma à uma entidade que imediatamente deveria funcionar perfeitamente. <strong>Poderíamos até deixar à cargo do usuário ligar ou desligar as <em>class extensions</em> de seu interesse.</strong></p>
<p align="justify">Entendo que este post é um <em>ArcObjects</em> um pouco mais avançado, mas é muito divertido ver como simples mudanças de arquitetura facilitam a vida dos desenvolvedores e transformar a forma como o usuário se relaciona com o software.</p>
<p align="justify">O que acharam?</p>
<p align="justify">Um abraço pessoal,</p>
<p align="justify">George R. C. Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/' rel='bookmark' title='Permanent Link: Cascading Class Extensions'>Cascading Class Extensions</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #1'>ArcObjects e Class Extensions #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/' rel='bookmark' title='Permanent Link: Padr&atilde;o de Projeto ActiveRecord e ArcObjects'>Padr&atilde;o de Projeto ActiveRecord e ArcObjects</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ArcObjects e Class Extensions #1</title>
		<link>http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arcobjects-e-class-extensions-1</link>
		<comments>http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/#comments</comments>
		<pubDate>Sat, 11 Dec 2010 20:53:10 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[ArcGIS]]></category>
		<category><![CDATA[ArcObjects]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[ESRI]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/</guid>
		<description><![CDATA[Boa noite senhores e senhoras, Class Extensions é um assunto relativamente antigo. Quem já desenvolveu para ArcObjects às conhecem razoavelmente bem e são implementadas em larga escala como forma de customização avançada dos famosos geodatabases (qualquer um deles, seja Personal, File ou ArcSDE). Bem, as class extensions são implementadas através de algumas interfaces especiais e [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #2'>ArcObjects e Class Extensions #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/' rel='bookmark' title='Permanent Link: Padr&atilde;o de Projeto ActiveRecord e ArcObjects'>Padr&atilde;o de Projeto ActiveRecord e ArcObjects</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/' rel='bookmark' title='Permanent Link: Cascading Class Extensions'>Cascading Class Extensions</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<div align="justify">
Boa noite senhores e senhoras,</p>
<p><i>Class Extensions</i> é um assunto relativamente antigo. Quem já desenvolveu para <i>ArcObjects</i> às conhecem razoavelmente bem e são implementadas em larga escala como forma de customização avançada dos famosos <i>geodatabases</i> (qualquer um deles, seja <i>Personal</i>, <i>File</i> ou <i>ArcSDE</i>).</p>
<p>Bem, as <i>class extensions</i> são implementadas através de algumas interfaces especiais e devem ser registradas em uma categoria apropriada (o assunto das categorias de objetos ESRI merece um post sozinho!), <i>GeoObjectClassExtensions</i> para funcionarem e além disso devem ser aplicadas à uma <i>Feature Class</i> ou <i>Table</i> para rodarem apropriadamente. E outra coisa: elas só funcionam com quem possui o código cliente (da <i>Class Extension</i>) instalado na máquina. Para quem não possui o cliente elas se comportam de maneira comum.</p>
<p>Com <i>Class Extensions</i> é possível customizar o inspetor de objetos (aquele carinha utilizado para editar os objetos), customizar a renderização de objetos (isso é poderoso!) e customizar a validação realizada pelo <i>ArcGIS</i> antes da <i>feature</i> receber uma chamada no método Store() (ou seja, antes de ir para o banco);</p>
<p>Existem diversas coisas legais que podemos fazer com estas <i>class extensions</i> e não existe muita dificuldade de implementação (claro, quanto mais requisitos ou quanto mais complexos, mais complicado é de implementar e manter uma CE.).</p>
<p>As <i>CEs</i> podem existes para os seguintes tipos:</p>
<ul>
<li>Features</li>
<li>Rows</li>
<li>Quaisquer tipos derivados de IRow</li>
</ul>
<p>O que isto quer dizer? Bem, tanto tabelas, quanto <i>feature classes</i> e qualquer objeto derivado disto podem ter <i>CEs</i>.</p>
<p>Os requerimentos/limitações para <i>Class Extensions</i> são:</p>
<ul>
<li>Feature classes e tabelas só podem ter uma <i>class extension;</i></li>
<li>A <i>CE</i> precisa ser registrada na categoria apropriada (<i>GeoObjectClassExtensions</i>)</li>
<li>A funcionalidade não está presente no repositório de dados e sim no cliente. Sempre será necessário realizar o <i>deploy</i> de todo o código das <i>CEs</i> em <b>todos</b> os clientes;</li>
</ul>
<p>Não são requerimentos/limitações muito pesadas, portanto é uma alternativa viável para customizações mais complexas do procedimento de edição/criação/deleção de objetos.</p>
<p>Obrigatoriamente, o desenvolvedor <b>precisa implementar as seguintes interfaces</b>: IObjectClassExtension (e IFeatureClassExtension, caso seja uma extensão para <i>feature classes</i>). Neste ponto, nossa <i>CE</i> não tem nenhuma funcionalidade. Ela apenas existe.</p>
<p>Para adicionar funcionalidade, podemos implementar outras interfaces, listadas à seguir:</p>
<ul>
<li>IObjectClassEvents</li>
<li>IObjectClassValidation</li>
<li>IObjectClassInfo</li>
<li>IRelatedObjectClassEvents</li>
<li>IConfirmSendRelatedObjectEvents</li>
<li>IFeatureClassEdit</li>
<li>IFeatureClassDraw</li>
<li>IFeatureClassCreation</li>
<li>IObjectInspector</li>
</ul>
<p>Estas interfaces são opcionais, cada uma oferencendo um pouquinho de funcionalidade customizada. Hoje falaremos sobre IObjectClassEvents, que é uma das interfaces mais comum de se implementar. Ao longo de uma pequena série tentarei demonstrar a funcionalidade de algumas destas interfaces.</p>
<h3>IObjectClassEvents</h3>
<p>Esta interface é responsável por nos fornecer métodos para lidar com os eventos de criação, atualização e deleção de um registro. Pense em uma <i>trigger</i> de um banco de dados. Sempre que o evento disparar, determinado método será disparado em sequência.</p>
<p>Os métodos que devem ser implementados para total aderência ao contrato (a interface <img src='http://blog.geoprocessamento.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> ) são:</p>
<ul>
<li>OnCreate(IObject obj);</li>
<li>OnChange(IObject obj);</li>
<li>OnDelete(IObject obj);</li>
</ul>
<p>Um exemplo de implementação de uma <i>CE</i> com a interface IObjectClassEvents. Note que esta implementação não é completa, ou seja, faltam métodos para o registro da <i>CE</i>, inicialização correta, etc;</p>
<p>Imagine que temos uma tabela log de operação. Nela salvamos os registros relativos às operações realizadas por todos operadores durante o dia. Sua estrutura é a seguinte (em SQL, mas devemos considerar que a tabela está presente em um ambiente ArcGIS - Geodatabases de qualquer tipo);</p>
<pre name="code" class="sql">
CREATE TABLE LOG_OPERACAO(
OBJECTID serial NOT NULL,
NOME_TABELA VARCHAR(100) NOT NULL,
NOME_USUARIO VARCHAR(100) NOT NULL,
TIPO_OPERACAO VARCHAR(20) NOT NULL,
OID_ORIGINAL integer NOT NULL,
DATA_HORA_OPERACAO timestamp NOT NULL default now()
CONSTRAINT LOG_OPERACAO_PK PRIMARY KEY (OBJECTID)
);
</pre>
<pre name="code" class="c#">
    public class LogUsuario:IObjectClassExtension,IObjectClassEvents
    {
        public void OnCreate(IObject obj)
        {
            // vamos adicionar um registro à uma tabela de log de operações
            // precisamos de nosso workspace para abrir a tabela
            IFeatureWorkspace workspace = ((IDataset)obj.Class).Workspace;
            ITable logTable = workspace.OpenTable("LOG_OPERACAO");

            // só vamos tentar adicionar se a tabela existir no geodatabase!
            if (logTable != null)
            {
                // ok, a tabela existe. caso não existisse, ela seria nula
                // portanto, vamos criar um novo registro
                IRow novoRegistroLog = logTable.CreateRow();

                novoRegistroLog.set_Value(1,((IDataset)obj.Class).Name); // nome da tabela que estamos modificando
                novoRegistroLog.set_Value(1,Environment.UserName); // nome do usuario
                novoRegistroLog.set_Value(2,"INSERCAO"); // tipo da operacao
                novoRegistroLog.set_Value(3,obj.OID); // id no geodatabase
                novoRegistroLog.set_Value(4,DateTime.Now); // data e hora
                novoRegistroLog.Store();
           }
     }

        public void OnChange(IObject obj)
        {
            // vamos adicionar um registro à uma tabela de log de operações
            // precisamos de nosso workspace para abrir a tabela
            IFeatureWorkspace workspace = ((IDataset)obj.Class).Workspace;
            ITable logTable = workspace.OpenTable("LOG_OPERACAO");

            // só vamos tentar adicionar se a tabela existir no geodatabase!
            if (logTable != null)
            {
                // ok, a tabela existe. caso não existisse, ela seria nula
                // portanto, vamos criar um novo registro
                IRow novoRegistroLog = logTable.CreateRow();

                novoRegistroLog.set_Value(1,((IDataset)obj.Class).Name); // nome da tabela que estamos modificando
                novoRegistroLog.set_Value(1,Environment.UserName); // nome do usuario
                novoRegistroLog.set_Value(2,"ATUALIZACAO"); // tipo da operacao
                novoRegistroLog.set_Value(3,obj.OID); // id no geodatabase
                novoRegistroLog.set_Value(4,DateTime.Now); // data e hora
                novoRegistroLog.Store();
           }
     }

        public void OnDelete(IObject obj)
        {
            // vamos adicionar um registro à uma tabela de log de operações
            // precisamos de nosso workspace para abrir a tabela
            IFeatureWorkspace workspace = ((IDataset)obj.Class).Workspace;
            ITable logTable = workspace.OpenTable("LOG_OPERACAO");

            // só vamos tentar adicionar se a tabela existir no geodatabase!
            if (logTable != null)
            {
                // ok, a tabela existe. caso não existisse, ela seria nula
                // portanto, vamos criar um novo registro
                IRow novoRegistroLog = logTable.CreateRow();

                novoRegistroLog.set_Value(1,((IDataset)obj.Class).Name); // nome da tabela que estamos modificando
                novoRegistroLog.set_Value(1,Environment.UserName); // nome do usuario
                novoRegistroLog.set_Value(2,"INSERCAO"); // tipo da operacao
                novoRegistroLog.set_Value(3,obj.OID); // id no geodatabase
                novoRegistroLog.set_Value(4,DateTime.Now); // data e hora
                novoRegistroLog.Store();
           }
     }
}
</pre>
<p>Bem, este é um exemplo de implementação da interface IObjectClassEvents. Poderiamos ter deixado o código muito mais limpo (escrevendo uma função à parte para a criação de um registro na tabela de log, por exemplo) e implementado outras funcionalidades. O que importa é que você já sabe como implementar algumas funcionalidades extras dentro do <i>ArcGIS</i>. Lembrando que para esta <i>CE</i> funcionar precisamos aplicar a mesma à uma <i>feature class</i>. Para aplicar uma <i>class extension</i> programaticamente, preciso utilizar algo similar à isto:</p>
<pre name="code" class="c#">
public void ChangeClassExtension(IObjectClass objectClass, String extensionUID,IPropertySet extensionProperties)
{
    ISchemaLock schemaLock = (ISchemaLock)objectClass;

    try
    {
        // Attempt to get an exclusive schema lock.
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);

        // Cast the object class to the IClassSchemaEdit2 interface.
        IClassSchemaEdit2 classSchemaEdit = (IClassSchemaEdit2)objectClass;

        if (!extensionUID.Equals(""))
        {
            // Create a unique identifier (UID) object and change the extension.
            UID extUID = new UIDClass();
            extUID.Value = extensionUID;
            classSchemaEdit.AlterClassExtensionCLSID(extUID, extensionProperties);
        }
        else
        {
            // Clear the class extension.
            classSchemaEdit.AlterClassExtensionCLSID(null, null);
        }
    }
    catch (COMException comExc)
    {
        throw new Exception("Could not change class extension.", comExc);
    }
    finally
    {
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
    }
}
</pre>
<p>Este <i>snippet</i> de código tirado da documentação da <i><b>EDN (ESRI Developer Network)</b></i>, instalado junto com o <i>SDK</i> faz as seguintes operações:</p>
<ol>
<li>Tenta assumir um <i>lock</i> <b>exclusivo</b> sobre a <i>ObjectClass</i> (veja a interface IObjectClass);</li>
<li>Converte a <i>object class</i> para um <i>class schema edit</i> (veja IClassSchemaEdit2), para poder acessar os membros (métodos e propriedades) de edição;</li>
<li>Acha a extensão através do código GUID (é o carinho que se vê como um atributo de classe, localizado acima da declaração comum de classe, no seu projeto do <i>Visual Studio</i>;</li>
<li>Altera a <i>class extension</i>;</li>
<li>Libera o <i>lock</i> exclusivo (feito na chamada <i>finally</i> para termos garantia que o <i>lock</i> não ficará por lá, atoa);</li>
</ol>
<p>O que acharam pessoal? Não é exatamente um bixo de sete cabeças, mas precisamos aprofundar nos <i>ArcObjects</i> para ter sucesso na implementação de <i>class extensions</i> úteis. O exemplo fornecido é bobo, pode ter utilidade, mas existem milhares de possibilidades com esses diabinhos. Vários produtos de nível corporativo (soluções de energia, da Miner&#038;Miner por exemplo), apostam pesado na customização de <i>feature classes</i> como saída  para problemas <b>complexos</b>.</p>
<p>Tentem brincar um pouquinho com as <i>class extensions</i>. É bem divertido e rende um trabalho interessante.</p>
<p>Vou ficar por aqui!</p>
<p>Um abraço,</p>
<p>George R. C. Silva
</p></div>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/02/arcobjects-e-class-extensions-2/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #2'>ArcObjects e Class Extensions #2</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/' rel='bookmark' title='Permanent Link: Padr&atilde;o de Projeto ActiveRecord e ArcObjects'>Padr&atilde;o de Projeto ActiveRecord e ArcObjects</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/07/cascading-class-extensions/' rel='bookmark' title='Permanent Link: Cascading Class Extensions'>Cascading Class Extensions</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Integração CAD/GIS</title>
		<link>http://blog.geoprocessamento.net/2010/10/integracao-cadgis/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=integracao-cadgis</link>
		<comments>http://blog.geoprocessamento.net/2010/10/integracao-cadgis/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 04:19:32 +0000</pubDate>
		<dc:creator>George Rodrigues da Cunha Silva</dc:creator>
				<category><![CDATA[George Silva]]></category>
		<category><![CDATA[ArcGIS]]></category>
		<category><![CDATA[ArcSDE]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[ESRI]]></category>
		<category><![CDATA[PLTS]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=992</guid>
		<description><![CDATA[Boa noite pessoal, Faz um tempo que não apareço, mas é por um bom motivo. Estou completamente atolado de trabalho e tenho passado a maior parte de meus dias em Manaus. É uma ótima cidade, apesar do calor que vem fazendo e das constantes quedas de energia que sofremos no escritório. Esquenta, ligam mais ar-condicionados, [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/01/arcobjects1/' rel='bookmark' title='Permanent Link: ArcObjects #1 &#8211; introdução'>ArcObjects #1 &#8211; introdução</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/' rel='bookmark' title='Permanent Link: Padr&atilde;o de Projeto ActiveRecord e ArcObjects'>Padr&atilde;o de Projeto ActiveRecord e ArcObjects</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #1'>ArcObjects e Class Extensions #1</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Boa noite pessoal,</p>
<p style="text-align: justify;">Faz um tempo que não apareço, mas é por um bom motivo. Estou completamente atolado de trabalho e tenho passado a maior parte de meus dias em Manaus. É uma ótima cidade, apesar do calor que vem fazendo e das constantes quedas de energia que sofremos no escritório. Esquenta, ligam mais ar-condicionados, a rede não aguenta e todo mundo fica sem luz e sem ar. É divertido ver como essas coisas funcionam <img src='http://blog.geoprocessamento.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> .</p>
<p style="text-align: justify;">Hoje gostaria de falar um pouquinho sobre as dificuldades da integração de produtos CAD com SIGs ou <em>GIS</em>s. É um assunto, como sempre, extenso, mas como está me tomando um bocado de tempo, achei que seria bastante apropriado comentar alguma coisa sobre isso.</p>
<p style="text-align: justify;">Gostaria de começar explicitando que o CAD é um excelente programa: <strong>para o que ele foi construído</strong>. Ele não foi desenvolvido para construção ou armazenamento de feições geográficas. O CAD é um programa de <strong>desenho e apenas isso.</strong> Ele entende o básico, pontos, linhas, polígonos e anotações. Não tem a menor idéia de <strong>semântica.</strong> Quando digo semântica, ele não compreende o que cada linha significa ou o que pode ser. O <em>GIS</em> também não é muito esperto neste ponto, mas o número de regras de negócio que podem ser representadas é maior e mais consistente.</p>
<p style="text-align: justify;">Então imaginem, um projeto enorme, que requer que se levante uma área extensa, tudo feito em CAD. O CAD dá produtividade, é mais fácil de arrumar mão de obra, por aí vai. Tudo bem, mas quando chegamos na parte de conversão de dados para o <em>ArcGIS</em> ou qualquer outro software, ficamos em uma saia justíssima. Porque?</p>
<ul>
<li style="text-align: justify;">As plantas em CAD <strong>em geral</strong> são mal construídas. Isto significa que veremos muitos polígonos não fechados, vértices duplicados em uma mesma linha, <em>self-intersections</em> (é quando dentro de um polígono ou uma linha, temos uma auto-inteseção, a geometria se cruza - gerando um erro difícil de detectar e causador de inúmeros problemas, como no cálculo de área);</li>
<li style="text-align: justify;">Plantas em CAD <strong>sempre</strong> terão <strong>inúmeras versões</strong>. Mas muitas mesmo. Não estou falando de três ou quatro. São três ou quatro - por dia. Pelo menos <strong>uma por usuário</strong> trabalhando na mesma área geográfica.</li>
<li style="text-align: justify;">Os objetos CAD (pontos, linhas e polígonos) não possuem atributos. É difícil identificá-los unicamente num mar de geometrias. Dependemos unicamente de <em>labels</em> estrategicamente posicionados e milhares de <em>joins</em> espaciais para tentar identificar um objeto corretamente.</li>
</ul>
<p>Bem, estes são alguns dos problemas que existem em ambientes mistos, mas temos de tolerá-los, correto?</p>
<p>A melhor maneira de lidar com este <em>workflow</em> é a criação de um <em>modelbuilder</em> (quando estamos falando de <em>ArcGIS</em>, claro) ou algum <em>script</em> esperto em Python para cuidar dos detalhes chatos.</p>
<p style="text-align: justify;">Foi o que fizemos, mas outros problemas de gerenciamento de dados e <em>workflow</em> nos deram bastante trabalho. Mas está tudo mudando - existe uma salvação! ArcSDE ao resgate. Apesar do que dizem, que <em>geodatabases</em> são lentos, difíceis de se trabalhar, etc. montamos um <em>mini</em> ambiente em menos de um dia e conseguimos colocar todo mundo trabalhando em cima de uma pequena máquina DELL - que já conseguiu seu próprio no-break e vou pedir mais alguns GB de RAM nesta semana.</p>
<p style="text-align: justify;">Mudou de ambiente, mudou de problema, mas pelo menos é um problema que eu consigo resolver com trabalho de máquina <img src='http://blog.geoprocessamento.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> , ao invés de trabalho "braçal".</p>
<p style="text-align: justify;">Até comecei um pequeno novo projeto para ajudar nas (infinitas) correções dos problemas CAD. Estou montando uma pequena extensão do ArcMap para gerenciar usuários e correções, com áreas assinaladas à usuários, prazos, entre outras coisinhas mais para facilitar a (nossa) vida. Por ser um projeto da empresa, não posso comentar, mas vou dando pequenos detalhes assim que possível (o ArcMap já possui uma extensão oficial da ESRI para cuidar disso, é a PLTS - <em>Production Line Tool Set</em> - mas como não preciso de todos os recursos e não tenho tempo ($) para isso, vou criar uma coisinha mais simples).</p>
<p style="text-align: justify;">Bem pessoal, vou nessa. Amanhã é preto na folhinha.</p>
<p style="text-align: justify;">Abraços,</p>
<p style="text-align: justify;">George R. C. Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/01/arcobjects1/' rel='bookmark' title='Permanent Link: ArcObjects #1 &#8211; introdução'>ArcObjects #1 &#8211; introdução</a></li>
<li><a href='http://blog.geoprocessamento.net/2011/03/padro-de-projeto-activerecord-e-arcobjects/' rel='bookmark' title='Permanent Link: Padr&atilde;o de Projeto ActiveRecord e ArcObjects'>Padr&atilde;o de Projeto ActiveRecord e ArcObjects</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/12/arcobjects-e-class-extensions-1/' rel='bookmark' title='Permanent Link: ArcObjects e Class Extensions #1'>ArcObjects e Class Extensions #1</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2010/10/integracao-cadgis/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Criar plugin para TerraView</title>
		<link>http://blog.geoprocessamento.net/2010/09/criar-plugin-para-terraview/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=criar-plugin-para-terraview</link>
		<comments>http://blog.geoprocessamento.net/2010/09/criar-plugin-para-terraview/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 03:16:58 +0000</pubDate>
		<dc:creator>João Tácio</dc:creator>
				<category><![CDATA[João Tácio Silva]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[SIG]]></category>
		<category><![CDATA[TerraView]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=964</guid>
		<description><![CDATA[Tutorial para configurar as bibliotecas TerraView e Qt 3 no Visual Studio 2003. Por: Joao Tacio 1. Introdução Este tutorial tem o objetivo de explicar como configurar o ambiente de programação para desenvolver aplicações utilizando a IDE Visual Studio 2003, e as bibliotecas TerraView e Qt 3. 2. Configurar TortoiseCVS para acessar o repositório do [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/05/terraview/' rel='bookmark' title='Permanent Link: Conheça melhor o TerraView'>Conheça melhor o TerraView</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/02/hello-world-arcgis-style/' rel='bookmark' title='Permanent Link: Hello World, ArcGIS style!'>Hello World, ArcGIS style!</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<h1><strong>Tutorial para configurar as bibliotecas</strong></h1>
<h1><strong>TerraView</strong><strong> e </strong><strong>Qt 3</strong><strong> no Visual Studio 2003.</strong></h1>
<h5><span style="font-weight: normal"><span style="color: #339966"><em><span style="color: #808080">Por: Joao Tacio</span></em></span></span></h5>
<p><strong>1. Introdução </strong></p>
<p>Este tutorial tem o objetivo de explicar como configurar o ambiente de</p>
<p>programação para desenvolver aplicações utilizando a IDE Visual Studio 2003,</p>
<p>e as bibliotecas <em>TerraView</em> e <em>Qt 3</em>.</p>
<p><strong>2. Configurar TortoiseCVS para acessar o repositório do TerraLib. </strong></p>
<p>Após instalar o  <em><a rel="nofollow" target="_blank" href="http://blog.geoprocessamento.net//www.tortoisecvs.org/">TortoiseCVS</a></em>, crie uma pasta na raiz do disco principal, por</p>
<p>exemplo <em>TerraDIR </em>e siga os passos abaixo:</p>
<p>• Clique com o botão direito sobre a pasta;</p>
<p>• Escolha <em>SVN Checkout</em>;</p>
<p>• A figura 1 apresenta a janela que vai aparecer.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/checkout.png" alt="CheckOut" /></p>
<p>Figura 1 -  Tela de Checkout</p>
<p>Para acessar o repositório do  TerraView, é necessário informar a  <em>URL of</em></p>
<p><em> </em></p>
<p><em>repository</em>, que deverá ser usado sempre o caminho atualizado  no site do</p>
<p><a rel="nofollow" target="_blank" href="http://blog.geoprocessamento.net//www.dpi.inpe.br/terraview/index.php">TerraView</a>, na guia Downloads e subitem Fontes (desenvolvedor).</p>
<p>A figura 2 apresenta o endereço acessado no dia 21/05/2010. Este tutorial vai utilizar a versão 3-3-1.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/checkout2.png" alt="Checkout2" /></p>
<p>Figura 2 – Endereço para acessar o TerraView</p>
<p><strong>3. Configura a biblioteca Qt. </strong></p>
<p><em>Qt</em> é uma biblioteca C++ que permite que você possa programar para <em>Windows</em>,</p>
<p><em>Unix</em>/<em>Linux </em>e <em>Mac</em>, de modo portável, escrevendo o código uma única vez para</p>
<p>esses sistemas. Atualmente essa biblioteca pertence à  <em>Nokia</em>. Para maiores</p>
<p>informações consulte o site <a rel="nofollow" target="_blank" href="http://blog.geoprocessamento.net//www.trolltech.com/">trolltech</a>.</p>
<p>Crie uma pasta em C:/, com o nome de <em>Qt3 </em>e em seguida baixe a biblioteca</p>
<p>para essa pasta. Para baixar a biblioteca <em>Qt</em>, siga os mesmos passos utilizados</p>
<p>ao obter a biblioteca TerraView porém, em <em>URL of repository</em>, insira o caminho:</p>
<p>https://qtwin.svn.sourceforge.net/svnroot/qtwin/qt-3/trunk  ~ 40 MB</p>
<p><strong>4. Variáveis de ambiente</strong></p>
<p>As variáveis de ambiente são criadas a partir da tela de propriedades do sistema. Para exibir essa tela, clique em iniciar/painel de controle/sistema. Escolha a guia avançado e em seguida clique em variáveis de ambiente, conforme é apresentado na figura 3.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/varAmbiente.png" alt="" /></p>
<p>Figura 3 – Variáveis de ambiente</p>
<p>A seguir é necessário criar duas variáveis de ambiente (de usuário), <em>QTDIR </em>e <em>QMAKESPEC</em>. A figura 4 ilustra como essas variáveis são configuradas. Atenção o valor da variável <em>QTDIR</em>, deverá ser o diretório do <em>Qt</em>, <em>QMAKESPEC </em>varia conforme o compilador.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/varAmbiente1.png" alt="" /></p>
<p>Figura 4 – Variáveis QTDIR e QMAKESPEC</p>
<p>Após criar <em>QTDIR </em>e <em>QMAKESPEC</em>, é necessário atualizar a variável <em>Path </em>(de usuário). Clique sobre a variável <em>path</em>, escolha a opção editar e sem seguida adicione ao final a linha (;%QDIR%\bin\), apresentado na figura 5.</p>
<p>Nota: Observe que existe um ponto e vírgula (;) antes da linha %QDIR%\bin\.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/path.png" alt="" /></p>
<p>Figura 5 – Variável de ambiente Path</p>
<p><strong>5. Realizar um Build da biblioteca Qt.</strong></p>
<p>O compilação (<em>Build</em>) será realizado usando o <em>Prompt </em>de Comando do <em>Visual Studio</em>. Clique em iniciar/programas/Microsoft Visual Studio 2003/Visual Studio Tools/Visual Studio 2003 Command Prompt.</p>
<p>A figura 6 apresenta o Prompt de Comando.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/vs2003.png" alt="" /></p>
<p>Figura 6  - Prompt de comando do Visual Studio</p>
<p>Na tela do Prompt Command digite os comando abaixo:</p>
<p>•	cd\ e pressione Enter;</p>
<p>•	cd Qt3 Enter;</p>
<p>•	digite configure Enter.</p>
<p>Aguarde todo o <em>Build </em>ser realizado. O tempo aproximado são 30 minutos. Após concluir o <em>Build </em>digite <em>nmake</em>, e aguarde pouco minutos. Para certificar-se que a instalação ocorreu de maneira correta, abra o projeto t1, no endereço C:\Qt3\tutorial\t1\ t1.vcproj. Faça um Build e execute o projeto para aparecer uma tela com um botão escrito <em>Hello Word</em>.</p>
<p><strong><em>5.1 Atalho para a biblioteca Qt.</em></strong></p>
<p>Pressione com o botão direito do mouse no arquivo designer.exe, que está em C:\Qt3\bin, escolha enviar para e por fim clique em área de trabalho(criar atalho).</p>
<p><strong>6 Compilando o TerraView</strong></p>
<p>O projeto TerraView no Visual Studio já vem configurado com a seqüência correta que os projetos agregados a ele serão compilados, portanto para compilar o TerraView basta selecionar o menu Build/Rebuild Solution. Caso não por possível compilar o projeto por falta de alguma configuração no <em>Visual Studio</em>, compile os projetos na seguinte ordem abaixo:</p>
<p>•	libjpeg;</p>
<p>•	tiff;</p>
<p>•	shapelib;</p>
<p>•	terralib;</p>
<p>•	qtw;</p>
<p>•	libspl;</p>
<p>•	stat;</p>
<p>•	terralibpdi;</p>
<p>•	terraView.</p>
<p>A figura 7 apresenta a maneira de compilar os projetos separadamente. Clique com o botão direito sobre o projeto, por exemplo: <em>libjpeg </em>e escolha <em>Rebuild</em>.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/buldvs.png" alt="" /></p>
<p>Figura 7 – Rebuild projeto</p>
<p><strong><em>6.3 Compilando Plugin no TerraView</em></strong></p>
<p>Esta sessão apresenta os passos para inserir um plugin personalizado no <em>TerraView</em>. Primeiramente verifique se o <em>plugin HelloWorld</em> está criado no projeto do TerraView. Essa verificação é feita visualizando se existem a pasta <em>HelloWorld</em>, no caminho C:\FullTerraib\terraViewPlugins\HelloWorld. Caso o seu projeto não possua essa pasta, veja com criar os primeiros artifícios para o plugin no tutorial do <em>TerraView </em><a rel="nofollow" target="_blank" href="http://www.dpi.inpe.br/terraview/php/plugins.php. Construindo um plugin">3.3.1</a> , páginas 3 até 14.</p>
<p>A ferramenta qmake da biblioteca <em>Qt</em>, será usada na criação de um projeto para o <em>Visual Studio</em>, através do arquivo de projeto do <em>plugin </em>(HelloWorld.pro). A figura 9 apresenta como criar o um projeto para o <em>Visual Studio</em> através da tela de Prompt de Comando. Inicie a janela do prompt de comando, através do caminho: iniciar/executar/digite cmd + Enter. No prompt de comando digite C:/Qt3/bin + Enter. Informe o caminho completo do arquivo HelloWorld.pro entre aspas duplas + Enter. Consulte a figura 8, para esclarecer as dúvidas.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/buldmake.png" alt="" /></p>
<p>Figura 8 – Criar projeto para Visual Studio usando o prompt de comando</p>
<p>O arquivo de projeto para o <em>Visual Studio</em> (HelloWorld.vcproj), será criado após terminar a execução do qmake. Para visualizá-lo, entre na pasta C:\FullTerraib\terraViewPlugins\HelloWorld.</p>
<p>O <em>TerraView </em>carrega os <em>plugin´s</em> que estão dentro da pasta C:\FullTerraib\terraView\windows\plugins. Antes de continuar, verifique que esta pasta não contém arquivos de projetos. O próximo passo é compilar o <em>plugin </em>do <em>Visual Studio</em>. Clique duas vezes sobre o arquivo de projeto HelloWorld.vcproj no diretório C:\FullTerraib\terraViewPlugins\HelloWorld, em seguida selecione o menu <em>Build </em>e escolha a opção <em>Rebuild Solution</em>. Consulte novamente a pasta C:\FullTerraib\terraView\windows\plugins e veja que todo o resultado da compilação do projeto. Pode fechar o <em>Visual Studio</em>.</p>
<p>O <em>plugin HelloWorld </em>já poderá ser visto. Abra novamente a solution do <em>TerraView</em>, no diretório C:\FullTerraib\terraView\windows\ terraView.sln e em seguida clique sobre  o menu <em>Build</em>/<em>Rebuild Solution</em>. Assim que terminar o build com sucesso, clique em <em>start debugging</em> e será apresentado o <em>plugin</em>, conforme a figura 9.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/helloWord.png" alt="" /></p>
<p>Figura 9 – Plugin para TerraView</p>
<p><strong>7 Erros comuns</strong></p>
<p><strong> </strong></p>
<p><strong><em> 7.1 Não encontrou qt.lib</em></strong></p>
<p>Não foi possível encontrar o qt.lib. Clique com o botão direito sobre o projeto que gerou o erro e selecione propriedades para exibir a figura 10.</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/naoEncontrouQt.png" alt="" /></p>
<p>Figura 10 – Propriedades do projeto</p>
<p>Selecione a tag <em>Linker </em>e escolha <em>input</em>. No lugar de \lib\qt.lib, insira \lib\qt-mt3.lib.</p>
<p><strong>7.2 (...Binary was not built with debug information...)</strong></p>
<p>Clique com o botão direito sobre o projeto <em>TerraView</em>;</p>
<p>Escolha propriedades;</p>
<p>Selecione a guia <em>Configuration Properties</em>/CC++/<em>Optimization</em></p>
<p><em> Optimization</em>: escolha <em>Disabled </em>(/Od)</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/binarErro.png" alt="" /></p>
<p>Selecione a guia <em>Linker </em>na guia <em>Configuration Properties</em>/ <em>Linker</em>/<em>Debugging</em></p>
<p><em> Debugging Debug</em> Info: escolha <em>Yes </em>(/<em>DEBUG</em>)</p>
<p><img src="http://blog.geoprocessamento.net/wp-content/uploads/2010/09/binarErro2.png" alt="" /></p>
<p><strong>7.3 Erro ao compilar projeto qwt</strong></p>
<p>Descrição do erro:</p>
<p>qwt error PRJ0019: A tool returned an error code from "Moc'ing .\..\src\qwt\include\qwt_wheel.h..."</p>
<p>Verifique se as variáveis de ambiente estão corretas</p>
<p>Nome da variável: <em>QTDIR</em></p>
<p>Valor da variável: Diretório que está o <em>Qt</em>, por exemplo C:\Qt\3.2.0</p>
<p>Nome da variável: <em>QMAKESPEC</em></p>
<p>Valor da variável: win32-msvc.net (para o compilador visual studio 2003)</p>
<p>Em seguida procure e selecione a variável <em>path</em>.</p>
<p>Nota: Geralmente a variável que necessita ser alterada é a variável de ambiente do sistema, porém já encontrei</p>
<p>algumas máquinas que por algum motivo, é necessário editar a variável de ambiente do usuário.</p>
<p>Para alterar o conteúdo da variável path, clique sobre o botão editar e adicione ao final -&gt; ;%QDIR%\bin\.</p>
<p>Não esqueça do ponto-e-vírgula antes do sinal %.</p>
<p>Após verificar os itens acima, compile o projeto <em>qwt</em>. Casoo erro persista, clique com o botão direito</p>
<p>sobre o projeto qtw, selecione propriedades e faça a configuração abaixo.</p>
<p>Guia C C++/General/Additional Include Directories</p>
<p>..\..\src\qwt\include;"$(QTDIR)\include"</p>
<p>Guia <em>Linker</em>/<em>Input</em></p>
<p>$(QTDIR)\lib\qt-mt3.lib</p>
<p><span style="color: #ff0000"><em>Se esse tutorial foi útil, deixe um comentário por favor. Obrigado</em></span></p>
<p><strong>Referências</strong></p>
<p>Configurar Qt para Windows. Disponível em http://qtwin.sourceforge.net/qt3-win32/compile-msvc-2005.php. Acesso 21/05/2010.</p>
<p>TortoiseCVS. Disponível em: http://www.tortoisecvs.org. Acesso 18/05/2010.</p>
<p>TerraView. Disponível em: http://www.terralib.org. Acesso 18/05/2010.</p>
<p>Trolltec. Disponível em: hhttp://www.trolltech.com. Acesso 18/05/2010.</p>
<p>Visual Studio. Disponível em: http://social.msdn.microsoft.com 11-06. Acesso 15/05/2010.</p>
<p>Construindo um Plugin - TerraView  3.3.1. Disponível em http://www.dpi.inpe.br/terraview/php/plugins.php. Acesso 11/05/2010.</p>
<p><span style="color: #ff0000">Joao Tacio/TerraLab/UFOP-MG</span></p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/05/terraview/' rel='bookmark' title='Permanent Link: Conheça melhor o TerraView'>Conheça melhor o TerraView</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/02/hello-world-arcgis-style/' rel='bookmark' title='Permanent Link: Hello World, ArcGIS style!'>Hello World, ArcGIS style!</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2010/09/criar-plugin-para-terraview/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

