35

基于 VS 2017 编译 C/C++ 与 C# 均可用的 GDAL + Proj4

 5 years ago
source link: https://mp.weixin.qq.com/s/UR1My0mKk_cCYsyPop2Qvw?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

GISer们在实际学习与研究中经常会遇到这样一个需求:基于C#开发程序界面(WinForm或者WPF),使用GDAL来实现读写GroTiff、地理空间信息获取、地理坐标系转换、地图投影定义等功能。要想达到这一步,就必须首先打通C/C++编写的GDAL与C#语言之间的连接通道,也即不仅要将GDAL的C/C+源代码编译为应用程序扩展(.DLL)文件,同时还需将Proj4的功能集成到GDAL中一起编译。本文中,小编将整个编译过程分为“4个准备工作阶段”+“3个编译阶段”+“1个应用示例阶段”,向大家讲解如何使用Visual Studio 2017来实现这一目标。

小编的编译结果

如下图,图1为编译好的GDAL目录,默认编译到"C:\warmerda\bld"目录下,图2为C#程序所需的GDAL引用,共10个DLL文件。当然这10个DLL文件不是默认就是这样位于某个目录的,而是小编经将默认位于下文将讲到的proj-5.0.2\src目录下的proj.dll,上文所说的"C:\warmerda\bld\bin"下的gdal202.dll以及位于"C:\warmerda\bld\csharp"的8个DLL程序复制到了您当前所看到的目录。

uUNR732.jpg!web

rmyuyue.jpg!web

 准备工作——下载源码与程序

  • 下载GDAL源码

小编这里下载的是GDAL2.2.0版本,当然你也可以从网址:https://trac.osgeo.org/gdal/wiki/DownloadSource下载其他版本,小编一开是下载的是最新版本2.3.1,但是发现在./swig/gdal、./swig/ogr、./swig/osr等目录下缺少很多C#源码文件(*.cs)(其实这可能是需要你自行编译),这会导致后边只能编译C/C++可用的GDAL,而无法编译C#版本的GDAL。

JBJJr2z.jpg!web

  • 下载Proj4源码

从网址https://proj4.org/download.html下载tar.gz压缩格式的Proj4源码文件,小编这里下载的是最新版5.2.0版本。若是进入官网首页https://proj4.org,则点击左侧的“Download”链接即可进入下载页面。

b6nQjmz.jpg!web

  • 下载swig程序

从网址http://www.swig.org/download.html下载swig程序的压缩文件(解压即可使用),小编这里下载的是3.0.12。若是进入swig官网首页http://www.swig.org/,则点击左侧的“Download”链接,然后在加载出来的页面http://www.swig.org/survey.html依次勾选“C#”和“Windows”,然后点击Submit,在加载出来的页面https://oligarchy.co.uk/swigsurveyresponse.cgi点击“Download area”即可进入最终的下载页面http://www.swig.org/download.html

uuyu22n.jpg!web

准备工作——解压源码文件与程序

如下图,您需要将下载的GDAL源码文件、Proj4源码文件和Swig程序文件都解压到一个您自己新建的目录里( 稍微注意下小编这里对GDAL解压的目录处理 )。具体的步骤和所需下载的文件版本,请务必详细阅看下文。(这里, 小编在桌面上新建了一个名为“compile_gdal_csharp2”文件夹,然后,将所需的文件都解压到了里面 ,最终的目录结构如下。)

7R77ZbB.jpg!web

准备工作——修改nmakep.opt文件 中的4个地方

打开gdal2.2.0根目录下的nmake.opt文件(可使用记事本、vs code、notepad++等软件),需要修改的4个地方分别位于约48行、93行、203行和534行的位置。

(1)修改C/C++编译器版本为VS2017的编译器,即使得MSVC=1910(1900则是VS2015所使用的编译器版本),具体修改如下图所示:

MzIviaJ.jpg!web

(2)修改SWIG的路径为您swig.exe的完整路径,此程序存在于解压的.\swig-3.0.12\目录下,因此可使用相对路径,小编这里使用的路径便是相对路径即..\swig-3.0.12\swig.exe,具体修改如下图所示:

juQn6zV.jpg!web

(3)修改编译的目标平台为64位(即X64),即将WIN64由NO改为YES,具体修改如下图所示:

AVFbAbf.jpg!web

(4) 添加Proj.4的支持 ,即须取消注释于编译Proj4相关的命令,将命令改为可执行状态,即只有“PROK_INCLUDE=..."和"PROJ_LIBARY=..."这两行要都须取消注释,如下两幅图为修改前后的nmake.opt配置文件命令( 其中,..\Proj5.0.2\src\proj_i.lib文件需要在下文中,编译好Proj4后才能在src目录找到 ):

