From 0f44df8cecf4f9e798f7534dbee8c4e8a9622ac1 Mon Sep 17 00:00:00 2001 From: liyubo Date: Mon, 19 Jan 2026 10:42:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9D=A1=E5=BA=A6=E5=9D=A1=E5=90=91=E5=90=88?= =?UTF-8?q?=E5=B9=B6tif=E7=94=9F=E6=88=90=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- b3dm/glb_with_draco.py | 6 +++--- b3dm/slope_aspect_img.py | 2 +- b3dm/terrain_api.py | 38 ++++++++++++++++++++++++++++++++++ b3dm/terrain_calculator.py | 42 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 82 insertions(+), 6 deletions(-) diff --git a/b3dm/glb_with_draco.py b/b3dm/glb_with_draco.py index 460528b..f4a324f 100644 --- a/b3dm/glb_with_draco.py +++ b/b3dm/glb_with_draco.py @@ -70,9 +70,9 @@ class DracoGLBParser: extensions_required = self.json_data.get('extensionsRequired', []) if 'KHR_draco_mesh_compression' in extensions_used: - print("✓ 使用 Draco 压缩") + print("使用 Draco 压缩") if 'KHR_draco_mesh_compression' in extensions_required: - print("⚠ Draco 压缩是必需的") + print("Draco 压缩是必需的") # 网格信息 meshes = self.json_data.get('meshes', []) @@ -88,7 +88,7 @@ class DracoGLBParser: if 'extensions' in primitive: draco_info = primitive['extensions'].get('KHR_draco_mesh_compression') if draco_info: - print(f" ✓ 使用 Draco 压缩") + print(f" 使用 Draco 压缩") print(f" 属性: {draco_info.get('attributes', {})}") # 缓冲区信息 diff --git a/b3dm/slope_aspect_img.py b/b3dm/slope_aspect_img.py index 922c126..56d313a 100644 --- a/b3dm/slope_aspect_img.py +++ b/b3dm/slope_aspect_img.py @@ -376,5 +376,5 @@ def setup_chinese_font(): if __name__ == "__main__": - dem_path = r'D:\devForBdzlWork\ai_project_v1\b3dm\test\o_dem_df67f1cc.tif' + dem_path = r'D:/devForBdzlWork/ai_project_v1/b3dm/o_dem_f1cb6f69_slopeAspect.tif' read_slope_aspect_by_dem(dem_path) \ No newline at end of file diff --git a/b3dm/terrain_api.py b/b3dm/terrain_api.py index 70e8733..4394fe0 100644 --- a/b3dm/terrain_api.py +++ b/b3dm/terrain_api.py @@ -232,6 +232,44 @@ async def calculate_slopeAspect(request: Request): "success": False }, status=500) +@terrain_bp.post("/api/v1/calculate/slopeAspectTif") +async def calculate_slopeAspect_tif(request: Request): + """生成坡向坡度tif文件""" + try: + data = request.json + if not data: + return json({"error": "请求体不能为空"}, status=400) + + # 验证输入 + try: + vector = PointRequest(**data) + except Exception as e: + return json({"error": f"输入验证失败: {str(e)}"}, status=400) + + # 生成坡向坡度俯视图 + region_coords = [(point.x, point.y, point.z) for point in vector.points] + slope_aspect_tif_name = f"o_dem_{uuid.uuid4().hex[:8]}_slopeAspect.tif" + # 创建并启动线程 + thread1 = threading.Thread(target=TerrainCalculator.generate_slopeAspect_tif, args=(region_coords, vector.url, slope_aspect_tif_name, MINIO_SUB_PATH)) + # 启动线程 + thread1.start() + url_prefix = extract_and_rebuild_url(vector.url) + return json({ + "success": True, + "data": f"{url_prefix}/{MINIO_SUB_PATH}/{slope_aspect_tif_name}", + "request": { + "input_vector": vector.model_dump(), + "timestamp": time.time() + } + }) + + except Exception as e: + logger.error(f"坡向计算API错误: {e}") + return json({ + "error": f"服务器内部错误: {str(e)}", + "success": False + }, status=500) + @terrain_bp.post("/api/v1/calculate/both") async def calculate_both(request: Request): """同时计算坡度和坡向""" diff --git a/b3dm/terrain_calculator.py b/b3dm/terrain_calculator.py index 8b5017a..cf0e2af 100644 --- a/b3dm/terrain_calculator.py +++ b/b3dm/terrain_calculator.py @@ -6,6 +6,7 @@ import uuid from b3dm.data_3dtiles_manager import MinIO3DTilesManager import b3dm.data_3dtiles_to_dem as data_3dtiles_to_dem import b3dm.slope_aspect_img as slope_aspect_img +import b3dm.slope_aspect_tif as slope_aspect_tif logger = logging.getLogger(__name__) @@ -28,7 +29,7 @@ class TerrainCalculator: script_dir = os.path.dirname(os.path.abspath(__file__)) success, entry_local_path = manager.download_full_tileset( tileset_url=url, - save_dir=f"{script_dir}/data_3dtiles", + save_dir=f"data_3dtiles", region_filter=None ) if not success : @@ -46,7 +47,7 @@ class TerrainCalculator: script_dir = os.path.dirname(os.path.abspath(__file__)) success, entry_local_path = manager.download_full_tileset( tileset_url=url, - save_dir=f"{script_dir}/data_3dtiles", + save_dir=f"data_3dtiles", region_filter=None ) if not success : @@ -71,6 +72,43 @@ class TerrainCalculator: return "生成成功", minio_path else : return "生成失败", None + + def generate_slopeAspect_tif(region_coords, url, slope_aspect_tif_name, minio_sub_path) : + # 下载3dtiles地图数据 + manager = MinIO3DTilesManager( + endpoint_url=ENDPOINT_URL, + access_key=ACCESS_KEY, + secret_key=SECRET_KEY, + secure=False + ) + script_dir = os.path.dirname(os.path.abspath(__file__)) + success, entry_local_path = manager.download_full_tileset( + tileset_url=url, + save_dir=f"data_3dtiles", + region_filter=None + ) + if not success : + logger.info(f"下载地图数据失败: {url},{region_coords}") + return "下载地图数据失败", None + + tileset_path = entry_local_path + dem_path = os.path.join(script_dir, f"o_dem_{uuid.uuid4().hex[:8]}.tif") + data_3dtiles_to_dem.generate_dem(tileset_path, dem_path, region_coords) + + if not os.path.exists(dem_path) : + logger.info(f"生成坡度坡向俯视图失败: {url},{region_coords}") + return "生成坡度坡向俯视图失败", None + + slope_aspect_tif_path = os.path.join(script_dir, slope_aspect_tif_name) + slope_aspect_tif.create_slope_aspect(dem_path, 'combined', slope_aspect_tif_path) + logger.info(f"生成成功: {url},{region_coords},{slope_aspect_tif_path}") + + entry_bucket, _ = manager.parse_minio_url(url); + success, minio_path = manager.upload_file(entry_bucket, f"{minio_sub_path}/{slope_aspect_tif_name}", slope_aspect_tif_path) + if success : + return "生成成功", minio_path + else : + return "生成失败", None @staticmethod def validate_vector(vector: List[float]) -> bool: