gdal111编译版部署指南:环境变量配置与避坑实践 简介预编译的GDAL 1.11版本针对需要直接调用地理空间处理能力的开发者与GIS分析者省去从源码编译的繁琐流程开箱即用。其功能覆盖栅格数据的读取、写入、转换、裁剪与重采样同时借助OGR模块支持Shapefile、GeoJSON等矢量数据操作适合遥感影像预处理、地图制图及空间分析等场景。整个压缩包共241个文件约3.46MB结构紧凑。其中lib目录提供核心动态链接库与导入库include目录包含72个C/C头文件供二次开发调用bin目录内含22个可执行工具可直接完成格式转换data目录存放28个CSV坐标系统及投影参数文件并附带WKT、GFS等辅助数据html目录收录89个离线API文档便于查阅函数用法。此外还包含DLL、XSD、XML等文件组件齐全。当前已有297人学习下载对需要轻量化集成GDAL的工程项目这包预编译文件能显著降低环境搭建成本快速支撑从影像镶嵌、矢量合并到坐标转换的日常任务。1. 为什么还在用 gdal111一个“老版本”解决新项目依赖的实例前阵子接手一个 2015 年就冻结的 GIS 插件日志里反复出现 gdal111.dll 加载失败。GDAL gdal111 正是那套项目锁死的版本新一代机器上想直接跑没有这个 dll 一切白搭。GDAL 是栅格处理的基石库OGR 管矢量而 gdal111 指 1.11.x 这条版本线也是 GDAL 2.0 大改版之前的最后稳定线。自己从源码编一遍要准备编译器、第三方依赖还要排错而 GISInternals 这类站点把编译好的 GDAL 直接挂出来解压就能用。这份编译版对三类人最有用接手老项目要做维护的工程师、写 C/C 插件必须在 1.11 的 ABI 下编译的开发者、以及不想在编译上耗时间只想验证流程的入门者。我这次拆的就是拿到这套编译版之后从配置到调用的完整路径包括那些翻过车才知道的细节。2. 先看懂 gdal111 编译版版本脉络、文件组成与适用边界2.1 gdal111 到底指什么1.11.x 那条 GDAL 版本线gdal111 不是一个虚构的代号它对应的就是 GDAL 1.11 分支版本线最后停在 1.11.5。这个版本在 GDAL 的历史里位置很特殊它是 2.0 大改版之前的最后一个稳定线。2.0 里栅格模型、驱动体系、C API 都做了破坏性调整很多在 2014 到 2016 年之间编译的项目A依存关系全都锁死在 1.11 的接口上。从工程角度理解1.11 的 C API 已经是给后期 2.x、3.x 打样的底子GDALAllRegister、GDALOpen、RasterIO 这些函数名一直延续下来。但 C API 不一样类内部的成员布局在 2.0 里改过如果你用一个 2.x 的头文件去编译代码再运行时加载 1.11 的 dll大概率是内存布局错位直接崩溃在看似人畜无害的成员函数调用上。这就是为什么很多老项目宁可继续用 1.11也不愿意做一次看起来不太难的大版本迁移。还有一个很多人忽略的事实1.11 的 OGR 已经和 GDAL 统一成一个库了你不需要单独找什么 ogr dll。所以 gdal111.dll 这个文件里栅格驱动、矢量驱动、坐标转换核心是合在一起的出了问题排查范围会小一些。你要是见到某个资源压缩包只放了 bin 和 data 两个文件夹没有 plugins那多半是静态编译的裁剪版能用但驱动不全。2.2 编译版资源里都有什么bin、lib、data、plugins 逐个说GISInternals 这类站点给的编译版解压之后基本是这样一个布局目录 / 文件作用常见问题bingdalinfo.exe、ogrinfo.exe、gdal_translate.exe、ogr2ogr.exe、gdal111.dll缺 DLL、PATH 不指向这里libgdal_i.lib 导入库VS 工程链接时找不到includegdal.h、gdal_priv.h、ogrsf_frmts.h头文件版本和 dll 不一致datagcs.csv、pcs.csv、epsg.wkt、defaults.csv不设 GDAL_DATA 会导致坐标系统识别失败pluginsogr_* 驱动 DLL、gdal_* 驱动 DLL不设 GDAL_DRIVER_PATH 会提示驱动未注册bin 里的 gdal111.dll 是核心exe 都是依赖它来跑的。lib 目录给 C/C 开发用gdal_i.lib 是导入库链接期需要运行期不参与。include 里我特别提醒gdal.h 是 C 接口头文件gdal_priv.h 是 C 内部头文件写插件的人基本绕不开这两个。ogrsf_frmts.h 是 OGR 矢量功能的关键入口老代码里常出现。data 目录最容易被漏掉。里面那一堆 csv 和 wkt 文件是坐标系统描述表。GDAL 启动时需要读取它们否则 EPSG:4326 这种编号完全无法解析你调用投影转换会得到“unknown coordinate system”之类的报错。plugins 目录在 1.11 编译版里是把驱动拆成一个个 DLL比如矢量格式的 ogr_geojson.dll、栅格格式的 gdal_gtiff.dll。这样设计的好处是主库体积小坏处就是你少配一个环境变量驱动就悄悄缺一堆。2.3 什么场景该选编译版而不是自编译三条判断标准很多新手拿到编译版第一反应是怀疑这东西可信吗要不要自己编我的判断标准很简单满足任何一条就果断用编译版。第一条目标机器上只有运行环境没有编译器。自编译至少要装 VS 或者 mingw再拉一堆依赖库耗时长且容易中途放弃。编译版解压就能用适合交付场景。第二条你的代码是在 1.11 的 API 下写的需要精准的 ABI 兼容。自编译如果编译器版本、运行时库配置和原来的不一样编出来的 ABI 可能也有差异。GISInternals 的编译版用固定工具链反而是一个相对稳定的参照。第三条需要绿色免安装部署。编译版不需要注册表写入不需要安装服务拷贝目录就能迁移。反过来说什么情况要自编译你要裁剪驱动比如只留三五个格式你要改 GDAL 源码或者加钩子你要用的第三方库版本和编译版冲突。这几类情况编译版救不了你。3. 把 gdal111 装进项目环境变量、依赖检查和最小可运行验证3.1 环境变量配置PATH、GDAL_DATA、GDAL_DRIVER_PATH 三条命拿到编译版第一件事不是写代码而是把环境变量配好。我建议把解压目录定成一个固定路径比如 D:\gdal111然后在当前 shell 里先验证一遍export GDAL_HOME/d/gdal111 export PATH$GDAL_HOME/bin:$PATH export GDAL_DATA$GDAL_HOME/data export GDAL_DRIVER_PATH$GDAL_HOME/pluginsWindows 下这套命令的对应写法是 set PATHD:\gdal111\bin;%PATH%set GDAL_DATAD:\gdal111\dataset GDAL_DRIVER_PATHD:\gdal111\plugins。PATH 负责让系统找到 gdal111.dll 和 exeGDAL_DATA 负责坐标系统表GDAL_DRIVER_PATH 负责让 GDAL 去 plugins 目录扫驱动。三条缺一不可。我个人习惯是把 GDAL_DATA 和 GDAL_DRIVER_PATH 直接做成系统环境变量而不是只在当前 shell 里 set。因为很多时候程序不是从终端启动的而是从桌面双击、从服务管理器拉起的这些进程读不到 shell 里的临时变量。设置完之后记得把终端全部关掉重开因为 Windows 的环境变量广播只对新的进程生效。3.2 依赖排查MSVC 运行库和第三方 DLL 的检查方法解压完双击 gdalinfo.exe最常见的翻车是弹窗提示“找不到 msvcp120.dll”或者“找不到 vcruntime140.dll”。这不是 GDAL 文件损坏是机器上缺 Microsoft Visual C 运行库。GISInternals 编译的 GDAL 用的是 VS2013 或 VS2015 工具链对应需要 vc_redist 运行库。要确认某个 exe 或 dll 到底依赖什么可以用 VS 自带的 dumpbin 命令dumpbin /dependents D:\gdal111\bin\gdal111.dll输出里会列出 KERNEL32.dll、MSVCP120.dll、VCRUNTIME140.dll 这些依赖项。看到 MSVCP120 就去装 VS2013 的运行库看到 VCRUNTIME140 就去装 VS2015-2022 那个合并版运行库。注意一点dumpbin 本身需要从 VS 的开发人员命令提示符里运行普通 cmd 里找不到。不想开 VS 的话可以用 Dependency Walker 这类绿色小工具拖进去看效果一样。还有一个容易翻车的点PATH 里如果已经存在别的 GDAL比如 QGIS 自带的某个版本你会发现 gdalinfo 能跑但版本号不对或者一堆驱动显示不出来。所以检查依赖之前先跑一下 where gdalinfo确认它到底解析到哪个路径。我之前就有过一次这样的经历排查了半天依赖最后发现是 PATH 里的 QGIS 目录排在前面整个调试方向都偏了。3.3 最小化验证用 gdalinfo 和 ogrinfo 确认编译版健康环境变量配好、依赖没问题之后做一次最小化验证确认这个编译版是健康的gdalinfo --version gdalinfo D:\data\sample.tif ogrinfo --formats第一行看版本号确认是 GDAL 1.11.x而不是 PATH 里混入了别的版本。第二行找一个真实的 tif 文件打开看输出里是否包含 Driver: GTiff/GeoTIFF、Coordinate System、Size 这些关键字段。第三行列出所有矢量驱动里面必须有 ESRI Shapefile、GeoJSON 这些常见项。如果你发现 ogrinfo --formats 列出的格式列表和你解压的 plugins 目录对不上比如某驱动在 plugins 里明明有 DLL但列表里没有那就要回到 GDAL_DRIVER_PATH 的检查上。我常遇到的情况是用户把路径写错了多了一个斜杠或者空格GDAL 扫不到就静默跳过。4. 用 gdal111 干活C/C 与 Python 两种调法的落地4.1 C/C 调用include、lib 配置和 GDALAllRegister 的坑C/C 调用 gdal111 编译版本质是让链接器找到 gdal_i.lib让编译器找到头文件然后运行期让系统找到 gdal111.dll。VS 工程里三处配置C/C 附加包含目录填 include 路径链接器附加库目录填 lib 路径附加依赖项加 gdal_i.lib。最小调用代码长这样#include gdal_priv.h #include ogr_spatialref.h int main() { GDALAllRegister(); // 1.11 版本无参数注册全部驱动 GDALDataset* ds (GDALDataset*)GDALOpen(D:\\data\\sample.tif, GA_ReadOnly); if (ds NULL) { printf(open failed\n); return -1; } int width ds-GetRasterXSize(); int height ds-GetRasterYSize(); printf(size: %dx%d\n, width, height); GDALClose(ds); return 0; }这里有两个老版本的坑。第一个是 GDALAllRegister在 1.11 里它是无参函数到了 GDAL 2.x 有 GDALAllRegister 和 GDALAllRegisterEx 两个版本参数也不一样。如果你拿 2.x 的示例代码硬套编译大概率不过。第二个坑是 GDALOpen 返回的指针在 C 里要强转成 GDALDataset*因为 C 接口返回的是 void*。有些新手忘了包含 gdal_priv.h直接用 gdal.h 打开 C 数据集编译能过但成员函数调不了。调试的时候还有一个细节如果代码里调用了 GDALOpen 但忘了先调 GDALAllRegister返回值一定是 NULL而且不会给你任何错误提示。因为 GDAL 还没有注册任何驱动它根本不知道该怎么打开这个 tif。所以排查打开失败时先确认注册调用有没有执行。4.2 Python 绑定从 GDAL 2.x 退到 1.11 的兼容性注意点gdal111 时代的官方 Python 绑定做得比较完善的是 Python 2.7 和 3.4。现在的主流 Python 3.8 以上要装 1.11 的绑定pip 上很难找到对应 wheel源码编译又容易因为 Cython 和头文件版本不一致出一堆问题。我的建议是别折腾直接用 subprocess 调命令行工具import subprocess def gdal_version(): out subprocess.run( [gdalinfo, --version], capture_outputTrue, textTrue ) print(out.stdout.strip()) def translate_wgs84_to_mercator(src, dst): subprocess.run([ gdal_translate, -a_srs, EPSG:4326, -of, GTiff, src, dst ], checkTrue)gdal_translate 参数里 -a_srs 是把源文件强制赋一个坐标系统-of 指定输出格式GTiff 是 GeoTIFF。这里我特意用 subprocess 而不是 os.system因为 subprocess 能让你拿到返回码和标准输出出问题时排查方便。checkTrue 会让命令失败时直接抛异常避免流程继续跑出不可预料的结果。如果你真的需要原生 Python 绑定血泪经验是开一个干净的 conda 环境锁 Python 3.4然后用老版本的 setuptools 去编译。这个过程比较玄学遇到编译错误要反复调 include 路径我是建议非必要不碰。4.3 命令行批量处理用 gdal_translate 和 ogr2ogr 打通流程日常做批量转换编译版的命令行工具比写代码快得多。一个典型场景是把一批 WGS84 的 GeoTIFF 重投影到 Web 墨卡托for f in D:/data/src/*.tif; do name$(basename $f) gdal_translate -a_srs EPSG:4326 -t_srs EPSG:3857 -r bilinear \ -of GTiff $f D:/data/out/$name done-a_srs 声明输入坐标系统-t_srs 指定输出坐标系统-r bilinear 是重采样方法bilinear 对连续栅格效果好如果做分类图应该用 near 保持整数值。这里我习惯在命令里显式加一下环境变量前缀防止系统 PATH 被其他版本干扰GDAL_DATAD:/gdal111/data GDAL_DRIVER_PATHD:/gdal111/plugins gdal_translate ...这个写法在 bash 里是临时给单条命令设置环境变量不污染当前 shell。命令行工具是编译版里最值得反复使用的部分很多你以为要写代码的活实际一条命令就结束了。5. 避坑gdal111 编译版最常见的六个翻车现场5.1 崩溃在 GDALAllRegister插件 DLL 路径不匹配现象同一个程序在自己机器上跑得好好的拷到另一台机器就崩溃在 GDALAllRegister 这一行错误码也不稳定有时候是 0xC0000005。原因目标机器的 GDAL_DRIVER_PATH 指向了另一个 GDAL 版本的 plugins 目录或者指向了一个根本不存在的路径。GDAL 扫描到这个路径下 DLL 后尝试加载加载到和主库版本不一致的插件就崩。解决在程序入口处显式用 CPLSetConfigOption(GDAL_DRIVER_PATH, D:/gdal111/plugins) 设置路径并且用绝对路径。不要依赖系统环境变量因为环境变量在不同机器上不可控。5.2 gdalinfo 能跑但 gdal_translate 报错PATH 里混入了别的 GDAL现象gdalinfo --version 输出版本号是 1.11.5但调用 gdal_translate 做投影转换时报出“invalid SRS”或者“找不到 proj.db”之类的错误。原因两个 exe 在 PATH 里被解析到了不同路径。gdalinfo 在你配的目录里找到了gdal_translate 却被系统先匹配到了 QGIS 或者别的软件带的新版本。新版本 GDAL 2.x 用的是 proj.db 数据库你给 1.11 设置的 GDAL_DATA 里有 gcs.csv 它不认识。解决跑 where gdalinfo 和 where gdal_translate 看两个路径统一排在 PATH 最前面。我在本地习惯把编译版目录放到系统 PATH 的顶部同时把 QGIS 的路径挪到后面。5.3 中文路径和 UTF-8GDAL 1.11 的编码坑现象文件路径全英文时一切正常一旦目录里带上“数据”这样的中文名GDALOpen 返回 NULL命令行工具提示“No such file or directory”。原因Windows 控制台默认 ANSI 编码中文路径在传递时被转换成本地代码页GDAL 1.11 对路径解析走的是 C 运行时库不认这种编码转换结果。解决命令行场景下先执行 chcp 65001 切到 UTF-8 代码页代码场景里 C 接口传入路径前用 CP_UTF8 做一次转换批量处理任务干脆把中间文件全部放在英文路径下最后再改名。5.4 网盘下载的文件被杀毒误删DLL 签名和校验现象解压过程中没有任何报错但运行时提示缺 ogr_geojson.dll回头看目录plugins 文件夹里确实少了文件。原因杀毒软件把编译版里没有数字签名的 DLL 当作风险文件隔离了而且有些杀毒软件是静默处理日志里才有记录。解决解压前先临时关闭实时防护解压后把整个目录加进白名单。再校验一遍文件完整性GISInternals 页面通常会附带 MD5 或者 SHA1我每次下载后都会对一遍防止传输损坏和误删。5.5 和 Qt/其他库同时用符号冲突与运行时库不一致现象程序里同时链接了 GDAL 和另一个用到 GEOS 的库初始化正常但某个几何运算结果莫名其妙错误或者直接段错误。原因GDAL 编译版内部带有 GEOS 和 PROJ 的符号这两个符号是全局可见的。程序里如果还链接了其他版本的 GEOS/PROJ运行期符号解析就会发生覆盖行为不可预测。解决把 GDAL 相关操作封装到一个独立模块编译成单独的 dll让宿主程序通过这个 dll 间接调用避免全局符号交叉。我在实际项目里就是这么处理的从根上隔离了符号冲突。5.6 换到服务器跑不了缺少 VC 运行库现象开发机上程序正常部署到一台干净的 Windows Server 上双击 exe 直接弹“缺少 VCRUNTIME140.dll”。原因开发机装了 VS运行库齐全服务器是纯净环境没有装任何 VC 运行库。GDAL 编译版的 exe 和 dll 都依赖于这个运行库。解决在服务器上安装 vc_redist.x64.exe。不想装的话把对应版本的 msvcp140.dll、vcruntime140.dll 复制到程序目录也可以但这里要注意架构匹配x64 程序必须放 64 位版本的 dll。6. 让 gdal111 发挥余热做一套免安装的 GIS 工具链6.1 把编译版打包成绿色工具包部署的最后一公里是把编译版做成一个免安装的绿色工具包。我的做法是写一个 start.bat用相对路径代替绝对路径这样整个目录拷到哪里都能跑echo off set BASE%~dp0 set PATH%BASE%bin;%PATH% set GDAL_DATA%BASE%data set GDAL_DRIVER_PATH%BASE%plugins cd /d %BASE% gdalinfo --version这段脚本里的 %~dp0 会自动展开成 bat 文件所在的目录所以目录改名、换机器、放到 D 盘或者 E 盘都不影响。启动器放在工具包根目录所有依赖都从 bin、data、plugins 三个子目录里找不触碰系统全局环境变量。6.2 验证打包结果打包完做一次闭环验证解压到全新路径运行 start.bat确认版本号正确再用 gdal_translate 跑一次重投影最后用 ogrinfo 检查矢量驱动列表。这样一套绿色工具包可以直接交付给其它同事。我第一次打包时就吃过亏把环境变量写死在系统里换台机器部署直接抓瞎。从那以后我每次打包都强制走一遍 start.bat 相对路径再对压缩包做一次 SHA1 校验确保发给别人的东西解压即用。希望帮到你。本文还有配套的精品资源点击获取