src/lemon/graph_writer.h
changeset 1421 7a21e1414c38
parent 1410 dcfad73b3965
child 1429 4283998fb2be
equal deleted inserted replaced
16:06a412d7990e 17:2617740bfa46
    50   ///
    50   ///
    51   /// \code
    51   /// \code
    52   /// IdMap<ListGraph, Node> nodeIdMap;
    52   /// IdMap<ListGraph, Node> nodeIdMap;
    53   /// writer.writeNodeMap("id", nodeIdMap);
    53   /// writer.writeNodeMap("id", nodeIdMap);
    54   ///
    54   ///
    55   /// writer.writeNodeMap("x-coord", xCoordMap);
    55   /// writer.writeNodeMap("coords", coords);
    56   /// writer.writeNodeMap("y-coord", yCoordMap);
       
    57   /// writer.writeNodeMap("color", colorMap);
    56   /// writer.writeNodeMap("color", colorMap);
    58   /// \endcode
    57   /// \endcode
    59   ///
    58   ///
    60   /// With the \c writeEdgeMap() member function you can give an edge map
    59   /// With the \c writeEdgeMap() member function you can give an edge map
    61   /// writing command similar to the NodeMaps.
    60   /// writing command similar to the NodeMaps.
    89   ///
    88   ///
    90   /// \see DefaultWriterTraits
    89   /// \see DefaultWriterTraits
    91   /// \see QuotedStringWriter
    90   /// \see QuotedStringWriter
    92   /// \see IdMap
    91   /// \see IdMap
    93   /// \see DescriptorMap
    92   /// \see DescriptorMap
    94   /// \see \ref GraphWriter
    93   /// \see \ref GraphReader
    95   /// \see \ref graph-io-page
    94   /// \see \ref graph-io-page
    96   /// \author Balazs Dezso
    95   /// \author Balazs Dezso
    97   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
    96   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
    98   class GraphWriter {
    97   class GraphWriter {
    99   public:
    98   public:
   108     ///
   107     ///
   109     /// Construct a new GraphWriter. It writes the given graph
   108     /// Construct a new GraphWriter. It writes the given graph
   110     /// to the given stream.
   109     /// to the given stream.
   111     GraphWriter(std::ostream& _os, const Graph& _graph) 
   110     GraphWriter(std::ostream& _os, const Graph& _graph) 
   112       : writer(new LemonWriter(_os)), own_writer(true), 
   111       : writer(new LemonWriter(_os)), own_writer(true), 
   113 	graph(_graph), 
   112 	nodeset_writer(*writer, _graph, std::string()),
   114 	nodeset_writer(*writer, graph, std::string()),
   113 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   115 	edgeset_writer(*writer, graph, nodeset_writer, std::string()),
       
   116 	node_writer(*writer, nodeset_writer, std::string()),
   114 	node_writer(*writer, nodeset_writer, std::string()),
   117 	edge_writer(*writer, edgeset_writer, std::string()),
   115 	edge_writer(*writer, edgeset_writer, std::string()),
   118 	attribute_writer(*writer, std::string()) {}
   116 	attribute_writer(*writer, std::string()) {}
   119 
   117 
   120     /// \brief Construct a new GraphWriter.
   118     /// \brief Construct a new GraphWriter.
   121     ///
   119     ///
   122     /// Construct a new GraphWriter. It writes into the given graph
   120     /// Construct a new GraphWriter. It writes into the given graph
   123     /// to the given file.
   121     /// to the given file.
   124     GraphWriter(const std::string& _filename, const Graph& _graph) 
   122     GraphWriter(const std::string& _filename, const Graph& _graph) 
   125       : writer(new LemonWriter(_filename)), own_writer(true), 
   123       : writer(new LemonWriter(_filename)), own_writer(true), 
   126 	graph(_graph),
   124 	nodeset_writer(*writer, _graph, std::string()),
   127 	nodeset_writer(*writer, graph, std::string()),
   125 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   128 	edgeset_writer(*writer, graph, nodeset_writer, std::string()),
       
   129 	node_writer(*writer, nodeset_writer, std::string()),
   126 	node_writer(*writer, nodeset_writer, std::string()),
   130 	edge_writer(*writer, edgeset_writer, std::string()),
   127 	edge_writer(*writer, edgeset_writer, std::string()),
   131 	attribute_writer(*writer, std::string()) {}
   128 	attribute_writer(*writer, std::string()) {}
   132 
   129 
   133     /// \brief Construct a new GraphWriter.
   130     /// \brief Construct a new GraphWriter.
   134     ///
   131     ///
   135     /// Construct a new GraphWriter. It writes into the given graph
   132     /// Construct a new GraphWriter. It writes into the given graph
   136     /// to given LemonReader.
   133     /// to given LemonReader.
   137     GraphWriter(LemonWriter& _writer, const Graph& _graph)
   134     GraphWriter(LemonWriter& _writer, const Graph& _graph)
   138       : writer(_writer), own_writer(false), 
   135       : writer(_writer), own_writer(false), 
   139 	graph(_graph),
   136 	nodeset_writer(*writer, _graph, std::string()),
   140 	nodeset_writer(*writer, graph, std::string()),
   137 	edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
   141 	edgeset_writer(*writer, graph, nodeset_writer, std::string()),
       
   142 	node_writer(*writer, nodeset_writer, std::string()),
   138 	node_writer(*writer, nodeset_writer, std::string()),
   143 	edge_writer(*writer, edgeset_writer, std::string()),
   139 	edge_writer(*writer, edgeset_writer, std::string()),
   144 	attribute_writer(*writer, std::string()) {}
   140 	attribute_writer(*writer, std::string()) {}
   145 
   141 
   146     /// \brief Destruct the graph writer.
   142     /// \brief Destruct the graph writer.
   154     /// \brief Add a new node map writer command for the writer.
   150     /// \brief Add a new node map writer command for the writer.
   155     ///
   151     ///
   156     /// Add a new node map writer command for the writer.
   152     /// Add a new node map writer command for the writer.
   157     template <typename Map>
   153     template <typename Map>
   158     GraphWriter& writeNodeMap(std::string name, const Map& map) {
   154     GraphWriter& writeNodeMap(std::string name, const Map& map) {
   159       nodeset_writer.writeMap(name, map);
   155       nodeset_writer.writeNodeMap(name, map);
   160       return *this;
   156       return *this;
   161     }
   157     }
   162 
   158 
   163     /// \brief Add a new node map writer command for the writer.
   159     /// \brief Add a new node map writer command for the writer.
   164     ///
   160     ///
   165     /// Add a new node map writer command for the writer.
   161     /// Add a new node map writer command for the writer.
   166     template <typename Writer, typename Map>
   162     template <typename Writer, typename Map>
   167     GraphWriter& writeNodeMap(std::string name, const Map& map, 
   163     GraphWriter& writeNodeMap(std::string name, const Map& map, 
   168 			     const Writer& writer = Writer()) {
   164 			      const Writer& writer = Writer()) {
   169       nodeset_writer.writeMap(name, map, writer);
   165       nodeset_writer.writeNodeMap(name, map, writer);
   170       return *this;
   166       return *this;
   171     }
   167     }
   172 
   168 
   173 
   169 
   174     /// \brief Add a new edge map writer command for the writer.
   170     /// \brief Add a new edge map writer command for the writer.
   175     ///
   171     ///
   176     /// Add a new edge map writer command for the writer.
   172     /// Add a new edge map writer command for the writer.
   177     template <typename Map>
   173     template <typename Map>
   178     GraphWriter& writeEdgeMap(std::string name, const Map& map) { 
   174     GraphWriter& writeEdgeMap(std::string name, const Map& map) { 
   179       edgeset_writer.writeMap(name, map);
   175       edgeset_writer.writeEdgeMap(name, map);
   180       return *this;
   176       return *this;
   181     }
   177     }
   182 
   178 
   183 
   179 
   184     /// \brief Add a new edge map writer command for the writer.
   180     /// \brief Add a new edge map writer command for the writer.
   185     ///
   181     ///
   186     /// Add a new edge map writer command for the writer.
   182     /// Add a new edge map writer command for the writer.
   187     template <typename Writer, typename Map>
   183     template <typename Writer, typename Map>
   188     GraphWriter& writeEdgeMap(std::string name, const Map& map,
   184     GraphWriter& writeEdgeMap(std::string name, const Map& map,
   189 			     const Writer& writer = Writer()) {
   185 			      const Writer& writer = Writer()) {
   190       edgeset_writer.writeMap(name, map, writer);
   186       edgeset_writer.writeEdgeMap(name, map, writer);
   191       return *this;
   187       return *this;
   192     }
   188     }
   193 
   189 
   194     /// \brief Add a new labeled node writer for the writer.
   190     /// \brief Add a new labeled node writer for the writer.
   195     ///
   191     ///
   244 
   240 
   245   private:
   241   private:
   246 
   242 
   247     LemonWriter* writer;
   243     LemonWriter* writer;
   248     bool own_writer;
   244     bool own_writer;
   249 
       
   250     const Graph& graph;
       
   251 
   245 
   252     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   246     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
   253     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   247     EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
   254 
   248 
   255     NodeWriter<Graph> node_writer;
   249     NodeWriter<Graph> node_writer;
   358     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   352     IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
   359     writer.writeEdgeMap("id", edgeIdMap);
   353     writer.writeEdgeMap("id", edgeIdMap);
   360     writer.run();
   354     writer.run();
   361   }
   355   }
   362 
   356 
       
   357   /// \brief The undirected graph writer class.
       
   358   ///
       
   359   /// The \c UndirGraphWriter class provides the undir graph output. To write 
       
   360   /// a graph you should first give writing commands for the writer. You can 
       
   361   /// declare write command as \c NodeMap, \c EdgeMap or \c UndirEdgeMap 
       
   362   /// writing and labeled Node, Edge or UndirEdge writing.
       
   363   ///
       
   364   /// \code
       
   365   /// UndirGraphWriter<UndirListGraph> writer(std::cout, graph);
       
   366   /// \endcode
       
   367   ///
       
   368   /// The \c writeNodeMap() function declares a \c NodeMap writing 
       
   369   /// command in the \c UndirGraphWriter. You should give as parameter 
       
   370   /// the name of the map and the map object. The NodeMap writing 
       
   371   /// command with name "id" should write a unique map because it 
       
   372   /// is regarded as ID map.
       
   373   ///
       
   374   /// \code
       
   375   /// IdMap<UndirListGraph, Node> nodeIdMap;
       
   376   /// writer.writeNodeMap("id", nodeIdMap);
       
   377   ///
       
   378   /// writer.writeNodeMap("coords", coords);
       
   379   /// writer.writeNodeMap("color", colorMap);
       
   380   /// \endcode
       
   381   ///
       
   382   /// With the \c writeUndirEdgeMap() member function you can give an 
       
   383   /// undirected edge map writing command similar to the NodeMaps.
       
   384   ///
       
   385   /// \code
       
   386   /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
       
   387   ///   edgeDescMap(graph);
       
   388   /// writer.writeUndirEdgeMap("descriptor", edgeDescMap);
       
   389   ///
       
   390   /// writer.writeUndirEdgeMap("weight", weightMap);
       
   391   /// writer.writeUndirEdgeMap("label", labelMap);
       
   392   /// \endcode
       
   393   /// 
       
   394   /// The EdgeMap handling is just a syntactical sugar. It writes
       
   395   /// two undirected edge map with '+' and '-' prefix in the name.
       
   396   ///
       
   397   /// \code
       
   398   /// writer.writeEdgeMap("capacity", capacityMap);
       
   399   /// \endcode
       
   400   ///
       
   401   ///
       
   402   /// With \c writeNode() and \c writeUndirEdge() functions you can 
       
   403   /// point out nodes and undirected edges in the graph. By example, you can 
       
   404   /// write out the source and target of the graph.
       
   405   ///
       
   406   /// \code
       
   407   /// writer.writeNode("source", sourceNode);
       
   408   /// writer.writeNode("target", targetNode);
       
   409   ///
       
   410   /// writer.writeUndirEdge("observed", undirEdge);
       
   411   /// \endcode
       
   412   ///
       
   413   /// After you give all write commands you must call the \c run() member
       
   414   /// function, which execute all the writer commands.
       
   415   ///
       
   416   /// \code
       
   417   /// writer.run();
       
   418   /// \endcode
       
   419   ///
       
   420   /// \see DefaultWriterTraits
       
   421   /// \see QuotedStringWriter
       
   422   /// \see IdMap
       
   423   /// \see DescriptorMap
       
   424   /// \see \ref GraphWriter
       
   425   /// \see \ref graph-io-page
       
   426   /// \author Balazs Dezso
       
   427   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
       
   428   class UndirGraphWriter {
       
   429   public:
       
   430     
       
   431     typedef _Graph Graph;
       
   432     typedef typename Graph::Node Node;
       
   433     typedef typename Graph::Edge Edge;
       
   434     typedef typename Graph::UndirEdge UndirEdge;
       
   435 
       
   436     typedef _WriterTraits WriterTraits;
       
   437 
       
   438     /// \brief Construct a new UndirGraphWriter.
       
   439     ///
       
   440     /// Construct a new UndirGraphWriter. It writes the given graph
       
   441     /// to the given stream.
       
   442     UndirGraphWriter(std::ostream& _os, const Graph& _graph) 
       
   443       : writer(new LemonWriter(_os)), own_writer(true), 
       
   444 	nodeset_writer(*writer, _graph, std::string()),
       
   445 	undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
       
   446 	node_writer(*writer, nodeset_writer, std::string()),
       
   447 	undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
       
   448 	attribute_writer(*writer, std::string()) {}
       
   449 
       
   450     /// \brief Construct a new UndirGraphWriter.
       
   451     ///
       
   452     /// Construct a new UndirGraphWriter. It writes into the given graph
       
   453     /// to the given file.
       
   454     UndirGraphWriter(const std::string& _filename, const Graph& _graph) 
       
   455       : writer(new LemonWriter(_filename)), own_writer(true), 
       
   456 	nodeset_writer(*writer, _graph, std::string()),
       
   457 	undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
       
   458 	node_writer(*writer, nodeset_writer, std::string()),
       
   459 	undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
       
   460 	attribute_writer(*writer, std::string()) {}
       
   461 
       
   462     /// \brief Construct a new UndirGraphWriter.
       
   463     ///
       
   464     /// Construct a new UndirGraphWriter. It writes into the given graph
       
   465     /// to given LemonReader.
       
   466     UndirGraphWriter(LemonWriter& _writer, const Graph& _graph)
       
   467       : writer(_writer), own_writer(false), 
       
   468 	nodeset_writer(*writer, _graph, std::string()),
       
   469 	undir_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
       
   470 	node_writer(*writer, nodeset_writer, std::string()),
       
   471 	undir_edge_writer(*writer, undir_edgeset_writer, std::string()),
       
   472 	attribute_writer(*writer, std::string()) {}
       
   473 
       
   474     /// \brief Destruct the graph writer.
       
   475     ///
       
   476     /// Destruct the graph writer.
       
   477     ~UndirGraphWriter() {
       
   478       if (own_writer) 
       
   479 	delete writer;
       
   480     }
       
   481 
       
   482     /// \brief Add a new node map writer command for the writer.
       
   483     ///
       
   484     /// Add a new node map writer command for the writer.
       
   485     template <typename Map>
       
   486     UndirGraphWriter& writeNodeMap(std::string name, const Map& map) {
       
   487       nodeset_writer.writeNodeMap(name, map);
       
   488       return *this;
       
   489     }
       
   490 
       
   491     /// \brief Add a new node map writer command for the writer.
       
   492     ///
       
   493     /// Add a new node map writer command for the writer.
       
   494     template <typename Writer, typename Map>
       
   495     UndirGraphWriter& writeNodeMap(std::string name, const Map& map, 
       
   496 			      const Writer& writer = Writer()) {
       
   497       nodeset_writer.writeNodeMap(name, map, writer);
       
   498       return *this;
       
   499     }
       
   500 
       
   501     /// \brief Add a new edge map writer command for the writer.
       
   502     ///
       
   503     /// Add a new edge map writer command for the writer.
       
   504     template <typename Map>
       
   505     UndirGraphWriter& writeEdgeMap(std::string name, const Map& map) { 
       
   506       undir_edgeset_writer.writeEdgeMap(name, map);
       
   507       return *this;
       
   508     }
       
   509 
       
   510     /// \brief Add a new edge map writer command for the writer.
       
   511     ///
       
   512     /// Add a new edge map writer command for the writer.
       
   513     template <typename Writer, typename Map>
       
   514     UndirGraphWriter& writeEdgeMap(std::string name, const Map& map,
       
   515 				   const Writer& writer = Writer()) {
       
   516       undir_edgeset_writer.writeEdgeMap(name, map, writer);
       
   517       return *this;
       
   518     }
       
   519 
       
   520     /// \brief Add a new undirected edge map writer command for the writer.
       
   521     ///
       
   522     /// Add a new undirected edge map writer command for the writer.
       
   523     template <typename Map>
       
   524     UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map) { 
       
   525       undir_edgeset_writer.writeUndirEdgeMap(name, map);
       
   526       return *this;
       
   527     }
       
   528 
       
   529     /// \brief Add a new undirected edge map writer command for the writer.
       
   530     ///
       
   531     /// Add a new edge undirected map writer command for the writer.
       
   532     template <typename Writer, typename Map>
       
   533     UndirGraphWriter& writeUndirEdgeMap(std::string name, const Map& map,
       
   534 					const Writer& writer = Writer()) {
       
   535       undir_edgeset_writer.writeUndirEdgeMap(name, map, writer);
       
   536       return *this;
       
   537     }
       
   538 
       
   539     /// \brief Add a new labeled node writer for the writer.
       
   540     ///
       
   541     /// Add a new labeled node writer for the writer.
       
   542     UndirGraphWriter& writeNode(std::string name, const Node& node) {
       
   543       node_writer.writeNode(name, node);
       
   544       return *this;
       
   545     }
       
   546 
       
   547     /// \brief Add a new labeled edge writer for the writer.
       
   548     ///
       
   549     /// Add a new labeled edge writer for the writer.
       
   550     UndirGraphWriter& writeUndirEdge(std::string name, const UndirEdge& edge) {
       
   551       undir_edge_writer.writeUndirEdge(name, edge);
       
   552     }
       
   553 
       
   554     /// \brief Add a new attribute writer command.
       
   555     ///
       
   556     ///  Add a new attribute writer command.
       
   557     template <typename Value>
       
   558     UndirGraphWriter& writeAttribute(std::string name, const Value& value) {
       
   559       attribute_writer.writeAttribute(name, value);
       
   560       return *this;
       
   561     }
       
   562     
       
   563     /// \brief Add a new attribute writer command.
       
   564     ///
       
   565     ///  Add a new attribute writer command.
       
   566     template <typename Writer, typename Value>
       
   567     UndirGraphWriter& writeAttribute(std::string name, const Value& value, 
       
   568 			       const Writer& writer) {
       
   569       attribute_writer.writeAttribute<Writer>(name, value, writer);
       
   570       return *this;
       
   571     }
       
   572 
       
   573     /// \brief Conversion operator to LemonWriter.
       
   574     ///
       
   575     /// Conversion operator to LemonWriter. It make possible
       
   576     /// to access the encapsulated \e LemonWriter, this way
       
   577     /// you can attach to this writer new instances of 
       
   578     /// \e LemonWriter::SectionWriter.
       
   579     operator LemonWriter&() {
       
   580       return *writer;
       
   581     }
       
   582 
       
   583     /// \brief Executes the writer commands.
       
   584     ///
       
   585     /// Executes the writer commands.
       
   586     void run() {
       
   587       writer->run();
       
   588     }
       
   589 
       
   590   private:
       
   591 
       
   592     LemonWriter* writer;
       
   593     bool own_writer;
       
   594 
       
   595     NodeSetWriter<Graph, WriterTraits> nodeset_writer;
       
   596     UndirEdgeSetWriter<Graph, WriterTraits> undir_edgeset_writer;
       
   597 
       
   598     NodeWriter<Graph> node_writer;
       
   599     UndirEdgeWriter<Graph> undir_edge_writer;
       
   600     
       
   601     AttributeWriter<WriterTraits> attribute_writer;
       
   602   };
       
   603 
       
   604 
       
   605   /// \brief Write an undirected graph to the output.
       
   606   ///
       
   607   /// Write an undirected graph to the output.
       
   608   /// \param os The output stream.
       
   609   /// \param g The graph.
       
   610   /// \param capacity The capacity undirected map.
       
   611   template<typename Graph, typename CapacityMap>
       
   612   void writeUndirGraph(std::ostream& os, const Graph &g, 
       
   613 		       const CapacityMap& capacity) {
       
   614     UndirGraphWriter<Graph> writer(os, g);
       
   615     writer.writeUndirEdgeMap("capacity", capacity);
       
   616     writer.run();
       
   617   }
       
   618 
       
   619   /// \brief Write an undirected graph to the output.
       
   620   ///
       
   621   /// Write an undirected graph to the output.
       
   622   /// \param os The output stream.
       
   623   /// \param g The graph.
       
   624   template<typename Graph>
       
   625   void writeUndirGraph(std::ostream& os, const Graph &g) {
       
   626     UndirGraphWriter<Graph> writer(os, g);
       
   627     writer.run();
       
   628   }
       
   629 
   363   /// @}
   630   /// @}
   364 
   631 
   365 }
   632 }
   366 
   633 
   367 #endif
   634 #endif