src/terralib/vp/Utils.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 terralib/vp/qt/Utils.cpp
22 
23  \brief Utility functions for Vector Processing.
24 */
25 
26 // TerraLib
27 
28 #include "../common/StringUtils.h"
29 
30 #include "../core/translator/Translator.h"
31 
32 #include "../dataaccess/dataset/DataSetTypeConverter.h"
33 #include "../dataaccess/dataset/DataSetTypeCapabilities.h"
34 #include "../dataaccess/datasource/DataSourceCapabilities.h"
35 #include "../dataaccess/datasource/DataSourceInfo.h"
36 #include "../dataaccess/datasource/DataSourceManager.h"
37 #include "../dataaccess/datasource/DataSourceInfoManager.h"
38 #include "../dataaccess/datasource/DataSourceTransactor.h"
39 #include "../dataaccess/utils/Utils.h"
40 
41 #include "../geometry/GeometryProperty.h"
42 #include "../geometry/MultiPoint.h"
43 #include "../geometry/MultiLineString.h"
44 #include "../geometry/MultiPolygon.h"
45 #include "../geometry/Point.h"
46 
47 #include "AlgorithmParams.h"
48 #include "Utils.h"
49 
50 //STL
51 #include <vector>
52 #include <memory>
53 
54 // Boost
55 #include <boost/algorithm/string.hpp>
56 #include <boost/filesystem.hpp>
57 #include <boost/lexical_cast.hpp>
58 #include <boost/uuid/random_generator.hpp>
59 #include <boost/uuid/uuid_io.hpp>
60 
61 
62 te::gm::Geometry* te::vp::GetGeometryUnion(const std::vector<te::mem::DataSetItem*>& items, size_t geomIdx, te::gm::GeomType outGeoType)
63 {
64  te::gm::Geometry* resultGeometry(nullptr);
65 
66  std::unique_ptr<te::gm::Geometry> seedGeometry = items[0]->getGeometry(geomIdx);
67 
68  if(items.size() < 2)
69  resultGeometry = seedGeometry.release();
70 
71  if(items.size() == 2)
72  {
73  std::unique_ptr<te::gm::Geometry> teGeom = items[1]->getGeometry(geomIdx);
74 
75  if(teGeom->isValid())
76  resultGeometry = seedGeometry->Union(teGeom.release());
77  else
78  resultGeometry = seedGeometry.release();
79  }
80  if(items.size() > 2)
81  {
82  //te::gm::GeometryCollection* teGeomColl = new te::gm::GeometryCollection(0, te::gm::GeometryCollectionType, seedGeometry->getSRID());
83 
84  std::size_t pos = 1;
85  while (!seedGeometry->isValid())
86  {
87  seedGeometry = items[pos]->getGeometry(geomIdx);
88  ++pos;
89  }
90 
91  for (std::size_t i = pos; i < items.size(); ++i)
92  {
93  std::unique_ptr<te::gm::Geometry> currentGeom = items[i]->getGeometry(geomIdx);
94 
95  if(currentGeom->isValid())
96  resultGeometry = seedGeometry->Union(currentGeom.release());
97 
98  seedGeometry.reset(resultGeometry);
99  }
100 
101  resultGeometry = seedGeometry.release();
102  //resultGeometry = seedGeometry->Union(teGeomColl);
103 
104  }
105 
106  if (resultGeometry->getGeomTypeId() != outGeoType)
107  {
108  if(resultGeometry->getGeomTypeId() == te::gm::GeometryCollectionType)
109  {
110  te::gm::GeometryCollection* gc = new te::gm::GeometryCollection(0, outGeoType, resultGeometry->getSRID());
111  std::vector<te::gm::Geometry*> geomVec = ((te::gm::GeometryCollection*)resultGeometry)->getGeometries();
112  for(std::size_t i = 0; i < geomVec.size(); ++i)
113  {
114  te::gm::GeometryCollection* gcIn = dynamic_cast<te::gm::GeometryCollection*>(geomVec[i]);
115  if(gcIn == nullptr)
116  gc->add(geomVec[i]);
117  else
118  SplitGeometryCollection(gcIn, gc);
119  }
120  return gc;
121  }
122  else
123  {
124  te::gm::GeometryCollection* gc = new te::gm::GeometryCollection(1, outGeoType, resultGeometry->getSRID());
125  gc->setGeometryN(0,resultGeometry);
126  return gc;
127  }
128  }
129  else
130  return resultGeometry;
131 }
132 
133 te::gm::Geometry* te::vp::GetGeometryUnion(const std::vector<te::mem::DataSetItem*>& items, size_t geomIdx)
134 {
135  te::gm::Geometry* resultGeometry(nullptr);
136 
137  std::unique_ptr<te::gm::Geometry> seedGeometry = items[0]->getGeometry(geomIdx);
138 
139  if(items.size() < 2)
140  resultGeometry = seedGeometry.release();
141 
142  if(items.size() == 2)
143  {
144  std::unique_ptr<te::gm::Geometry> teGeom = items[1]->getGeometry(geomIdx);
145 
146  if(teGeom->isValid())
147  resultGeometry = seedGeometry->Union(teGeom.release());
148  else
149  resultGeometry = seedGeometry.release();
150  }
151  if(items.size() > 2)
152  {
153  te::gm::GeometryCollection* teGeomColl = new te::gm::GeometryCollection(0, te::gm::GeometryCollectionType, seedGeometry->getSRID());
154 
155  for(std::size_t i = 1; i < items.size(); ++i)
156  {
157  std::unique_ptr<te::gm::Geometry> currentGeom = items[i]->getGeometry(geomIdx);
158 
159  if(currentGeom->isValid())
160  teGeomColl->add(currentGeom.release());
161  }
162 
163  resultGeometry = seedGeometry->Union(teGeomColl);
164 
165  }
166  return resultGeometry;
167 }
168 
170 {
171  std::vector<te::gm::Geometry*> geomVec = ((te::gm::GeometryCollection*)gcIn)->getGeometries();
172  for(std::size_t i = 0; i < geomVec.size(); ++i)
173  {
174  te::gm::GeometryCollection* gc = dynamic_cast<te::gm::GeometryCollection*>(geomVec[i]);
175  if (gc == nullptr)
176  gcOut->add((te::gm::Geometry*)geomVec[i]->clone());
177  else
178  SplitGeometryCollection(gc, gcOut);
179  }
180 }
181 
182 std::string te::vp::GetSimpleTableName(std::string fullName)
183 {
184  std::size_t found = fullName.rfind(".");
185 
186  if(found >= std::string::npos)
187  return fullName;
188 
189  return fullName.substr(found + 1);
190 }
191 
192 std::unique_ptr<te::da::DataSet> te::vp::PrepareAdd(te::da::DataSet* ds, te::da::DataSetType* dt)
193 {
194  std::vector<std::string> pkPropNames;
195  te::da::PrimaryKey* pk = dt->getPrimaryKey();
196 
197  std::vector<te::dt::Property*> props;
198 
199  if (pk)
200  props = pk->getProperties();
201 
202  for (std::size_t i = 0; i < props.size(); ++i)
203  {
204  te::dt::SimpleProperty* sp = dynamic_cast<te::dt::SimpleProperty*>(props[i]);
205 
206  if (sp && sp->isAutoNumber())
207  pkPropNames.push_back(sp->getName());
208 
209  }
210 
211  std::unique_ptr<te::da::DataSet> dataSet;
212 
213  if (!pkPropNames.empty())
214  dataSet = te::da::HideColumns(ds, dt, pkPropNames);
215  else
216  dataSet.reset(ds);
217 
218  return dataSet;
219 }
220 
221 void te::vp::Save(te::da::DataSource* source, te::da::DataSet* result, te::da::DataSetType* outDsType, const bool& enableProgress)
222 {
223  // do any adaptation necessary to persist the output dataset
224  std::unique_ptr<te::da::DataSetTypeConverter> converter(new te::da::DataSetTypeConverter(outDsType, source->getCapabilities()));
225  te::da::DataSetType* dsTypeResult = converter->getResult();
226 
227  std::unique_ptr<te::da::DataSourceTransactor> t = source->getTransactor();
228 
229  std::map<std::string, std::string> options;
230 
231  try
232  {
233  t->begin();
234 
235  std::string dsTypeName = outDsType->getName();
236  std::vector<std::string> dataSetNames = t->getDataSetNames();
237  bool create = true;
238 
239  for (std::size_t i = 0; i < dataSetNames.size(); ++i)
240  {
241  std::vector<std::string> tok;
242  te::common::Tokenize(dataSetNames[i], tok, ".");
243 
244  std::string temp_dsName;
245 
246  if (tok.size() > 1)
247  temp_dsName = tok[1];
248  else
249  temp_dsName = dataSetNames[i];
250 
251  if (dsTypeName == temp_dsName)
252  {
253  create = false;
254  }
255  }
256 
257  if (create)
258  {
259  // create the dataset
260  t->createDataSet(dsTypeResult, options);
261  }
262 
263  // copy from memory to output datasource
264  result->moveBeforeFirst();
265  t->add(dsTypeName, result, options, 0, enableProgress);
266 
267  t->commit();
268  }
269  catch(te::common::Exception& e)
270  {
271  t->rollBack();
272  throw e;
273  }
274  catch(std::exception& e)
275  {
276  t->rollBack();
277  throw e;
278  }
279 }
280 
282 {
283  //create new data source
284  boost::filesystem::path uri(repository);
285 
286  const std::string dsInfo("file://" + uri.string());
287 
288  boost::uuids::basic_random_generator<boost::mt19937> gen;
289  boost::uuids::uuid u = gen();
290  std::string id_ds = boost::uuids::to_string(u);
291 
293  dsInfoPtr->setConnInfo(dsInfo);
294  dsInfoPtr->setTitle(uri.stem().string());
295  dsInfoPtr->setAccessDriver("OGR");
296  dsInfoPtr->setType("OGR");
297  dsInfoPtr->setDescription(uri.string());
298  dsInfoPtr->setId(id_ds);
299 
301 
302  return te::da::DataSourceManager::getInstance().get(id_ds, "OGR", dsInfoPtr->getConnInfo());
303 }
304 
306 {
307  std::vector<te::vp::InputParams> inputParams = mainParams->getInputParams();
308 
309  for (std::size_t i = 0; i < inputParams.size(); ++i)
310  {
311  if (!inputParams[i].m_inputDataSetType)
312  throw te::common::Exception(TE_TR("It is necessary to set the DataSetType from Input Layer."));
313 
314  if (st == MEMORY)
315  {
316  if (!inputParams[i].m_inputDataSet)
317  throw te::common::Exception(TE_TR("It is necessary to set the Input DataSet."));
318  }
319  else
320  {
321  if (!inputParams[i].m_inputQuery)
322  throw te::common::Exception(TE_TR("It is necessary to set the Input Query."));
323  }
324  }
325 
326  if (!mainParams->getOutputDataSource())
327  throw te::common::Exception(TE_TR("It is necessary to set the Output DataSource."));
328 }
329 
331 {
333 
334  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(data);
335 
336  data->moveBeforeFirst();
337 
338  int count = 0;
339 
340  while (data->moveNext()) {
341  if (!data->isNull(geomPos)) {
342  std::unique_ptr<te::gm::Geometry> geom = data->getGeometry(geomPos);
343 
344  rtree->insert(*geom->getMBR(), count);
345  }
346 
347  ++count;
348  }
349 
350  return rtree;
351 }
352 
354 {
355  switch (geom.getGeomTypeId())
356  {
357  case te::gm::PointType:
358  {
360  geomColl->add(dynamic_cast<te::gm::Geometry*>(geom.clone()));
361 
362  return geomColl;
363  }
365  {
367  geomColl->add(dynamic_cast<te::gm::Geometry*>(geom.clone()));
368 
369  return geomColl;
370  }
371  case te::gm::PolygonType:
372  {
374  geomColl->add(dynamic_cast<te::gm::Geometry*>(geom.clone()));
375 
376  return geomColl;
377  }
378  default:
379  break;
380  }
381 
382  return dynamic_cast<te::gm::Geometry*>(geom.clone());
383 }
384 
385 std::string te::vp::GetDistinctName(const std::string& name, std::vector<std::string> names, std::size_t maxSize)
386 {
387  std::string result = name;
388 
389  bool hasToResize = false;
390 
391  if (maxSize > 0)
392  hasToResize = true;
393 
394  std::size_t count = 1;
395 
396  while (std::find(names.begin(), names.end(), result) != names.end())
397  {
398  std::size_t aux = 2;
399  if (count > 99)
400  aux = 3;
401  if (count > 999)
402  aux = 4;
403 
404  if (hasToResize)
405  {
406  if (result.size() + aux > maxSize)
407  {
408  result = result.substr(0, maxSize - aux) + "_" + boost::lexical_cast<std::string>(count);
409  }
410  else
411  {
412  result = result + "_" + boost::lexical_cast<std::string>(count);
413  }
414  }
415  else
416  {
417  result = result + "_" + boost::lexical_cast<std::string>(count);
418  }
419 
420  ++count;
421  }
422 
423  if (maxSize > 0 && name.size() > maxSize)
424  result = result.substr(0, maxSize);
425 
426  return result;
427 }
428 
430 {
431  if ((geomType == te::gm::PointType) ||
432  (geomType == te::gm::PointZType) ||
433  (geomType == te::gm::PointMType) ||
434  (geomType == te::gm::PointZMType) ||
435  (geomType == te::gm::PointKdType) ||
436 
437  (geomType == te::gm::MultiPointType) ||
438  (geomType == te::gm::MultiPointZType) ||
439  (geomType == te::gm::MultiPointMType) ||
440  (geomType == te::gm::MultiPointZMType))
441  return true;
442 
443  return false;
444 }
445 
447 {
448  if ((geomType == te::gm::LineStringType) ||
449  (geomType == te::gm::LineStringZType) ||
450  (geomType == te::gm::LineStringMType) ||
451  (geomType == te::gm::LineStringZMType) ||
452 
453  (geomType == te::gm::MultiLineStringType) ||
454  (geomType == te::gm::MultiLineStringZType) ||
455  (geomType == te::gm::MultiLineStringMType) ||
456  (geomType == te::gm::MultiLineStringZMType))
457  return true;
458 
459  return false;
460 }
461 
463 {
464  if ((geomType == te::gm::PolygonType) ||
465  (geomType == te::gm::PolygonZType) ||
466  (geomType == te::gm::PolygonMType) ||
467  (geomType == te::gm::PolygonZMType) ||
468 
469  (geomType == te::gm::MultiPolygonType) ||
470  (geomType == te::gm::MultiPolygonZType) ||
471  (geomType == te::gm::MultiPolygonMType) ||
472  (geomType == te::gm::MultiPolygonZMType))
473  return true;
474 
475  return false;
476 }
477 
479 {
480  te::mem::DataSetItem* dataSetItem = new te::mem::DataSetItem(dataSet);
481 
482  std::size_t numberOfProperties = dataSetItem->getNumProperties();
483 
484  for(std::size_t i = 0; i < numberOfProperties; ++i)
485  {
486  std::unique_ptr<te::dt::AbstractData> value(dataSet->getValue(dataSet->getPropertyName(i))->clone());
487  dataSetItem->setValue(i, value.release());
488  }
489 
490  return dataSetItem;
491 }
virtual std::unique_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
TEVPEXPORT std::unique_ptr< te::da::DataSet > PrepareAdd(te::da::DataSet *ds, te::da::DataSetType *dt)
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
virtual std::unique_ptr< DataSourceTransactor > getTransactor()=0
It returns the set of parameters used to set up the access channel to the underlying repository...
An atomic property like an integer or double.
TEVPEXPORT te::da::DataSourcePtr CreateOGRDataSource(std::string repository)
boost::shared_ptr< DataSource > DataSourcePtr
TEVPEXPORT bool IsPointType(const te::gm::GeomType &geomType)
A class that represents an R-tree.
A class that models the description of a dataset.
Definition: DataSetType.h:72
GeomType getGeomTypeId() const _NOEXCEPT_OP(true)
It returns the geometry subclass type identifier.
TEVPEXPORT te::gm::Geometry * GetGeometryUnion(const std::vector< te::mem::DataSetItem * > &items, size_t geomIdx, te::gm::GeomType outGeoType)
It returns the union of a geometry vector.
void setValue(std::size_t i, te::dt::AbstractData *value)
It sets the value of the i-th property.
PrimaryKey * getPrimaryKey() const
It returns the primary key associated to the dataset type.
Definition: DataSetType.h:214
std::vector< te::vp::InputParams > getInputParams()
TEVPEXPORT te::sam::rtree::Index< size_t, 8 > * GetRtree(te::da::DataSet *data)
TEVPEXPORT bool IsPolygonType(const te::gm::GeomType &geomType)
static te::dt::Date ds(2010, 01, 01)
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
Algorithm Parameters.
virtual Geometry * Union(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns a geometric object that represents the point set union with another geometry.
std::size_t getNumProperties() const
It returns the number of properties.
const std::vector< te::dt::Property * > & getProperties() const
It returns the properties that take part of the primary key.
Definition: PrimaryKey.h:109
TEDATAACCESSEXPORT std::unique_ptr< te::da::DataSet > HideColumns(te::da::DataSet *ds, te::da::DataSetType *dst, const std::vector< std::string > &columns)
It hide columns of a DataSet using DataSetAdapter.
An converter for DataSetType.
te::gm::GeometryCollection * gc
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
TEVPEXPORT void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType, const bool &enableProgress=true)
void Tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" ")
It tokenizes a given string with a delimiter of your own choice.
Definition: StringUtils.h:221
int getSRID() const _NOEXCEPT_OP(true)
It returns the Spatial Reference System ID associated to this geometric object.
virtual const DataSourceCapabilities & getCapabilities() const =0
It returns the known capabilities of the data source.
MultiPoint is a GeometryCollection whose elements are restricted to points.
Definition: MultiPoint.h:50
TEDATAACCESSEXPORT std::size_t GetFirstSpatialPropertyPos(const te::da::DataSet *dataset)
It returns the first dataset spatial property or NULL if none is found.
static DataSourceInfoManager & getInstance()
It returns a reference to the singleton instance.
TEVPEXPORT bool IsLineStringType(const te::gm::GeomType &geomType)
TEVPEXPORT void SplitGeometryCollection(te::gm::GeometryCollection *geomIn, te::gm::GeometryCollection *gcOut)
static te::dt::TimeDuration dt(20, 30, 50, 11)
virtual AbstractData * clone() const =0
It returns a clone of this object.
te::da::DataSourcePtr getOutputDataSource()
Utility functions for the data access module.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
MultiLineString is a MultiCurve whose elements are LineStrings.
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
A dataset is the unit of information manipulated by the data access module of TerraLib.
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
virtual std::unique_ptr< te::dt::AbstractData > getValue(std::size_t i) const
Method for retrieving any other type of data value stored in the data source.
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
void add(Geometry *g)
It adds the geometry into the collection.
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
const std::vector< Geometry * > & getGeometries() const
It returns a reference to the internal list of geometries.
void setGeometryN(std::size_t i, Geometry *g)
It sets the n-th geometry in this geometry collection.
TEVPEXPORT te::mem::DataSetItem * GetFilledItemMemory(te::da::DataSet *dataSet)
It returns a memory item with all properties filled with values from the current position dataset...
A class that represents a data source component.
TEVPEXPORT void ValidateAlgorithmParams(AlgorithmParams *mainParams, Strategy st)
virtual bool isNull(std::size_t i) const =0
It checks if the attribute value is NULL.
TEVPEXPORT std::string GetDistinctName(const std::string &name, std::vector< std::string > names, std::size_t maxSize=0)
virtual std::string getPropertyName(std::size_t i) const =0
It returns the property name at position pos.
It is a collection of other geometric objects.
bool isAutoNumber() const
It returns true if the attribute is an autonumber, otherwise it returns false.
TEVPEXPORT te::gm::Geometry * SetGeomAsMulti(const te::gm::Geometry &geom)
boost::shared_ptr< DataSourceInfo > DataSourceInfoPtr
const std::string & getName() const
It returns the property name.
Definition: Property.h:127
TEVPEXPORT std::string GetSimpleTableName(std::string fullName)