All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RasterToVector.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 RasterToVector.cpp
22  */
23 
24 #include "../common/progress/TaskProgress.h"
25 #include "../common/Translator.h"
26 
27 #include "../dataaccess/dataset/DataSet.h"
28 #include "../dataaccess/dataset/DataSetAdapter.h"
29 
30 #include "../dataaccess/dataset/DataSetType.h"
31 #include "../dataaccess/dataset/DataSetTypeConverter.h"
32 #include "../dataaccess/dataset/ObjectIdSet.h"
33 #include "../dataaccess/datasource/DataSource.h"
34 #include "../dataaccess/datasource/DataSourceCapabilities.h"
35 #include "../dataaccess/utils/Utils.h"
36 
37 #include "../datatype/Property.h"
38 #include "../datatype/StringProperty.h"
39 
40 #include "../geometry.h"
41 
42 #include "../memory/DataSetItem.h"
43 
44 #include "../raster/RasterProperty.h"
45 #include "../raster/Utils.h"
46 
47 #include "../rp/RasterAttributes.h"
48 #include "../rp/Texture.h"
49 
50 #include "../statistics/core/Utils.h"
51 
52 #include "Exception.h"
53 #include "RasterToVector.h"
54 
55 // Boost
56 #include <boost/lexical_cast.hpp>
57 
59 {
60 }
61 
63  std::string inRasterName,
64  std::auto_ptr<te::da::DataSetType> inRasterDsType,
65  te::da::DataSourcePtr inVectorDsrc,
66  std::string inVectorName,
67  std::auto_ptr<te::da::DataSetType> inVectorDsType)
68 {
69  m_inRasterDsrc = inRasterDsrc;
70  m_inRasterName = inRasterName;
71  m_inRasterDsType = inRasterDsType;
72  m_inVectorDsrc = inVectorDsrc;
73  m_inVectorName = inVectorName;
74  m_inVectorDsType = inVectorDsType;
75 }
76 
77 void te::attributefill::RasterToVector::setParams(std::vector<unsigned int> bands,
78  std::vector<te::stat::StatisticalSummary> statSum,
79  bool texture)
80 {
81  m_bands = bands;
82  m_statSum = statSum;
83  m_texture = texture;
84 }
85 
87 {
88  m_outDsrc = outDsrc;
89  m_outDset = dsName;
90 }
91 
93 {
94  if (!m_inVectorDsType.get())
95  return false;
96 
97  if (!m_inVectorDsType->hasGeom())
98  return false;
99 
100  if (m_outDset.empty() || !m_outDsrc.get())
101  return false;
102 
103  return true;
104 }
105 
107 {
108 // get output DataSetType.
109  std::auto_ptr<te::da::DataSetType> outDsType = getDataSetType();
110 // create the output dataset in memory
111  std::auto_ptr<te::mem::DataSet> outDataset(new te::mem::DataSet(outDsType.get()));
112 
113 // prepare raster
114  te::rst::RasterProperty* rasterProp = te::da::GetFirstRasterProperty(m_inRasterDsType.get());
115 
116  std::auto_ptr<te::da::DataSet> dsRaster = m_inRasterDsrc->getDataSet(m_inRasterName);
117  std::auto_ptr<te::rst::Raster> raster = dsRaster->getRaster(rasterProp->getName());
118 
119 // prepare vector
120  te::gm::GeometryProperty* vectorProp = te::da::GetFirstGeomProperty(m_inVectorDsType.get());
121 
122  std::auto_ptr<te::da::DataSet> dsVector = m_inVectorDsrc->getDataSet(m_inVectorName);
123 
124 // Raster Attributes
125  te::rp::RasterAttributes* rasterAtt = 0;
126 
127  te::common::TaskProgress task("Processing Operation...");
128  task.setTotalSteps(dsVector->size() * m_statSum.size() * m_bands.size());
129  task.useTimer(true);
130 
131  dsVector->moveBeforeFirst();
132  while(dsVector->moveNext())
133  {
134  te::mem::DataSetItem* outDSetItem = new te::mem::DataSetItem(outDataset.get());
135 
136  std::vector<te::dt::Property*> vecProp = m_inVectorDsType->getProperties();
137  for(std::size_t i = 0; i < vecProp.size(); ++i)
138  {
139  outDSetItem->setValue(i, dsVector->getValue(i).release());
140  }
141 
142 // Geometry
143  std::auto_ptr<te::gm::Geometry> geom = dsVector->getGeometry(vectorProp->getName());
144 
145 // Values from raster
146  std::vector<std::vector<double> > valuesFromRaster;
147  valuesFromRaster.resize(m_bands.size());
148 
149  if(geom->getGeomTypeId() == te::gm::MultiPolygonType)
150  {
151  te::gm::MultiPolygon* mPolygon = dynamic_cast< te::gm::MultiPolygon* >(geom.get());
152  std::size_t n_geom = mPolygon->getNumGeometries();
153 
154  for(std::size_t n = 0; n < n_geom; ++n)
155  {
156  te::gm::Polygon* polygon = dynamic_cast< te::gm::Polygon* >(mPolygon->getGeometryN(n));
157  std::vector<std::vector<double> > tempValues = rasterAtt->getValuesFromRaster(*raster, *polygon, m_bands);
158 
159  for(std::size_t band = 0; band < tempValues.size(); ++band)
160  {
161  std::vector<double>::iterator it;
162  it = valuesFromRaster[band].end();
163 
164  valuesFromRaster[band].insert(it,
165  tempValues[band].begin(),
166  tempValues[band].end());
167  }
168  }
169  }
170  else if(geom->getGeomTypeId() == te::gm::PolygonType)
171  {
172  te::gm::Polygon* polygon = dynamic_cast< te::gm::Polygon* >(geom.get());
173  valuesFromRaster = rasterAtt->getValuesFromRaster(*raster, *polygon, m_bands);
174  }
175  else
176  {
177  return false;
178  }
179 
180  std::size_t init_index = m_inVectorDsType->getProperties().size();
181 
182 // Statistics set value
183  for(std::size_t band = 0; band < valuesFromRaster.size(); ++band)
184  {
185  te::stat::NumericStatisticalSummary summary = rasterAtt->getStatistics(valuesFromRaster[band]);
186  int current_index = init_index + m_statSum.size();
187 
188  for(int it = 0, i = init_index; i < current_index; ++it, ++i)
189  {
190  te::stat::StatisticalSummary ss = m_statSum[it];
191 
192  switch(ss)
193  {
194  case te::stat::MIN_VALUE:
195  outDSetItem->setDouble(i, summary.m_minVal);
196  break;
197  case te::stat::MAX_VALUE:
198  outDSetItem->setDouble(i, summary.m_maxVal);
199  break;
200  case te::stat::COUNT:
201  outDSetItem->setDouble(i, summary.m_count);
202  break;
204  outDSetItem->setDouble(i, summary.m_validCount);
205  break;
206  case te::stat::MEAN:
207  outDSetItem->setDouble(i, summary.m_mean);
208  break;
209  case te::stat::SUM:
210  outDSetItem->setDouble(i, summary.m_sum);
211  break;
213  outDSetItem->setDouble(i, summary.m_stdDeviation);
214  break;
215  case te::stat::VARIANCE:
216  outDSetItem->setDouble(i, summary.m_variance);
217  break;
218  case te::stat::SKEWNESS:
219  outDSetItem->setDouble(i, summary.m_skewness);
220  break;
221  case te::stat::KURTOSIS:
222  outDSetItem->setDouble(i, summary.m_kurtosis);
223  break;
224  case te::stat::AMPLITUDE:
225  outDSetItem->setDouble(i, summary.m_amplitude);
226  break;
227  case te::stat::MEDIAN:
228  outDSetItem->setDouble(i, summary.m_median);
229  break;
230  case te::stat::VAR_COEFF:
231  outDSetItem->setDouble(i, summary.m_varCoeff);
232  break;
233  case te::stat::MODE:
234  {
235  std::string mode;
236 
237  if (!summary.m_mode.empty())
238  {
239  mode = boost::lexical_cast<std::string>(summary.m_mode[0]);
240  for(std::size_t m=1; m<summary.m_mode.size(); ++m)
241  {
242  mode += ",";
243  mode += boost::lexical_cast<std::string>(summary.m_mode[m]);
244  }
245  outDSetItem->setString(i, mode);
246  }
247  else
248  {
249  outDSetItem->setString(i, "");
250  }
251  break;
252  }
253  default:
254  continue;
255  }
256  task.pulse();
257  }
258 
259  // texture
260  std::vector<te::rp::Texture> metrics;
261  init_index = current_index;
262 
263  if(m_texture == true)
264  {
265  metrics = getTexture(raster.get(), geom.get(), m_bands.size());
266  current_index += 5;
267  for(int t = 0, i = init_index; i < current_index; ++t,++i)
268  {
269  switch (t)
270  {
271  case 0:
272  {
273  outDSetItem->setDouble(i, metrics[band].m_contrast);
274  break;
275  }
276  case 1:
277  {
278  outDSetItem->setDouble(i, metrics[band].m_dissimilarity);
279  break;
280  }
281  case 2:
282  {
283  outDSetItem->setDouble(i, metrics[band].m_energy);
284  break;
285  }
286  case 3:
287  {
288  outDSetItem->setDouble(i, metrics[band].m_entropy);
289  break;
290  }
291  case 4:
292  {
293  outDSetItem->setDouble(i, metrics[band].m_homogeneity);
294  break;
295  }
296  }
297  }
298  }
299 
300  init_index = current_index;
301  }
302 
303  outDataset->add(outDSetItem);
304 
305  if (task.isActive() == false)
306  throw te::attributefill::Exception(TE_TR("Operation canceled!"));
307  }
308 
309  return save(outDataset,outDsType);
310 }
311 
312 
313 std::auto_ptr<te::da::DataSetType> te::attributefill::RasterToVector::getDataSetType()
314 {
315  std::auto_ptr<te::da::DataSetType> outdsType(new te::da::DataSetType(*m_inVectorDsType));
316  outdsType->setCompositeName(m_outDset);
317  outdsType->setName(m_outDset);
318  outdsType->setTitle(m_outDset);
319 
320  te::da::PrimaryKey* pk = outdsType->getPrimaryKey();
321 
322  std::string name = pk->getName();
323  name += "_" + m_outDset;
324  pk->setName(name);
325 
326  for(std::size_t b = 0; b < m_bands.size(); ++b)
327  {
328  for(std::size_t i = 0; i < m_statSum.size(); ++i)
329  {
331  switch(m_statSum[i])
332  {
333  case 0:
334  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Min_Value", te::dt::DOUBLE_TYPE);
335  outdsType->add(prop);
336  break;
337  case 1:
338  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Max_Value", te::dt::DOUBLE_TYPE);
339  outdsType->add(prop);
340  break;
341  case 2:
342  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Mean", te::dt::DOUBLE_TYPE);
343  outdsType->add(prop);
344  break;
345  case 3:
346  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Sum", te::dt::DOUBLE_TYPE);
347  outdsType->add(prop);
348  break;
349  case 4:
350  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Count", te::dt::DOUBLE_TYPE);
351  outdsType->add(prop);
352  break;
353  case 5:
354  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Valid_Count", te::dt::DOUBLE_TYPE);
355  outdsType->add(prop);
356  break;
357  case 6:
358  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Standard_Deviation", te::dt::DOUBLE_TYPE);
359  outdsType->add(prop);
360  break;
361  case 7:
362  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Variance", te::dt::DOUBLE_TYPE);
363  outdsType->add(prop);
364  break;
365  case 8:
366  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Skewness", te::dt::DOUBLE_TYPE);
367  outdsType->add(prop);
368  break;
369  case 9:
370  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Kurtosis", te::dt::DOUBLE_TYPE);
371  outdsType->add(prop);
372  break;
373  case 10:
374  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Amplitude", te::dt::DOUBLE_TYPE);
375  outdsType->add(prop);
376  break;
377  case 11:
378  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Median", te::dt::DOUBLE_TYPE);
379  outdsType->add(prop);
380  break;
381  case 12:
382  prop = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Var_Coeff", te::dt::DOUBLE_TYPE);
383  outdsType->add(prop);
384  break;
385  case 13:
386  prop = new te::dt::StringProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Mode");
387  outdsType->add(prop);
388  break;
389  default:
390  continue;
391  }
392  }
393  if(m_texture == true)
394  {
395  te::dt::SimpleProperty* propContrast = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Contrast", te::dt::DOUBLE_TYPE);
396  outdsType->add(propContrast);
397 
398  te::dt::SimpleProperty* propDissimilarity = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Dissimilarity", te::dt::DOUBLE_TYPE);
399  outdsType->add(propDissimilarity);
400 
401  te::dt::SimpleProperty* propEnergy = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Energy", te::dt::DOUBLE_TYPE);
402  outdsType->add(propEnergy);
403 
404  te::dt::SimpleProperty* propEntropy = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Entropy", te::dt::DOUBLE_TYPE);
405  outdsType->add(propEntropy);
406 
407  te::dt::SimpleProperty* propHomogeneity = new te::dt::SimpleProperty("B"+ boost::lexical_cast<std::string>(m_bands[b]) +"_Homogeneity", te::dt::DOUBLE_TYPE);
408  outdsType->add(propHomogeneity);
409  }
410  }
411 
412  return outdsType;
413 }
414 
416  te::gm::Geometry* geom,
417  int bands)
418 {
419  te::rp::RasterAttributes rattributes;
420  std::vector<te::rp::Texture> textureVec;
421 
422  te::gm::Polygon* polygon;
423 
425  {
426  te::gm::MultiPolygon* mPolygon = dynamic_cast< te::gm::MultiPolygon* >(geom);
427  polygon = dynamic_cast< te::gm::Polygon* >(mPolygon->getGeometryN(0));
428  }
429  else
430  {
431  polygon = dynamic_cast< te::gm::Polygon* >(geom);
432  }
433 
434  for(int i = 0; i < bands; ++i)
435  {
436  boost::numeric::ublas::matrix<double> glcm = rattributes.getGLCM(*rst, i, 1, 1, *polygon);
437  te::rp::Texture metrics = rattributes.getGLCMMetrics(glcm);
438  textureVec.push_back(metrics);
439  }
440 
441  return textureVec;
442 }
443 
444 bool te::attributefill::RasterToVector::save(std::auto_ptr<te::mem::DataSet> result, std::auto_ptr<te::da::DataSetType> outDsType)
445 {
446  // do any adaptation necessary to persist the output dataset
447  te::da::DataSetTypeConverter* converter = new te::da::DataSetTypeConverter(outDsType.get(), m_outDsrc->getCapabilities());
448  te::da::DataSetType* dsTypeResult = converter->getResult();
449  std::auto_ptr<te::da::DataSetAdapter> dsAdapter(te::da::CreateAdapter(result.get(), converter));
450 
451  std::map<std::string, std::string> options;
452  // create the dataset
453  m_outDsrc->createDataSet(dsTypeResult, options);
454 
455  // copy from memory to output datasource
456  result->moveBeforeFirst();
457  m_outDsrc->add(dsTypeResult->getName(),result.get(), options);
458 
459  // create the primary key if it is possible
460  if (m_outDsrc->getCapabilities().getDataSetTypeCapabilities().supportsPrimaryKey())
461  {
462  std::string pk_name = dsTypeResult->getName() + "_pkey";
463  te::da::PrimaryKey* pk = new te::da::PrimaryKey(pk_name, dsTypeResult);
464  pk->add(dsTypeResult->getProperty(0));
465  m_outDsrc->addPrimaryKey(m_outDset,pk);
466  }
467 
468  return true;
469 }
virtual void setName(const std::string &name)
It sets the constraint name.
Definition: Constraint.h:126
std::size_t getNumGeometries() const
It returns the number of geometries in this GeometryCollection.
Mean.
Definition: Enums.h:43
TEDATAACCESSEXPORT te::rst::RasterProperty * GetFirstRasterProperty(const DataSetType *dt)
Definition: Utils.cpp:571
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
Geometric property.
A structure to hold the set of statistics from a set of numerical values.
void add(te::dt::Property *p)
It adds a property to the list of properties of the primary key.
Definition: PrimaryKey.h:123
void setDouble(std::size_t i, double value)
It sets the value of the i-th property.
An atomic property like an integer or double.
boost::shared_ptr< DataSource > DataSourcePtr
Definition: DataSource.h:1435
Skewness.
Definition: Enums.h:49
Total not null values.
Definition: Enums.h:46
Total number of values.
Definition: Enums.h:45
A class that models the description of a dataset.
Definition: DataSetType.h:72
void useTimer(bool flag)
Used to define if task use progress timer information.
void setOutput(te::da::DataSourcePtr outDsrc, std::string dsName)
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
void setValue(std::size_t i, te::dt::AbstractData *value)
It sets the value of the i-th property.
An exception class for the Attribute Fill module.
void setParams(std::vector< unsigned int > bands, std::vector< te::stat::StatisticalSummary > statSum, bool texture)
boost::numeric::ublas::matrix< double > getGLCM(const te::rst::Raster &rin, unsigned int band, int dx, int dy)
Computes the Gray-Level CoOccurrence Matrix (GLCM) from a raster band.
#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.
Raster property.
Extraction of attributes from Raster, Bands, and Polygons.
std::vector< te::rp::Texture > getTexture(te::rst::Raster *rst, te::gm::Geometry *geom, int bands)
void setTotalSteps(int value)
Set the task total stepes.
Minimum value.
Definition: Enums.h:41
An converter for DataSetType.
std::auto_ptr< te::da::DataSetType > getDataSetType()
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
Definition: DataSet.h:65
Median.
Definition: Enums.h:52
An abstract class for raster data strucutures.
Definition: Raster.h:71
Raster to Vector processing.
std::vector< std::vector< double > > getValuesFromRaster(const te::rst::Raster &raster, const te::gm::Polygon &polygon, std::vector< unsigned int > bands)
Returns the pixel values for all the bands in raster, inside the polygon.
Kurtosis.
Definition: Enums.h:50
te::rp::Texture getGLCMMetrics(boost::numeric::ublas::matrix< double > glcm)
Compute texture metrics from GLCM matrix.
Standard deviation.
Definition: Enums.h:47
Sum of values.
Definition: Enums.h:44
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
The type for string types: FIXED_STRING, VAR_STRING or STRING.
void setInput(te::da::DataSourcePtr inRasterDsrc, std::string inRasterName, std::auto_ptr< te::da::DataSetType > inRasterDsType, te::da::DataSourcePtr inVectorDsrc, std::string inVectorName, std::auto_ptr< te::da::DataSetType > inVectorDsType)
GeomType getGeomTypeId() const
It returns the geometry subclass type identifier.
Definition: Geometry.h:178
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
te::stat::NumericStatisticalSummary getStatistics(std::vector< double > &pixels)
Returns several statistics from a set of pixels.
Coefficient variation.
Definition: Enums.h:53
Geometry * getGeometryN(std::size_t i) const
It returns the n-th geometry in this GeometryCollection.
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Definition: DataSetItem.h:56
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
bool save(std::auto_ptr< te::mem::DataSet > result, std::auto_ptr< te::da::DataSetType > outDsType)
It describes a primary key (pk) constraint.
Definition: PrimaryKey.h:52
Mode.
Definition: Enums.h:54
A structure to hold the set of GLCM metrics.
Definition: Texture.h:44
StatisticalSummary
Define grouping functions type.
Definition: Enums.h:39
void setString(std::size_t i, const std::string &value)
It sets the value of the i-th property.
virtual const std::string & getName() const
It returns the constraint name.
Definition: Constraint.h:119
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:557
TEDATAACCESSEXPORT DataSetAdapter * CreateAdapter(DataSet *ds, DataSetTypeConverter *converter, bool isOwner=false)
Definition: Utils.cpp:644
Variance.
Definition: Enums.h:48
Maximum value.
Definition: Enums.h:42
Amplitude.
Definition: Enums.h:51
const std::string & getName() const
It returns the property name.
Definition: Property.h:127