OpenLayers: objeto Feature. Que bicho é este?

Publicado: 08/07/2013 em Programação, Serviços IP
Tags:, ,

1. Introdução
Podemos afirmar que a feature é a centralidade da biblioteca OpenLayers. Ou de outra forma, a feature é o elemento central quando estamos trabalhando com GIS no client-side. O que se deseja, em última instância sob o ponto de vista client-side, é mostrar pontos, retas e polígonos no mapa e interagir com estes objetos geométricos. Ou seja, é trabalhar com as features.

Forma-se uma estrutura hierárquica: no mais baixo nível temos a geometria (o ponto, a reta, o polígono); quando a esta geometria são agregados os estilos e atributos constitui-se o objeto feature; a feature deverá ser incluída em um layer vetorial e, por último, esse layer será incluído no mapa. Com isto a feature ficará visível no mapa.

O processo de inclusão da feature no layer vetorial vem acompanhada de regras e filtros, possibilitando a este layer “impor” regras e não aceitar a inclusão de qualquer feature. Adicionalmente, essa feature pode ser manipulada por um conjunto de facilidades de controle (ou interação). É sobre esta dinâmica que trataremos neste post.

2. Do objeto geométrico ao mapa
2.1 A Geometria
Começando, a geometria é o nível mais baixo da cadeia. A geometria é um objeto vetorial, representada por uma classe que faz a descrição do objego geográfico. Esta classe, OpenLayers.Geometry, é responsável por armazenar a informação geográfica, além de ser o fundamento das features (como veremos mais adiante neste post).

A classe básica da geometria é a “OpenLayers.Geometry” (que chamaremos genericamente por “Geometry Class”). Mas existem diversas subclasses:
OpenLayers.Geometry.Point
OpenLayers.Geometry.LinearRing
OpenLayers.Geometry.LineString
OpenLayers.Geometry.MultiLineString
OpenLayers.Geometry.Polygon
e outras.

A “Geometry Class” possui diversos métodos, conforme pode ser visto no manual do OpenLayers. Veja a utilização prática de dois destes métodos:
a) Método distanceTo
O método distanceTo trabalha em medidas planares o qual assume o mundo como um plano usando coordenadas cartesianas.
A resposta será dada em graus. Para transformar o resultado para km: km = dist * 60 * 1.8520
Veja o exemplo:
var dist = geom_point1.distanceTo(geom_point2);

b) Método clone
Como o próprio nome já sugere, utilizada para clonar geometrias. Por exemplo:
var geom_point3 = geom_point1.clone();

2.2 A constituição de uma feature
Visto a geometria, chegamos ao conceito de feature. A idéia que está por traz do conceito de uma feature é a de representação dos elementos do mundo real através do GIS. Uma feature pode ser uma cidade, uma rodovia, uma estrada de ferro, uma região, um lago, a fronteira de um país e muito mais.

Cada feature é representada visualmente através de um símbolo geométrico: ponto, linha, polígono, um ícone, etc; possui um conjunto de atributos: população, tamanho e assim por diante; e usa algum estilo visual: cor, raio, largura, etc. Ou seja, cada feature possui geometria + atributos + style. A feature class está definida através da classe OpenLayers.Feature.Vector (como dito, a feature é um objeto vetorial), onde tem propriedades obrigatórias e opcionais:

Propriedade Descrição
geometry objeto geometry: é obrigatório, composto pela classe OpenLayers.Geometry.
atributes objeto attributes: opcional, contendo arbitrárias e serializadas propriedades que descrevem a feature
style objeto style: opcional. Não sendo definido, o OpenLayers utiliza seu estilo default.

Estrutura de criação (instanciação) de uma feature:
var nome_feature = new OpenLayers.Feature.Vector (geometry_object, {atributo-1_object,…,atributo-n_object},style_object);

As “features” (novamente: que são objetos vetoriais) devem pertencer a algum layer vetorial para poderem ficar visiveis no mapa. Ou seja, as features precisam ser adicionadas a algum layer vetorial. Assim, lembramos outra vez o conceito da estrutura hierárquica: “vector class” faz uso da “feature class” para possibilitar a visualização da feature no mapa. Por sua vez, para a “feature class” funcionar é necessário a utilização da “geometry class”.

