
简介本资源为在 Windows 平台下基于 msys2 MinGW32 方式编译完成的 GDAL 1.11.5 库面向使用 QtMinGW 版进行地理信息、遥感影像或空间数据处理开发的工程师与学习者可省去自行编译 GDAL 的繁琐过程。压缩包共 149 个文件约 74.73MB包含 63 个头文件、28 个 csv 数据表、22 个可执行工具、若干 gfs、wkt、xsd、dgn 等格式定义与示例数据以及静态库、动态库、gdal-config 与 pc 配置文件覆盖开发所需的头文件、库文件与配套数据。已有 779 人学习下载。解压后将 bin 目录加入系统环境变量并在 .pro 文件中配置 GDAL 路径即可直接调用适合需要快速搭建 GDAL 开发环境、专注业务逻辑实现的 Qt 项目。若运行中出现程序异常结束可参考作者博客中的排错思路定位依赖或路径问题。1. GDAL 1.11.5 mingw32为什么老项目还在找这个包如果你手头有一个基于 Qt MinGW 32 位工具链的 Windows 桌面程序需要在里面读 Shapefile、拼 GeoTIFF、做坐标转换那你大概率绕不开 GDAL。而当你打开 GDAL 官网发现新版本早就换成 CMake 构建、默认 MSVC 编译MinGW 32 位的预编译包几乎绝迹时才会理解为什么“GDAL 1.11.5 mingw32”这个组合到今天还有人在搜。它不是一个新东西而是一个特定历史阶段的产物Qt 4/5 时代大量 Windows 项目用 MinGW 32 位编译GDAL 1.11.5 恰好是那个时期能直接拿来链接的稳定版本。这份资源解决的核心问题很具体让你不用从源码开始折腾一整套编译环境就能在 Qt MinGW 32 位工程里直接调用 GDAL 的 C/C API。适合两类人一是维护老 GIS 桌面系统的工程师二是教学或实验环境里需要快速跑通 GDAL 读写流程的开发者。如果你用的是 MSVC 或 64 位工具链这篇的路径不完全适用但排查思路可以借鉴。2. 把 GDAL 1.11.5 接进 Qt MinGW 工程目录、头文件与链接参数2.1 先看清包里有什么再决定怎么放拿到一个 GDAL 1.11.5 mingw32 的包别急着往工程里塞。先解压看目录结构常见布局是bin/、include/、lib/三件套有的还会带share/gdal/放数据文件。bin下一般有gdal111.dll、gdalwarp.exe、gdalinfo.exe这些运行时和命令行工具include下是gdal.h、gdal_priv.h、ogr_api.h等头文件lib下是libgdal.a或gdal_i.lib这类导入库。我一般会先在磁盘上固定一个路径比如D:\dev\gdal-1.11.5-mingw32不要放在带空格或中文的目录里。MinGW 的链接器对路径里的空格处理不如 MSVC 稳这是血泪经验。放好之后用gdalinfo --version跑一下确认 DLL 能加载、版本号输出是 1.11.5。如果这一步就报缺少libstdc-6.dll或libgcc_s_dw2-1.dll说明你的 MinGW 运行时和编译这个 GDAL 的运行时不一致后面链接也会出问题。2.2 Qt .pro 文件里怎么写 INCLUDEPATH 和 LIBSQt MinGW 工程用.pro管理构建核心就是三行头文件路径、库路径、链接库名。下面是一个可抄的片段# GDAL 1.11.5 mingw32 在 Qt .pro 中的典型配置 GDAL_ROOT D:/dev/gdal-1.11.5-mingw32 INCLUDEPATH $$GDAL_ROOT/include LIBS -L$$GDAL_ROOT/lib -lgdal # 如果导入库叫 gdal_i就改成 -lgdal_i # 如果链接时报 undefined reference优先检查库名和顺序逻辑说明INCLUDEPATH让编译器找到gdal_priv.hLIBS里的-L指定库目录-lgdal告诉链接器去找libgdal.a或gdal.dll对应的导入库。参数上要注意MinGW 的库搜索顺序是从右到左如果同时链接多个库GDAL 依赖的proj、geos等要放在-lgdal后面否则会出现符号找不到。常见做法是把-lgdal放最后。还有一个坑Qt 的构建目录和运行目录不是一回事。编译通过不代表运行能加载 DLL。你需要把GDAL_ROOT/bin下的gdal111.dll以及它依赖的proj.dll、geos_c.dll复制到 exe 同级目录或者把bin加进系统 PATH。我习惯在.pro里加一条QMAKE_POST_LINK自动拷贝省得每次手动。# 构建后自动把 GDAL 运行时拷到输出目录 QMAKE_POST_LINK $$quote(cmd /c copy /Y $$GDAL_ROOT\\bin\\*.dll $$OUT_PWD\\release)这段命令在 Windows 下用cmd /c copy执行$$OUT_PWD是 Qt 的输出目录。注意release和debug要分开处理如果你用 shadow build路径会变建议先手动确认一次输出目录再写死。2.3 用 gdalinfo 和一段最小代码验证链接是否真的通了配置写完先别写业务代码。用gdalinfo命令行工具验证数据能读再用一段最小 C 代码验证 API 能调。最小代码可以是这样#include gdal_priv.h #include cpl_conv.h #include iostream int main() { GDALAllRegister(); // 注册所有驱动必须最先调用 GDALDataset* ds (GDALDataset*)GDALOpen(test.tif, GA_ReadOnly); if (ds nullptr) { std::cerr 打开失败 std::endl; return 1; } std::cout 波段数: ds-GetRasterCount() std::endl; std::cout 宽x高: ds-GetRasterXSize() x ds-GetRasterYSize() std::endl; GDALClose(ds); return 0; }逻辑说明GDALAllRegister()是 GDAL 的初始化入口不调用它后面所有驱动都不可用这是新手最容易漏的一步。GDALOpen第二个参数GA_ReadOnly表示只读写数据要用GA_Update。返回的GDALDataset*用 C 风格转换是因为 GDAL 1.x 的 C API 还没有现在这么规范。参数上GetRasterCount返回波段数GetRasterXSize/YSize返回像素尺寸这三个是后续做裁剪、重投影的基础。如果这段代码编译报undefined reference to GDALAllRegister说明链接库没对上如果运行报无法定位程序输入点说明 DLL 版本和导入库不匹配。这两种错误在 MinGW 32 位环境下很常见下一章专门拆。3. 避坑与排查MinGW 32 位链接 GDAL 的五个翻车现场3.1 现象编译报 undefined reference toGDALAllRegister原因通常有三个一是LIBS里库名写错比如实际是libgdal.a但你写了-lgdal111二是库路径-L指向的目录里根本没有导入库三是链接顺序不对GDAL 依赖的库没跟在后面。解决方法是先用dir或ls确认lib目录下的文件名再在.pro里把-lgdal放到LIBS最后一行。如果还不行用g -print-search-dirs看链接器实际搜索路径。3.2 现象程序启动时报缺少libgcc_s_dw2-1.dll这是 MinGW 运行时库缺失不是 GDAL 本身的问题。原因是你编译 Qt 工程用的 MinGW 版本和编译 GDAL 1.11.5 的 MinGW 版本不一致比如一个是 DW2 异常模型一个是 SJLJ。解决方法是找到 GDAL 包对应的 MinGW 运行时把libgcc_s_dw2-1.dll、libstdc-6.dll、libwinpthread-1.dll一起拷到 exe 目录。如果找不到就统一用 Qt 安装目录下Tools/mingw里的运行时。3.3 现象GDALOpen返回空但文件确实存在原因可能是驱动没注册或者路径里有中文。GDAL 1.11.5 对中文路径的支持取决于编译时的编码设置MinGW 下默认可能按本地编码处理。解决方法是先调用GDALAllRegister()再把路径转成 UTF-8 或短路径。我一般用CPLSetConfigOption(GDAL_FILENAME_IS_UTF8, NO)强制按本地编码读或者干脆把数据放在纯英文路径下测试。3.4 现象链接通过但调用GDALClose时崩溃这通常是 DLL 和导入库版本不匹配或者你链接的是静态库但运行时又加载了另一个版本的 DLL。解决方法是确认lib下的导入库和bin下的 DLL 来自同一个包不要混用不同来源的 GDAL。另外GDAL 1.x 的GDALClose对空指针不友好传参前先判空。3.5 现象Qt Creator 里能跑单独双击 exe 就报错原因是 Qt Creator 会把 Qt 和 MinGW 的 bin 目录加进 PATH而单独运行没有。解决方法是用windeployqt处理 Qt 依赖再手动把 GDAL 的 DLL 和 MinGW 运行时拷过去。常见做法是写一个deploy.bat把gdal111.dll、proj.dll、geos_c.dll、libgcc_s_dw2-1.dll、libstdc-6.dll一次性拷全。4. 在 Qt 界面里用 GDAL 读栅格并显示从 GDALDataset 到 QImage4.1 把 GDAL 波段数据转成 QImage 的完整流程很多 Qt GIS 程序的需求是用 GDAL 打开一张 GeoTIFF把第一个波段渲染到QLabel或QGraphicsView里。核心步骤是读波段、拉伸、转 QImage。下面是一段可复现的代码#include gdal_priv.h #include QImage QImage gdalRasterToQImage(const QString filePath) { GDALAllRegister(); GDALDataset* ds (GDALDataset*)GDALOpen(filePath.toUtf8().constData(), GA_ReadOnly); if (!ds) return QImage(); int width ds-GetRasterXSize(); int height ds-GetRasterYSize(); GDALRasterBand* band ds-GetRasterBand(1); // 取第一个波段 // 读取数据到缓冲区 std::vectorGByte buffer(width * height); band-RasterIO(GF_Read, 0, 0, width, height, buffer.data(), width, height, GDT_Byte, 0, 0); // 构造 QImage 并拷贝数据 QImage image(width, height, QImage::Format_Grayscale8); for (int y 0; y height; y) { memcpy(image.scanLine(y), buffer.data() y * width, width); } GDALClose(ds); return image; }逻辑说明RasterIO是 GDAL 读栅格的核心函数参数依次是读写标志、起始列、起始行、列数、行数、目标缓冲区、目标宽高、目标数据类型、像素间距、行间距。这里用GDT_Byte是因为 QImage 的Format_Grayscale8每像素一字节。如果原始数据是 16 位或浮点需要先做拉伸映射到 0-255否则直接转会丢精度或显示全黑。参数上0, 0表示像素和行之间无额外间距这是最紧凑的读法。4.2 波段拉伸与 NoData 处理的实际参数真实遥感影像很少是 8 位常见的是 16 位或 Float32。直接按GDT_Byte读会截断。正确做法是先读统计值再做线性拉伸。GDAL 提供GetStatistics和GetMinimum/GetMaximum但 1.11.5 里这些函数对某些格式可能返回失败需要手动算。double minVal, maxVal; band-ComputeRasterMinMax(0, minVal, maxVal); // 第二个参数 0 表示近似计算 double scale 255.0 / (maxVal - minVal); std::vectorfloat raw(width * height); band-RasterIO(GF_Read, 0, 0, width, height, raw.data(), width, height, GDT_Float32, 0, 0); std::vectorGByte stretched(width * height); for (size_t i 0; i raw.size(); i) { if (raw[i] band-GetNoDataValue()) { stretched[i] 0; // NoData 显示为黑 } else { stretched[i] static_castGByte((raw[i] - minVal) * scale); } }逻辑说明ComputeRasterMinMax第二个参数传 0 表示用采样近似速度快但可能漏掉极值传 1 表示精确计算大图会很慢。GetNoDataValue返回 NoData 值如果返回空指针说明该波段没定义 NoData需要自己判断。参数上scale是拉伸系数(raw[i] - minVal) * scale把原始范围映射到 0-255。注意浮点转GByte前要 clamp否则溢出会变成随机值。4.3 在 QGraphicsView 里做缩放和平移的注意点把 QImage 放进QGraphicsScene后缩放用QGraphicsView::scale平移用setDragMode(ScrollHandDrag)。但要注意 GDAL 读出来的影像是左上角原点而 Qt 的坐标系也是左上角方向一致不需要翻转。如果显示出来是上下颠倒检查RasterIO的行顺序或者确认数据本身是不是南向上。常见做法是先用gdalinfo看Origin和Pixel Size确认地理变换参数再决定是否翻转。5. 进阶用 GDAL 1.11.5 做坐标转换与格式导出的参数细节坐标转换是 GDAL 在 Qt 项目里另一个高频需求。1.11.5 自带OGRSpatialReference和OCTTransform可以在不依赖 proj 命令行的情况下做点转换。下面这段代码把 WGS84 经纬度转成 Web Mercator#include ogr_spatialref.h bool transformPoint(double x, double y) { OGRSpatialReference src, dst; src.importFromEPSG(4326); // WGS84 dst.importFromEPSG(3857); // Web Mercator OGRCoordinateTransformation* ct OGRCreateCoordinateTransformation(src, dst); if (!ct) return false; int ok ct-Transform(1, x, y); OCTDestroyCoordinateTransformation(ct); return ok 1; }逻辑说明importFromEPSG用 EPSG 代码初始化坐标系4326 是 WGS843857 是 Web Mercator。OGRCreateCoordinateTransformation创建转换对象失败返回空通常是因为 proj 数据文件没找到。Transform第一个参数是点数后面是 x、y 数组。参数上转换前 x 是经度、y 是纬度转换后单位是米。注意 1.11.5 的Transform是原地修改传入的变量会被覆盖。如果转换返回失败先检查GDAL_DATA环境变量是否指向share/gdal目录。GDAL 1.11.5 需要gcs.csv、pcs.csv这些文件来解析 EPSG 代码没有它们importFromEPSG会失败。我一般会在main函数开头加一行CPLSetConfigOption(GDAL_DATA, D:/dev/gdal-1.11.5-mingw32/share/gdal)把路径写死省得依赖系统环境变量。格式导出方面把内存里的 QImage 写成 GeoTIFF 需要构造GDALDriver和GDALDataset。关键参数是SetGeoTransform和SetProjection前者定义左上角坐标和像素分辨率后者定义坐标系 WKT。如果只是导出普通 TIFF 不做地理配准这两个可以省略但那样就不是 GIS 数据了。常见做法是先把 QImage 转成GByte数组再用RasterIO的GF_Write写入。最后一个习惯每次在 Qt 工程里升级或替换 GDAL 包我都会先跑一遍gdalinfo --version、再跑最小读写代码、最后跑坐标转换三步都过才动业务代码。从那以后MinGW 32 位下的 GDAL 链接问题基本没再让我返工过。希望帮到你。本文还有配套的精品资源点击获取