All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Buffer.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 Buffer.h
22 
23  \brief Buffer Vector Processing functions.
24 */
25 
26 //Terralib
27 #include "../common/Translator.h"
28 #include "../common/progress/TaskProgress.h"
29 #include "../dataaccess/dataset/PrimaryKey.h"
30 #include "../dataaccess/dataset/DataSet.h"
31 #include "../dataaccess/dataset/DataSetAdapter.h"
32 #include "../dataaccess/dataset/DataSetType.h"
33 #include "../dataaccess/datasource/DataSourceCapabilities.h"
34 #include "../dataaccess/datasource/DataSourceInfo.h"
35 #include "../dataaccess/datasource/DataSourceManager.h"
36 #include "../dataaccess/datasource/DataSourceFactory.h"
37 #include "../dataaccess/dataset/DataSetTypeConverter.h"
38 #include "../dataaccess/query_h.h"
39 #include "../dataaccess/utils/Utils.h"
40 #include "../datatype/Property.h"
41 #include "../datatype/SimpleProperty.h"
42 #include "../datatype/StringProperty.h"
43 #include "../geometry/Geometry.h"
44 #include "../geometry/GeometryCollection.h"
45 #include "../geometry/GeometryProperty.h"
46 #include "../geometry/MultiPolygon.h"
47 #include "../maptools/AbstractLayer.h"
48 #include "../memory/DataSet.h"
49 #include "../memory/DataSetItem.h"
50 #include "../qt/widgets/layer/utils/DataSet2Layer.h"
51 #include "../sam/rtree.h"
52 #include "Buffer.h"
53 #include "BufferDialog.h"
54 #include "Config.h"
55 #include "Exception.h"
56 #include "Utils.h"
57 
58 // STL
59 #include <map>
60 #include <math.h>
61 #include <string>
62 #include <vector>
63 
64 // BOOST
65 #include <boost/lexical_cast.hpp>
66 #include <boost/algorithm/string.hpp>
67 
68 
69 // -- auxiliary functions
70 te::da::DataSetType* GetDataSetType(const std::string& inDatasetName,
71  te::da::DataSource* inDataSource,
72  const std::string& outputLayerName,
73  const int& bufferBoundariesRule,
74  const bool& copyInputColumns);
75 
76 bool BufferMemory(const std::string& inDatasetName,
77  te::da::DataSource* inDataSource,
78  const double& distance,
79  const int& bufferPolygonRule,
80  const int& bufferBoundariesRule,
81  const bool& copyInputColumns,
82  const int& levels,
83  te::mem::DataSet* outputDataSet,
84  te::da::DataSetType* outputDataSetType,
85  te::gm::GeomType outGeoType);
86 
87 bool BufferMemory(const std::string& inDatasetName,
88  te::da::DataSource* inDataSource,
89  const std::string& distance,
90  const int& bufferPolygonRule,
91  const int& bufferBoundariesRule,
92  const bool& copyInputColumns,
93  const int& levels,
94  te::mem::DataSet* outputDataSet,
95  te::da::DataSetType* outputDataSetType,
96  te::gm::GeomType outGeoType);
97 
98 bool BufferQuery(const std::string& inDatasetName,
99  te::da::DataSource* inDataSource,
100  const double& fixedDistance,
101  const int& bufferPolygonRule,
102  const int& bufferBoundariesRule,
103  const bool& copyInputColumns,
104  const int& levels,
105  te::mem::DataSet* outputDataSet,
106  te::da::DataSetType* outputDataSetType,
107  te::gm::GeomType outGeoType);
108 
109 bool BufferQuery(const std::string& inDatasetName,
110  te::da::DataSource* inDataSource,
111  const std::string& fromAttDistance,
112  const int& bufferPolygonRule,
113  const int& bufferBoundariesRule,
114  const bool& copyInputColumns,
115  const int& levels,
116  te::mem::DataSet* outputDataSet,
117  te::da::DataSetType* outputDataSetType,
118  te::gm::GeomType outGeoType);
119 
121  const int& bufferPolygonRule,
122  const double& distance,
123  const int& level,
124  te::gm::Geometry*& auxGeom);
125 
126 void PrepareDataSet(te::da::DataSetType* dataSetType,
127  te::da::DataSet* dataSetQuery,
128  te::mem::DataSet* outputDataSet,
129  const double& distance);
130 // ---
131 
132 
133 
134 bool te::vp::Buffer(const std::string& inDatasetName,
135  te::da::DataSource* inDataSource,
136  const int& bufferPolygonRule,
137  const int& bufferBoundariesRule,
138  const bool& copyInputColumns,
139  const int& levels,
140  const std::string& outDataSetName,
141  te::da::DataSource* outDataSource,
142  const double& fixedDistance,
143  const std::string& fromAttDistance)
144 {
145  assert(inDataSource);
146  assert(outDataSource);
147 
148  // define the schema of the output dataset based on the aggregation parameters for the non-spatial attributes
149  std::auto_ptr<te::da::DataSetType> outputDataSetType(GetDataSetType(inDatasetName, inDataSource, outDataSetName, bufferBoundariesRule, copyInputColumns));
150  std::auto_ptr<te::mem::DataSet> outputDataSet(new te::mem::DataSet(outputDataSetType.get()));
151 
152  // select a strategy based on the capabilities of the input datasource
153  const te::da::DataSourceCapabilities dsCapabilities = inDataSource->getCapabilities();
154 
155  // execute the strategy
156  bool res;
157  if(dsCapabilities.supportsPreparedQueryAPI() && dsCapabilities.getQueryCapabilities().supportsSpatialSQLDialect())
158  {
159  if(fromAttDistance == "")
160  res = BufferQuery(inDatasetName, inDataSource, fixedDistance, bufferPolygonRule, bufferBoundariesRule, copyInputColumns, levels, outputDataSet.get(), outputDataSetType.get(), te::gm::MultiPolygonType);
161  else
162  res = BufferQuery(inDatasetName, inDataSource, fromAttDistance, bufferPolygonRule, bufferBoundariesRule, copyInputColumns,levels, outputDataSet.get(), outputDataSetType.get(), te::gm::MultiPolygonType);
163  }
164  else
165  {
166  res = BufferMemory(inDatasetName, inDataSource, fixedDistance, bufferPolygonRule, bufferBoundariesRule, copyInputColumns, levels, outputDataSet.get(), outputDataSetType.get(), te::gm::MultiPolygonType);
167  }
168 
169  if (!res)
170  return false;
171 
172  // do any adaptation necessary to persist the output dataset
173  te::da::DataSetTypeConverter* converter = new te::da::DataSetTypeConverter(outputDataSetType.get(), outDataSource->getCapabilities());
174  te::da::DataSetType* dsTypeResult = converter->getResult();
175  std::auto_ptr<te::da::DataSetAdapter> dsAdapter(te::da::CreateAdapter(outputDataSet.get(), converter));
176 
177  std::map<std::string, std::string> options;
178  // create the dataset
179  outDataSource->createDataSet(dsTypeResult, options);
180 
181  // copy from memory to output datasource
182  te::common::TaskProgress task("Saving buffer...");
183  outputDataSet->moveBeforeFirst();
184  outDataSource->add(dsTypeResult->getName(),outputDataSet.get(), options);
185 
186  return true;
187 }
188 
189 te::da::DataSetType* GetDataSetType(const std::string& inDatasetName,
190  te::da::DataSource* inDataSource,
191  const std::string& outputLayerName,
192  const int& bufferBoundariesRule,
193  const bool& copyInputColumns)
194 {
195  te::da::DataSetType* dsType = new te::da::DataSetType(outputLayerName);
196 
197  //Primary key
198  te::dt::SimpleProperty* pkProperty = new te::dt::SimpleProperty(outputLayerName + "_id", te::dt::INT32_TYPE);
199  pkProperty->setAutoNumber(true);
200  dsType->add(pkProperty);
201 
202  te::da::PrimaryKey* pk = new te::da::PrimaryKey(outputLayerName + "_pk", dsType);
203  pk->add(pkProperty);
204  dsType->setPrimaryKey(pk);
205 
207  dsType->add(levelProperty);
208 
209  te::dt::SimpleProperty* distanceProperty = new te::dt::SimpleProperty("distance", te::dt::DOUBLE_TYPE);
210  dsType->add(distanceProperty);
211 
212 
213  if(copyInputColumns)
214  {
215  boost::ptr_vector<te::dt::Property> props = inDataSource->getProperties(inDatasetName);
216  boost::ptr_vector<te::dt::Property>::iterator it = props.begin();
217 
218  while(it != props.end())
219  {
220  if(it->getType() != te::dt::GEOMETRY_TYPE && it->getName() != "FID")
221  dsType->add(it->clone());
222 
223  ++it;
224  }
225  }
226 
227  std::auto_ptr<te::da::DataSetType> inputDataSetType = inDataSource->getDataSetType(inDatasetName);
228  te::gm::GeometryProperty* p = static_cast<te::gm::GeometryProperty*>(te::da::GetFirstGeomProperty(inputDataSetType.get()));
229 
230  te::gm::GeometryProperty* geometry = new te::gm::GeometryProperty("geom");
232  geometry->setSRID(p->getSRID());
233  dsType->add(geometry);
234 
235  return dsType;
236 }
237 
238 bool BufferMemory(const std::string& inDataSetName,
239  te::da::DataSource* inDataSource,
240  const double& distance,
241  const int& bufferPolygonRule,
242  const int& bufferBoundariesRule,
243  const bool& copyInputColumns,
244  const int& levels,
245  te::mem::DataSet* outputDataSet,
246  te::da::DataSetType* outputDataSetType,
247  te::gm::GeomType outGeoType)
248 {
249  std::auto_ptr<te::da::DataSet> inputDataSet = inDataSource->getDataSet(inDataSetName);
250 
251  int type;
252  int pk = 0;
253 
254 
255  te::common::TaskProgress task("Processing buffer...");
256  task.setTotalSteps(inputDataSet->size());
257  task.useTimer(true);
258 
259  inputDataSet->moveBeforeFirst();
260  while(inputDataSet->moveNext())
261  {
262  te::gm::Geometry* auxGeom = 0;
263 
264  for(int i = 1; i <= levels; ++i)
265  {
266  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
267 
268  for(std::size_t j = 0; j < inputDataSet->getNumProperties(); ++j)
269  {
270  type = inputDataSet->getPropertyDataType(j);
271  if(copyInputColumns)
272  {
273  switch (type)
274  {
275  case te::dt::INT32_TYPE:
276  if(inputDataSet->getPropertyName(j) != "FID")
277  dataSetItem->setInt32(j+2, inputDataSet->getInt32(j));
278  break;
279  case te::dt::INT64_TYPE:
280  dataSetItem->setInt64(j+2, inputDataSet->getInt64(j));
281  break;
282  case te::dt::DOUBLE_TYPE:
283  dataSetItem->setDouble(j+2, inputDataSet->getDouble(j));
284  break;
285  case te::dt::STRING_TYPE:
286  dataSetItem->setString(j+2, inputDataSet->getString(j));
287  break;
289  dataSetItem->setInt32(0, pk); //pk
290  dataSetItem->setInt32(1, i); //level
291  dataSetItem->setDouble(2, distance*(i)); //distance
292 
293  std::auto_ptr<te::gm::Geometry> currentGeom = inputDataSet->getGeometry(j);
294  std::auto_ptr<te::gm::Geometry> outGeom;
295 
296  if(currentGeom->isValid())
297  outGeom.reset(SetBuffer(currentGeom.get(), bufferPolygonRule, distance, i, auxGeom));
298 
299  if(outGeom.get() && outGeom->isValid())
300  {
301  if(outGeom->getGeomTypeId() == te::gm::MultiPolygonType)
302  {
303  dataSetItem->setGeometry(j+2, outGeom.release());
304  }
305  else
306  {
307  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, outGeom->getSRID()));
308  mPolygon->add(outGeom.release());
309  dataSetItem->setGeometry(j+2, mPolygon.release());
310  }
311 
312  outputDataSet->add(dataSetItem);
313  ++pk;
314  }
315  }
316  }
317  else
318  {
319  if(type == te::dt::GEOMETRY_TYPE)
320  {
321  dataSetItem->setInt32(0, pk); //pk
322  dataSetItem->setInt32(1, i); //level
323  dataSetItem->setDouble(2, distance*(i)); //distance
324 
325  std::auto_ptr<te::gm::Geometry> currentGeom = inputDataSet->getGeometry(j);
326  std::auto_ptr<te::gm::Geometry> outGeom;
327 
328  if(currentGeom->isValid())
329  outGeom.reset(SetBuffer(currentGeom.get(), bufferPolygonRule, distance, i, auxGeom));
330 
331  if(outGeom.get() && outGeom->isValid())
332  {
333  if(outGeom->getGeomTypeId() == te::gm::MultiPolygonType)
334  {
335  dataSetItem->setGeometry(3, outGeom.release());
336  }
337  else
338  {
339  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, outGeom->getSRID()));
340  mPolygon->add(outGeom.release());
341  dataSetItem->setGeometry(3, mPolygon.release());
342  }
343 
344  outputDataSet->add(dataSetItem);
345  ++pk;
346  }
347  }
348  }
349  }
350  }
351  delete auxGeom;
352 
353  task.pulse();
354  }
355 
356  if(bufferBoundariesRule == te::vp::DISSOLVE)
357  {
358  std::map<int, std::vector<te::gm::Geometry*> > mapGeom;
359 
360  int levelPos = te::da::GetPropertyPos(outputDataSet, "level");
361  int geomPos = te::da::GetPropertyPos(outputDataSet, "geom");
362  int level;
363 
364  task.setMessage("Dissolving boundaries...");
365  task.setTotalSteps(levels*outputDataSet->size());
366  task.setCurrentStep(1);
367  for(int i = 1; i <= levels; ++i)
368  {
370 
371  outputDataSet->moveBeforeFirst();
372  while(outputDataSet->moveNext())
373  {
374  level = outputDataSet->getInt32(levelPos);
375  if(level == i)
376  {
377  te::gm::Geometry* geom = outputDataSet->getGeometry(geomPos).release();
378 
379  std::vector<te::gm::Geometry*> vec;
380 
381  rtree.search(*(geom->getMBR()), vec);
382 
383  if(!vec.empty())
384  {
385  for(std::size_t t = 0; t < vec.size(); ++t)
386  {
387  if(geom->intersects(vec[t]))
388  {
389  geom = geom->Union(vec[t]);
390  rtree.remove(*(vec[t]->getMBR()), vec[t]);
391  }
392  }
393  }
394  rtree.insert(*(geom->getMBR()), geom);
395  }
396  task.pulse();
397  }
398 
399  std::vector<te::gm::Geometry*> geomVec;
400  std::auto_ptr<te::gm::Envelope> e = outputDataSet->getExtent(geomPos);
401  rtree.search(*(e.get()), geomVec);
402  mapGeom.insert(std::pair<int, std::vector<te::gm::Geometry*> >(i, geomVec));
403  rtree.clear();
404  }
405 
406  outputDataSet->clear();
407  outputDataSet->moveBeforeFirst();
408 
409  task.setTotalSteps(mapGeom.size());
410  task.setCurrentStep(1);
411  int pk = 0;
412  std::map<int, std::vector<te::gm::Geometry*> >::iterator it = mapGeom.begin();
413  while(it != mapGeom.end())
414  {
415  for(std::size_t i = 0; i < it->second.size(); ++i)
416  {
417  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
418  dataSetItem->setInt32(0, pk); //pk
419  dataSetItem->setInt32(1, it->first); //level
420  dataSetItem->setDouble(2, 0/*distance*(i)*/); //distance
421 
422  if(it->second[i]->getGeomTypeId() == te::gm::MultiPolygonType)
423  {
424  dataSetItem->setGeometry(3, it->second[i]);
425  }
426  else
427  {
428  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, it->second[i]->getSRID()));
429  mPolygon->add(it->second[i]);
430  dataSetItem->setGeometry(3, mPolygon.release());
431  }
432 
433  outputDataSet->add(dataSetItem);
434  ++pk;
435  }
436  ++it;
437  task.pulse();
438  }
439  }
440 
441  return true;
442 }
443 
444 bool BufferMemory(const std::string& inDatasetName,
445  te::da::DataSource* inDataSource,
446  const std::string& distance,
447  const int& bufferPolygonRule,
448  const int& bufferBoundariesRule,
449  const int& levels,
450  te::mem::DataSet* outputDataSet,
451  te::da::DataSetType* outputDataSetType,
452  te::gm::GeomType outGeoType)
453 {
454  return false;
455 }
456 
457 bool BufferQuery(const std::string& inDatasetName,
458  te::da::DataSource* inDataSource,
459  const double& distance,
460  const int& bufferPolygonRule,
461  const int& bufferBoundariesRule,
462  const bool& copyInputColumns,
463  const int& levels,
464  te::mem::DataSet* outputDataSet,
465  te::da::DataSetType* outputDataSetType,
466  te::gm::GeomType outGeoType)
467 {
468  std::auto_ptr<te::da::DataSetType> dsType = inDataSource->getDataSetType(inDatasetName);
469 
470  te::da::Fields* fields = new te::da::Fields;
471 
472  if(copyInputColumns)
473  {
474  std::vector<te::dt::Property*> props = dsType->getProperties();
475  for(std::size_t i=0; i < props.size(); ++i)
476  {
477  if(props[i]->getType() != te::dt::GEOMETRY_TYPE)
478  {
479  te::da::Field* f_props = new te::da::Field(te::da::PropertyName(props[i]->getName()));
480  fields->push_back(f_props);
481  }
482  }
483  }
484 
486 
487  te::da::Expression* e_buffer = 0;
488  te::da::Expression* e_aux = 0;
489  te::da::Field* f_buffer = 0;
490 
491 
492  for(int i=1; i <= levels; ++i)
493  {
494  std::stringstream ss;
495  ss << i;
496  std::string index = ss.str();
497 
498  //buffer
499  if(bufferPolygonRule == te::vp::INSIDE_OUTSIDE)
500  {
501  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), distance*i);
502  te::da::Expression* e_buffer2 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), -distance*i);
503  e_buffer = new te::da::ST_Difference(e_buffer1, e_buffer2);
504  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
505  }
506  else if(bufferPolygonRule == te::vp::ONLY_OUTSIDE)
507  {
508  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), distance*i);
509  te::da::Expression* e_buffer2 = new te::da::PropertyName(geom->getName());
510  e_buffer = new te::da::ST_Difference(e_buffer1, e_buffer2);
511  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
512  }
513  else
514  {
515  te::da::Expression* e_buffer1 = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), -distance*i);
516  te::da::Expression* e_buffer2 = new te::da::PropertyName(geom->getName());
517  e_buffer = new te::da::ST_Difference(e_buffer2, e_buffer1);
518  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
519  }
520 
521  if(bufferBoundariesRule == te::vp::DISSOLVE)
522  {
523  delete f_buffer;
524  te::da::Expression* e_union = new te::da::ST_Union(e_buffer);
525 
526  if(!e_aux)
527  {
528  f_buffer = new te::da::Field(*e_union, "geom"+index);
529  fields->push_back(f_buffer);
530  e_aux = e_union;
531  }
532  else
533  {
534  te::da::Expression* e_diff = new te::da::ST_Difference(e_union, e_aux);
535  f_buffer = new te::da::Field(*e_diff, "geom"+index);
536  fields->push_back(f_buffer);
537  e_aux = e_union;
538  }
539  }
540  else
541  {
542  if(!e_aux)
543  {
544  fields->push_back(f_buffer);
545  e_aux = e_buffer;
546  }
547  else
548  {
549  te::da::Expression* e_diff = new te::da::ST_Difference(e_buffer, e_aux);
550  f_buffer = new te::da::Field(*e_diff, "geom"+index);
551  fields->push_back(f_buffer);
552  e_aux = e_buffer;
553  }
554  }
555  }
556 
557  te::da::FromItem* fromItem = new te::da::DataSetName(dsType->getName());
558  te::da::From* from = new te::da::From;
559  from->push_back(fromItem);
560 
561  te::da::Select select(fields, from);
562  std::auto_ptr<te::da::DataSet> dsQuery = inDataSource->query(select);
563 
564  PrepareDataSet(outputDataSetType, dsQuery.get(), outputDataSet, distance);
565 
566  return true;
567 }
568 
569 bool BufferQuery(const std::string& inDatasetName,
570  te::da::DataSource* inDataSource,
571  const std::string& distance,
572  const int& bufferPolygonRule,
573  const int& bufferBoundariesRule,
574  const bool& copyInputColumns,
575  const int& levels,
576  te::mem::DataSet* outputDataSet,
577  te::da::DataSetType* outputDataSetType,
578  te::gm::GeomType outGeoType)
579 {
580  std::auto_ptr<te::da::DataSetType> dsType = inDataSource->getDataSetType(inDatasetName);
581 
582  te::da::Fields* fields = new te::da::Fields;
583 
584  std::vector<te::dt::Property*> props = dsType->getProperties();
585  for(std::size_t i=0; i < props.size(); ++i)
586  {
587  te::da::Field* f_props = new te::da::Field(te::da::PropertyName(props[i]->getName()));
588  fields->push_back(f_props);
589  }
590 
592  te::da::Expression* e_buffer = 0;
593  te::da::Expression* e_aux = 0;
594  te::da::Field* f_buffer = 0;
595 
596  for(int i=1; i <= levels; ++i)
597  {
598  std::stringstream ss;
599  ss << i;
600  std::string index = ss.str();
601 
602  //buffer
603  if(bufferPolygonRule == te::vp::INSIDE_OUTSIDE)
604  {
607  e_buffer = new te::da::ST_Difference(e_buffer1, e_buffer2);
608  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
609  }
610  else
611  {
612  e_buffer = new te::da::ST_Buffer(te::da::PropertyName(geom->getName()), te::da::PropertyName(distance));
613  f_buffer = new te::da::Field(*e_buffer, "geom"+index);
614  }
615 
616  if(bufferBoundariesRule == te::vp::DISSOLVE)
617  {
618  delete f_buffer;
619  te::da::Expression* e_union = new te::da::ST_Union(e_buffer);
620 
621  if(!e_aux)
622  {
623  f_buffer = new te::da::Field(*e_union, "geom"+index);
624  fields->push_back(f_buffer);
625  e_aux = e_union;
626  }
627  else
628  {
629  te::da::Expression* e_diff = new te::da::ST_Difference(e_union, e_aux);
630  f_buffer = new te::da::Field(*e_diff, "geom"+index);
631  fields->push_back(f_buffer);
632  e_aux = e_union;
633  }
634  }
635  else
636  {
637  if(!e_aux)
638  {
639  fields->push_back(f_buffer);
640  e_aux = e_buffer;
641  }
642  else
643  {
644  te::da::Expression* e_diff = new te::da::ST_Difference(e_buffer, e_aux);
645  f_buffer = new te::da::Field(*e_diff, "geom"+index);
646  fields->push_back(f_buffer);
647  e_aux = e_buffer;
648  }
649  }
650  }
651 
652  te::da::FromItem* fromItem = new te::da::DataSetName(dsType->getName());
653  te::da::From* from = new te::da::From;
654  from->push_back(fromItem);
655 
656  te::da::Select select(fields, from);
657  std::auto_ptr<te::da::DataSet> dsQuery = inDataSource->query(select);
658 
659  //PrepareDataSet(outputDataSetType, dsQuery.get(), outputDataSet);
660 
661  return false;
662 }
663 
665  const int& bufferPolygonRule,
666  const double& distance,
667  const int& level,
668  te::gm::Geometry*& auxGeom)
669 {
670  te::gm::Geometry* geomResult = 0;
671  te::gm::Geometry* geomTemp = 0;
672  std::auto_ptr<te::gm::Geometry> outGeom;
673  std::auto_ptr<te::gm::Geometry> inGeom;
674  switch(bufferPolygonRule)
675  {
676  case (te::vp::INSIDE_OUTSIDE):
677  outGeom.reset(geom->buffer(distance * level, 16, te::gm::CapButtType));
678  inGeom.reset(geom->buffer(-distance * level, 16, te::gm::CapButtType));
679  geomResult = outGeom->difference(inGeom.get());
680 
681  geomTemp = (te::gm::Geometry*)geomResult->clone();
682  if(auxGeom && auxGeom->isValid())
683  geomResult = geomResult->difference(auxGeom);
684 
685  delete auxGeom;
686  auxGeom = geomTemp;
687 
688  break;
689 
690  case (te::vp::ONLY_OUTSIDE):
691  outGeom.reset(geom->buffer(distance * level, 16, te::gm::CapButtType));
692  geomResult = outGeom->difference(geom);
693 
694  geomTemp = (te::gm::Geometry*)geomResult->clone();
695  if(auxGeom && auxGeom->isValid())
696  geomResult = geomResult->difference(auxGeom);
697 
698  delete auxGeom;
699  auxGeom = geomTemp;
700 
701  break;
702 
703  case (te::vp::ONLY_INSIDE):
704  inGeom.reset(geom->buffer(-distance * level, 16, te::gm::CapButtType));
705  geomResult = geom->difference(inGeom.get());
706 
707  geomTemp = (te::gm::Geometry*)geomResult->clone();
708  if(auxGeom && auxGeom->isValid())
709  geomResult = geomResult->difference(auxGeom);
710 
711  delete auxGeom;
712  auxGeom = geomTemp;
713 
714  break;
715  }
716  return geomResult;
717 }
718 
720  te::da::DataSet* dataSetQuery,
721  te::mem::DataSet* outputDataSet,
722  const double& distance)
723 {
724  std::size_t numProps = dataSetQuery->getNumProperties();
725  std::size_t firstGeomPos = te::da::GetFirstSpatialPropertyPos(dataSetQuery);
726  int numItems = numProps - firstGeomPos;
727  int pk = 0;
728  dataSetQuery->moveBeforeFirst();
729 
730  unsigned int type;
731 
732  while(dataSetQuery->moveNext())
733  {
734  int numCurrentItem = 0;
735 
736  for(int i = 0; i < numItems; ++i)
737  {
738  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(outputDataSet);
739 
740  for(std::size_t j = 0; j < numProps; ++j)
741  {
742  type = dataSetQuery->getPropertyDataType(j);
743 
744  switch (type){
745  case te::dt::INT32_TYPE:
746  dataSetItem->setInt32(j+3, dataSetQuery->getInt32(j));
747  break;
748  case te::dt::INT64_TYPE:
749  dataSetItem->setInt64(j+3, dataSetQuery->getInt64(j));
750  break;
751  case te::dt::DOUBLE_TYPE:
752  dataSetItem->setDouble(j+3, dataSetQuery->getDouble(j));
753  break;
754  case te::dt::STRING_TYPE:
755  dataSetItem->setString(j+3, dataSetQuery->getString(j));
756  break;
758  dataSetItem->setInt32(0, pk); //pk
759  dataSetItem->setInt32(1, i+1); //level
760  dataSetItem->setDouble(2, distance*(i+1)); //distance
761 
762  std::auto_ptr<te::gm::Geometry> geom = dataSetQuery->getGeometry(j+numCurrentItem);
763  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
764  {
765  dataSetItem->setGeometry(j+3, geom.release());
766  }
767  else
768  {
769  std::auto_ptr<te::gm::GeometryCollection> mPolygon(new te::gm::GeometryCollection(0, te::gm::MultiPolygonType, geom->getSRID()));
770  mPolygon->add(geom.release());
771  dataSetItem->setGeometry(j+3, mPolygon.release());
772  }
773 
774  outputDataSet->add(dataSetItem);
775 
776  ++numCurrentItem;
777  ++pk;
778  j = numProps;
779  break;
780  }
781  }
782  }
783  }
784 }
virtual double getDouble(std::size_t i) const =0
Method for retrieving a double attribute value.
void setGeometryType(GeomType t)
It sets the geometry subtype.
void PrepareDataSet(te::da::DataSetType *dataSetType, te::da::DataSet *dataSetQuery, te::mem::DataSet *outputDataSet, const double &distance)
Definition: Buffer.cpp:719
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
virtual AbstractData * clone() const =0
It returns a clone of this object.
virtual void createDataSet(DataSetType *dt, const std::map< std::string, std::string > &options)
It creates the dataset schema definition in the target data source.
Definition: DataSource.cpp:424
void setGeometry(std::size_t i, te::gm::Geometry *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 boost::ptr_vector< te::dt::Property > getProperties(const std::string &datasetName)
It retrieves the properties of the dataset.
Definition: DataSource.cpp:161
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:409
An atomic property like an integer or double.
std::size_t size() const
It returns the collection size, if it is known.
Definition: DataSet.cpp:279
An converter for DataSetType.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
Definition: DataSet.h:64
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:504
virtual const DataSourceCapabilities & getCapabilities() const =0
It returns the known capabilities of the data source.
A Select models a query to be used when retrieving data from a DataSource.
Definition: Select.h:65
int getSRID() const
It returns the spatial reference system identifier associated to this property.
void setTotalSteps(int value)
Set the task total stepes.
virtual bool intersects(const Geometry *const rhs) const
It returns true if the geometry object spatially intersects rhs geometry.
Definition: Geometry.cpp:243
bool supportsSpatialSQLDialect() const
virtual boost::int32_t getInt32(std::size_t i) const =0
Method for retrieving a 32-bit integer attribute value (4 bytes long).
void add(DataSetItem *item)
It adds a new item to the dataset and takes its ownership.
Definition: DataSet.cpp:149
The Field class can be used to model an expression that takes part of the output items of a SELECT...
Definition: Field.h:50
std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const
Method for retrieving a geometric attribute value.
Definition: DataSet.cpp:505
virtual std::string getString(std::size_t i) const =0
Method for retrieving a string value attribute.
boost::int32_t getInt32(std::size_t i) const
Method for retrieving a 32-bit integer attribute value (4 bytes long).
Definition: DataSet.cpp:385
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
boost::ptr_vector< FromItem > From
It models the FROM clause for a query.
Definition: From.h:37
const QueryCapabilities & getQueryCapabilities() const
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Definition: DataSetItem.h:56
const std::string & getName() const
It returns the property name.
Definition: Property.h:126
A class that represents an R-tree.
Definition: Index.h:56
void add(Constraint *c)
It adds a new constraint.
void setInt64(std::size_t i, boost::int64_t value)
It sets the value of the i-th property.
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
A class that models the name of any property of an object.
Definition: PropertyName.h:50
A class that represents the known capabilities of a specific data source, i.e. this class informs all...
void setCurrentStep(int value)
Set the task current step.
boost::ptr_vector< Field > Fields
Fields is just a boost::ptr_vector of Field pointers.
Definition: Fields.h:37
virtual Geometry * buffer(const double &distance) const
This method calculates the buffer of a geometry.
Definition: Geometry.cpp:406
virtual bool isValid() const
It tells if the geometry is well formed.
Definition: Geometry.cpp:167
void setPrimaryKey(PrimaryKey *pk)
It sets the primary key constraint.
ST_Union statistical function.
Definition: ST_Union.h:46
void clear(void)
Definition: Index.h:299
Configuration flags for the Terrralib Vector Processing module.
Spatial difference operator.
Definition: ST_Difference.h:46
An abstract class that models a source of data in a query.
Definition: FromItem.h:50
The boundaries between buffers will be dissolved.
Definition: Enums.h:91
bool remove(const te::gm::Envelope &mbr, const DATATYPE &data)
It removes an item from the tree.
Definition: Index.h:320
Utility functions for the data access module.
The buffer is generated only outside of the polygons.
Definition: Enums.h:80
void setDouble(std::size_t i, double value)
It sets the value of the i-th property.
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
void setAutoNumber(bool a)
It tells if the property is an autonumber or not.
virtual int getPropertyDataType(std::size_t i) const =0
It returns the underlying data type of the property at position pos.
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
Definition: Enums.h:41
The buffer is generated Inside and outside of the polygons.
Definition: Enums.h:79
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
virtual boost::int64_t getInt64(std::size_t i) const =0
Method for retrieving a 64-bit integer attribute value (8 bytes long).
virtual std::auto_ptr< DataSet > query(const Select &q, te::common::TraverseType travType=te::common::FORWARDONLY, const te::common::AccessPolicy accessPolicy=te::common::RAccess)
It executes a query that may return some data using a generic query. This method always returns a dis...
Definition: DataSource.cpp:99
void clear()
It clears all the dataset items.
Definition: DataSet.cpp:91
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
void setString(std::size_t i, const std::string &value)
It sets the value of the i-th property.
virtual void add(const std::string &datasetName, DataSet *d, const std::map< std::string, std::string > &options, std::size_t limit=0)
It adds data items to the dataset in the data source.
Definition: DataSource.cpp:450
An exception class for the Vector processing module.
TEDATAACCESSEXPORT std::size_t GetPropertyPos(const DataSet *dataset, const std::string &name)
Definition: Utils.cpp:447
Spatial Buffer operator.
Definition: ST_Buffer.h:51
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:116
bool BufferQuery(const std::string &inDatasetName, te::da::DataSource *inDataSource, const double &fixedDistance, const int &bufferPolygonRule, const int &bufferBoundariesRule, const bool &copyInputColumns, const int &levels, te::mem::DataSet *outputDataSet, te::da::DataSetType *outputDataSetType, te::gm::GeomType outGeoType)
Definition: Buffer.cpp:457
It is a collection of other geometric objects.
A class that models the description of a dataset.
Definition: DataSetType.h:72
bool moveNext()
It moves the internal pointer to the next item of the collection.
Definition: DataSet.cpp:284
te::da::DataSetType * GetDataSetType(const std::string &inDatasetName, te::da::DataSource *inDataSource, const std::string &outputLayerName, const int &bufferBoundariesRule, const bool &copyInputColumns)
Definition: Buffer.cpp:189
void add(te::dt::Property *p)
It adds a property to the list of properties of the primary key.
Definition: PrimaryKey.h:123
This is an abstract class that models a query expression.
Definition: Expression.h:47
bool moveBeforeFirst()
It moves the internal pointer to a position before the first item in the collection.
Definition: DataSet.cpp:296
void useTimer(bool flag)
Used to define if task use progress timer information.
bool BufferMemory(const std::string &inDatasetName, te::da::DataSource *inDataSource, const double &distance, const int &bufferPolygonRule, const int &bufferBoundariesRule, const bool &copyInputColumns, const int &levels, te::mem::DataSet *outputDataSet, te::da::DataSetType *outputDataSetType, te::gm::GeomType outGeoType)
Definition: Buffer.cpp:238
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 setMessage(const std::string &message)
Set the task message.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
virtual std::auto_ptr< DataSet > getDataSet(const std::string &name, te::common::TraverseType travType=te::common::FORWARDONLY, const te::common::AccessPolicy accessPolicy=te::common::RAccess)
It gets the dataset identified by the given name. This method always returns a disconnected dataset...
Definition: DataSource.cpp:60
const Envelope * getMBR() const
It returns the minimum bounding rectangle for the geometry in an internal representation.
Definition: Geometry.cpp:103
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:218
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
Definition: Index.h:326
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
Definition: Index.h:313
Buffer Vector Processing functions.
virtual std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
te::gm::Geometry * SetBuffer(te::gm::Geometry *geom, const int &bufferPolygonRule, const double &distance, const int &level, te::gm::Geometry *&auxGeom)
Definition: Buffer.cpp:664
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
Geometric property.
A dialog buffer operation.
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:111
TEDATAACCESSEXPORT DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
Definition: Utils.cpp:591
virtual std::auto_ptr< te::da::DataSetType > getDataSetType(const std::string &name)
It gets information about the given dataset.
Definition: DataSource.cpp:155
TEVPEXPORT bool Buffer(const std::string &inDataset, te::da::DataSource *inDatasource, const int &bufferPolygonRule, const int &bufferBoundariesRule, const bool &copyInputColumns, const int &levels, const std::string &outDataset, te::da::DataSource *outDatasource, const double &fixedDistance=0, const std::string &fromAttDistance="")
Executes the Buffer Geographical Operation and persists the result as a dataset in a given output dat...
Definition: Buffer.cpp:134