Quanto a subclass: só existe uma única subclass da classe Feature: Feature.Vector

2.3 Incluir a feature no Mapa
Para colocar um objeto feature em um layer vetorial, faz-se uso da função pertencente a classe OpenLayers.Layer.Vector entitulada “addFeatures“:
addFeatures(Array{OpenLayers.Feature.Vector},option_object);
Onde:
– Array{OpenLayers.Feature.Vector}: lista de features para serem adicionadas.
– option_object: propriedades opcionais para alterar o comportamento da inclusão da feature no layer vetorial.

Exemplos:
map.layers[1].addFeatures ([nome_feature-1,….,nome_feature-n]);
layer_vetorial.addFeatures([feature-1,feature-2,feature-3]);

2.4 Uma demonstração prática desta sequência
Como dito, devem ser cumpridas 3 etapas para se ter o objeto geométrico representado no mapa: criar a geometria do ponto, associar esta geometria a uma feature e, por fim, adicionar a feature ao mapa. Vejamos estas etapas em exemplo prático:

a) Criar objetos geométricos
var geom_point1 = new OpenLayers.Geometry.Point(-53,-17);
var geom_point2 = new OpenLayers.Geometry.Point(-55,-15);
var geom_line1 = new OpenLayers.Geometry.LineString([geom_point1,geom_point2]);

b) Criar Features
var feature_point1 = new OpenLayers.Feature.Vector(geom_point1,{‘localizacao’:’lago Paranoá’,’descricao’:’muita água, muito bonito!’});
var feature_point2 = new OpenLayers.Feature.Vector(geom_point2);
var feature_line1 = new OpenLayers.Feature.Vector(geom_line1);

c) Adicionar Features ao Layer Vetorial, e tudo estar visivel no mapa
var layer_vetorial = new OpenLayers.Layer.Vector(‘Layer Testes Geometria’);
layer_vetorial.addFeatures([feature_point1,feature_point2,feature_line1]);
map.addLayer(layer_vetorial);

3. Interatividade
Para fazer alguma coisa acontecer quando do clicking do mouse sobre uma feature, há necessidade de se usar a classe selectFeature control: OpenLayers.Control.SelectFeature.

A classe de controle (ou de interatividade, como se queira) OpenLayers.Control.SelectFeature está associada a um determinado layer vetorial, e destina-se a selecionar objetos features deste layer quando do click do mouse ou o hover. Para se criar (instanciar) um objeto SelectFeature control, deve-se fazer:

var select_feature = new OpenLayers.Control.SelectFeature(vector_layer,{});
obs: vê-se que a classe está associada a um layer vetorial, no caso “vector_layer”. O espaço entre chaves deve ser preenchido com as propriedades desta classe (mas é opcional!).
Na forma como está, a feature já será selecionada no mapa e destacada das demais com um style de destaque default do OpenLayers. Nos exemplos abaixo mostraremos como melhorar o tratamento da(s) feature(s) destacada(s), através de comportamentos mais rebuscados ou com funções listeners de tratamento.

Algumas propriedades da classe SelectFeature control (consultar o manual para visão completa):

Propriedade Descrição
box {Boolean} Permite a seleção de features através do desenho de uma caixa.
clickout {Boolean} Deseleciona as features quando do clicking fora de qualquer feature.
events Classe {OpenLayers.Events} Instancia de eventos para listeners e controle de triggering dos eventos.
hover {Boolean} Seleciona quando o mouse estiver sobre a fearture e deseleciona quando o mouse sair da feature.
multiple {Boolean} Permite a seleção de múltiplas geometrias.
togle {Boolean} Deseleciona uma feature selecionada quando do click.
onSelect / onUnselect {Function} Função opcional para ser chamada quando uma feature for selecionada / deselecionada.
…. e outras

