All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SkaterOperation.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/SkaterOperation.cpp
22 
23  \brief This file contains a class that represents the skater operation.
24 
25  \reference Adapted from TerraLib4.
26 */
27 
28 //TerraLib
29 #include "../../dataaccess/datasource/DataSource.h"
30 #include "../../dataaccess/datasource/DataSourceManager.h"
31 #include "../../dataaccess/utils/Utils.h"
32 #include "../../datatype/SimpleProperty.h"
33 #include "../../datatype/SimpleData.h"
34 #include "../../graph/core/AbstractGraph.h"
35 #include "../../graph/core/AbstractGraphFactory.h"
36 #include "../../graph/core/Edge.h"
37 #include "../../graph/core/GraphMetadata.h"
38 #include "../../graph/core/Vertex.h"
39 #include "../../graph/iterator/MemoryIterator.h"
40 #include "../../graph/Globals.h"
41 #include "../../memory/DataSet.h"
42 #include "../../memory/DataSetItem.h"
44 #include "MinimumSpanningTree.h"
45 #include "SkaterOperation.h"
46 #include "SkaterPartition.h"
47 #include "Utils.h"
48 
49 //STL
50 #include <cassert>
51 #include <list>
52 #include <queue>
53 
55 {
56 }
57 
59 {
60 }
61 
63 {
64  assert(m_inputParams->m_ds.get());
65  assert(m_inputParams->m_dsType.get());
66 
67  //associate gpm vertex attributes
68  std::vector<int> attrsIdx;
69 
70  for(std::size_t t = 0; t < m_inputParams->m_attrs.size(); ++t)
71  {
72  std::string attrName = m_inputParams->m_attrs[t];
73 
74  std::size_t idx = m_inputParams->m_dsType->getPropertyPosition(attrName);
75  int type = m_inputParams->m_ds->getPropertyDataType(idx);
76  int gpmIdx = te::sa::AssociateGPMVertexAttribute(m_inputParams->m_gpm.get(), m_inputParams->m_ds.get(), m_inputParams->m_gpmAttrLink, attrName, type);
77 
78  attrsIdx.push_back(gpmIdx);
79  }
80 
81  //check if use population information
82  if(m_inputParams->m_attrPop != "")
83  {
84  std::size_t idx = m_inputParams->m_dsType->getPropertyPosition(m_inputParams->m_attrPop);
85 
86  int type = m_inputParams->m_ds->getPropertyDataType(idx);
87 
88  te::sa::AssociateGPMVertexAttribute(m_inputParams->m_gpm.get(), m_inputParams->m_ds.get(), m_inputParams->m_gpmAttrLink, m_inputParams->m_attrPop, type);
89  }
90 
91  //calculate gpm edge attribute
92  int edgeWeightIdx = te::sa::AddGraphEdgeAttribute(m_inputParams->m_gpm->getGraph(), TE_SA_SKATER_ATTR_WEIGHT_NAME, te::dt::DOUBLE_TYPE);
93 
94  createWeightAttribute(edgeWeightIdx, attrsIdx);
95 
96  //calculate the mst
97  te::sa::MinimumSpanningTree mst(m_inputParams->m_gpm->getGraph());
98 
99  te::graph::AbstractGraph* graph = mst.kruskal(edgeWeightIdx);
100 
101  //partition the graph
102  te::sa::SkaterPartition sp(graph, m_inputParams->m_attrs);
103 
104  std::vector<std::size_t> roots;
105 
106  if(m_inputParams->m_aggregType == te::sa::Both || m_inputParams->m_aggregType == te::sa::Clusters)
107  roots = sp.execute(m_inputParams->m_nClusters, m_inputParams->m_attrPop, m_inputParams->m_minPop);
108  else if(m_inputParams->m_aggregType == te::sa::Population)
109  roots = sp.execute(m_inputParams->m_attrPop, m_inputParams->m_minPop);
110 
111  m_nClassGroups = (int)roots.size();
112 
113  std::map<int, int> skaterMap = createSkaterMap(graph, roots);
114 
115  //create output information information
116  std::auto_ptr<te::da::DataSetType> outDsType = createDataSetType(m_inputParams->m_dsType.get());
117 
118  std::string gpmLink = m_inputParams->m_gpm->getAttributeName();
119 
120  std::auto_ptr<te::mem::DataSet> outDs = createDataSet(m_inputParams->m_ds.get(), outDsType.get(), skaterMap, gpmLink);
121 
122  //save data
123  saveDataSet(outDs.get(), outDsType.get());
124 
125  roots.clear();
126  skaterMap.clear();
127 
128  delete graph;
129 }
130 
132 {
133  m_inputParams.reset(inParams);
134  m_outputParams.reset(outParams);
135 }
136 
138 {
139  return m_nClassGroups;
140 }
141 
142 std::auto_ptr<te::da::DataSetType> te::sa::SkaterOperation::createDataSetType(te::da::DataSetType* dsType)
143 {
144  std::auto_ptr<te::da::DataSetType> dataSetType(new te::da::DataSetType(m_outputParams->m_outputDataSetName));
145 
146  //create all input dataset properties
147  std::vector<te::dt::Property*> propertyVec = dsType->getProperties();
148 
149  for(std::size_t t = 0; t < propertyVec.size(); ++t)
150  {
151  te::dt::Property* prop = propertyVec[t];
152 
153  te::dt::Property* newProp = prop->clone();
154  newProp->setId(0);
155  newProp->setParent(0);
156 
157  dataSetType->add(newProp);
158  }
159 
160  //create skater class event property
162  dataSetType->add(skaterClass);
163 
164  return dataSetType;
165 }
166 
167 std::auto_ptr<te::mem::DataSet> te::sa::SkaterOperation::createDataSet(te::da::DataSet* inputDataSet, te::da::DataSetType* dsType, std::map<int, int>& skaterMap, std::string linkName)
168 {
169  std::auto_ptr<te::mem::DataSet> outDataset(new te::mem::DataSet(dsType));
170 
171  std::size_t nProp = inputDataSet->getNumProperties();
172 
173  inputDataSet->moveBeforeFirst();
174 
175  while(inputDataSet->moveNext())
176  {
177  //create dataset item
178  te::mem::DataSetItem* outDSetItem = new te::mem::DataSetItem(outDataset.get());
179 
180  std::string idStrValue = inputDataSet->getAsString(linkName);
181 
182  for(std::size_t t = 0; t < nProp; ++t)
183  {
184  te::dt::AbstractData* ad = inputDataSet->getValue(t).release();
185 
186  outDSetItem->setValue(t, ad);
187  }
188 
189  //set kernel default value
190  outDSetItem->setInt32(TE_SA_SKATER_ATTR_CLASS_NAME, skaterMap[atoi(idStrValue.c_str())]);
191 
192  //add item into dataset
193  outDataset->add(outDSetItem);
194  }
195 
196  return outDataset;
197 }
198 
200 {
201  //save dataset
202  dataSet->moveBeforeFirst();
203 
204  std::map<std::string, std::string> options;
205 
206  m_outputParams->m_dataSource->createDataSet(dsType, options);
207 
208  m_outputParams->m_dataSource->add(m_outputParams->m_outputDataSetName, dataSet, options);
209 }
210 
211 void te::sa::SkaterOperation::createWeightAttribute(int weightAttrIdx, std::vector<int> attrsIdx)
212 {
213  te::graph::AbstractGraph* graph = m_inputParams->m_gpm->getGraph();
214 
215  int size = graph->getMetadata()->getEdgePropertySize();
216 
218 
219  te::graph::Edge* edge = iterator->getFirstEdge();
220 
221  while(edge)
222  {
223  te::graph::Vertex* vFrom = graph->getVertex(edge->getIdFrom());
224  te::graph::Vertex* vTo = graph->getVertex(edge->getIdTo());
225 
226  if(vFrom && vTo)
227  {
228  double weight = calculateWeight(attrsIdx, vFrom, vTo);
229 
230  edge->setAttributeVecSize(size);
231  edge->addAttribute(weightAttrIdx, new te::dt::SimpleData<double, te::dt::DOUBLE_TYPE>(weight));
232  }
233 
234  edge = iterator->getNextEdge();
235  }
236 }
237 
238 double te::sa::SkaterOperation::calculateWeight(std::vector<int> attrsIdx, te::graph::Vertex* vFrom, te::graph::Vertex* vTo)
239 {
240  double weight = 0.;
241 
242  for(std::size_t t = 0; t < attrsIdx.size(); ++t)
243  {
244  double valueFrom = te::sa::GetDataValue(vFrom->getAttributes()[attrsIdx[t]]);
245  double valueTo = te::sa::GetDataValue(vTo->getAttributes()[attrsIdx[t]]);
246 
247  weight += (valueTo - valueFrom) * (valueTo - valueFrom);
248  }
249 
250  return sqrt(weight);
251 }
252 
253 std::map<int, int> te::sa::SkaterOperation::createSkaterMap(te::graph::AbstractGraph* graph, std::vector<std::size_t>& roots)
254 {
255  std::map<int, int> skaterMap;
256 
257  for(std::size_t t = 0; t < roots.size(); ++t)
258  {
259  std::size_t rootId = roots[t];
260 
261  //create list
262  std::queue<int> queue;
263  std::set<int> visited;
264 
265  queue.push(rootId);
266  visited.insert(rootId);
267 
268  //bfs over the graph
269  while(!queue.empty())
270  {
271  int currentId = queue.front();
272  queue.pop();
273 
274  //get vertex from graph
275  te::graph::Vertex* vertex = graph->getVertex(currentId);
276 
277  if(vertex)
278  {
279  //add to map
280  skaterMap.insert(std::map<int, int>::value_type(currentId, (int)t));
281 
282  //get neighbours
283  std::set<int> neighbours = vertex->getNeighborhood();
284  std::set<int>::iterator itNeighbours = neighbours.begin();
285 
286  while(itNeighbours != neighbours.end())
287  {
288  te::graph::Edge* e = graph->getEdge(*itNeighbours);
289  te::graph::Vertex* vTo = 0;
290 
291  if(e)
292  {
293  if(e->getIdFrom() == currentId)
294  vTo = graph->getVertex(e->getIdTo());
295  else
296  vTo = graph->getVertex(e->getIdFrom());
297  }
298 
299  if(vTo)
300  {
301  //check if already visted
302  if(visited.find(vTo->getId()) == visited.end())
303  {
304  //add in queue
305  queue.push(vTo->getId());
306  visited.insert(vTo->getId());
307  }
308  }
309 
310  ++itNeighbours;
311  }
312  }
313  }
314  }
315 
316  return skaterMap;
317 }
Class that represents the skater partition operation.
void execute()
Function to execute the skater operation.
virtual te::graph::Edge * getNextEdge()
It returns a pointer to the next edge element of a graph.
void setAttributeVecSize(int size)
This function is used to set the number of attributes associated with the edge elements.
Definition: Edge.cpp:86
Utility functions for the data access module.
An atomic property like an integer or double.
This file contains a class that represents the skater operation.
A class that models the description of a dataset.
Definition: DataSetType.h:72
void saveDataSet(te::da::DataSet *dataSet, te::da::DataSetType *dsType)
virtual te::graph::Edge * getEdge(int id)=0
It returns the edge element if it's exist.
std::auto_ptr< te::mem::DataSet > createDataSet(te::da::DataSet *inputDataSet, te::da::DataSetType *dsType, std::map< int, int > &skaterMap, std::string linkName)
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.
double calculateWeight(std::vector< int > attrsIdx, te::graph::Vertex *vFrom, te::graph::Vertex *vTo)
Function to calculate the weight attribute using the euclidean distance.
Class that represents the skater input parameters.
Definition: SkaterParams.h:56
~SkaterOperation()
Virtual destructor.
std::vector< te::dt::AbstractData * > & getAttributes()
It returns the vector of attributes associated with this element.
Definition: Vertex.cpp:74
It models a property definition.
Definition: Property.h:59
Class that represents the skater output parameters.
Definition: SkaterParams.h:98
This file contains a class that represents the Minimum Spanning Tree operation.
From the point of view of graph theory, vertices are treated as featureless and indivisible objects...
Definition: Vertex.h:68
void setId(unsigned int id)
It sets the property identifier.
Definition: Property.h:118
virtual te::graph::GraphMetadata * getMetadata()=0
Function used to access the graph metadata.
void setInt32(std::size_t i, boost::int32_t value)
It sets the value of the i-th property.
Class used to define the edge struct of a graph. Its compose with a identifier, the vertex origin and...
Definition: Edge.h:58
virtual bool moveNext()=0
It moves the internal pointer to the next item of the collection.
Implementation of a random-access dataset class for the TerraLib In-Memory Data Access driver...
Definition: DataSet.h:65
This file contains a class that represents the skater partition operation.
const std::vector< Property * > & getProperties() const
It returns the list of properties describing the CompositeProperty.
std::vector< std::size_t > execute(std::size_t nGroups, std::string popAttr="", std::size_t minPop=0)
Function to execute the skater partition.
void createWeightAttribute(int weightAttrIdx, std::vector< int > attrsIdx)
Function to create the weight attribute.
Abstract class used to define the main functions of graph struct. All graph implementations must used...
Definition: AbstractGraph.h:55
std::auto_ptr< te::da::DataSetType > createDataSetType(te::da::DataSetType *dsType)
void setParameters(te::sa::SkaterInputParams *inParams, te::sa::SkaterOutputParams *outParams)
virtual std::string getAsString(std::size_t i, int precision=0) const
Method for retrieving a data value as a string plain representation.
Definition: DataSet.cpp:218
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
std::map< int, int > createSkaterMap(te::graph::AbstractGraph *graph, std::vector< std::size_t > &roots)
int getIdFrom()
It returns the vertex origin identification.
Definition: Edge.cpp:71
std::set< int > & getNeighborhood()
Returns the Neighborhood vector.
Definition: Vertex.cpp:111
virtual std::size_t getNumProperties() const =0
It returns the number of properties that composes an item of the dataset.
virtual te::graph::Edge * getFirstEdge()
It returns a pointer to the first edge element of a graph.
An implementation of the DatasetItem class for the TerraLib In-Memory Data Access driver...
Definition: DataSetItem.h:56
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:112
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
#define TE_SA_SKATER_ATTR_WEIGHT_NAME
Definition: Config.h:101
virtual int getEdgePropertySize()
Used to verify the number of properties associated to edge elements.
#define TE_SA_SKATER_ATTR_CLASS_NAME
Definition: Config.h:104
int getId()
It returns the vertex id.
Definition: Vertex.cpp:69
A template for atomic data types (integers, floats, strings and others).
Definition: SimpleData.h:59
TESAEXPORT int AddGraphEdgeAttribute(te::graph::AbstractGraph *graph, std::string attrName, int dataType)
Function used to create the edge attribute metadata in the graph of the gpm.
Definition: Utils.cpp:142
TESAEXPORT double GetDataValue(te::dt::AbstractData *ad)
Function used to get the numeric value from a gpm property.
Definition: Utils.cpp:200
TESAEXPORT int AssociateGPMVertexAttribute(te::sa::GeneralizedProximityMatrix *gpm, te::da::DataSource *ds, std::string dataSetName, std::string attrLink, std::string attr, int dataType, int srid=TE_UNKNOWN_SRS, int subType=te::gm::UnknownGeometryType)
Function used to set a an attribute valeu from a dataset to the vertex objects from a gpm...
Definition: Utils.cpp:58
virtual te::graph::Vertex * getVertex(int id)=0
It returns the vertex element if it's exist.
void addAttribute(int idx, te::dt::AbstractData *ad)
Add a new attribute to this element.
Definition: Edge.cpp:91
SkaterOperation()
Default constructor.
virtual std::auto_ptr< te::dt::AbstractData > getValue(std::size_t i) const
Method for retrieving any other type of data value stored in the data source.
Definition: DataSet.cpp:151
int getIdTo()
It returns the vertex destiny identification.
Definition: Edge.cpp:76
This class defines the GPM class.
void setParent(Property *p)
It associate this property to the informed parent.
Definition: Property.h:177