All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AbstractLayerRenderer.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/maptools/AbstractLayerRenderer.cpp
22 
23  \brief It renders the objects associated to an abstract layer. i.e. a generic renderer.
24 */
25 
26 // TerraLib
27 #include "../color/RGBAColor.h"
28 #include "../common/progress/TaskProgress.h"
29 #include "../common/Globals.h"
30 #include "../common/STLUtils.h"
31 #include "../common/Translator.h"
32 #include "../dataaccess/dataset/DataSet.h"
33 #include "../dataaccess/dataset/DataSetType.h"
34 #include "../dataaccess/query/And.h"
35 #include "../dataaccess/query/EqualTo.h"
36 #include "../dataaccess/query/GreaterThanOrEqualTo.h"
37 #include "../dataaccess/query/LessThanOrEqualTo.h"
38 #include "../dataaccess/query/LiteralDouble.h"
39 #include "../dataaccess/query/LiteralEnvelope.h"
40 #include "../dataaccess/query/LiteralString.h"
41 #include "../dataaccess/query/PropertyName.h"
42 #include "../dataaccess/query/ST_Intersects.h"
43 #include "../dataaccess/utils/Utils.h"
44 #include "../fe/Filter.h"
45 #include "../geometry/Coord2D.h"
46 #include "../geometry/Envelope.h"
47 #include "../geometry/GeometryProperty.h"
48 #include "../raster/Raster.h"
49 #include "../raster/RasterProperty.h"
50 #include "../se/FeatureTypeStyle.h"
51 #include "../se/CoverageStyle.h"
52 #include "../se/Rule.h"
53 #include "../se/Utils.h"
54 #include "../srs/Config.h"
55 #include "AbstractLayer.h"
56 #include "AbstractLayerRenderer.h"
57 #include "Canvas.h"
58 #include "CanvasConfigurer.h"
59 #include "Chart.h"
60 #include "ChartRendererManager.h"
61 #include "Exception.h"
62 #include "Grouping.h"
63 #include "GroupingItem.h"
64 #include "QueryEncoder.h"
65 #include "Utils.h"
66 
67 // Boost
68 #include <boost/format.hpp>
69 #include <boost/lexical_cast.hpp>
70 
71 // STL
72 #include <cassert>
73 #include <cstdlib>
74 #include <memory>
75 #include <utility>
76 
77 
78 
80  : m_index(0)
81 {
82 }
83 
85 {
86 }
87 
89  Canvas* canvas,
90  const te::gm::Envelope& bbox,
91  int srid)
92 {
93  if(!bbox.isValid())
94  throw Exception(TR_MAP("The requested box is invalid!"));
95 
96  assert(layer);
97  assert(canvas);
98 
99  // Check if layer extent intersects the drawing area and so compute bounding box intersection
100  te::gm::Envelope reprojectedBBOX(bbox);
101 
102  if((layer->getSRID() != TE_UNKNOWN_SRS) && (srid != TE_UNKNOWN_SRS))
103  {
104  reprojectedBBOX.transform(srid, layer->getSRID());
105 
106  if(!reprojectedBBOX.isValid())
107  throw Exception(TR_MAP("The reprojected box is invalid!"));
108  }
109  else if(layer->getSRID() != srid)
110  {
111  throw Exception(TR_MAP("The layer or map don't have a valid SRID!"));
112  }
113 
114  if(!reprojectedBBOX.intersects(layer->getExtent()))
115  return;
116 
117  // Adjust internal renderer transformer
118  m_transformer.setTransformationParameters(bbox.m_llx, bbox.m_lly, bbox.m_urx, bbox.m_ury, canvas->getWidth(), canvas->getHeight());
119 
120  // Resets internal renderer state
121  reset();
122 
123  te::gm::Envelope ibbox = reprojectedBBOX.intersection(layer->getExtent());
124 
125  assert(ibbox.isValid());
126 
127  // Gets the layer schema
128  std::auto_ptr<LayerSchema> schema(layer->getSchema());
129  assert(schema.get());
130 
131  if(schema->hasGeom())
132  {
133  // For while, first geometry property. TODO: need a visitor to get which spatial properties the layer style references
134  te::gm::GeometryProperty* geometryProperty = te::da::GetFirstGeomProperty(schema.get());
135 
136  /** For while if the AbstractLayer has a grouping, do not consider the style. Need review! **/
137  Grouping* grouping = layer->getGrouping();
138  if(grouping && grouping->isVisible())
139  {
140  drawLayerGroupingMem(layer, geometryProperty->getName(), canvas, ibbox, srid);
141  return;
142  }
143 
144  // Gets the layer style
145  te::se::Style* style = layer->getStyle();
146  if(style == 0)
147  {
148  // Try create an appropriate style. i.e. a FeatureTypeStyle
149  style = te::se::CreateFeatureTypeStyle(geometryProperty->getGeometryType());
150 
151  if(style == 0)
152  throw Exception((boost::format(TR_MAP("Could not create a default feature type style to the layer %1%.")) % layer->getTitle()).str());
153 
154  layer->setStyle(style);
155  }
156 
157  // Should I render this style?
158  te::se::FeatureTypeStyle* fts = dynamic_cast<te::se::FeatureTypeStyle*>(style);
159  if(fts == 0)
160  throw Exception(TR_MAP("The layer style is not a Feature Type Style!"));
161 
162  drawLayerGeometries(layer, geometryProperty->getName(), fts, canvas, ibbox, srid);
163  }
164  else if(schema->hasRaster())
165  {
166  // For while, first raster property. TODO: need a visitor to get which spatial properties the layer style references
167  te::rst::RasterProperty* rasterProperty = te::da::GetFirstRasterProperty(schema.get());
168 
169  // Get the layer style
170  te::se::Style* style = layer->getStyle();
171  if(style == 0)
172  {
173  // Try create an appropriate style. i.e. a CoverageStyle
174  style = te::se::CreateCoverageStyle(rasterProperty->getBandProperties());
175 
176  if(style == 0)
177  throw Exception((boost::format(TR_MAP("Could not create a default coverage style to the layer %1%.")) % layer->getTitle()).str());
178 
179  layer->setStyle(style);
180  }
181 
182  // Should I render this style?
183  te::se::CoverageStyle* cs = dynamic_cast<te::se::CoverageStyle*>(style);
184  if(cs == 0)
185  throw Exception(TR_MAP("The layer style is not a Coverage Style!"));
186 
187  // Retrieves the data
188  std::auto_ptr<te::da::DataSet> dataset = layer->getData(rasterProperty->getName(), &ibbox, te::gm::INTERSECTS);
189 
190  if(dataset.get() == 0)
191  throw Exception((boost::format(TR_MAP("Could not retrieve the data set from the layer %1%.")) % layer->getTitle()).str());
192 
193  std::size_t rpos = te::da::GetFirstPropertyPos(dataset.get(), te::dt::RASTER_TYPE);
194 
195  // Retrieves the raster
196  std::auto_ptr<te::rst::Raster> raster(dataset->getRaster(rpos));
197  if(dataset.get() == 0)
198  throw Exception((boost::format(TR_MAP("Could not retrieve the raster from the layer %1%.")) % layer->getTitle()).str());
199 
200  // Let's draw!
201  DrawRaster(raster.get(), canvas, ibbox, layer->getSRID(), bbox, srid, cs);
202  }
203  else
204  {
205  throw Exception(TR_MAP("The layer don't have a geometry or raster property!"));
206  }
207 }
208 
210  const std::string& geomPropertyName,
212  Canvas* canvas,
213  const te::gm::Envelope& bbox,
214  int srid)
215 {
216  assert(!geomPropertyName.empty());
217 
218  // Creates a canvas configurer
219  CanvasConfigurer cc(canvas);
220 
221  // Number of rules defined on feature type style
222  std::size_t nRules = style->getRules().size();
223 
224  for(std::size_t i = 0; i < nRules; ++i) // for each <Rule>
225  {
226  // The current rule
227  te::se::Rule* rule = style->getRule(i);
228  assert(rule);
229 
230  // TODO: Should be verified the MinScaleDenominator and MaxScaleDenominator. Where will we put the current scale information? Method parameter?
231 
232  // Gets the rule filter
233  const te::fe::Filter* filter = rule->getFilter();
234 
235  // Let's retrieve the correct dataset
236  std::auto_ptr<te::da::DataSet> dataset(0);
237 
238  if(!filter)
239  {
240  try
241  {
242  // There isn't a Filter expression. Gets the data using only extent spatial restriction...
243  dataset = layer->getData(geomPropertyName, &bbox, te::gm::INTERSECTS);
244  }
245  catch(std::exception& /*e*/)
246  {
247  continue; // TODO: deal the exceptions!
248  }
249  }
250  else
251  {
252  try
253  {
254  // Gets an enconder
255  te::map::QueryEncoder filter2Query;
256 
257  // Converts the Filter expression to a TerraLib Expression!
258  te::da::Expression* exp = filter2Query.getExpression(filter);
259  if(exp == 0)
260  throw Exception(TR_MAP("Could not convert the OGC Filter expression to TerraLib expression!"));
261 
262  /* 1) Creating the final restriction. i.e. Filter expression + extent spatial restriction */
263 
264  // The extent spatial restriction
265  te::da::LiteralEnvelope* lenv = new te::da::LiteralEnvelope(bbox, layer->getSRID());
266  te::da::PropertyName* geometryPropertyName = new te::da::PropertyName(geomPropertyName);
267  te::da::ST_Intersects* intersects = new te::da::ST_Intersects(geometryPropertyName, lenv);
268 
269  // Combining the expressions (Filter expression + extent spatial restriction)
270  te::da::And* restriction = new te::da::And(exp, intersects);
271 
272  /* 2) Calling the layer query method to get the correct restricted data. */
273  dataset = layer->getData(restriction);
274  }
275  catch(std::exception& /*e*/)
276  {
277  continue; // TODO: deal the exceptions!
278  }
279  }
280 
281  if(dataset.get() == 0)
282  throw Exception((boost::format(TR_MAP("Could not retrieve the data set from the layer %1%.")) % layer->getTitle()).str());
283 
284  if(dataset->moveNext() == false)
285  continue;
286 
287  // Gets the set of symbolizers defined on current rule
288  const std::vector<te::se::Symbolizer*>& symbolizers = rule->getSymbolizers();
289 
290  // Builds task message; e.g. ("Drawing the layer Countries. Rule 1 of 3.")
291  std::string message = TR_MAP("Drawing the layer");
292  message += " " + layer->getTitle() + ". ";
293  message += TR_MAP("Rule");
294  message += " " + boost::lexical_cast<std::string>(i + 1) + " " + TR_MAP("of") + " ";
295  message += boost::lexical_cast<std::string>(nRules) + ".";
296 
297  // Creates a draw task
299  //task.setTotalSteps(symbolizers.size() * dataset->size()); // Removed! The te::da::DataSet size() method would be too costly to compute.
300 
301  // For while, first geometry property. TODO: get which geometry property the symbolizer references
302  std::size_t gpos = te::da::GetFirstPropertyPos(dataset.get(), te::dt::GEOMETRY_TYPE);
303 
304  if(symbolizers.empty())
305  {
306  // The current rule do not have a symbolizer. Try creates a default based on first geometry of dataset.
307  std::auto_ptr<te::gm::Geometry> g(dataset->getGeometry(gpos));
308  assert(g.get());
309 
310  te::se::Symbolizer* symbolizer = te::se::CreateSymbolizer(g->getGeomTypeId());
311  assert(symbolizer);
312 
313  rule->push_back(symbolizer);
314 
315  dataset->moveFirst();
316  }
317 
318  std::size_t nSymbolizers = symbolizers.size();
319 
320  for(std::size_t j = 0; j < nSymbolizers; ++j) // for each <Symbolizer>
321  {
322  // The current symbolizer
323  te::se::Symbolizer* symb = symbolizers[j];
324 
325  // Let's config the canvas based on the current symbolizer
326  cc.config(symb);
327 
328  // Let's draw! for each data set geometry...
329  if(j != nSymbolizers - 1)
330  drawDatSetGeometries(dataset.get(), gpos, canvas, layer->getSRID(), srid, 0, &task);
331  else
332  drawDatSetGeometries(dataset.get(), gpos, canvas, layer->getSRID(), srid, layer->getChart(), &task); // Here, produces the chart if exists
333 
334  // Prepares to draw the other symbolizer
335  dataset->moveFirst();
336 
337  } // end for each <Symbolizer>
338 
339  } // end for each <Rule>
340 }
341 
343  const std::string& geomPropertyName,
344  Canvas* canvas,
345  const te::gm::Envelope& bbox,
346  int srid)
347 {
348  assert(!geomPropertyName.empty());
349 
350  // Creates a canvas configurer
351  te::map::CanvasConfigurer cc(canvas);
352 
353  // The layer grouping
354  Grouping* grouping = layer->getGrouping();
355 
356  // The referenced property name
357  std::string propertyName = grouping->getPropertyName();
358  assert(!propertyName.empty());
359 
360  // The referenced property type
361  int propertyType = grouping->getPropertyType();
362 
363  // The grouping type
364  GroupingType type = grouping->getType();
365 
366  // The grouping items
367  const std::vector<GroupingItem*>& items = grouping->getGroupingItems();
368 
369  std::size_t nGroupItems = items.size();
370 
371  // Builds the task message; e.g. ("Drawing the grouping of layer Countries.")
372  std::string message = TR_MAP("Drawing the grouping of layer");
373  message += " " + layer->getTitle() + ".";
374 
375  // Creates the draw task
376  te::common::TaskProgress task(message, te::common::TaskProgress::DRAW, nGroupItems);
377 
378  for(std::size_t i = 0; i < nGroupItems; ++i) // for each GroupingItem
379  {
380  // The current group item
381  GroupingItem* item = items[i];
382  assert(item);
383 
384  /* 1) Creating te::da::Where object with the group item restriction expression + extent spatial restriction */
385 
386  te::da::PropertyName* groupingPropertyName = new te::da::PropertyName(propertyName);
387 
388  // Grouping item restriction
389  te::da::Expression* exp = 0;
390 
391  if(type == UNIQUE_VALUE)
392  {
394  exp = new te::da::EqualTo(groupingPropertyName, value);
395  }
396  else
397  {
398  te::da::Expression* lowerValue = 0;
399  te::da::Expression* upperrValue = 0;
400 
401  switch(propertyType)
402  {
403  case te::dt::STRING_TYPE:
404  lowerValue = new te::da::LiteralString(item->getLowerLimit());
405  upperrValue = new te::da::LiteralString(item->getUpperLimit());
406  break;
407 
408  default:
409  lowerValue = new te::da::LiteralDouble(boost::lexical_cast<double>(item->getLowerLimit()));
410  upperrValue = new te::da::LiteralDouble(boost::lexical_cast<double>(item->getUpperLimit()));
411  }
412 
413  te::da::GreaterThanOrEqualTo* gte = new te::da::GreaterThanOrEqualTo(groupingPropertyName, lowerValue);
414  te::da::LessThanOrEqualTo* lte = new te::da::LessThanOrEqualTo(groupingPropertyName->clone(), upperrValue);
415 
416  exp = new te::da::And(gte, lte);
417  }
418 
419  // The extent spatial restriction
420  te::da::LiteralEnvelope* lenv = new te::da::LiteralEnvelope(bbox, layer->getSRID());
421  te::da::PropertyName* geometryPropertyName = new te::da::PropertyName(geomPropertyName);
422  te::da::ST_Intersects* intersects = new te::da::ST_Intersects(geometryPropertyName, lenv);
423 
424  // Combining the expressions (group item restriction expression + extent spatial restriction)
425  te::da::And* restriction = new te::da::And(exp, intersects);
426 
427  /* 2) Calling the layer query method to get the correct restricted data. */
428 
429  std::auto_ptr<te::da::DataSet> dataset(0);
430  try
431  {
432  dataset = layer->getData(restriction);
433  }
434  catch(std::exception& /*e*/)
435  {
436  continue; // TODO: deal the exceptions!
437  }
438 
439  if(dataset.get() == 0)
440  throw Exception((boost::format(TR_MAP("Could not retrieve the data set from the layer %1%.")) % layer->getTitle()).str());
441 
442  if(dataset->moveNext() == false)
443  continue;
444 
445  // Gets the set of symbolizers defined on group item
446  const std::vector<te::se::Symbolizer*>& symbolizers = item->getSymbolizers();
447  std::size_t nSymbolizers = symbolizers.size();
448 
449  // For while, first geometry property. TODO: get which geometry property the symbolizer references
450  std::size_t gpos = te::da::GetFirstPropertyPos(dataset.get(), te::dt::GEOMETRY_TYPE);
451 
452  for(std::size_t j = 0; j < nSymbolizers; ++j) // for each <Symbolizer>
453  {
454  // The current symbolizer
455  te::se::Symbolizer* symb = symbolizers[j];
456 
457  // Let's config the canvas based on the current symbolizer
458  cc.config(symb);
459 
460  // Let's draw! for each data set geometry...
461  if(j != nSymbolizers - 1)
462  drawDatSetGeometries(dataset.get(), gpos, canvas, layer->getSRID(), srid, 0, &task);
463  else
464  drawDatSetGeometries(dataset.get(), gpos, canvas, layer->getSRID(), srid, layer->getChart(), &task); // Here, produces the chart if exists
465 
466  // Prepares to draw the other symbolizer
467  dataset->moveFirst();
468 
469  } // end for each <Symbolizer>
470 
471  if(!task.isActive())
472  return;
473 
474  task.pulse();
475 
476  } // end for each GroupItem
477 }
478 
480  const std::string& geomPropertyName,
481  Canvas* canvas,
482  const te::gm::Envelope& bbox,
483  int srid)
484 {
485  assert(!geomPropertyName.empty());
486 
487  // Creates a canvas configurer
488  te::map::CanvasConfigurer cc(canvas);
489 
490  // The layer grouping
491  Grouping* grouping = layer->getGrouping();
492 
493  // The referenced property name
494  std::string propertyName = grouping->getPropertyName();
495  assert(!propertyName.empty());
496 
497  // The grouping type
498  GroupingType type = grouping->getType();
499 
500  // The grouping precision
501  const std::size_t& precision = grouping->getPrecision();
502 
503  // The grouping items
504  const std::vector<GroupingItem*>& items = grouping->getGroupingItems();
505 
506  std::size_t nGroupItems = items.size();
507 
508  // case UNIQUE_VALUE: for each GroupingItem, builds a map [item value] -> [symbolizers]
509  std::map<std::string, std::vector<te::se::Symbolizer*> > uniqueGroupsMap;
510 
511  // case (NOT) UNIQUE_VALUE: for each GroupingItem, builds a map [item upper limit] -> [symbolizers]
512  std::map<std::pair< double, double>, std::vector<te::se::Symbolizer*> > othersGroupsMap;
513 
514  for(std::size_t i = 0; i < nGroupItems; ++i)
515  {
516  // The current group item
517  GroupingItem* item = items[i];
518  assert(item);
519 
520  if(type == UNIQUE_VALUE)
521  {
522  uniqueGroupsMap[item->getValue()] = item->getSymbolizers();
523  }
524  else
525  {
526  double lowerLimit = atof(item->getLowerLimit().c_str());
527  double upperLimit = atof(item->getUpperLimit().c_str());
528  std::pair<double, double> range(lowerLimit, upperLimit);
529 
530  othersGroupsMap[range] = item->getSymbolizers();
531  }
532  }
533 
534  // Builds the task message; e.g. ("Drawing the grouping of layer Countries.")
535  std::string message = TR_MAP("Drawing the grouping of layer");
536  message += " " + layer->getTitle() + ".";
537 
538  // Creates the draw task
540 
541  std::auto_ptr<te::da::DataSet> dataset(0);
542  try
543  {
544  dataset = layer->getData(geomPropertyName, &bbox, te::gm::INTERSECTS);
545  }
546  catch(std::exception& /*e*/)
547  {
548  return; // TODO: deal the exceptions!
549  }
550 
551  if(dataset.get() == 0)
552  throw Exception((boost::format(TR_MAP("Could not retrieve the data set from the layer %1%.")) % layer->getTitle()).str());
553 
554  if(dataset->moveNext() == false)
555  return;
556 
557  // Gets the first geometry property
558  std::size_t gpos = te::da::GetFirstPropertyPos(dataset.get(), te::dt::GEOMETRY_TYPE);
559 
560  // Gets the property position
561  std::auto_ptr<te::map::LayerSchema> dt(layer->getSchema());
562  std::size_t propertyPos = te::da::GetPropertyPos(dt.get(), propertyName);
563 
564  // Verifies if is necessary convert the data set geometries to the given srid
565  bool needRemap = false;
566  if((layer->getSRID() != TE_UNKNOWN_SRS) && (srid != TE_UNKNOWN_SRS) && (layer->getSRID() != srid))
567  needRemap = true;
568 
569  // The layer chart
570  Chart* chart = layer->getChart();
571 
572  do
573  {
574  std::vector<te::se::Symbolizer*> symbolizers;
575 
576  // Finds the current data set item on group map
577  std::string value;
578 
579  if(dataset->isNull(propertyPos))
581  else
582  value = dataset->getAsString(propertyPos, precision);
583 
584  if(type == UNIQUE_VALUE)
585  {
586  std::map<std::string, std::vector<te::se::Symbolizer*> >::const_iterator it = uniqueGroupsMap.find(value);
587  if(it == uniqueGroupsMap.end())
588  continue;
589  symbolizers = it->second;
590  }
591  else
592  {
593  double dvalue = atof(value.c_str());
594  std::map<std::pair< double, double>, std::vector<te::se::Symbolizer*> >::const_iterator it;
595  for(it = othersGroupsMap.begin(); it != othersGroupsMap.end(); ++it)
596  {
597  if(dvalue >= it->first.first && dvalue <= it->first.second)
598  break;
599  }
600 
601  if(it == othersGroupsMap.end())
602  {
603  te::se::Style* style = layer->getStyle();
604  if(style)
605  {
606  if(!style->getRules().empty())
607  {
608  te::se::Rule* rule = style->getRule(0);
609 
610  symbolizers = rule->getSymbolizers();
611  }
612  }
613  }
614  else
615  {
616  symbolizers = it->second;
617  }
618 
619  if(symbolizers.empty())
620  continue;
621  }
622 
623  std::auto_ptr<te::gm::Geometry> geom;
624  try
625  {
626  geom = dataset->getGeometry(gpos);
627  if(geom.get() == 0)
628  continue;
629  }
630  catch(std::exception& /*e*/)
631  {
632  continue;
633  }
634 
635  // Gets the set of symbolizers defined on group item
636  std::size_t nSymbolizers = symbolizers.size();
637 
638  for(std::size_t j = 0; j < nSymbolizers; ++j) // for each <Symbolizer>
639  {
640  // The current symbolizer
641  te::se::Symbolizer* symb = symbolizers[j];
642 
643  // Let's config the canvas based on the current symbolizer
644  cc.config(symb);
645 
646  // If necessary, geometry remap
647  if(needRemap)
648  {
649  geom->setSRID(layer->getSRID());
650  geom->transform(srid);
651  }
652 
653  canvas->draw(geom.get());
654 
655  if(chart && j == nSymbolizers - 1)
656  buildChart(chart, dataset.get(), geom.get());
657  }
658 
659  } while(dataset->moveNext());
660 
661  // Let's draw the generated charts
662  for(std::size_t i = 0; i < m_chartCoordinates.size(); ++i)
663  {
664  canvas->drawImage(static_cast<int>(m_chartCoordinates[i].x),
665  static_cast<int>(m_chartCoordinates[i].y),
666  m_chartImages[i],
667  chart->getWidth(),
668  chart->getHeight());
669 
670  te::common::Free(m_chartImages[i], chart->getHeight());
671  }
672 }
673 
674 void te::map::AbstractLayerRenderer::drawDatSetGeometries(te::da::DataSet* dataset, const std::size_t& gpos, Canvas* canvas,
675  int fromSRID, int toSRID,
676  Chart* chart, te::common::TaskProgress* task)
677 {
678  assert(dataset);
679  assert(canvas);
680 
681  // Verify if is necessary convert the data set geometries to the given srid
682  bool needRemap = false;
683  if((fromSRID != TE_UNKNOWN_SRS) && (toSRID != TE_UNKNOWN_SRS) && (fromSRID != toSRID))
684  needRemap = true;
685 
686  do
687  {
688  if(task)
689  {
690  if(!task->isActive())
691  return;
692 
693  // update the draw task
694  task->pulse();
695  }
696 
697  std::auto_ptr<te::gm::Geometry> geom(0);
698  try
699  {
700  geom = dataset->getGeometry(gpos);
701  if(geom.get() == 0)
702  continue;
703  }
704  catch(std::exception& /*e*/)
705  {
706  continue;
707  }
708 
709  // If necessary, geometry remap
710  if(needRemap)
711  {
712  geom->setSRID(fromSRID);
713  geom->transform(toSRID);
714  }
715 
716  canvas->draw(geom.get());
717 
718  if(chart)
719  buildChart(chart, dataset, geom.get());
720 
721  } while(dataset->moveNext()); // next geometry!
722 
723  // Let's draw the generated charts
724  for(std::size_t i = 0; i < m_chartCoordinates.size(); ++i)
725  {
726  canvas->drawImage(static_cast<int>(m_chartCoordinates[i].x),
727  static_cast<int>(m_chartCoordinates[i].y),
728  m_chartImages[i],
729  chart->getWidth(),
730  chart->getHeight());
731 
732  te::common::Free(m_chartImages[i], chart->getHeight());
733  }
734 }
735 
737 {
738  if(!chart->isVisible())
739  return;
740 
741  // Builds the chart point (world coordinates)
742  const te::gm::Envelope* e = geom->getMBR();
743 
744  // Device coordinates
745  double dx = 0.0; double dy = 0.0;
746  m_transformer.world2Device(e->getCenter().x, e->getCenter().y, dx, dy);
747 
748  double dw = dx + chart->getWidth();
749  double dh = dy + chart->getHeight();
750 
751  // Builds the chart envelope
752  te::gm::Envelope chartEnvelope(dx, dy, dw, dh);
753 
754  // Search on rtree
755  std::vector<std::size_t> report;
756  m_rtree.search(chartEnvelope, report);
757 
758  if(!report.empty())
759  return;
760 
761  // Here, no intersections considering the current chart envelope
762  m_rtree.insert(chartEnvelope, ++m_index);
763 
764  // Stores the chart coordinate
765  m_chartCoordinates.push_back(te::gm::Coord2D(dx, dy));
766 
767  // Builds the chart image
768  std::size_t width = 0;
769  te::color::RGBAColor** rgba = ChartRendererManager::getInstance().render(chart, dataset, width);
770  m_chartImages.push_back(rgba);
771 }
772 
774 {
775  m_index = 0;
776  m_chartCoordinates.clear();
777  m_chartImages.clear();
778 }
GroupingType
The grouping type associated to the layer.
Definition: Enums.h:150
std::vector< te::rst::BandProperty * > & getBandProperties()
Returns a reference to the list of bands definitions.
bool isActive() const
Verify if the task is active.
This class represents the informations needed to build map charts.
const std::vector< Rule * > & getRules() const
Definition: Style.cpp:94
virtual te::map::Chart * getChart() const
It returns the Chart associated to the Layer.
bool isValid() const
It tells if the rectangle is valid or not.
Definition: Envelope.h:438
void push_back(Symbolizer *s)
Definition: Rule.cpp:138
This class contains the parameters needed for grouping the values of a Property.
Definition: Grouping.h:59
The FeatureTypeStyle defines the styling that is to be applied to a dataset that can be viewed as a f...
Rule * getRule(std::size_t i) const
Definition: Style.cpp:105
TEDATAACCESSEXPORT te::rst::RasterProperty * GetFirstRasterProperty(const DataSetType *dt)
Definition: Utils.cpp:518
std::size_t getWidth() const
Definition: Chart.cpp:128
Expression * clone() const
It creates a new copy of this expression.
virtual const std::string & getTitle() const
It returns the layer title.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:504
This is the base class for layers.
Definition: AbstractLayer.h:76
A canvas is an abstraction of a drawing area.
Definition: Canvas.h:91
void drawDatSetGeometries(te::da::DataSet *dataset, const std::size_t &gpos, Canvas *canvas, int fromSRID, int toSRID, Chart *chart, te::common::TaskProgress *task=0)
It draws the data set geometries in the given canvas using the informed SRS.
A Symbolizer describes how a feature is to appear on a map.
Definition: Symbolizer.h:80
double y
y-coordinate.
Definition: Coord2D.h:87
Spatial intersects operator.
Definition: ST_Intersects.h:46
bool isVisible() const
It gets the chart visibility.
Definition: Chart.cpp:163
It models the inequality operator greater than or equal to (&gt;=).
This class models a string Literal value.
Definition: LiteralString.h:46
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
virtual std::auto_ptr< LayerSchema > getSchema() const =0
It returns the layer schema.
It renders the objects associated to an abstract layer. i.e. a generic renderer.
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
The CoverageStyle defines the styling that is to be applied to a subset of Coverage data...
Definition: CoverageStyle.h:45
const std::vector< Symbolizer * > & getSymbolizers() const
Definition: Rule.cpp:152
A class that models the name of any property of an object.
Definition: PropertyName.h:50
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:72
const std::string & getValue() const
It gets the value of the legend item.
virtual te::map::Grouping * getGrouping() const
It returns the Grouping associated to the Layer.
int getPropertyType() const
It gets the property type whose values will be grouped.
Definition: Grouping.cpp:58
void drawLayerGeometries(AbstractLayer *layer, const std::string &geomPropertyName, te::se::FeatureTypeStyle *style, Canvas *canvas, const te::gm::Envelope &bbox, int srid)
It draws the abstract layer in the given canvas using the SRS informed.
A filter is any valid predicate expression.
Definition: Filter.h:52
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
virtual void drawImage(char *src, std::size_t size, ImageType t)=0
It draws the src image over the canvas.
A Rule is used to attach property/scale conditions to and group the individual symbols used for rende...
Definition: Rule.h:78
Boolean logic operator: AND.
Definition: And.h:46
TESEEXPORT Style * CreateFeatureTypeStyle(const te::gm::GeomType &geomType)
Try creates an appropriate feature type style based on given geometry type.
Definition: Utils.cpp:282
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
A Symbology Enconding visitor that configures a given canvas based on symbolizers elements...
This is a singleton for managing chart renderer instance available in the system. ...
Utility functions for the data access module.
An exception class for the MapTools module.
virtual int getHeight() const =0
It returns the canvas height.
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
It models the inequality operator less than or equal to (&lt;=).
TESEEXPORT Style * CreateCoverageStyle(const std::vector< te::rst::BandProperty * > &properties)
Try creates an appropriate coverage style based on given band properties.
Definition: Utils.cpp:297
std::string getPropertyName() const
It gets the property name whose values will be grouped.
Definition: Grouping.cpp:47
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
A visitor that converts a OGC Filter Expression to TerraLib Expression.
TESEEXPORT Symbolizer * CreateSymbolizer(const te::gm::GeomType &geomType)
Try creates an appropriate symbolizer based on given geometry type.
Definition: Utils.cpp:218
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:428
void drawLayerGroupingMem(AbstractLayer *layer, const std::string &geomPropertyName, Canvas *canvas, const te::gm::Envelope &bbox, int srid)
It draws the grouping of the abstract layer in the given canvas using the SRS informed.
A class that models a literal for Envelope values.
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
A Symbology Enconding visitor that configures a given canvas based on symbolizers elements...
virtual te::se::Style * getStyle() const
It returns the Style associated to the layer.
virtual const te::gm::Envelope & getExtent() const
It returns the Layer extent (or minimum bounding box).
void draw(AbstractLayer *layer, Canvas *canvas, const te::gm::Envelope &bbox, int srid)
It draws the layer geographic objects in the given canvas using the SRS informed. ...
const size_t getPrecision() const
It gets the precision used for the property values.
Definition: Grouping.cpp:79
Envelope intersection(const Envelope &rhs) const
It returns an envelope that represents the point set intersection with another envelope.
Definition: Envelope.h:543
const std::string & getLowerLimit() const
It gets the lower limit value of the legend item.
Coord2D getCenter() const
It returns the rectangle&#39;s center coordinate.
Definition: Envelope.cpp:48
void transform(int oldsrid, int newsrid)
It will transform the coordinates of the Envelope from the old SRS to the new one.
Definition: Envelope.cpp:89
#define TR_MAP(message)
It marks a string in order to get translated. This is a special mark used in the Map Rendering module...
TEDATAACCESSEXPORT std::size_t GetPropertyPos(const DataSet *dataset, const std::string &name)
Definition: Utils.cpp:447
const te::fe::Filter * getFilter() const
Definition: Rule.cpp:97
The Style defines the styling that is to be applied to a geographic dataset (vector geometries or cov...
Definition: Style.h:65
void Free(std::vector< T * > *v)
This function can be applied to a pointer to a vector of pointers.
Definition: STLUtils.h:131
This class contains the parameters needed for grouping the values of a Property.
bool intersects(const Envelope &rhs) const
It returns true if the envelopes &quot;spatially intersects&quot;.
Definition: Envelope.h:493
virtual void draw(const te::gm::Geometry *geom)=0
It draws the geometry on canvas.
const std::vector< te::se::Symbolizer * > & getSymbolizers() const
It gets the symbolizer of the legend item.
Raster property.
te::da::Expression * getExpression(const te::fe::Filter *f)
It converts the OGC Filter Expression to a TerraLib Expression.
This is an abstract class that models a query expression.
Definition: Expression.h:47
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
This class represents the informations needed to build map charts.
Definition: Chart.h:51
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
const Envelope * getMBR() const
It returns the minimum bounding rectangle for the geometry in an internal representation.
Definition: Geometry.cpp:103
It models the comparison operator.
Definition: EqualTo.h:46
This is the base class for Layers.
A visitor that converts a OGC Filter Expression to TerraLib Expression.
Definition: QueryEncoder.h:53
void drawLayerGrouping(AbstractLayer *layer, const std::string &geomPropertyName, Canvas *canvas, const te::gm::Envelope &bbox, int srid)
It draws the grouping of the abstract layer in the given canvas using the SRS informed.
static const std::string sm_nanStr
Not a number string value.
Definition: Globals.h:57
static T & getInstance()
It returns a reference to the singleton instance.
Definition: Singleton.h:120
double x
x-coordinate.
Definition: Coord2D.h:86
void buildChart(Chart *chart, te::da::DataSet *dataset, te::gm::Geometry *geom)
virtual std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
TEMAPEXPORT void DrawRaster(te::da::DataSetType *type, te::da::DataSourcePtr ds, Canvas *canvas, const te::gm::Envelope &bbox, int bboxSRID, const te::gm::Envelope &visibleArea, int srid, te::se::CoverageStyle *style)
Definition: Utils.cpp:532
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
std::size_t getHeight() const
Definition: Chart.cpp:118
virtual int getSRID() const
It returns the Spatial Reference System ID associated to the Layer.
virtual int getWidth() const =0
It returns the canvas width.
A class that models a literal for double values.
Definition: LiteralDouble.h:43
Geometric property.
const std::string & getUpperLimit() const
It gets the upper limit value of the legend item.
const std::vector< te::map::GroupingItem * > & getGroupingItems() const
It gets the vector of grouping items.
Definition: Grouping.cpp:109
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:111
virtual void setStyle(te::se::Style *style)
It sets the Style associated to the layer.
virtual std::auto_ptr< te::da::DataSet > getData(te::common::TraverseType travType=te::common::FORWARDONLY, const te::common::AccessPolicy accessPolicy=te::common::RAccess) const =0
It gets the dataset identified by the layer name.
const GroupingType getType() const
It gets the grouping type.
Definition: Grouping.cpp:69
A GroupingItem contains information about a grouping item associated to a layer.
Definition: GroupingItem.h:48