<?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; .NET</title>
	<atom:link href="http://blog.geoprocessamento.net/tag/net/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>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[


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>Brincando com ArcObjects #2</title>
		<link>http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects-2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=brincando-com-arcobjects-2</link>
		<comments>http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects-2/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 21:52:35 +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>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=870</guid>
		<description><![CDATA[No último post sobre ArcObjects, falamos como construir pontos de uma maneira simples. Hoje vamos brincar com alguns polígonos e polilinhas. Qual é a diferença? Bem, como explicado anteriormente, um polígono é uma coleção de anéis (rings), formados por pontos ou por segmentos. As polilinhas funcionam quase da mesma maneira, só que ao invés de [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects/' rel='bookmark' title='Permanent Link: Brincando com ArcObjects'>Brincando com ArcObjects</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/05/funcoes-postgis-3/' rel='bookmark' title='Permanent Link: Funções PostGIS #3'>Funções PostGIS #3</a></li>
<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>
</ol>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">No último post sobre <em>ArcObjects</em>, falamos como construir pontos de uma maneira simples. Hoje vamos brincar com alguns polígonos e polilinhas. Qual é a diferença? Bem, como explicado anteriormente, um polígono é uma coleção de anéis (<em>rings</em>), formados por pontos ou por segmentos. As polilinhas funcionam quase da mesma maneira, só que ao invés de anéis, as polilinhas são formadas por uma coleção de caminhos (<em>paths</em>).</p>
<p style="text-align: justify;">Não podemos criar estas geometrias de alto nível, sem criar antes as geometrias de baixo nível que as compõe. É a maneira na qual o ArcGIS trabalha, e é a mais sã, do ponto de vista de desenvolvimento.</p>
<p style="text-align: justify;">Primeiro vamos construir um polígono. Podemos construir os anéis separadamente, de pontos ou de segmentos e logo depois, adicionar à uma coleção de geometrias, na qual o próprio <em>ArcGIS</em> irá entender como um polígono.</p>
<pre name="code" class="c#">
public static IPolygon ConstruirPolígono()
    {
        object _missing = Type.Missing;

        IGeometryCollection poligonoFinal = new PolygonClass();

        // vamos criar primeiro nosso anel exterior
        // perceba com estamos utilizando uma interface IPointCollection

        IPointCollection anelExterior = new RingClass();

        // lembram da função BuildPoint do post anterior?

        anelExterior.AddPoint(BuildPoint(0,0,0),ref _missing, ref _missing);
        anelExterior.AddPoint(BuildPoint(0,1,0),ref _missing, ref _missing);
        anelExterior.AddPoint(BuildPoint(1,1,0),ref _missing, ref _missing);
        anelExterior.AddPoint(BuildPoint(1,0,0),ref _missing, ref _missing);

        // o último ponto deve ser sempre igual ao primeiro - somente assim
        // o polígono está fechado
        // podemos utilizar também uma outra técnica para usar o primeiro ponto
        // sem duplicar o ponto inicial - muito útil se você não sabe de antemão qual é o primeiro ponto.
        // anelExterior.AddPoint(anelExterior.get_Point(0),ref _missing, ref _missing);

        anelExterior.AddPoint(BuildPoint(0,0,0));

        poligono.AddGeometry(anelExterior as IGeometry, ref _missing, ref _missing);

        // definir a referência espacial - sem a referência espacial o ArcGis não realiza operações espaciais direitinho!

        return poligono as IPolygon;
}
</pre>
<div id="attachment_871" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/poligono_simples.png"><img class="size-full wp-image-871" title="BrincandoArcObjects_Figura01" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/poligono_simples.png" alt="Polígono construído com o código anterior" width="300" height="300" /></a><p class="wp-caption-text">Polígono construído com o código anterior</p></div><br />
Este é um código simples para a criação de um polígono igualmente simples. Vamos aumentar um pouco a dificuldade inserindo outros anéis.</p>
<pre name="code" class="c#">
public static IPolygon ConstruirPolígono()
    {
        object _missing = Type.Missing;

        IGeometryCollection poligonoFinal = new PolygonClass();

        // vamos criar primeiro nosso anel exterior
        // perceba com estamos utilizando uma interface IPointCollection

        IPointCollection anelExterior = new RingClass();

        // lembram da função BuildPoint do post anterior?

        anelExterior.AddPoint(BuildPoint(0,0,0),ref _missing, ref _missing);
        anelExterior.AddPoint(BuildPoint(0,10,0),ref _missing, ref _missing);
        anelExterior.AddPoint(BuildPoint(10,10,0),ref _missing, ref _missing);
        anelExterior.AddPoint(BuildPoint(10,0,0),ref _missing, ref _missing);

        // o último ponto deve ser sempre igual ao primeiro - somente assim
        // o polígono está fechado
        // podemos utilizar também uma outra técnica para usar o primeiro ponto
        // sem duplicar o ponto inicial - muito útil se você não sabe de antemão qual é o primeiro ponto.
        anelExterior.AddPoint(anelExterior.get_Point(0),ref _missing, ref _missing);

        IPointCollection anelInterior = new RingClass();
        anelInterior.AddPoint(BuildPoint(1,1,0), ref _missing, ref _missing);
        anelInterior.AddPoint(BuildPoint(1,2,0), ref _missing, ref _missing);
        anelInterior.AddPoint(BuildPoint(2,2,0), ref _missing, ref _missing);
        anelInterior.AddPoint(BuildPoint(2,1,0), ref _missing, ref _missing);
        anelInterior.AddPoint(anelInterior.get_Point(0),ref _missing, ref _missing);

        // nao é permitido sobrepor anéis, à menos que eles tenham orientações contrárias
        // nosso anel exterior tem orientação horária - todos os anéis exteriores devem ter orientação horária!
        // anéis interiores, que descrevem buracos em nossos polígonos devem ter orientação anti-horária!
        ICurve curva = anelInterior as ICurve;
        curva.ReverseOrientation();

        poligono.AddGeometry(anelExterior as IGeometry, ref _missing, ref _missing);
        poligono.AddGeometry(anelInterior as IGeometry, ref _missing, ref _missing);

        // definir a referência espacial - sem a referência espacial o ArcGis não realiza operações espaciais direitinho!

        return poligono as IPolygon;
}
</pre>
<p><div id="attachment_872" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/poligono_simples2.png"><img class="size-full wp-image-872" title="BrincandoArcObjects2_Figura02" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/poligono_simples2.png" alt="Polígono simples criado pelo código acima" width="300" height="300" /></a><p class="wp-caption-text">Polígono simples criado pelo código acima (fora de escala)</p></div>
<p style="text-align: justify;">Bem, é fácil trabalhar com geometrias da <em>ESRI</em>. Claro, quanto mais complexa a geometria, mais complexo deverá ser o código para cuidar da mesma. Mas não é nenhum bixo de 7 cabeças. Um outro detalhe interessante é que revertemos a orientação da geometria interna usando uma outra interface, e adicionamos nosso anel original. Por que funciona? A biblioteca <em>ArcObjects</em> fica responsável por notificar a geometria original de que certa operação ocorreu e a realiza de acordo.</p>
<p style="text-align: justify;">Em geral, os passos para se trabalhar com geometrias complexas é construir anéis ou segmentos, criados através da interface IPointCollection, pois assim podemos ir adicionando os pontos que temos interesse e depois ajeitar a orientação de cada anel para nos dar o resultado desejado.</p>
<p style="text-align: justify;">Certo, mas e um polígono que contenha curvas? O formato <em>shapefile</em> não suporta(va) o desenho delas e estão disponíveis à partir dos <em>geodatabases</em> (as curvas são convertidas em diversos segmentos, aproximando o resultado. Mas podemos criar um polígon com curvas via código? Sim, claro! O segredo, neste caso, é separar cada segmento em um anel, mesmo que ele, no final, seja parte de uma coisa só.</p>
<p style="text-align: justify;">Vamos criar dois anéis, um para nosso segmento curvo e o outro para nossos segmentos retos. Juntaremos os dois em apenas um anel e depois adicionaremos este anel ao polígono.</p>
<p style="text-align: justify;">Para construir segmentos curvos, existem diversas interfaces do tipo <em>IConstruct*</em> (<em>IConstructCircularArc, IConstructBezierCurve</em>, etc.), cada uma com suas particularidades.</p>
<pre name="code" class="c#">
object _missing = Type.Missing;

        IGeometryCollection polygon = new PolygonClass();

        // building circular arc

        IPoint p1 = PointPolygonBuilder.BuildPoint(1, 2);
        IPoint p2 = PointPolygonBuilder.BuildPoint(1, 1);
        IPoint p3 = PointPolygonBuilder.BuildPoint(1, 0);
        IPoint p4 = PointPolygonBuilder.BuildPoint(0, 0);
        IPoint p5 = PointPolygonBuilder.BuildPoint(0, 1);

        IConstructCircularArc constructCircularArc = new CircularArcClass();
        constructCircularArc.ConstructThreePoints(p5, p2, p1, true);
        ICircularArc circularArc = constructCircularArc as ICircularArc;
        // end circular Arc

        ISegmentCollection finalRing = new RingClass();
        ISegmentCollection ring1 = new RingClass();
        IPointCollection ring2 = new RingClass();

        ring1.AddSegment(circularArc as ISegment, ref _missing, ref _missing);
        ring2.AddPoint(p1, ref _missing, ref _missing);
        ring2.AddPoint(p3, ref _missing, ref _missing);
        ring2.AddPoint(p4, ref _missing, ref _missing);
        ring2.AddPoint(p5, ref _missing, ref _missing);

        finalRing.AddSegmentCollection(ring1);
        finalRing.AddSegmentCollection(ring2 as ISegmentCollection);
        polygon.AddGeometry(finalRing as IGeometry, ref _missing, ref _missing);
</pre>
<div id="attachment_873" class="wp-caption aligncenter" style="width: 190px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/poligono_curva.png"><img class="size-medium wp-image-873" title="BrincandoArcObjects2_PoligonoCurva" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/poligono_curva-180x300.png" alt="Polígono resultante do código acima" width="180" height="300" /></a><p class="wp-caption-text">Polígono resultante do código acima</p></div>
<p style="text-align: justify;">Note que deu um trabalhinho à mais para montar este segmento curvo. É bom deixar claro também, que o ponto (1,1) representado na figura, não entra no anel feito de segmentos retos, ele é apenas utilizado para construir o segmento curvo.</p>
<p style="text-align: justify;">Outra coisa legal é ver que para acessar alguns métodos, você tem que instanciar certas interfaces. Notem que o <em>finalRing</em> e <em>ring1</em> possuem propriedades semelhantes, pois têm a mesma interface. Já <em>ring2</em> possui outros membros, pois é de interface diferente. Classes iguais, interfaces diferentes = propriedades diferentes.</p>
<p style="text-align: justify;">E aí, o que acharam?</p>
<p style="text-align: justify;">Abraços pessoal!</p>
<p style="text-align: justify;">George R. C. Silva</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects/' rel='bookmark' title='Permanent Link: Brincando com ArcObjects'>Brincando com ArcObjects</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/05/funcoes-postgis-3/' rel='bookmark' title='Permanent Link: Funções PostGIS #3'>Funções PostGIS #3</a></li>
<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>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configure o TerraLib no Visual Studio 2003</title>
		<link>http://blog.geoprocessamento.net/2010/06/configure-o-terralib-3-3-no-visual-studio-2003/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=configure-o-terralib-3-3-no-visual-studio-2003</link>
		<comments>http://blog.geoprocessamento.net/2010/06/configure-o-terralib-3-3-no-visual-studio-2003/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 03:50:18 +0000</pubDate>
		<dc:creator>João Tácio</dc:creator>
				<category><![CDATA[João Tácio Silva]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[TerraLib]]></category>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=835</guid>
		<description><![CDATA[Configure o TerraLib no Visual Studio 2003 Por: Joao Tacio Este é o primeiro post de uma série sobre como utilizar a biblioteca TerraLib para desenvolver suas próprias aplicações. Espero que gostem! O tutorial apresentado é um complemento da documentação disponibilizada pelo INPE , que ensina como configurar a biblioteca TerraLib 3.3.1 no Visual Studio [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/09/criar-plugin-para-terraview/' rel='bookmark' title='Permanent Link: Criar plugin para TerraView'>Criar plugin para TerraView</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects-2/' rel='bookmark' title='Permanent Link: Brincando com ArcObjects #2'>Brincando com ArcObjects #2</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[<div class="mceTemp">
<h1>Configure o TerraLib no Visual Studio 2003</h1>
<h5><span style="font-weight: normal"><span style="color: #888888"><em>Por: Joao Tacio</em></span></span></h5>
</div>
<p>Este é o primeiro post de uma série sobre como utilizar a biblioteca TerraLib para desenvolver suas próprias aplicações. Espero que gostem!</p>
<p style="text-align: justify">O tutorial apresentado é um complemento da documentação disponibilizada pelo INPE , que ensina como configurar a biblioteca TerraLib 3.3.1 no Visual Studio 2003.</p>
<h3>1 - Requisitos para executar os exemplos</h3>
<ul>
<li>Visual Studio C++ 2003;</li>
<li>MySQL Administrator 5.o;</li>
<li>Driver MySQL para Windows;</li>
<li>Banco de Dados MySQL 5.1;</li>
<li>Biblioteca TerraLib para Windows, 3.3 ou superior;</li>
</ul>
<h3 style="text-align: justify">2 - Instruções gerais de instalação</h3>
<p style="text-align: justify">O primeiro software a instalar é o Visual Studio 2003. Utilize a instalação personalizada e <strong>desmarque o suporte a todas as outras linguagens diferentes do C++,</strong> por exemplo: C# e VB. A seguir, instale o MySQL, Driver do MySQL e o MySQL Administrator.</p>
<p style="text-align: justify">Após instalar com sucesso os softwares descritos acima, crie uma pasta no disco C, por exemplo C:/TerraDir e descompacte todo o conteúdo do arquivo TerraLib_win_v_3_3_1.zip. Após descompactar, a árvore de pastas deve seguir o formato da figura 1.</p>
<div id="attachment_836" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/1.png"><img class="size-medium wp-image-836" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/1-300x80.png" alt="Árvore de pastas do TerraLib" width="300" height="80" /></a><p class="wp-caption-text">Árvore de pastas do TerraLib</p></div>
<h3 style="text-align: justify">3 - Compilando a biblioteca TerraLib</h3>
<p style="text-align: justify">O primeiro passo é compilar toda biblioteca TerrLib. Para isso, abra o Visual Studio, clique em File/Open Project / e escolha a solution, referente à biblioteca que será executada. No exemplo abaixo será compilado a solution createDatabase.sln.</p>
<p style="text-align: justify"><strong>1) File/Open project/ ou Ctrl+Shift+O</strong><br />
C:\TerraDir\examples\createDatabase\createDatabase.sln. Certifique-se que o arquivo escolhido possui a extensão.sln, porque na pasta createDatabase, também possui um arquivo chamado createDatabase.dsw.</p>
<p style="text-align: justify"><strong>2) Build/Build Solution ou Ctrl+Shitf+B</strong><br />
Build Sucessfull -&gt; Essa mensagem é indício que está indo tudo muito bem, parabéns!</p>
<p style="text-align: justify">Faça este mesmo procedimento para todas as bibliotecas abaixo na ordem que estão listadas.</p>
<ul>
<li>createLayer;</li>
<li>createTable;</li>
<li>importMIDMIF;</li>
<li>importShape;</li>
<li>importDBF;</li>
<li>importJPEG;</li>
<li>copyLayer;</li>
<li>importGeoTab;</li>
<li>convertCoordinates;</li>
<li>databaseQuery;</li>
<li>databaseSQLQuery;</li>
<li>spatialQuery;</li>
<li>addGeomRepresentation;</li>
<li>createTheme;</li>
<li>themeGrouping;</li>
<li>createSTElementSet;</li>
<li>mosaicTIFFImages;</li>
<li>importCSV;</li>
<li>importGridData;</li>
<li>rasterSlicing;</li>
<li>querierFromTheme;</li>
<li>proxMatrixAndSpatialStatistics;</li>
<li>spatialQueryAndBuffer;</li>
<li>querierFromLayer;</li>
<li>createSTElementSetFromLayer;</li>
<li>image_processing.</li>
</ul>
<p style="text-align: justify">Após compilar todas as bibliotecas acima sem erros, pode fechar o Visual Studio. A próxima etapa consiste em codificar alguns trechos de códigos para iniciar o aprendizado na biblioteca TerraLib. No tutorial do INPE  existem diversas páginas com trechos de código.</p>
<p style="text-align: justify"><strong>4 - Configurar o projeto</strong></p>
<p style="text-align: justify">Este tutorial ficará limitado em explicar detalhadamente apenas os passos necessários para criar um projeto.</p>
<p style="text-align: justify">O primeiro passo é criar um novo projeto, para isso abra o Visual Studio. Escolha File/New/Project, conforme a figura 2 e coloque o nome no projeto de Primeiro Exemplo.</p>
<div id="attachment_837" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/2.png"><img class="size-medium wp-image-837" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/2-300x236.png" alt="Criar um novo projeto" width="300" height="236" /></a><p class="wp-caption-text">Criar um novo projeto</p></div>
<p>Escolha o template Console Application (.NET), conforme imagem 3.</p>
<div id="attachment_838" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/3.png"><img class="size-medium wp-image-838" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/3-300x204.png" alt="Figura 3 - Escolher Template" width="300" height="204" /></a><p class="wp-caption-text">Figura 3 - Escolher Template</p></div>
<p style="text-align: justify">Após criar o projeto PrimeiroExemplo, é necessário várias configurações. A primeira é adicionar os projetos existentes do TerraLib. Para isso clique na solution e escolha add e selecione Existing Project. Veja nas figuras 4, 5 e 6 como adicionamos o projeto terralib.</p>
<div id="attachment_839" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/4.png"><img class="size-medium wp-image-839" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/4-300x263.png" alt="Figura 04  - Adicionar projeto existente" width="300" height="263" /></a><p class="wp-caption-text">Figura 04 - Adicionar projeto existente</p></div>
<div id="attachment_840" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/5.png"><img class="size-medium wp-image-840" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/5-300x193.png" alt="Figura 05 - Adicionar projeto existente  (2° passo)" width="300" height="193" /></a><p class="wp-caption-text">Figura 05 - Adicionar projeto existente (2° passo)</p></div>
<div id="attachment_841" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/6.png"><img class="size-medium wp-image-841" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/6-300x193.png" alt="Figura 06 - Adicionar projeto existente (3° passo)" width="300" height="193" /></a><p class="wp-caption-text">Figura 06 - Adicionar projeto existente (3° passo)</p></div>
<div id="attachment_842" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/7.png"><img class="size-medium wp-image-842" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/7-300x193.png" alt="Figura 07 - Adicionar projeto existente (4° passo)" width="300" height="193" /></a><p class="wp-caption-text">Figura 07 - Adicionar projeto existente (4° passo)</p></div>
<p style="text-align: justify">Além do projeto terralib, é necessário adicionar os projetos libjpeg e tiff, que estão respectivamente nos caminhos C:\TerraDir\terralibw\libjpeg  e C:\TerraDir\terralibw\tiff. Após adicionar os três projetos, faça um Build na solution.</p>
<p style="text-align: justify">Além desses três projetos que foram incorporados ao projeto PrimeiroExemplo, outros projetos do TerraLib poderão ser agregados conforme a necessidade.</p>
<p style="text-align: justify">O procedimento a seguir objetiva configurar o projeto PrimeiroExemplo. Clique nas propriedades do projeto, conforme na figura 08.</p>
<div id="attachment_843" class="wp-caption aligncenter" style="width: 224px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/8.png"><img class="size-medium wp-image-843" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/8-214x300.png" alt="Figura 08 - Propriedades do Projeto" width="214" height="300" /></a><p class="wp-caption-text">Figura 08 - Propriedades do Projeto</p></div>
<p style="text-align: justify">Insira o caminho para os diversos diretórios adicionais do projeto. Para realizar essa operação, copie e cole toda a linha a seguir no campo Additional Include Directories. A figura 09 detalha o que precisa ser feito.</p>
<blockquote><p>.;..\..\src\terralib\kernel;..\..\src\terralib\drivers\MySQL;..\..\src\terralib\drivers\MySQL\include</p></blockquote>
<div id="attachment_844" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/9.png"><img class="size-medium wp-image-844" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/9-300x201.png" alt="Figura 09 - Adicionar Diretórios Adicionais" width="300" height="201" /></a><p class="wp-caption-text">Figura 09 - Adicionar Diretórios Adicionais</p></div>
<p style="text-align: justify">Desabilite o Precompiled headers. Não feche a janela de propriedades. Configure o Linker do projeto PrimeiroExemplo. Esse procedimento é necessário para que o projeto criado consiga referenciar as classes do TerraLib. Inclua as dependências adicionais conforme ilustra a figura 10. Para isso copie as linhas abaixo e cole em Additional Dependencies.</p>
<div id="attachment_845" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/10.png"><img class="size-medium wp-image-845" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/10-300x201.png" alt="Figura 10 - Desabilite os precompiled headers" width="300" height="201" /></a><p class="wp-caption-text">Figura 10 - Desabilite os precompiled headers</p></div>
<div id="attachment_846" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/11.png"><img class="size-medium wp-image-846" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/11-300x201.png" alt="Figura 11 - Additional dependencies" width="300" height="201" /></a><p class="wp-caption-text">Figura 11 - Additional dependencies</p></div>
<blockquote><p>../../Debug/terralib/terralib.lib ../../Debug/libjpeg/libjpeg.lib ../../Debug/tiff/tiff.lib</p>
<p>../../terralibw/zlib/zlibdll.lib ../../terralibw/MySQL/libMySQL.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib imm32.lib winmm.lib wsock32.lib winspool.lib delayimp.lib</p></blockquote>
<p style="text-align: justify">Após realizar todos os procedimentos acima, faça um build do projeto. Caso ocorrer algum erro, tente remover e copiar novamente as linhas que foram inseridas nas propriedades do projeto. Atenção ao copiar essas linhas, espaços não podem ser retirados ou inseridos.</p>
<p style="text-align: justify">Os procedimentos abaixo consistem em adicionar itens existentes ao projeto. Para o projeto PrimeiroProjeto, será adicionado as bibliotecas TeMySQL.h e TeMySQL.cpp. As figuras de 12 14 demonstram como adicionar o item TeMySQL.cpp ao Source File do Projeto.</p>
<div id="attachment_847" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/12.png"><img class="size-medium wp-image-847" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/12-300x192.png" alt="Figura 12 - Adicionar itens existentes do 1° passo" width="300" height="192" /></a><p class="wp-caption-text">Figura 12 - Adicionar itens existentes do 1° passo</p></div>
<div id="attachment_848" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/13.png"><img class="size-medium wp-image-848" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/13-300x192.png" alt="Figura 13 - Adicionar Itens existentes (2° passo)" width="300" height="192" /></a><p class="wp-caption-text">Figura 13 - Adicionar Itens existentes (2° passo)</p></div>
<p>A figura 13 apresenta os dois arquivos da biblioteca TerraLib que deverão ser inseridos ao projeto. Inicialmente escolha apenas TeMySQL.cpp a selecione Open.</p>
<div id="attachment_849" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/14.png"><img class="size-medium wp-image-849" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/14-300x290.png" alt="Figura 14 - Arquivos existentes da biblioteca" width="300" height="290" /></a><p class="wp-caption-text">Figura 14 - Arquivos existentes da biblioteca</p></div>
<p style="text-align: justify">Para adicionar o arquivo TeMySQL.h ao projeto, click sobre Header Files do projeto PrimeiroProjeto. A figura 14 demonstra como fazer isso. Os próximos passos para adicionar TeMySQL.h são os mesmos das figuras 12 e 13, porém escolha TeMySQL.h e pressione open.</p>
<p style="text-align: justify">Ao final de todos esses procedimentos, realize um build de todo o projeto PrimeiroProjeto para certificarmos que todos as configurações estão corretas.</p>
<h3 style="text-align: justify">5 – Codificar o primeiro exemplo</h3>
<p style="text-align: justify">Para iniciar a codificação do primeiro exemplo, click duas vezes sobre a classe PrimeiroExemplo.cpp, conforme a imagem 15 e adicione as bibliotecas e os métodos criarBancoDeDados e conectar. Após a figura 15 tem o código completo da classe PrimeiroExemplo.cpp. Após codificar a classe, realize um build no projeto e execute-o.</p>
<div id="attachment_850" class="wp-caption aligncenter" style="width: 266px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/15.png"><img class="size-medium wp-image-850" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/06/15-256x300.png" alt="Figura 15 - Alterando a classe PrimeiroExemplo.cpp" width="256" height="300" /></a><p class="wp-caption-text">Figura 15 - Alterando a classe PrimeiroExemplo.cpp</p></div>
<pre>#include "stdafx.h"
#include "conio.h"

#include "TeMySQL.h"
#include "TeDriverMIDMIF.h"

#using 

using namespace System;

//Declaração dos métodos
int conectar();
int criarBancoDeDados();

int _tmain()
{
    // TODO: Please replace the sample code below with your own.
    Console::WriteLine(S"Hello World");
	conectar();
	criarBancoDeDados();
	getch();
	return 0;
}

int criarBancoDeDados ()
{
	// Parâmetros do servidor de bancos de dados
	string host = "localhost";
	string dbname = "TerraTeste";
	string user = "root";
	string password = ""; 

	// Cria um novo banco
	TeDatabase* db = new TeMySQL();
	if (!db-&gt;newDatabase(dbname,user, password, host))
	{
	cout &lt;&lt; "Erro: " &lt;&lt; db-&gt;errorMessage() &lt;&lt; endl;
	return 1;
	} 

	cout &lt;&lt; "O banco de dados \"" &lt;&lt; dbname;
	cout &lt;&lt;"\" foi criado com sucesso no servidor MySQL localizado em\""
		&lt;&lt; host;
	cout &lt;&lt; "\" para o usuario \"" &lt;&lt; user &lt;&lt; "\"!"  &lt;&lt; endl;  	// Fecha o banco de dados  	db-&gt;close();
	delete db;
	return 0;
}

int conectar()
{
	// Cria uma conexão a um servidor de banco de dados
	TeDatabase* db = new TeMySQL();
	// Parametros do servidor de bancos de dados
	string host ="localhost";
	string dbname = "TerraTeste";
	string user = "root";
	string password = "";
	if (!db-&gt;connect(host,user, password,dbname,0))
	{
	cout&lt;&lt; "Erro: " &lt;&lt; db-&gt;errorMessage() &lt;&lt; endl;
	return 0;
	}
	cout &lt;&lt; "Aberta conexão ao banco: " &lt;&lt; dbname;
             db-&gt;close();
	delete db;
  }</pre>
<p><span style="color: #ff0000">Se esse tutorial foi útil, deixe um comentário por favor. Obrigado</span></p>
<p>Joao Tacio/TerraLab/UFOP-MG</p>


<p>Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2010/09/criar-plugin-para-terraview/' rel='bookmark' title='Permanent Link: Criar plugin para TerraView'>Criar plugin para TerraView</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects-2/' rel='bookmark' title='Permanent Link: Brincando com ArcObjects #2'>Brincando com ArcObjects #2</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/06/configure-o-terralib-3-3-no-visual-studio-2003/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Hello World, ArcGIS style!</title>
		<link>http://blog.geoprocessamento.net/2010/02/hello-world-arcgis-style/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=hello-world-arcgis-style</link>
		<comments>http://blog.geoprocessamento.net/2010/02/hello-world-arcgis-style/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 23:27:58 +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>

		<guid isPermaLink="false">http://blog.geoprocessamento.net/?p=389</guid>
		<description><![CDATA[Boa noite pessoal, Conforme prometi, vamos começar a brincar de ArcObjects. Se vocês instalaram o Visual Studio 2005 (pode ser o Express, disponível gratuitamente) e depois instalaram o software development kit vocês não teram problema para acompanhar este simples guia. Notas importantes Não irei focar no código. Não irei explicar detalhadamente o que cada função [...]


Related posts:<ol><li><a href='http://blog.geoprocessamento.net/2011/07/diquinhas-de-arcgis-1/' rel='bookmark' title='Permanent Link: Diquinhas de ArcGIS #1'>Diquinhas de ArcGIS #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects/' rel='bookmark' title='Permanent Link: Brincando com ArcObjects'>Brincando com ArcObjects</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/05/arcgis-com-lancado/' rel='bookmark' title='Permanent Link: ArcGIS.com lançado'>ArcGIS.com lançado</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Boa noite pessoal,</p>
<p>Conforme prometi, vamos começar a brincar de <em>ArcObjects</em>.</p>
<p>Se vocês instalaram o Visual Studio 2005 (pode ser o <em>Express</em>, disponível gratuitamente) e <strong>depois</strong> instalaram o <em>software development kit </em>vocês não teram problema para acompanhar este simples guia.</p>
<h3>Notas importantes</h3>
<ul>
<li>Não irei focar no código. Não irei explicar detalhadamente o que cada função faz. Isto é trabalho de vocês.</li>
<li>Irei ajudar na parte mais difícil: como começar. Existem algumas coisinhas que são chatíssimas quando programamos para <em>ArcGIS</em>, mas ainda bem que o próprio <em>Visual Studio</em> resolve algumas delas para nós.</li>
</ul>
<h3>Início</h3>
<p>Primeiramente, abra o <em>Visual Studio</em> e peça um <em>New Project</em>. Selecione um <em>Empty Project </em>e dê um nome para seu projeto.</p>
<div id="attachment_390" class="wp-caption aligncenter" style="width: 420px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/02/p1.png"><img class="size-full wp-image-390 " title="Criando um novo projeto" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/02/p1.png" alt="Criando um novo projeto" width="410" height="278" /></a><p class="wp-caption-text">Criando um novo projeto no Visual Studio 2005</p></div>
<p>Depois de isso feito, termos algo mais ou menos assim:</p>
<p style="text-align: center;">
<div id="attachment_391" class="wp-caption aligncenter" style="width: 440px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/02/p2.png"><img class="size-large wp-image-391  " title="Empty Project" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/02/p2-1024x537.png" alt="Projeto vazio" width="430" height="226" /></a><p class="wp-caption-text">Projeto vazio</p></div>
<p>O Visual Studio é extremamente personalizável, portanto não precisa se concentar em deixar sua tela <strong>exatamente</strong> igual a minha. Quero que você veja o <em>Solution Explorer </em>que fica à direita.</p>
<p>Vamos para o <em>rock.</em> O que iremos fazer?</p>
<p>Vamos criar uma simples barrinha de ferramentas que nos avisa quantas camadas temos em um determinado MXD. Simples né? Besta né? Mas isso vai ser o fundamento, coisas mais complexas virão.</p>
<p>Então vamos lá. Vá na raiz do projeto (escrito <em>HelloWorldArcGIS</em>) e clique com o botão direito. Clique em <em>Add ArcGIS Reference.</em></p>
<p><strong>O que isto exatamente faz?<em> </em></strong>Bem, o ArcGIS como diversos softwares, são muito grandes, e não podemos/devemos referenciar todo o código junto. Para que adicionar referências que <strong>não iremos utilizar?</strong></p>
<p>Certo, quando você clicar no botãozinho, irá aparecer uma janelinha. Vá na opção <em>Desktop ArcMap </em>e adicione as seguintes <em>assemblies:</em></p>
<ul>
<li>ESRI.ArcGIS.ArcMapUI;</li>
<li>ESRI.ArcGIS.ArcMap;</li>
<li>ESRI.ArcGIS.Display;</li>
<li>ESRI.ArcGIS.Framework;</li>
<li>ESRI.ArcGIS.Geodatabase;</li>
<li>ESRI.ArcGIS.System;</li>
<li>ESRI.ArcGIS.Carto;</li>
</ul>
<p>Clique em <em><strong>Finish.</strong></em></p>
<p>Você verá que a pasta <em><strong>References</strong></em> foi atualizada. Vamos adicionar algumas <em>assemblies </em>do <em>Windows </em>e do .<em>NET.</em></p>
<p>Siga o mesmo passo acima, mas ao invés de escolher <em>Add ArcGIS Reference</em>, escolha <em>Add Reference</em>. Uma caixinha irá se abrir, portanto em .<em>NET</em>, seleciona as seguintes <em>assemblies</em>:</p>
<ul>
<li>System</li>
<li>System.Drawing</li>
<li>System.Windows.Forms</li>
</ul>
<p>Clique <strong>ok</strong>. Estamos <em>good to go.</em></p>
<p>Nossas referências estão no lugar. Isto significa que poderemos utilizar código pronto contido nestas <em>assemblies</em>. Isto é importante e interessante que se aprenda cedo, senão algo pode deixar de funcionar simplesmente porque você nao colocou aquela referência...</p>
<p>Vamos agora criar uma barra de ferramentas para colocar nossas coisinhas nela.</p>
<p>Clique com o botão direito na raiz do projeto e clique em <em>Add &gt; Add New Item</em>.</p>
<div id="attachment_392" class="wp-caption aligncenter" style="width: 419px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/02/p4.png"><img class="size-full wp-image-392 " title="Adicionando uma barra de ferramentas" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/02/p4.png" alt="Adicionando uma barra de ferramentas" width="409" height="247" /></a><p class="wp-caption-text">Adicionando uma barra de ferramentas</p></div>
<p>Selecione Base Toolbar e dê um nome à esta toolbar. Algo como <em>HelloWorldToolbar, </em>e clique em <em>Add.</em> Um tela irá aparecer perguntando <strong>qual tipo </strong>de barra de ferramentas você quer. Selecione <em>ArcMap </em>e boa.</p>
<p>Olhe suas referências. Elas foram atualizadas e adicionados alguns <em>assemblies</em> extras. Não se preocupe com eles. O <em>Visual Studio</em> é até inteligente para colocar algumas que você pode ter esquecido, mas só pelos canais oficiais (como este de adicionar uma <em>toolbar</em>). Se você criar uma classe e tentar herdar de BaseToolbar você provavelmente ganhará um erro.</p>
<p>Ele abriu um arquivo de código com a extensão .cs que contém diversas coisas, uns números muito doidos e por aí vai. Vamos explicar:</p>
<pre name="code" class="c-sharp">using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.ADF.BaseClasses;

namespace HelloWorldArcGIS
{
    ///
    /// Summary description for HelloWorldToolbar.
    ///
    [Guid("cc7ed839-de6c-46a7-9817-f4a3756cc57c")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("HelloWorldArcGIS.HelloWorldToolbar")]
    public sealed class HelloWorldToolbar : BaseToolbar
    {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);

            //
            // TODO: Add any COM registration code here
            //
        }

        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);

            //
            // TODO: Add any COM unregistration code here
            //
        }

        #region ArcGIS Component Category Registrar generated code
        ///
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        ///
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            MxCommandBars.Register(regKey);
        }
        ///
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        ///
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            MxCommandBars.Unregister(regKey);
        }

        #endregion
        #endregion

        public HelloWorldToolbar()
        {
            //
            // TODO: Define your toolbar here by adding items
            //
            //AddItem("esriArcMapUI.ZoomInTool");
            //BeginGroup(); //Separator
            //AddItem("{FBF8C3FB-0480-11D2-8D21-080009EE4E51}", 1); //undo command
            //AddItem(new Guid("FBF8C3FB-0480-11D2-8D21-080009EE4E51"), 2); //redo command
        }

        public override string Caption
        {
            get
            {
                //TODO: Replace bar caption
                return "My C# Toolbar";
            }
        }
        public override string Name
        {
            get
            {
                //TODO: Replace bar ID
                return "HelloWorldToolbar";
            }
        }
    }
}
</pre>
<p>Vamos lá:</p>
<p>O que merece nota <strong>imediata:</strong></p>
<ul>
<li>O construtor da barra de ferramentas. O construtor é o método responsável por instanciar um novo objeto do tipo HelloWorldToolbar. Veja que existem um monte de comentários ensinando como podemos inserir ferramentas ou botões nele. À seguir utilizaremos eles. Mas dê uma lida nos <em>comments </em>com carinho.</li>
<li>A propriedade Caption. Nela temos "My C# Toolbar" como caption. Altere para o que achar melhor. Este nome é o nome que irá aparecer dentro do <em>ArcGIS</em>.</li>
<li>A propriedade Name. Deve ser único. Portanto, é melhor nem mexer com isto, por enquanto.</li>
<li>O restante são funções para registro/desregistro da barra de ferramentas. Isto é um pré-requisito, pois estamos trabalhando com tecnologia COM, se lembram? Não altere <strong>nada.</strong></li>
</ul>
<p>Nossa barra de ferramentas está criada, mas uma barra de ferramentas sozinha não me adianta de nada. Vamos criar umas ferramentinhas. Siga o mesmo procedimento que utilizou para criar a barra de ferramentas, mas desta vez, escolha BaseCommand e nomeie ele como achar melhor. No meu caso, vou dar o nome de <strong>ComandoHelloWorld</strong>.</p>
<p>Mais uma vez um <em>prompt</em> irá aparecer e te perguntar qual é o tipo de comando você quer criar. Vejamos...escolha <em>Desktop ArcMap Command</em> e boa.</p>
<pre name="code" class="c-sharp">using System;
using System.Drawing;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.ArcMapUI;

namespace HelloWorldArcGIS
{
    ///
    /// Summary description for ComandoHelloWorld.
    ///
    // preste atenção neste valor aqui!
    [Guid("2423ecdf-4f14-4993-a165-df9d79167f4d")]
    // preste atenção neste valor aqui!
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("HelloWorldArcGIS.ComandoHelloWorld")]
    public sealed class ComandoHelloWorld : BaseCommand
    {
        #region COM Registration Function(s)
        [ComRegisterFunction()]
        [ComVisible(false)]
        static void RegisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryRegistration(registerType);

            //
            // TODO: Add any COM registration code here
            //
        }

        [ComUnregisterFunction()]
        [ComVisible(false)]
        static void UnregisterFunction(Type registerType)
        {
            // Required for ArcGIS Component Category Registrar support
            ArcGISCategoryUnregistration(registerType);

            //
            // TODO: Add any COM unregistration code here
            //
        }

        #region ArcGIS Component Category Registrar generated code
        ///
        /// Required method for ArcGIS Component Category registration -
        /// Do not modify the contents of this method with the code editor.
        ///
        private static void ArcGISCategoryRegistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            MxCommands.Register(regKey);

        }
        ///
        /// Required method for ArcGIS Component Category unregistration -
        /// Do not modify the contents of this method with the code editor.
        ///
        private static void ArcGISCategoryUnregistration(Type registerType)
        {
            string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
            MxCommands.Unregister(regKey);

        }

        #endregion
        #endregion

        private IApplication m_application;
        public ComandoHelloWorld()
        {
            //
            // TODO: Define values for the public properties
            //
            base.m_category = ""; //localizable text
            base.m_caption = "";  //localizable text
            base.m_message = "";  //localizable text
            base.m_toolTip = "";  //localizable text
            base.m_name = "";   //unique id, non-localizable (e.g. "MyCategory_ArcMapCommand")

            try
            {
                //
                // TODO: change bitmap name if necessary
                //
                string bitmapResourceName = GetType().Name + ".bmp";
                base.m_bitmap = new Bitmap(GetType(), bitmapResourceName);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.Message, "Invalid Bitmap");
            }
        }

        #region Overriden Class Methods

        ///
        /// Occurs when this command is created
        ///
        ///
        Instance of the application
        public override void OnCreate(object hook)
        {
            if (hook == null)
                return;

            m_application = hook as IApplication;

            //Disable if it is not ArcMap
            if (hook is IMxApplication)
                base.m_enabled = true;
            else
                base.m_enabled = false;

            // TODO:  Add other initialization code
        }

        ///
        /// Occurs when this command is clicked
        ///
        public override void OnClick()
        {
            // TODO: Add ComandoHelloWorld.OnClick implementation
        }

        #endregion
    }
}
</pre>
<p>Pontos merecedores de notas:</p>
<ul>
<li>Novamente o construtor do comando. Ele tem diversas informações que são mostradas ao usuário no <em>ArcGIS</em>. Não irei explicar uma à uma, brinque com elas e teste.</li>
<li>Um campo (<em>field) </em>importantissímo: m_application. Ele guarda uma referência de memória à sua aplicação que está rodando. Sem o software não teria como chamar coisas que estão lá dentro.</li>
<li>Método OnClick(). Este método é que irá rodar quando o usuário clicar no comando. Nós implementaremos as coisinhas todas ali. <em>Capiche?</em></li>
</ul>
<p>Vamos adicionar nosso comando à barra de ferramentas. Lembram do construtor da barra de ferramentas, que contém alguns exemplos de Add?</p>
<p>Vá no seu comando e procure pelo valor GUID dele. O meu é 2423ecdf-4f14-4993-a165-df9d79167f4d. Digite isto (claro, com o seu valor GUID) no construtor da barra de ferramentas.</p>
<pre name="code" class="c-sharp">
    AddItem(new Guid("2423ecdf-4f14-4993-a165-df9d79167f4d"), 0);
