GDAL 空间参考与投影怎么处理

坐标系与投影
Dr.GIS
wowwwai GIS研习社 · 工具流程与项目排障

GDAL 处理空间参考与投影,核心是用 OGRSpatialReference(Python 为 osr.SpatialReference)描述 CRS,再用 OGRCoordinateTransformation(Python 为 osr.CoordinateTransformation)做点或要素坐标转换;底层依赖 PROJ。定义 CRS 可用 EPSG 代码、WKT、PROJ 字符串或 SetFromUserInput 等接口,命令行则用 gdalsrsinfo 查看信息,用 gdalwarp / ogr2ogr 做栅格、矢量重投影。从 GDAL 3.0 起默认遵循权威轴顺序(如 EPSG:4326 为 lat/long),写脚本时务必显式处理轴映射,否则极易出现 X/Y 互换。

空间参考与投影转换概念示意

怎么定义与查询空间参考

要解决的问题很直接:给数据一个可被 GDAL/PROJ 识别的 CRS 描述,并确认它是地理坐标系还是投影坐标系。Python 里通常这样起步:

  1. 创建对象:from osgeo import osr,再 srs = osr.SpatialReference()。
  2. 导入定义(任选其一):ImportFromEPSG(4326)、SetWellKnownGeogCS(“WGS84”)、ImportFromWkt(wkt_str)、ImportFromProj4(proj4_str),或最省事的 SetFromUserInput(“EPSG:4326”) / SetFromUserInput(“WGS84”)。
  3. 投影 CRS 需在地理基准之上设投影参数,例如 SetUTM(zone, north)、SetTM(…)、SetLCC(…) 等。
  4. 查询与导出:用 IsGeographic() / IsProjected() 判断类型;ExportToWkt()(可指定 WKT2 等格式)、ExportToPROJJSON()(GDAL≥3.1 且 PROJ≥6.2)、AutoIdentifyEPSG()、Validate() 做核对。

命令行可用 gdalsrsinfo 对文件、EPSG、WKT 或 PROJ 字符串做同样的事,输出格式可选 proj4、wkt、wkt2、PROJJSON、epsg 等。需要对照官方参数与选项时,可看 gdalsrsinfo 程序说明。注意:ExportToProj4() 属于遗留接口,新代码优先 WKT2 或 PROJJSON。

  • 地理 CRS 示例输入:EPSG:4326、WGS84、CRS84(经度在前的常见写法)。
  • 投影 CRS 示例:EPSG:3857、EPSG:32650(UTM 50N)或带完整参数的 WKT。
  • 从图层/数据集读出的 SRS,先 ExportToWkt() 看一眼,再决定是否 MorphToESRI() 或做轴策略调整。

怎么做坐标转换与重投影

点坐标转换与整层重投影是两件事:前者用 API 算一组 (x,y[,z]),后者用工具改数据集的几何与元数据。

API 点转换(Python)大致步骤:

  1. 分别创建源、目标 SpatialReference 并导入 CRS。
  2. (强烈建议)对两者都调用 SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER),让输入输出按传统 GIS 的 long/lat 或 easting/northing 顺序处理。
  3. ct = osr.CoordinateTransformation(src, dst)。
  4. 调用 ct.TransformPoint(x, y) 或 TransformPoints;也可在创建时传入坐标操作相关选项(高级场景)。

整数据重投影: 栅格用 gdalwarp -s_srs <源> -t_srs <目标> …,矢量用 ogr2ogr -s_srs … -t_srs …。源、目标都支持 EPSG、WKT、PROJ 字符串、.prj 文件等。垂直基准、高精度网格变换依赖 PROJ 数据是否齐全(见下文)。

场景 推荐方式 验收标准
少量点、脚本内计算 CoordinateTransformation 抽样点与已知正确结果对比,误差在预期范围内
栅格整幅重投影 gdalwarp 输出有正确 SRS;角点或控制点位置合理
矢量整层重投影 ogr2ogr 图层 SRS 正确;几何拓扑与范围符合目标 CRS
只查 SRS、不改数据 gdalsrsinfo 能识别 EPSG/WKT,且 -V 校验通过

接口细节与 C++/Python 示例见官方 OSR API 教程。截至 2026 年 11 月,稳定版 GDAL 为 3.13.x 一带,均建立在 PROJ 6+ 的 CRS 数据库与 late-binding 转换之上;构建时要求 PROJ ≥ 6.3.1。

