All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FlowGraphBuilder.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 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 = 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 }
void setGeometryType(GeomType t)
It sets the geometry subtype.
int m_edgeId
Attribute used as a index counter for edge objects.
static AbstractGraph * make()
It creates and returns an empty graph with default graph type.
Class used to define the edge struct of a graph. Its compose with a identifier, the vertex origin and...
Definition: Edge.h:58
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.
void setParent(Property *p)
It associate this property to the informed parent.
Definition: Property.h:159
virtual boost::ptr_vector< te::dt::Property > getProperties(const std::string &datasetName)
It retrieves the properties of the dataset.
Definition: DataSource.cpp:161
An atomic property like an integer or double.
virtual std::vector< std::string > getDataSetNames()
It gets the dataset names available in the data source.
Definition: DataSource.cpp:143
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
boost::ptr_vector< te::dt::Property > getProperties(te::da::DataSource *ds)
Function used to get the data source properties.
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 setAttributeVecSize(int size)
This function is used to set the number of attributes associated with the vertex elements.
Definition: Vertex.cpp:79
FlowGraphBuilder()
Default constructor.
From the point of view of graph theory, vertices are treated as featureless and indivisible objects...
Definition: Vertex.h:68
This abstract class provides the common functions for graph builder classes. Each builder strategy ha...
A template for atomic data types (integers, floats, strings and others).
Definition: SimpleData.h:59
std::string Convert2UCase(const std::string &value)
It converts a string to upper case.
Definition: StringUtils.h:163
static std::auto_ptr< DataSource > make(const std::string &dsType)
void setId(unsigned int id)
It sets the property identifier.
Definition: Property.h:117
int getEdgeId()
Function used to generated the edge id.
virtual ~FlowGraphBuilder()
Virtual destructor.
std::auto_ptr< te::da::DataSource > getDataSource(const std::string fileName)
Function used to get the data source with the vectorial data.
void addAttribute(int idx, te::dt::AbstractData *ad)
Add a new attribute to this element.
Definition: Vertex.cpp:84
MultiPolygon is a MultiSurface whose elements are Polygons.
Definition: MultiPolygon.h:50
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
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.
GeomType getGeomTypeId() const
It returns the geometry subclass type identifier.
Definition: Geometry.h:178
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:116
std::auto_ptr< te::da::DataSet > getDataSet(te::da::DataSource *ds)
Function used to get the data set with the vectorial data.
It models a property definition.
Definition: Property.h:59
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:60
Point * getCentroid() const
It returns the mathematical centroid for this surface as a point.
void setSRID(int srid)
It sets the spatial reference system identifier associated to this property.
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.
bool createVertexObjects(const std::string &shapeFileName, const std::string &linkColumn, const int &srid)
Function used to create all vertex object based on vectorial data.
Geometric property.
virtual Property * clone() const =0
It returns a clone of the object.