All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SamplePointsGeneratorStratified.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/sa/core/SamplePointsGeneratorStratified.cpp
22 
23  \brief This file contains a class to generate samples points using stratified strategy.
24 
25  \reference Adapted from TerraLib4.
26 */
27 
28 // Terralib Includes
29 #include "../../common/Exception.h"
30 #include "../../common/Translator.h"
31 #include "../../common/STLUtils.h"
32 #include "../../common/progress/TaskProgress.h"
33 #include "../../dataaccess/utils/Utils.h"
34 #include "../../datatype/SimpleProperty.h"
35 #include "../../geometry/Geometry.h"
36 #include "../../geometry/GeometryProperty.h"
37 #include "../../geometry/Polygon.h"
38 #include "../../memory/DataSet.h"
39 #include "../../memory/DataSetItem.h"
40 #include "../core/Utils.h"
41 #include "../Enums.h"
43 
45 {
47 }
48 
50 {
51  std::map<std::string, std::vector<te::gm::Geometry*> >::iterator it = m_classMap.begin();
52 
53  while(it != m_classMap.end())
54  {
55  std::vector<te::gm::Geometry*> geomVec = it->second;
56 
57  te::common::FreeContents(geomVec);
58 
59  ++it;
60  }
61 
62  m_classMap.clear();
63 }
64 
66 {
67  m_nPoints = nPoints;
68 }
69 
70 void te::sa::SamplePointsGeneratorStratified::setInputDataSet(std::auto_ptr<te::da::DataSet> dataSet)
71 {
72  m_dataSet = dataSet;
73 }
74 
76 {
77  m_attrName = attrName;
78 }
79 
81 {
82  m_propToArea = isProp;
83 }
84 
86 {
87  std::vector<std::string> names;
88 
89  std::map<std::string, std::vector<te::gm::Geometry*> >::iterator it = m_classMap.begin();
90 
91  while(it != m_classMap.end())
92  {
93  names.push_back(it->first);
94 
95  ++it;
96  }
97 
98  return names;
99 }
100 
102 {
103  std::auto_ptr<te::da::DataSetType> dsType(new te::da::DataSetType(m_outputDataSetName));
104 
105  //create id property
107  dsType->add(idProperty);
108 
109  //create class property
111  dsType->add(classProperty);
112 
113  //create geometry property
115  dsType->add(geomProperty);
116 
117  //create primary key
118  std::string pkName = TE_SA_SPG_ATTR_PK_NAME;
119  pkName+= "_" + m_outputDataSetName;
120  te::da::PrimaryKey* pk = new te::da::PrimaryKey(pkName, dsType.get());
121  pk->add(idProperty);
122 
123  return dsType;
124 }
125 
127 {
128  std::auto_ptr<te::mem::DataSet> ds(new te::mem::DataSet(dsType));
129 
130  //create the class map
131  createClassMap();
132 
133  std::map<std::string, int> nPointsPerClass;
134 
135  //define the number of samples for each class using the area of the polygons
136  if(m_propToArea)
137  {
138  std::map<std::string, double> areaPerClass;
139 
140  std::map<std::string, std::vector<te::gm::Geometry*> >::iterator it = m_classMap.begin();
141 
142  //calculate the total area of each class
143  std::vector<double> areas;
144 
145  while(it != m_classMap.end())
146  {
147  std::vector<te::gm::Geometry*> geomVec = it->second;
148 
149  double totArea = 0.;
150 
151  for(std::size_t t = 0; t < geomVec.size(); ++t)
152  {
153  totArea += te::sa::GetArea(geomVec[t]);
154  }
155 
156  areaPerClass.insert(std::map<std::string, double>::value_type(it->first, totArea));
157 
158  areas.push_back(totArea);
159 
160  ++it;
161  }
162 
163  //calculate the proportional number of points for each class
164  std::vector<double>::iterator minPos = std::min_element(areas.begin(), areas.end());
165  double minArea = *minPos;
166 
167  it = m_classMap.begin();
168 
169  while(it != m_classMap.end())
170  {
171  int nPoints = (int)((areaPerClass[it->first] * m_nPoints) / minArea);
172 
173  nPointsPerClass.insert(std::map<std::string, int>::value_type(it->first, nPoints));
174 
175  ++it;
176  }
177  }
178  else
179  {
180  std::map<std::string, std::vector<te::gm::Geometry*> >::iterator it = m_classMap.begin();
181 
182  //associate the default number of points for each class
183  while(it != m_classMap.end())
184  {
185  nPointsPerClass.insert(std::map<std::string, int>::value_type(it->first, m_nPoints));
186 
187  ++it;
188  }
189  }
190 
191  //create task
193 
194  task.setTotalSteps(m_classMap.size());
195  task.setMessage(TE_TR("Creating Points by Class."));
196 
197  //generate samples
198  int idCount = 0;
199 
200  std::map<std::string, std::vector<te::gm::Geometry*> >::iterator it = m_classMap.begin();
201 
202  while(it != m_classMap.end())
203  {
204  std::string className = it->first;
205 
206  std::vector<te::gm::Geometry*> geomVec = it->second;
207 
208  m_distInt = boost::random::uniform_int_distribution<>(0, geomVec.size() - 1);
209 
210  int nPoints = nPointsPerClass[className];
211 
212  for(int i = 0; i < nPoints; ++i)
213  {
214  //create dataset item
215  te::mem::DataSetItem* item = new te::mem::DataSetItem(ds.get());
216 
217  //set id
218  item->setInt32(TE_SA_SPG_ATTR_ID_NAME, idCount);
219 
220  //set class name
221  item->setString(TE_SA_SPG_ATTR_CLASS_NAME, className);
222 
223  //set geometry
224  item->setGeometry(TE_SA_SPG_ATTR_GEOM_NAME, getPointInGeometry(geomVec[m_distInt(m_gen)]));
225 
226  ds->add(item);
227 
228  ++idCount;
229  }
230 
231  if(!task.isActive())
232  {
233  throw te::common::Exception(TE_TR("Operation canceled by the user."));
234  }
235 
236  task.pulse();
237 
238  ++it;
239  }
240 
241  return ds;
242 }
243 
245 {
246  m_classMap.clear();
247 
248  m_dataSet->moveBeforeFirst();
249 
250  std::size_t geomIdx = te::da::GetFirstPropertyPos(m_dataSet.get(), te::dt::GEOMETRY_TYPE);
251 
252  while(m_dataSet->moveNext())
253  {
254  //class name
255  std::string className = m_dataSet->getString(m_attrName);
256 
257  //geometry
258  te::gm::Geometry* geom = m_dataSet->getGeometry(geomIdx).release();
259 
260  std::map<std::string, std::vector<te::gm::Geometry*> >::iterator it = m_classMap.find(className);
261 
262  //insert into map
263  if(it == m_classMap.end())
264  {
265  std::vector<te::gm::Geometry*> geomVec;
266  geomVec.push_back(geom);
267 
268  m_classMap.insert(std::map<std::string, std::vector<te::gm::Geometry*> >::value_type(className, geomVec));
269  }
270  else
271  {
272  it->second.push_back(geom);
273  }
274  }
275 }
276 
278 {
279  te::gm::Point* p = 0;
280 
281  bool within = false;
282 
283  while(within == false)
284  {
285  p = getPoint(g->getMBR());
286 
287  if(p->within(g))
288  within = true;
289  else
290  delete p;
291  }
292 
293  return p;
294 }
Geometric property.
void setMessage(const std::string &message)
Set the task message.
void add(te::dt::Property *p)
It adds a property to the list of properties of the primary key.
Definition: PrimaryKey.h:123
void setGeometry(std::size_t i, te::gm::Geometry *value)
It sets the value of the i-th property.
An atomic property like an integer or double.
te::sa::SamplePointsGeneratorType m_type
Generator Type.
A class that models the description of a dataset.
Definition: DataSetType.h:72
virtual std::auto_ptr< te::da::DataSetType > createDataSetType()
This file contains a class to generate samples points using stratified strategy.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
bool isActive() const
Verify if the task is active.
void setTotalSteps(int value)
Set the task total stepes.
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
TESAEXPORT double GetArea(te::gm::Geometry *geom)
Function used to get area of a geometry.
Definition: Utils.cpp:278
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
Definition: DataSet.h:65
te::gm::Point * getPointInGeometry(te::gm::Geometry *g)
A point with x and y coordinate values.
Definition: Point.h:50
#define TE_SA_SPG_ATTR_GEOM_NAME
Definition: Config.h:95
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
#define TE_SA_SPG_ATTR_PK_NAME
Definition: Config.h:98
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
Virtual class to generate samples points.
void setInputDataSet(std::auto_ptr< te::da::DataSet > dataSet)
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Definition: DataSetItem.h:56
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
virtual std::auto_ptr< te::mem::DataSet > generateSamples(te::da::DataSetType *dsType)
#define TE_SA_SPG_ATTR_ID_NAME
Definition: Config.h:89
TEDATAACCESSEXPORT std::size_t GetFirstPropertyPos(const te::da::DataSet *dataset, int datatype)
Definition: Utils.cpp:481
void setString(std::size_t i, const std::string &value)
It sets the value of the i-th property.
#define TE_SA_SPG_ATTR_CLASS_NAME
Definition: Config.h:92
void FreeContents(boost::unordered_map< K, V * > &m)
This function can be applied to a map of pointers. It will delete each pointer in the map...
Definition: BoostUtils.h:55
const Envelope * getMBR() const
It returns the minimum bounding rectangle for the geometry in an internal representation.
Definition: Geometry.cpp:104
virtual ~SamplePointsGeneratorStratified()
Virtual destructor.
virtual bool within(const Geometry *const rhs) const
It returns true if the geometry object is spatially within rhs geometry.
Definition: Geometry.cpp:311