Também existem métodos sobre a classe SelectFeature control: como esta é uma classe de controle, este controle pode ser ativado ou desativado por funções em tempo de execução:

  • Activate – ativa o controle
  • Deactivate – desativa o controle

Exemplo:

var select_feature = new OpenLayers.Control.SelectFeature(
        layer_vetorial, 
        {
               multiple: false,
               toggle: true,
               toggleKey: 'ctrlKey',
               multipleKey: 'shiftKey' 
        }
);
map.addControl(select_feature); 
select_feature.activate();  // ativar o controle

Pelo exemplo acima, vemos a criação de um objeto de manipulação das features que pertencem ao  “layer_vetorial”, com 4 propriedades de funcionamento. Este objeto de interatividade (ou controle, como se queira) fora adicionado ao mapa e ativado. Ou seja, está em funcionamento.

3.1 Eventos
A classe SelectFeature control possui entre as suas propriedades a classe evento, como visto acima. Veja a seguir um exemplo de como utilizar esta propriedade:

		  	// Criar um layer vetorial
var layer_vetorial = new OpenLayers.Layer.Vector('Layer Testes Geometria');
var select_fc = new OpenLayers.Control.SelectFeature( 
       layer_vetorial,	// Adicionar interatividade com as features do layer vetorial
       {
            multiple: false,
            toggle: true,
            toggleKey: 'ctrlKey',
            multipleKey: 'shiftKey' 
        }
);
			// Criar as funções "listeners"
function selected_feature(event)  { alert("Feature selecionada",  feature.id);};
function unselected_feature(event){ alert("Feature deselecionada",feature.id);};
			// Registrar os eventos pertencentes as features do layer_vetorial
layer_vetorial.events.register('featureselected', this, selected_feature);
layer_vetorial.events.register('featureunselected', this, unselected_feature);
			// Adicionar o controle da interatiidade ao mapa e ativá-lo
map.addControl(select_fc);
select_fc.activate();

O que vemos? Sobre o layer vetorial adicionou-se interatividade (selecionar/deselecionar features), e criou-se listeners para tratamentos adicionais.

4. Firebug
O Firebug pode ser uma ferramenta essencial para fazer o debug dos scripts Javascript desenvolvidos, pois facilita o acesso as informações contidas em um Layer Vetorial e disponibiliza comandos. Utilizar o Firebug é muito fácil, pois é só usar as mesmas instruções do script desenvolvido, conforme se pode ver pelos exemplos abaixo:
map.layers
map.layers[3]
map.layers[1].features
map.layers[1].features[3]
map.layers[1].features[2].geometry
map.layers[1].features[2].attributes
map.layers[1].getFeatureByID(‘OpenLayers.Feature.Vector_342′)
map.layers[1].addfeatures([feature_point1])
map.layers[1].features[0].destroy()
map.layers[1].destroyFeatures([map.layers[1].features[0]])

Veja também o post Debug de scripts com Firefox.

Referências:
1- OpenLayers: API Documentation
2- OpenLayers Library Documentation
Veja Também:
3- Um pouco de OpenLayers, Geoserver e PostGis
4- Um exemplo de script utilizando a classe OpenLayers.Control.SelectFeature

Anúncios
comentários
  1. Legal! Bom posto. Vi que você usa “feature” várias vezes. Esse termo não tem uma tradução? Ele é usado assim mesmo? Estou com dificuldade de compreender o significado. Obrigado!

    • Albuquerque disse:

      Daniel, deixei feature pois está assim na literatura da língua internacional. Mas podemos traduzir por feição, ou figura geométrica. Uma “feature” é um ente vetorial que tem uma geometria (localização e dimensões, podendo ser basicamente um ponto, uma linha ou um polígono), possui um estilo (ícone, cor, transparência….) e atributos literais (que podem ser quaisquer). Espero ter ajudado um pouquinho.

  2. Estou adorando o seu Blog. Mais didático, impossível! A partir de hoje vou acompanhar seus posts sobre OpenLayers ou sobre qualquer coisa que se refira a SIG de uma forma geral. Parabéns!

Deixe um comentário, pois isto é muito motivante para continuarmos este trabalho

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s