MultipartToSinglepart.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 MultipartToSinglepart.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/ObjectId.h"
34 #include "../dataaccess/dataset/ObjectIdSet.h"
35 #include "../dataaccess/utils/Utils.h"
36 #include "../datatype/Property.h"
37 #include "../datatype/SimpleProperty.h"
38 #include "../datatype/StringProperty.h"
39 
40 #include "../geometry/Geometry.h"
41 #include "../geometry/GeometryProperty.h"
42 #include "../geometry/MultiLineString.h"
43 #include "../geometry/MultiPoint.h"
44 #include "../geometry/MultiPolygon.h"
45 #include "../geometry/Utils.h"
46 
47 #include "../memory/DataSet.h"
48 #include "../memory/DataSetItem.h"
49 
50 #include "MultipartToSinglepart.h"
51 #include "Config.h"
52 #include "Exception.h"
53 #include "Utils.h"
54 
55 // STL
56 #include <map>
57 #include <math.h>
58 #include <string>
59 #include <vector>
60 
61 // BOOST
62 #include <boost/lexical_cast.hpp>
63 #include <boost/algorithm/string.hpp>
64 
66  : m_oidSet(0)
67 {
68 }
69 
71 {
72 }
73 
75 {
76  te::dt::Property* prop = te::da::GetFirstSpatialProperty(m_inDsType.get());
77  te::gm::GeometryProperty* geomProp = dynamic_cast<te::gm::GeometryProperty*>(prop);
78 
79  if(!te::vp::IsMultiType(geomProp->getGeometryType()))
80  {
81  throw te::common::Exception(TE_TR("This layer has not a multipart geometry!"));
82  }
83 
84  if(m_oidSet)
85  return runSelected();
86  else
87  return runAll();
88 }
89 
91 {
92  std::auto_ptr<te::da::DataSet> inDs;
93 
94  inDs = m_inDsrc->getDataSet(m_inDsName);
95 
96  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(inDs.get());
97 
98  std::auto_ptr<te::da::DataSetType> outDst = getOutDst();
99 
100  std::auto_ptr<te::mem::DataSet> outDs(new te::mem::DataSet(outDst.get()));
101 
102  inDs->moveBeforeFirst();
103 
104  std::size_t pkCount = 0;
105 
106  while(inDs->moveNext())
107  {
108  std::auto_ptr<te::gm::Geometry> geom = inDs->getGeometry(geomPos);
109 
110  std::vector<te::gm::Geometry*> geoms;
111  te::vp::Multi2Single(geom.release(), geoms);
112 
113  if(geoms.size() == 1)
114  {
115  te::mem::DataSetItem* item = new te::mem::DataSetItem(outDs.get());
116 
117  for(std::size_t i = 0; i < inDs->getNumProperties(); ++i)
118  {
119  if(i == 0)
120  {
121  item->setInt32(0, (int32_t)pkCount);
122  ++pkCount;
123  item->setValue(1, inDs->getValue(i).release());
124  }
125  else if(i != geomPos)
126  item->setValue((i+1), inDs->getValue(i).release());
127  else
128  item->setGeometry((i+1), geoms[0]);
129  }
130 
131  outDs->add(item);
132  }
133  else
134  {
135  for(std::size_t g = 0; g < geoms.size(); ++g)
136  {
137  te::mem::DataSetItem* item = new te::mem::DataSetItem(outDs.get());
138 
139  for(std::size_t i = 0; i < inDs->getNumProperties(); ++i)
140  {
141  if(i == 0)
142  {
143  item->setInt32(0, (int32_t)pkCount);
144  ++pkCount;
145  item->setValue(1, inDs->getValue(i).release());
146  }
147  else if(i != geomPos)
148  item->setValue((i+1), inDs->getValue(i).release());
149  else
150  item->setGeometry((i+1), geoms[g]);
151  }
152 
153  outDs->add(item);
154  }
155  }
156  }
157 
158  te::vp::Save(m_outDsrc.get(), outDs.get(), outDst.get());
159 
160  return true;
161 }
162 
164 {
165  std::auto_ptr<te::da::DataSet> inDs;
166 
167  inDs = m_inDsrc->getDataSet(m_inDsName);
168 
169  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(inDs.get());
170 
171  std::auto_ptr<te::da::DataSetType> outDst = getOutDst(true);
172 
173  std::auto_ptr<te::mem::DataSet> outDs(new te::mem::DataSet(outDst.get()));
174 
175  inDs->moveBeforeFirst();
176 
177  std::size_t pkCount = 0;
178 
179  while(inDs->moveNext())
180  {
181  std::auto_ptr<te::gm::Geometry> geom = inDs->getGeometry(geomPos);
182 
183  te::da::ObjectId* geomOid = te::da::GenerateOID(inDs.get(), m_oidSet->getPropertyNames());
184 
185  std::vector<te::gm::Geometry*> geoms;
186  std::vector<te::gm::Geometry*> multiGeoms;
187 
188  if(m_oidSet->contains(geomOid))
189  {
190  te::vp::Multi2Single(geom.release(), geoms);
191 
192  for(std::size_t i = 0; i < geoms.size(); ++i)
193  {
194  multiGeoms.push_back(single2multi(geoms[i]));
195  }
196  }
197  else
198  {
199  geoms.push_back(geom.release());
200  }
201 
202  if(geoms.size() == 1)
203  {
204  te::mem::DataSetItem* item = new te::mem::DataSetItem(outDs.get());
205 
206  for(std::size_t i = 0; i < inDs->getNumProperties(); ++i)
207  {
208  if(i == 0)
209  {
210  item->setInt32(0, (int32_t)pkCount);
211  ++pkCount;
212  item->setValue(1, inDs->getValue(i).release());
213  }
214  else if(i != geomPos)
215  item->setValue((i+1), inDs->getValue(i).release());
216  else
217  item->setGeometry((i+1), geoms[0]);
218  }
219 
220  outDs->add(item);
221  }
222  else
223  {
224  for(std::size_t g = 0; g < multiGeoms.size(); ++g)
225  {
226  te::mem::DataSetItem* item = new te::mem::DataSetItem(outDs.get());
227 
228  for(std::size_t i = 0; i < inDs->getNumProperties(); ++i)
229  {
230  if(i == 0)
231  {
232  item->setInt32(0, (int32_t)pkCount);
233  ++pkCount;
234  item->setValue(1, inDs->getValue(i).release());
235  }
236  else if(i != geomPos)
237  item->setValue((i+1), inDs->getValue(i).release());
238  else
239  item->setGeometry((i+1), multiGeoms[g]);
240  }
241 
242  outDs->add(item);
243  }
244  }
245  }
246 
247  te::vp::Save(m_outDsrc.get(), outDs.get(), outDst.get());
248  return true;
249 }
250 
252  std::string inDsName,
253  std::auto_ptr<te::da::DataSetType> inDsType,
254  const te::da::ObjectIdSet* oidSet)
255 {
256  m_inDsrc = inDsrc;
257  m_inDsName = inDsName;
258  m_inDsType = inDsType;
259  m_oidSet = oidSet;
260 }
261 
263 {
264  m_outDsrc = outDsrc;
265  m_outDsName = outDsName;
266 }
267 
268 std::auto_ptr<te::da::DataSetType> te::vp::MultipartToSinglepart::getOutDst(bool onlySelected)
269 {
270  std::auto_ptr<te::da::DataSetType> outDst(new te::da::DataSetType(m_outDsName));
271 
272  te::dt::Property* newId = new te::dt::SimpleProperty("newid", te::dt::INT32_TYPE, true);
273 
274  outDst->add(newId);
275 
276  for(std::size_t i = 0; i < m_inDsType->size(); ++i)
277  {
278  te::dt::Property* oldP = m_inDsType->getProperty(i);
279  te::dt::Property* newP = oldP->clone();
280 
281  if(!onlySelected)
282  {
283  if(newP->getType() == te::dt::GEOMETRY_TYPE)
284  {
285  te::gm::GeometryProperty* geomP = dynamic_cast<te::gm::GeometryProperty*>(newP);
286 
288  }
289  }
290 
291  outDst->add(newP);
292  }
293 
294  return outDst;
295 }
296 
298 {
299  switch(geom->getGeomTypeId())
300  {
302  {
304  g->add(geom);
305  g->setSRID(geom->getSRID());
306  return g;
307  }
309  {
311  g->add(geom);
312  g->setSRID(geom->getSRID());
313  return g;
314  }
316  {
318  g->add(geom);
319  g->setSRID(geom->getSRID());
320  return g;
321  }
323  {
325  g->add(geom);
326  g->setSRID(geom->getSRID());
327  return g;
328  }
329  case te::gm::PointType:
330  {
332  g->add(geom);
333  g->setSRID(geom->getSRID());
334  return g;
335  }
336  case te::gm::PointMType:
337  {
339  g->add(geom);
340  g->setSRID(geom->getSRID());
341  return g;
342  }
343  case te::gm::PointZType:
344  {
346  g->add(geom);
347  g->setSRID(geom->getSRID());
348  return g;
349  }
350  case te::gm::PointZMType:
351  {
353  g->add(geom);
354  g->setSRID(geom->getSRID());
355  return g;
356  }
357  case te::gm::PolygonType:
358  {
360  g->add(geom);
361  g->setSRID(geom->getSRID());
362  return g;
363  }
365  {
367  g->add(geom);
368  g->setSRID(geom->getSRID());
369  return g;
370  }
372  {
374  g->add(geom);
375  g->setSRID(geom->getSRID());
376  return g;
377  }
379  {
381  g->add(geom);
382  g->setSRID(geom->getSRID());
383  return g;
384  }
385  default:
386  return 0;
387  }
388 }
int getSRID() const
It returns the Spatial Reference System ID associated to this geometric object.
Definition: Geometry.h:189
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
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.
te::gm::Geometry * single2multi(te::gm::Geometry *geom)
void setGeometryType(GeomType t)
It sets the geometry subtype.
void Multi2Single(te::gm::Geometry *g, std::vector< te::gm::Geometry * > &geoms)
Definition: Utils.cpp:222
An atomic property like an integer or double.
TEDATAACCESSEXPORT ObjectId * GenerateOID(DataSet *dataset, const std::vector< std::string > &names)
Definition: Utils.cpp:446
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
A class that models the description of a dataset.
Definition: DataSetType.h:72
void Save(te::da::DataSource *source, te::da::DataSet *result, te::da::DataSetType *outDsType)
Definition: Utils.cpp:172
virtual Property * clone() const =0
It returns a clone of the object.
void setValue(std::size_t i, te::dt::AbstractData *value)
It sets the value of the i-th property.
std::auto_ptr< te::da::DataSetType > getOutDst(bool onlySelected=false)
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:346
It models a property definition.
Definition: Property.h:59
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
Definition: DataSet.h:65
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.
Definition: Utils.cpp:462
void setOutput(te::da::DataSourcePtr outDsrc, std::string outDsName)
This class represents a set of unique ids created in the same context. i.e. from the same data set...
Definition: ObjectIdSet.h:55
This class represents an unique id for a data set element.
Definition: ObjectId.h:47
GeomType getGeometryType() const
It returns the geometry subtype allowed for the property.
GeomType getGeomTypeId() const
It returns the geometry subclass type identifier.
Definition: Geometry.h:178
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
int getType() const
It returns the property data type.
Definition: Property.h:161
MultiLineString is a MultiCurve whose elements are LineStrings.
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Definition: DataSetItem.h:56
void setSRID(int srid)
It sets the Spatial Reference System ID of the geometry collection and all its parts.
void setInput(te::da::DataSourcePtr inDsrc, std::string inDsName, std::auto_ptr< te::da::DataSetType > inDsType, const te::da::ObjectIdSet *oidSet=0)
void add(Geometry *g)
It adds the geometry into the collection.
te::gm::GeomType GetSimpleType(te::gm::GeomType geomType)
Definition: Utils.cpp:256
Configuration flags for the Terrralib Vector Processing module.
Aggregation Vector Processing functions.
TEDATAACCESSEXPORT te::dt::Property * GetFirstSpatialProperty(const DataSetType *dt)
Definition: Utils.cpp:534
bool IsMultiType(te::gm::GeomType geomType)
Definition: Utils.cpp:234