All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
BufferQuery.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 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 AggregationQuery.h
22 
23  \brief Aggregation Vector Processing functions.
24 */
25 
26 //Terralib
27 
28 #include "../common/progress/TaskProgress.h"
29 #include "../common/Logger.h"
30 #include "../common/Translator.h"
31 
32 #include "../dataaccess/dataset/DataSet.h"
33 
34 #include "../datatype/Property.h"
35 #include "../datatype/SimpleProperty.h"
36 #include "../datatype/StringProperty.h"
37 
38 #include "../dataaccess/dataset/ObjectIdSet.h"
39 #include "../dataaccess/query/DataSetName.h"
40 #include "../dataaccess/query/Expression.h"
41 #include "../dataaccess/query/Field.h"
42 #include "../dataaccess/query/Fields.h"
43 #include "../dataaccess/query/From.h"
44 #include "../dataaccess/query/FromItem.h"
45 #include "../dataaccess/query/PropertyName.h"
46 #include "../dataaccess/query/Select.h"
47 #include "../dataaccess/query/ST_Buffer.h"
48 #include "../dataaccess/query/ST_Difference.h"
49 #include "../dataaccess/query/Where.h"
50 #include "../dataaccess/utils/Utils.h"
51 
52 #include "../geometry/Geometry.h"
53 #include "../geometry/GeometryCollection.h"
54 #include "../geometry/GeometryProperty.h"
55 #include "../geometry/Utils.h"
56 
57 #include "../memory/DataSet.h"
58 #include "../memory/DataSetItem.h"
59 
60 #include "../sam/rtree.h"
61 
62 #include "BufferQuery.h"
63 #include "Config.h"
64 #include "Exception.h"
65 #include "Utils.h"
66 
67 // STL
68 #include <map>
69 #include <math.h>
70 #include <string>
71 #include <vector>
72 
73 // BOOST
74 #include <boost/lexical_cast.hpp>
75 #include <boost/algorithm/string.hpp>
76 
78 {}
79 
81 {}
82 
83 bool te::vp::BufferQuery::run() throw(te::common::Exception)
84 {
85  te::da::Fields* fields = new te::da::Fields;
86 
87  if(m_copyInputColumns)
88  {
89  std::vector<te::dt::Property*> props = m_inDsetType->getProperties();
90  for(std::size_t i=0; i < props.size(); ++i)
91  {
92  if(props[i]->getType() != te::dt::GEOMETRY_TYPE)
93  {
94  te::da::Field* f_props = new te::da::Field(te::da::PropertyName(props[i]->getName()));
95  fields->push_back(f_props);
96  }
97  }
98  }
99 
100  te::gm::GeometryProperty* geom = te::da::GetFirstGeomProperty(m_inDsetType.get());
101 
102  te::da::Expression* e_buffer = 0;
103  te::da::Expression* e_aux = 0;
104  te::da::Field* f_buffer = 0;
105 
106 
107  for(int i=1; i <= m_levels; ++i)
108  {
109  std::stringstream ss;
110  ss << i;
111  std::string index = ss.str();
112 
113  //buffer
114  if(m_bufferPolygonRule == te::vp::INSIDE_OUTSIDE)
115  {
116  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), m_distance*i);
117  te::da::Expression* e_buffer2 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), -m_distance*i);
118  e_buffer = new te::da::ST_Difference(e_buffer1, e_buffer2);
119  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
120  }
121  else if(m_bufferPolygonRule == te::vp::ONLY_OUTSIDE)
122  {
123  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), m_distance*i);
124  te::da::Expression* e_buffer2 = new te::da::PropertyName(geom->getName());
125  e_buffer = new te::da::ST_Difference(e_buffer1, e_buffer2);
126  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
127  }
128  else
129  {
130  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), -m_distance*i);
131  te::da::Expression* e_buffer2 = new te::da::PropertyName(geom->getName());
132  e_buffer = new te::da::ST_Difference(e_buffer2, e_buffer1);
133  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
134  }
135 
136  if(!e_aux)
137  {
138  fields->push_back(f_buffer);
139  e_aux = e_buffer;
140  }
141  else
142  {
143  te::da::Expression* e_diff = new te::da::ST_Difference(e_buffer, e_aux);
144  f_buffer = new te::da::Field(*e_diff, "geom"+index);
145  fields->push_back(f_buffer);
146  e_aux = e_buffer;
147  }
148  }
149 
150  te::da::FromItem* fromItem = new te::da::DataSetName(m_inDsetType->getName());
151  te::da::From* from = new te::da::From;
152  from->push_back(fromItem);
153 
154  te::da::Where* w_oid = 0;
155 
156  if(m_oidSet)
157  {
158  w_oid = new te::da::Where(m_oidSet->getExpression());
159  }
160 
161  te::da::Select select(fields, from, w_oid);
162  std::auto_ptr<te::da::DataSet> dsQuery = m_inDsrc->query(select);
163 
164  std::auto_ptr<te::da::DataSetType> outDSType(GetDataSetType());
165  std::auto_ptr<te::mem::DataSet> outDSet(new te::mem::DataSet(outDSType.get()));
166 
167  if(m_bufferBoundariesRule == te::vp::DISSOLVE)
168  {
169  std::vector<std::vector<te::gm::Geometry*> > vecDissolvedGeom = dissolveQuery(dsQuery.get(), m_levels);
170  prepareDataSet(outDSType.get(), vecDissolvedGeom, outDSet.get(), m_distance);
171  }
172  else
173  {
174  prepareDataSet(outDSType.get(), dsQuery.get(), outDSet.get(), m_distance);
175  }
176 
177  te::vp::Save(m_outDsrc.get(), outDSet.get(), outDSType.get());
178  return true;
179 
180 }
181 
182 std::vector<std::vector<te::gm::Geometry*> > te::vp::BufferQuery::dissolveQuery(te::da::DataSet* dsQuery,
183  const int& levels)
184 {
185  std::map<int, std::vector<te::gm::Geometry*> > mapGeom;
186  std::vector<std::vector<te::gm::Geometry*> > vecGeom;
187 
188  for(int i = 0; i < levels; ++i)
189  {
191 
192  dsQuery->moveBeforeFirst();
193  while(dsQuery->moveNext())
194  {
195  te::gm::Geometry* geom = dsQuery->getGeometry(i).release();
196 
197  std::vector<te::gm::Geometry*> vec;
198 
199  rtree.search(*(geom->getMBR()), vec);
200 
201  if(!vec.empty())
202  {
203  for(std::size_t t = 0; t < vec.size(); ++t)
204  {
205  if(geom->intersects(vec[t]))
206  {
207  geom = geom->Union(vec[t]);
208  rtree.remove(*(vec[t]->getMBR()), vec[t]);
209  }
210  }
211  }
212  rtree.insert(*(geom->getMBR()), geom);
213  }
214 
215  std::vector<te::gm::Geometry*> geomVec;
216  std::auto_ptr<te::gm::Envelope> e = dsQuery->getExtent(i);
217  rtree.search(*(e.get()), geomVec);
218  vecGeom.push_back(geomVec);
219 
220  rtree.clear();
221  }
222 
223  std::size_t vecSize = vecGeom.size();
224 
225  if(levels > 1)
226  {
227  for(std::size_t i = vecSize - 1; i > 0; --i)
228  {
229  std::vector<te::gm::Geometry*> currentVec = vecGeom[i];
230  std::size_t c_vecSize = currentVec.size();
231 
232  for(std::size_t j = 0; j < i; ++j)
233  {
234  std::vector<te::gm::Geometry*> innerVec = vecGeom[j];
235  std::size_t i_vecSize = innerVec.size();
236 
237  for(std::size_t k = 0; k < c_vecSize; ++k)
238  {
239  for(std::size_t l = 0; l < i_vecSize; ++l)
240  {
241  te::gm::Geometry* k_geom = currentVec[k];
242  te::gm::Geometry* l_geom = innerVec[l];
243 
244  if(k_geom->intersects(l_geom))
245  {
246  te::gm::Geometry* tGeom = k_geom->difference(l_geom);
247  if(tGeom->isValid())
248  {
249  delete currentVec[k];
250  currentVec[k] = tGeom;
251  vecGeom[i] = currentVec;
252  }
253  }
254  }
255  }
256  }
257  }
258  }
259 
260  return vecGeom;
261 }
262 
264  te::da::DataSet* dataSetQuery,
265  te::mem::DataSet* outputDataSet,
266  const double& distance)
267 {
268  std::size_t numProps = dataSetQuery->getNumProperties();
269  std::size_t firstGeomPos = te::da::GetFirstSpatialPropertyPos(dataSetQuery);
270  int numItems = numProps - firstGeomPos;
271  int pk = 0;
272  dataSetQuery->moveBeforeFirst();
273 
274  unsigned int type;
275 
276  while(dataSetQuery->moveNext())
277  {
278  int numCurrentItem = 0;
279 
280  for(int i = 0; i < numItems; ++i)
281  {
282  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
283 
284  for(std::size_t j = 0; j < numProps; ++j)
285  {
286  type = dataSetQuery->getPropertyDataType(j);
287 
288  switch (type){
289  case te::dt::INT32_TYPE:
290  dataSetItem->setInt32(j+3, dataSetQuery->getInt32(j));
291  break;
292  case te::dt::INT64_TYPE:
293  dataSetItem->setInt64(j+3, dataSetQuery->getInt64(j));
294  break;
295  case te::dt::DOUBLE_TYPE:
296  dataSetItem->setDouble(j+3, dataSetQuery->getDouble(j));
297  break;
298  case te::dt::STRING_TYPE:
299  dataSetItem->setString(j+3, dataSetQuery->getString(j));
300  break;
302  {
303  dataSetItem->setInt32(0, pk); //pk
304  dataSetItem->setInt32(1, i+1); //level
305  dataSetItem->setDouble(2, distance*(i+1)); //distance
306 
307  std::auto_ptr<te::gm::Geometry> geom = dataSetQuery->getGeometry(j+numCurrentItem);
308  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
309  {
310  dataSetItem->setGeometry(j+3, geom.release());
311  }
312  else
313  {
314  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
315  mPolygon->add(geom.release());
316  dataSetItem->setGeometry(j+3, mPolygon.release());
317  }
318 
319  outputDataSet->add(dataSetItem);
320 
321  ++numCurrentItem;
322  ++pk;
323  j = numProps;
324  }
325  break;
326  default:
327 #ifdef TERRALIB_LOGGER_ENABLED
328  te::common::Logger::logDebug("vp", "Buffer - Type not found.");
329 #endif //TERRALIB_LOGGER_ENABLED
330  break;
331  }
332  }
333  }
334  }
335 }
336 
338  std::vector<std::vector<te::gm::Geometry*> > vecDissolvedGeom,
339  te::mem::DataSet* outputDataSet,
340  const double& distance)
341 {
342  int pk = 0;
343 
344  for(std::size_t i = 0; i < vecDissolvedGeom.size(); ++i)
345  {
346  std::vector<te::gm::Geometry*> vecGeom = vecDissolvedGeom[i];
347  std::size_t sizeVecGeom = vecGeom.size();
348 
349  for(std::size_t j=0; j < sizeVecGeom; ++j)
350  {
351  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
352  dataSetItem->setInt32(0, pk); //pk
353  dataSetItem->setInt32(1, i+1); //level
354  dataSetItem->setDouble(2, distance*(i+1)); //distance
355 
356  std::auto_ptr<te::gm::Geometry> geom(vecGeom[j]);
357 
358  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
359  {
360  dataSetItem->setGeometry(3, geom.release());
361  }
362  else
363  {
364  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
365  mPolygon->add(geom.release());
366  dataSetItem->setGeometry(3, mPolygon.release());
367  }
368 
369  outputDataSet->add(dataSetItem);
370 
371  ++pk;
372  }
373  }
374 }
bool remove(const te::gm::Envelope &mbr, const DATATYPE &data)
It removes an item from the tree.
Definition: Index.h:320
Geometric property.
An exception class for the Vector processing module.
void setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
Utility functions for the data access module.
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
virtual boost::int32_t getInt32(std::size_t i) const =0
Method for retrieving a 32-bit integer attribute value (4 bytes long).
void setDouble(std::size_t i, double value)
It sets the value of the i-th property.
A class that models the name of a dataset used in a From clause.
Definition: DataSetName.h:43
virtual bool intersects(const Geometry *const rhs) const
It returns true if the geometry object spatially intersects rhs geometry.
Definition: Geometry.cpp:254
A class that represents an R-tree.
Definition: Index.h:56
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
void prepareDataSet(te::da::DataSetType *dataSetType, te::da::DataSet *dataSetQuery, te::mem::DataSet *outputDataSet, const double &distance)
virtual boost::int64_t getInt64(std::size_t i) const =0
Method for retrieving a 64-bit integer attribute value (8 bytes long).
void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType)
Definition: Utils.cpp:213
std::vector< std::vector< te::gm::Geometry * > > dissolveQuery(te::da::DataSet *dsQuery, const int &levels)
virtual double getDouble(std::size_t i) const =0
Method for retrieving a double attribute value.
This is an abstract class that models a query expression.
Definition: Expression.h:47
void add(DataSetItem *item)
It adds a new item to the dataset and takes its ownership.
Definition: DataSet.cpp:172
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
The buffer is generated only outside of the polygons.
Definition: Enums.h:80
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
Definition: DataSet.h:65
TEDATAACCESSEXPORT std::size_t GetFirstSpatialPropertyPos(const te::da::DataSet *dataset)
It returns the first dataset spatial property or NULL if none is found.
Definition: Utils.cpp:462
Spatial Buffer operator.
Definition: ST_Buffer.h:51
boost::ptr_vector< Field > Fields
Fields is just a boost::ptr_vector of Field pointers.
Definition: Fields.h:37
Spatial difference operator.
Definition: ST_Difference.h:46
A class that can be used to model a filter expression that can be applied to a query.
Definition: Where.h:47
virtual bool isValid() const
It tells if the geometry is well formed.
Definition: Geometry.cpp:168
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
Definition: Index.h:326
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
virtual std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
boost::ptr_vector< FromItem > From
It models the FROM clause for a query.
Definition: From.h:37
The buffer is generated Inside and outside of the polygons.
Definition: Enums.h:79
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Definition: DataSetItem.h:56
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:112
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
Definition: Index.h:313
virtual std::auto_ptr< te::gm::Envelope > getExtent(std::size_t i)=0
It computes the bounding rectangle for a spatial property of the dataset.
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
TEDATAACCESSEXPORT DataSetType * GetDataSetType(const std::string &name, const std::string &datasourceId)
Definition: Utils.cpp:228
Configuration flags for the Terrralib Vector Processing module.
virtual std::string getString(std::size_t i) const =0
Method for retrieving a string value attribute.
void setString(std::size_t i, const std::string &value)
It sets the value of the i-th property.
virtual Geometry * Union(const Geometry *const rhs) const
It returns a geometric object that represents the point set union with another geometry.
Definition: Geometry.cpp:544
void setInt64(std::size_t i, boost::int64_t value)
It sets the value of the i-th property.
It is a collection of other geometric objects.
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:557
virtual int getPropertyDataType(std::size_t i) const =0
It returns the underlying data type of the property at position pos.
const Envelope * getMBR() const
It returns the minimum bounding rectangle for the geometry in an internal representation.
Definition: Geometry.cpp:104
virtual Geometry * difference(const Geometry *const rhs) const
It returns a geometric object that represents the point set difference with another geometry...
Definition: Geometry.cpp:567
void clear(void)
Definition: Index.h:299
The boundaries between buffers will be dissolved.
Definition: Enums.h:91
const std::string & getName() const
It returns the property name.
Definition: Property.h:127