如何保持boost::readgraphviz读取图形的所有属性?

如何保持boost::readgraphviz读取图形的所有属性?,graphviz,Graphviz,假设您想将.dot图读入boost,其中可能有您无法识别的属性。忽略它们很容易(通过将ignore_其他_属性传递给dynamic_properties构造函数),但是如果您希望将所有属性添加到dynamic_属性,该怎么办 下面的代码演示了这个问题。handle_custom_属性是ignore_other_属性的副本,代码将编译/运行,报告“3个顶点,2个边”。需要添加什么来处理_custom_属性,以便在返回时,dp将包含属性“label”,而节点a的label属性值为“x” #inclu

假设您想将.dot图读入boost,其中可能有您无法识别的属性。忽略它们很容易(通过将ignore_其他_属性传递给dynamic_properties构造函数),但是如果您希望将所有属性添加到dynamic_属性,该怎么办

下面的代码演示了这个问题。handle_custom_属性是ignore_other_属性的副本,代码将编译/运行,报告“3个顶点,2个边”。需要添加什么来处理_custom_属性,以便在返回时,dp将包含属性“label”,而节点a的label属性值为“x”

#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