in MyGraphBuilder Class I'm facing some Problems During My Implementation of the Graph property assignment:
G:\QT\Projects\My Project\boost\graph\detail\adjacency_list.hpp:2700: error: forming reference to void
typedef value_type& reference;
G:\QT\Projects\MY Project\boost\graph\dijkstra_shortest_paths.hpp:588: error: no matching function for call to 'choose_const_pmap(const type&, const boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertProperty, EdgeProperty>&, boost::edge_weight_t)'
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
Also When I used The Print Function to just Print The Count of Nodes and Edges, it Counted Nodes Only, but the Count of Edges Showed '0' can you tell me what is the problem please ?
#ifndef MYGRAPHBUILDER_H
#define MYGRAPHBUILDER_H
// Generic Libraries
//===============================================
#include <iostream>
#include <vector>
#include <map>
// Boost Libraries
//===============================================
#include <boost/config.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/graph_utility.hpp>
// MyColleague Libraries
//===============================================
#include <modelDataStructure.h>
#include <modelDataHandler.h>
#include <modeldata.h>
#include <model.h>
// Osmium Libraries
//===============================================
#include <osmium/osm.hpp>
#include <osmium/index/map/flex_mem.hpp>
#include <osmium/visitor.hpp>
#include <osmium/osm/location.hpp>
#include <osmium/osm/node_ref.hpp>
//===============================================
using namespace std;
using namespace boost;
//===============================================
typedef osmium::unsigned_object_id_type idType ;
typedef map<idType, wayData> WayMap;//Define map of Ways ans Their ID
//==================================================
struct VertProperty
{
idType id;
osmium::Location loc;
};
struct EdgeProperty
{
double length;
};
typedef adjacency_list < vecS, vecS, directedS,VertProperty,EdgeProperty > graph_t;
typedef graph_traits < graph_t >::vertex_descriptor Vertex; // Vertex declaration
typedef graph_traits < graph_t >::edge_descriptor Edge; // Edge as link between two Nodes specified by ID
//==================================================
class MyGraphBuilder
{
private: // This Line is Useless just for clarity
graph_t MyGraph;
/////////////////////////////////////////////////////////
public:
MyGraphBuilder(); // default Constructor
MyGraphBuilder(Model); // Parameters Constructor
~MyGraphBuilder(); // Destructor
double Distance(idType,idType); // function to calculate the distance between 2 Verices
//===============================================
//Accessors
// function to get the Graph
graph_t getGraph();
//===============================================
// Mutators
void setGraph(graph_t);
//===============================================
void printGraph() const;
//friend class MyAlgorithm;
};//end of the Class
/////////////////////////////////////
#endif // MYGRAPHBUILDER_H
// Generic Libraries
//===============================================
#include <math.h>
// Belal Libraries
//===============================================
#include <mygraphbuilder.h>
// Boost Libraries
//===============================================
using namespace std;
using namespace boost;
/////////////////////////////////////////////////
MyGraphBuilder::MyGraphBuilder() // default Constructor
{
Model OurModel;
WayMap MyWayMap = OurModel.getWayMap();
WayMap::iterator it;
// it->first ;// (key = WayID)
// it->second ;// (Value WayData.nodRefList[idType])
for ( it = MyWayMap.begin(); it != MyWayMap.end(); it++ ) // Loop the Whole Way Map
{
unsigned int NodesOfWayIndex = 0; //define Index
idType VertixID; // define Variable to Store Vertix Index
vector<Vertex> WayNodes(it->second.nodeRefList.size());//define a vector of nodes with size of Way
for(auto j = it->second.nodeRefList.begin(); j != it->second.nodeRefList.end(); ++j){// Loop The Whole Nodes of Each way
VertixID = it->second.nodeRefList.at(NodesOfWayIndex);
//VertixID added as Bundeled property name to the vertex
Vertex v = *vertices(MyGraph).first;
Edge e = *edges(MyGraph).first;
//=======================================================
MyGraph[v].id = VertixID;
MyGraph[v].loc = OurModel.getNodeLoaction(VertixID);
//=======================================================
WayNodes[NodesOfWayIndex] = VertixID;
if(NodesOfWayIndex != 0) {
MyGraph[e].length = Distance(WayNodes[NodesOfWayIndex - 1], WayNodes[NodesOfWayIndex]);
}
}
NodesOfWayIndex++;
}
cout<<"\n\n Graph Was Built ...\n\n";
}
//===========================================================================
MyGraphBuilder::MyGraphBuilder(Model OurModel){ // Parameters Constructor
WayMap MyWayMap = OurModel.getWayMap();
WayMap::iterator it;
// it->first ;// (key = WayID)
// it->second ;// (Value WayData.nodRefList[idType])
for ( it = MyWayMap.begin(); it != MyWayMap.end(); it++ ) // Loop the Whole Way Map
{
unsigned int NodesOfWayIndex = 0; //define Index
idType VertixID; // define Variable to Store Vertix Index
vector<Vertex> WayNodes(it->second.nodeRefList.size());//define a vector of nodes with size of Way
for(auto j = it->second.nodeRefList.begin(); j != it->second.nodeRefList.end(); ++j){// Loop The Whole Nodes of Each way
VertixID = it->second.nodeRefList.at(NodesOfWayIndex);
//VertixID added as Bundeled property name to the vertex
Vertex v = *vertices(MyGraph).first;
Edge e = *edges(MyGraph).first;
//=======================================================
MyGraph[v].id = VertixID;
MyGraph[v].loc = OurModel.getNodeLoaction(VertixID);
//=======================================================
WayNodes[NodesOfWayIndex] = VertixID;
if(NodesOfWayIndex != 0) {
MyGraph[e].length = Distance(WayNodes[NodesOfWayIndex - 1], WayNodes[NodesOfWayIndex]);
}
}
NodesOfWayIndex++;
}
cout<<"\n\n Graph Was Built ...\n\n";
}
MyGraphBuilder::~MyGraphBuilder (){ // default Destructor
}
double MyGraphBuilder::Distance(idType Nod1_ID, idType Nod2_ID){ // Function to calculate Euclidean Distance between Vertices
modelData*m_Data = new modelData;
osmium::Location L1,L2; // define any 2 locations on earth
L1 = m_Data->getNodeLoaction(Nod1_ID) ; // get first location
L2 = m_Data->getNodeLoaction(Nod2_ID) ; // get second location
double dist = 0; // distance
double x1 = L1.lat(); // first location latitude
double x2 = L2.lat(); // second location latitude
double y1 = L1.lon(); // first location longitude
double y2 = L2.lon(); // second location longitude
dist = sqrt(pow((x1-x2),2)+pow((y1-y2),2));
return dist;
}
// Accessors
graph_t MyGraphBuilder::getGraph(){
return MyGraph;
}
// Mutators
void MyGraphBuilder::setGraph(graph_t YourGraph){
MyGraphBuilder::MyGraph = YourGraph;
}
//=========================================
void MyGraphBuilder::printGraph()const{
unsigned long long NodesCount = num_vertices(MyGraph);
cout<<"Number of Vertices is :\t"<<NodesCount<<"\n";
unsigned long long EdgesCount = num_edges(MyGraphBuilder::MyGraph);
cout<<"Number of Edges is :\t"<<EdgesCount<<"\n";
//for (auto v : make_iterator_range(vertices(MyGraph))) {
// cout << "Nodes " << v << " name " << MyGraph[v].name << "\n";
// for (auto oe : make_iterator_range(out_edges(v, MyGraph))) {
// cout << "Edge " << oe << " weight " << MyGraph[oe].weight << "\n";
// }
// }
}
cout << "Nodes " << v << " name " << MyGraph[v].name << "\n";
This syntax asks for the boost::vertex_bundle_t
property, but none exists.
From the documentation:
Class templates
adjacency_list
andadjacency_matrix
support the introduction of named properties via internal properties. However, this method is cumbersome in many uses, where it would be more intuitive to just specify a structure or class that contains internal properties for edges or vertices. Bundled properties allow one to useadjacency_list
andadjacency_matrix
in this manner, providing a simple way to introduce and access any number of internal properties for vertices and edges.
Compare with How can I solve this error in Printing Nodes and Edges Boost Graph Library?, where the vertex property type is a class. This is known as a "bundle property" and they're generally more user-friendly to use.
If you are using the older style of internal properties:
property<vertex_name_t, idType>
You need to access them using property-maps. You can use them with the get
or put
accessor methods:
boost::put(boost::vertex_name, MyGraph, 0, "one");
or grab a propertymap first:
auto name_pmap = boost::get(boost::vertex_name, MyGraph);
name_pmap[0] = "one";
Here's the same example from the previous answer but using internal properties instead of bundles:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_utility.hpp>
#include <iostream>
#include <random>
using idType = std::string; // mock osmium stuff?
using graph_t = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS,
boost::property<boost::vertex_name_t, idType>,
boost::property<boost::edge_weight_t, double> >;
using boost::make_iterator_range;
class MyGraphBuilder {
graph_t MyGraph;
public:
void generate();
void printGraph() const;
};
#include <boost/graph/random.hpp>
void MyGraphBuilder::generate() {
std::mt19937 prng { 42 }; // fixed random seed
generate_random_graph(MyGraph, 5, 5, prng);
boost::put(boost::vertex_name, MyGraph, 0, "one");
// or grab a propertymap first:
auto name_pmap = boost::get(boost::vertex_name, MyGraph);
name_pmap[0] = "one";
name_pmap[1] = "two";
name_pmap[2] = "three";
name_pmap[3] = "four";
name_pmap[4] = "five";
auto weight_pmap = boost::get(boost::edge_weight, MyGraph);
for (auto e : make_iterator_range(edges(MyGraph))) {
weight_pmap[e] = std::uniform_real_distribution<>(1.0, 10.0)(prng);
}
}
void MyGraphBuilder::printGraph() const {
std::cout << "Number of Vertices is:" << num_vertices(MyGraph) << "\n";
std::cout << "Number of Edges is:" << num_edges(MyGraph) << "\n";
print_graph(MyGraph, get(boost::vertex_name, MyGraph), std::cout);
// to print with edge weights:
for (auto v : make_iterator_range(vertices(MyGraph))) {
for (auto oe : make_iterator_range(out_edges(v, MyGraph))) {
std::cout << "Edge " << oe << " weight " << boost::get(boost::edge_weight, MyGraph, oe) << "\n";
}
}
}
int main() {
MyGraphBuilder builder;
builder.generate();
builder.printGraph();
}
Printing:
Number of Vertices is:5
Number of Edges is:5
one -->
two --> four
three --> one one
four --> three
five --> one
Edge (1,3) weight 1.52275
Edge (2,0) weight 8.79559
Edge (2,0) weight 6.41004
Edge (3,2) weight 7.37265
Edge (4,0) weight 1.18526