All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
QueryLayer.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/QueryLayer.cpp
22 
23  \brief A layer resulting from a query.
24 */
25 
26 // TerraLib
27 #include "../common/StringUtils.h"
28 #include "../dataaccess/dataset/ObjectIdSet.h"
29 #include "../dataaccess/datasource/DataSource.h"
30 #include "../dataaccess/datasource/DataSourceCapabilities.h"
31 #include "../dataaccess/query/And.h"
32 #include "../dataaccess/query/DataSetName.h"
33 #include "../dataaccess/query/Expression.h"
34 #include "../dataaccess/query/Field.h"
35 #include "../dataaccess/query/Function.h"
36 #include "../dataaccess/query/FunctionNames.h"
37 #include "../dataaccess/query/FromItem.h"
38 #include "../dataaccess/query/LiteralEnvelope.h"
39 #include "../dataaccess/query/PropertyName.h"
40 #include "../dataaccess/query/Select.h"
41 #include "../dataaccess/query/ST_Intersects.h"
42 #include "../dataaccess/query/ST_EnvelopeIntersects.h"
43 #include "../dataaccess/query/Where.h"
44 #include "../dataaccess/utils/Utils.h"
45 #include "../datatype/Property.h"
46 #include "../geometry/GeometryProperty.h"
47 #include "Exception.h"
48 #include "QueryLayer.h"
49 #include "RendererFactory.h"
50 
51 // Boost
52 #include <boost/format.hpp>
53 
54 // STL
55 #include <memory>
56 
57 const std::string te::map::QueryLayer::sm_type("QUERYLAYER");
58 
60  : AbstractLayer(parent),
61  m_query(0)
62 {
63 }
64 
65 te::map::QueryLayer::QueryLayer(const std::string& id, AbstractLayer* parent)
66  : AbstractLayer(id, parent),
67  m_query(0)
68 {
69 }
70 
71 te::map::QueryLayer::QueryLayer(const std::string& id,
72  const std::string& title,
73  AbstractLayer* parent)
74  : AbstractLayer(id, title, parent),
75  m_query(0)
76 {
77 }
78 
80 {
81  delete m_query;
82 }
83 
84 std::auto_ptr<te::map::LayerSchema> te::map::QueryLayer::getSchema() const
85 {
86  std::auto_ptr<te::map::LayerSchema> output(new te::map::LayerSchema(getTitle()));
87 
88  te::da::DataSourcePtr ds = te::da::GetDataSource(m_datasourceId, true);
89 
90  const te::da::Fields* fields = m_query->getFields();
91  const te::da::From* from = m_query->getFrom();
92 
93  for(size_t i = 0; i < fields->size(); ++i)
94  {
95  te::da::Field field = fields->at(i);
96  te::da::Expression* exp = field.getExpression();
97 
98  te::da::PropertyName* pName = dynamic_cast<te::da::PropertyName*>(exp);
99 
100  std::vector<std::string> tokens;
101  te::common::Tokenize(pName->getName(), tokens, ".");
102 
103  assert(tokens.size() == 2);
104 
105  std::string name;
106 
107  for(size_t j = 0; j < from->size(); ++j)
108  {
109  const te::da::FromItem& item = from->at(j);
110  const te::da::DataSetName* dsName = dynamic_cast<const te::da::DataSetName*>(&item);
111  if(dsName->getAlias() == tokens[0])
112  name = dsName->getName();
113  }
114 
115  assert(!name.empty());
116 
117  std::auto_ptr<te::da::DataSetType> dt = ds->getDataSetType(name);
118 
119  te::dt::Property* pRef = dt->getProperty(tokens[1]);
120  assert(pRef);
121 
122  std::auto_ptr<te::dt::Property> p(pRef->clone());
123  //p->setName(pName->getName());
124 
125  output->add(p.release());
126  }
127 
128  return output;
129 }
130 
131 std::auto_ptr<te::da::DataSet> te::map::QueryLayer::getData(te::common::TraverseType travType,
132  const te::common::AccessPolicy accessPolicy) const
133 {
134  return getData(m_query, travType, accessPolicy);
135 }
136 
137 std::auto_ptr<te::da::DataSet> te::map::QueryLayer::getData(const std::string& propertyName,
138  const te::gm::Envelope* e,
140  te::common::TraverseType travType,
141  const te::common::AccessPolicy accessPolicy) const
142 {
143  te::da::LiteralEnvelope* lenv = new te::da::LiteralEnvelope(*e, m_srid);
144 
145  te::da::PropertyName* pname = new te::da::PropertyName(propertyName);
146 
147  te::da::DataSourcePtr ds = te::da::GetDataSource(m_datasourceId, true);
148 
149  const te::da::DataSourceCapabilities dsCap = ds->getCapabilities();
150 
151  const te::da::QueryCapabilities queryCap = dsCap.getQueryCapabilities();
152 
153  std::set<std::string> spatialTopOp = queryCap.getSpatialTopologicOperators();
154 
155  // The final select
156  std::auto_ptr<te::da::Select> select(static_cast<te::da::Select*>(m_query->clone()));
157 
158  // Original Where
159  te::da::Where* wh = select->getWhere();
160 
161  // Original restriction expression
162  te::da::Expression* exp = wh->getExp()->clone();
163 
164  // TODO: switch that verifies the given te::gm::SpatialRelation and build the query object (ST_Intersects. ST_Touches, etc).
165 
166  if(spatialTopOp.find(te::da::FunctionNames::sm_ST_EnvelopeIntersects) != spatialTopOp.end())
167  {
168  te::da::ST_EnvelopeIntersects* intersects = new te::da::ST_EnvelopeIntersects(pname, lenv);
169 
170  // The final restriction: original restriction expression + extent restriction
171  te::da::And* andop = new te::da::And(exp, intersects);
172 
173  wh->setExp(andop);
174  }
175  else if(spatialTopOp.find(te::da::FunctionNames::sm_ST_Intersects) != spatialTopOp.end())
176  {
177  te::da::ST_Intersects* intersects = new te::da::ST_Intersects(pname, lenv);
178 
179  // The final restriction: original restriction expression + extent restriction
180  te::da::And* andop = new te::da::And(exp, intersects);
181 
182  wh->setExp(andop);
183  }
184 
185  return getData(select.get(), travType, accessPolicy);
186 }
187 
188 std::auto_ptr<te::da::DataSet> te::map::QueryLayer::getData(const std::string& propertyName,
189  const te::gm::Geometry* /*g*/,
191  te::common::TraverseType /*travType*/,
192  const te::common::AccessPolicy) const
193 {
194  throw Exception("Not implemented yet!");
195 }
196 
197 std::auto_ptr<te::da::DataSet> te::map::QueryLayer::getData(te::da::Expression* restriction,
198  te::common::TraverseType travType,
199  const te::common::AccessPolicy accessPolicy) const
200 {
201  // The final select
202  std::auto_ptr<te::da::Select> select(static_cast<te::da::Select*>(m_query->clone()));
203 
204  // Original Where
205  te::da::Where* wh = select->getWhere();
206 
207  // Original restriction expression
208  te::da::Expression* exp = wh->getExp()->clone();
209 
210  // The final restriction: original restriction expression + the given restriction expression
211  te::da::And* andop = new te::da::And(exp, restriction);
212  wh->setExp(andop);
213 
214  return getData(select.get(), travType, accessPolicy);
215 }
216 
217 std::auto_ptr<te::da::DataSet> te::map::QueryLayer::getData(const te::da::ObjectIdSet* oids,
218  te::common::TraverseType travType,
219  const te::common::AccessPolicy accessPolicy) const
220 {
221  // The final select
222  std::auto_ptr<te::da::Select> select(static_cast<te::da::Select*>(m_query->clone()));
223 
224  // Original Where
225  te::da::Where* wh = select->getWhere();
226 
227  // Original restriction expression
228  te::da::Expression* exp = wh->getExp()->clone();
229 
230  // The final restriction: original restriction expression + the oids restriction
231  te::da::And* andop = new te::da::And(exp, oids->getExpression());
232  wh->setExp(andop);
233 
234  return getData(select.get(), travType, accessPolicy);
235 }
236 
238 {
239  if(m_query == 0)
240  return false;
241 
242  if(m_datasourceId.empty())
243  return false;
244 
246  try
247  {
248  ds = te::da::GetDataSource(m_datasourceId, true);
249  }
250  catch(...)
251  {
252  return false;
253  }
254 
255  if(ds.get() == 0 || !ds->isValid() || !ds->isOpened())
256  return false;
257 
258  return true;
259 }
260 
261 void te::map::QueryLayer::draw(Canvas* canvas, const te::gm::Envelope& bbox, int srid)
262 {
263  if(m_rendererType.empty())
264  throw Exception((boost::format(TE_TR("Could not draw the query layer %1%. The renderer type is empty!")) % getTitle()).str());
265 
266  // Try get the defined renderer
267  std::auto_ptr<AbstractRenderer> renderer(RendererFactory::make(m_rendererType));
268  if(renderer.get() == 0)
269  throw Exception((boost::format(TE_TR("Could not draw the query layer %1%. The renderer %2% could not be created!")) % getTitle() % m_rendererType).str());
270 
271  renderer->draw(this, canvas, bbox, srid);
272 }
273 
274 const std::string& te::map::QueryLayer::getType() const
275 {
276  return sm_type;
277 }
278 
280 {
281  return m_query;
282 }
283 
285 {
286  delete m_query;
287 
288  m_query = s;
289 }
290 
291 const std::string& te::map::QueryLayer::getDataSourceId() const
292 {
293  return m_datasourceId;
294 }
295 
296 void te::map::QueryLayer::setDataSourceId(const std::string& id)
297 {
298  m_datasourceId = id;
299 }
300 
301 const std::string& te::map::QueryLayer::getRendererType() const
302 {
303  return m_rendererType;
304 }
305 
306 void te::map::QueryLayer::setRendererType(const std::string& t)
307 {
308  m_rendererType = t;
309 }
310 
312 {
313  if(m_mbr.isValid())
314  return;
315 
316  // Get the associated data source
317  te::da::DataSourcePtr ds = te::da::GetDataSource(m_datasourceId, true);
318 
319  // Get the dataset
320  std::auto_ptr<te::da::DataSet> dataset(ds->query(m_query));
321  assert(dataset.get());
322 
323  // MBR
324  m_mbr = *dataset->getExtent(te::da::GetFirstPropertyPos(dataset.get(), te::dt::GEOMETRY_TYPE));
325 }
326 
327 std::auto_ptr<te::da::DataSet> te::map::QueryLayer::getData(te::da::Select* query,
328  te::common::TraverseType travType,
329  const te::common::AccessPolicy accessPolicy) const
330 {
331  te::da::DataSourcePtr ds = te::da::GetDataSource(m_datasourceId, true);
332 
333  return ds->query(query, travType, accessPolicy);
334 }
TEDATAACCESSEXPORT DataSourcePtr GetDataSource(const std::string &datasourceId, const bool opened=true)
Search for a data source with the informed id in the DataSourceManager.
Definition: Utils.cpp:259
const std::string & getName() const
It returns the property name.
Definition: PropertyName.h:80
An abstract class that models a source of data in a query.
Definition: FromItem.h:50
The Field class can be used to model an expression that takes part of the output items of a SELECT...
Definition: Field.h:50
Spatial intersects operator.
Definition: ST_Intersects.h:46
This is the base class for layers.
Definition: AbstractLayer.h:76
A class that models the name of a dataset used in a From clause.
Definition: DataSetName.h:43
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
Expression * getExpression(const std::string source="") const
It returns the expression that can be used to retrieve the data set that contains the all indentified...
Definition: ObjectIdSet.cpp:77
A class that models the name of any property of an object.
Definition: PropertyName.h:50
A class that models the description of a dataset.
Definition: DataSetType.h:72
static const std::string sm_ST_Intersects
Definition: FunctionNames.h:84
std::auto_ptr< LayerSchema > getSchema() const
It returns the layer schema.
Definition: QueryLayer.cpp:84
Expression * getExpression() const
It returns the expression set for an output select query.
Definition: Field.cpp:80
An abstract factory for layer renderers.
virtual Property * clone() const =0
It returns a clone of the object.
SpatialRelation
Spatial relations between geometric objects.
Definition: Enums.h:122
QueryLayer(AbstractLayer *parent=0)
It initializes a new layer.
Definition: QueryLayer.cpp:59
A class that represents the known capabilities of a specific data source, i.e. this class informs all...
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:345
const QueryCapabilities & getQueryCapabilities() const
It models a property definition.
Definition: Property.h:59
Boolean logic operator: AND.
Definition: And.h:46
This is an abstract class that models a query expression.
Definition: Expression.h:47
An exception class for the MapTools module.
AccessPolicy
Supported data access policies (can be used as bitfield).
Definition: Enums.h:40
~QueryLayer()
Destructor.
Definition: QueryLayer.cpp:79
TraverseType
A dataset can be traversed in two ways:
Definition: Enums.h:53
void Tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" ")
It tokenizes a given string with a delimiter of your own choice.
Definition: StringUtils.h:216
void setRendererType(const std::string &t)
Definition: QueryLayer.cpp:306
A class that informs the query support of a given data source.
An operator that considers the intersection among approximations or envelopes of geometries.
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
const std::string & getAlias() const
It returns the alias associated to the source item.
Definition: FromItem.cpp:47
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:53
boost::ptr_vector< Field > Fields
Fields is just a boost::ptr_vector of Field pointers.
Definition: Fields.h:37
const std::string & getDataSourceId() const
Definition: QueryLayer.cpp:291
A class that can be used to model a filter expression that can be applied to a query.
Definition: Where.h:47
static const std::string sm_ST_EnvelopeIntersects
Definition: FunctionNames.h:86
void setExp(Expression *exp)
Sets the expression.
Definition: Where.cpp:65
Expression * getExp() const
Definition: Where.cpp:60
te::da::Select * getQuery() const
Definition: QueryLayer.cpp:279
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
static AbstractRenderer * make(const std::string &factoryKey)
It creates an object with the appropriated factory.
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
const std::set< std::string > & getSpatialTopologicOperators() const
boost::ptr_vector< FromItem > From
It models the FROM clause for a query.
Definition: From.h:37
A canvas is an abstraction of a drawing area.
Definition: Canvas.h:91
void setDataSourceId(const std::string &id)
Definition: QueryLayer.cpp:296
void draw(Canvas *canvas, const te::gm::Envelope &bbox, int srid)
It draws the layer geographic objects in the given canvas using the informed SRS. ...
Definition: QueryLayer.cpp:261
void setQuery(te::da::Select *s)
Definition: QueryLayer.cpp:284
A layer resulting from a query.
A class that models a literal for Envelope values.
const std::string & getRendererType() const
Definition: QueryLayer.cpp:301
const std::string & getName() const
It returns the dataset name.
Definition: DataSetName.cpp:57
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 Expression * clone() const =0
It creates a new copy of this expression.
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:432
static const std::string sm_type
A static data member used in the implementation of getType method.
Definition: QueryLayer.h:173
const std::string & getType() const
It returns the layer type: QUERY_LAYER.
Definition: QueryLayer.cpp:274
bool isValid() const
It returns true if the layer can be used for instance to draw, otherwise, it returns false...
Definition: QueryLayer.cpp:237