
GeoPandas 1.0+ 默认使用 pyogrio 作为底层读取引擎,而该引擎不支持 read_file() 的 crs 参数;若强行指定会触发警告且无效。正确做法是省略该参数(让 GeoPandas 自动从 .prj 文件解析 CRS),或在读取后用 set_crs() 显式设置/覆盖坐标系。
geopandas 1.0+ 默认使用 pyogrio 作为底层读取引擎,而该引擎不支持 `read_file()` 的 `crs` 参数;若强行指定会触发警告且无效。正确做法是省略该参数(让 geopandas 自动从 `.prj` 文件解析 crs),或在读取后用 `set_crs()` 显式设置/覆盖坐标系。
在使用 GeoPandas 读取 ESRI Shapefile(如 World Countries Generalized)时,你可能会遇到如下报错:
/opt/anaconda3/envs/geo_env/lib/python3.12/site-packages/pyogrio/raw.py:198: RuntimeWarning: driver ESRI Shapefile does not support open option CRS
该警告源于 pyogrio 引擎不接受 crs= 参数 —— 这是 GeoPandas 1.0 起的重大变更:默认读取后端已从 Fiona 切换为更高效的 pyogrio。而 pyogrio 的 read() 函数(对应 gpd.read_file)完全忽略 crs 参数,既不会应用它,也不会静默跳过,而是发出运行时警告。
✅ 正确做法是:不要在 read_file() 中传入 crs 参数。只要 shapefile 包含有效的 .prj 文件(标准 ESRI 投影定义),GeoPandas 就能自动识别并正确设置 CRS:
import geopandas as gpd
# ✅ 推荐:省略 crs 参数,让 GeoPandas 自动解析 .prj
shp_file = gpd.read_file('World_Countries/World_Countries_Generalized.shp')
print(shp_file.crs) # 输出: EPSG:3857(若 .prj 正确)
⚠️ 注意:手动传入 crs='EPSG:3857' 不仅无用,还会掩盖潜在问题(例如 .prj 实际定义的是 WGS84,却硬设为 Web Mercator),导致空间运算结果错误。
? 若确实需要强制指定或修正 CRS(常见于缺失 .prj、.prj 损坏或内容错误的情况),请在读取后使用 GeoDataFrame.set_crs() 方法:
# ❌ 错误(触发警告且无效)
# shp_file = gpd.read_file('data.shp', crs='EPSG:4326')
# ✅ 正确:先读取,再显式设置(allow_override=True 允许覆盖已有 CRS)
shp_file = (
gpd.read_file('data.shp')
.set_crs(crs='EPSG:4326', allow_override=True)
)
# 或:若原数据无 CRS(crs=None),可直接 set_crs(无需 allow_override)
shp_file_no_crs = gpd.read_file('no_prj.shp')
shp_file_no_crs = shp_file_no_crs.set_crs('EPSG:3857')
? 补充说明:
-
set_crs(..., allow_override=True)仅用于覆盖已有但错误的 CRS,不可滥用; - 若需转换坐标系(如从 EPSG:3857 转为 EPSG:4326),应使用
to_crs()而非set_crs(); - 可通过
shp_file.crs is None检查 CRS 是否缺失,避免后续to_crs()报错。
总之:read_file() 的 crs 参数在 pyogrio 后端下已被弃用,应彻底移除;CRS 管理应交由 set_crs()(定义)和 to_crs()(转换)两个明确语义的方法完成。










