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