From 796d36c0934238781d0f70dc64af83b193c643ba Mon Sep 17 00:00:00 2001 From: duxin Date: Tue, 7 Jul 2026 16:51:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20TIF=20=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=20CRS=20=E6=97=B6=20fallback=20=E5=88=B0=20WGS84=20?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E6=8E=A9=E8=86=9C=E6=93=A6=E9=99=A4=E5=85=A8?= =?UTF-8?q?=E9=83=A8=E5=83=8F=E5=85=83=E7=9A=84=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: step11 日志反复出现: '栅格 TIF 缺失坐标系,默认按 WGS84 渲染' '擦除后有效像元: 0/15300' 根因: step10 生成的 GeoTIFF 缺少 CRS (可能是 PROJ 异常时生成的)。 visualize_raster 中当 crs_obj 为 None 时无条件回退到 EPSG:4326 (WGS84), 但 transform 实际是 UTM 米坐标 (e.g. x≈470000, y≈2200000)。 UTM 度坐标的掩膜被 reproject 到 WGS84 后, 与仍在 UTM 米坐标的 transform 彻底错位 → geometry_mask 全部为 False → 0 个有效像元。 修复: 当 crs_obj 为 None 且 boundary 有投影 CRS 时, 检查 transform 的 X 坐标量级: 若 >180 则必定是投影坐标 (UTM 等), 直接使用 boundary 的 CRS 而非 WGS84 回退。 仅当坐标量级 <180 时才回退到 WGS84 (真经纬度)。 --- src/postprocessing/map.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/postprocessing/map.py b/src/postprocessing/map.py index 1b0658b..e7fffc5 100644 --- a/src/postprocessing/map.py +++ b/src/postprocessing/map.py @@ -2402,11 +2402,27 @@ class ContentMapper: f"默认按 WGS84 (EPSG:4326) 处理 ({Path(boundary_shp_path).name})。") boundary_gdf = boundary_gdf.set_crs(epsg=4326) - # 兜底:如果栅格 TIF 缺失坐标系,默认也赋予 WGS84(CRS 顶部已导入,无需局部 import) + # 兜底:如果栅格 TIF 缺失坐标系 + # ★ 关键修复:不能盲目回退到 WGS84 (EPSG:4326) + # transform 的坐标值如果是数十万~数百万量级,一定是投影坐标(UTM 等), + # 而非 WGS84 经纬度(-180~180)。此时应使用掩膜的 CRS 作为正确参考, + # 否则 geometry_mask 的空间坐标与 transform 完全错位 → 全部像元被擦除。 if crs_obj is None: - crs_obj = CRS.from_epsg(4326) - print(f"[visualize_raster] 警告: 栅格 TIF 缺失坐标系," - f"默认按 WGS84 渲染 ({Path(raster_tif_path).name})。") + if (boundary_gdf.crs is not None + and boundary_gdf.crs.is_projected + and transform is not None): + # transform 坐标量级检测:UTM 坐标通常在 10^5~10^7 范围 + x_magnitude = max(abs(transform.c), abs(transform.c + transform.a * array.shape[1])) + if x_magnitude > 180.0: + crs_obj = boundary_gdf.crs + print(f"[visualize_raster] 栅格 TIF 缺失坐标系," + f"根据 transform 坐标量级 (x≈{x_magnitude:.0f}) " + f"判定为投影坐标系,使用掩膜 CRS ({crs_obj.to_epsg()}) " + f"({Path(raster_tif_path).name})") + if crs_obj is None: + crs_obj = CRS.from_epsg(4326) + print(f"[visualize_raster] 警告: 栅格 TIF 缺失坐标系," + f"默认按 WGS84 渲染 ({Path(raster_tif_path).name})。") # 坐标系对齐到当前栅格的 CRS(不是 self.output_crs,必须与 transform 保持一致) if boundary_gdf.crs != crs_obj: