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