c++boostgraphboost-graphboost-property-map

Writing boost dynamic properties to a file using Boost Graph Library


I have already asked a question here about using Boost Graph Library and writing graph into file. Due to change in my requirements, I need to write dynamic graph properties into a DOT file. After some look up, I managed to come up with some code but it does not work. Below is what I have done so far:

Map class uses the Cell class as vertices and Cell class uses a separate CellProperty class for setting and getting all the Cell properties.

And finally Map class where I build the graph and try to write the graph into a DOT file.

Map.h

class Map {
 public:
  typedef boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS, Cell> Graph;
  typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;

  explicit Map(std::string pGraphFilePath);
  virtual ~Map();
  void LoadGraph();
 private:
  Graph mGraph;
  std::vector<std::vector<Vertex>> mGrid;
};

Map.cpp

const unsigned int RowNum = 3;
const unsigned int ColumnNum = 4;

Map::Map(std::string pGraphFilePath) : mGraph(), mGrid() {}
Map::~Map() {}

void Map::LoadGraph() {
  int dummyID = 1;
  for (unsigned int row = 0; row < RowNum; row++) {
    mGrid.resize(RowNum);
    for (unsigned int col = 0; col < ColumnNum; col++) {
      mGrid[row].resize(ColumnNum);

      Vertex vID = boost::add_vertex(mGraph);
      mGraph[vID].SetProperty<unsigned int>("ID", dummyID);
      mGraph[vID].SetProperty<bool>("Navigable", true);
      mGrid[row][col] = vID;
      dummyID++;
      // add the edges for the contained cells in the grid
      if (col > 0) { boost::add_edge(mGrid[row][col - 1], mGrid[row][col], mGraph); }
      if (row > 0) { boost::add_edge(mGrid[row - 1][col], mGrid[row][col], mGraph); }
    }
  }

  // write cell properties
  boost::dynamic_properties propertiesOutPut;

  propertiesOutPut.property("ID", boost::get(boost::vertex_index, mGraph));

  // As Navigable is an external property, it need to be mapped with the internal graph property
  // the lines below are the update after I got the answers and link for my query
  // cell.GetProperty() is a templated method the takes a default parameter, thus passing "false" bool parameter which returns the "Navigable" cell property
  auto valueNavigable = boost::make_transform_value_property_map([](Cell &cell) { return cell.GetProperty<bool>("Navigable", false); }, boost::get(boost::vertex_bundle, mGraph));
  propertiesOutPut.property("Navigable", valueNavigable);

  std::ofstream fout("MyGraph.dot");
  boost::write_graphviz_dp(fout, mGraph, propertiesOutPut, std::string("ID"));
}

The problem I am getting is with the propertiesOutPut.property() method for boost::get(). I can not figure out the correct parameters for boost::get(). Please help me out. Thanks !!


Solution

  • You could use a transform_value_property_map on top of the propertymap that contains the vertex properties struct. (You didn't show it).

    I have a number of answers showing how to do that, although these are all using internal properties, there is no big difference because anu property map can be transformed in the same way, regardless of whether the property map is internal or external (that's the whole purpose of property maps: decoupling the way properties are accessed).

    Most relevant:

    Other: