WIN10和VS2019环境下编译GDAL详细步骤

Detailed steps of compiling GDAL under environment of win10 and vs2019

1. 引言

对于很多GIS、遥感等地学专业的同学来说,GDAL并不陌生。

GDAL(Geospatial Data Abstraction Library)是一个开源的栅格或矢量空间数据转换库,提供对多种栅格数据的支持,包括ASC,GeoTiff,IMG等。它可以利用抽象数据模型来表达所支持的各种文件格式,有一系列函数功能库来进行数据处理。在这里不再详细介绍GDAL,如果想了解更多,可参考GDAL官方网站https://gdal.org/

因为GDAL是个开源库,应用环境多样,所以官方并不提供各种应用环境下的编译版本,仅提供源码。如果需要使用GDAL,则必须在用户当前系统环境下进行编译。这便是本文主要介绍的内容,如何成功编译GDAL!

本文介绍编译GDAL的环境:WIN10 x64VS2019;GDAL版本:GDAL3.0

当然,有同学怕麻烦,从网上直接找懒人包(已编译好的GDAL版本),但是,在这里我要提醒一下,懒人包不一定香。正如前面介绍的,为什么GDAL需要自行编译,就是因为应用环境多样,网络上并不一定能找到合适自己系统环境的GDAL编译版本。如果没找到对的(很大概率),先不说无法使用,就算可以使用了,难免会遇到各种因版本不兼容而导致的问题,不如“自己动手,丰衣足食”。

2. 准备与下载

GDAL3.0编译依赖PROJ6投影库,PROJ6要求SQLite3环境。所以在编译GDAL之前,需要先编译SQLite和PROJ6。除了下载所需要的源码,还有一个很重要的编译工具,CMAKE

1GDAL官方下载地址为https://gdal.org/download.html,我下载的版本是gdal-3.0.0

2PROJ6官方下载地址为https://proj.org/download.html,我下载的版本为proj-6.3.2

3SQLite3的官方下载地址为https://www.sqlite.org/download.html,打开网址,下载Source Code下的sqlite-amalgamation-3330000.zip,和Precompiled Binaries for Windows下的sqlite-dll-win64-x64-3330000.zipsqlite-tools-win32-x86-3330000.zip

4CMAKE的官方下载地址为https://cmake.org/download/,我下载的是cmake-3.18.1-win64-x64.msi文件,下载后可直接双击安装。安装之后添加系统环境变量,以便在CMD命令行中使用。

为了文件组织清晰且方便编译,将下载的文件分别解压在C盘的根目录GDALPROJSQLite文件夹内,其中,SQLite的三个文件解压在SQLite文件夹中。

注意事项和补充说明

---- 下载的版本最好与自己的系统版本一致,比如我的电脑是64位,我下载的都是64位的版本。

---- CMAKE是一个软件工具,用作源码编译,PROJ6源码中有cmake指令文件,可直接用CMAKE软件编译。

3. 编译和安装

3.1 编译SQLite静态库

在SQLite目录下创建一个新的VS项目,创建时选择“空项目”。

项目创建完成之后,将SQLite文件夹中的sqlite3.csqlite3.hsqlite3ext.hsqlite3.def四个文件添加到项目中,添加位置如下图所示。

设置预定义处理,打开项目属性窗口,C/C++ -> 预处理器 -> 预处理器定义,替换为以下内容:

_USRDLL
SQLITE_ENABLE_RTREE
SQLITE_ENABLE_COLUMN_METADATA
SQLITE_ENABLE_FTS5
SQLITE_ENABLE_UNLOCK_NOTIFY
					

设置模块定义文件

打开项目属性窗口,链接器 -> 输入 -> 模块定义文件:sqlite3.def

注意事项

---- 这里要输入绝对路径,否则后续过程容易出错。


修改模块定义文件

打开sqlite3.def,在最后追加一行:

sqlite3_unlock_notify

项目配置类型改为静态库lib

打开项目属性窗口,配置属性 -> 常规。


最后,生成解决方案,我以Debug版本为例。

C:\SQLite\SQLite3\x64\Debug文件夹可以看到SQLite3.lib静态库和SQLite3.exe

(Release版在F:\SQLite\SQLite3\x64\Release文件夹中)。

SQLite目录中分别创建includelibbin文件夹,将刚才生成的.lib文件放入lib文件夹中,将sqlite3.hsqlite3ext.h放入include中,将sqlite-tools-win32-x86-3280000.zip中的sqlite3.exe放在bin文件夹中。

注意事项

---- 如果在这里生成Debug版本,那后后续编译GDAL也需要选择Debug,如果需要Release版本需要重新编译GDAL版本,反之亦然。

3.2 编译PROJ6

首先,将下载好的proj-6.3.1解压到PROJ文件夹内,在源码目录中创建build文件夹。

然后,打开cmake软件,添加source code和build路径,如下图所示。


点击Configure,弹出版本选择窗口.

选择vs2019版本,编译64位,点击“Finish”。


之后开始创建,在这过程中,会弹出错误窗口,如下图所示。

莫慌,正常

