All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
BufferMemory.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 AggregationMemory.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 #include "../dataaccess/utils/Utils.h"
34 #include "../datatype/Property.h"
35 #include "../datatype/SimpleProperty.h"
36 #include "../datatype/StringProperty.h"
37 
38 #include "../geometry/Geometry.h"
39 #include "../geometry/GeometryCollection.h"
40 #include "../geometry/GeometryProperty.h"
41 #include "../geometry/Utils.h"
42 
43 #include "../memory/DataSet.h"
44 #include "../memory/DataSetItem.h"
45 
46 #include "../sam/rtree.h"
47 
48 #include "BufferMemory.h"
49 #include "Config.h"
50 #include "Exception.h"
51 #include "Utils.h"
52 
53 // STL
54 #include <map>
55 #include <string>
56 #include <vector>
57 
58 // BOOST
59 #include <boost/lexical_cast.hpp>
60 #include <boost/algorithm/string.hpp>
61 
63 {}
64 
66 {}
67 
69 {
70  std::auto_ptr<te::da::DataSetType> outDSType(GetDataSetType());
71  std::auto_ptr<te::mem::DataSet> outDSet(new te::mem::DataSet(outDSType.get()));
72 
73  int type;
74  int pk = 0;
75 
76  std::auto_ptr<te::da::DataSet> inDset;
77 
78  if(m_oidSet == 0)
79  inDset = m_inDsrc->getDataSet(m_inDsetName);
80  else
81  inDset = m_inDsrc->getDataSet(m_inDsetName, m_oidSet);
82 
83  inDset->moveBeforeFirst();
84 
85  while(inDset->moveNext())
86  {
87  te::gm::Geometry* auxGeom = 0;
88 
89  for(int i = 1; i <= m_levels; ++i)
90  {
91  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outDSet.get());
92 
93  for(std::size_t j = 0; j < inDset->getNumProperties(); ++j)
94  {
95  type = inDset->getPropertyDataType(j);
96  if(m_copyInputColumns)
97  {
98  switch (type)
99  {
100  case te::dt::INT32_TYPE:
101  if(inDset->getPropertyName(j) != "FID")
102  dataSetItem->setInt32(j+2, inDset->getInt32(j));
103  break;
104  case te::dt::INT64_TYPE:
105  dataSetItem->setInt64(j+2, inDset->getInt64(j));
106  break;
107  case te::dt::DOUBLE_TYPE:
108  dataSetItem->setDouble(j+2, inDset->getDouble(j));
109  break;
110  case te::dt::STRING_TYPE:
111  dataSetItem->setString(j+2, inDset->getString(j));
112  break;
114  {
115  dataSetItem->setInt32(0, pk); //pk
116  dataSetItem->setInt32(1, i); //level
117  dataSetItem->setDouble(2, m_distance*(i)); //distance
118 
119  std::auto_ptr<te::gm::Geometry> currentGeom = inDset->getGeometry(j);
120  std::auto_ptr<te::gm::Geometry> outGeom;
121 
122  if(currentGeom->isValid())
123  outGeom.reset(setBuffer(currentGeom.get(), m_distance, i, auxGeom));
124  else
125  te::common::Logger::logDebug("vp", "Buffer - Invalid geometry found");
126 
127  if(outGeom.get() && outGeom->isValid())
128  {
129  if(outGeom->getGeomTypeId() == te::gm::MultiPolygonType)
130  {
131  dataSetItem->setGeometry(j+2, outGeom.release());
132  }
133  else
134  {
135  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, outGeom->getSRID()));
136  mPolygon->add(outGeom.release());
137  dataSetItem->setGeometry(j+2, mPolygon.release());
138  }
139 
140  outDSet->add(dataSetItem);
141  ++pk;
142  }
143  }
144  break;
145  default:
146  te::common::Logger::logDebug("vp", "Buffer - Type not found.");
147  }
148  }
149  else
150  {
151  if(type == te::dt::GEOMETRY_TYPE)
152  {
153  dataSetItem->setInt32(0, pk); //pk
154  dataSetItem->setInt32(1, i); //level
155  dataSetItem->setDouble(2, m_distance*(i)); //distance
156 
157  std::auto_ptr<te::gm::Geometry> currentGeom = inDset->getGeometry(j);
158  std::auto_ptr<te::gm::Geometry> outGeom;
159 
160  if(currentGeom->isValid())
161  outGeom.reset(setBuffer(currentGeom.get(), m_distance, i, auxGeom));
162  else
163  te::common::Logger::logDebug("vp", "Buffer - Invalid geometry found");
164 
165  if(outGeom.get() && outGeom->isValid())
166  {
167  if(outGeom->getGeomTypeId() == te::gm::MultiPolygonType)
168  {
169  dataSetItem->setGeometry(3, outGeom.release());
170  }
171  else
172  {
173  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, outGeom->getSRID()));
174  mPolygon->add(outGeom.release());
175  dataSetItem->setGeometry(3, mPolygon.release());
176  }
177 
178  outDSet->add(dataSetItem);
179  ++pk;
180  }
181  }
182  }
183  }
184  }
185  }
186 
187  if(m_bufferBoundariesRule == te::vp::DISSOLVE)
188  {
189  dissolveMemory(outDSet.get(), m_levels);
190  }
191 
192  return save(outDSet,outDSType);
193 }
194 
195 
197  const double& distance,
198  const int& level,
199  te::gm::Geometry*& auxGeom)
200 {
201  te::gm::Geometry* geomResult = 0;
202  te::gm::Geometry* geomTemp = 0;
203  std::auto_ptr<te::gm::Geometry> outGeom;
204  std::auto_ptr<te::gm::Geometry> inGeom;
205  switch(m_bufferPolygonRule)
206  {
207  case (te::vp::INSIDE_OUTSIDE):
208  outGeom.reset(geom->buffer(distance * level, 16, te::gm::CapButtType));
209  inGeom.reset(geom->buffer(-distance * level, 16, te::gm::CapButtType));
210  geomResult = outGeom->difference(inGeom.get());
211 
212  geomTemp = (te::gm::Geometry*)geomResult->clone();
213  if(auxGeom && auxGeom->isValid())
214  geomResult = geomResult->difference(auxGeom);
215 
216  delete auxGeom;
217  auxGeom = geomTemp;
218 
219  break;
220 
221  case (te::vp::ONLY_OUTSIDE):
222  outGeom.reset(geom->buffer(distance * level, 16, te::gm::CapButtType));
223  geomResult = outGeom->difference(geom);
224 
225  geomTemp = (te::gm::Geometry*)geomResult->clone();
226  if(auxGeom && auxGeom->isValid())
227  geomResult = geomResult->difference(auxGeom);
228 
229  delete auxGeom;
230  auxGeom = geomTemp;
231 
232  break;
233 
234  case (te::vp::ONLY_INSIDE):
235  inGeom.reset(geom->buffer(-distance * level, 16, te::gm::CapButtType));
236  geomResult = geom->difference(inGeom.get());
237 
238  geomTemp = (te::gm::Geometry*)geomResult->clone();
239  if(auxGeom && auxGeom->isValid())
240  geomResult = geomResult->difference(auxGeom);
241 
242  delete auxGeom;
243  auxGeom = geomTemp;
244 
245  break;
246 
247  default:
248  te::common::Logger::logDebug("vp", "Buffer - Polygon rule not found.");
249  }
250  return geomResult;
251 }
252 
254  const int& levels)
255 {
256  std::vector<std::vector<te::gm::Geometry*> > vecGeom;
257 
258  int levelPos = te::da::GetPropertyPos(outDSet, "level");
259  int geomPos = te::da::GetPropertyPos(outDSet, "geom");
260  int level;
261 
262  //te::common::TaskProgress task1("Dissolving boundaries...");
263  //task1.setTotalSteps(levels*outDSet->size());
264  //task1.setCurrentStep(1);
265  for(int i = 1; i <= levels; ++i)
266  {
268 
269  outDSet->moveBeforeFirst();
270  while(outDSet->moveNext())
271  {
272  level = outDSet->getInt32(levelPos);
273  if(level == i)
274  {
275  te::gm::Geometry* geom = outDSet->getGeometry(geomPos).release();
276 
277  std::vector<te::gm::Geometry*> vec;
278 
279  rtree.search(*(geom->getMBR()), vec);
280 
281  if(!vec.empty())
282  {
283  for(std::size_t t = 0; t < vec.size(); ++t)
284  {
285  if(geom->intersects(vec[t]))
286  {
287  geom = geom->Union(vec[t]);
288  rtree.remove(*(vec[t]->getMBR()), vec[t]);
289  }
290  }
291  }
292  rtree.insert(*(geom->getMBR()), geom);
293  }
294  //task1.pulse();
295  }
296 
297  std::vector<te::gm::Geometry*> geomVec;
298  std::auto_ptr<te::gm::Envelope> e = outDSet->getExtent(geomPos);
299  rtree.search(*(e.get()), geomVec);
300 
301  vecGeom.push_back(geomVec);
302 
303  rtree.clear();
304  }
305 
306  outDSet->clear();
307  outDSet->moveBeforeFirst();
308 
309 
310  int pk = 0;
311  std::size_t vecSize = vecGeom.size();
312 
313  //task1.setTotalSteps(vecSize);
314  //task1.setCurrentStep(1);
315  if(levels > 1)
316  {
317  for(std::size_t i = vecSize - 1; i > 0; --i)
318  {
319  std::vector<te::gm::Geometry*> currentVec = vecGeom[i];
320  std::size_t c_vecSize = currentVec.size();
321 
322  for(std::size_t j = 0; j < i; ++j)
323  {
324  std::vector<te::gm::Geometry*> innerVec = vecGeom[j];
325  std::size_t i_vecSize = innerVec.size();
326 
327  for(std::size_t k = 0; k < c_vecSize; ++k)
328  {
329  for(std::size_t l = 0; l < i_vecSize; ++l)
330  {
331  te::gm::Geometry* k_geom = currentVec[k];
332  te::gm::Geometry* l_geom = innerVec[l];
333 
334  if(k_geom->intersects(l_geom))
335  {
336  te::gm::Geometry* tGeom = k_geom->difference(l_geom);
337  if(tGeom->isValid())
338  {
339  delete currentVec[k];
340  currentVec[k] = tGeom;
341  vecGeom[i] = currentVec;
342  }
343  }
344  }
345  }
346  }
347  //task1.pulse();
348  }
349  }
350 
351  //task1.setTotalSteps(vecSize);
352  //task1.setCurrentStep(1);
353  for(std::size_t i = 0; i < vecSize; ++i)
354  {
355  std::vector<te::gm::Geometry*> currentVec = vecGeom[i];
356  std::size_t c_vecSize = currentVec.size();
357 
358  for(std::size_t j = 0; j < c_vecSize; ++j)
359  {
360  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outDSet);
361  dataSetItem->setInt32(0, pk); //pk
362  dataSetItem->setInt32(1, i+1); //level
363  dataSetItem->setDouble(2, 0/*distance*(i)*/); //distance
364 
365  if(currentVec[j]->getGeomTypeId() == te::gm::MultiPolygonType)
366  {
367  dataSetItem->setGeometry(3, currentVec[j]);
368  }
369  else
370  {
371  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, currentVec[j]->getSRID()));
372  te::gm::GeometryCollection* gcIn = dynamic_cast<te::gm::GeometryCollection*>(currentVec[j]);
373  if(gcIn == 0)
374  mPolygon->add(currentVec[j]);
375  else
376  te::vp::SplitGeometryCollection(gcIn, mPolygon.get());
377 
378  dataSetItem->setGeometry(3, mPolygon.release());
379  }
380 
381  outDSet->add(dataSetItem);
382  ++pk;
383  }
384  //task1.pulse();
385  }
386 }
387 
bool remove(const te::gm::Envelope &mbr, const DATATYPE &data)
It removes an item from the tree.
Definition: Index.h:320
std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const
Method for retrieving a geometric attribute value.
Definition: DataSet.cpp:533
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.
virtual Geometry * buffer(const double &distance) const
This method calculates the buffer of a geometry.
Definition: Geometry.cpp:406
void setDouble(std::size_t i, double value)
It sets the value of the i-th property.
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
int getPropertyDataType(std::size_t pos) const
It returns the type of the pos-th property.
TEDATAACCESSEXPORT std::size_t GetPropertyPos(const DataSet *dataset, const std::string &name)
Definition: Utils.cpp:451
te::gm::Geometry * setBuffer(te::gm::Geometry *geom, const double &distance, const int &level, te::gm::Geometry *&auxGeom)
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.
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
boost::int32_t getInt32(std::size_t i) const
Method for retrieving a 32-bit integer attribute value (4 bytes long).
Definition: DataSet.cpp:413
void SplitGeometryCollection(te::gm::GeometryCollection *geomIn, te::gm::GeometryCollection *gcOut)
Definition: Utils.cpp:144
The buffer is generated only inside of the polygons.
Definition: Enums.h:81
std::auto_ptr< te::gm::Envelope > getExtent(std::size_t i)
It computes the bounding rectangle for a spatial property of the dataset.
Definition: DataSet.cpp:237
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
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
Definition: DataSet.cpp:324
void dissolveMemory(te::mem::DataSet *outDSet, const int &levels)
bool moveNext()
It moves the internal pointer to the next item of the collection.
Definition: DataSet.cpp:312
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
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
Definition: Index.h:313
void add(Geometry *g)
It adds the geometry into the collection.
TEDATAACCESSEXPORT DataSetType * GetDataSetType(const std::string &name, const std::string &datasourceId)
Definition: Utils.cpp:225
void clear()
It clears all the dataset items.
Definition: DataSet.cpp:110
Configuration flags for the Terrralib Vector Processing module.
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.
virtual AbstractData * clone() const =0
It returns a clone of this object.
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