MapTools

TerraLib provides a basic set of tools for dealing with maps. You can extend this basic framework in order to have your own way of rendering and representing the concept of a map.

In this module you will find some useful concepts:

  • Canvas: a canvas is an abstraction of a drawing area.
  • Layer: a base class designed to support applications that handle information as layers. A layer is just a reference to the data (not the data itself) and can be used to logically organize it. The information about a layer can be stored in different medias (a XML file or a DBMS table) depending on the type of persistence choosed.
  • Renderer: a set of classes for rendering layers, geographical objects and other stuffs.
  • Project: an auxiliary class that can be used to split a set of layers… <color red>(não deve ser mais necessário)</color>
  • DataGrid: a base class representing the data table associated to a dataset.
  • MapDisplay: A helper class to control the display of a set of layers.

The data structures in this module are not bounded to a specific GUI nor a given data model. There are complementary modules that can be used to take advantage of thi module:

  • TerraLib Symbology Encoding Module
  • TerraLib Qt Widgets
  • TerraLib XML Persistence module
  • TerraLib DB Persistence module

Design Rationale

Examples

Canvas

Layer

Rendering

How to Extend MapTools

Remarks

Análise e ideias

  • Definição da classe AbstractRenderer
  • Inicialmente… método draw():
     AbstractRenderer::draw(AbstractLayer* l, Canvas* c, Envelope& bbox, int srid); 
  • Qual o papel de um Renderer?

Básico:

  1. Capaz de obter as geometrias do layer;
  2. Intepretação das regras (Rules) definidas no estilo. Inclui a decodificação das expressões de restrição <Filters>;
  3. Interpretação dos Symbolizers e ajuste dos parâmetros visuais no Canvas;
  4. Transformação de coordenadas / projeção?
  5. (2) e (3): Utilização do padrão Visitor?
// Something like that...
LayerRenderer::draw(Layer* layer, Canvas* canvas, const te::gm::Envelope& bbox, int srid)
{
  // Gets the associated data source
  te::da::DataSource* ds = layer->getDataSource();
 
  // Gets a transactor!
  te::da::DataSourceTransactor* t = ds->getTransactor();
 
  // What is the data set?
  std::string dsname = layer->getDataSetName();
  // or
  size_t idx = layer->getDataSet();
 
  // Gets the style and rules
  Style* style = layer->getStyle();
  std::vector<Rule*> rules = style->getRules();
  for(unsigned int i = 0; i < rules.size(); i++) // for each rule
  {
    Rule* r = rules[i];  
 
    /* Gets the objects that obey the rule's restriction. 
       Case there isn't restriction, gets all objects! */
 
    /* Here should be called the transactor query() method. 
       It is necessary interprets the <Rule> elements included on Style.
       For now, gets the data set using only box restriction. */
    te::da::DataSet* dataset = t->getDataSet(dsname, &bbox, te::gm::SpatialRelation::INTERSECTS);
 
    // Gets the symbolizers
    std::vector<Symbolizer*> symbs = r->getSymbolizers();
    for(unsigned int i = 0; i < symbs.size(); i++) // for each symbolizer
    {
      /* Sets the graphics parameters on canvas
         and for each geometry, let´s draw! */
 
      /* For while, Default Geometry.
         How can we get anothers or a specified, for example? 
         And others data sets (dataset->getDataSet())? 
         Uses <Geometry> element? */
      te::gm::Geometry* g = dataset->getGeometry();
 
      // Verifies the SRID. Case different, converts coordinates...
 
      canvas->draw(g);
 
      delete g;
    }
  }
  delete t;
}
  • A especificação SE permite que atributos de visual (ex.: a expessura da linha, tamanho de uma imagem, etc.) sejam definidos com base em atributos dos objetos. Mais ainda, podem ser definidos a partir de uma expressão. Por exemplo, no desenho de um dado Rodovias, é possível definir a expessura de cada linha a partir do atributo numero_de_pistas. Como esta questão pode ser tratada?
  • Revisar a interface AbstractLayer, métodos e atributos;
  • Atualmente, um layer possui um Style. É interessante a criação de um novo nível chamado StyledLayer para associar um estilo + layer? Ou então, definição de um método AbstractLayer::draw(Style* s)? Implica em…
     AbstractRenderer::draw(AbstractLayer* l, Style* s, Canvas* c, Envelope& bbox, int srid); 

Basicamente, permite sobreescrever um estilo pré-determinado…

  • Pensando no caso mais simples, o DataSetLayer:
  1. Aponta um DataSource, ok? Qual DataSet o layer referencia? Carregar o nome (std::string) resolve. Ou ainda, o index associado (+ rápido)…
  2. É necessário a utilização de um Filter separado das restrições que podem ser definidas nas Rules?
  3. Sendo possível sub-layers, quem é responsável pelo desenho deles? O próprio layer?
  • É interessante (é possível), neste nível, fornecer métodos utilizados geralmente para análise? Por exemplo: interseção, diferença, união, etc. entre dois layers. Temos no Geometry:
    Geometry* result = g1->intersection(g2);
    // ......
    AbstractLayer* result = l1->intersection(l2); // ?
  • Discutir e definir a classe base MapDisplay. Alguns pontos:
  1. Possui um conjunto de layers e;
  2. um conjunto de canvas?
  3. Qual o melhor modo de trabalhar com estas duas classes?
  4. Define a ordem de exibição das camadas?
  5. Responsável pelo desenho dos sub-layers?
  • Construção de uma classe base AbstractMapDisplay sem atributos e com a definição de alguns métodos para controle e configuração;
  • Podemos fornecer uma classe concreta básica que implementa uma estratégia, ou seja, um modo de trabalhar com as questões apontadas acima.
  • É o melhor? Se não, o 'insatisfeito' pode estender direto o Abstract…
  • Urgente! É necessário implementar a tradução de um objeto <Filter> para o nosso Query. Só assim, será possível fazer o join das restrições e repassar ao Transactor. Desse modo, eliminamos o QueryLayer do modo que está implementado…

QR Code
QR Code wiki:designimplementation:maptools (generated for current page)