RAGGraphBuilder.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 RAGGraphBuilder.cpp
22 
23  \brief This class defines the RAG strategy to build a graph,
24 
25  This is strategy is based on adjacency of a region.
26 
27 */
28 
29 // TerraLib
30 #include "../../common/progress/TaskProgress.h"
31 #include "../../common/StringUtils.h"
32 #include "../../common/STLUtils.h"
33 #include "../../core/translator/Translator.h"
34 #include "../../dataaccess/datasource/DataSource.h"
35 #include "../../dataaccess/datasource/DataSourceFactory.h"
36 #include "../../datatype/AbstractData.h"
37 #include "../../geometry/GeometryProperty.h"
38 #include "../../geometry/MultiPolygon.h"
39 #include "../../geometry/Point.h"
40 #include "../../geometry/Polygon.h"
41 #include "../../sam/rtree.h"
42 #include "../core/AbstractGraphFactory.h"
43 #include "../core/Edge.h"
44 #include "../core/Vertex.h"
45 #include "../core/VertexProperty.h"
46 #include "../graphs/Graph.h"
47 #include "../Config.h"
48 #include "../Exception.h"
49 #include "RAGGraphBuilder.h"
50 
51 
53 {
54  m_edgeId = 0;
55 }
56 
58 
59 bool te::graph::RAGGraphBuilder::build(const std::string& shapeFileName, const std::string& linkColumn, const int& srid,
60  const std::string& dsInfo, const std::string& graphType, const std::map<std::string, std::string>& gInfo)
61 {
62  //create output graph
63  m_graph.reset(te::graph::AbstractGraphFactory::make(graphType, dsInfo, gInfo));
64 
65  assert(m_graph);
66 
67  if(createVertexObjects(shapeFileName, linkColumn, srid) == false)
68  {
69  return false;
70  }
71 
72  if(createEdgeObjects(shapeFileName, linkColumn) == false)
73  {
74  return false;
75  }
76 
77 
78  return true;
79 }
80 
82 {
83  int id = m_edgeId;
84 
85  m_edgeId++;
86 
87  return id;
88 }
89 
90 
91 std::unique_ptr<te::da::DataSource> te::graph::RAGGraphBuilder::getDataSource(const std::string& fileName)
92 {
93  // Creates and connects data source
94  std::unique_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("OGR", ("file://" + fileName));
95  ds->open();
96 
97  return ds;
98 }
99 
101 {
102  std::vector<std::string> names = ds->getDataSetNames();
103 
104  std::string dsName = names[0];
105 
106  std::unique_ptr<te::da::DataSet> dataset = ds->getDataSet(dsName);
107 
108  return dataset;
109 }
110 
112 {
113  std::vector<std::string> names = ds->getDataSetNames();
114 
115  std::string dsName = names[0];
116 
117  return ds->getProperties(dsName);
118 }
119 
120 bool te::graph::RAGGraphBuilder::createVertexObjects(const std::string& shapeFileName, const std::string& linkColumn, const int& srid)
121 {
122  //get data source
123  std::unique_ptr<te::da::DataSource> ds = getDataSource(shapeFileName);
124 
125  if(ds.get() == nullptr)
126  {
127  return false;
128  }
129 
130  //get data set
131  std::unique_ptr<te::da::DataSet> dataSet = getDataSet(ds.get());
132 
133  if(dataSet.get() == nullptr)
134  {
135  return false;
136  }
137 
138  //create graph vertex attrs
139  te::gm::GeometryProperty* gProp = new te::gm::GeometryProperty("coords");
140  gProp->setId(0);
142  gProp->setSRID(srid);
143 
144  m_graph->addVertexProperty(gProp);
145 
146  //get geometry column
147  std::string geomColumn;
148  if(getGeometryColumn(shapeFileName, geomColumn) == false)
149  {
150  return false;
151  }
152 
153  //create vertex objects
154  while(dataSet->moveNext())
155  {
156  int id = dataSet->getInt32(linkColumn);
157 
158  Vertex* v = new Vertex(id);
159 
160  v->setAttributeVecSize(1);
161 
162  te::gm::Geometry* g = dataSet->getGeometry(geomColumn).release();
163  g->setSRID(srid);
164 
165  te::dt::AbstractData* ad = nullptr;
166 
167  if(g->getGeomTypeId() == te::gm::PointType)
168  {
169  ad = g;
170  }
171  else if(g->getGeomTypeId() == te::gm::PolygonType)
172  {
174  p->setSRID(srid);
175 
176  ad = p;
177  }
178  else if(g->getGeomTypeId() == te::gm::MultiPolygonType)
179  {
180  te::gm::Polygon* poly = (te::gm::Polygon*)((te::gm::MultiPolygon*)g)->getGeometryN(0);
181 
182  te::gm::Point* p = poly->getCentroid();
183  p->setSRID(srid);
184 
185  ad = p;
186  }
187 
188  v->addAttribute(0, ad);
189 
190  m_graph->add(v);
191  }
192 
193  return true;
194 }
195 
196 bool te::graph::RAGGraphBuilder::createEdgeObjects(const std::string& shapeFileName, const std::string& linkColumn)
197 {
198  //get data source
199  std::unique_ptr<te::da::DataSource> ds = getDataSource(shapeFileName);
200 
201  if(ds.get() == nullptr)
202  {
203  return false;
204  }
205 
206  //get data set
207  std::unique_ptr<te::da::DataSet> dataSet = getDataSet(ds.get());
208 
209  if(dataSet.get() == nullptr)
210  {
211  return false;
212  }
213 
214  //get geometry column
215  std::string geomColumn;
216  if(getGeometryColumn(shapeFileName, geomColumn) == false)
217  {
218  return false;
219  }
220 
222  std::map<int, te::gm::Geometry*> geomMap;
223  //create tree
224  while(dataSet->moveNext())
225  {
226  int id = dataSet->getInt32(linkColumn);
227  te::gm::Geometry* g = dataSet->getGeometry(geomColumn).release();
228  const te::gm::Envelope* box = g->getMBR();
229 
230  rtree.insert(*box, id);
231 
232  geomMap.insert(std::map<int, te::gm::Geometry*>::value_type(id, g));
233  }
234 
235  dataSet->moveBeforeFirst();
236 
238 
239  task.setTotalSteps((int)dataSet->size());
240  task.setMessage("RAG Builder - Extracting Edges");
241 
242  //create vertex objects
243  while(dataSet->moveNext())
244  {
245  int vFromId = dataSet->getInt32(linkColumn);
246 
247  std::unique_ptr<te::gm::Geometry> g = dataSet->getGeometry(geomColumn);
248 
249  std::vector<int> results;
250 
251  rtree.search(*g->getMBR(), results);
252 
253  for(size_t t = 0; t < results.size(); ++t)
254  {
255  std::map<int, te::gm::Geometry*>::iterator it = geomMap.find(results[t]);
256 
257  if(it != geomMap.end())
258  {
259  if(g->touches(it->second))
260  {
261  int edgeId = getEdgeId();
262 
263  int vToId = results[t];
264 
265  Edge* e = new Edge(edgeId, vFromId, vToId);
266 
267  m_graph->add(e);
268  }
269  }
270  }
271 
272  task.pulse();
273  }
274 
275  te::common::FreeContents(geomMap);
276  geomMap.clear();
277 
278  return true;
279 }
280 
281 bool te::graph::RAGGraphBuilder::getGeometryColumn(const std::string& shapeFileName, std::string& columnName)
282 {
283  //get data source
284  std::unique_ptr<te::da::DataSource> ds = getDataSource(shapeFileName);
285 
286  if(ds.get() == nullptr)
287  {
288  return false;
289  }
290 
291  //get properties
292  boost::ptr_vector<te::dt::Property> properties = getProperties(ds.get());
293 
294  if(properties.empty())
295  {
296  return false;
297  }
298 
299  boost::ptr_vector<te::dt::Property>::iterator it = properties.begin();
300  while(it != properties.end())
301  {
302  if(it->getType() == te::dt::GEOMETRY_TYPE)
303  {
304  columnName = it->getName();
305  }
306 
307  ++it;
308  }
309 
310  if(columnName.empty())
311  {
312  return false;
313  }
314 
315  return true;
316 }
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
static std::unique_ptr< DataSource > make(const std::string &driver, const te::core::URI &connInfo)
Geometric property.
void setMessage(const std::string &message)
Set the task message.
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
void setGeometryType(GeomType t)
It sets the geometry subtype.
void setSRID(int srid) _NOEXCEPT_OP(true)
It sets the Spatial Reference System ID of the Point.
virtual boost::ptr_vector< te::dt::Property > getProperties(const std::string &datasetName)
It retrieves the properties of the dataset.
GeomType getGeomTypeId() const _NOEXCEPT_OP(true)
It returns the geometry subclass type identifier.
std::unique_ptr< te::da::DataSet > getDataSet(te::da::DataSource *ds)
Function used to get the data set with the vectorial data.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
static te::dt::Date ds(2010, 01, 01)
bool getGeometryColumn(const std::string &shapeFileName, std::string &columnName)
Function used to get the geometry column name.
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
This class defines the RAG strategy to build a graph,.
int m_edgeId
Attribute used as a index counter for edge objects.
int getEdgeId()
Function used to generated the edge id.
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.
std::unique_ptr< te::da::DataSource > getDataSource(const std::string &fileName)
Function used to get the data source with the vectorial data.
void setId(unsigned int id)
It sets the property identifier.
Definition: Property.h:118
Class used to define the edge struct of a graph. Its compose with a identifier, the vertex origin and...
Definition: Edge.h:58
A point with x and y coordinate values.
Definition: Point.h:50
const Envelope * getMBR() const _NOEXCEPT_OP(true)
It returns the minimum bounding rectangle for the geometry in an internal representation.
An Envelope defines a 2D rectangular region.
boost::ptr_vector< te::dt::Property > getProperties(te::da::DataSource *ds)
Function used to get the data source properties.
bool createVertexObjects(const std::string &shapeFileName, const std::string &linkColumn, const int &srid)
Function used to create all vertex object based on vectorial data.
te::gm::Polygon * p
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
virtual std::vector< std::string > getDataSetNames()
It gets the dataset names available in the data source.
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
virtual ~RAGGraphBuilder()
Virtual destructor.
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
virtual std::unique_ptr< DataSet > getDataSet(const std::string &name, te::common::TraverseType travType=te::common::FORWARDONLY, const te::common::AccessPolicy accessPolicy=te::common::RAccess)
It gets the dataset identified by the given name. This method always returns a disconnected dataset...
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.
virtual void setSRID(int srid) _NOEXCEPT_OP(true)=0
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
Point * getCentroid() const
It returns the mathematical centroid for this surface as a point.
RAGGraphBuilder()
Default constructor.
void addAttribute(int idx, te::dt::AbstractData *ad)
Add a new attribute to this element.
Definition: Vertex.cpp:84
boost::shared_ptr< AbstractGraph > m_graph
Graph object.
static AbstractGraph * make()
It creates and returns an empty graph with default graph type.
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
bool build(const std::string &shapeFileName, const std::string &linkColumn, const int &srid, const std::string &dsInfo, const std::string &graphType, const std::map< std::string, std::string > &gInfo)
Function used to generated a graph using the RAG strategy.
bool createEdgeObjects(const std::string &shapeFileName, const std::string &linkColumn)
Function used to create all edges object based on vectorial data.