在OGR官网中可以看到OGR库支持Postgresql/PostGIS数据库的读写,但是编译的时候需要加入Postgresql client library (libpq),下面就介绍一下如何编译GDAL/OGR使其可以支持Postgresql/PostGIS数据库的访问。
首先,安装Postgresql/PostGIS。安装步骤网上有好多,也并不复杂,不需要特殊设置,具体步骤可参考http://wenku.baidu.com/view/ac2b40ab284ac850ad0242f3.html。
安装完成后到安装目录C:\Program Files (x86)\Postgresql\9.2\lib下,找到libpq.lib文件,这个文件就是要在编译GDAL/OGR时加入的那个文件。为了方便起见,可以将其拷贝的浅层目录下,在这里,我将其拷贝到C盘根目录下。同时C:\Program Files (x86)\Postgresql\9.2目录下的include文件夹拷贝到C盘根目录下,这个文件夹也要添加到GDAL编译文件中。
现在,打开GDAL源码的解决方案,到Make Files文件夹中中的nmake.opt文件,定位到364行,将下面三行
# PostGIS Libraries
#PG_INC_DIR = n:\pkg\libpq_win32\include
#PG_LIB = n:\pkg\libpq_win32\lib\libpqdll.lib wsock32.lib
改为
# PostGIS Libraries
PG_INC_DIR = C:\include
PG_LIB = C:\libpq.lib
由于我已经将include文件夹和libpq.lib拷贝到C盘根目录下,所以PG_INC_DIR = C:\include,PG_LIB = C:\libpq.lib。如果你将这两个文件放到了其他目录下,那就将此处改为你存放的那个目录。
修改完成后,编译GDAL。编译成功后,将C:\Program Files (x86)\Postgresql\9.2\bin\postgisgui目录下的libpq.dll和libintl.dll文件拷贝到GDAL编译生成的目录,默认是C:\warmerda\bld\bin 下面。现在通过命令行到C:\warmerda\bld\bin 目录下运行 ogrinfo.exe --formats,出现下图结果:
下面介绍在程序里面如何读取数据库中的表。新建C++ 控制台程序,按GDAL程序的搭建步骤,在项目属性里设置好包含目录和库目录,并将编译生成的gdal110.dll和libpq.dll、libintl.dll三个文件拷贝到项目的Debug文件夹下。Postgresql数据源的连接字符串如下:
PG:dbname=postgis host=localhost port=5432 user=postgres password=renyibin
下面的代码是连接数据库,并读取数据库中名为layer1的表,显示layer1中的要素个数。
OGRRegisterAll(); const char *filePath = "PG:dbname=postgis host=localhost port=5432 user=postgres password=renyibin"; const char *driveName = "Postgresql"; const char *pLayerName = "layer1"; OGRSFDriver *pDriver = NULL; OGRLayer *pLayer = NULL; OGRDataSource *pODS = NULL; pDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driveName); if (pDriver == NULL) { cout<<"Can not get Postgresql Driver"<<endl; exit(1); } pODS = pDriver->Open(filePath,0); if (pODS == NULL) { cout<<"Can not open "<<filePath<<endl; exit(1); } pLayer = pODS->GetLayerByName(pLayerName); if (pLayer == NULL) { cout<<"Can not get layer "<<pLayerName<<endl; exit(1); } cout<<"feature count of layer1 is "<<pLayer->GetFeatureCount(1)<<endl; OGRDataSource::DestroyDataSource(pODS); system("pause");输出结果为: