diff --git a/odm_preprocess.py b/odm_preprocess.py index 351b913..7556849 100644 --- a/odm_preprocess.py +++ b/odm_preprocess.py @@ -18,6 +18,7 @@ from utils.grid_divider import GridDivider from utils.logger import setup_logger from utils.visualizer import FilterVisualizer from post_pro.merge_tif import MergeTif +from post_pro.merge_obj import MergeObj from post_pro.obj_post_pro import ObjPostProcessor from post_pro.merge_laz import MergePly @@ -255,10 +256,16 @@ class ImagePreprocessor: merger.merge_grid_laz(grid_points) def merge_obj(self, grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]): - """合并所有网格的OBJ模型""" + """合并所有网格的OBJ模型并转换为OSGB格式""" self.logger.info("开始合并OBJ模型") + merger = MergeObj(self.config.output_dir) + center_coords = merger.merge_grid_obj(grid_points) + + # 转换为OSGB格式 + self.logger.info("开始转换为OSGB格式") processor = ObjPostProcessor(self.config.output_dir) - processor.process_obj_files() + if not processor.convert_to_osgb(center_coords): + self.logger.error("OSGB转换失败") def post_process(self, successful_grid_points: Dict[tuple, pd.DataFrame], grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]): """后处理:合并或复制处理结果""" diff --git a/odm_preprocess_fast.py b/odm_preprocess_fast.py index 02f6a15..79a95d8 100644 --- a/odm_preprocess_fast.py +++ b/odm_preprocess_fast.py @@ -18,6 +18,7 @@ from utils.grid_divider import GridDivider from utils.logger import setup_logger from utils.visualizer import FilterVisualizer from post_pro.merge_tif import MergeTif +from post_pro.merge_obj import MergeObj from post_pro.obj_post_pro import ObjPostProcessor from post_pro.merge_laz import MergePly @@ -255,10 +256,16 @@ class ImagePreprocessor: merger.merge_grid_laz(grid_points) def merge_obj(self, grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]): - """合并所有网格的OBJ模型""" + """合并所有网格的OBJ模型并转换为OSGB格式""" self.logger.info("开始合并OBJ模型") + merger = MergeObj(self.config.output_dir) + center_coords = merger.merge_grid_obj(grid_points) + + # 转换为OSGB格式 + self.logger.info("开始转换为OSGB格式") processor = ObjPostProcessor(self.config.output_dir) - processor.process_obj_files() + if not processor.convert_to_osgb(center_coords): + self.logger.error("OSGB转换失败") def post_process(self, successful_grid_points: Dict[tuple, pd.DataFrame], grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]): """后处理:合并或复制处理结果""" diff --git a/post_pro/merge_obj.py b/post_pro/merge_obj.py index 6cad5d2..1b3a0ec 100644 --- a/post_pro/merge_obj.py +++ b/post_pro/merge_obj.py @@ -1,18 +1,26 @@ import os import logging -import numpy as np -from typing import Dict import pandas as pd +from typing import Dict, List, Tuple +import numpy as np import shutil import time import cv2 import subprocess +from pyproj import Transformer class MergeObj: def __init__(self, output_dir: str): self.output_dir = output_dir self.logger = logging.getLogger('UAV_Preprocess.MergeObj') + # 用于存储所有grid的UTM范围 + self.min_east = float('inf') + self.min_north = float('inf') + self.max_east = float('-inf') + self.max_north = float('-inf') + # 初始化UTM到WGS84的转换器 + self.transformer = Transformer.from_crs("EPSG:32649", "EPSG:4326", always_xy=True) def read_obj(self, file_path): """读取.obj文件,返回顶点、纹理坐标、法线、面的列表和MTL文件名""" @@ -103,11 +111,7 @@ class MergeObj: face_str += "/" file.write(face_str + "\n") - def translate_vertices(self, vertices, translation): - """平移顶点""" - return [[v[0] + translation[0], v[1] + translation[1], v[2] + translation[2]] for v in vertices] - - def merge_two_objs(self, obj1_path: str, obj2_path: str, output_path: str, translation, grid_id1: tuple, grid_id2: tuple): + def merge_two_objs(self, obj1_path: str, obj2_path: str, output_path: str, grid_id1: tuple, grid_id2: tuple): """合并两个OBJ文件""" try: self.logger.info(f"开始合并OBJ模型:\n输入1: {obj1_path}\n输入2: {obj2_path}") @@ -144,17 +148,13 @@ class MergeObj: for old_name in materials2.keys(): material_map2[old_name] = f"material_{grid_id2[0]}_{grid_id2[1]}_{old_name}" - # 平移第二个模型的顶点 - vertices2_translated = self.translate_vertices( - vertices2, translation) - # 计算偏移量 v_offset = len(vertices1) vt_offset = len(tex_coords1) vn_offset = len(normals1) # 合并顶点、纹理坐标和法线 - all_vertices = vertices1 + vertices2_translated + all_vertices = vertices1 + vertices2 all_tex_coords = tex_coords1 + tex_coords2 all_normals = normals1 + normals2 @@ -186,6 +186,188 @@ class MergeObj: self.logger.error(f"合并OBJ模型时发生错误: {str(e)}", exc_info=True) raise + def merge_grid_obj(self, grid_points: Dict[tuple, pd.DataFrame]) -> Tuple[float, float]: + """合并所有网格的OBJ模型 + Args: + grid_points: 网格点数据字典 + Returns: + Tuple[float, float]: (longitude, latitude)中心点经纬度坐标 + """ + if len(grid_points) == 1: + grid_id = list(grid_points.keys())[0] + shutil.copytree(os.path.join(self.output_dir, + f"grid_{grid_id[0]}_{grid_id[1]}", + "project", + "odm_texturing"), + os.path.join(self.output_dir, "texturing")) + os.rename(os.path.join(self.output_dir, "texturing", "odm_textured_model_geo.obj"), + os.path.join(self.output_dir, "texturing", "textured_model.obj")) + return + + try: + # 创建输出目录 + output_model_dir = os.path.join(self.output_dir, "texturing") + os.makedirs(output_model_dir, exist_ok=True) + + # 第一次遍历:获取所有grid的UTM范围 + for grid_id, points in grid_points.items(): + base_dir = os.path.join( + self.output_dir, + f"grid_{grid_id[0]}_{grid_id[1]}", + "project" + ) + log_file = os.path.join(base_dir, "odm_orthophoto", "odm_orthophoto_log.txt") + east_offset, north_offset = self.read_utm_offset(log_file) + + # 更新UTM范围 + self.min_east = min(self.min_east, east_offset) + self.min_north = min(self.min_north, north_offset) + self.max_east = max(self.max_east, east_offset) + self.max_north = max(self.max_north, north_offset) + + # 获取所有有效的网格文件 + grid_files = {} + all_vertices = [] # 用于存储所有顶点坐标 + for grid_id, points in grid_points.items(): + base_dir = os.path.join( + self.output_dir, + f"grid_{grid_id[0]}_{grid_id[1]}", + "project", + "odm_texturing" + ) + obj_path = os.path.join(base_dir, "odm_textured_model_geo.obj") + mtl_path = os.path.join(base_dir, "odm_textured_model_geo.mtl") + + if not os.path.exists(obj_path) or not os.path.exists(mtl_path): + self.logger.warning( + f"网格 ({grid_id[0]},{grid_id[1]}) 的文件不存在") + continue + + # 读取UTM偏移量 + log_file = os.path.join(base_dir, "..", "odm_orthophoto", "odm_orthophoto_log.txt") + utm_offset = self.read_utm_offset(log_file) + + # 修改obj文件的顶点坐标 + modified_obj = self.modify_obj_coordinates(obj_path, utm_offset) + + grid_files[grid_id] = { + 'obj': modified_obj, + 'mtl': mtl_path.replace('.mtl', '_utm.mtl'), + 'dir': base_dir + } + + # 读取obj文件的顶点坐标 + vertices, _, _, _, _, _ = self.read_obj(modified_obj) + all_vertices.extend(vertices) + + if not grid_files: + self.logger.error("没有找到有效的文件") + return + + # 收集所有材质和纹理信息 + all_materials = {} + for grid_id, files in grid_files.items(): + # 复制并重命名纹理文件 + texture_map = self.copy_and_rename_texture( + files['dir'], + output_model_dir, + grid_id + ) + + # 读取并更新MTL内容 + materials = self.read_mtl(files['mtl']) + updated_materials = self.update_mtl_content( + materials, + texture_map, + grid_id + ) + all_materials.update(updated_materials) + + # 写入合并后的MTL文件 + final_mtl = os.path.join(output_model_dir, "textured_model.mtl") + with open(final_mtl, 'w') as f: + for mat_name, content in all_materials.items(): + f.write(f"newmtl {mat_name}\n") + for line in content: + f.write(f"{line}\n") + f.write("\n") + + # 合并OBJ文件 + reference_id = list(grid_files.keys())[0] + merged_obj = grid_files[reference_id]['obj'] + temp_files = [] # 记录所有中间文件 + + for grid_id, files in list(grid_files.items())[1:]: + # 生成临时输出文件名 + temp_output = os.path.join( + output_model_dir, + f"temp_merged_{int(time.time())}.obj" + ) + temp_files.append(temp_output) # 添加到临时文件列表 + + self.merge_two_objs( + merged_obj, files['obj'], temp_output, reference_id, grid_id) + + merged_obj = temp_output + + # 最终结果 + final_obj = os.path.join(output_model_dir, "textured_model.obj") + try: + if os.path.exists(final_obj): + os.remove(final_obj) + os.rename(merged_obj, final_obj) + except Exception as e: + self.logger.warning(f"重命名最终文件失败: {str(e)}") + shutil.copy2(merged_obj, final_obj) + try: + os.remove(merged_obj) + except: + pass + + # 清理所有临时文件 + for temp_file in temp_files: + if os.path.exists(temp_file): + try: + os.remove(temp_file) + except Exception as e: + self.logger.warning( + f"删除临时文件失败: {temp_file}, 错误: {str(e)}") + + # 计算中心点经纬度 + center_lon, center_lat = self.get_center_coordinates(all_vertices) + self.logger.info(f"模型中心点经纬度: ({center_lon}, {center_lat})") + + return center_lon, center_lat + + except Exception as e: + self.logger.error(f"合并过程中发生错误: {str(e)}", exc_info=True) + raise + + def get_center_coordinates(self, vertices: List[List[float]]) -> Tuple[float, float]: + """计算顶点的中心点UTM坐标,并转换为WGS84经纬度。 + 注意:顶点坐标是相对于整体最小UTM坐标的偏移值,需要加回最小UTM坐标。 + Args: + vertices: 顶点列表,每个顶点是[x, y, z]格式,x和y是相对于最小UTM坐标的偏移 + Returns: + Tuple[float, float]: (longitude, latitude)经纬度坐标 + """ + # 计算相对坐标的边界框 + x_coords = [v[0] for v in vertices] + y_coords = [v[1] for v in vertices] + + # 计算中心点相对坐标 + center_x_relative = (min(x_coords) + max(x_coords)) / 2 + center_y_relative = (min(y_coords) + max(y_coords)) / 2 + + # 加回最小UTM坐标得到实际的UTM坐标 + center_x_utm = center_x_relative + self.min_east + center_y_utm = center_y_relative + self.min_north + + # 转换为WGS84经纬度 + lon, lat = self.transformer.transform(center_x_utm, center_y_utm) + self.logger.info(f"模型UTM中心点: ({center_x_utm}, {center_y_utm})") + return lon, lat + def read_mtl(self, mtl_path: str) -> dict: """读取MTL文件内容 Returns: @@ -291,153 +473,54 @@ class MergeObj: return updated_materials - def merge_grid_obj(self, grid_points: Dict[tuple, pd.DataFrame], translations: Dict[tuple, tuple]): - """合并所有网格的OBJ模型""" - if len(grid_points) == 1: - grid_id = list(grid_points.keys())[0] - shutil.copytree(os.path.join(self.output_dir, - f"grid_{grid_id[0]}_{grid_id[1]}", - "project", - "odm_texturing"), - os.path.join(self.output_dir, "texturing")) - os.rename(os.path.join(self.output_dir, "texturing", "odm_textured_model_geo.obj"), - os.path.join(self.output_dir, "texturing", "textured_model.obj")) - self.logger.info(f"开始执行格式转换") - docker_command = ( - f"docker run --rm -it " - f"-v {self.output_dir}/texturing:/data " - f"-e LD_LIBRARY_PATH=/opt/osg/build/lib:$LD_LIBRARY_PATH " - f"osg-ubuntu2004 osgconv /data/textured_model.obj /data/textured_model.osgb" - ) - self.logger.info(docker_command) - subprocess.run( - docker_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - self.logger.info(f"格式转换完成") - return + def read_utm_offset(self, log_file: str) -> tuple: + """读取UTM偏移量""" + try: + east_offset = None + north_offset = None + + with open(log_file, 'r') as f: + lines = f.readlines() + for i, line in enumerate(lines): + if 'utm_north_offset' in line and i + 1 < len(lines): + north_offset = float(lines[i + 1].strip()) + elif 'utm_east_offset' in line and i + 1 < len(lines): + east_offset = float(lines[i + 1].strip()) + + if east_offset is None or north_offset is None: + raise ValueError("未找到UTM偏移量") + + return east_offset, north_offset + except Exception as e: + self.logger.error(f"读取UTM偏移量时发生错误: {str(e)}") + raise + + def modify_obj_coordinates(self, obj_file: str, utm_offset: tuple) -> str: + """修改obj文件中的顶点坐标,使用相对坐标系""" + east_offset, north_offset = utm_offset + output_obj = obj_file.replace('.obj', '_utm.obj') try: - # 创建输出目录 - output_model_dir = os.path.join(self.output_dir, "texturing") - os.makedirs(output_model_dir, exist_ok=True) + with open(obj_file, 'r') as f_in, open(output_obj, 'w') as f_out: + for line in f_in: + if line.startswith('v '): + # 处理顶点坐标行 + parts = line.strip().split() + # 使用相对于整体最小UTM坐标的偏移 + x = float(parts[1]) + (east_offset - self.min_east) + y = float(parts[2]) + (north_offset - self.min_north) + z = float(parts[3]) + f_out.write(f'v {x:.6f} {y:.6f} {z:.6f}\n') + else: + # 其他行直接写入 + f_out.write(line) - # 获取所有有效的网格文件 - grid_files = {} - for grid_id, points in grid_points.items(): - base_dir = os.path.join( - self.output_dir, - f"grid_{grid_id[0]}_{grid_id[1]}", - "project", - "odm_texturing" - ) - obj_path = os.path.join(base_dir, "odm_textured_model_geo.obj") - mtl_path = os.path.join(base_dir, "odm_textured_model_geo.mtl") - - if not os.path.exists(obj_path) or not os.path.exists(mtl_path): - self.logger.warning( - f"网格 ({grid_id[0]},{grid_id[1]}) 的文件不存在") - continue - - grid_files[grid_id] = { - 'obj': obj_path, - 'mtl': mtl_path, - 'dir': base_dir - } - - if not grid_files: - self.logger.error("没有找到有效的文件") - return - - # 收集所有材质和纹理信息 - all_materials = {} - for grid_id, files in grid_files.items(): - # 复制并重命名纹理文件 - texture_map = self.copy_and_rename_texture( - files['dir'], - output_model_dir, - grid_id - ) - - # 读取并更新MTL内容 - materials = self.read_mtl(files['mtl']) - updated_materials = self.update_mtl_content( - materials, - texture_map, - grid_id - ) - all_materials.update(updated_materials) - - # 写入合并后的MTL文件 - final_mtl = os.path.join(output_model_dir, "textured_model.mtl") - with open(final_mtl, 'w') as f: - for mat_name, content in all_materials.items(): - f.write(f"newmtl {mat_name}\n") - for line in content: - f.write(f"{line}\n") - f.write("\n") - - # 合并OBJ文件 - reference_id = list(grid_files.keys())[0] - merged_obj = grid_files[reference_id]['obj'] - temp_files = [] # 记录所有中间文件 - - for grid_id, files in list(grid_files.items())[1:]: - translation = translations[grid_id] - translation = (translation[0], translation[1], 0) - - # 生成临时输出文件名 - temp_output = os.path.join( - output_model_dir, - f"temp_merged_{int(time.time())}.obj" - ) - temp_files.append(temp_output) # 添加到临时文件列表 - - self.merge_two_objs( - merged_obj, files['obj'], temp_output, translation, reference_id, grid_id) - - merged_obj = temp_output - - # 最终结果 - final_obj = os.path.join(output_model_dir, "textured_model.obj") - try: - if os.path.exists(final_obj): - os.remove(final_obj) - os.rename(merged_obj, final_obj) - except Exception as e: - self.logger.warning(f"重命名最终文件失败: {str(e)}") - shutil.copy2(merged_obj, final_obj) - try: - os.remove(merged_obj) - except: - pass - - # 清理所有临时文件 - for temp_file in temp_files: - if os.path.exists(temp_file): - try: - os.remove(temp_file) - except Exception as e: - self.logger.warning( - f"删除临时文件失败: {temp_file}, 错误: {str(e)}") - - self.logger.info( - f"模型合并完成,输出目录: {output_model_dir}\n" - f"- OBJ文件: textured_model.obj\n" - f"- MTL文件: textured_model.mtl\n" - f"- 纹理文件: {len(os.listdir(output_model_dir)) - 2}个" - ) - - self.logger.info(f"开始执行格式转换") - docker_command = ( - f"docker run --rm -it " - f"-v {output_model_dir}:/data " - f"-e LD_LIBRARY_PATH=/opt/osg/build/lib:$LD_LIBRARY_PATH " - f"osg-ubuntu2004 osgconv /data/textured_model.obj /data/textured_model.osgb" - ) - self.logger.info(docker_command) - subprocess.run( - docker_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - self.logger.info(f"格式转换完成") + # 复制材质文件 + mtl_file = obj_file.replace('.obj', '.mtl') + if os.path.exists(mtl_file): + shutil.copy2(mtl_file, mtl_file.replace('.mtl', '_utm.mtl')) + return output_obj except Exception as e: - self.logger.error(f"合并过程中发生错误: {str(e)}", exc_info=True) + self.logger.error(f"修改obj坐标时发生错误: {str(e)}") raise diff --git a/post_pro/obj_post_pro.py b/post_pro/obj_post_pro.py index 6676a04..b5a95e6 100644 --- a/post_pro/obj_post_pro.py +++ b/post_pro/obj_post_pro.py @@ -1,140 +1,63 @@ import os import logging import subprocess -import shutil -from typing import List, Tuple -import numpy as np +from typing import Tuple class ObjPostProcessor: def __init__(self, output_dir: str): self.output_dir = output_dir self.logger = logging.getLogger('UAV_Preprocess.ObjPostProcessor') - # 用于存储所有grid的UTM范围 - self.min_east = float('inf') - self.min_north = float('inf') - self.max_east = float('-inf') - self.max_north = float('-inf') - def process_obj_files(self): - """处理所有grid中的obj文件""" + def create_metadata_xml(self, osgb_dir: str, lon: float, lat: float): + """创建metadata.xml文件,包含地理参考信息 + Args: + osgb_dir: osgb输出目录 + lon: 中心点经度 + lat: 中心点纬度 + """ try: - # 1. 遍历所有grid文件夹 - grid_dirs = [d for d in os.listdir( - self.output_dir) if d.startswith('grid_')] - - # 第一次遍历:获取所有grid的UTM范围 - for grid_dir in grid_dirs: - grid_path = os.path.join(self.output_dir, grid_dir) - log_file = os.path.join( - grid_path, 'project', 'odm_orthophoto', 'odm_orthophoto_log.txt') - east_offset, north_offset = self.read_utm_offset(log_file) + metadata_content = f''' + + + EPSG:4326 + + {lon},{lat},0.000000 + + Visible + +''' + + # metadata.xml 放在根目录 + metadata_path = os.path.join(osgb_dir, 'metadata.xml') + with open(metadata_path, 'w', encoding='utf-8') as f: + f.write(metadata_content) - # 更新UTM范围 - self.min_east = min(self.min_east, east_offset) - self.min_north = min(self.min_north, north_offset) - self.max_east = max(self.max_east, east_offset) - self.max_north = max(self.max_north, north_offset) + self.logger.info(f"已创建metadata.xml: {metadata_path}") + + except Exception as e: + self.logger.error(f"创建metadata.xml时发生错误: {str(e)}") + raise - # 创建osgb输出目录 + def convert_to_osgb(self, center_coords: Tuple[float, float]): + """将obj转换为osgb,并创建metadata.xml + Args: + center_coords: (longitude, latitude)中心点经纬度坐标 + """ + try: + # 获取合并后的obj文件路径 + obj_dir = os.path.join(self.output_dir, 'texturing') + obj_file = os.path.join(obj_dir, 'textured_model.obj') + if not os.path.exists(obj_file): + raise Exception(f"未找到obj文件: {obj_file}") + + # 创建osgb目录结构 osgb_dir = os.path.join(self.output_dir, 'osgb') - os.makedirs(os.path.join(osgb_dir, 'Data'), exist_ok=True) + osgb_data_dir = os.path.join(osgb_dir, 'Data', 'textured_model') + os.makedirs(osgb_data_dir, exist_ok=True) - # 第二次遍历:处理每个grid - for grid_dir in grid_dirs: - grid_path = os.path.join(self.output_dir, grid_dir) - self.process_single_grid(grid_path, osgb_dir) - - # 创建metadata.xml - self.create_metadata_xml(osgb_dir) - - self.logger.info("所有grid处理完成") - return True - except Exception as e: - self.logger.error(f"处理obj文件时发生错误: {str(e)}") - return False - - def process_single_grid(self, grid_path: str, osgb_dir: str): - """处理单个grid的obj文件""" - try: - # 1. 读取UTM偏移量 - log_file = os.path.join( - grid_path, 'project', 'odm_orthophoto', 'odm_orthophoto_log.txt') - utm_offset = self.read_utm_offset(log_file) - - # 2. 修改obj文件的顶点坐标 - obj_file = os.path.join( - grid_path, 'project', 'odm_texturing', 'odm_textured_model_geo.obj') - modified_obj = self.modify_obj_coordinates(obj_file, utm_offset) - - # 3. 使用osgconv转换为osgb - grid_name = os.path.basename(grid_path) - self.convert_to_osgb(modified_obj, grid_name, osgb_dir) - - except Exception as e: - self.logger.error(f"处理grid {grid_path} 时发生错误: {str(e)}") - raise - - def read_utm_offset(self, log_file: str) -> Tuple[float, float]: - """读取UTM偏移量""" - try: - east_offset = None - north_offset = None - - with open(log_file, 'r') as f: - lines = f.readlines() - for i, line in enumerate(lines): - if 'utm_north_offset' in line and i + 1 < len(lines): - north_offset = float(lines[i + 1].strip()) - elif 'utm_east_offset' in line and i + 1 < len(lines): - east_offset = float(lines[i + 1].strip()) - - if east_offset is None or north_offset is None: - raise ValueError("未找到UTM偏移量") - - return east_offset, north_offset - except Exception as e: - self.logger.error(f"读取UTM偏移量时发生错误: {str(e)}") - raise - - def modify_obj_coordinates(self, obj_file: str, utm_offset: Tuple[float, float]) -> str: - """修改obj文件中的顶点坐标,使用相对坐标系""" - east_offset, north_offset = utm_offset - output_obj = obj_file.replace('.obj', '_utm.obj') - - try: - with open(obj_file, 'r') as f_in, open(output_obj, 'w') as f_out: - for line in f_in: - if line.startswith('v '): - # 处理顶点坐标行 - parts = line.strip().split() - # 使用相对于整体最小UTM坐标的偏移 - x = float(parts[1]) + (east_offset - self.min_east) - y = float(parts[2]) + (north_offset - self.min_north) - z = float(parts[3]) - f_out.write(f'v {x:.6f} {y:.6f} {z:.6f}\n') - else: - # 其他行直接写入 - f_out.write(line) - - # 复制材质文件 - mtl_file = obj_file.replace('.obj', '.mtl') - if os.path.exists(mtl_file): - shutil.copy2(mtl_file, mtl_file.replace('.mtl', '_utm.mtl')) - - return output_obj - except Exception as e: - self.logger.error(f"修改obj坐标时发生错误: {str(e)}") - raise - - def convert_to_osgb(self, obj_file: str, grid_name: str, osgb_dir: str): - """使用osgconv将obj转换为osgb""" - try: - # 创建tile目录 - tile_dir = os.path.join(osgb_dir, 'Data', grid_name) - os.makedirs(tile_dir, exist_ok=True) - - output_osgb = os.path.join(tile_dir, f'{grid_name}.osgb') + # 输出文件路径 + output_osgb = os.path.join(osgb_data_dir, 'textured_model.osgb') # 构建osgconv命令 cmd = [ @@ -148,35 +71,19 @@ class ObjPostProcessor: ] # 执行命令 - self.logger.info(f"执行osgconv命令:{cmd}") + self.logger.info(f"执行osgconv命令:{' '.join(cmd)}") result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: - raise Exception(f"osgconv执行失败: {result.stderr}") + raise Exception(f"osgb格式转换失败: {result.stderr}") + + # 创建metadata.xml + lon, lat = center_coords + self.create_metadata_xml(osgb_dir, lon, lat) self.logger.info(f"转换完成: {output_osgb}") + return True except Exception as e: self.logger.error(f"转换osgb时发生错误: {str(e)}") - raise - - def create_metadata_xml(self, osgb_dir: str): - """创建metadata.xml文件,包含UTM偏移信息""" - try: - # 这里需要将UTM坐标转换为WGS84经纬度坐标 - # 这里使用示例值,实际应用中需要进行真实的坐标转换 - metadata_content = f''' - - EPSG:32649 - {self.min_east:.6f},{self.min_north:.6f},0.000000 - - Visible - -''' - - with open(os.path.join(osgb_dir, 'metadata.xml'), 'w') as f: - f.write(metadata_content) - - except Exception as e: - self.logger.error(f"创建metadata.xml时发生错误: {str(e)}") - raise + return False