VWED_server/services/map_tools/extract_scene_points_mapping.py

178 lines
5.4 KiB
Python
Raw Normal View History

2025-09-25 10:52:52 +08:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Scene文件点位映射表提取器
.scene文件中提取points字段的站点名称name和id的映射关系
"""
import json
import csv
import os
import sys
from datetime import datetime
import argparse
class ScenePointsExtractor:
def __init__(self):
self.scene_data = None
self.points_mapping = []
def load_scene_file(self, scene_path):
"""加载Scene文件"""
try:
with open(scene_path, 'r', encoding='utf-8') as f:
self.scene_data = json.load(f)
print(f"Scene文件加载成功: {scene_path}")
return True
except FileNotFoundError:
print(f"文件不存在: {scene_path}")
return False
except json.JSONDecodeError as e:
print(f"Scene文件格式错误: {e}")
return False
except Exception as e:
print(f"加载Scene文件失败: {e}")
return False
def extract_points_mapping(self):
"""提取points字段的映射关系"""
if not self.scene_data or 'points' not in self.scene_data:
print("Scene数据中未找到points字段")
return False
points = self.scene_data['points']
if not points:
print("points字段为空")
return False
print(f"开始提取站点映射关系,共{len(points)}个站点")
self.points_mapping = []
for i, point in enumerate(points, 1):
mapping = {
'sequence': i,
'name': point.get('name', ''),
'id': point.get('id', '')
}
self.points_mapping.append(mapping)
print(f"站点映射提取完成,共{len(self.points_mapping)}个站点")
return True
def generate_csv_report(self, output_path):
"""生成CSV格式的映射表"""
if not self.points_mapping:
print("没有映射数据可导出")
return False
try:
with open(output_path, 'w', newline='', encoding='utf-8-sig') as csvfile:
fieldnames = ['sequence', 'name', 'id']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
# 写入表头
writer.writeheader()
# 写入数据
for mapping in self.points_mapping:
writer.writerow(mapping)
print(f"CSV映射表生成完成: {output_path}")
return True
except Exception as e:
print(f"生成CSV文件失败: {e}")
return False
def print_summary(self):
"""打印映射关系摘要"""
if not self.points_mapping:
print("没有映射数据")
return
print("\n" + "=" * 60)
print("站点映射摘要")
print("=" * 60)
print(f"总站点数: {len(self.points_mapping)}")
# 显示前10个站点示例
print(f"\n前10个站点示例:")
print(f"{'序号':<6} {'名称':<20} {'ID':<15}")
print("-" * 45)
for i, mapping in enumerate(self.points_mapping[:10]):
print(f"{mapping['sequence']:<6} {mapping['name']:<20} {mapping['id']:<15}")
if len(self.points_mapping) > 10:
print(f"... 还有 {len(self.points_mapping) - 10} 个站点")
print("=" * 60)
def process(self, scene_path, output_dir="output"):
"""处理Scene文件并生成映射表"""
self.source_file = scene_path
print("开始提取Scene文件站点映射")
print("=" * 60)
# 1. 加载Scene文件
if not self.load_scene_file(scene_path):
return False
# 2. 提取映射关系
if not self.extract_points_mapping():
return False
# 3. 打印摘要
self.print_summary()
# 4. 创建输出目录
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 5. 生成CSV格式的报告
scene_name = os.path.splitext(os.path.basename(scene_path))[0]
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
# CSV格式
csv_path = os.path.join(output_dir, f"{scene_name}_PointsMapping_{timestamp}.csv")
self.generate_csv_report(csv_path)
print("\n" + "=" * 60)
print("处理完成!生成的文件:")
print(f"CSV格式: {csv_path}")
print("=" * 60)
return True
def main():
parser = argparse.ArgumentParser(description='Scene文件站点映射表提取器')
parser.add_argument('scene_path', help='Scene文件路径')
parser.add_argument('-o', '--output', default='output', help='输出目录(默认: output')
args = parser.parse_args()
# 检查Scene文件是否存在
if not os.path.exists(args.scene_path):
print(f"Scene文件不存在: {args.scene_path}")
sys.exit(1)
# 创建提取器并处理
extractor = ScenePointsExtractor()
success = extractor.process(args.scene_path, args.output)
if success:
print("\n✅ 提取成功完成!")
sys.exit(0)
else:
print("\n❌ 提取失败!")
sys.exit(1)
if __name__ == "__main__":
main()