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 #include "../dataaccess/dataset/DataSetAdapter.h"
34 #include "../dataaccess/dataset/DataSetTypeConverter.h"
35 
36 #include "../datatype/Property.h"
37 #include "../datatype/SimpleProperty.h"
38 #include "../datatype/StringProperty.h"
39 
40 #include "../dataaccess/dataset/ObjectIdSet.h"
41 #include "../dataaccess/query/DataSetName.h"
42 #include "../dataaccess/query/Expression.h"
43 #include "../dataaccess/query/Field.h"
44 #include "../dataaccess/query/Fields.h"
45 #include "../dataaccess/query/From.h"
46 #include "../dataaccess/query/FromItem.h"
47 #include "../dataaccess/query/PropertyName.h"
48 #include "../dataaccess/query/Select.h"
49 #include "../dataaccess/query/ST_Buffer.h"
50 #include "../dataaccess/query/ST_Difference.h"
51 #include "../dataaccess/query/Where.h"
52 #include "../dataaccess/utils/Utils.h"
53 
54 #include "../geometry/Geometry.h"
55 #include "../geometry/GeometryCollection.h"
56 #include "../geometry/GeometryProperty.h"
57 #include "../geometry/Utils.h"
58 
59 #include "../memory/DataSet.h"
60 #include "../memory/DataSetItem.h"
61 
62 #include "../sam/rtree.h"
63 
64 #include "BufferQuery.h"
65 #include "Config.h"
66 #include "Exception.h"
67 #include "Utils.h"
68 
69 // STL
70 #include <map>
71 #include <math.h>
72 #include <string>
73 #include <vector>
74 
75 // BOOST
76 #include <boost/lexical_cast.hpp>
77 #include <boost/algorithm/string.hpp>
78 
80 {}
81 
83 {}
84 
85 bool te::vp::BufferQuery::run() throw(te::common::Exception)
86 {
87  te::da::Fields* fields = new te::da::Fields;
88 
89  if(m_copyInputColumns)
90  {
91  std::vector<te::dt::Property*> props = m_converter->getResult()->getProperties();
92  for(std::size_t i=0; i < props.size(); ++i)
93  {
94  if(props[i]->getType() != te::dt::GEOMETRY_TYPE)
95  {
96  te::da::Field* f_props = new te::da::Field(te::da::PropertyName(props[i]->getName()));
97  fields->push_back(f_props);
98  }
99  }
100  }
101 
102  te::gm::GeometryProperty* geom = te::da::GetFirstGeomProperty(m_converter->getResult());
103 
104  te::da::Expression* e_buffer = 0;
105  te::da::Expression* e_aux = 0;
106  te::da::Field* f_buffer = 0;
107 
108 
109  for(int i=1; i <= m_levels; ++i)
110  {
111  std::stringstream ss;
112  ss << i;
113  std::string index = ss.str();
114 
115  //buffer
116  if(m_bufferPolygonRule == te::vp::INSIDE_OUTSIDE)
117  {
118  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), m_distance*i);
119  te::da::Expression* e_buffer2 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), -m_distance*i);
120  e_buffer = new te::da::ST_Difference(e_buffer1, e_buffer2);
121  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
122  }
123  else if(m_bufferPolygonRule == te::vp::ONLY_OUTSIDE)
124  {
125  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), m_distance*i);
126  te::da::Expression* e_buffer2 = new te::da::PropertyName(geom->getName());
127  e_buffer = new te::da::ST_Difference(e_buffer1, e_buffer2);
128  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
129  }
130  else
131  {
132  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), -m_distance*i);
133  te::da::Expression* e_buffer2 = new te::da::PropertyName(geom->getName());
134  e_buffer = new te::da::ST_Difference(e_buffer2, e_buffer1);
135  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
136  }
137 
138  if(!e_aux)
139  {
140  fields->push_back(f_buffer);
141  e_aux = e_buffer;
142  }
143  else
144  {
145  te::da::Expression* e_diff = new te::da::ST_Difference(e_buffer, e_aux);
146  f_buffer = new te::da::Field(*e_diff, "geom"+index);
147  fields->push_back(f_buffer);
148  e_aux = e_buffer;
149  }
150  }
151 
152  te::da::FromItem* fromItem = new te::da::DataSetName(m_converter->getResult()->getName());
153  te::da::From* from = new te::da::From;
154  from->push_back(fromItem);
155 
156  te::da::Where* w_oid = 0;
157 
158  if(m_oidSet)
159  {
160  w_oid = new te::da::Where(m_oidSet->getExpression());
161  }
162 
163  te::da::Select select(fields, from, w_oid);
164  std::auto_ptr<te::da::DataSet> dsQuery = m_inDsrc->query(select);
165 
166  std::auto_ptr<te::da::DataSetType> outDSType(GetDataSetType());
167  std::auto_ptr<te::mem::DataSet> outDSet(new te::mem::DataSet(outDSType.get()));
168 
169  if(m_bufferBoundariesRule == te::vp::DISSOLVE)
170  {
171  std::vector<std::vector<te::gm::Geometry*> > vecDissolvedGeom = dissolveQuery(dsQuery.get(), m_levels);
172  prepareDataSet(outDSType.get(), vecDissolvedGeom, outDSet.get(), m_distance);
173  }
174  else
175  {
176  prepareDataSet(outDSType.get(), dsQuery.get(), outDSet.get(), m_distance);
177  }
178 
179 // Converter to use SRID from layer.
180  te::gm::GeometryProperty* geomPropertyLayer = te::da::GetFirstGeomProperty(m_converter->getResult());
181  int layerSRID = geomPropertyLayer->getSRID();
182 
183  te::da::DataSetTypeConverter* converter = new te::da::DataSetTypeConverter(outDSType.get(), m_outDsrc->getCapabilities(), m_outDsrc->getEncoding());
184  te::da::AssociateDataSetTypeConverterSRID(converter, layerSRID);
185  te::da::DataSetType* dsTypeResult = converter->getResult();
186  std::auto_ptr<te::da::DataSetAdapter> dsAdapter(te::da::CreateAdapter(outDSet.get(), converter));
187 
188  te::vp::Save(m_outDsrc.get(), dsAdapter.get(), dsTypeResult);
189  return true;
190 
191 }
192 
193 std::vector<std::vector<te::gm::Geometry*> > te::vp::BufferQuery::dissolveQuery(te::da::DataSet* dsQuery,
194  const int& levels)
195 {
196  std::map<int, std::vector<te::gm::Geometry*> > mapGeom;
197  std::vector<std::vector<te::gm::Geometry*> > vecGeom;
198 
199  for(int i = 0; i < levels; ++i)
200  {
202 
203  dsQuery->moveBeforeFirst();
204  while(dsQuery->moveNext())
205  {
206  te::gm::Geometry* geom = dsQuery->getGeometry(i).release();
207 
208  std::vector<te::gm::Geometry*> vec;
209 
210  rtree.search(*(geom->getMBR()), vec);
211 
212  if(!vec.empty())
213  {
214  for(std::size_t t = 0; t < vec.size(); ++t)
215  {
216  if(geom->intersects(vec[t]))
217  {
218  geom = geom->Union(vec[t]);
219  rtree.remove(*(vec[t]->getMBR()), vec[t]);
220  }
221  }
222  }
223  rtree.insert(*(geom->getMBR()), geom);
224  }
225 
226  std::vector<te::gm::Geometry*> geomVec;
227  std::auto_ptr<te::gm::Envelope> e = dsQuery->getExtent(i);
228  rtree.search(*(e.get()), geomVec);
229  vecGeom.push_back(geomVec);
230 
231  rtree.clear();
232  }
233 
234  std::size_t vecSize = vecGeom.size();
235 
236  if(levels > 1)
237  {
238  for(std::size_t i = vecSize - 1; i > 0; --i)
239  {
240  std::vector<te::gm::Geometry*> currentVec = vecGeom[i];
241  std::size_t c_vecSize = currentVec.size();
242 
243  for(std::size_t j = 0; j < i; ++j)
244  {
245  std::vector<te::gm::Geometry*> innerVec = vecGeom[j];
246  std::size_t i_vecSize = innerVec.size();
247 
248  for(std::size_t k = 0; k < c_vecSize; ++k)
249  {
250  for(std::size_t l = 0; l < i_vecSize; ++l)
251  {
252  te::gm::Geometry* k_geom = currentVec[k];
253  te::gm::Geometry* l_geom = innerVec[l];
254 
255  if(k_geom->intersects(l_geom))
256  {
257  te::gm::Geometry* tGeom = k_geom->difference(l_geom);
258  if(tGeom->isValid())
259  {
260  delete currentVec[k];
261  currentVec[k] = tGeom;
262  vecGeom[i] = currentVec;
263  }
264  }
265  }
266  }
267  }
268  }
269  }
270 
271  return vecGeom;
272 }
273 
275  te::da::DataSet* dataSetQuery,
276  te::mem::DataSet* outputDataSet,
277  const double& distance)
278 {
279  std::size_t numProps = dataSetQuery->getNumProperties();
280  std::size_t firstGeomPos = te::da::GetFirstSpatialPropertyPos(dataSetQuery);
281  int numItems = (int)numProps - (int)firstGeomPos;
282  int pk = 0;
283  dataSetQuery->moveBeforeFirst();
284 
285  unsigned int type;
286 
287  while(dataSetQuery->moveNext())
288  {
289  int numCurrentItem = 0;
290 
291  for(int i = 0; i < numItems; ++i)
292  {
293  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
294 
295  for(std::size_t j = 0; j < numProps; ++j)
296  {
297  type = dataSetQuery->getPropertyDataType(j);
298 
299  switch (type){
300  case te::dt::INT32_TYPE:
301  dataSetItem->setInt32(j+3, dataSetQuery->getInt32(j));
302  break;
303  case te::dt::INT64_TYPE:
304  dataSetItem->setInt64(j+3, dataSetQuery->getInt64(j));
305  break;
306  case te::dt::DOUBLE_TYPE:
307  dataSetItem->setDouble(j+3, dataSetQuery->getDouble(j));
308  break;
309  case te::dt::STRING_TYPE:
310  dataSetItem->setString(j+3, dataSetQuery->getString(j));
311  break;
313  {
314  dataSetItem->setInt32(0, pk); //pk
315  dataSetItem->setInt32(1, i+1); //level
316  dataSetItem->setDouble(2, distance*(i+1)); //distance
317 
318  std::auto_ptr<te::gm::Geometry> geom = dataSetQuery->getGeometry(j+numCurrentItem);
319  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
320  {
321  dataSetItem->setGeometry(j+3, geom.release());
322  }
323  else
324  {
325  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
326  mPolygon->add(geom.release());
327  dataSetItem->setGeometry(j+3, mPolygon.release());
328  }
329 
330  outputDataSet->add(dataSetItem);
331 
332  ++numCurrentItem;
333  ++pk;
334  j = numProps;
335  }
336  break;
337  default:
338 #ifdef TERRALIB_LOGGER_ENABLED
339  te::common::Logger::logDebug("vp", "Buffer - Type not found.");
340 #endif //TERRALIB_LOGGER_ENABLED
341  break;
342  }
343  }
344  }
345  }
346 }
347 
349  std::vector<std::vector<te::gm::Geometry*> > vecDissolvedGeom,
350  te::mem::DataSet* outputDataSet,
351  const double& distance)
352 {
353  int pk = 0;
354 
355  for(std::size_t i = 0; i < vecDissolvedGeom.size(); ++i)
356  {
357  std::vector<te::gm::Geometry*> vecGeom = vecDissolvedGeom[i];
358  std::size_t sizeVecGeom = vecGeom.size();
359 
360  for(std::size_t j=0; j < sizeVecGeom; ++j)
361  {
362  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
363  dataSetItem->setInt32(0, pk); //pk
364  dataSetItem->setInt32(1, (int)i+1); //level
365  dataSetItem->setDouble(2, distance*((int)i+1)); //distance
366 
367  std::auto_ptr<te::gm::Geometry> geom(vecGeom[j]);
368 
369  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
370  {
371  dataSetItem->setGeometry(3, geom.release());
372  }
373  else
374  {
375  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
376  mPolygon->add(geom.release());
377  dataSetItem->setGeometry(3, mPolygon.release());
378  }
379 
380  outputDataSet->add(dataSetItem);
381 
382  ++pk;
383  }
384  }
385 }
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
TEDATAACCESSEXPORT void AssociateDataSetTypeConverterSRID(DataSetTypeConverter *converter, const int &inputSRID, const int &outputSRID=TE_UNKNOWN_SRS)
Definition: Utils.cpp:670
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:172
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
An converter for DataSetType.
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
int getSRID() const
It returns the spatial reference system identifier associated to this property.
Spatial Buffer operator.
Definition: ST_Buffer.h:51
URI C++ Library.
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
TEDATAACCESSEXPORT DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
Definition: Utils.cpp:644
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