</pre>
<p>Vamos tentar compilar. Aperte F6.</p>
<p>Um erro <strong>deve</strong> aparecer. Ainda não configuramos nossa aplicação para abrir com o <em>ArcMap.</em> Vá na raiz do projeto, clique com o botão direito e vá em <em>Properties.</em></p>
<p>Você irá ver um monte de coisas.</p>
<p>Na parte de <em>Application</em> procure <em>Output Type </em>e escolha <em>Class Library.</em></p>
<p>Em <em>Build</em> marque a última opção, <em>Register for COM Interop</em>. Lembra que tudo que fazemos com <em>ArcObjects </em><strong>temos<em> </em></strong>que fazer com COM? Ficou estranho isso, mas válá.</p>
<p>Vá em DEBUG e procure a seção <em>Start Action</em>. Marque <em>Start External Program </em>e localize o arquivo ArcMap.exe no seu computador. O meu fica em C:\Program Files\ArcGIS\bin\ArcMap.exe.</p>
<p>Tente compilar novamente. Aperte F6. Você não deve ver <strong>nenhum</strong> erro. O <em>ArcGIS </em>irá abrir sozinho.</p>
<p style="text-align: left;">
<div id="attachment_395" class="wp-caption aligncenter" style="width: 440px"><a href="http://blog.geoprocessamento.net/wp-content/uploads/2010/02/p51.png"><img class="size-large wp-image-395  " title="ArcGIS aberto e barra de ferramenta disponível" src="http://blog.geoprocessamento.net/wp-content/uploads/2010/02/p51-1024x535.png" alt="ArcGIS aberto e barra de ferramenta disponível" width="430" height="225" /></a><p class="wp-caption-text">ArcGIS aberto e barra de ferramenta disponível</p></div>
<p>Nossa barrinha de ferramentas esta lá!</p>
<p style="text-align: left;">Agora vamos implementar a nossa <em>super-ultra-mega-</em>complexa funcionalidade. Feche o <em>ArcMap. </em>Retorne ao <em>Visual Studio.</em></p>
<p style="text-align: left;">Abra o arquivo de código do nosso comando. Suba até o topo de nosso arquivo.</p>
<p style="text-align: left;">Você verá um monte de coisas como <em>using System.Drawing</em> entre outros. Aqui nós dizemos ao <em>Visual Studio</em> quais assemblies este arquivo poderá acessar. Faltam duas importantes para nós aí.</p>
<p style="text-align: left;">Insira a<em> assembly </em>ESRI.ArcGIS.Carto e a <em>assembly </em>System.Windows.Forms. Lembre-se de colocar cada uma em uma linha, e <strong>não se esqueça do ponto-e-vírgula.</strong></p>
<pre name="code" class="c-sharp">        public override void OnClick()
        {
            // pegue uma referência ao documento que está rodando
            // note o uso do campo m_application
            IMxDocument documento = (IMxDocument)this.m_application.Document;

            // pegue uma referência ao mapa atual
            // note que caso tenha múltiplos data-frames isto pode não funcionar como esperado...
            IMap mapa = documento.FocusMap;

            // vamos contar quantas camadas temos no nosso mapa?
            Int32 numeroCamadas = mapa.LayerCount;

            // me diga quantas camadas eu tenho!
            MessageBox.Show("Temos neste mapa " + numeroCamadas.ToString() + " camadas!");
        }
