BufferMemory.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 AggregationMemory.h
22 
23  \brief Aggregation Vector Processing functions.
24 */
25 
26 //Terralib
27 
28 #include "../BuildConfig.h"
29 #include "../common/progress/TaskProgress.h"
30 #include "../common/Logger.h"
31 #include "../common/Translator.h"
32 
33 #include "../dataaccess/dataset/DataSet.h"
34 #include "../dataaccess/dataset/DataSetAdapter.h"
35 #include "../dataaccess/utils/Utils.h"
36 #include "../datatype/Property.h"
37 #include "../datatype/SimpleProperty.h"
38 #include "../datatype/StringProperty.h"
39 
40 #include "../geometry/Geometry.h"
41 #include "../geometry/GeometryCollection.h"
42 #include "../geometry/GeometryProperty.h"
43 #include "../geometry/Utils.h"
44 
45 #include "../memory/DataSet.h"
46 #include "../memory/DataSetItem.h"
47 
48 #include "../sam/rtree.h"
49 
50 #include "BufferMemory.h"
51 #include "Config.h"
52 #include "Exception.h"
53 #include "Utils.h"
54 
55 // STL
56 #include <map>
57 #include <string>
58 #include <vector>
59 
60 // BOOST
61 #include <boost/lexical_cast.hpp>
62 #include <boost/algorithm/string.hpp>
63 
65 {}
66 
68 {}
69 
70 bool te::vp::BufferMemory::run() throw(te::common::Exception)
71 {
72  std::auto_ptr<te::da::DataSetType> outDSType(GetDataSetType());
73  std::auto_ptr<te::mem::DataSet> outDSet(new te::mem::DataSet(outDSType.get()));
74 
75  int type;
76  int pk = 0;
77 
78  std::auto_ptr<te::da::DataSet> inDsetSrc;
79 
80  if(m_oidSet == 0)
81  inDsetSrc = m_inDsrc->getDataSet(m_inDsetName);
82  else
83  inDsetSrc = m_inDsrc->getDataSet(m_inDsetName, m_oidSet);
84 
85  std::auto_ptr<te::da::DataSetAdapter> inDset(te::da::CreateAdapter(inDsetSrc.get(), m_converter.get()));
86 
87  inDset->moveBeforeFirst();
88 
89  while(inDset->moveNext())
90  {
91  te::gm::Geometry* auxGeom = 0;
92 
93  for(int i = 1; i <= m_levels; ++i)
94  {
95  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outDSet.get());
96 
97  for(std::size_t j = 0; j < inDset->getNumProperties(); ++j)
98  {
99  type = inDset->getPropertyDataType(j);
100  if(m_copyInputColumns)
101  {
102  switch (type)
103  {
104  case te::dt::INT32_TYPE:
105  if(inDset->getPropertyName(j) != "FID")
106  dataSetItem->setInt32(j+2, inDset->getInt32(j));
107  break;
108  case te::dt::INT64_TYPE:
109  dataSetItem->setInt64(j+2, inDset->getInt64(j));
110  break;
111  case te::dt::DOUBLE_TYPE:
112  dataSetItem->setDouble(j+2, inDset->getDouble(j));
113  break;
114  case te::dt::STRING_TYPE:
115  dataSetItem->setString(j+2, inDset->getString(j));
116  break;
118  {
119  dataSetItem->setInt32(0, pk); //pk
120  dataSetItem->setInt32(1, i); //level
121  dataSetItem->setDouble(2, m_distance*(i)); //distance
122 
123  std::auto_ptr<te::gm::Geometry> currentGeom = inDset->getGeometry(j);
124  std::auto_ptr<te::gm::Geometry> outGeom;
125 
126  if (currentGeom->isValid())
127  {
128  outGeom.reset(setBuffer(currentGeom.get(), m_distance, i, auxGeom));
129  }
130  else
131  {
132 #ifdef TERRALIB_LOGGER_ENABLED
133  te::common::Logger::logDebug("vp", "Buffer - Invalid geometry found");
134 #endif //TERRALIB_LOGGER_ENABLED
135  }
136 
137  if(outGeom.get() && outGeom->isValid())
138  {
139  if(outGeom->getGeomTypeId() == te::gm::MultiPolygonType)
140  {
141  dataSetItem->setGeometry(j+2, outGeom.release());
142  }
143  else
144  {
145  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, outGeom->getSRID()));
146  mPolygon->add(outGeom.release());
147  dataSetItem->setGeometry(j+2, mPolygon.release());
148  }
149 
150  outDSet->add(dataSetItem);
151  ++pk;
152  }
153  }
154  break;
155  default:
156  {
157 #ifdef TERRALIB_LOGGER_ENABLED
158  te::common::Logger::logDebug("vp", "Buffer - Type not found.");
159 #endif //TERRALIB_LOGGER_ENABLED
160  }
161  }
162  }
163  else
164  {
165  if(type == te::dt::GEOMETRY_TYPE)
166  {
167  dataSetItem->setInt32(0, pk); //pk
168  dataSetItem->setInt32(1, i); //level
169  dataSetItem->setDouble(2, m_distance*(i)); //distance
170 
171  std::auto_ptr<te::gm::Geometry> currentGeom = inDset->getGeometry(j);
172  std::auto_ptr<te::gm::Geometry> outGeom;
173 
174  if (currentGeom->isValid())
175  {
176  outGeom.reset(setBuffer(currentGeom.get(), m_distance, i, auxGeom));
177  }
178  else
179  {
180 #ifdef TERRALIB_LOGGER_ENABLED
181  te::common::Logger::logDebug("vp", "Buffer - Invalid geometry found");
182 #endif //TERRALIB_LOGGER_ENABLED
183  }
184 
185  if(outGeom.get() && outGeom->isValid())
186  {
187  if(outGeom->getGeomTypeId() == te::gm::MultiPolygonType)
188  {
189  dataSetItem->setGeometry(3, outGeom.release());
190  }
191  else
192  {
193  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, outGeom->getSRID()));
194  mPolygon->add(outGeom.release());
195  dataSetItem->setGeometry(3, mPolygon.release());
196  }
197 
198  outDSet->add(dataSetItem);
199  ++pk;
200  }
201  }
202  }
203  }
204  }
205  }
206 
207  if(m_bufferBoundariesRule == te::vp::DISSOLVE)
208  {
209  dissolveMemory(outDSet.get(), m_levels);
210  }
211 
212  te::vp::Save(m_outDsrc.get(), outDSet.get(), outDSType.get());
213  return true;
214 }
215 
216 
218  const double& distance,
219  const int& level,
220  te::gm::Geometry*& auxGeom)
221 {
222  te::gm::Geometry* geomResult = 0;
223  te::gm::Geometry* geomTemp = 0;
224  std::auto_ptr<te::gm::Geometry> outGeom;
225  std::auto_ptr<te::gm::Geometry> inGeom;
226  switch(m_bufferPolygonRule)
227  {
228  case (te::vp::INSIDE_OUTSIDE):
229  {
230  outGeom.reset(geom->buffer(distance * level, 16, te::gm::CapButtType));
231  inGeom.reset(geom->buffer(-distance * level, 16, te::gm::CapButtType));
232  geomResult = outGeom->difference(inGeom.get());
233 
234  geomTemp = (te::gm::Geometry*)geomResult->clone();
235  if (auxGeom && auxGeom->isValid())
236  geomResult = geomResult->difference(auxGeom);
237 
238  delete auxGeom;
239  auxGeom = geomTemp;
240  }
241  break;
242 
243  case (te::vp::ONLY_OUTSIDE):
244  {
245  outGeom.reset(geom->buffer(distance * level, 16, te::gm::CapButtType));
246  geomResult = outGeom->difference(geom);
247 
248  geomTemp = (te::gm::Geometry*)geomResult->clone();
249  if (auxGeom && auxGeom->isValid())
250  geomResult = geomResult->difference(auxGeom);
251 
252  delete auxGeom;
253  auxGeom = geomTemp;
254  }
255  break;
256 
257  case (te::vp::ONLY_INSIDE):
258  {
259  inGeom.reset(geom->buffer(-distance * level, 16, te::gm::CapButtType));
260  geomResult = geom->difference(inGeom.get());
261 
262  geomTemp = (te::gm::Geometry*)geomResult->clone();
263  if (auxGeom && auxGeom->isValid())
264  geomResult = geomResult->difference(auxGeom);
265 
266  delete auxGeom;
267  auxGeom = geomTemp;
268  }
269  break;
270 
271  default:
272  {
273 #ifdef TERRALIB_LOGGER_ENABLED
274  te::common::Logger::logDebug("vp", "Buffer - Polygon rule not found.");
275 #endif //TERRALIB_LOGGER_ENABLED
276  }
277  }
278  return geomResult;
279 }
280 
282  const int& levels)
283 {
284  std::vector<std::vector<te::gm::Geometry*> > vecGeom;
285 
286  int levelPos = (int)te::da::GetPropertyPos(outDSet, "level");
287  int geomPos = (int)te::da::GetPropertyPos(outDSet, "geom");
288  int level;
289 
290  //te::common::TaskProgress task1("Dissolving boundaries...");
291  //task1.setTotalSteps(levels*outDSet->size());
292  //task1.setCurrentStep(1);
293  for(int i = 1; i <= levels; ++i)
294  {
296 
297  outDSet->moveBeforeFirst();
298  while(outDSet->moveNext())
299  {
300  level = outDSet->getInt32(levelPos);
301  if(level == i)
302  {
303  te::gm::Geometry* geom = outDSet->getGeometry(geomPos).release();
304 
305  std::vector<te::gm::Geometry*> vec;
306 
307  rtree.search(*(geom->getMBR()), vec);
308 
309  if(!vec.empty())
310  {
311  for(std::size_t t = 0; t < vec.size(); ++t)
312  {
313  if(geom->intersects(vec[t]))
314  {
315  geom = geom->Union(vec[t]);
316  rtree.remove(*(vec[t]->getMBR()), vec[t]);
317  }
318  }
319  }
320  rtree.insert(*(geom->getMBR()), geom);
321  }
322  //task1.pulse();
323  }
324 
325  std::vector<te::gm::Geometry*> geomVec;
326  std::auto_ptr<te::gm::Envelope> e = outDSet->getExtent(geomPos);
327  rtree.search(*(e.get()), geomVec);
328 
329  vecGeom.push_back(geomVec);
330 
331  rtree.clear();
332  }
333 
334  outDSet->clear();
335  outDSet->moveBeforeFirst();
336 
337 
338  int pk = 0;
339  std::size_t vecSize = vecGeom.size();
340 
341  //task1.setTotalSteps(vecSize);
342  //task1.setCurrentStep(1);
343  if(levels > 1)
344  {
345  for(std::size_t i = vecSize - 1; i > 0; --i)
346  {
347  std::vector<te::gm::Geometry*> currentVec = vecGeom[i];
348  std::size_t c_vecSize = currentVec.size();
349 
350  for(std::size_t j = 0; j < i; ++j)
351  {
352  std::vector<te::gm::Geometry*> innerVec = vecGeom[j];
353  std::size_t i_vecSize = innerVec.size();
354 
355  for(std::size_t k = 0; k < c_vecSize; ++k)
356  {
357  for(std::size_t l = 0; l < i_vecSize; ++l)
358  {
359  te::gm::Geometry* k_geom = currentVec[k];
360  te::gm::Geometry* l_geom = innerVec[l];
361 
362  if(k_geom->intersects(l_geom))
363  {
364  te::gm::Geometry* tGeom = k_geom->difference(l_geom);
365  if(tGeom->isValid())
366  {
367  delete currentVec[k];
368  currentVec[k] = tGeom;
369  vecGeom[i] = currentVec;
370  }
371  }
372  }
373  }
374  }
375  //task1.pulse();
376  }
377  }
378 
379  //task1.setTotalSteps(vecSize);
380  //task1.setCurrentStep(1);
381  for(std::size_t i = 0; i < vecSize; ++i)
382  {
383  std::vector<te::gm::Geometry*> currentVec = vecGeom[i];
384  std::size_t c_vecSize = currentVec.size();
385 
386  for(int j = 0; j < c_vecSize; ++j)
387  {
388  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outDSet);
389  dataSetItem->setInt32(0, pk); //pk
390  dataSetItem->setInt32(1, (int)i+1); //level
391  dataSetItem->setDouble(2, 0/*distance*(i)*/); //distance
392 
393  if(currentVec[j]->getGeomTypeId() == te::gm::MultiPolygonType)
394  {
395  dataSetItem->setGeometry(3, currentVec[j]);
396  }
397  else
398  {
399  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, currentVec[j]->getSRID()));
400  te::gm::GeometryCollection* gcIn = dynamic_cast<te::gm::GeometryCollection*>(currentVec[j]);
401  if(gcIn == 0)
402  mPolygon->add(currentVec[j]);
403  else
404  te::vp::SplitGeometryCollection(gcIn, mPolygon.get());
405 
406  dataSetItem->setGeometry(3, mPolygon.release());
407  }
408 
409  outDSet->add(dataSetItem);
410  ++pk;
411  }
412  //task1.pulse();
413  }
414 }
415 
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:537
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:472
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:254
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.
void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType)
Definition: Utils.cpp:172
TEDATAACCESSEXPORT std::size_t GetPropertyPos(const DataSet *dataset, const std::string &name)
Definition: Utils.cpp:500
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:172
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:417
void SplitGeometryCollection(te::gm::GeometryCollection *geomIn, te::gm::GeometryCollection *gcOut)
Definition: Utils.cpp:149
The buffer is generated only inside of the polygons.
Definition: Enums.h:81
URI C++ Library.
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:241
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
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:328
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:316
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:228
void clear()
It clears all the dataset items.
Definition: DataSet.cpp:114
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: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 DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
Definition: Utils.cpp:644
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: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