gdalsrsinfo 官方文档页面截图
gdalsrsinfo 官方文档页面截图(截图来源:gdal.org)

GDAL 3.0 之后轴顺序怎么处理

这是实操里最容易踩坑的一点。GDAL 3.0 起默认尊重权威定义的轴顺序:EPSG:4326 为 纬度/经度,不再默认当成 long/lat。坐标转换也会按此解释,于是“写进去的是经度、读出来却当纬度”的问题很常见。

  • 默认策略一般是 OAMS_AUTHORITY_COMPLIANT。
  • 恢复传统 GIS 顺序(数据按 long/lat 或 easting/northing):对 SRS 调用 SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER)。
  • 从 GDAL 3.5 起,可用配置项 OSR_DEFAULT_AXIS_MAPPING_STRATEGY 设为 TRADITIONAL_GIS_ORDER 或 AUTHORITY_COMPLIANT,控制新建对象的默认行为。
  • 需要“经度在前”的地理 CRS 时,可用 CRS84 等替代笼统的 WGS84 写法,减少歧义。
  • 不少读写驱动会对图层 SRS 默认设成传统顺序,但你自己 ImportFromEPSG(4326) 再去做 CoordinateTransformation 时,仍要自己设策略。

验收方法:用同一对已知点(例如某城市近似经纬度)在设/不设传统轴顺序两种情况下各转一次,看结果是否互换;再与 QGIS 或已知正确结果对比。

PROJ 数据、环境变量与精度

转换能不能做、精度高不高,取决于 PROJ 资源是否到位。运行时通过 PROJ_DATA(PROJ 9.1+;旧名 PROJ_LIB 仍兼容但将弃用)指定 proj.db 与网格等资源路径,多路径在 Unix 用 :、Windows 用 ; 分隔。高精度基准变换常需要网格:PROJ 7+ 可在开启网络时从官方 CDN 拉取(如设置 PROJ_NETWORK=ON,或在 proj.ini 中打开 network),并缓存到本地;无网格时往往退化为 ballpark 转换,精度明显变差。

  • 先装齐与当前 PROJ 匹配的 proj-data,再设 PROJ_DATA。
  • 无外网环境:提前下载所需网格放到 PROJ 搜索路径,不要依赖运行时下载。
  • 怀疑路径不对:用 projinfo 或 gdalsrsinfo -V 做校验,看是否还能解析完整操作管道。
  • 证书/SSL 导致网格下载失败时,优先修好系统证书或改为本地网格,而不是关掉校验凑合用。

和空间参考直接相关的配置还有 OSR_STRIP_TOWGS84 等,一般按默认即可;只有在你明确要剥离或保留 TOWGS84 参数时再改。

常见问题

转换后的 X/Y 好像对调了,怎么修?

多半是 GDAL 3.0+ 轴顺序问题。对源、目标 SRS 都执行 SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER),或设置环境/配置 OSR_DEFAULT_AXIS_MAPPING_STRATEGY=TRADITIONAL_GIS_ORDER;输入改为与策略一致的顺序,并用已知控制点验收。

只用 EPSG 代码重投影,结果精度很差怎么办?

先确认已安装对应版本的 proj-data,并正确设置 PROJ_DATA;需要基准网格时开启 PROJ_NETWORK 或预置网格。用 gdalsrsinfo / projinfo 查看实际选用的坐标操作,避免一直落在 ballpark 路径上。

还能不能继续用 PROJ.4 字符串当主格式?

能读,但不推荐作为新代码的主交换格式。ExportToProj4() 是遗留接口,信息可能不完整;优先 WKT2 或 PROJJSON,命令行与 API 仍可把 PROJ 字符串当输入之一。

怎么快速确认某个文件的 SRS 是否可用?

对文件跑 gdalsrsinfo 你的数据,看能否识别并导出 WKT/EPSG;必要时加校验相关选项。再在 Python 里 ImportFromWkt 后调用 Validate(),并用两三点做往返转换,误差应在业务允许范围内。

处理 GDAL 空间参考与投影,记住三条:用 SpatialReference 明确 CRS、用 CoordinateTransformation 或 gdalwarp/ogr2ogr 做转换,以及在 GDAL 3+ 里主动管理轴顺序并保证 PROJ 数据完整。建议:脚本里对 EPSG 地理 CRS 一律设传统 GIS 轴顺序后再转换;上线前用 gdalsrsinfo 加少量控制点做一次往返验收,避免轴序和缺失网格这两类静默错误。