Windows下GDAL3.1.2编译 (VS2015)

    科技2022-07-13  141

    前言

    GDAL(Geospatial Data Abstraction Library )是一个使用C/C++语言编写的操作各种地理数据格式的跨平台的,开源库。

    现有的大部分GIS或者遥感平台,不论是商业软件ArcGIS,ENVI还是开源软件GRASS,QGIS,都使用了GDAL作为底层构建库。

    GDAL库由OGR和GDAL项目合并而来,OGR主要用于空间要素矢量数据的解析,GDAL主要用于空间栅格数据的读写。另外,空间参考及其投影转换使用开源库 PROJ.4。

    GDAL提供了C/C++接口,并且通过SWIG提供了Python,Java,C#等的调用接口。当我们在Python中调用GDAL的API函数时,其实底层执行的是C/C++编译的二进制文件。

    GDAL不但提供了API接口方便开发人员开发自己的功能,而且还提供了一系列实用工具可以实现方便快速的空间数据处理。

    GDAL3.0以上编译依赖PROJ6投影库,而PROJ6的proj.db使用sqlite存储数据,所以又依赖SQLite3环境,所以在编译GDAL之前我们需要先编译SQLite和PROJ6。

    安装(编译)工具 cmake官方下载地址为https://cmake.org/download/。目前最新版3.18.3。windows x64有cmake-3.18.3-win64-x64.zip和cmake-3.18.3-win64-x64.msi两个版本下载。

    一、SQLite3编译

    1、下载

    下载地址:https://www.sqlite.org/download.html 下载版本:3.33.0

    下载内容:

    Source Code下的sqlite-amalgamation-3330000.zipPrecompiled Binaries for Windows下的sqlite-dll-win64-x64-3330000.zip,sqlite-tools-win32-x86-3330000.zip

    2、解压

    将下载的文件解压到sqlite-3.33.0文件夹内,如下所示:

    sqlite-3.33.0 ├─sqlite-amalgamation-3330000 │ shell.c │ sqlite3.c │ sqlite3.h │ sqlite3ext.h ├─sqlite-dll-win64-x64-3330000 │ sqlite3.def │ sqlite3.dll └─sqlite-tools-win32-x86-3330000 sqldiff.exe sqlite3.exe sqlite3_analyzer.exe

    3、创建静态库工程

    在sqlite-3.33.0目录下创建一个空的c++工程,工程名为SQLite3将sqlite3.c、sqlite3.h、sqlite3ext.h、sqlite3.def四个文件添加到工程中 C/C++ --> 预处理器 --> 预处理器定义:设置预定义处理 _USRDLL SQLITE_ENABLE_RTREE SQLITE_ENABLE_COLUMN_METADATA SQLITE_ENABLE_FTS5 SQLITE_ENABLE_UNLOCK_NOTIFY

    设置模块定义文件,链接器 --> 输入 --> 模块定义文件:sqlite3.def

    修改模块定义文件:在最后追加sqlite3_unlock_notify

    配置类型改为静态库lib

    最后生成解决方案,在D:\sqlite-3.33.0\SQLite3\x64\Debug文件夹可以看到SQLite3.lib静态库。

    在SQLite目录中分别创建include和lib和bin文件夹,以备后用。 将刚才生成的.lib文件放入lib文件夹中, 将sqlite3.h、sqlite3ext.h放入include中, 将sqlite-tools-win32-x86-3330000中的sqlite3.exe放在bin文件夹中。

    二、PROJ6编译

    gdal的编译依赖于PROJ6投影库,否则会有如下提示。

    PROJ_INCLUDE should be defined. PROJ >= 6 is a required dependency

    1、下载

    下载地址:https://proj.org/download.html 下载版本:6.3.2

    将下载后文件解压到D:\proj-6.3.2文件夹内。

    2、配置编译项

    在源码目录中创建build文件夹,打开cmake-gui.exe

    点击Configure,编译64位,vs2015 点击Finish,会出现错误。 SQLITE3_INCLUDE_DIR和SQLITE3_LIBRARY属性,可以看到现在它们的Value值都为NOTFOUND的状态,设置为前边准备的include和SQLite3.lib的路径。 如果EXE_SQLITE3也提示NOFOUND的话,修改为相应的SQLite3.exe的路径。 设置文件生成目录,我设置的是D:/proj-6.3.2/OSGeo4W。 重新点击Configure,提示Configuring done。

    点击Generate,这时可以看到build文件夹里有PROJ4.sln。

    3、编译

    打开【VS2015 x64 本机工具命令提示符】,进入D:\proj-6.3.2\build文件夹,执行编译

    msbuild ALL_BUILD.vcxproj /p:Configuration="Release"

    警告,是因为这个文件中有特殊字符的注释文字。可以忽略。

    执行如下,整理编译的成果物。 bin中有各种*.exe文件、 include中放有头文件、 lib 中是静态库文件、share放有一些数据文件。

    msbuild INSTALL.vcxproj /p:Configuration="Release"

    debug版是将上边命令行的Release改为Debug。

    三、GDAL3编译

    1、下载

    下载地址:官网地址       OSGeo Download Server 下载版本:3.1.2

    将下载的gdal-3.1.2.tar.gz解压到D:\gdal-3.1.2-src文件夹内。

    2、修改编译参数

    进入D:\gdal-3.1.2-src文件夹中,找到nmake.opt文件,用VS2015打开。 nmake.opt中参数的设置含义,请参见链接。

    第42行左右,找到MSVC_VER=设置为1900(1900是指 VS 版本为2015,1910是指 VS 版本为2017,1921是指 VS 版本为2019)。第66行左右,找到GDAL_HOME =位置为你想编译后输出的路径,比如"D:\gdal-3.1.2-bld"。第207行左右,找到WIN64=YES,如果固定生成64位版本,就取消注释本行。第234行左右,找到DLLBUILD=设置为1启动动态编译、 0为静态编译。第254行左右,找到PROJ_INCLUDE,PROJ_LIBRARY。分别设置成PROJ6的include和lib文件夹(其中PROJ_INCLUDE的-I后为地址)。第642行左右,找到SQLITE_INC,SQLITE_LIB。设置方式同上。

    3、编译

    打开【VS2015 x64 本机工具命令提示符】,进入D:\gdal-3.1.2-src文件夹,执行以下命令。

    nmake /f makefile.vc //编译64位的release版本,如果不是固定为64,可以通过参数WIN64=1 nmake -f makefile.vc DEBUG=1 //编译64位的debug版本 nmake /f makefile.vc devinstall // 编译release版本并安装开发头文件和库文件 nmake -f makefile.vc clean // 清理编译

    打开安装目录下的文件夹有bin,data,lib,include几个文件夹。

    四、测试

    1、设置项目环境

    打开vs2015,新建一个 c++ 空项目。 点击【视图->其他窗口->属性管理器】,打开属性管理器。

    选择Deubg|X64的Micsoft.Cpp.x64.user,点击右键。

    在VC++目录依次添加包含目录、库目录 链接器->输入添加附加依赖项,手动输入gdal_i.lib

    2、新建cpp文件

    新建一个main.cpp文件,添加代码:

    #include <iostream> #include <iomanip> #include "gdal_priv.h" using std::cout; /* @brief 计算图像行列号在给定坐标系下对应的地理坐标 @param x 行号 @param y 列号 @param coords 返回的地理坐标 @param transform 变换的六参数 */ void toGeoCoord(int x, int y, double* coords, double* transform) { coords[0] = transform[0] + x * transform[1] + y * transform[2]; coords[1] = transform[3] + x * transform[4] + y * transform[5]; } /* @brief 读取数据并输出元数据信息 @param fileName 数据文件路径 @return 数据读取失败返回1,读取成功返回0 */ int readGeoRaster(const char* fileName) { GDALAllRegister(); // 注册所有支持的数据格式驱动 GDALDataset* dataset = static_cast<GDALDataset*>(GDALOpen(fileName, GA_ReadOnly)); // 以只读模式打开给定的数据文件 if (!dataset) { cout << "影像读取失败:(" << fileName << ")!" << '\n'; return EXIT_FAILURE; } int nSizeX = dataset->GetRasterXSize(); // 影像的宽度(像元数目) int nSizeY = dataset->GetRasterYSize(); // 影像的高度(像元数目) int nBandCount = dataset->GetRasterCount(); // 影像波段数 cout << "图像大小:(" << nSizeX << ", " << nSizeY << ")\n"; cout << "波段数:" << nBandCount << "\n"; double adfGeoTransform[6]; // 存储图像的六参数信息 dataset->GetGeoTransform(adfGeoTransform); // 获取数据的六参数信息 double adfULCoord[2]; // 图像左上角坐标 double adfLRCoord[2]; // 图像右下角坐标 // 获取左上角和右下角的地理坐标 toGeoCoord(0, 0, adfULCoord, adfGeoTransform); toGeoCoord(nSizeX - 1, nSizeY - 1, adfLRCoord, adfGeoTransform); cout << std::fixed; // 对于double类型的数据可以使其正常输入,阻止默认的科学计数法输出, cout << "左上角坐标:(" << adfULCoord[0] << ", " << adfULCoord[1] << ")\n"; cout << "右下角坐标:(" << adfLRCoord[0] << ", " << adfLRCoord[1] << ")\n"; const char* pszProj = dataset->GetProjectionRef(); // 获得WKT形式的投影信息 cout << "投影信息:" << pszProj << '\n'; GDALClose(dataset); // 关闭数据集 return EXIT_SUCCESS; } int main() { const char* pszFileName = R"(D:\test\img.tif)"; return readGeoRaster(pszFileName); }

    3、编译执行

    执行结果如下:

    D:\Project\GdalTestCPP\x64\Debug>GdalTestCPP.exe 图像大小:(1147, 615) 波段数:4 左上角坐标:(0.127203, -89.249658) 右下角坐标:(0.128073, -89.249192) 投影信息:GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]

    提示:

    找不到gdal301.dll。把gdal编译的bin目录增加到环境变量Path中。找不到pro.db。解决方法是设置环境变量PROJ_LIB,将其路径设定到你share文件夹下proj文件夹中,因为在那里面有pro.db文件。
    Processed: 0.012, SQL: 8