Blog Geo.NET Geoprocessamento, SIG e Sensoriamento Remoto

30Jun/100

Brincando com ArcObjects #2

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 anéis, as polilinhas são formadas por uma coleção de caminhos (paths).

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.

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 ArcGIS irá entender como um polígono.

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;
}
Polígono construído com o código anterior

Polígono construído com o código anterior


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.

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;
}

Polígono simples criado pelo código acima

Polígono simples criado pelo código acima (fora de escala)

Bem, é fácil trabalhar com geometrias da ESRI. 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 ArcObjects fica responsável por notificar a geometria original de que certa operação ocorreu e a realiza de acordo.

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.

Certo, mas e um polígono que contenha curvas? O formato shapefile não suporta(va) o desenho delas e estão disponíveis à partir dos geodatabases (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ó.

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.

Para construir segmentos curvos, existem diversas interfaces do tipo IConstruct* (IConstructCircularArc, IConstructBezierCurve, etc.), cada uma com suas particularidades.

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);
Polígono resultante do código acima

Polígono resultante do código acima

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.

Outra coisa legal é ver que para acessar alguns métodos, você tem que instanciar certas interfaces. Notem que o finalRing e ring1 possuem propriedades semelhantes, pois têm a mesma interface. Já ring2 possui outros membros, pois é de interface diferente. Classes iguais, interfaces diferentes = propriedades diferentes.

E aí, o que acharam?

Abraços pessoal!

George R. C. Silva

18Jun/100

Configure o TerraLib 3.3 no Visual Studio 2003

Boa noite pessoal,

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

1 - Requisitos para executar os exemplos

  • Visual Studio C++ 2003;
  • MySQL Administrator 5.o;
  • Driver MySQL para Windows;
  • Banco de Dados MySQL 5.1;
  • Biblioteca TerraLib para Windows, 3.3 ou superior;

2 - Instruções gerais de instalação

O primeiro software a instalar é o Visual Studio 2003. Utilize a instalação personalizada e desmarque o suporte a todas as outras linguagens diferentes do C++, por exemplo: C# e VB. A seguir, instale o MySQL, Driver do MySQL e o MySQL Administrator.

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.

Árvore de pastas do TerraLib

Árvore de pastas do TerraLib

3 - Compilando a biblioteca TerraLib

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.

1) File/Open project/ ou Ctrl+Shift+O
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.

2) Build/Build Solution ou Ctrl+Shitf+B
Build Sucessfull -> Essa mensagem é indício que está indo tudo muito bem, parabéns!

Faça este mesmo procedimento para todas as bibliotecas abaixo na ordem que estão listadas.

  • createLayer;
  • createTable;
  • importMIDMIF;
  • importShape;
  • importDBF;
  • importJPEG;
  • copyLayer;
  • importGeoTab;
  • convertCoordinates;
  • databaseQuery;
  • databaseSQLQuery;
  • spatialQuery;
  • addGeomRepresentation;
  • createTheme;
  • themeGrouping;
  • createSTElementSet;
  • mosaicTIFFImages;
  • importCSV;
  • importGridData;
  • rasterSlicing;
  • querierFromTheme;
  • proxMatrixAndSpatialStatistics;
  • spatialQueryAndBuffer;
  • querierFromLayer;
  • createSTElementSetFromLayer;
  • image_processing.

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.

4 - Configurar o projeto

Este tutorial ficará limitado em explicar detalhadamente apenas os passos necessários para criar um projeto.

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.

Criar um novo projeto

Criar um novo projeto

 Escolha o template Console Application (.NET), conforme imagem 3.

Figura 3 - Escolher Template

Figura 3 - Escolher Template

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.

Figura 04  - Adicionar projeto existente

Figura 04 - Adicionar projeto existente

Figura 05 - Adicionar projeto existente  (2° passo)

Figura 05 - Adicionar projeto existente (2° passo)

Figura 06 - Adicionar projeto existente (3° passo)

Figura 06 - Adicionar projeto existente (3° passo)

Figura 07 - Adicionar projeto existente (4° passo)

Figura 07 - Adicionar projeto existente (4° passo)

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.

Além desses três projetos que foram incorporados ao projeto PrimeiroExemplo, outros projetos do TerraLib poderão ser agregados conforme a necessidade.

