All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GPMGraphBuilder.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 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 GPMGraphBuilder.cpp
22 
23  \brief This class defines the GPM strategy to build a graph,
24 
25  This is builder uses diferent strategies to build a graph based
26  on a generalized proximity matrix.
27 
28 */
29 
30 // TerraLib
31 #include "../../common/progress/TaskProgress.h"
32 #include "../../common/StringUtils.h"
33 #include "../../common/STLUtils.h"
34 #include "../../common/Translator.h"
35 #include "../../dataaccess/datasource/DataSource.h"
36 #include "../../dataaccess/utils/Utils.h"
37 #include "../../datatype/AbstractData.h"
38 #include "../../datatype/SimpleData.h"
39 #include "../../datatype/SimpleProperty.h"
40 #include "../../geometry/GeometryProperty.h"
41 #include "../../geometry/MultiPolygon.h"
42 #include "../../geometry/Point.h"
43 #include "../../geometry/Polygon.h"
44 #include "../../sam/rtree.h"
45 #include "../core/AbstractGraphFactory.h"
46 #include "../core/Edge.h"
47 #include "../core/Vertex.h"
48 #include "../core/VertexProperty.h"
49 #include "../graphs/Graph.h"
50 #include "../Config.h"
51 #include "../Exception.h"
52 #include "GPMGraphBuilder.h"
53 
54 
56 {
57  m_edgeId = 0;
58 }
59 
61 {
62 }
63 
64 bool te::graph::GPMGraphBuilder::setGraphInfo(const std::map<std::string, std::string>& dsInfo, const std::string& graphType, const std::map<std::string, std::string>& gInfo)
65 {
66  //create output graph
67  m_graph.reset(te::graph::AbstractGraphFactory::make(graphType, dsInfo, gInfo));
68 
69  assert(m_graph);
70 
71  return true;
72 }
73 
74 bool te::graph::GPMGraphBuilder::buildAdjacency(std::auto_ptr<te::da::DataSource> ds, std::string dataSetName, std::string columnId, bool calcDist)
75 {
76  std::auto_ptr<te::da::DataSet> dataSet = ds->getDataSet(dataSetName);
77 
78  std::auto_ptr<te::da::DataSetType> dataSetType = ds->getDataSetType(dataSetName);
79 
81 
82  createVertexObjects(dataSet.get(), columnId, gp->getSRID());
83 
84  createAdjacencyEdges(dataSet.get(), columnId, calcDist);
85 
86  return true;
87 }
88 
89 bool te::graph::GPMGraphBuilder::buildDistance(std::auto_ptr<te::da::DataSource> ds, std::string dataSetName, std::string columnId, double dist)
90 {
91  std::auto_ptr<te::da::DataSet> dataSet = ds->getDataSet(dataSetName);
92 
93  std::auto_ptr<te::da::DataSetType> dataSetType = ds->getDataSetType(dataSetName);
94 
96 
97  createVertexObjects(dataSet.get(), columnId, gp->getSRID());
98 
99  createDistanceEdges(dataSet.get(), columnId, dist);
100 
101  return true;
102 }
103 
104 void te::graph::GPMGraphBuilder::createVertexObjects(te::da::DataSet* dataSet, std::string columnId, int srid)
105 {
106  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(dataSet);
107 
108  //create graph vertex attrs
109  te::gm::GeometryProperty* gProp = new te::gm::GeometryProperty("coords");
110  gProp->setId(0);
112  gProp->setSRID(srid);
113 
114  m_graph->addVertexProperty(gProp);
115 
116  //create graph vertex
117  dataSet->moveBeforeFirst();
118 
119  while(dataSet->moveNext())
120  {
121  int id = dataSet->getInt32(columnId);
122 
123  Vertex* v = new Vertex(id);
124 
125  v->setAttributeVecSize(1);
126 
127  std::auto_ptr<te::gm::Geometry> g = dataSet->getGeometry(geomPos);
128 
129  te::dt::AbstractData* ad = 0;
130 
131  if(g->getGeomTypeId() == te::gm::PointType)
132  {
133  g->setSRID(srid);
134 
135  ad = g->clone();
136  }
137  else if(g->getGeomTypeId() == te::gm::PolygonType)
138  {
139  te::gm::Point* p = ((te::gm::Polygon*)g.get())->getCentroid();
140  p->setSRID(srid);
141 
142  ad = p;
143  }
144  else if(g->getGeomTypeId() == te::gm::MultiPolygonType)
145  {
146  te::gm::Polygon* poly = (te::gm::Polygon*)((te::gm::MultiPolygon*)g.get())->getGeometryN(0);
147 
148  te::gm::Point* p = poly->getCentroid();
149  p->setSRID(srid);
150 
151  ad = p;
152  }
153 
154  v->addAttribute(0, ad);
155 
156  m_graph->add(v);
157  }
158 }
159 
160 void te::graph::GPMGraphBuilder::createAdjacencyEdges(te::da::DataSet* dataSet, std::string columnId, bool calcDist)
161 {
162  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(dataSet);
163 
164  //create distance attribute
165  if(calcDist)
166  {
168  p->setParent(0);
169  p->setId(0);
170 
171  m_graph->addEdgeProperty(p);
172  }
173 
174  //create tree
176  std::map<int, te::gm::Geometry*> geomMap;
177 
178  dataSet->moveBeforeFirst();
179 
180  while(dataSet->moveNext())
181  {
182  int id = dataSet->getInt32(columnId);
183  te::gm::Geometry* g = dataSet->getGeometry(geomPos).release();
184  const te::gm::Envelope* box = g->getMBR();
185 
186  rtree.insert(*box, id);
187 
188  geomMap.insert(std::map<int, te::gm::Geometry*>::value_type(id, g));
189  }
190 
192 
193  task.setTotalSteps(dataSet->size());
194  task.setMessage("GPM Builder - Extracting Edges");
195 
196  //create vertex objects
197  dataSet->moveBeforeFirst();
198 
199  while(dataSet->moveNext())
200  {
201  int vFromId = dataSet->getInt32(columnId);
202 
203  std::auto_ptr<te::gm::Geometry> g = dataSet->getGeometry(geomPos);
204 
205  std::vector<int> results;
206 
207  rtree.search(*g->getMBR(), results);
208 
209  for(size_t t = 0; t < results.size(); ++t)
210  {
211  std::map<int, te::gm::Geometry*>::iterator it = geomMap.find(results[t]);
212 
213  if(it != geomMap.end())
214  {
215  if(g->touches(it->second))
216  {
217  int edgeId = getEdgeId();
218 
219  int vToId = results[t];
220 
221  Edge* e = new Edge(edgeId, vFromId, vToId);
222 
223  if(calcDist)
224  {
225  Vertex* vFrom = m_graph->getVertex(vFromId);
226  te::gm::Point* pFrom = dynamic_cast<te::gm::Point*>(vFrom->getAttributes()[0]);
227 
228  Vertex* vTo = m_graph->getVertex(vToId);
229  te::gm::Point* pTo = dynamic_cast<te::gm::Point*>(vTo->getAttributes()[0]);
230 
231  double dist = pFrom->distance(pTo);
232 
234 
235  e->setAttributeVecSize(1);
236  e->addAttribute(0, sd);
237  }
238 
239  m_graph->add(e);
240  }
241  }
242  }
243 
244  task.pulse();
245  }
246 
247  te::common::FreeContents(geomMap);
248  geomMap.clear();
249 }
250 
251 void te::graph::GPMGraphBuilder::createDistanceEdges(te::da::DataSet* dataSet, std::string columnId, double distance)
252 {
253  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(dataSet);
254 
255  //create distance attribute
257  p->setParent(0);
258  p->setId(0);
259 
260  m_graph->addEdgeProperty(p);
261 
262  //create tree
264  std::map<int, te::gm::Geometry*> geomMap;
265 
266  dataSet->moveBeforeFirst();
267 
268  while(dataSet->moveNext())
269  {
270  int id = dataSet->getInt32(columnId);
271  te::gm::Geometry* g = dataSet->getGeometry(geomPos).release();
272  const te::gm::Envelope* box = g->getMBR();
273 
274  rtree.insert(*box, id);
275 
276  geomMap.insert(std::map<int, te::gm::Geometry*>::value_type(id, g));
277  }
278 
280 
281  task.setTotalSteps(dataSet->size());
282  task.setMessage("GPM Builder - Extracting Edges");
283 
284  //create vertex objects
285  dataSet->moveBeforeFirst();
286 
287  while(dataSet->moveNext())
288  {
289  int vFromId = dataSet->getInt32(columnId);
290 
291  std::auto_ptr<te::gm::Geometry> g = dataSet->getGeometry(geomPos);
292 
293  std::vector<int> results;
294 
295  te::gm::Envelope ext(*g->getMBR());
296 
297  ext.m_llx -= distance;
298  ext.m_lly -= distance;
299  ext.m_urx += distance;
300  ext.m_ury += distance;
301 
302  rtree.search(ext, results);
303 
304  for(size_t t = 0; t < results.size(); ++t)
305  {
306  std::map<int, te::gm::Geometry*>::iterator it = geomMap.find(results[t]);
307 
308  if(it != geomMap.end())
309  {
310  int vToId = results[t];
311 
312  Vertex* vFrom = m_graph->getVertex(vFromId);
313  te::gm::Point* pFrom = dynamic_cast<te::gm::Point*>(vFrom->getAttributes()[0]);
314 
315  Vertex* vTo = m_graph->getVertex(vToId);
316  te::gm::Point* pTo = dynamic_cast<te::gm::Point*>(vTo->getAttributes()[0]);
317 
318  double dist = pFrom->distance(pTo);
319 
320  if(dist <= distance)
321  {
322  int edgeId = getEdgeId();
323 
324  Edge* e = new Edge(edgeId, vFromId, vToId);
325 
327 
328  e->setAttributeVecSize(1);
329  e->addAttribute(0, sd);
330 
331  m_graph->add(e);
332  }
333  }
334  }
335 
336  task.pulse();
337  }
338 
339  te::common::FreeContents(geomMap);
340  geomMap.clear();
341 }
342 
344 {
345  int id = m_edgeId;
346 
347  m_edgeId++;
348 
349  return id;
350 }
bool buildDistance(std::auto_ptr< te::da::DataSource > ds, std::string dataSetName, std::string columnId, double dist)
Function used to generated a graph using the GPM Distance Strategy.
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
void setAttributeVecSize(int size)
This function is used to set the number of attributes associated with the vertex elements.
Definition: Vertex.cpp:79
bool setGraphInfo(const std::map< std::string, std::string > &dsInfo, const std::string &graphType, const std::map< std::string, std::string > &gInfo)
Function used to create a empty graph.
Geometric property.
void setMessage(const std::string &message)
Set the task message.
void setAttributeVecSize(int size)
This function is used to set the number of attributes associated with the edge elements.
Definition: Edge.cpp:86
void createVertexObjects(te::da::DataSet *dataSet, std::string columnId, int srid)
Function used to create all vertex object based on data set.
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
void setGeometryType(GeomType t)
It sets the geometry subtype.
virtual boost::int32_t getInt32(std::size_t i) const =0
Method for retrieving a 32-bit integer attribute value (4 bytes long).
An atomic property like an integer or double.
This class defines the GPM strategy to build a graph,.
A class that represents an R-tree.
Definition: Index.h:56
virtual ~GPMGraphBuilder()
Virtual destructor.
GPMGraphBuilder()
Default constructor.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
std::vector< te::dt::AbstractData * > & getAttributes()
It returns the vector of attributes associated with this element.
Definition: Vertex.cpp:74
From the point of view of graph theory, vertices are treated as featureless and indivisible objects...
Definition: Vertex.h:68
void setTotalSteps(int value)
Set the task total stepes.
void setId(unsigned int id)
It sets the property identifier.
Definition: Property.h:117
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.
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
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:413
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.
Definition: Envelope.h:51
void createDistanceEdges(te::da::DataSet *dataSet, std::string columnId, double distance)
Function used to create all edges object based on data set, using the distance strategy.
void setSRID(int srid)
It sets the Spatial Reference System ID of the Point.
virtual std::size_t size() const =0
It returns the collection size, if it is known.
void pulse()
Calls setCurrentStep() function using getCurrentStep() + 1.
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
Definition: Index.h:326
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
virtual std::auto_ptr< te::gm::Geometry > getGeometry(std::size_t i) const =0
Method for retrieving a geometric attribute value.
A dataset is the unit of information manipulated by the data access module of TerraLib.
Definition: DataSet.h:112
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
Definition: Index.h:313
virtual bool moveBeforeFirst()=0
It moves the internal pointer to a position before the first item in the collection.
Point * getCentroid() const
It returns the mathematical centroid for this surface as a point.
int getEdgeId()
Function used to generated the edge id.
void addAttribute(int idx, te::dt::AbstractData *ad)
Add a new attribute to this element.
Definition: Vertex.cpp:84
A template for atomic data types (integers, floats, strings and others).
Definition: SimpleData.h:59
TEDATAACCESSEXPORT te::gm::GeometryProperty * GetFirstGeomProperty(const DataSetType *dt)
Definition: Utils.cpp:508
static AbstractGraph * make()
It creates and returns an empty graph with default graph type.
virtual AbstractData * clone() const =0
It returns a clone of this object.
void addAttribute(int idx, te::dt::AbstractData *ad)
Add a new attribute to this element.
Definition: Edge.cpp:91
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:103
void createAdjacencyEdges(te::da::DataSet *dataSet, std::string columnId, bool calcDist)
Function used to create all edges object based on data set, using the adjacency strategy.
bool buildAdjacency(std::auto_ptr< te::da::DataSource > ds, std::string dataSetName, std::string columnId, bool calcDist)
Function used to generated a graph using the GPM Adjacency Strategy.
virtual double distance(const Geometry *const rhs) const
It returns the shortest distance between any two points in the two geometry objects.
Definition: Geometry.cpp:392
This abstract class provides the common functions for graph builder classes. Each builder strategy ha...
int m_edgeId
Attribute used as a index counter for edge objects.
void setParent(Property *p)
It associate this property to the informed parent.
Definition: Property.h:159