All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
QueryLayerRenderer.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/QueryLayerRenderer.cpp
22 
23  \brief It renders the objects associated to a query layer.
24 */
25 
26 // TerraLib
27 #include "../common/Translator.h"
28 #include "../common/progress/TaskProgress.h"
29 #include "../dataaccess/datasource/DataSource.h"
30 #include "../dataaccess/datasource/DataSourceTransactor.h"
31 #include "../dataaccess/dataset/DataSet.h"
32 #include "../dataaccess/dataset/DataSetType.h"
33 #include "../dataaccess/query/And.h"
34 #include "../dataaccess/query/DataSetName.h"
35 #include "../dataaccess/query/Field.h"
36 #include "../dataaccess/query/LiteralEnvelope.h"
37 #include "../dataaccess/query/PropertyName.h"
38 #include "../dataaccess/query/Select.h"
39 #include "../dataaccess/query/ST_Intersects.h"
40 #include "../dataaccess/query/Where.h"
41 #include "../dataaccess/utils/Utils.h"
42 #include "../geometry/Envelope.h"
43 #include "../geometry/Geometry.h"
44 #include "../geometry/GeometryProperty.h"
45 #include "../geometry/Utils.h"
46 #include "../se/CoverageStyle.h"
47 #include "../se/FeatureTypeStyle.h"
48 #include "../se/ImageOutline.h"
49 #include "../se/RasterSymbolizer.h"
50 #include "../se/Rule.h"
51 #include "../se/Utils.h"
52 #include "../srs/Config.h"
53 #include "../srs/Converter.h"
54 #include "Canvas.h"
55 #include "CanvasConfigurer.h"
56 #include "Exception.h"
57 #include "QueryEncoder.h"
58 #include "QueryLayer.h"
59 #include "QueryLayerRenderer.h"
60 
61 // Boost
62 #include <boost/format.hpp>
63 #include <boost/lexical_cast.hpp>
64 
65 // STL
66 #include <cassert>
67 
69 {
70 }
71 
73 {
74 }
75 
77  Canvas* canvas,
78  const te::gm::Envelope& bbox,
79  int srid)
80 {
81 // Is this a query layer?
82  te::map::QueryLayer* qlayer = dynamic_cast<te::map::QueryLayer*>(layer);
83 
84  if(qlayer == 0)
85  throw Exception(TE_TR("Wrong type render type for this layer!"));
86 
87 // check if layer extent intersects the drawing area and so compute bounding box intersection
88  te::gm::Envelope reprojectedBBOX(bbox);
89 
90  if((qlayer->getSRID() != TE_UNKNOWN_SRS) && (srid != TE_UNKNOWN_SRS))
91  {
92  reprojectedBBOX.transform(srid, qlayer->getSRID());
93  }
94  else if(qlayer->getSRID() != srid)
95  {
96  throw Exception(TE_TR("The layer or map don't have a valid SRID!"));
97  }
98 
99  if(!reprojectedBBOX.intersects(qlayer->getExtent()))
100  return;
101 
102  te::gm::Envelope ibbox = reprojectedBBOX.intersection(qlayer->getExtent());
103 
104 // get dataset information
105  std::auto_ptr<LayerSchema> schema(qlayer->getSchema());
106  assert(schema.get());
107 
108  if(schema->hasGeom())
109  {
110  drawGeometries(qlayer, canvas, ibbox, srid);
111  }
112  else if(schema->hasRaster())
113  {
114  drawRaster(qlayer, canvas, ibbox, bbox, srid);
115  }
116  else
117  {
118  throw Exception(TE_TR("The layer don't have a geometry or raster property!"));
119  }
120 }
121 
123  Canvas* canvas,
124  const te::gm::Envelope& bbox,
125  int srid)
126 {
127  std::auto_ptr<const te::map::LayerSchema> schema(layer->getSchema());
128  assert(schema.get());
129 
130 // verify if is necessary convert the data set geometries to the given srid
131  bool needRemap = false;
132  if((layer->getSRID() != TE_UNKNOWN_SRS) && (srid != TE_UNKNOWN_SRS) && (layer->getSRID() != srid))
133  needRemap = true;
134 
135 // for while, default geometry. TODO: need a visitor to get which properties the style references
136  assert(schema->hasGeom());
137  te::gm::GeometryProperty* geometryProperty = te::da::GetFirstGeomProperty(schema.get());
138 
139 // get the associated layer style
140  te::se::Style* style = layer->getStyle();
141  if(style == 0)
142  {
143 // try create an appropriate style
144  style = te::se::CreateFeatureTypeStyle(geometryProperty->getGeometryType());
145 
146  if(style == 0)
147  throw Exception((boost::format(TE_TR("Could not create a default feature type style to the layer %1%.")) % layer->getTitle()).str());
148 
149  layer->setStyle(style);
150  }
151 
152 // should I render this style?
153  te::se::FeatureTypeStyle* fts = dynamic_cast<te::se::FeatureTypeStyle*>(style);
154  if(fts == 0)
155  throw Exception(TE_TR("The layer style is not a Feature Type Style!"));
156 
157 // create a canvas configurer
158  te::map::CanvasConfigurer cc(canvas);
159 
160 // number of rules defined on feature type style
161  std::size_t nRules = fts->getRules().size();
162 
163  for(std::size_t i = 0; i < nRules; ++i) // for each <Rule>
164  {
165 // the current rule
166  const te::se::Rule* rule = fts->getRule(i);
167  assert(rule);
168 
169 // TODO: should be verified the MinScaleDenominator and MaxScaleDenominator. Where will we put the current scale information? AbstractLayer? Method parameter?
170 
171 // gets the rule filter
172  const te::fe::Filter* filter = rule->getFilter();
173 
174 // let's retrieve the correct dataset
175  std::auto_ptr<te::da::DataSet> dataset(0);
176  if(!filter)
177  {
178 // there isn't a Filter expression. Gets the dataset using only box restriction...
179  dataset = layer->getData(geometryProperty->getName(), &bbox, te::gm::INTERSECTS);
180  }
181  else
182  {
183  // TODO!
184  throw Exception(TE_TR("No implemented yet!"));
185  }
186 
187  if(dataset.get() == 0)
188  throw Exception((boost::format(TE_TR("Could not retrieve the data set %1% referenced by the layer %2%.")) % schema->getName() % layer->getTitle()).str());
189 
190  if(dataset->moveNext() == false)
191  continue;
192 
193 // get the set of symbolizers defined on current rule
194  const std::vector<te::se::Symbolizer*>& symbolizers = rule->getSymbolizers();
195  std::size_t nSymbolizers = symbolizers.size();
196 
197 // build task message; e.g. ("Drawing the layer Countries. Rule 1 of 3.")
198  std::string message = TE_TR("Drawing the layer");
199  message += " " + layer->getTitle() + ". ";
200  message += TE_TR("Rule");
201  message += " " + boost::lexical_cast<std::string>(i + 1) + " " + TE_TR("of") + " ";
202  message += boost::lexical_cast<std::string>(nRules) + ".";
203 
204 // create a draw task
206  //task.setTotalSteps(nSymbolizers * dataset->size()); // Removed! The te::da::DataSet size() method would be too costly to compute.
207 
208  for(std::size_t j = 0; j < nSymbolizers; ++j) // for each <Symbolizer>
209  {
210 // the current symbolizer
211  te::se::Symbolizer* symb = symbolizers[j];
212 
213 // let's config de canvas based on the current symbolizer
214  cc.config(symb);
215 
216 // for while, first geometry. TODO: get which property the symbolizer references
217  std::size_t gpos = te::da::GetFirstPropertyPos(dataset.get(), te::dt::GEOMETRY_TYPE);
218 
219 // let's draw! for each data set object...
220  do
221  {
222  if(!task.isActive())
223  return;
224 
225 // update the draw task
226  task.pulse();
227 
228  std::auto_ptr<te::gm::Geometry> geom = dataset->getGeometry(gpos);
229  if(geom.get() == 0)
230  continue;
231 
232 // if necessary, geometry remap
233  if(needRemap)
234  {
235  geom->setSRID(layer->getSRID());
236  geom->transform(srid);
237  }
238 
239  canvas->draw(geom.get());
240 
241  }while(dataset->moveNext()); // next geometry!
242 
243 // prepare to draw the other symbolizer
244  dataset->moveFirst();
245 
246  } // end for each <Symbolizer>
247 
248  } // end for each <Rule>
249 }
250 
252  Canvas* canvas,
253  const te::gm::Envelope& bbox,
254  const te::gm::Envelope& visibleArea,
255  int srid)
256 {
257 }
Geometric property.
bool intersects(const Envelope &rhs) const
It returns true if the envelopes "spatially intersects".
Definition: Envelope.h:493
The Style defines the styling that is to be applied to a geographic dataset (vector geometries or cov...
Definition: Style.h:65
This is the base class for layers.
Definition: AbstractLayer.h:76
virtual const te::gm::Envelope & getExtent() const
It returns the Layer extent (or minimum bounding box).
virtual const std::string & getTitle() const
It returns the layer title.
A Symbolizer describes how a feature is to appear on a map.
Definition: Symbolizer.h:80
std::auto_ptr< LayerSchema > getSchema() const
It returns the layer schema.
Definition: QueryLayer.cpp:84
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. ...
A visitor that converts a OGC Filter Expression to TerraLib Expression.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
void drawRaster(QueryLayer *layer, Canvas *canvas, const te::gm::Envelope &bbox, const te::gm::Envelope &visibleArea, int srid)
A layer resulting from a query.
Definition: QueryLayer.h:50
const te::fe::Filter * getFilter() const
Definition: Rule.cpp:97
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:345
It renders the objects associated to a query layer.
An exception class for the MapTools module.
TESEEXPORT Style * CreateFeatureTypeStyle(const te::gm::GeomType &geomType)
Try creates an appropriate feature type style based on given geometry type.
Definition: Utils.cpp:284
Rule * getRule(std::size_t i) const
Definition: Style.cpp:105
const std::vector< Rule * > & getRules() const
Definition: Style.cpp:94
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
The FeatureTypeStyle defines the styling that is to be applied to a dataset that can be viewed as a f...
#define TE_UNKNOWN_SRS
A numeric value to represent a unknown SRS identification in TerraLib.
Definition: Config.h:44
void drawGeometries(QueryLayer *layer, Canvas *canvas, const te::gm::Envelope &bbox, int srid)
virtual te::se::Style * getStyle() const
It returns the Style associated to the layer.
A filter is any valid predicate expression.
Definition: Filter.h:52
const std::vector< Symbolizer * > & getSymbolizers() const
Definition: Rule.cpp:158
A canvas is an abstraction of a drawing area.
Definition: Canvas.h:91
A Rule is used to attach property/scale conditions to and group the individual symbols used for rende...
Definition: Rule.h:78
virtual void setStyle(te::se::Style *style)
It sets the Style associated to the layer.
A layer resulting from a query.
std::auto_ptr< te::da::DataSet > getData(te::common::TraverseType travType=te::common::FORWARDONLY, const te::common::AccessPolicy accessPolicy=te::common::RAccess) const
It gets the dataset identified by the layer name.
Definition: QueryLayer.cpp:131
virtual int getSRID() const
It returns the Spatial Reference System ID associated to the Layer.
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:432
void config(const te::se::Symbolizer *symbolizer)
It configs the canvas based on given symbolizer.
Envelope intersection(const Envelope &rhs) const
It returns an envelope that represents the point set intersection with another envelope.
Definition: Envelope.h:543
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:508
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:90
virtual void draw(const te::gm::Geometry *geom)=0
It draws the geometry on canvas.
A Symbology Enconding visitor that configures a given canvas based on symbolizers elements...
A Symbology Enconding visitor that configures a given canvas based on symbolizers elements...