如何保持boost::readgraphviz读取图形的所有属性?
假设您想将.dot图读入boost,其中可能有您无法识别的属性。忽略它们很容易(通过将ignore_其他_属性传递给dynamic_properties构造函数),但是如果您希望将所有属性添加到dynamic_属性,该怎么办 下面的代码演示了这个问题。handle_custom_属性是ignore_other_属性的副本,代码将编译/运行,报告“3个顶点,2个边”。需要添加什么来处理_custom_属性,以便在返回时,dp将包含属性“label”,而节点a的label属性值为“x”如何保持boost::readgraphviz读取图形的所有属性?,graphviz,Graphviz,假设您想将.dot图读入boost,其中可能有您无法识别的属性。忽略它们很容易(通过将ignore_其他_属性传递给dynamic_properties构造函数),但是如果您希望将所有属性添加到dynamic_属性,该怎么办 下面的代码演示了这个问题。handle_custom_属性是ignore_other_属性的副本,代码将编译/运行,报告“3个顶点,2个边”。需要添加什么来处理_custom_属性,以便在返回时,dp将包含属性“label”,而节点a的label属性值为“x” #inclu
#include <iostream>
#include <string>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/exception/exception.hpp>
#include <boost/exception/diagnostic_information.hpp>
struct vertex_p {
std::string node_id;
};
typedef boost::adjacency_list < boost::vecS, boost::vecS, boost::undirectedS, vertex_p> graph_t;
boost::shared_ptr<boost::dynamic_property_map>
handle_custom_properties(const std::string& s,
const boost::any& k,
const boost::any& v) {
// What goes in here to add dynamic property map for property "s" which key-value pair <k,v>?
// What ignore_other_properties does
return boost::shared_ptr<boost::dynamic_property_map>();
}
int main() {
std::string str(R"(graph {
A [ label="x" ]
B
C
A -- B
A -- C
}
)");
try {
graph_t g;
boost::dynamic_properties dp{handle_custom_properties};
dp.property("node_id", get(&vertex_p::node_id, g));
if (boost::read_graphviz(str, g, dp)) {
std::cout << "read_graphviz returned success" << std::endl;
std::cout << "graph stats:" << std::endl;
std::cout << " " << g.m_vertices.size() << " vertices" << std::endl;
std::cout << " " << g.m_edges.size() << " edges" << std::endl;
}
else {
std::cout << "read_graphviz returned failure" << std::endl;
}
}
catch (std::exception& e) {
std::cerr << e.what() << std::endl;
}
catch (boost::exception& e) {
std::cerr << boost::diagnostic_information(e) << std::endl;
}
}
#包括
#包括
#包括
#包括
#包括
#包括
结构顶点{
std::字符串节点\u id;
};
typedef boost::邻接列表图;
boost::共享\u ptr
句柄自定义属性(const std::string&s,
const boost::any&k,
const boost::any&v){
//这里是什么为属性“s”添加动态属性映射的?哪个键值对?
//忽略其他属性的作用是什么
返回boost::shared_ptr();
}
int main(){
字符串str(R)(图{
A[label=“x”]
B
C
A--B
A--C
}
)");
试一试{
图g;
boost::dynamic_properties dp{handle_custom_properties};
属性(“node_id”,get(&vertex_p::node_id,g));
if(boost::read_graphviz(str,g,dp)){
std::cout我无法找到一个现有的类来解决这个问题,但是根据std::map实现一个动态属性映射是可行的:
template<typename TKey, typename TValue>
class dynamic_property_map_impl : public boost::dynamic_property_map {
std::map<TKey, TValue> map_;
public:
boost::any get(const boost::any& key) override { return map_[boost::any_cast<TKey>(key)]; }
std::string get_string(const boost::any& key) override { std::ostringstream s; s << map_[boost::any_cast<TKey>(key)]; return s.str(); }
void put(const boost::any& key, const boost::any& value) override { map_[boost::any_cast<TKey>(key)] = boost::any_cast<TValue>(value); }
const std::type_info& key() const override { return typeid(TKey); }
const std::type_info& value() const override { return typeid(TValue); }
};
boost::shared_ptr<boost::dynamic_property_map>
handle_custom_properties(const std::string&,
const boost::any&,
const boost::any&) {
return boost::make_shared<dynamic_property_map_impl<unsigned, std::string>>();
}
std::string str(R"(graph {
A [ label="x", stuff="y" ]
B
C [ happy="yes" ]
A -- B
A -- C
}
)");
...
std::cout << "properties:" << std::endl;
for (const auto& p : dp) {
std::cout << " " << p.first << std::endl;
}
read_graphviz returned success
graph stats:
3 vertices
2 edges
properties:
happy
label
node_id
stuff