2025-09-12 16:15:13 +08:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
"""
|
|
|
|
|
交互式场景转换器 v2.0
|
|
|
|
|
用于指导用户填写必填参数并执行转换流程
|
|
|
|
|
支持Scene转换和华睿地图转换
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
import json
|
|
|
|
|
import logging
|
|
|
|
|
from pathlib import Path
|
2025-09-25 10:52:52 +08:00
|
|
|
|
from services.map_tools.convert_basic import SceneBasicConverter
|
2025-09-12 16:15:13 +08:00
|
|
|
|
|
|
|
|
|
# 设置logger
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def save_uploaded_file(file_obj, filename):
|
|
|
|
|
"""
|
|
|
|
|
保存上传的文件到指定目录
|
|
|
|
|
file_obj: 文件对象或内容
|
|
|
|
|
filename: 保存的文件名
|
|
|
|
|
返回保存后的绝对路径
|
|
|
|
|
"""
|
|
|
|
|
upload_dir = os.path.join(os.path.dirname(__file__), 'map_converter', 'uploads')
|
|
|
|
|
if not os.path.exists(upload_dir):
|
|
|
|
|
os.makedirs(upload_dir)
|
|
|
|
|
save_path = os.path.join(upload_dir, filename)
|
|
|
|
|
# file_obj 可能是文件对象或字节内容
|
|
|
|
|
if hasattr(file_obj, 'read'):
|
|
|
|
|
content = file_obj.read()
|
|
|
|
|
else:
|
|
|
|
|
content = file_obj
|
|
|
|
|
# 如果是bytes则直接写,否则以文本写
|
|
|
|
|
mode = 'wb' if isinstance(content, bytes) else 'w'
|
|
|
|
|
with open(save_path, mode, encoding=None if mode=='wb' else 'utf-8') as f:
|
|
|
|
|
f.write(content)
|
|
|
|
|
return save_path
|
|
|
|
|
|
|
|
|
|
def convert_smap_to_scene(smap_file, scene_file=None):
|
|
|
|
|
"""
|
|
|
|
|
smap_file/scene_file: 可以是文件路径、文件对象或内容
|
|
|
|
|
自动完成scene转换,若scene_file不为空则自动丰富场景
|
|
|
|
|
"""
|
|
|
|
|
import time
|
2025-09-25 10:52:52 +08:00
|
|
|
|
from services.map_tools.convert_basic import SceneBasicConverter
|
2025-09-12 16:15:13 +08:00
|
|
|
|
# 如果传入的是文件对象或内容,则先保存
|
|
|
|
|
if not isinstance(smap_file, str) or not os.path.exists(smap_file):
|
|
|
|
|
smap_path = save_uploaded_file(smap_file, f'smap_{int(time.time())}.smap')
|
|
|
|
|
else:
|
|
|
|
|
smap_path = smap_file
|
|
|
|
|
scene_path = ''
|
|
|
|
|
if scene_file:
|
|
|
|
|
if not isinstance(scene_file, str) or not os.path.exists(scene_file):
|
|
|
|
|
scene_path = save_uploaded_file(scene_file, f'scene_{int(time.time())}.scene')
|
|
|
|
|
else:
|
|
|
|
|
scene_path = scene_file
|
|
|
|
|
|
|
|
|
|
params = {}
|
|
|
|
|
params['smap_file'] = smap_path
|
|
|
|
|
params['scene_file'] = scene_path
|
|
|
|
|
params['scene_id'] = int(time.time())
|
2025-09-25 10:52:52 +08:00
|
|
|
|
|
|
|
|
|
# 第一阶段转换固定使用 converter.scene
|
|
|
|
|
intermediate_output_file = 'converter.scene'
|
|
|
|
|
# 最终输出文件名为smap文件同名的scene文件
|
|
|
|
|
final_output_file = str(Path(smap_path).with_suffix('.scene').name)
|
|
|
|
|
|
|
|
|
|
params['output_file'] = intermediate_output_file
|
|
|
|
|
params['final_output_file'] = final_output_file
|
|
|
|
|
params['scene_name'] = Path(final_output_file).stem
|
2025-09-12 16:15:13 +08:00
|
|
|
|
params['scale'] = 0.66
|
|
|
|
|
params['origin'] = {'x': 0, 'y': 0}
|
|
|
|
|
params['setting'] = ''
|
|
|
|
|
params['ratio'] = 100
|
|
|
|
|
|
|
|
|
|
logger.info("==== 开始Scene转换 ====")
|
|
|
|
|
logger.info(f"SMAP文件: {params['smap_file']}")
|
2025-09-25 10:52:52 +08:00
|
|
|
|
logger.info(f"中间输出文件: {params['output_file']}")
|
|
|
|
|
logger.info(f"最终输出文件: {params['final_output_file']}")
|
2025-09-12 16:15:13 +08:00
|
|
|
|
logger.info(f"场景ID: {params['scene_id']}")
|
|
|
|
|
logger.info(f"场景名称: {params['scene_name']}")
|
|
|
|
|
logger.info(f"比例: {params['scale']}, 原点: {params['origin']}, 设置: {params['setting']}, 比率: {params['ratio']}")
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
converter = SceneBasicConverter(
|
|
|
|
|
scene_id=params['scene_id'],
|
|
|
|
|
setting=params['setting'],
|
|
|
|
|
ratio=params['ratio']
|
|
|
|
|
)
|
|
|
|
|
result = converter.convert_basic(
|
|
|
|
|
smap_file=params['smap_file'],
|
|
|
|
|
scene_file=params['scene_file'],
|
|
|
|
|
output_file=params['output_file']
|
|
|
|
|
)
|
|
|
|
|
# 更新自定义参数
|
|
|
|
|
result['name'] = params['scene_name']
|
|
|
|
|
result['scale'] = params['scale']
|
|
|
|
|
result['origin'] = params['origin']
|
|
|
|
|
with open(params['output_file'], 'w', encoding='utf-8') as f:
|
|
|
|
|
json.dump(result, f, indent=2, ensure_ascii=False)
|
|
|
|
|
# coordinate_system.json
|
|
|
|
|
coordinate_data = {
|
|
|
|
|
'scale': result['scale'],
|
|
|
|
|
'origin': result['origin']
|
|
|
|
|
}
|
|
|
|
|
converted_dir = "converted"
|
|
|
|
|
if not os.path.exists(converted_dir):
|
|
|
|
|
os.makedirs(converted_dir)
|
|
|
|
|
with open(f"{converted_dir}/coordinate_system.json", 'w', encoding='utf-8') as f:
|
|
|
|
|
json.dump(coordinate_data, f, indent=2, ensure_ascii=False)
|
2025-09-25 10:52:52 +08:00
|
|
|
|
logger.info(f"✓ Scene转换完成!中间文件已保存到: {params['output_file']}")
|
2025-09-12 16:15:13 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"✗ Scene转换过程中出现错误: {str(e)}")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 自动丰富场景
|
|
|
|
|
if scene_path:
|
|
|
|
|
try:
|
2025-09-25 10:52:52 +08:00
|
|
|
|
from services.map_tools.enrich_scene import SceneEnricher
|
2025-09-12 16:15:13 +08:00
|
|
|
|
logger.info("==== 自动执行场景丰富化 ====")
|
|
|
|
|
enricher = SceneEnricher(params['output_file'], params['scene_file'])
|
|
|
|
|
enricher.enrich(params['output_file'])
|
|
|
|
|
logger.info("✓ 场景丰富化完成!")
|
2025-09-25 10:52:52 +08:00
|
|
|
|
|
|
|
|
|
# 重新读取场景丰富化后的文件内容,更新返回结果
|
|
|
|
|
try:
|
|
|
|
|
with open(params['output_file'], 'r', encoding='utf-8') as f:
|
|
|
|
|
result = json.load(f)
|
|
|
|
|
logger.info("✓ 已重新加载场景丰富化后的数据")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"✗ 重新加载场景丰富化后数据失败: {str(e)}")
|
2025-09-12 16:15:13 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"✗ 场景丰富化过程中出现错误: {str(e)}")
|
|
|
|
|
|
2025-09-25 10:52:52 +08:00
|
|
|
|
# 最终重命名输出文件
|
|
|
|
|
try:
|
|
|
|
|
import shutil
|
|
|
|
|
if os.path.exists(params['output_file']):
|
|
|
|
|
shutil.move(params['output_file'], params['final_output_file'])
|
|
|
|
|
logger.info(f"✓ 输出文件已重命名为: {params['final_output_file']}")
|
|
|
|
|
|
|
|
|
|
# 如果没有进行场景丰富化,但进行了文件重命名,需要确保返回的数据是最新的
|
|
|
|
|
# 因为result在场景丰富化时已经更新过,所以这里只处理未进行丰富化的情况
|
|
|
|
|
if not scene_path:
|
|
|
|
|
try:
|
|
|
|
|
with open(params['final_output_file'], 'r', encoding='utf-8') as f:
|
|
|
|
|
result = json.load(f)
|
|
|
|
|
logger.info("✓ 已重新加载最终文件数据")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"✗ 重新加载最终文件数据失败: {str(e)}")
|
|
|
|
|
else:
|
|
|
|
|
logger.warning(f"中间文件 {params['output_file']} 不存在,无法重命名")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logger.error(f"✗ 文件重命名过程中出现错误: {str(e)}")
|
|
|
|
|
|
2025-09-12 16:15:13 +08:00
|
|
|
|
logger.info("==== 所有操作已完成 ====")
|
2025-09-25 10:52:52 +08:00
|
|
|
|
|
|
|
|
|
# 在返回结果中添加输出文件名信息
|
|
|
|
|
if isinstance(result, dict):
|
|
|
|
|
result['output_filename'] = params['final_output_file']
|
|
|
|
|
|
2025-09-12 16:15:13 +08:00
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# import argparse
|
|
|
|
|
# def main():
|
|
|
|
|
# parser = argparse.ArgumentParser(description='SMAP到Scene自动转换工具')
|
|
|
|
|
# parser.add_argument('--smap', required=True, help='输入的smap地图文件路径')
|
|
|
|
|
# parser.add_argument('--scene', required=False, help='可选,参考scene文件路径')
|
|
|
|
|
# args = parser.parse_args()
|
|
|
|
|
# convert_smap_to_scene(args.smap, args.scene)
|
|
|
|
|
|
|
|
|
|
# if __name__ == "__main__":
|
|
|
|
|
# main()
|