点击“OK”,找到列表中Name为EXE_SQLITE3SQLITE3_INCLUDE_DIRSQLITE3_LIBRARY的三个属性,可以看到现在它们的Value值都为NOTFOUND状态,也就是SQLite环境为空。这时,需要将SQLite3.exeincludeSQLite3.lib的路径分别赋给这三个属性。


重新点击Configure,完成后会在下方提示Configuring done。

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

注意事项

---- cmake完成后会创建文件生成目录,我设置的是C:/OSGeo4W

打开x64 Native Tools Command Prompt for VS 2019(一般在开始菜单安装VS2019的文件夹里能找到),cd到build文件夹。

然后输入命令(分别输入,第一个运行完,输入第二个运行)

msbuild ALL_BUILD.vcxproj /p:Configuration="Debug"
msbuild INSTALL.vcxproj /p:Configuration="Debug"

开始编译(编译Release版是将上述命令中引号里面的Debug改为Release)。



这时,可以在设置的文件生成目录中找到生成的文件,并检查是否生成成功。

bin中有各种可执行exe文件、include中有头文件、lib中是静态库文件等。


至此,PROJ编译完成!

3.3 编译GDAL

安装好GDAL的依赖环境后,开始编译和安装GDAL。

首先,将下载的GDAL3.0.0压缩包解压到GDAL文件夹内。

进入GDAL3.0.0库文件夹中,找到nmake.opt文件,用VS2019打开,或者文本编辑器(我习惯用Notepad++,推荐),修改GDAL相关配置,比如添加PROJ、SQLite环境(路径)。

第45行左右,MSVC_VER=,设置为1921(VS2019版本);
第59行左右,GDAL_HOME=,将生成GDAL文件的路径设置为你要存放GDAL的位置,我设置的是"C:\GDAL";
第189行左右,找到WIN64=YES,如果生成64位版本,取消注释,反之亦然;
第227行,左右找到DLLBUILD=, 1启动动态编译、0为静态编译。我进行静态编译,设置DLLBUILD=0;
第249行左右,找到PROJ_INCLUDE和PROJ_LIBRARY,分别设置成你刚才生成PROJ时的include和lib文件夹, 在PROJ_INCLUDE的“-I”后修改地址,并将.lib的名称对应修改为你的lib名。
第495行左右,找到SQLITE_INC和SQLITE_LIB,同样的方式,设置SQLite路径。
					

设置完成后,保存文件。

注意事项

---- 上述行数,不同版本不一样,但位置接近,也可以搜索寻找。

修改完成后,打开x64 Native Tools Command Prompt for VS 2019,cd进入库文件夹,输入以下命令(Debug版):

nmake /f makefile.vc WIN64=YES DEBUG=1
nmake /f makefile.vc install
nmake /f makefile.vc devinstall

如果是Release版,可输入以下命令:

nmake /f makefile.vc
nmake /f makefile.vc devinstall

编译和安装完成后,可以在GDAL文件夹下看到5个文件夹:bindatahtmlincludelib

至此,GDAL编译完成,恭喜恭喜!

4. 使用和测试

在VS项目中使用GDAL,只需要在项目属性中添加GDAL目录,并引用.h头文件即可。


1
2
#include <gdal.h>
#include <gdal_priv.h>

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* GDAL GeoTiff*/
void readRaster()
{
    // 支持中文路径
    CPLSetConfigOption("GDAL_FILENAME_IS_UTF8""NO");
    //注册所有的驱动 
    GDALAllRegister();
 
    //GDAL数据集 
    GDALDataset* dataset;
    dataset = (GDALDataset*)GDALOpen(inRaster, GA_ReadOnly);
 
    if (dataset == NULL)
    {
        cout << "Failed in open files!!!" << endl;
        throw;
    }
 
    // 获取数据行列数 
    nRows = dataset->GetRasterYSize();
    nCols = dataset->GetRasterXSize();
 
    //获取坐标变信息
    dataset->GetGeoTransform(geotrans);
    dx = geotrans[1];
    xMin = geotrans[0];
    xMax = geotrans[0] - nCols * geotrans[1];
    yMax = geotrans[3];
    yMin = geotrans[3] - nRows * geotrans[5];
 
    //获取投影信息
    srs = dataset->GetProjectionRef();
 
    //获取波段 
    GDALRasterBand* band;
    band = dataset->GetRasterBand(1);
 
    // No data value
    noDataValue = band->GetNoDataValue();
 
    //读取数据 
    //scanline = new BYTE[nRows * nCols];
    dataLine = (float*)CPLMalloc(sizeof(float) * (nCols) * (nRows));
    band->RasterIO(GF_Read, 0, 0, nCols, nRows, dataLine, nCols, nRows, GDALDataType(band->GetRasterDataType()), 0, 0);
    //band->RasterIO(GF_Read, 0, 0, nCols, nRows, scanline, nCols, nRows, GDT_Float64, 0, 0);
 
    // 关闭数据集
    GDALClose(dataset); 
}

注意事项

---- 以上代码为GDAL测试代码类函数的定义部分,不能直接运行,如果参考可自行修改补充!


建议使用Google浏览器,IE内核浏览器可能不正常显示下载按钮等!


Fighting, GISer!

最新博文