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()(转换)完成两种明确语义的方法。