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(