vUzmUv7.jpg!web

uAfyIfr.jpg!web

准备工作——修改7个有错误的C#源码文件

下面对4个C#源代码文件的修改其实就是删除重复定义的函数。其中 OsrPINVOKE.cs源文件在./gdal-2.2.0/swig/csharp/ogr和./gdal-2.2.0/swig/csharp/osr两个目录下均存在,因此两个目录下的OsrPINVOKE.cs源文件都须修改。

(1)修改路径(./gdal-2.2.0/swig/csharp/gdal)下的GdalPINVOKE.cs文件,如下图,打开C#源码文件GdalPINVOKE.cs,

jUJb6vZ.jpg!web

(2)修改路径(./gdal-2.2.0/swig/csharp/ogr)下的ogrPINVOKE.cs文件,如下图,打开C#源码文件OgrPINVOKE.cs,

eyYneuj.jpg!web

(3)修改路径(./gdal-2.2.0/swig/csharp/ogr)下的ogrPINVOKE.cs文件,如下图,打开C#源码文件OsrPINVOKE.cs:

UvUF7r6.jpg!web

(4)修改路径(./gdal-2.2.0/swig/csharp/osr)下的osrPINVOKE.cs文件,如下图,打开C#源码文件OsrPINVOKE.cs:

UvUF7r6.jpg!web

下面对第(5)、 (6)、(7)的修改,实际上是更改数据类型, 一并可以归纳为,即在"GdalPINVOKE.BandUPCAST"、"GdalPINVOKE.DataUPCAST"和"GdalPINVOKE.DriverUPCAST"、 中间均加上“_SWIG” 。):