</pre>
<p>Altere sua função OnClick nestes termos. Não copie e cole. Tente entender o que está acontencendo dentro do código. Digite linha por linha. Porque? Porque faz bem e o <em>Visual Studio</em> ainda irá mostrar para vocês a jóia de sua coroa, o <em>Intellisense</em>. Ele te sugere o que você <strong>pode </strong>estar precisando. Você conseguirá enxergar diversos atributos e propriedades de cada uma destas classes.</p>
<p>Tem bastante coisa interessante só nessas três classezinhas. Navegue. Use o <a rel="nofollow" target="_blank" title="EDN" href="http://edn.esri.com" target="_blank">EDN</a>. Use o <em>Help (</em>F1). E poste suas dúvidas.</p>
<p>Bem, agora é com vocês. Me digam o que acharam. Foi difícil? À princípio vai ser difícil sim! Como meu bom e velho avô diz: rapadura é doce mas não é mole não!</p>
<p>Estou no aguardo das dúvidas, comentários e blasfêmias!</p>
<p>Espero que tenham gostado,</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/diquinhas-de-arcgis-1/' rel='bookmark' title='Permanent Link: Diquinhas de ArcGIS #1'>Diquinhas de ArcGIS #1</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/06/brincando-com-arcobjects/' rel='bookmark' title='Permanent Link: Brincando com ArcObjects'>Brincando com ArcObjects</a></li>
<li><a href='http://blog.geoprocessamento.net/2010/05/arcgis-com-lancado/' rel='bookmark' title='Permanent Link: ArcGIS.com lançado'>ArcGIS.com lançado</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://blog.geoprocessamento.net/2010/02/hello-world-arcgis-style/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

