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-2013 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 
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  return save(outDSet,outDSType);
178 }
179 
180 std::vector<std::vector<te::gm::Geometry*> > te::vp::BufferQuery::dissolveQuery(te::da::DataSet* dsQuery,
181  const int& levels)
182 {
183  std::map<int, std::vector<te::gm::Geometry*> > mapGeom;
184  std::vector<std::vector<te::gm::Geometry*> > vecGeom;
185 
186  for(int i = 0; i < levels; ++i)
187  {
189 
190  dsQuery->moveBeforeFirst();
191  while(dsQuery->moveNext())
192  {
193  te::gm::Geometry* geom = dsQuery->getGeometry(i).release();
194 
195  std::vector<te::gm::Geometry*> vec;
196 
197  rtree.search(*(geom->getMBR()), vec);
198 
199  if(!vec.empty())
200  {
201  for(std::size_t t = 0; t < vec.size(); ++t)
202  {
203  if(geom->intersects(vec[t]))
204  {
205  geom = geom->Union(vec[t]);
206  rtree.remove(*(vec[t]->getMBR()), vec[t]);
207  }
208  }
209  }
210  rtree.insert(*(geom->getMBR()), geom);
211  }
212 
213  std::vector<te::gm::Geometry*> geomVec;
214  std::auto_ptr<te::gm::Envelope> e = dsQuery->getExtent(i);
215  rtree.search(*(e.get()), geomVec);
216  vecGeom.push_back(geomVec);
217 
218  rtree.clear();
219  }
220 
221  std::size_t vecSize = vecGeom.size();
222 
223  if(levels > 1)
224  {
225  for(std::size_t i = vecSize - 1; i > 0; --i)
226  {
227  std::vector<te::gm::Geometry*> currentVec = vecGeom[i];
228  std::size_t c_vecSize = currentVec.size();
229 
230  for(std::size_t j = 0; j < i; ++j)
231  {
232  std::vector<te::gm::Geometry*> innerVec = vecGeom[j];
233  std::size_t i_vecSize = innerVec.size();
234 
235  for(std::size_t k = 0; k < c_vecSize; ++k)
236  {
237  for(std::size_t l = 0; l < i_vecSize; ++l)
238  {
239  te::gm::Geometry* k_geom = currentVec[k];
240  te::gm::Geometry* l_geom = innerVec[l];
241 
242  if(k_geom->intersects(l_geom))
243  {
244  te::gm::Geometry* tGeom = k_geom->difference(l_geom);
245  if(tGeom->isValid())
246  {
247  delete currentVec[k];
248  currentVec[k] = tGeom;
249  vecGeom[i] = currentVec;
250  }
251  }
252  }
253  }
254  }
255  }
256  }
257 
258  return vecGeom;
259 }
260 
262  te::da::DataSet* dataSetQuery,
263  te::mem::DataSet* outputDataSet,
264  const double& distance)
265 {
266  std::size_t numProps = dataSetQuery->getNumProperties();
267  std::size_t firstGeomPos = te::da::GetFirstSpatialPropertyPos(dataSetQuery);
268  int numItems = numProps - firstGeomPos;
269  int pk = 0;
270  dataSetQuery->moveBeforeFirst();
271 
272  unsigned int type;
273 
274  while(dataSetQuery->moveNext())
275  {
276  int numCurrentItem = 0;
277 
278  for(int i = 0; i < numItems; ++i)
279  {
280  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
281 
282  for(std::size_t j = 0; j < numProps; ++j)
283  {
284  type = dataSetQuery->getPropertyDataType(j);
285 
286  switch (type){
287  case te::dt::INT32_TYPE:
288  dataSetItem->setInt32(j+3, dataSetQuery->getInt32(j));
289  break;
290  case te::dt::INT64_TYPE:
291  dataSetItem->setInt64(j+3, dataSetQuery->getInt64(j));
292  break;
293  case te::dt::DOUBLE_TYPE:
294  dataSetItem->setDouble(j+3, dataSetQuery->getDouble(j));
295  break;
296  case te::dt::STRING_TYPE:
297  dataSetItem->setString(j+3, dataSetQuery->getString(j));
298  break;
300  {
301  dataSetItem->setInt32(0, pk); //pk
302  dataSetItem->setInt32(1, i+1); //level
303  dataSetItem->setDouble(2, distance*(i+1)); //distance
304 
305  std::auto_ptr<te::gm::Geometry> geom = dataSetQuery->getGeometry(j+numCurrentItem);
306  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
307  {
308  dataSetItem->setGeometry(j+3, geom.release());
309  }
310  else
311  {
312  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
313  mPolygon->add(geom.release());
314  dataSetItem->setGeometry(j+3, mPolygon.release());
315  }
316 
317  outputDataSet->add(dataSetItem);
318 
319  ++numCurrentItem;
320  ++pk;
321  j = numProps;
322  }
323  break;
324  default:
325  te::common::Logger::logDebug("vp", "Buffer - Type not found.");
326  }
327  }
328  }
329  }
330 }
331 
333  std::vector<std::vector<te::gm::Geometry*> > vecDissolvedGeom,
334  te::mem::DataSet* outputDataSet,
335  const double& distance)
336 {
337  int pk = 0;
338 
339  for(std::size_t i = 0; i < vecDissolvedGeom.size(); ++i)
340  {
341  std::vector<te::gm::Geometry*> vecGeom = vecDissolvedGeom[i];
342  std::size_t sizeVecGeom = vecGeom.size();
343 
344  for(std::size_t j=0; j < sizeVecGeom; ++j)
345  {
346  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
347  dataSetItem->setInt32(0, pk); //pk
348  dataSetItem->setInt32(1, i+1); //level
349  dataSetItem->setDouble(2, distance*(i+1)); //distance
350 
351  std::auto_ptr<te::gm::Geometry> geom(vecGeom[j]);
352 
353  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
354  {
355  dataSetItem->setGeometry(3, geom.release());
356  }
357  else
358  {
359  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
360  mPolygon->add(geom.release());
361  dataSetItem->setGeometry(3, mPolygon.release());
362  }
363 
364  outputDataSet->add(dataSetItem);
365 
366  ++pk;
367  }
368  }
369 }
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:243
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).
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:168
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:413
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:167
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:225
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:473
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:508
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:103
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:492
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:126