OpenFPM_io  0.2.0
Project that contain the implementation and interfaces for basic structure like vectors, grids, graph ... .
 All Data Structures Functions Variables Typedefs
GraphMLWriter.hpp
1 #ifndef GRAPHML_WRITER_HPP
2 #define GRAPHML_WRITER_HPP
3 
4 #include "Graph/map_graph.hpp"
5 #include <iostream>
6 #include <fstream>
7 #include "util/common.hpp"
8 
9 
19 template <typename T>
20 void create_prop(std::string * str)
21 {
22  // if T has attributes defined
23  if (has_attributes<T>::value )
24  {
25  // Create properties names based on the attributes name defined
26  for (size_t i = 0 ; i < T::max_prop ; i++)
27  {
28  str[i] = std::string(T::attributes::name[i]);
29  }
30  }
31  else
32  {
33  // Create default properties name
34  for (size_t i = 0 ; i < T::max_prop ; i++)
35  {
36  str[i] = "attr" + std::to_string(i);
37  }
38  }
39 }
40 
50 template<typename G>
52 {
53  // Properties counter
54  int cnt = 0;
55 
56  // vertex properties
57  std::string & v_prop;
58 
59  // Attribute names
60  std::string * attributes_names;
61 
62  // Number of attributes name defined into the vertex
63  int n_attr = 0;
64 
75  vertex_prop(std::string & v_prop, typename G::V_type::attributes & a_name)
76  :v_prop(v_prop),attributes_names(a_name.name)
77  {
78  // Calculate the number of attributes name
79  n_attr = sizeof(a_name.name)/sizeof(std::string);
80  };
81 
90  vertex_prop(std::string & v_prop)
91  :v_prop(v_prop),attributes_names(NULL)
92  {
93  // Calculate the number of attributes
94  n_attr = G::V_type::max_prop;
95 
96  // Create default property names
97  attributes_names = new std::string[G::V_type::max_prop];
98 
99  // Create default property names
100  create_prop<typename G::V_type>(attributes_names);
101  };
102 
104  template<typename T>
105  void operator()(T& t)
106  {
108  if (cnt < n_attr)
109  {
110  // if it is a yFile extension property name, does not process it
111  if (attributes_names[cnt] == "x" || attributes_names[cnt] == "y"
112  || attributes_names[cnt] == "z" || attributes_names[cnt] == "shape" )
113  {cnt++; return ;}
114 
115  // Create a property string based on the type of the property
116  if (typeid(T) == typeid(float))
117  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"float\"/>\n";
118  else if (typeid(T) == typeid(double))
119  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"double\"/>\n";
120  else if (typeid(T) == typeid(int))
121  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"int\"/>\n";
122  else if (typeid(T) == typeid(long int))
123  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"long\"/>\n";
124  else if (typeid(T) == typeid(bool))
125  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"boolean\"/>\n";
126  else if (typeid(T) == typeid(std::string))
127  v_prop += "<key id=\"vk" + std::to_string(cnt) + "\" for=\"node\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"string\"/>\n";
128  }
129 
130  cnt++;
131  }
132 };
133 
143 template<typename G>
145 {
146  // Vertex object container
147  const typename G::V_container & vo;
148 
149  // Properties counter
150  int cnt = 0;
151 
152  // vertex node string
153  std::string & v_node;
154 
155  // Attribute names
156  std::string * attributes_names;
157 
158  // Number of attributes name defined into the vertex
159  int n_attr = 0;
160 
171  inline vertex_node(std::string & v_node, const typename G::V_container & n_obj, typename G::V_type::attributes & a_name)
172  :vo(n_obj),v_node(v_node),attributes_names(a_name.name)
173  {
174  // Calculate the number of attributes name
175  n_attr = sizeof(a_name.name)/sizeof(std::string);
176  };
177 
178 #ifdef DEBUG
179 
185  inline vertex_node(std::string & v_node, const typename G::V_container && n_obj, typename G::V_type::attributes & a_name)
186  :vo(n_obj),v_node(v_node),attributes_names(a_name.name)
187  {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
188 #endif
189 
198  inline vertex_node(std::string & v_node, const typename G::V_container & n_obj)
199  :vo(n_obj),v_node(v_node),attributes_names(NULL)
200  {
201  // Calculate the number of attributes
202  n_attr = G::V_type::max_prop;
203 
204  // Create default property names
205  attributes_names = new std::string[G::V_type::max_prop];
206 
207  // Create default property names
208  create_prop<typename G::V_type>(attributes_names);
209  };
210 
211  inline ~vertex_node()
212  {
213  delete [] attributes_names;
214  }
215 
216 #ifdef DEBUG
217 
223  inline vertex_node(std::string & v_node, const typename G::V_container && n_obj)
224  :vo(n_obj),v_node(v_node),attributes_names(NULL)
225  {std::cerr << "Error: " <<__FILE__ << ":" << __LINE__ << " Passing a temporal object\n";};
226 #endif
227 
233  void new_node(size_t v_c)
234  {
235  // start a new node
236  v_node += "<node id=\"n"+ std::to_string(v_c) + "\">\n";
237 
238  // reset the counter properties
239  cnt = 0;
240  }
241 
247  void end_node()
248  {
249  // close a node
250  v_node += "</node>\n";
251  }
252 
254  template<typename T>
255  void operator()(T& t)
256  {
258  if (T::value < n_attr)
259  {
260  // Create a property string based on the type of the property
261  if (typeid(decltype(vo.template get<T::value>())) == typeid(float))
262  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
263  else if (typeid(decltype(vo.template get<T::value>())) == typeid(double))
264  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
265  else if (typeid(decltype(vo.template get<T::value>())) == typeid(int))
266  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
267  else if (typeid(decltype(vo.template get<T::value>())) == typeid(long int))
268  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
269  else if (typeid(decltype(vo.template get<T::value>())) == typeid(bool))
270  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
271  else if (typeid(decltype(vo.template get<T::value>())) == typeid(std::string))
272  v_node += " <data key=\"vk" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
273  }
274 
275  cnt++;
276  }
277 };
278 
288 template<typename G>
289 struct edge_prop
290 {
291  // Properties counter
292  int cnt = 0;
293 
294  // edge properties
295  std::string & e_prop;
296 
297  // Attribute names
298  std::string * attributes_names;
299 
300  // Number of attributes name defined into the vertex
301  int n_attr = 0;
302 
312  edge_prop(std::string & e_prop, typename G::E_type::attributes & a_name)
313  :e_prop(e_prop),attributes_names(a_name.name)
314  {
315  // Calculate the number of attributes name
316  n_attr = sizeof(a_name.name)/sizeof(std::string);
317  };
318 
327  edge_prop(std::string & e_prop)
328  :e_prop(e_prop),attributes_names(NULL)
329  {
330  // Calculate the number of attributes
331  n_attr = G::E_type::max_prop;
332 
333  // Create default property names
334  attributes_names = new std::string[G::E_type::max_prop];
335 
336  // Create default property names
337  create_prop<typename G::E_type>(attributes_names);
338  };
339 
341  template<typename T>
342  void operator()(T& t)
343  {
345  if (cnt < n_attr)
346  {
347  // Create a property string based on the type of the property
348  if (typeid(T) == typeid(float))
349  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"float\"/>\n";
350  else if (typeid(T) == typeid(double))
351  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"double\"/>\n";
352  else if (typeid(T) == typeid(int))
353  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"int\"/>\n";
354  else if (typeid(T) == typeid(long int))
355  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"long\"/>\n";
356  else if (typeid(T) == typeid(bool))
357  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"boolean\"/>\n";
358  else if (typeid(T) == typeid(std::string))
359  e_prop += "<key id=\"ek" + std::to_string(cnt) + "\" for=\"edge\" attr.name=\"" + attributes_names[cnt] + "\" attr.type=\"string\"/>\n";
360  }
361 
362  cnt++;
363  }
364 };
365 
375 template<typename G>
376 struct edge_node
377 {
378  // Vertex object container
379  typename G::E_container & vo;
380 
381  // Properties counter
382  int cnt = 0;
383 
384  // edge node string
385  std::string & e_node;
386 
387  // Attribute names
388  std::string * attributes_names;
389 
390  // Number of attributes name defined into the vertex
391  int n_attr = 0;
392 
403  edge_node(std::string & e_node, typename G::E_container & n_obj, typename G::E_type::attributes & a_name)
404  :vo(n_obj),e_node(e_node),attributes_names(a_name.name)
405  {
406  // Calculate the number of attributes name
407  n_attr = sizeof(a_name.name)/sizeof(std::string);
408  };
409 
419  edge_node(std::string & e_node, typename G::E_container & n_obj)
420  :vo(n_obj),e_node(e_node),attributes_names(NULL)
421  {
422  // Calculate the number of attributes
423  n_attr = G::E_type::max_prop;
424 
425  // Create a number of default properties name
426  attributes_names = new std::string[G::E_type::max_prop];
427 
428  // Create default property names
429  create_prop<typename G::E_type>(attributes_names);
430 
431  };
432 
438  void new_node(size_t v_c, size_t s, size_t d)
439  {
440  // start a new node
441  e_node += "<edge id=\"e"+ std::to_string(v_c) + "\" source=\"n" + std::to_string(s) + "\" target=\"n" + std::to_string(d) + "\">\n";
442 
443  // reset the counter properties
444  cnt = 0;
445  }
446 
452  void end_node()
453  {
454  // close a node
455  e_node += "</edge>\n";
456  }
457 
459  template<typename T>
460  void operator()(T& t)
461  {
463  if (T::value < n_attr)
464  {
465  // Create a property string based on the type of the property
466  if (typeid(decltype(vo.template get<T::value>())) == typeid(float))
467  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
468  else if (typeid(decltype(vo.template get<T::value>())) == typeid(double))
469  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
470  else if (typeid(decltype(vo.template get<T::value>())) == typeid(int))
471  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
472  else if (typeid(decltype(vo.template get<T::value>())) == typeid(long int))
473  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
474  else if (typeid(decltype(vo.template get<T::value>())) == typeid(bool))
475  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
476  else if (typeid(decltype(vo.template get<T::value>())) == typeid(std::string))
477  e_node += " <data key=\"ek" + std::to_string(cnt) + "\">" + std::to_string(vo.template get<T::value>()) + "</data>\n";
478  }
479 
480  cnt++;
481  }
482 };
483 
490 template <typename Graph>
492 {
493  Graph & g;
494 
506  {
508  std::string v_out("");
509 
510  // create a vertex property functor
511  vertex_prop<Graph> vp(v_out);
512 
513  // Iterate through all the vertex and create the vertex list
514  boost::mpl::for_each< typename Graph::V_type::type >(vp);
515 
516  // return the vertex properties string
517  return v_out;
518  }
519 
529  {
531  std::string e_out;
532 
533  // create a vertex property functor
534  edge_prop<Graph> ep(e_out);
535 
536  // Iterate through all the vertex and create the vertex list
537  boost::mpl::for_each< typename Graph::E_type::type >(ep);
538 
539  // return the edge properties string
540  return e_out;
541  }
542 
543  std::string get_vertex_list()
544  {
545  // node counter
546  size_t nc = 0;
547 
549  std::string v_out;
550 
552  auto it = g.getVertexIterator();
553 
554  // if there is the next element
555  while (it.isNext())
556  {
557  auto v = g.vertex(it.get());
558 
559  // create a vertex list functor
560  vertex_node<Graph> vn(v_out,v);
561 
562  // create new node
563  vn.new_node(nc);
564 
565  // Iterate through all the vertex and create the vertex list
566  boost::mpl::for_each_ref< boost::mpl::range_c<int,0,Graph::V_type::max_prop> >(vn);
567 
568  // end node
569  vn.end_node();
570 
571  // increment the iterator and counter
572  ++it;
573  nc++;
574  }
575 
576  // return the vertex list
577  return v_out;
578  }
579 
580  std::string get_edge_list()
581  {
582  // node counter
583  size_t nc = 0;
584 
586  std::string e_out;
587 
589  auto it = g.getEdgeIterator();
590 
591  // if there is the next element
592  while (it.isNext())
593  {
594  // Get the edge object
595  auto obj = g.edge(it.get());
596 
597  // create an edge list functor
598  edge_node<Graph> en(e_out,obj);
599 
600  // create a new node
601  en.new_node(nc,it.source(),it.target());
602 
603  // Iterate through all the edges and create the edge list
604  boost::mpl::for_each< boost::mpl::range_c<int,0,Graph::E_type::max_prop> >(en);
605 
606  // end new node
607  en.end_node();
608 
609  // increment the operator
610  ++it;
611  nc++;
612  }
613 
614  // return the edge list
615  return e_out;
616  }
617 
618 public:
619 
627  GraphMLWriter(Graph & g)
628  :g(g)
629  {}
630 
638  bool write(std::string file, std::string graph_name="Graph")
639  {
640  // Header for the GraphML
641  std::string gml_header;
642  // Vertex list of the GraphML
643  std::string vertex_list;
644  // End for the GraphML
645  std::string gml_header_end;
646  // Graph header
647  std::string graph_header;
648  // Graph header end
649  std::string graph_header_end;
650  // Edge list of the GraphML
651  std::string edge_list;
652  // vertex properties header
653  std::string vertex_prop_header;
654  // edge properties header
655  std::string edge_prop_header;
656 
657  // GraphML header
658  gml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
659  <graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"\n\
660  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\
661  xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns\n\
662  http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\">\n";
663 
664  // Graph header to define an header
665  graph_header = "<graph id=\"" + graph_name + "\" edgedefault=\"undirected\">\n";
666  // Graph header end
667  graph_header_end = "</graph>\n";
668 
669  // Vertex properties header
670  vertex_prop_header = get_vertex_properties_list();
671 
672  // Edge properties header
673  edge_prop_header = get_edge_properties_list();
674 
675  // Get the node graph list
676  vertex_list = get_vertex_list();
677 
678  // Get the edge graph list
679  edge_list = get_edge_list();
680 
681  // Header end
682  gml_header_end = "</graphml>";
683 
684  // write the file
685 
686  std::ofstream ofs(file);
687 
688  // Check if the file is open
689  if (ofs.is_open() == false)
690  {std::cerr << "Error cannot creare the graphML file: " + file;}
691 
692  ofs << gml_header << graph_header << vertex_prop_header << edge_prop_header <<
693  vertex_list << edge_list << graph_header_end << gml_header_end;
694 
695  // Close the file
696 
697  ofs.close();
698 
699  // Completed succefully
700  return true;
701  }
702 };
703 
704 #endif
this class is a functor for "for_each" algorithm
vertex_prop(std::string &v_prop)
Constructor.
vertex_node(std::string &v_node, const typename G::V_container &n_obj)
Constructor.
void end_node()
Close a node.
GraphMLWriter(Graph &g)
this class is a functor for "for_each" algorithm
void new_node(size_t v_c, size_t s, size_t d)
Create a new node.
std::string get_vertex_list()
std::string get_edge_list()
edge_node(std::string &e_node, typename G::E_container &n_obj, typename G::E_type::attributes &a_name)
Constructor.
void new_node(size_t v_c)
Create a new node.
bool write(std::string file, std::string graph_name="Graph")
It write a GraphML file from a graph.
edge_node(std::string &e_node, typename G::E_container &n_obj)
Constructor.
vertex_node(std::string &v_node, const typename G::V_container &n_obj, typename G::V_type::attributes &a_name)
Constructor.
void operator()(T &t)
It call the functor for each member.
this class is a functor for "for_each" algorithm
void operator()(T &t)
It call the functor for each member.
std::string get_vertex_properties_list()
It get the vertex properties list.
vertex_prop(std::string &v_prop, typename G::V_type::attributes &a_name)
Constructor.
void operator()(T &t)
It call the functor for each member.
void operator()(T &t)
It call the functor for each member.
edge_prop(std::string &e_prop, typename G::E_type::attributes &a_name)
Constructor.
this class is a functor for "for_each" algorithm
void end_node()
Close a node.
edge_prop(std::string &e_prop)
Constructor.
std::string get_edge_properties_list()
It get the edge properties list.