GeometricOpMemory.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 GeographicOpMemory.h
22 
23  \brief Geographic Vector Processing functions.
24 */
25 
26 //Terralib
27 #include "../core/logger/Logger.h"
28 #include "../core/translator/Translator.h"
29 
30 #include "../dataaccess/dataset/DataSetAdapter.h"
31 #include "../dataaccess/datasource/DataSourceFactory.h"
32 #include "../dataaccess/utils/Utils.h"
33 
34 #include "../geometry/GeometryProperty.h"
35 #include "../geometry/GeometryCollection.h"
36 #include "../geometry/LineString.h"
37 #include "../geometry/MultiLineString.h"
38 #include "../geometry/MultiPolygon.h"
39 #include "../geometry/Point.h"
40 #include "../geometry/Polygon.h"
41 #include "../geometry/Utils.h"
42 
43 #include "../memory/DataSet.h"
44 #include "../memory/DataSetItem.h"
45 
46 #include "GeometricOpMemory.h"
47 #include "Utils.h"
48 
49 // STL
50 #include <map>
51 
52 // BOOST
53 #include <boost/lexical_cast.hpp>
54 #include <boost/algorithm/string.hpp>
55 
57 
59 
61 {
62 // get the geometric operation and/or tabular operation.
63  std::vector<int> opGeom;
64  std::vector<int> opTab;
65  std::vector<te::da::DataSetType*> dsTypeVec;
66 
67  for(std::size_t i = 0; i < m_operations.size(); ++i)
68  {
69  switch (m_operations[i])
70  {
71  case te::vp::CENTROID:
72  opGeom.push_back(te::vp::CENTROID);
73  break;
75  opGeom.push_back(te::vp::CONVEX_HULL);
76  break;
77  case te::vp::MBR:
78  opGeom.push_back(te::vp::MBR);
79  break;
80  case te::vp::AREA:
81  opTab.push_back(te::vp::AREA);
82  break;
83  case te::vp::LINE:
84  opTab.push_back(te::vp::LINE);
85  break;
86  case te::vp::PERIMETER:
87  opTab.push_back(te::vp::PERIMETER);
88  break;
89  default:
90  {
91  TE_LOG_INFO("Vector Processing - Geometric Operation - The operation is not valid.");
92  }
93  }
94  }
95 
96  bool hasMultiGeomColumns = false;
97  bool result = false;
98 
99  switch(m_objStrategy)
100  {
101  case te::vp::ALL_OBJ:
102  {
103  if(hasMultiGeomColumns) // Condição se o DataSource suporta mais de uma
104  // coluna geometrica...
105  {
106  dsTypeVec.push_back(
108  }
109  else
110  {
111  if(opGeom.size() > 0)
112  {
113  for(std::size_t i = 0; i < opGeom.size(); ++i)
114  dsTypeVec.push_back(te::vp::GeometricOp::GetDataSetType(
115  te::vp::ALL_OBJ, false, opGeom[i]));
116  }
117  else
118  {
119  dsTypeVec.push_back(
121  }
122  }
123 
124  for(std::size_t dsTypePos = 0; dsTypePos < dsTypeVec.size();
125  ++dsTypePos)
126  {
127  m_outDsetNameVec.push_back(dsTypeVec[dsTypePos]->getName());
128 
129  std::unique_ptr<te::da::DataSetType> outDataSetType(
130  dsTypeVec[dsTypePos]);
131  std::unique_ptr<te::mem::DataSet> outDataSet(
132  SetAllObjects(dsTypeVec[dsTypePos], opTab, opGeom));
133 
134  if(m_outDsrc->getType() == "OGR")
135  {
136  std::string dsinfo("file://");
137 
138  dsinfo += m_outDsrc->getConnectionInfo().host() + m_outDsrc->getConnectionInfo().path() + "/" + m_outDsetNameVec[dsTypePos] + ".shp";
139 
140  std::unique_ptr<te::da::DataSource> dsOGR = te::da::DataSourceFactory::make("OGR", dsinfo);
141 
142  dsOGR->open();
143 
144  te::vp::Save(dsOGR.get(), outDataSet.get(), outDataSetType.get());
145 
146  dsOGR->close();
147  }
148  else
149  {
150  te::vp::Save(m_outDsrc.get(), outDataSet.get(), outDataSetType.get());
151  }
152  result = true;
153 
154  if(!result)
155  {
156  m_outDsrc->close();
157  return result;
158  }
159  }
160  }
161  break;
162  case te::vp::AGGREG_OBJ:
163  {
164  if(hasMultiGeomColumns) // Condição se o DataSource suporta mais de uma
165  // coluna geometrica...
166  {
167  dsTypeVec.push_back(
169  }
170  else
171  {
172  if(opGeom.size() > 0)
173  {
174  for(std::size_t i = 0; i < opGeom.size(); ++i)
175  dsTypeVec.push_back(te::vp::GeometricOp::GetDataSetType(
176  te::vp::AGGREG_OBJ, false, opGeom[i]));
177  }
178  else
179  {
180  dsTypeVec.push_back(
182  }
183  }
184 
185  for(std::size_t dsTypePos = 0; dsTypePos < dsTypeVec.size();
186  ++dsTypePos)
187  {
188  m_outDsetNameVec.push_back(dsTypeVec[dsTypePos]->getName());
189 
190  std::unique_ptr<te::da::DataSetType> outDataSetType(
191  dsTypeVec[dsTypePos]);
192  std::unique_ptr<te::mem::DataSet> outDataSet(
193  SetAggregObj(dsTypeVec[dsTypePos], opTab, opGeom));
194 
195  if(outDataSet->size() == 0)
196  {
197  m_outDsrc->close();
198  TE_LOG_INFO("Vector Processing - Geometric Operation - Result layer is empty! Verify input layer consistency.");
199  return false;
200  }
201 
202  if(m_outDsrc->getType() == "OGR")
203  {
204  std::string dsinfo("file://");
205 
206  dsinfo += m_outDsrc->getConnectionInfo().host() + m_outDsrc->getConnectionInfo().path() + "/" + m_outDsetNameVec[dsTypePos] + ".shp";
207 
208  std::unique_ptr<te::da::DataSource> dsOGR = te::da::DataSourceFactory::make("OGR", dsinfo);
209  dsOGR->open();
210 
211  te::vp::Save(dsOGR.get(), outDataSet.get(), outDataSetType.get());
212 
213  dsOGR->close();
214  }
215  else
216  {
217  te::vp::Save(m_outDsrc.get(), outDataSet.get(), outDataSetType.get());
218  }
219 
220  result = true;
221 
222  if(!result)
223  {
224  m_outDsrc->close();
225  return result;
226  }
227  }
228  }
229  break;
231  {
232  if(hasMultiGeomColumns) // Condição se o DataSource suporta mais de uma
233  // coluna geometrica...
234  {
235  dsTypeVec.push_back(te::vp::GeometricOp::GetDataSetType(
237  }
238  else
239  {
240  if(opGeom.size() > 0)
241  {
242  for(std::size_t i = 0; i < opGeom.size(); ++i)
243  dsTypeVec.push_back(te::vp::GeometricOp::GetDataSetType(
244  te::vp::AGGREG_BY_ATTRIBUTE, false, opGeom[i]));
245  }
246  else
247  {
248  dsTypeVec.push_back(te::vp::GeometricOp::GetDataSetType(
250  }
251  }
252 
253  for(std::size_t dsTypePos = 0; dsTypePos < dsTypeVec.size();
254  ++dsTypePos)
255  {
256  m_outDsetNameVec.push_back(dsTypeVec[dsTypePos]->getName());
257 
258  std::unique_ptr<te::da::DataSetType> outDataSetType(
259  dsTypeVec[dsTypePos]);
260  std::unique_ptr<te::mem::DataSet> outDataSet(
261  SetAggregByAttribute(dsTypeVec[dsTypePos], opTab, opGeom));
262 
263  if(outDataSet->size() == 0)
264  {
265  m_outDsrc->close();
266  TE_LOG_INFO("Vector Processing - Geometric Operation - Result layer is empty! Verify input layer consistency.");
267  return false;
268  }
269 
270  if(m_outDsrc->getType() == "OGR")
271  {
272  std::string dsinfo("file://");
273 
274  dsinfo += m_outDsrc->getConnectionInfo().host() + m_outDsrc->getConnectionInfo().path() + "/" + m_outDsetNameVec[dsTypePos] + ".shp";
275 
276  std::unique_ptr<te::da::DataSource> dsOGR = te::da::DataSourceFactory::make("OGR", dsinfo);
277  dsOGR->open();
278 
279  te::vp::Save(dsOGR.get(), outDataSet.get(), outDataSetType.get());
280 
281  dsOGR->close();
282  }
283  else
284  {
285  te::vp::Save(m_outDsrc.get(), outDataSet.get(), outDataSetType.get());
286  }
287 
288  result = true;
289 
290  if(!result)
291  {
292  m_outDsrc->close();
293  return result;
294  }
295  }
296  }
297  break;
298  default:
299  {
300  m_outDsrc->close();
301  TE_LOG_INFO("Vector Processing - Geometric Operation - Strategy Not found!");
302  }
303  return false;
304  }
305 
306  m_outDsrc->close();
307 
308  return result;
309 }
310 
312  te::da::DataSetType* dsType, std::vector<int> tabVec,
313  std::vector<int> geoVec)
314 {
315  std::unique_ptr<te::mem::DataSet> outDSet(new te::mem::DataSet(dsType));
317 
318  int pk = 0;
319 
320  std::unique_ptr<te::da::DataSetType> inDsType =
321  m_inDsrc->getDataSetType(m_inDsetName);
322 
323  std::unique_ptr<te::da::DataSet> inDsetSrc = m_inDsrc->getDataSet(m_inDsetName);
324  std::unique_ptr<te::da::DataSetAdapter> inDset(
325  te::da::CreateAdapter(inDsetSrc.get(), m_converter.get()));
326 
327  inDset->moveBeforeFirst();
328 
329  std::size_t geom_pos = te::da::GetFirstSpatialPropertyPos(inDset.get());
330 
331  while(inDset->moveNext())
332  {
333  try
334  {
335  te::mem::DataSetItem* item = new te::mem::DataSetItem(outDSet.get());
336 
337  item->setInt32(0, pk);
338  bool geom = true;
339 
340  if(m_selectedProps.size() > 0)
341  {
342  for(std::size_t prop_pos = 0; prop_pos < m_selectedProps.size();
343  ++prop_pos)
344  {
345  std::size_t inputPropertyPos =
346  inDsType->getPropertyPosition(m_selectedProps[prop_pos]);
347 
348  if(!inDset->isNull(inputPropertyPos))
349  {
350  item->setValue(m_selectedProps[prop_pos],
351  inDset->getValue(m_selectedProps[prop_pos]).release());
352  }
353  }
354  }
355 
356  std::unique_ptr<te::gm::Geometry> in_geom = inDset->getGeometry(geom_pos);
357 
358  if(tabVec.size() > 0)
359  {
360  for(std::size_t tabPos = 0; tabPos < tabVec.size(); ++tabPos)
361  {
362  switch(tabVec[tabPos])
363  {
364  case te::vp::AREA:
365  {
366  double area = 0;
367  area = CalculateTabularOp(tabVec[tabPos], *in_geom.get());
368  item->setDouble("area", area);
369  }
370  break;
371  case te::vp::LINE:
372  {
373  double line = 0;
374  line = CalculateTabularOp(tabVec[tabPos], *in_geom.get());
375  item->setDouble("line_length", line);
376  }
377  break;
378  case te::vp::PERIMETER:
379  {
380  double perimeter = 0;
381  perimeter = CalculateTabularOp(tabVec[tabPos], *in_geom.get());
382  item->setDouble("perimeter", perimeter);
383  }
384  break;
385  default:
386  {
387  TE_LOG_INFO(
388  "Vector Processing - Geometric Operation - Could not "
389  "insert the tabular value.");
390  }
391  }
392  }
393  }
394 
395  if(geoVec.size() > 0)
396  {
397  for(std::size_t geoPos = 0; geoPos < geoVec.size(); ++geoPos)
398  {
399  switch(geoVec[geoPos])
400  {
401  case te::vp::CONVEX_HULL:
402  {
403  std::size_t pos = te::da::GetPropertyPos(dsType, "convex_hull");
404  if(pos < dsType->size())
405  {
406  std::unique_ptr<te::gm::Geometry> convexHull(
407  in_geom->convexHull());
408  convexHull->setSRID(geomProp->getSRID());
409 
410  if((convexHull->getGeomTypeId() == te::gm::PolygonType) ||
411  (convexHull->getGeomTypeId() == te::gm::PolygonMType) ||
412  (convexHull->getGeomTypeId() == te::gm::PolygonZType) ||
413  (convexHull->getGeomTypeId() == te::gm::PolygonZMType))
414  {
415  item->setGeometry("convex_hull", convexHull.release());
416  geom = true;
417  }
418  else
419  {
420  geom = false;
421  }
422  }
423  }
424  break;
425  case te::vp::CENTROID:
426  {
427  std::size_t pos = te::da::GetPropertyPos(dsType, "centroid");
428  if(pos < dsType->size())
429  {
430  te::gm::Coord2D center = in_geom->getCentroid();
431  te::gm::Point* point =
432  new te::gm::Point(center.x, center.y, geomProp->getSRID());
433  item->setGeometry("centroid", point);
434  geom = true;
435  }
436  }
437  break;
438  case te::vp::MBR:
439  {
440  std::size_t pos = te::da::GetPropertyPos(dsType, "mbr");
441  if(pos < dsType->size())
442  {
443  std::unique_ptr<te::gm::Geometry> mbr(in_geom->getEnvelope());
444  mbr->setSRID(geomProp->getSRID());
445  if((mbr->getGeomTypeId() == te::gm::PolygonType) ||
446  (mbr->getGeomTypeId() == te::gm::PolygonMType) ||
447  (mbr->getGeomTypeId() == te::gm::PolygonZType) ||
448  (mbr->getGeomTypeId() == te::gm::PolygonZMType))
449  {
450  item->setGeometry("mbr", mbr.release());
451  geom = true;
452  }
453  else
454  {
455  geom = false;
456  }
457  }
458  }
459  break;
460  default:
461  {
462  TE_LOG_INFO(
463  "Vector Processing - Geometric Operation - Could not "
464  "insert the geometric value.");
465  }
466  }
467  }
468  }
469  else
470  {
471  std::unique_ptr<te::gm::Geometry> g(in_geom.release());
472  g->setSRID(geomProp->getSRID());
474  0, te::gm::GeometryCollectionType, g->getSRID());
475 
476  switch(g->getGeomTypeId())
477  {
478  case te::gm::PointType:
479  case te::gm::PointMType:
480  case te::gm::PointZType:
481  case te::gm::PointZMType:
486  case te::gm::PolygonType:
490  {
491  if(g->isValid())
492  teGeomColl->add(g.release());
493  }
494  break;
495  default:
496  {
497  TE_LOG_INFO(
498  "Vector Processing - Geometric Operation - Could not insert "
499  "the geometry in collection.");
500  }
501  }
502  if(teGeomColl->getNumGeometries() != 0)
503  item->setGeometry("geom", teGeomColl);
504  else
505  item->setGeometry("geom", g.release());
506  }
507 
508  if(geom)
509  {
510  outDSet->add(item);
511  ++pk;
512  }
513  }
514  catch(te::common::Exception& e)
515  {
516  TE_LOG_ERROR("Vector Processing - Geometric Operation - " + e.what());
517  continue;
518  }
519  }
520 
521  return outDSet.release();
522 }
523 
525  te::da::DataSetType* dsType, std::vector<int> tabVec,
526  std::vector<int> geoVec)
527 {
528  std::unique_ptr<te::mem::DataSet> outDSet(new te::mem::DataSet(dsType));
530 
531  int pk = 0;
532 
533  std::unique_ptr<te::da::DataSet> inDsetSrc = m_inDsrc->getDataSet(m_inDsetName);
534  std::unique_ptr<te::da::DataSetAdapter> inDset(
535  te::da::CreateAdapter(inDsetSrc.get(), m_converter.get()));
536 
537  std::size_t geom_pos = te::da::GetFirstSpatialPropertyPos(inDset.get());
538 
539  inDset->moveBeforeFirst();
540  te::mem::DataSetItem* item = new te::mem::DataSetItem(outDSet.get());
541 
542  item->setInt32(0, pk);
543 
544  std::vector<te::gm::Geometry*> geometriesToUnion;
545  std::unique_ptr<te::gm::Geometry> dissolvedGeometry;
546 
547  if(inDset->size() > 1)
548  {
549  while(inDset->moveNext())
550  {
551  try
552  {
553  if (inDset->isNull(geom_pos))
554  continue;
555 
556  std::unique_ptr<te::gm::Geometry> c_geom = inDset->getGeometry(geom_pos);
557 
558  if(c_geom->isValid())
559  geometriesToUnion.push_back(c_geom.release());
560 
561  }
562  catch(te::common::Exception& e)
563  {
564  TE_LOG_ERROR("Vector Processing - Geometric Operation - " + e.what());
565  continue;
566  }
567  }
568  }
569 
570  if(geometriesToUnion.empty())
571  return outDSet.release();
572 
573  dissolvedGeometry = GetGeometryUnion(geometriesToUnion);
574 
575  if(!dissolvedGeometry->isValid())
576  return outDSet.release();
577 
578  if(tabVec.size() > 0)
579  {
580  for(std::size_t tabPos = 0; tabPos < tabVec.size(); ++tabPos)
581  {
582  switch(tabVec[tabPos])
583  {
584  case te::vp::AREA:
585  {
586  double area = 0;
587  area = CalculateTabularOp(tabVec[tabPos], *dissolvedGeometry.get());
588  item->setDouble("area", area);
589  }
590  break;
591  case te::vp::LINE:
592  {
593  double line = 0;
594  line = CalculateTabularOp(tabVec[tabPos], *dissolvedGeometry.get());
595  item->setDouble("line_length", line);
596  }
597  break;
598  case te::vp::PERIMETER:
599  {
600  double perimeter = 0;
601  perimeter = CalculateTabularOp(tabVec[tabPos], *dissolvedGeometry.get());
602  item->setDouble("perimeter", perimeter);
603  }
604  break;
605  default:
606  {
607  TE_LOG_INFO(
608  "Vector Processing - Geometric Operation - Could not insert "
609  "the tabular value.");
610  }
611  }
612  }
613  }
614 
615  if(geoVec.size() > 0)
616  {
617  for(std::size_t geoPos = 0; geoPos < geoVec.size(); ++geoPos)
618  {
619  switch(geoVec[geoPos])
620  {
621  case te::vp::CONVEX_HULL:
622  {
623  std::size_t pos = te::da::GetPropertyPos(dsType, "convex_hull");
624  if(pos < dsType->size())
625  {
626  std::unique_ptr<te::gm::Geometry> convexHull(
627  dissolvedGeometry->convexHull());
628  convexHull->setSRID(geomProp->getSRID());
629 
630  item->setGeometry("convex_hull", convexHull.release());
631  }
632  }
633  break;
634  case te::vp::CENTROID:
635  {
636  std::size_t pos = te::da::GetPropertyPos(dsType, "centroid");
637  if(pos < dsType->size())
638  {
639  const te::gm::Envelope* env = dissolvedGeometry->getMBR();
640  te::gm::Coord2D center = env->getCenter();
641  te::gm::Point* point =
642  new te::gm::Point(center.x, center.y, geomProp->getSRID());
643  item->setGeometry("centroid", point);
644  }
645  }
646  break;
647  case te::vp::MBR:
648  {
649  std::size_t pos = te::da::GetPropertyPos(dsType, "mbr");
650  if(pos < dsType->size())
651  {
652  std::unique_ptr<te::gm::Geometry> mbr(dissolvedGeometry->getEnvelope());
653  mbr->setSRID(geomProp->getSRID());
654  item->setGeometry("mbr", mbr.release());
655  }
656  }
657  break;
658  default:
659  {
660  TE_LOG_INFO(
661  "Vector Processing - Geometric Operation - Could not insert "
662  "the geometry in collection.");
663  }
664  }
665  }
666  }
667  else
668  {
669  std::unique_ptr<te::gm::Geometry> g(dissolvedGeometry.release());
670  g->setSRID(geomProp->getSRID());
672  0, te::gm::GeometryCollectionType, g->getSRID());
673 
674  switch(g->getGeomTypeId())
675  {
676  case te::gm::PointType:
677  case te::gm::PointMType:
678  case te::gm::PointZType:
679  case te::gm::PointZMType:
684  case te::gm::PolygonType:
688  {
689  if(g->isValid())
690  teGeomColl->add(g.release());
691  }
692  break;
693  default:
694  {
695  TE_LOG_INFO(
696  "Vector Processing - Geometric Operation - Could not insert the "
697  "geometry in collection.");
698  }
699  }
700  if(teGeomColl->getNumGeometries() != 0)
701  item->setGeometry("geom", teGeomColl);
702  else
703  item->setGeometry("geom", g.release());
704  }
705 
706  outDSet->add(item);
707 
708  return outDSet.release();
709 }
710 
712  te::da::DataSetType* dsType, std::vector<int> tabVec,
713  std::vector<int> geoVec)
714 {
715  std::map<std::string, te::gm::Geometry*> geometries;
716 
717  std::unique_ptr<te::da::DataSet> inDsetSrc = m_inDsrc->getDataSet(m_inDsetName);
718  std::unique_ptr<te::da::DataSetAdapter> inDset(
719  te::da::CreateAdapter(inDsetSrc.get(), m_converter.get()));
720 
721  std::unique_ptr<te::mem::DataSet> outDSet(new te::mem::DataSet(dsType));
722 
723  std::size_t geom_pos = te::da::GetFirstSpatialPropertyPos(inDset.get());
724 
725  inDset->moveBeforeFirst();
726 
727  if(inDset->size() > 0)
728  {
729  std::map<std::string, std::vector<te::gm::Geometry*> > groups;
730  std::map<std::string, std::vector<te::gm::Geometry*> >::iterator itg;
731 
732  inDset->moveBeforeFirst();
733  while(inDset->moveNext())
734  {
735  try
736  {
737  std::string key = inDset->getAsString(m_attribute);
738  std::unique_ptr<te::gm::Geometry> geom = inDset->getGeometry(geom_pos);
739 
740  if(!geom->isValid())
741  continue;
742 
743  itg = groups.find(key);
744 
745  if (itg==groups.end())
746  {
747  std::vector<te::gm::Geometry*> geometriesToDissolve;
748 
749  geometriesToDissolve.push_back(geom.release());
750 
751  groups.insert(std::pair<std::string, std::vector<te::gm::Geometry*> >(
752  key, geometriesToDissolve));
753  }
754  else
755  {
756  itg->second.push_back(geom.release());
757  }
758  }
759  catch(te::common::Exception& e)
760  {
761  TE_LOG_ERROR("Vector Processing - Geometric Operation - " + e.what());
762  continue;
763  }
764  }
765 
766  itg = groups.begin();
767  while(itg != groups.end())
768  {
769  try
770  {
771  // calculate the spatial aggregation
772  std::unique_ptr<te::gm::Geometry> geometry = te::gm::GetGeometryUnion(itg->second);
773 
774  if(geometry->isValid())
775  geometries.insert(std::pair<std::string, te::gm::Geometry*>(itg->first, geometry.release()));
776 
777  ++itg;
778  }
779  catch(te::common::Exception& e)
780  {
781  TE_LOG_ERROR("Vector Processing - Geometric Operation - " + e.what());
782  ++itg;
783  continue;
784  }
785  }
786 
787  }
788  else
789  {
790  return outDSet.release();
791  }
792 
793 // insert result in dataset.
794  std::map<std::string, te::gm::Geometry*>::iterator itGeom;
795  int i = 0;
796 
797  itGeom = geometries.begin();
798  while(itGeom != geometries.end())
799  {
800  te::mem::DataSetItem* outItem = new te::mem::DataSetItem(outDSet.get());
801 
802  // inserting the id in dataSet.
803  outItem->setInt32(0, i);
804  // inserting aggregated attribute.
805  te::dt::Property* prop = m_converter->getResult()->getProperty(m_attribute);
806  switch(prop->getType())
807  {
808  case te::dt::STRING_TYPE:
809  outItem->setString(1, itGeom->first);
810  break;
811  case te::dt::INT16_TYPE:
812  outItem->setInt16(1, boost::lexical_cast<int16_t>(itGeom->first));
813  break;
814  case te::dt::INT32_TYPE:
815  outItem->setInt32(1, boost::lexical_cast<int>(itGeom->first));
816  break;
817  case te::dt::INT64_TYPE:
818  outItem->setInt64(1, boost::lexical_cast<int>(itGeom->first));
819  break;
820  case te::dt::DOUBLE_TYPE:
821  outItem->setDouble(1, boost::lexical_cast<double>(itGeom->first));
822  break;
823  default:
824  TE_LOG_INFO(
825  "Vector Processing - Geometric Operation - Could not insert the "
826  "aggregated value.");
827  break;
828  }
829 
830  // inserting geometries.
831  if(tabVec.size() > 0)
832  {
833  for(std::size_t tabPos = 0; tabPos < tabVec.size(); ++tabPos)
834  {
835  switch(tabVec[tabPos])
836  {
837  case te::vp::AREA:
838  {
839  double area = 0;
840  area = CalculateTabularOp(tabVec[tabPos], *itGeom->second);
841  outItem->setDouble("area", area);
842  }
843  break;
844  case te::vp::LINE:
845  {
846  double line = 0;
847  line = CalculateTabularOp(tabVec[tabPos], *itGeom->second);
848  outItem->setDouble("line_length", line);
849  }
850  break;
851  case te::vp::PERIMETER:
852  {
853  double perimeter = 0;
854  perimeter = CalculateTabularOp(tabVec[tabPos], *itGeom->second);
855  outItem->setDouble("perimeter", perimeter);
856  }
857  break;
858  default:
859  {
860  TE_LOG_INFO(
861  "Vector Processing - Geometric Operation - Could not insert "
862  "the tabular value.");
863  }
864  }
865  }
866  }
867 
868  if(geoVec.size() > 0)
869  {
870  for(std::size_t geoPos = 0; geoPos < geoVec.size(); ++geoPos)
871  {
872  switch(geoVec[geoPos])
873  {
874  case te::vp::CONVEX_HULL:
875  {
876  std::size_t pos = te::da::GetPropertyPos(dsType, "convex_hull");
877  if(pos < dsType->size())
878  {
879  std::unique_ptr<te::gm::Geometry> convexHull(
880  itGeom->second->convexHull());
881  convexHull->setSRID(itGeom->second->getSRID());
882 
883  outItem->setGeometry("convex_hull", convexHull.release());
884  }
885  }
886  break;
887  case te::vp::CENTROID:
888  {
889  std::size_t pos = te::da::GetPropertyPos(dsType, "centroid");
890  if(pos < dsType->size())
891  {
892  const te::gm::Envelope* env = itGeom->second->getMBR();
893  te::gm::Coord2D center = env->getCenter();
894  te::gm::Point* point =
895  new te::gm::Point(center.x, center.y, itGeom->second->getSRID());
896  outItem->setGeometry("centroid", point);
897  }
898  }
899  break;
900  case te::vp::MBR:
901  {
902  std::size_t pos = te::da::GetPropertyPos(dsType, "mbr");
903  if(pos < dsType->size())
904  {
905  std::unique_ptr<te::gm::Geometry> mbr(
906  itGeom->second->getEnvelope());
907  mbr->setSRID(itGeom->second->getSRID());
908  outItem->setGeometry("mbr", mbr.release());
909  }
910  }
911  break;
912  default:
913  {
914  TE_LOG_INFO(
915  "Vector Processing - Geometric Operation - Could not insert "
916  "the geometric value.");
917  }
918  }
919  }
920  }
921  else
922  {
924  0, te::gm::GeometryCollectionType, itGeom->second->getSRID());
925 
926  switch(itGeom->second->getGeomTypeId())
927  {
928  case te::gm::PointType:
929  case te::gm::PointMType:
930  case te::gm::PointZType:
931  case te::gm::PointZMType:
936  case te::gm::PolygonType:
940  {
941  if(itGeom->second->isValid())
942  teGeomColl->add(itGeom->second);
943  }
944  break;
945  default:
946  {
947  TE_LOG_INFO(
948  "Vector Processing - Geometric Operation - Could not insert the "
949  "geometry in collection.");
950  }
951  }
952  if(teGeomColl->getNumGeometries() != 0)
953  outItem->setGeometry("geom", teGeomColl);
954  else
955  outItem->setGeometry("geom", itGeom->second);
956  }
957 
958  outDSet->add(outItem);
959  ++itGeom;
960  ++i;
961  }
962 
963  return outDSet.release();
964 }
965 
966 
967 double te::vp::GeometricOpMemory::CalculateTabularOp(const int& tabOperation,
968  te::gm::Geometry& geom)
969 {
970  double value = 0;
971  te::gm::GeomType geomType = geom.getGeomTypeId();
972 
973  switch(tabOperation)
974  {
975  case te::vp::AREA:
976  {
977  if(geomType == te::gm::PolygonType)
978  {
979  std::unique_ptr<te::gm::Polygon> pol(dynamic_cast<te::gm::Polygon*>(geom.clone()));
980 
981  if(pol.get())
982  {
983  if(pol->getSRID() != m_newSRID)
984  pol->transform(m_newSRID);
985 
986  value = pol->getArea();
987  }
988  }
989  if(geomType == te::gm::MultiPolygonType)
990  {
991  std::string type = geom.getGeometryType();
992 
993  if(type == "GeometryCollection")
994  {
995  std::unique_ptr<te::gm::GeometryCollection> m_geoColl(dynamic_cast<te::gm::GeometryCollection*>(geom.clone()));
996 
997  if(m_geoColl.get())
998  {
999  if(m_geoColl->getSRID() != m_newSRID)
1000  m_geoColl->transform(m_newSRID);
1001 
1002  std::vector<te::gm::Geometry*> geomVec =
1003  m_geoColl->getGeometries();
1004 
1005  for(std::size_t i = 0; i < geomVec.size(); ++i)
1006  {
1007  te::gm::GeomType inType = geomVec[i]->getGeomTypeId();
1008  if(inType == te::gm::PolygonType)
1009  {
1010  te::gm::Polygon* m_pol =
1011  dynamic_cast<te::gm::Polygon*>(geomVec[i]);
1012  if(m_pol)
1013  value += m_pol->getArea();
1014  }
1015  if(inType == te::gm::MultiPolygonType)
1016  {
1017  te::gm::MultiPolygon* m_pol =
1018  dynamic_cast<te::gm::MultiPolygon*>(geomVec[i]);
1019  if(m_pol)
1020  value += m_pol->getArea();
1021  }
1022  }
1023  }
1024  }
1025  else
1026  {
1027  std::unique_ptr<te::gm::MultiPolygon> m_pol(dynamic_cast<te::gm::MultiPolygon*>(geom.clone()));
1028 
1029  if(m_pol.get())
1030  {
1031  if(m_pol->getSRID() != m_newSRID)
1032  m_pol->transform(m_newSRID);
1033 
1034  value = m_pol->getArea();
1035  }
1036 
1037  }
1038  }
1039  return value;
1040  }
1041  break;
1042  case te::vp::LINE:
1043  {
1044  if(geomType == te::gm::LineStringType)
1045  {
1046  std::unique_ptr<te::gm::LineString> lineString(dynamic_cast<te::gm::LineString*>(geom.clone()));
1047 
1048  if(lineString.get())
1049  {
1050  if(lineString->getSRID() != m_newSRID)
1051  lineString->transform(m_newSRID);
1052 
1053  value = lineString->getLength();
1054  }
1055  }
1056  if(geomType == te::gm::MultiLineStringType)
1057  {
1058  std::unique_ptr<te::gm::MultiLineString> m_lineString(dynamic_cast<te::gm::MultiLineString*>(geom.clone()));
1059 
1060  if(m_lineString.get())
1061  {
1062  if(m_lineString->getSRID() != m_newSRID)
1063  m_lineString->transform(m_newSRID);
1064 
1065  value = m_lineString->getLength();
1066  }
1067  }
1068  return value;
1069  }
1070  break;
1071  case te::vp::PERIMETER:
1072  {
1073  if(geomType == te::gm::PolygonType)
1074  {
1075  std::unique_ptr<te::gm::Polygon> pol(dynamic_cast<te::gm::Polygon*>(geom.clone()));
1076  if(pol.get())
1077  {
1078  if(pol->getSRID() != m_newSRID)
1079  pol->transform(m_newSRID);
1080 
1081  value = pol->getPerimeter();
1082  }
1083  }
1084  if(geomType == te::gm::MultiPolygonType)
1085  {
1086  std::string type = geom.getGeometryType();
1087 
1088  if(type == "GeometryCollection")
1089  {
1090  std::unique_ptr<te::gm::GeometryCollection> m_geoColl(dynamic_cast<te::gm::GeometryCollection*>(geom.clone()));
1091 
1092  if(m_geoColl.get())
1093  {
1094  if(m_geoColl->getSRID() != m_newSRID)
1095  m_geoColl->transform(m_newSRID);
1096 
1097  std::vector<te::gm::Geometry*> geomVec =
1098  m_geoColl->getGeometries();
1099 
1100  for(std::size_t i = 0; i < geomVec.size(); ++i)
1101  {
1102  te::gm::GeomType inType = geomVec[i]->getGeomTypeId();
1103  if(inType == te::gm::PolygonType)
1104  {
1105  te::gm::Polygon* m_pol =
1106  dynamic_cast<te::gm::Polygon*>(geomVec[i]);
1107  if(m_pol)
1108  value += m_pol->getPerimeter();
1109  }
1110  if(inType == te::gm::MultiPolygonType)
1111  {
1112  te::gm::MultiPolygon* m_pol =
1113  dynamic_cast<te::gm::MultiPolygon*>(geomVec[i]);
1114  if(m_pol)
1115  value += m_pol->getPerimeter();
1116  }
1117  }
1118  }
1119  }
1120  else
1121  {
1122  std::unique_ptr<te::gm::MultiPolygon> m_pol(dynamic_cast<te::gm::MultiPolygon*>(geom.clone()));
1123 
1124  if(m_pol.get())
1125  {
1126  if(m_pol->getSRID() != m_newSRID)
1127  m_pol->transform(m_newSRID);
1128 
1129  value = m_pol->getPerimeter();
1130  }
1131  }
1132  }
1133  return value;
1134  }
1135  break;
1136  default:
1137  {
1138  TE_LOG_INFO(
1139  "Vector Processing - Geometric Operation - Could not calculate the "
1140  "operation.");
1141  }
1142  }
1143 
1144  return value;
1145 }
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
te::da::DataSetType * GetDataSetType(te::vp::GeometricOpObjStrategy, bool MultiGeomColumns, int geomOp=-1)
Definition: GeometricOp.cpp:79
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
Geometric property.
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
void setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
double y
y-coordinate.
Definition: Coord2D.h:114
std::vector< std::string > m_outDsetNameVec
Definition: GeometricOp.h:93
void setDouble(std::size_t i, double value)
It sets the value of the i-th property.
The geographic operation Line.
The geographic operation Minimum Bounding Rectangle.
double x
x-coordinate.
Definition: Coord2D.h:113
Base exception class for plugin module.
A class that models the description of a dataset.
Definition: DataSetType.h:72
virtual const char * what() const
It outputs the exception message.
GeomType getGeomTypeId() const _NOEXCEPT_OP(true)
It returns the geometry subclass type identifier.
double getPerimeter() const
It returns the length of the boundary for the surface.
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.
TEDATAACCESSEXPORT std::size_t GetPropertyPos(const DataSet *dataset, const std::string &name)
void setValue(std::size_t i, te::dt::AbstractData *value)
It sets the value of the i-th property.
te::mem::DataSet * SetAggregObj(te::da::DataSetType *dsType, std::vector< int > tabVec, std::vector< int > geoVec)
TEGEOMEXPORT std::unique_ptr< te::gm::Geometry > GetGeometryUnion(const std::vector< te::gm::Geometry * > &geomVec)
It returns the union of a geometry vector.
double CalculateTabularOp(const int &tabOperation, gm::Geometry &geom)
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
void setInt16(std::size_t i, boost::int16_t value)
It sets the value of the i-th property.
double getPerimeter() const
It returns the length of the boundary for the surface.
#define TE_LOG_INFO(message)
Use this tag in order to log a message to the TerraLib default logger with the INFO level...
Definition: Logger.h:315
It models a property definition.
Definition: Property.h:59
unsigned int line
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
TEVPEXPORT void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType, const bool &enableProgress=true)
Coord2D getCenter() const
It returns the rectangle&#39;s center coordinate.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
TEDATAACCESSEXPORT std::size_t GetFirstSpatialPropertyPos(const te::da::DataSet *dataset)
It returns the first dataset spatial property or NULL if none is found.
The geographic operation Area.
Aggregate all objects.
int getSRID() const
It returns the spatial reference system identifier associated to this property.
A point with x and y coordinate values.
Definition: Point.h:50
An Envelope defines a 2D rectangular region.
te::mem::DataSet * SetAggregByAttribute(te::da::DataSetType *dsType, std::vector< int > tabVec, std::vector< int > geoVec)
te::mem::DataSet * SetAllObjects(te::da::DataSetType *dsType, std::vector< int > tabVec, std::vector< int > geoVec)
URI C++ Library.
Definition: Attributes.h:37
std::unique_ptr< te::da::DataSource > m_outDsrc
Definition: GeometricOp.h:91
std::string m_inDsetName
Definition: GeometricOp.h:82
Aggregate objects by attribute.
virtual AbstractData * clone() const =0
It returns a clone of this object.
The geographic operation Perimeter.
std::string m_attribute
Definition: GeometricOp.h:88
Utility functions for the data access module.
The geographic operation Centroid.
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.
double getArea() const
It returns the area of this surface, as measured in the spatial reference system of this surface...
int getType() const
It returns the property data type.
Definition: Property.h:161
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
te::da::DataSourcePtr m_inDsrc
Definition: GeometricOp.h:81
std::vector< std::string > m_selectedProps
Definition: GeometricOp.h:85
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
std::vector< te::vp::GeometricOperation > m_operations
Definition: GeometricOp.h:86
double getArea() const
It returns the area of this MultiSurface, as measured in the spatial reference system of this multisu...
void add(Geometry *g)
It adds the geometry into the collection.
#define TE_LOG_ERROR(message)
Use this tag in order to log a message to the TerraLib default logger with the ERROR level...
Definition: Logger.h:337
The geographic operation Convex Hull.
te::vp::GeometricOpObjStrategy m_objStrategy
Definition: GeometricOp.h:87
void setString(std::size_t i, const std::string &value)
It sets the value of the i-th property.
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)
TEDATAACCESSEXPORT DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
All objects individually.
std::unique_ptr< te::da::DataSetTypeConverter > m_converter
Definition: GeometricOp.h:83
virtual const std::string & getGeometryType() const _NOEXCEPT_OP(true)=0
It returns the name of the geometry subclass.