From 9fa60e2995e572c5bbc253aaa29df81af702ad98 Mon Sep 17 00:00:00 2001 From: duxin Date: Thu, 9 Jul 2026 09:37:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20CRS=20=E6=AF=94=E8=BE=83=E6=94=B9?= =?UTF-8?q?=E7=94=A8=20GDAL=20osr.IsSame()=20=E8=AF=AD=E4=B9=89=E6=AF=94?= =?UTF-8?q?=E5=AF=B9,=20=E6=B6=88=E9=99=A4=20WKT=20=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=B7=AE=E5=BC=82=E8=AF=AF=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: 两组不同数据的 .hdr 文件由不同软件生成, 同一 UTM 投影的 WKT 字符串格式不同 (PROJCS 命名/参数精度), 原 validate_projections 用字符串比较会误报 CRS 不一致。 修复: 改用 gdal.osr.SpatialReference.IsSame() 语义比对: - 同一定义 → 通过 (即使 WKT 格式不同) - 真正不同 → 报错 - osr 解析失败 → 回退字符串比较 --- src/core/utils/spatial_validator.py | 30 ++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/core/utils/spatial_validator.py b/src/core/utils/spatial_validator.py index 79eb285..16801c9 100644 --- a/src/core/utils/spatial_validator.py +++ b/src/core/utils/spatial_validator.py @@ -146,23 +146,35 @@ def validate_projections(proj_a: Optional[str], proj_b: Optional[str], label_a: str = "栅格A", label_b: str = "栅格B") -> None: - """验证两个投影坐标系 (WKT) 一致 + """验证两个投影坐标系语义一致(非字符串比较) + + 使用 GDAL SpatialReference.IsSame() 做语义比对。 + 同一坐标系但 WKT 格式不同(不同软件生成)不会误报。 空字符串视为"无投影",不验证。 Raises: - SpatialAlignmentError: 投影不一致时 + SpatialAlignmentError: 投影语义不一致时 """ if not proj_a or not proj_b: return # 至少一方无投影,跳过 - # 标准化比较(去除空白差异) - norm_a = " ".join(proj_a.split()) - norm_b = " ".join(proj_b.split()) - if norm_a != norm_b: - raise SpatialAlignmentError.from_projection_mismatch( - label_a, label_b, proj_a, proj_b - ) + try: + from osgeo import osr + sr_a = osr.SpatialReference(proj_a) + sr_b = osr.SpatialReference(proj_b) + if sr_a.IsSame(sr_b): + return # 语义相同,OK + except Exception: + # osr 解析失败 → 回退到字符串标准化比较 + norm_a = " ".join(proj_a.split()) + norm_b = " ".join(proj_b.split()) + if norm_a == norm_b: + return + + raise SpatialAlignmentError.from_projection_mismatch( + label_a, label_b, proj_a, proj_b + ) def validate_spatial_alignment(