All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
FlowGraphBuilder.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/graph/FlowGraphBuilder.cpp
22 
23  \brief This class defines the Flow strategy to build a graph.
24 
25  This function needs a vectorial data and table with flow information,
26  this table must have the origin and destination info about each flow.
27 
28 */
29 
30 // TerraLib Includes
31 #include "../../common/StringUtils.h"
32 #include "../../common/Translator.h"
33 #include "../../dataaccess/datasource/DataSource.h"
34 #include "../../dataaccess/datasource/DataSourceFactory.h"
35 #include "../../dataaccess/dataset/DataSet.h"
36 #include "../../datatype/AbstractData.h"
37 #include "../../datatype/SimpleData.h"
38 #include "../../datatype/SimpleProperty.h"
39 #include "../../geometry/GeometryProperty.h"
40 #include "../../geometry/MultiPolygon.h"
41 #include "../../geometry/Point.h"
42 #include "../../geometry/Polygon.h"
43 #include "../core/AbstractGraphFactory.h"
44 #include "../core/Edge.h"
45 #include "../core/Vertex.h"
46 #include "../core/VertexProperty.h"
47 #include "../graphs/Graph.h"
48 #include "../Config.h"
49 #include "../Exception.h"
50 #include "FlowGraphBuilder.h"
51 
52 // STL Includes
53 #include <fstream>
54 #include <iosfwd>
55 
56 // BOOST Includes
57 #include<boost/tokenizer.hpp>
58 
59 
61 {
62  m_edgeId = 0;
63 }
64 
66 {
67 }
68 
69 bool te::graph::FlowGraphBuilder::build(const std::string& shapeFileName, const std::string& linkColumn, const int& srid, const std::string& csvFileName, const int& fromIdx, const int& toIdx, const int& weightIdx,
70  const std::map<std::string, std::string>& dsInfo, const std::string& graphType, const std::map<std::string, std::string>& gInfo)
71 {
72  //create output graph
73  m_graph.reset(te::graph::AbstractGraphFactory::make(graphType, dsInfo, gInfo));
74 
75  assert(m_graph);
76 
77  if(createVertexObjects(shapeFileName, linkColumn, srid) == false)
78  {
79  return false;
80  }
81 
82  if(createEdgeObjects(csvFileName, fromIdx, toIdx, weightIdx) == false)
83  {
84  return false;
85  }
86 
87  return true;
88 }
89 
91 {
92  int id = m_edgeId;
93 
94  m_edgeId++;
95 
96  return id;
97 }
98 
99 std::auto_ptr<te::da::DataSource> te::graph::FlowGraphBuilder::getDataSource(const std::string fileName)
100 {
101  // Creates and connects data source
102  std::map<std::string, std::string> connInfo;
103  connInfo["path"] = fileName;
104  std::auto_ptr<te::da::DataSource> ds = te::da::DataSourceFactory::make("OGR");
105  ds->setConnectionInfo(connInfo);
106  ds->open();
107 
108  return ds;
109 }
110 
112 {
113  std::vector<std::string> names = ds->getDataSetNames();
114 
115  std::string dsName = names[0];
116 
117  std::auto_ptr<te::da::DataSet> dataset = ds->getDataSet(dsName);
118 
119  return dataset;
120 }
121 
122 boost::ptr_vector<te::dt::Property> te::graph::FlowGraphBuilder::getProperties(te::da::DataSource* ds)
123 {
124  std::vector<std::string> names = ds->getDataSetNames();
125 
126  std::string dsName = names[0];
127 
128  return ds->getProperties(dsName);
129 }
130 
131 bool te::graph::FlowGraphBuilder::createVertexObjects(const std::string& shapeFileName, const std::string& linkColumn, const int& srid)
132 {
133  //get data source
134  std::auto_ptr<te::da::DataSource> ds = getDataSource(shapeFileName);
135 
136  if(ds.get() == 0)
137  {
138  return false;
139  }
140 
141  //get data set
142  std::auto_ptr<te::da::DataSet> dataSet = getDataSet(ds.get());
143 
144  if(dataSet.get() == 0)
145  {
146  return false;
147  }
148 
149  //get properties
150  boost::ptr_vector<te::dt::Property> properties = getProperties(ds.get());
151 
152  if(properties.empty())
153  {
154  return false;
155  }
156 
157 //create graph vertex attrs
158  boost::ptr_vector<te::dt::Property>::iterator it = properties.begin();
159 
160  int count = 0;
161 
162  while(it != properties.end())
163  {
164  if(te::common::Convert2UCase(it->getName()) == te::common::Convert2UCase(linkColumn))
165  {
166  continue;
167  }
168 
169  te::dt::Property* p;
170 
171  if(it->getType() == te::dt::GEOMETRY_TYPE)
172  {
173  //create graph attrs
174  te::gm::GeometryProperty* gProp = new te::gm::GeometryProperty("coords");
175  gProp->setId(0);
177  gProp->setSRID(srid);
178 
179  p = gProp;
180  }
181  else
182  {
183  p = it->clone();
184  p->setParent(0);
185  p->setId(count);
186  }
187 
188  m_graph->addVertexProperty(p);
189 
190  ++count;
191 
192  ++it;
193  }
194 
195  //create vertex objects
196  while(dataSet->moveNext())
197  {
198  int id = dataSet->getInt32(linkColumn);
199 
200  Vertex* v = new Vertex(id);
201 
202  v->setAttributeVecSize(properties.size() - 1);
203 
204  int shift = 0;
205 
206  it = properties.begin();
207 
208  count = 0;
209 
210  while(it != properties.end())
211  {
212  if(te::common::Convert2UCase(it->getName()) == te::common::Convert2UCase(linkColumn))
213  {
214  shift = 1;
215  continue;
216  }
217 
218  te::dt::AbstractData* ad = 0;
219 
220  if(it->getType() == te::dt::GEOMETRY_TYPE)
221  {
222  te::gm::Geometry* g = dataSet->getGeometry(it->getName()).release();
223  g->setSRID(srid);
224 
225  if(g->getGeomTypeId() == te::gm::PointType)
226  {
227  ad = g;
228  }
229  else if(g->getGeomTypeId() == te::gm::PolygonType)
230  {
231  te::gm::Point* p = ((te::gm::Polygon*)g)->getCentroid();
232  p->setSRID(srid);
233 
234  ad = p;
235  }
236  else if(g->getGeomTypeId() == te::gm::MultiPolygonType)
237  {
238  te::gm::Polygon* poly = (te::gm::Polygon*)((te::gm::MultiPolygon*)g)->getGeometryN(0);
239 
240  te::gm::Point* p = poly->getCentroid();
241  p->setSRID(srid);
242 
243  ad = p;
244  }
245  }
246  else
247  {
248  ad = dataSet->getValue(it->getName()).release();
249  }
250 
251  v->addAttribute(count - shift, ad);
252 
253  ++ count;
254 
255  ++it;
256  }
257 
258  m_graph->add(v);
259  }
260 
261  return true;
262 }
263 
264 bool te::graph::FlowGraphBuilder::createEdgeObjects(const std::string& csvFileName, const int& fromIdx, const int& toIdx, const int& weightIdx)
265 {
266  //open file
267  std::ifstream in(csvFileName.c_str());
268 
269  if(in.is_open() == false)
270  {
271  return false;
272  }
273 
275  p->setParent(0);
276  p->setId(0);
277 
278  m_graph->addEdgeProperty(p);
279 
280  //create boost tokenizer
281  typedef boost::tokenizer< boost::escaped_list_separator<char> > Tokenizer;
282  boost::escaped_list_separator<char> sep('\\', ';', '\"');
283 
284  std::vector<std::string> line;
285  std::string buffer;
286 
287  //access each line of the csv file
288  while(std::getline(in, buffer))
289  {
290  line.clear();
291 
292  Tokenizer tok(buffer, sep);
293 
294  line.assign(tok.begin(), tok.end());
295 
296  std::string fromStr, toStr, weightStr;
297  try
298  {
299  fromStr = line[fromIdx];
300  toStr = line[toIdx];
301  weightStr = line[weightIdx];
302  }
303  catch(...)
304  {
305  return false;
306  }
307 
308  //create edge
309  int id = getEdgeId();
310  int from = atoi(fromStr.c_str());
311  int to = atoi(toStr.c_str());
312  int weight = atoi(weightStr.c_str());
313 
314  Edge* e = new Edge(id, from, to);
315 
316  e->setAttributeVecSize(1); //weight attribute
317  e->addAttribute(0, new te::dt::SimpleData<int, te::dt::INT32_TYPE>(weight));
318 
319  m_graph->add(e);
320  }
321 
322  return true;
323 }
FlowGraphBuilder()
Default constructor.
bool build(const std::string &shapeFileName, const std::string &linkColumn, const int &srid, const std::string &csvFileName, const int &fromIdx, const int &toIdx, const int &weightIdx, const std::map< std::string, std::string > &dsInfo, const std::string &graphType, const std::map< std::string, std::string > &gInfo)
Function used to build the output graph based on input parameters.
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
Geometric property.
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
void setGeometryType(GeomType t)
It sets the geometry subtype.
An atomic property like an integer or double.
virtual boost::ptr_vector< te::dt::Property > getProperties(const std::string &datasetName)
It retrieves the properties of the dataset.
Definition: DataSource.cpp:168
virtual ~FlowGraphBuilder()
Virtual destructor.
virtual Property * clone() const =0
It returns a clone of the object.
int m_edgeId
Attribute used as a index counter for edge objects.
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:163
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:118
It models a property definition.
Definition: Property.h:59
std::auto_ptr< te::da::DataSet > getDataSet(te::da::DataSource *ds)
Function used to get the data set with the vectorial data.
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
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
void setSRID(int srid)
It sets the Spatial Reference System ID of the Point.
static std::auto_ptr< DataSource > make(const std::string &dsType)
virtual std::auto_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...
Definition: DataSource.cpp:61
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.
Definition: DataSource.cpp:144
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
std::auto_ptr< te::da::DataSource > getDataSource(const std::string fileName)
Function used to get the data source with the vectorial data.
boost::ptr_vector< te::dt::Property > getProperties(te::da::DataSource *ds)
Function used to get the data source properties.
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
bool createEdgeObjects(const std::string &csvFileName, const int &fromIdx, const int &toIdx, const int &weightIdx)
Function used to create all edges object based on flow table data.
Point * getCentroid() const
It returns the mathematical centroid for this surface as a point.
int getEdgeId()
Function used to generated the edge id.
bool createVertexObjects(const std::string &shapeFileName, const std::string &linkColumn, const int &srid)
Function used to create all vertex object based on vectorial data.
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
static AbstractGraph * make()
It creates and returns an empty graph with default graph type.
This abstract class provides the common functions for graph builder classes. Each builder strategy ha...
virtual void setSRID(int srid)=0
It sets the Spatial Reference System ID of the geometry and all its parts if it is a GeometryCollecti...
void setParent(Property *p)
It associate this property to the informed parent.
Definition: Property.h:177