All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SpatialWeightsExchanger.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 SpatialWeightsExchanger.cpp
22 
23  \brief This class defines functions used to load and save graphs using GAL and GWT formats,
24  both formats use a ' ' as separator.
25 
26  GAL FORMAT
27 
28  0 NUMBER_OBSERVATIONS DATASET_NAME ATTRIBUTE_ID_NAME (HEADER LINE)
29  OBSERVATION_ID NUMBER_NEIGHBOURS
30  NEIGHBOURS_1 NEIGHBOURS_2 ... NEIGHBOURS_N
31  OBSERVATION_ID NUMBER_NEIGHBOURS
32  NEIGHBOURS_1 NEIGHBOURS_2 ... NEIGHBOURS_N
33  ...
34 
35 
36  GWT FORMAT
37 
38  0 NUMBER_OBSERVATIONS DATASET_NAME ATTRIBUTE_ID_NAME (HEADER LINE)
39  OBSERVATION_ID_FROM OBSERVATION_ID_TO DISTANCE
40  OBSERVATION_ID_FROM OBSERVATION_ID_TO DISTANCE
41  OBSERVATION_ID_FROM OBSERVATION_ID_TO DISTANCE
42  ...
43 */
44 
45 //Terralib Includes
46 #include "../../dataaccess/datasource/DataSource.h"
47 #include "../../dataaccess/utils/Utils.h"
48 #include "../../datatype/SimpleData.h"
49 #include "../../datatype/SimpleProperty.h"
50 #include "../../geometry/GeometryProperty.h"
51 #include "../../geometry/MultiPolygon.h"
52 #include "../../geometry/Point.h"
53 #include "../../geometry/Polygon.h"
54 #include "../core/AbstractGraph.h"
55 #include "../core/AbstractGraphFactory.h"
56 #include "../core/GraphMetadata.h"
57 #include "../core/Edge.h"
58 #include "../core/Vertex.h"
59 #include "../iterator/AbstractIterator.h"
60 #include "../iterator/SequenceIterator.h"
61 #include "../iterator/MemoryIterator.h"
63 
64 //STL Includes
65 #include <cassert>
66 #include <fstream>
67 #include <iosfwd>
68 #include <stdio.h>
69 
70 // BOOST Includes
71 #include<boost/tokenizer.hpp>
72 
74 {
75 }
76 
78 {
79 }
80 
81 void te::graph::SpatialWeightsExchanger::exportToGAL(te::graph::AbstractGraph* g, std::string pathFileName, std::string dataSetName, std::string propertyName)
82 {
83  //get iterator
84  std::auto_ptr<te::graph::AbstractIterator> it;
85 
86  if(g->getMetadata()->getDataSource())
87  {
88  it.reset(new te::graph::SequenceIterator(g));
89  }
90  else
91  {
92  it.reset(new te::graph::MemoryIterator(g));
93  }
94 
95  assert(it.get());
96 
97  //create file
98  FILE* fp = fopen(pathFileName.c_str(), "w");
99 
100  assert(fp);
101 
102  //write header info
103  if(dataSetName.empty())
104  {
105  fprintf(fp, "%d\n", (int)it->getVertexInteratorCount());
106  }
107  else
108  {
109  fprintf(fp, "0 %d %s %s\n", (int)it->getVertexInteratorCount(), dataSetName.c_str(), propertyName.c_str());
110  }
111 
112  //write body info
113  te::graph::Vertex* v = it->getFirstVertex();
114 
115  while(it->isVertexIteratorAfterEnd() == false)
116  {
117  int id = v->getId();
118  std::set<int> neighbours = v->getNeighborhood();
119  std::set<int>::iterator itNeighbours = neighbours.begin();
120 
121  if(!neighbours.empty())
122  {
123  fprintf(fp, "%d %d\n", id, (int)neighbours.size());
124 
125  while(itNeighbours != neighbours.end())
126  {
127  te::graph::Edge* e = g->getEdge(*itNeighbours);
128 
129  if(e)
130  {
131  if(e->getIdFrom() == id)
132  fprintf (fp, "%d ", e->getIdTo());
133  else
134  fprintf (fp, "%d ", e->getIdFrom());
135  }
136 
137  ++itNeighbours;
138  }
139 
140  fprintf (fp, "\n");
141  }
142 
143  v = it->getNextVertex();
144  }
145 
146  fclose(fp);
147 }
148 
149 te::graph::AbstractGraph* te::graph::SpatialWeightsExchanger::importFromGAL(std::string pathFileName, std::map<std::string, std::string> dsInfo,
150  std::string graphType, std::map<std::string, std::string> gInfo, te::da::DataSource* ds)
151 {
152  //open file
153  std::ifstream file(pathFileName.c_str());
154 
155  if(file.is_open() == false)
156  {
157  return 0;
158  }
159 
160  //create output graph
161  te::graph::AbstractGraph* graph = te::graph::AbstractGraphFactory::make(graphType, dsInfo, gInfo);
162  assert(graph);
163 
164  //create boost tokenizer
165  typedef boost::tokenizer< boost::escaped_list_separator<char> > Tokenizer;
166  boost::escaped_list_separator<char> sep('\\', ' ', '\"');
167 
168  std::vector<std::string> line;
169  std::string buffer;
170 
171  //get header line
172  std::getline(file, buffer);
173  Tokenizer tok(buffer, sep);
174  line.assign(tok.begin(), tok.end());
175 
176  std::string dataSetName = "";
177  std::string attributeName = "";
178  bool associateGeom = false;
179 
180  if(line.size() == 4 && ds) // has the number of observations and data set information
181  {
182  associateGeom = true;
183 
184  dataSetName = line[2];
185  attributeName = line[3];
186  }
187 
188  //access each line of the gat file
189  m_edgeId = 0;
190 
191  while(std::getline(file, buffer))
192  {
193  line.clear();
194  Tokenizer tok(buffer, sep);
195  line.assign(tok.begin(), tok.end());
196 
197  std::string vertexIdStr, nNeighboursStr;
198 
199  try
200  {
201  vertexIdStr = line[0];
202  nNeighboursStr = line[1];
203  }
204  catch(...)
205  {
206  delete graph;
207 
208  return 0;
209  }
210 
211  //create vertex
212  int vId = atoi(vertexIdStr.c_str());
213  Vertex* v = graph->getVertex(vId);
214 
215  if(!v)
216  {
217  v = new Vertex(vId);
218  graph->add(v);
219  }
220 
221  //get new line in gal file
222  std::getline(file, buffer);
223  line.clear();
224  Tokenizer tok2(buffer, sep);
225  line.assign(tok2.begin(), tok2.end());
226 
227  //get neighbours
228  int nNeighbours = atoi(nNeighboursStr.c_str());
229 
230  try
231  {
232  for(int i = 0; i < nNeighbours; ++i)
233  {
234  std::string vNeighbourStr = line[i];
235  int vNeighbourId = atoi(vNeighbourStr.c_str());
236 
237  //add vertex neighbour
238  Vertex* vNeighbour = graph->getVertex(vNeighbourId);
239 
240  if(!vNeighbour)
241  {
242  vNeighbour = new Vertex(vNeighbourId);
243  graph->add(vNeighbour);
244  }
245 
246  //create edge
247  int id = getEdgeId();
248 
249  Edge* e = new Edge(id, vId, vNeighbourId);
250  graph->add(e);
251  }
252  }
253  catch(...)
254  {
255  delete graph;
256 
257  return 0;
258  }
259  }
260 
261  file.close();
262 
263  if(associateGeom)
264  associateGeometry(graph, ds, dataSetName, attributeName);
265 
266  return graph;
267 }
268 
269 void te::graph::SpatialWeightsExchanger::exportToGWT(te::graph::AbstractGraph* g, std::string pathFileName, int distAttrIdx, std::string dataSetName, std::string propertyName)
270 {
271  //get iterator
272  std::auto_ptr<te::graph::AbstractIterator> it;
273 
274  if(g->getMetadata()->getDataSource())
275  {
276  it.reset(new te::graph::SequenceIterator(g));
277  }
278  else
279  {
280  it.reset(new te::graph::MemoryIterator(g));
281  }
282 
283  assert(it.get());
284 
285  //create file
286  FILE* fp = fopen(pathFileName.c_str(), "w");
287 
288  assert(fp);
289 
290  //write header info
291  if(dataSetName.empty())
292  {
293  fprintf(fp, "%d\n", (int)it->getEdgeInteratorCount());
294  }
295  else
296  {
297  fprintf(fp, "0 %d %s %s\n", (int)it->getEdgeInteratorCount(), dataSetName.c_str(), propertyName.c_str());
298  }
299 
300  //write body info
301  te::graph::Edge* e = it->getFirstEdge();
302 
303  while(it->isEdgeIteratorAfterEnd() == false)
304  {
305  int idFrom = e->getIdFrom();
306  int idTo = e->getIdTo();
307 
309 
310  double distance = sd->getValue();
311 
312  fprintf(fp, "%d %d %3.7f\n", idFrom, idTo, distance);
313 
314  e = it->getNextEdge();
315  }
316 
317  fclose(fp);
318 }
319 
320 te::graph::AbstractGraph* te::graph::SpatialWeightsExchanger::importFromGWT(std::string pathFileName, std::map<std::string, std::string> dsInfo,
321  std::string graphType, std::map<std::string, std::string> gInfo, te::da::DataSource* ds)
322 {
323  //open file
324  std::ifstream file(pathFileName.c_str());
325 
326  if(file.is_open() == false)
327  {
328  return 0;
329  }
330 
331  //create output graph
332  te::graph::AbstractGraph* graph = te::graph::AbstractGraphFactory::make(graphType, dsInfo, gInfo);
333  assert(graph);
334 
335  //add edge property
337  p->setParent(0);
338  p->setId(0);
339 
340  graph->addEdgeProperty(p);
341 
342  //create boost tokenizer
343  typedef boost::tokenizer< boost::escaped_list_separator<char> > Tokenizer;
344  boost::escaped_list_separator<char> sep('\\', ' ', '\"');
345 
346  std::vector<std::string> line;
347  std::string buffer;
348 
349  //get header line
350  std::getline(file, buffer);
351  Tokenizer tok(buffer, sep);
352  line.assign(tok.begin(), tok.end());
353 
354  std::string dataSetName = "";
355  std::string attributeName = "";
356  bool associateGeom = false;
357 
358  if(line.size() == 4 && ds) // has the number of observations and data set information
359  {
360  associateGeom = true;
361 
362  dataSetName = line[2];
363  attributeName = line[3];
364  }
365 
366  //access each line of the gwt file
367  m_edgeId = 0;
368 
369  while(std::getline(file, buffer))
370  {
371  line.clear();
372 
373  Tokenizer tok(buffer, sep);
374 
375  line.assign(tok.begin(), tok.end());
376 
377  std::string fromStr, toStr, distanceStr;
378 
379  try
380  {
381  fromStr = line[0];
382  toStr = line[1];
383  distanceStr = line[2];
384  }
385  catch(...)
386  {
387  delete graph;
388 
389  return 0;
390  }
391 
392  //create vertex from
393  int from = atoi(fromStr.c_str());
394 
395  Vertex* vFrom = graph->getVertex(from);
396 
397  if(!vFrom)
398  {
399  vFrom = new Vertex(from);
400  graph->add(vFrom);
401  }
402 
403  //create vertex to
404  int to = atoi(toStr.c_str());
405 
406  Vertex* vTo = graph->getVertex(to);
407 
408  if(!vTo)
409  {
410  vTo = new Vertex(to);
411  graph->add(vTo);
412  }
413 
414  //create edge
415  int id = getEdgeId();
416  double distance = atof(distanceStr.c_str());
417 
418  Edge* e = new Edge(id, from, to);
419  e->setAttributeVecSize(1); //distance attribute
420  e->addAttribute(0, new te::dt::SimpleData<double, te::dt::DOUBLE_TYPE>(distance));
421 
422  graph->add(e);
423  }
424 
425  file.close();
426 
427  if(associateGeom)
428  associateGeometry(graph, ds, dataSetName, attributeName);
429 
430  return graph;
431 }
432 
434 {
435  int id = m_edgeId;
436 
437  m_edgeId++;
438 
439  return id;
440 }
441 
443  std::string dataSetName, std::string propertyName)
444 {
445  //get srid information
446  std::auto_ptr<te::da::DataSetType> dataSetType = ds->getDataSetType(dataSetName);
448 
449  //create graph vertex attrs
450  te::gm::GeometryProperty* gProp = new te::gm::GeometryProperty("coords");
451  gProp->setId(0);
452  gProp->setGeometryType(te::gm::PointType);
453  gProp->setSRID(gp->getSRID());
454 
455  g->addVertexProperty(gProp);
456 
457  //get data set
458  std::auto_ptr<te::da::DataSet> dataSet = ds->getDataSet(dataSetName);
459 
460  std::size_t geomPos = te::da::GetFirstSpatialPropertyPos(dataSet.get());
461 
462  dataSet->moveBeforeFirst();
463 
464  while(dataSet->moveNext())
465  {
466  int id = dataSet->getInt32(propertyName);
467 
468  Vertex* v = g->getVertex(id);
469 
470  if(v)
471  {
472  v->setAttributeVecSize(1);
473 
474  std::auto_ptr<te::gm::Geometry> g = dataSet->getGeometry(geomPos);
475 
476  te::dt::AbstractData* ad = 0;
477 
478  if(g->getGeomTypeId() == te::gm::PointType)
479  {
480  g->setSRID(gp->getSRID());
481 
482  ad = g->clone();
483  }
484  else if(g->getGeomTypeId() == te::gm::PolygonType)
485  {
486  te::gm::Point* p = ((te::gm::Polygon*)g.get())->getCentroid();
487  p->setSRID(gp->getSRID());
488 
489  ad = p;
490  }
491  else if(g->getGeomTypeId() == te::gm::MultiPolygonType)
492  {
493  te::gm::Polygon* poly = (te::gm::Polygon*)((te::gm::MultiPolygon*)g.get())->getGeometryN(0);
494 
495  te::gm::Point* p = poly->getCentroid();
496  p->setSRID(gp->getSRID());
497 
498  ad = p;
499  }
500 
501  v->addAttribute(0, ad);
502 
503  v->setDirty(true);
504  }
505  }
506 }
te::da::DataSource * getDataSource()
It returns the data source associated with this graph.
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.
An atomic property like an integer or double.
virtual te::graph::Edge * getEdge(int id)=0
It returns the edge element if it's exist.
virtual void addEdgeProperty(te::dt::Property *p)=0
Add a new property associated to the edge element.
int getEdgeId()
Function used to generated the edge id.
T getValue() const
It returns the associated value.
Definition: SimpleData.h:139
An abstract class for data providers like a DBMS, Web Services or a regular file. ...
Definition: DataSource.h:118
void exportToGAL(te::graph::AbstractGraph *g, std::string pathFileName, std::string dataSetName="", std::string propertyName="")
Function used to export a graph to Spatial Weights File GAL Format.
This class defines functions used to load and save graphs using GAL and GWT formats, both formats use a ' ' as separator.
virtual void add(Vertex *v)=0
Add a new vertex element to a graph.
te::graph::AbstractGraph * importFromGAL(std::string pathFileName, std::map< std::string, std::string > dsInfo, std::string graphType, std::map< std::string, std::string > gInfo, te::da::DataSource *ds=0)
Function used to import a graph from a Spatial Weights File GAL Format.
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:117
virtual te::graph::GraphMetadata * getMetadata()=0
Function used to access the graph metadata.
Class used to define the edge struct of a graph. Its compose with a identifier, the vertex origin and...
Definition: Edge.h:58
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
void setSRID(int srid)
It sets the Spatial Reference System ID of the Point.
virtual void addVertexProperty(te::dt::Property *p)=0
Add a new property associated to the vertex element.
Abstract class used to define the main functions of graph struct. All graph implementations must used...
Definition: AbstractGraph.h:55
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
void associateGeometry(te::graph::AbstractGraph *g, te::da::DataSource *ds, std::string dataSetName, std::string propertyName)
Function used to associate the geometry coord attribute to vertex objects.
void setDirty(bool flag)
Flag used to indicate that this element was changed.
Definition: Vertex.cpp:116
A base class for values that can be retrieved from the data access module.
Definition: AbstractData.h:57
void exportToGWT(te::graph::AbstractGraph *g, std::string pathFileName, int distAttrIdx, std::string dataSetName="", std::string propertyName="")
Function used to export a graph to Spatial Weights File GWT Format.
int getIdFrom()
It returns the vertex origin identification.
Definition: Edge.cpp:71
std::set< int > & getNeighborhood()
Returns the Neighborhood vector.
Definition: Vertex.cpp:111
Polygon is a subclass of CurvePolygon whose rings are defined by linear rings.
Definition: Polygon.h:50
Point * getCentroid() const
It returns the mathematical centroid for this surface as a point.
te::graph::AbstractGraph * importFromGWT(std::string pathFileName, std::map< std::string, std::string > dsInfo, std::string graphType, std::map< std::string, std::string > gInfo, te::da::DataSource *ds=0)
Function used to import a graph from a Spatial Weights File GWT Format.
int getId()
It returns the vertex id.
Definition: Vertex.cpp:69
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.
virtual te::graph::Vertex * getVertex(int id)=0
It returns the vertex element if it's exist.
std::vector< te::dt::AbstractData * > & getAttributes()
It returns the vector of attributes associated with this element.
Definition: Edge.cpp:81
virtual std::auto_ptr< te::da::DataSetType > getDataSetType(const std::string &name)
It gets information about the given dataset.
Definition: DataSource.cpp:156
int getIdTo()
It returns the vertex destiny identification.
Definition: Edge.cpp:76
void setParent(Property *p)
It associate this property to the informed parent.
Definition: Property.h:159