178 lines
5.4 KiB
Python
178 lines
5.4 KiB
Python
|
#!/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()
|