(5)分别修改路径(./gdal-2.2.0/swig/csharp/gdal)下的Band.cs文件(下图分别你为 修改前(前者)和修改后(后者) 的源代码:

QNrIRbq.jpg!web

(6)分别修改路径(./gdal-2.2.0/swig/csharp/gdal)下的Data.cs文件(下图分别你为 修改前(前者)和修改后(后者) 的源代码):

uaYzE3n.jpg!web

(7)分别修改路径(./gdal-2.2.0/swig/csharp/gdal)下的Driver.cs文件(下图分别你为 修改前(前者)和修改后(后者) 的源代码):

7nmaUrU.jpg!web

iYzABjr.jpg!web

编译阶段——编译Porj4源代码

  • 启用“X64编译环境”

如下图所示,在windows开始菜单打开“适用于VS 2017的X64本机工具命令提示”(因为要编译64位的GDAL,所以打开“适用于VS 2017的X64本机工具命令提示”而不是“适用于VS 2017的X32本机工具命令提示”,下文中编译C/C++源码编译为C#依赖项时也须使用该命令交互环境):

V7BFV33.jpg!web

  • 编译proj4

(1) 必须先编译Proj4,否则下边编译GDAL时,无法找在..\Proj-5.0.2\src目录下到proj_i.lib文件。 如下图所示,使用cd命令进入.\Proj4-5.2.0目录,并使用如下所示的命令执行编译Proj4源代码:

  • 编译命令: nmake /f makefile.vc install-all

RBbIZra.jpg!web

(2)编译成功后, 将在.\Proj4-5.2.0\src目录下可找到proj_i.lib静态库文件和proj.dll文件 ,前者是下文编译GDAL将要用到的库文件,后者则需在C#程序中引用。另外,编译成功后,将在计算机的C盘根目录下看到一个“PROJ”的文件夹,这是C/C++程序所用的头文件和库文件,本文中暂时用不到:

baqqq2j.jpg!web

编译阶段——编译C/C++版本的GDAL+Proj4

注意: 必须先编译Proj4,否则下边编译GDAL时,无法找在..\Proj-5.0.2\src目录下到proj_i.lib文件。

(1)在“适用于VS 2017的X64本机工具命令提示”中,使用的“cd命令”进入gdal2.2.0的根目录,并使用如下所示的命令执行编译C/C++所用的GDAL:

  • 编译命令 nmake -f makefile.vc

zAj67rr.jpg!web

(2)使用如下所示的命令将编译好的GDAL复制文件到gdal的主目录下(这将取决于namke.opt中GDAL_HOME变量的设置,默认的路径为"C:\warmerda\bld")

  • 编译命令 nmake -f makefile.vc install

RfQvYvu.jpg!web

(3)使用如下所示的命令将C/C++调用编译好的GDAL开发时所需的头文件和库文件复制到gdal的主目录下(这将取决于namke.opt中GDAL_HOME变量的设置,默认的路径为"C:\warmerda\bld")

  • 编译命令 nmake -f makefile.vc devinstall

juyUbyZ.jpg!web

编译阶段——编译C#版本的GDAL+Proj4

1) 使用“cd命令”进入..\gdal-2.2.0\swig\csharp目录 :执行如下命令编译C#版本的GDAL

  • 编译命令 nmake -f makefile.vc

IRr2aib.jpg!web

(2)完成上述过程后,在..\gdal-2.2.0\swig\csharp目录,执行如下所示的命令,将编译好的C#版本的GDAL(扩展程序*.dll,共8个)复制到GDAL的主目录的"C:\warmerda\bld\csharp"目录下:

  • 编译命令 nmake -f makefile.vc install

UBvyeiQ.jpg!web

(3)至此完成了所有的编译工作,在之前编译C/C++版本的GDAL主目录下"C:\warmerda\bld\"下,会多出来一个sharp文件夹。因此在 "C:\warmerda\bld\csharp"目录下 ,您将看到如下所示的8个dll文件,这是以后在C#程序中使用GDAL所需的程序扩展库:

2IRj2yB.jpg!web

应用阶段——C#版本的GDAL的使用示例

(1)如下图,在Visual Studio Comunity 2017中新建一个控制台程序,选择最新的“.Net Framework4.6.1即可”!

yAJRfiE.jpg!web

(2)在“解决方案管理器”窗口, 右键选择“属性” ,然后将 目标平台设置为“X64” ,具体操作如下图所示:

fUNrAbj.jpg!web

UnA7jyy.png!web

BJ3y2qq.jpg!web

如果您编译的是64位系统的GDAL和Proj4,而 没有正确配置 新建的工程项目的 目标工作平台为X64 ,即便默认为VS的Any CPU,也会 在运行程序时 遇到如下图所示的 错误信息(OSGeo.GDAL.GdalINVOKE中类型初始值设定引发异常,这是因为64位系统和32位系统对应的变量类型所占的内存空间不一致。)

qMZFvqQ.jpg!web

(3)可将之前编译好的 10个“DLL”文件 (C:\warmerda\bld\bin\目录下的1个gdal202.dll,C:\warmerda\bld\csharp目录下的8个dll文件,..\Proj-5.0.2\src目录下1个proj.dll) 放到新建的项目下的“packages”( 需要手动新建),这么建议,是因为以后,您会发现在用C#/.Net平台的包管理器Nuget引用库时,也会在此自动新建一个packages文件夹,然后将你所下载安装的包放在里面:

6ZRF7nR.jpg!web

(4)内添加对编译好的C#版本的GDAL的引用, 在“解决方案管理器”窗口中刚新建的工程下的"引用"处,右键选择“添加引用”,然后选择“浏览”,定位到packages文件夹下,选择带“_csharp.dll”的文件,然后点击确定 同时,您也需要将10个“dll”文件拷贝到Debug目录,为了日后编译发布,也最好同时拷贝到“Release”目录下,具体操作如下图所示:

ru6VBre.jpg!web

zmYzauj.jpg!web

fiMfMvu.jpg!web

(5)完成上述的GDAL的dll引用后,如下图,在新建的项目下的“Program.cs”中,首先在代码的开头,使用C#的usinng语句引入GDAL的3个命名空间,当然目前只用到了“Osgeo.GDAL”;然后,在Main函数中编写如下代码:

VVbauab.jpg!web

euURRrI.jpg!web

(6)如下图,编写完代码后,选中“解决方案“ConsoleApp1(1个项目)””,然后, 鼠标右键选择“生成” ,如果没有报错,则点击菜单栏“调试”——“ 开始执行(不调试) ”开始编译运行程序。

m6v6Jzr.jpg!web

FBFzQ3u.jpg!web

(7)最终如果您看到如下运行结果,则说明您已经成功编译了C#版本的GDAL, 值得注意的是,您编译的是具有增加了Proj4的地图投影、坐标转换等功能的GDAL 。在日后小编推出的相关文章中,您将能体会到这一点。

6J3YZvY.jpg!web

如果您 没有 在namke.opt中 添加对proj4的编译命令 (即,没有取消对proj4的编译命令的注释),则在运行涉及使用投影转换的函数时,会遇到如下图所示的 错误信息

NFjuimY.jpg!web

或者是下面这种错误信息(“开始执行(不调试)”的运行模型):

r6byArZ.jpg!web

本文讲解到此结束……若大家实际研究学习中有需求,可按照本文的编译指导来编译其他版本的GDAL,这包括了32位版系统本、集成GEOS、HDF4、HDF5、NetCDF等格式文件的读写功能的版本。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK