181 lines
8.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import os
class SceneEnricher:
def __init__(self, scene_file, scene_ref_file):
self.scene_file = scene_file
self.scene_ref_file = scene_ref_file
self.scene_data = self.load_json(scene_file)
self.scene_ref_data = self.load_json(scene_ref_file)
def load_json(self, file_path):
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
else:
print(f"警告: 文件 {file_path} 不存在")
return {}
def save_scene(self, output_file=None):
if not output_file:
output_file = self.scene_file
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(self.scene_data, f, indent=2, ensure_ascii=False)
print(f"已保存补全后的scene到: {output_file}")
def update_points_robots(self):
if 'points' not in self.scene_data or not self.scene_data['points']:
print("scene_data['points'] 为空无法更新robots字段")
return
scene_points = {p['name']: p for p in self.scene_ref_data.get('points', [])}
update_count = 0
for point in self.scene_data['points']:
name = point.get('name')
if name in scene_points:
robots = scene_points[name].get('robots')
if robots:
point['robots'] = robots
update_count += 1
print(f"已同步 {update_count} 个点的robots字段到输出points中")
def update_area_points(self):
if 'areas' not in self.scene_data or not self.scene_data['areas']:
print("scene_data['areas'] 为空无法更新区域points")
return
scene_areas = {a['id']: a for a in self.scene_ref_data.get('areas', [])}
update_count = 0
for area in self.scene_data['areas']:
area_id = area.get('id')
area_type = area.get('type')
if area_type != 1 and area_id in scene_areas:
scene_points = scene_areas[area_id].get('points')
if scene_points is not None:
area['points'] = scene_points
update_count += 1
print(f"已为 {update_count} 个区域同步scene_file中的points")
def update_points_with_brand_type(self):
bin_locations_file = os.path.join('converted', 'binLocationsList.json')
if not os.path.exists(bin_locations_file):
print(f"未找到 {bin_locations_file}跳过brand/type补全")
return
with open(bin_locations_file, 'r', encoding='utf-8') as f:
bin_data = json.load(f)
scene_points = {p['name']: p for p in self.scene_ref_data.get('points', [])}
point_brand_type = {}
for group in bin_data.get('binLocationsList', []):
for loc in group.get('binLocationList', []):
point_name = loc.get('pointName')
scene_point = scene_points.get(point_name)
if scene_point:
brand = scene_point.get('brand')
type_ = scene_point.get('type')
if brand is not None and type_ is not None:
point_brand_type[point_name] = {'brand': brand, 'type': type_}
update_count = 0
for point in self.scene_data['points']:
name = point.get('name')
if name in point_brand_type:
brand = point_brand_type[name]['brand']
type_ = point_brand_type[name]['type']
point['brand'] = brand
point['type'] = type_
update_count += 1
print(f"已为 {update_count} 个点增加brand/type字段")
def update_point_types(self):
if 'points' not in self.scene_data or not self.scene_data['points']:
print("scene_data['points'] 为空,无法更新点类型")
return
scene_points = {p['name']: p for p in self.scene_ref_data.get('points', [])}
update_count = 0
for point in self.scene_data['points']:
if point.get('type') == 1:
name = point.get('name')
if name in scene_points:
scene_type = scene_points[name].get('type')
if scene_type is not None and point['type'] != scene_type:
point['type'] = scene_type
update_count += 1
print(f"已同步 {update_count} 个点的type到scene_file中的值")
def update_routes_pass(self):
"""
遍历scene_file中routes字段下的路径将scene_ref_file中的对应路径下的pass的值映射到最终生成的output_file中去
"""
if 'routes' not in self.scene_data or not self.scene_data['routes']:
print("scene_data['routes'] 为空无法更新路径pass字段")
return
# 建立参考文件中路径的映射关系根据desc字段
scene_ref_routes_by_desc = {}
for route in self.scene_ref_data.get('routes', []):
desc = route.get('desc')
if desc:
scene_ref_routes_by_desc[desc] = route
print(f"参考文件中找到 {len(self.scene_ref_data.get('routes', []))} 条路径")
print(f"当前文件中有 {len(self.scene_data['routes'])} 条路径")
print(f"建立了 {len(scene_ref_routes_by_desc)} 个描述映射关系")
update_count = 0
for route in self.scene_data['routes']:
desc = route.get('desc')
if desc and desc in scene_ref_routes_by_desc:
ref_route = scene_ref_routes_by_desc[desc]
ref_pass = ref_route.get('pass')
if ref_pass is not None:
route['pass'] = ref_pass
update_count += 1
if update_count <= 5: # 只显示前5个匹配
print(f"匹配路径描述: {desc}, pass值: {ref_pass}")
print(f"已同步 {update_count} 条路径的pass字段到输出routes中")
def enrich(self, output_file=None):
# 若 areas 为空,则从参考文件补全
if ('areas' not in self.scene_data or not self.scene_data['areas']) and \
('areas' in self.scene_ref_data and self.scene_ref_data['areas']):
print("scene_data['areas'] 为空自动从参考文件补全areas字段")
self.scene_data['areas'] = self.scene_ref_data['areas'].copy()
# 优先从 scene_file 读取 robotGroups 和 robots 字段,如果为空则从 scene_ref_file 读取补全
robotGroups = []
robots = []
if os.path.exists(self.scene_file):
with open(self.scene_file, 'r', encoding='utf-8') as f:
scene_origin = json.load(f)
robotGroups = scene_origin.get('robotGroups', [])
robots = scene_origin.get('robots', [])
# 如果为空则从参考文件补全
if not robotGroups and 'robotGroups' in self.scene_ref_data:
robotGroups = self.scene_ref_data['robotGroups']
print("robotGroups 字段为空,已从参考文件补全")
if not robots and 'robots' in self.scene_ref_data:
robots = self.scene_ref_data['robots']
print("robots 字段为空,已从参考文件补全")
self.scene_data['robotGroups'] = robotGroups
self.scene_data['robots'] = robots
self.update_points_robots()
self.update_area_points()
self.update_points_with_brand_type()
self.update_point_types()
self.update_routes_pass()
self.save_scene(output_file)
def main():
scene_file = "converted_test.scene"
scene_ref_file = "现场测试地图-0819 (1).scene"
output_file = "converted_scene.scene" # 可自定义输出
enricher = SceneEnricher(scene_file, scene_ref_file)
print("=== 场景补全器 ===")
print("执行字段补全...")
print("-" * 50)
enricher.enrich(output_file)
print("补全完成!")
if __name__ == "__main__":
main()