本文共 5020 字,大约阅读时间需要 16 分钟。
gdal是著名的开源GIS数据操作库,包括arcgis在内的软件都在用它。
官网地址如下:
支持的格式很多。包括 基础的图片png,gif,jpg,tiff,bmp
pci,erdas,arcinfo的遥感影像数据
shp,tab,mif等的矢量文件
oracle spatial,postsql的空间数据库
打算结合qt做一些相关的学习性开发,走了不少弯子。因为是打算抛开微软的那一套来开发,所以也麻烦了许多。
编译器采用的是MinGW,我用的版本是4.5,下载地址如下:
gdal的源码最新版本是1.7.3,下载地址如下:
安装好MinGW后,通过MinGW的shell进入到gdal的源码根目录
运行
./configure --prefix=$PATH_TO_INSTALL_GDAL_ROOT --without-libtool --without-python
说明一下:
PATH_TO_INSTALL_GDAL_ROOT是一个变量,表示要build gdal到哪个目录
--without-libtool 表示不生成.a文件(如果要交叉编译生成linux下的静态库,可以不加这项)
--without-python 表示不生成python可用的相关文件
完整的命令是 ./configure --prefix=/d/gis/gdal
这样就生成了makefile,如果没有报错,那么继续运行
make
我在过程中一直报错,折腾了一天,查了很多资料,才知道是GNUMakefile.opt文件中的路径错了,
需要将 12行之前的 "$(GDAL_ROOT)" 替换成 句点 "."
再次make,终于生成了一堆o文件(相当于win平台的obj文件),时间稍微有点久(这编译效率,比.net差远了)
如果一路顺利,继续运行
make install
会在D:\gis\gdal 目录下生成一些文件,包括一些头文件和一个libgdal.dll(20多m,可能是编译时乱七八糟的都加进去了,暴大的一个dll)
而gdal-1.7.3目录下自身也生成了许多中间文件,搞得本来几m的文件夹变成了几百m。
不太懂gcc,也不太懂configure,使得中间文件全都留在那里。
到此,终于可以用在qt中使用gdal了。
我使用的是qt库的4.6.2版本,当前最新是4.7.1了,新版本包括了一些meego的东西。
ide用的是自家的qt creator ,最新版本是2.0
新建了一个控制台的工程,在main.cpp中的代码如下:
#include < QtCore / QCoreApplication > #include < iostream > #include " include/gdal/ogrsf_frmts.h " using namespace std; int main( int argc, char * argv[]) { QCoreApplication a(argc, argv); OGRRegisterAll(); OGRDataSource * poDS; poDS = OGRSFDriverRegistrar::Open( " ZW0817P.shp " , FALSE ); if ( poDS == NULL ) { printf( " Open failed.\n " ); exit( 1 ); } OGRLayer * poLayer; poLayer = poDS -> GetLayerByName( " point " ); OGRFeature * poFeature; poLayer -> ResetReading(); while ( (poFeature = poLayer -> GetNextFeature()) != NULL ) { OGRFeatureDefn * poFDefn = poLayer -> GetLayerDefn(); int iField; for ( iField = 0 ; iField < poFDefn -> GetFieldCount(); iField ++ ) { OGRFieldDefn * poFieldDefn = poFDefn -> GetFieldDefn( iField ); if ( poFieldDefn -> GetType() == OFTInteger ) printf( " %d, " , poFeature -> GetFieldAsInteger( iField ) ); else if ( poFieldDefn -> GetType() == OFTReal ) printf( " %.3f, " , poFeature -> GetFieldAsDouble(iField) ); else if ( poFieldDefn -> GetType() == OFTString ) printf( " %s, " , poFeature -> GetFieldAsString(iField) ); else printf( " %s, " , poFeature -> GetFieldAsString(iField) ); } OGRGeometry * poGeometry; poGeometry = poFeature -> GetGeometryRef(); if ( poGeometry != NULL && wkbFlatten(poGeometry -> getGeometryType()) == wkbPoint ) { OGRPoint * poPoint = (OGRPoint * ) poGeometry; printf( " %.3f,%3.f\n " , poPoint -> getX(), poPoint -> getY() ); } else { printf( " no point geometry\n " ); } OGRFeature::DestroyFeature( poFeature ); } OGRDataSource::DestroyDataSource( poDS ); return a.exec(); }
说明一下:
#include "include/gdal/ogrsf_frmts.h"
我是将之前make install编译生成的gdal下的include和lib文件复制到项目文件夹中
除了include这个头文件外,还要在项目的pro文件中加入一行
LIBS += D:\\gis\\gdal\\lib\\libgdal.dll
这是告诉编译器要去链接这个dll.这样一来就可以build了。
生成的exe默认在proname-build-desktop\debug下
可是运行的时候会报不到libstdc++-6.dll,libgcc_s_dw2-1.dll,这两个文件在MinGW安装目录的bin目录下,
然后还会报libgdal,找不到
接着还有QtCore4.dll,QtCored4.dll,mingw10.dll, 这几个文件在qt安装目录的qt\bin目录下
要将以上6个dll全数copy到运行目录下才行。
如果在项目的pro文件中加入一行 config += static 的话,则编译器会将libgdal编译到exe文件中
而mingw和qt的dll,因为不太熟悉makefile的写法,我还没找到将其静态编译到exe文件中的办法,否则在没有安装mingw和qt的机器上运行时需要拷贝这些dll过去
。一个解决方法是可以用vc的depends工具看到底需要哪些dll,这样全都复制到运行目录下。
就这样,把gdal库用成还真tnnd的费劲,在vc上编译了一下,要方便得多:(
而自己的摸索的过程中查阅了很多资料,也花费了很多时间,想说的是自学的效率真的是不高,并且到现在也还没彻底搞懂.C++编译的究竟。
总结:
MinGW是将gcc,gdb移植到windows的编译环境,而cygwin,msys是在windows上模拟linux、unix的运行环境。
对configure,make的用法还不熟。
对静态、动态编译的方法还不够了解,以致对def,lib,a,dll,so等文件的理解也不够清楚。
接下来会继续对gdal的ogr部分做一些学习,以理解gis数据的存储模型。
参考文档:
configure命令的使用:
libtool的作用和用法:
MinGW编译GDAL的方法:
qt creator的工程文件pro的常用参数说明:
qt动态编译生成可执行文件的依赖
重新静态编译qt的方法
gdal for c++ api 入门示例
转载地址:http://halgb.baihongyu.com/