如何将GraphML文件读取到带自定义顶点属性的Boost图
问题解决:Boost Graph读取GraphML时恢复顶点关节角度属性
核心问题分析
你当前的读取代码存在两个关键错误:
- 字符串分割逻辑失效:保存关节角度时用逗号分隔,但读取时直接使用
ss >> number会在遇到逗号时停止解析,只能读取第一个数值,后续角度值会被丢弃。 - Property Map类型不匹配:读取GraphML时,
dynamic_properties需要的是可写的顶点属性映射,但你定义的function_property_map是从字符串到vector<double>的转换,无法将解析后的值赋值给顶点的joint_angles属性。
修复方案
1. 修复字符串分割函数
重新实现readJointAngles,按逗号分割字符串并转换为vector<double>,同时保证向量长度与默认构造的3个元素一致:
std::vector<double> BoostGraph::readJointAngles(const std::string& joint_angle_string) { std::vector<double> joint_angles; std::stringstream ss(joint_angle_string); std::string token; // 按逗号分割每个角度值 while (std::getline(ss, token, ',')) { try { joint_angles.push_back(std::stod(token)); } catch (const std::invalid_argument&) { // 处理无效格式,这里默认补0,可根据需求调整 joint_angles.push_back(0.0); } catch (const std::out_of_range&) { // 处理数值超出范围的情况 joint_angles.push_back(0.0); } } // 确保向量长度固定为3,与顶点属性的默认构造一致 if (joint_angles.size() < 3) { joint_angles.resize(3, 0.0); } else if (joint_angles.size() > 3) { joint_angles.resize(3); } return joint_angles; }
2. 修正GraphML读取逻辑
使用boost::transform_value_property_map将字符串转换逻辑与顶点属性的可写映射绑定,确保解析后的角度值能正确赋值到顶点属性中:
void BoostGraph::readGraphGraphML(std::istream& file) { // 创建指向顶点joint_angles属性的可写映射 auto joint_angle_ref_map = boost::make_function_property_map<Vertex>( [this](Vertex v) -> std::vector<double>& { return graph[v].joint_angles; }); boost::dynamic_properties dp(boost::ignore_other_properties); // 绑定字符串转换逻辑到顶点属性映射 dp.property("Joint_Angles", boost::transform_value_property_map( [this](const std::string& s) { return readJointAngles(s); }, joint_angle_ref_map ) ); dp.property("edge_weight", boost::get(&EdgeProperties::weight, graph)); boost::read_graphml(file, graph, dp); }
3. 可选:优化保存逻辑(非必须)
原保存代码中无需复制joint_angles向量,直接引用即可:
std::string BoostGraph::vertexJointAngles(Vertex v) { std::ostringstream sstream; const auto& jointAngles = graph[v].joint_angles; for (std::size_t i = 0; i < jointAngles.size(); ++i) { sstream << jointAngles[i]; if (i != jointAngles.size() - 1) { sstream << ','; } } return sstream.str(); }
关键说明
transform_value_property_map的作用是将输入的字符串值通过自定义转换函数转为vector<double>,再赋值给底层的顶点属性映射。boost::ignore_other_properties用于忽略GraphML中自动生成的id等默认属性,避免读取时出现未处理属性的错误。
内容的提问来源于stack exchange,提问作者Samarth Jain
相关产品推荐
相关产品推荐