O procedimento a seguir objetiva configurar o projeto PrimeiroExemplo. Clique nas propriedades do projeto, conforme na figura 08.

Figura 08 - Propriedades do Projeto

Figura 08 - Propriedades do Projeto

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.

.;..\..\src\terralib\kernel;..\..\src\terralib\drivers\MySQL;..\..\src\terralib\drivers\MySQL\include

Figura 09 - Adicionar Diretórios Adicionais

Figura 09 - Adicionar Diretórios Adicionais

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.

Figura 10 - Desabilite os precompiled headers

Figura 10 - Desabilite os precompiled headers

Figura 11 - Additional dependencies

Figura 11 - Additional dependencies

../../Debug/terralib/terralib.lib ../../Debug/libjpeg/libjpeg.lib ../../Debug/tiff/tiff.lib

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

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.

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.

Figura 12 - Adicionar itens existentes do 1° passo

Figura 12 - Adicionar itens existentes do 1° passo

Figura 13 - Adicionar Itens existentes (2° passo)

Figura 13 - Adicionar Itens existentes (2° passo)

 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.

Figura 14 - Arquivos existentes da biblioteca

Figura 14 - Arquivos existentes da biblioteca

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.

Ao final de todos esses procedimentos, realize um build de todo o projeto PrimeiroProjeto para certificarmos que todos as configurações estão corretas.

5 – Codificar o primeiro exemplo

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.

Figura 15 - Alterando a classe PrimeiroExemplo.cpp

Figura 15 - Alterando a classe PrimeiroExemplo.cpp

#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->newDatabase(dbname,user, password, host))
	{
	cout << "Erro: " << db->errorMessage() << endl;
	return 1;
	} 

	cout << "O banco de dados \"" << dbname;
	cout <<"\" foi criado com sucesso no servidor MySQL localizado em\""
		<< host;
	cout << "\" para o usuario \"" << user << "\"!"  << endl;  	// Fecha o banco de dados  	db->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->connect(host,user, password,dbname,0))
	{
	cout<< "Erro: " << db->errorMessage() << endl;
	return 0;
	}
	cout << "Aberta conexão ao banco: " << dbname;
             db->close();
	delete db;
  }

É isso aí pessoal! O que acharam? Abraços e comentem!

João Tácio Silva

Tagged as: , , , No Comments
8Feb/100

Hello World, ArcGIS style!

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 faz. Isto é trabalho de vocês.
  • Irei ajudar na parte mais difícil: como começar. Existem algumas coisinhas que são chatíssimas quando programamos para ArcGIS, mas ainda bem que o próprio Visual Studio resolve algumas delas para nós.

Início

Primeiramente, abra o Visual Studio e peça um New Project. Selecione um Empty Project e dê um nome para seu projeto.

Criando um novo projeto

Criando um novo projeto no Visual Studio 2005

Depois de isso feito, termos algo mais ou menos assim:

Projeto vazio

Projeto vazio

O Visual Studio é extremamente personalizável, portanto não precisa se concentar em deixar sua tela exatamente igual a minha. Quero que você veja o Solution Explorer que fica à direita.

Vamos para o rock. O que iremos fazer?

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.

Então vamos lá. Vá na raiz do projeto (escrito HelloWorldArcGIS) e clique com o botão direito. Clique em Add ArcGIS Reference.

O que isto exatamente faz? 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 não iremos utilizar?

Certo, quando você clicar no botãozinho, irá aparecer uma janelinha. Vá na opção Desktop ArcMap e adicione as seguintes assemblies:

  • ESRI.ArcGIS.ArcMapUI;
  • ESRI.ArcGIS.ArcMap;
  • ESRI.ArcGIS.Display;
  • ESRI.ArcGIS.Framework;
  • ESRI.ArcGIS.Geodatabase;
  • ESRI.ArcGIS.System;
  • ESRI.ArcGIS.Carto;

Clique em Finish.

Você verá que a pasta References foi atualizada. Vamos adicionar algumas assemblies do Windows e do .NET.

Siga o mesmo passo acima, mas ao invés de escolher Add ArcGIS Reference, escolha Add Reference. Uma caixinha irá se abrir, portanto em .NET, seleciona as seguintes assemblies:

  • System
  • System.Drawing
  • System.Windows.Forms

Clique ok. Estamos good to go.

