修改metadata.xml,添加boundingbox
This commit is contained in:
parent
9b151d0768
commit
3df39f76d2
2
main.py
2
main.py
@ -1,6 +1,6 @@
|
||||
import argparse
|
||||
from datetime import timedelta
|
||||
from odm_preprocess import PreprocessConfig, ImagePreprocessor
|
||||
from odm_preprocess_fast import PreprocessConfig, ImagePreprocessor
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='ODM预处理工具')
|
||||
|
@ -259,12 +259,12 @@ class ImagePreprocessor:
|
||||
"""合并所有网格的OBJ模型并转换为OSGB格式"""
|
||||
self.logger.info("开始合并OBJ模型")
|
||||
merger = MergeObj(self.config.output_dir)
|
||||
center_coords = merger.merge_grid_obj(grid_points)
|
||||
center_lon, center_lat, bounding_box = merger.merge_grid_obj(grid_points)
|
||||
|
||||
# 转换为OSGB格式
|
||||
self.logger.info("开始转换为OSGB格式")
|
||||
processor = ObjPostProcessor(self.config.output_dir)
|
||||
if not processor.convert_to_osgb(center_coords):
|
||||
if not processor.convert_to_osgb(center_lon, center_lat, bounding_box):
|
||||
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]):
|
||||
|
@ -259,12 +259,12 @@ class ImagePreprocessor:
|
||||
"""合并所有网格的OBJ模型并转换为OSGB格式"""
|
||||
self.logger.info("开始合并OBJ模型")
|
||||
merger = MergeObj(self.config.output_dir)
|
||||
center_coords = merger.merge_grid_obj(grid_points)
|
||||
center_lon, center_lat, bounding_box = merger.merge_grid_obj(grid_points)
|
||||
|
||||
# 转换为OSGB格式
|
||||
self.logger.info("开始转换为OSGB格式")
|
||||
processor = ObjPostProcessor(self.config.output_dir)
|
||||
if not processor.convert_to_osgb(center_coords):
|
||||
if not processor.convert_to_osgb(center_lon, center_lat, bounding_box):
|
||||
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]):
|
||||
|
@ -124,6 +124,12 @@ class MergeObj:
|
||||
output_model_dir = os.path.join(self.output_dir, "texturing")
|
||||
os.makedirs(output_model_dir, exist_ok=True)
|
||||
|
||||
# 初始化全局边界框坐标
|
||||
global_min_lon = float('inf')
|
||||
global_min_lat = float('inf')
|
||||
global_max_lon = float('-inf')
|
||||
global_max_lat = float('-inf')
|
||||
|
||||
# 第一次遍历:获取所有grid的UTM范围
|
||||
for grid_id, points in grid_points.items():
|
||||
base_dir = os.path.join(
|
||||
@ -170,16 +176,28 @@ class MergeObj:
|
||||
log_file = os.path.join(
|
||||
base_dir, "..", "odm_orthophoto", "odm_orthophoto_log.txt")
|
||||
utm_offset = self.read_utm_offset(log_file)
|
||||
modified_obj = self.modify_obj_coordinates(obj_path, utm_offset)
|
||||
modified_obj = self.modify_obj_coordinates(
|
||||
obj_path, utm_offset)
|
||||
|
||||
# 读取obj文件内容
|
||||
vertices, tex_coords, normals, faces, face_materials, _ = self.read_obj(modified_obj)
|
||||
vertices, tex_coords, normals, faces, face_materials, _ = self.read_obj(
|
||||
modified_obj)
|
||||
|
||||
# 计算当前grid的中心点
|
||||
grid_center_lon, grid_center_lat = self.get_center_coordinates(vertices)
|
||||
grid_center_lon, grid_center_lat, grid_bounding_box = self.get_center_coordinates(
|
||||
vertices)
|
||||
grid_centers.append((grid_center_lon, grid_center_lat))
|
||||
self.logger.info(
|
||||
f"网格 ({grid_id[0]},{grid_id[1]}) 中心点经纬度: ({grid_center_lon}, {grid_center_lat})")
|
||||
# 更新全局边界框坐标
|
||||
global_min_lon = min(
|
||||
global_min_lon, grid_bounding_box['LB_lon'])
|
||||
global_min_lat = min(
|
||||
global_min_lat, grid_bounding_box['LB_lat'])
|
||||
global_max_lon = max(
|
||||
global_max_lon, grid_bounding_box['RU_lon'])
|
||||
global_max_lat = max(
|
||||
global_max_lat, grid_bounding_box['RU_lat'])
|
||||
|
||||
# 复制并重命名纹理文件
|
||||
texture_map = self.copy_and_rename_texture(
|
||||
@ -211,13 +229,16 @@ class MergeObj:
|
||||
for face, material in zip(faces, face_materials):
|
||||
# 调整面的索引
|
||||
new_face_v = [f + v_offset for f in face[0]]
|
||||
new_face_vt = [f + vt_offset for f in face[1]] if face[1] else []
|
||||
new_face_vn = [f + vn_offset for f in face[2]] if face[2] else []
|
||||
new_face_vt = [
|
||||
f + vt_offset for f in face[1]] if face[1] else []
|
||||
new_face_vn = [
|
||||
f + vn_offset for f in face[2]] if face[2] else []
|
||||
all_faces.append((new_face_v, new_face_vt, new_face_vn))
|
||||
|
||||
|
||||
# 添加材质前缀
|
||||
if material:
|
||||
all_face_materials.append(f"material_{grid_id[0]}_{grid_id[1]}_{material}")
|
||||
all_face_materials.append(
|
||||
f"material_{grid_id[0]}_{grid_id[1]}_{material}")
|
||||
else:
|
||||
all_face_materials.append(material)
|
||||
|
||||
@ -240,23 +261,29 @@ class MergeObj:
|
||||
all_faces, all_face_materials, "textured_model.mtl")
|
||||
|
||||
# 计算整体中心点
|
||||
center_lon = sum(center[0] for center in grid_centers) / len(grid_centers)
|
||||
center_lat = sum(center[1] for center in grid_centers) / len(grid_centers)
|
||||
center_lon = sum(center[0]
|
||||
for center in grid_centers) / len(grid_centers)
|
||||
center_lat = sum(center[1]
|
||||
for center in grid_centers) / len(grid_centers)
|
||||
self.logger.info(f"模型整体中心点经纬度: ({center_lon}, {center_lat})")
|
||||
|
||||
return center_lon, center_lat
|
||||
# 计算整个区域的边界框
|
||||
bounding_box = [global_min_lon, global_min_lat, global_max_lon, global_max_lat]
|
||||
self.logger.info(
|
||||
f"模型整体边界框: ({bounding_box[0]}, {bounding_box[1]}) - ({bounding_box[2]}, {bounding_box[3]})")
|
||||
|
||||
return center_lon, center_lat, bounding_box
|
||||
|
||||
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]:
|
||||
def get_center_coordinates(self, vertices: List[List[float]]) -> Tuple[float, float, Dict[str, float]]:
|
||||
"""计算顶点的中心点UTM坐标,并转换为WGS84经纬度。
|
||||
注意:顶点坐标是相对于整体最小UTM坐标的偏移值,需要加回最小UTM坐标。
|
||||
Args:
|
||||
vertices: 顶点列表,每个顶点是[x, y, z]格式,x和y是相对于最小UTM坐标的偏移
|
||||
Returns:
|
||||
Tuple[float, float]: (longitude, latitude)经纬度坐标
|
||||
Tuple[float, float, Dict[str, float]]: (longitude, latitude, bounding_box)
|
||||
"""
|
||||
# 计算相对坐标的边界框
|
||||
x_coords = [v[0] for v in vertices]
|
||||
@ -272,8 +299,16 @@ class MergeObj:
|
||||
|
||||
# 转换为WGS84经纬度
|
||||
lon, lat = self.transformer.transform(center_x_utm, center_y_utm)
|
||||
# 计算边界框并转换为经纬度
|
||||
bounding_box = {
|
||||
'LB_lon': self.transformer.transform(min(x_coords) + self.min_east, min(y_coords) + self.min_north)[0],
|
||||
'LB_lat': self.transformer.transform(min(x_coords) + self.min_east, min(y_coords) + self.min_north)[1],
|
||||
'RU_lon': self.transformer.transform(max(x_coords) + self.min_east, max(y_coords) + self.min_north)[0],
|
||||
'RU_lat': self.transformer.transform(max(x_coords) + self.min_east, max(y_coords) + self.min_north)[1]
|
||||
}
|
||||
|
||||
self.logger.info(f"模型UTM中心点: ({center_x_utm}, {center_y_utm})")
|
||||
return lon, lat
|
||||
return lon, lat, bounding_box
|
||||
|
||||
def read_mtl(self, mtl_path: str) -> dict:
|
||||
"""读取MTL文件内容
|
||||
|
@ -1,7 +1,7 @@
|
||||
import os
|
||||
import logging
|
||||
import subprocess
|
||||
from typing import Tuple
|
||||
from typing import Tuple, Dict
|
||||
|
||||
|
||||
class ObjPostProcessor:
|
||||
@ -9,7 +9,7 @@ class ObjPostProcessor:
|
||||
self.output_dir = output_dir
|
||||
self.logger = logging.getLogger('UAV_Preprocess.ObjPostProcessor')
|
||||
|
||||
def create_metadata_xml(self, osgb_dir: str, lon: float, lat: float):
|
||||
def create_metadata_xml(self, osgb_dir: str, lon: float, lat: float, bounding_box):
|
||||
"""创建metadata.xml文件,包含地理参考信息
|
||||
Args:
|
||||
osgb_dir: osgb输出目录
|
||||
@ -18,15 +18,29 @@ class ObjPostProcessor:
|
||||
"""
|
||||
try:
|
||||
metadata_content = f'''<?xml version="1.0" encoding="utf-8"?>
|
||||
<ModelMetadata version="1">
|
||||
<!--Spatial Reference System-->
|
||||
<SRS>EPSG:4326</SRS>
|
||||
<!--Origin in Spatial Reference System-->
|
||||
<SRSOrigin>{lon},{lat},0.000000</SRSOrigin>
|
||||
<Texture>
|
||||
<ColorSource>Visible</ColorSource>
|
||||
</Texture>
|
||||
</ModelMetadata>'''
|
||||
<ModelMetadata version="1">
|
||||
<!-- Spatial Reference System -->
|
||||
<SRS>EPSG:4326</SRS>
|
||||
|
||||
<!-- Center point in Spatial Reference System (in Longitude, Latitude, Height) -->
|
||||
<SRSOrigin>{lon},{lat},0.000000</SRSOrigin>
|
||||
|
||||
<!-- Bounding Box with Two Points -->
|
||||
<BoundingBox>
|
||||
<!-- Left-Bottom Corner (Longitude, Latitude) -->
|
||||
<LB_lon>{bounding_box[0]}</LB_lon>
|
||||
<LB_lat>{bounding_box[1]}</LB_lat>
|
||||
|
||||
<!-- Right-Top Corner (Longitude, Latitude) -->
|
||||
<RU_lon>{bounding_box[2]}</RU_lon>
|
||||
<RU_lat>{bounding_box[3]}</RU_lat>
|
||||
</BoundingBox>
|
||||
|
||||
<Texture>
|
||||
<ColorSource>Visible</ColorSource>
|
||||
</Texture>
|
||||
</ModelMetadata>
|
||||
'''
|
||||
|
||||
# metadata.xml 放在根目录
|
||||
metadata_path = os.path.join(osgb_dir, 'metadata.xml')
|
||||
@ -39,7 +53,7 @@ class ObjPostProcessor:
|
||||
self.logger.error(f"创建metadata.xml时发生错误: {str(e)}")
|
||||
raise
|
||||
|
||||
def convert_to_osgb(self, center_coords: Tuple[float, float]):
|
||||
def convert_to_osgb(self, center_lon, center_lat, bounding_box):
|
||||
"""将obj转换为osgb,并创建metadata.xml
|
||||
Args:
|
||||
center_coords: (longitude, latitude)中心点经纬度坐标
|
||||
@ -76,12 +90,11 @@ class ObjPostProcessor:
|
||||
|
||||
if result.returncode != 0:
|
||||
raise Exception(f"osgb格式转换失败: {result.stderr}")
|
||||
self.logger.info(f"转换完成: {output_osgb}")
|
||||
|
||||
# 创建metadata.xml
|
||||
lon, lat = center_coords
|
||||
self.create_metadata_xml(osgb_dir, lon, lat)
|
||||
self.create_metadata_xml(osgb_dir, center_lon, center_lat, bounding_box)
|
||||
|
||||
self.logger.info(f"转换完成: {output_osgb}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
|
Loading…
Reference in New Issue
Block a user