MSVC 编译生成支持 SpatiaLite 的 GDAL

  使用 GDAL 能够非常简便地操作空间数据,并且能够支持 SpatiaLite,像操作 Shapefile 一样操作 SpatiaLite,将精力更多地放在功能的实现上。

  在 Windows 下,要想使编译出来的 GDAL 支持 SpatiaLite,需要先有编译好的 libspatialite 库,并修改编译配置项。对于 libspatialite 库,再次强烈推荐 OSGeo4W,不仅能够快速获取相关的 GIS 库,还能自动解决依赖库问题,甚至可以直接获取到编译好的 GDAL 库。

  如果希望 GDAL 只依赖所需库,可以自己配置选项并编译 GDAL,如果想尝试自己编译 SpatiaLite 及其依赖库,可以参考《MSVC 编译生成 libspatialite》。本文就是在此一系列前文的编译基础上,介绍如何针对这些自己编译的依赖库,修改配置文件,编译生成和使用 GDAL。当然,如果依赖库是从 OSGeo4W 获取或直接下载的,配置也是类似的。

版本

Visual Studio: 2015

GDAL: 2.1.3

libspatialite: 4.3.0a

编译生成

第 1 步

  下载 gdal-2.1.3.tar.xz,并解压到目标文件夹。

第 2 步

  用文本编辑器打开 …\gdal-2.1.3\nmake.opt,修改相关配置。

  1. 由于这里使用 VS2015 编译,修改第 45 行:

1
MSVC_VER=1900

  2. 修改 GDAL 默认的安装路径,在第 61 行,将 GDAL_HOME 修改为目标安装路径。

  3. 如果需要支持其他开发语言,例如我需要 GDAL 支持 C#,需要下载安装 SWIG。Windows 下可以下载 swigwin 直接使用,目前最新版本为 swigwin-3.0.12。下载解压到目标路径后,在 GDAL 的 nmake.opt 文件的第 90 行将 SWIG 修改为目标路径中 swig.exe 的路径。

  4. 如果需要编译 64 位版本,在第 189 行,取消注释:

1
WIN64=YES

  5. 配置 libspatialite 支持。在第 441 行附近可找到相关的配置。对于根据《MSVC 编译生成 libspatialite》编译生成的libspatialite,还需注意配置的路径中包含根据《MSVC 编译生成 SQLite3》的内容。

  在第 447 行,取消 SQLITE_INC 的注释,并配置路径。例如,沿用前文的习惯,头文件放在 C:\OSGeo4W\include 中,需要将 sqlite 生成的 include 目录下的 sqlite3.hsqlite3ext.h 复制到 C:\OSGeo4W\include\ 中;将 libspatialite 生成的 include 目录下的 spatialite.h 文件和 spatialite 文件夹复制到 C:\OSGeo4W\include\ 中。

  删除或注释 -DSPATIALITE_AMALGAMATION

1
SQLITE_INC=-IC:\OSGeo4w\include -DHAVE_SPATIALITE

  在第 448 行,取消 SQLITE_LIB 的注释,并同时配置前文编译生成的 spatialite_i.lib 和 sqlite3_i.lib 的路径。

1
SQLITE_LIB=C:\OSGeo4w\lib\spatialite_i.lib C:\OSGeo4w\lib\sqlite3_i.lib

  取消第 452 行的注释。

1
SPATIALITE_412_OR_LATER=yes

  整体的配置示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
# SQLite Libraries
#SQLITE_INC=-IN:\pkg\sqlite-win32
#SQLITE_LIB=N:\pkg\sqlite-win32\sqlite3_i.lib
# For spatialite support, try this instead (assuming you grab the libspatialite-amalgamation-2.3.1 and installed it in osgeo4w):
# The -DSPATIALITE_AMALGAMATION, which cause "spatialite/sqlite3.h" to be included instead of "sqlite3.h" might not be necessary
# depending on the layout of the include directories. In case of compilation errors, remove it.
SQLITE_INC=-IC:\OSGeo4w\include -DHAVE_SPATIALITE
SQLITE_LIB=C:\OSGeo4w\lib\spatialite_i.lib C:\OSGeo4w\lib\sqlite3_i.lib
# Uncomment following line if libsqlite3 has been compiled with SQLITE_HAS_COLUMN_METADATA=yes
#SQLITE_HAS_COLUMN_METADATA=yes
# Uncomment following line if spatialite is 4.1.2 or later
SPATIALITE_412_OR_LATER=yes

  注意,此配置是针对根据之前系列博文自己编译生成相关依赖库的配置。对于从 OSGeo4W 中直接获取的依赖库,是只需要 libspatialite 的路径,还是需要额外添加 sqlite3 的路径,我没有尝试过,因此无法确定。

  6. 对于其他 GDAL 支持库的配置,网上能找的很多相关内容。由于我的后续应用只需要 GEOS,这里只修改 GEOS 相关的配置。在 551 行附近可找到相关配置。

  GEOS 的编译生成,可参考《MSVC 编译 GEOS》。编译完成后,将 552 行的 GEOS_DIR 配置为编译 GEOS 的路径。

  553 行的 GEOS_CFLAGS 需要指向 geos_c.h 的路径和 geos.h 的路径。

  554 行的 GEOS_LIB 配置为 geos_c_i.lib 的路径。

  整体的配置示例如下:

1
2
3
4
# Uncomment for GEOS support (GEOS >= 3.1.0 required)
GEOS_DIR=D:\Libs\geos-3.6.1
GEOS_CFLAGS = -I$(GEOS_DIR)/capi -I$(GEOS_DIR)/include -DHAVE_GEOS
GEOS_LIB = $(GEOS_DIR)/src/geos_c_i.lib

  7. 如果 Windows 上安装了 Oracle,但不想编译的 GDAL 依赖 Oracle,可将 492 行附近关于 ORACLE support 的相关设置注释掉。

第 3 步

  管理员身份打开 VS2015 Native Tools Command Prompt(根据实际需要选择 x86 或 x64)。

1
2
3
4
cd gdal-2.1.3
nmake /f makefile.vc
nmake /f makefile.vc install
nmake /f makefile.vc devinstall

  完成后在 GDAL_HOME 路径中可找到生成的头文件、静态链接和动态链接。

使用

  设置 C++ 工程属性,选择 Configuration Properties > VC++ Directories,为 Include Directories 添加路径 ${GDAL_HOME}\include,为 Library Directories 添加路径 ${GDAL_HOME}\lib。

  选择 Configuration Properties > Linker > Input,为 Additional Dependencies 添加 gdal_i.lib

  示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include "ogrsf_frmts.h"
using namespace std;
int main()
{
GDALAllRegister();
GDALDataset* dataset = (GDALDataset*)GDALOpenEx("D:\\poi.db", GDAL_OF_VECTOR, NULL, NULL, NULL); // 打开数据
OGRLayer* layer = dataset->GetLayer(0); // 获取图层
cout << layer->GetFeatureCount() << endl; // 打印 Feature 总数
GDALClose(dataset); // 关闭数据
return 0;
}

  编译运行代码,还需要拷贝相关的 dll 文件到生成的 exe 文件下,如果 dll 不全,程序会有提示,复制相应文件即可。

  如果根据之前系列博文自己编译所有的依赖库的话,所需的 dll 文件包括:

  • libiconv.dll
  • freexl.dll
  • sqlite3.dll
  • zlib1.dll(32 位)/ zlibwapi.dll(64 位)
  • geos_c.dll
  • proj.dll
  • libxml2.dll
  • spatialite.dll
  • gdal201.dll

  程序能够正确运行,说明所有的库都成功编译生成。