Search code examples
c++gml-geographic-markup-lanogdf

Maintaining GraphAttributes with GraphCopy::initByCC in OGDF


I am trying to use OGDF to perform some processing on graphs loaded from GML files. These graphs are only meaningful if the node labels are maintained. Unfortunately, OGDF does not make it easy to keep node attributes like labels, since they are maintained in a separate data structure called GraphAttributes. My problem is that GraphAttributes associates node labels with node indices, which are not maintained by some of the graph transformations I need to use.

One of the transformations I need to perform on the Graphs is to split up each connected subgraph in a GML file. Loading the graph and its node labels is simple:

ogdf::Graph graph;
ogdf::GraphAttributes attributes(graph, ogdf::GraphAttributes::nodeLabel);
ogdf::GraphIO::readGML(attributes, graph, FILENAME);

// this gives the correct label of the first node in the graph
attributes.label(graph.firstNode());

Similarly, OGDF provide the CCsInfo class to find the connected subgraphs of a graph. Since, I want to work with these subgraphs independently, I use the GraphCopy::initByCC method to create separate Graph instances.

ogdf::CCsInfo info(graph);
ogdf::GraphCopy copy(graph);
ogdf::EdgeArray< ogdf::edge > edgeArray(graph);
// where i (int) is the number of the connected subgraph to copy
copy.initByCC(info, i, edgeArray);

// this now gives the wrong label for the first node in copy
attributes.label(copy.firstNode());

This works, and copy contains only the nodes and edges of the connected subgraph. However, the indices of the nodes in the copy are different from the indices of the nodes in the original graph. This means that the mapping of labels to nodes in the attributes object do not apply to the nodes in copy.

Is there a way to perform the same transformation on the attributes object so that I can get the correct labels for the nodes in the copied connected subgraph?


Solution

  • It turns out this isn't as difficult as I thought. The key piece I was missing is that you can use the GraphCopy::original method to get the node with the index from the original graph and then use that node to get the label.

    // get the correct label for the first node of the GraphCopy object copy
    attributes.label(copy.original(copy.firstNode()));