Nossas referências estão no lugar. Isto significa que poderemos utilizar código pronto contido nestas assemblies. Isto é importante e interessante que se aprenda cedo, senão algo pode deixar de funcionar simplesmente porque você nao colocou aquela referência...

Vamos agora criar uma barra de ferramentas para colocar nossas coisinhas nela.

Clique com o botão direito na raiz do projeto e clique em Add > Add New Item.

Adicionando uma barra de ferramentas

Adicionando uma barra de ferramentas

Selecione Base Toolbar e dê um nome à esta toolbar. Algo como HelloWorldToolbar, e clique em Add. Um tela irá aparecer perguntando qual tipo de barra de ferramentas você quer. Selecione ArcMap e boa.

Olhe suas referências. Elas foram atualizadas e adicionados alguns assemblies extras. Não se preocupe com eles. O Visual Studio é até inteligente para colocar algumas que você pode ter esquecido, mas só pelos canais oficiais (como este de adicionar uma toolbar). Se você criar uma classe e tentar herdar de BaseToolbar você provavelmente ganhará um erro.

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:

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";
            }
        }
    }
}

Vamos lá:

O que merece nota imediata:

  • 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 comments com carinho.
  • 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 ArcGIS.
  • A propriedade Name. Deve ser único. Portanto, é melhor nem mexer com isto, por enquanto.
  • 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 nada.

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

Mais uma vez um prompt irá aparecer e te perguntar qual é o tipo de comando você quer criar. Vejamos...escolha Desktop ArcMap Command e boa.

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
    }
}

Pontos merecedores de notas:

  • Novamente o construtor do comando. Ele tem diversas informações que são mostradas ao usuário no ArcGIS. Não irei explicar uma à uma, brinque com elas e teste.
  • Um campo (field) 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.
  • Método OnClick(). Este método é que irá rodar quando o usuário clicar no comando. Nós implementaremos as coisinhas todas ali. Capiche?

Vamos adicionar nosso comando à barra de ferramentas. Lembram do construtor da barra de ferramentas, que contém alguns exemplos de Add?

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.

    AddItem(new Guid("2423ecdf-4f14-4993-a165-df9d79167f4d"), 0);

Vamos tentar compilar. Aperte F6.

Um erro deve aparecer. Ainda não configuramos nossa aplicação para abrir com o ArcMap. Vá na raiz do projeto, clique com o botão direito e vá em Properties.

Você irá ver um monte de coisas.

Na parte de Application procure Output Type e escolha Class Library.

Em Build marque a última opção, Register for COM Interop. Lembra que tudo que fazemos com ArcObjects temos que fazer com COM? Ficou estranho isso, mas válá.

Vá em DEBUG e procure a seção Start Action. Marque Start External Program e localize o arquivo ArcMap.exe no seu computador. O meu fica em C:\Program Files\ArcGIS\bin\ArcMap.exe.

Tente compilar novamente. Aperte F6. Você não deve ver nenhum erro. O ArcGIS irá abrir sozinho.

ArcGIS aberto e barra de ferramenta disponível

ArcGIS aberto e barra de ferramenta disponível

Nossa barrinha de ferramentas esta lá!

Agora vamos implementar a nossa super-ultra-mega-complexa funcionalidade. Feche o ArcMap. Retorne ao Visual Studio.

Abra o arquivo de código do nosso comando. Suba até o topo de nosso arquivo.

Você verá um monte de coisas como using System.Drawing entre outros. Aqui nós dizemos ao Visual Studio quais assemblies este arquivo poderá acessar. Faltam duas importantes para nós aí.

Insira a assembly ESRI.ArcGIS.Carto e a assembly System.Windows.Forms. Lembre-se de colocar cada uma em uma linha, e não se esqueça do ponto-e-vírgula.

        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!");
        }

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 Visual Studio ainda irá mostrar para vocês a jóia de sua coroa, o Intellisense. Ele te sugere o que você pode estar precisando. Você conseguirá enxergar diversos atributos e propriedades de cada uma destas classes.

Tem bastante coisa interessante só nessas três classezinhas. Navegue. Use o EDN. Use o Help (F1). E poste suas dúvidas.

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!

Estou no aguardo das dúvidas, comentários e blasfêmias!

Espero que tenham gostado,

Um abraço,

George R. C. Silva

   
Get Adobe Flash playerPlugin by wpburn.com wordpress themes