基於 VS 2017 編譯 C/C++ 與 C# 均可用的 GDAL + Proj4
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程式複製到了您當前所看到的目錄。
準備工作——下載原始碼與程式
-
下載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。
-
下載Proj4原始碼
從網址https://proj4.org/download.html下載tar.gz壓縮格式的Proj4原始碼檔案,小編這裡下載的是最新版5.2.0版本。若是進入官網首頁https://proj4.org,則點選左側的“Download”連結即可進入下載頁面。
-
下載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
準備工作——解壓原始碼檔案與程式
如下圖,您需要將下載的GDAL原始碼檔案、Proj4原始碼檔案和Swig程式檔案都解壓到一個您自己新建的目錄裡( 稍微注意下小編這裡對GDAL解壓的目錄處理 )。具體的步驟和所需下載的檔案版本,請務必詳細閱看下文。(這裡, 小編在桌面上新建了一個名為“compile_gdal_csharp2”資料夾,然後,將所需的檔案都解壓到了裡面 ,最終的目錄結構如下。)
準備工作——修改nmakep.opt檔案 中的4個地方
開啟gdal2.2.0根目錄下的nmake.opt檔案(可使用記事本、vs code、notepad++等軟體),需要修改的4個地方分別位於約48行、93行、203行和534行的位置。
(1)修改C/C++編譯器版本為VS2017的編譯器,即使得MSVC=1910(1900則是VS2015所使用的編譯器版本),具體修改如下圖所示:
(2)修改SWIG的路徑為您swig.exe的完整路徑,此程式存在於解壓的.\swig-3.0.12\目錄下,因此可使用相對路徑,小編這裡使用的路徑便是相對路徑即..\swig-3.0.12\swig.exe,具體修改如下圖所示:
(3)修改編譯的目標平臺為64位(即X64),即將WIN64由NO改為YES,具體修改如下圖所示:
(4) 新增Proj.4的支援 ,即須取消註釋於編譯Proj4相關的命令,將命令改為可執行狀態,即只有“PROK_INCLUDE=..."和"PROJ_LIBARY=..."這兩行要都須取消註釋,如下兩幅圖為修改前後的nmake.opt配置檔案命令( 其中,..\Proj5.0.2\src\proj_i.lib檔案需要在下文中,編譯好Proj4後才能在src目錄找到 ):
準備工作——修改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,
(2)修改路徑(./gdal-2.2.0/swig/csharp/ogr)下的ogrPINVOKE.cs檔案,如下圖,開啟C#原始碼檔案OgrPINVOKE.cs,
(3)修改路徑(./gdal-2.2.0/swig/csharp/ogr)下的ogrPINVOKE.cs檔案,如下圖,開啟C#原始碼檔案OsrPINVOKE.cs:
(4)修改路徑(./gdal-2.2.0/swig/csharp/osr)下的osrPINVOKE.cs檔案,如下圖,開啟C#原始碼檔案OsrPINVOKE.cs:
下面對第(5)、 (6)、(7)的修改,實際上是更改資料型別, 一併可以歸納為,即在"GdalPINVOKE.BandUPCAST"、"GdalPINVOKE.DataUPCAST"和"GdalPINVOKE.DriverUPCAST"、 中間均加上“_SWIG” 。):
(5)分別修改路徑(./gdal-2.2.0/swig/csharp/gdal)下的Band.cs檔案(下圖分別你為 修改前(前者)和修改後(後者) 的原始碼:
(6)分別修改路徑(./gdal-2.2.0/swig/csharp/gdal)下的Data.cs檔案(下圖分別你為 修改前(前者)和修改後(後者) 的原始碼):
(7)分別修改路徑(./gdal-2.2.0/swig/csharp/gdal)下的Driver.cs檔案(下圖分別你為 修改前(前者)和修改後(後者) 的原始碼):
編譯階段——編譯Porj4原始碼
-
啟用“X64編譯環境”
如下圖所示,在windows開始選單開啟“適用於VS 2017的X64本機工具命令提示”(因為要編譯64位的GDAL,所以開啟“適用於VS 2017的X64本機工具命令提示”而不是“適用於VS 2017的X32本機工具命令提示”,下文中編譯C/C++原始碼編譯為C#依賴項時也須使用該命令互動環境):
-
編譯proj4
(1) 必須先編譯Proj4,否則下邊編譯GDAL時,無法找在..\Proj-5.0.2\src目錄下到proj_i.lib檔案。 如下圖所示,使用cd命令進入.\Proj4-5.2.0目錄,並使用如下所示的命令執行編譯Proj4原始碼:
-
編譯命令: nmake /f makefile.vc install-all
(2)編譯成功後, 將在.\Proj4-5.2.0\src目錄下可找到proj_i.lib靜態庫檔案和proj.dll檔案 ,前者是下文編譯GDAL將要用到的庫檔案,後者則需在C#程式中引用。另外,編譯成功後,將在計算機的C盤根目錄下看到一個“PROJ”的資料夾,這是C/C++程式所用的標頭檔案和庫檔案,本文中暫時用不到:
編譯階段——編譯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
(2)使用如下所示的命令將編譯好的GDAL複製檔案到gdal的主目錄下(這將取決於namke.opt中GDAL_HOME變數的設定,預設的路徑為"C:\warmerda\bld")
-
編譯命令 : nmake -f makefile.vc install
(3)使用如下所示的命令將C/C++呼叫編譯好的GDAL開發時所需的標頭檔案和庫檔案複製到gdal的主目錄下(這將取決於namke.opt中GDAL_HOME變數的設定,預設的路徑為"C:\warmerda\bld")
-
編譯命令 : nmake -f makefile.vc devinstall
編譯階段——編譯C#版本的GDAL+Proj4
( 1) 使用“cd命令”進入..\gdal-2.2.0\swig\csharp目錄 :執行如下命令編譯C#版本的GDAL
-
編譯命令 : nmake -f makefile.vc
(2)完成上述過程後,在..\gdal-2.2.0\swig\csharp目錄,執行如下所示的命令,將編譯好的C#版本的GDAL(擴充套件程式*.dll,共8個)複製到GDAL的主目錄的"C:\warmerda\bld\csharp"目錄下:
-
編譯命令 : nmake -f makefile.vc install
(3)至此完成了所有的編譯工作,在之前編譯C/C++版本的GDAL主目錄下"C:\warmerda\bld\"下,會多出來一個sharp資料夾。因此在 "C:\warmerda\bld\csharp"目錄下 ,您將看到如下所示的8個dll檔案,這是以後在C#程式中使用GDAL所需的程式擴充套件庫:
應用階段——C#版本的GDAL的使用示例
(1)如下圖,在Visual Studio Comunity 2017中新建一個控制檯程式,選擇最新的“.Net Framework4.6.1即可”!
(2)在“解決方案管理器”視窗, 右鍵選擇“屬性” ,然後將 目標平臺設定為“X64” ,具體操作如下圖所示:
如果您編譯的是64位系統的GDAL和Proj4,而 沒有正確配置 新建的工程專案的 目標工作平臺為X64 ,即便預設為VS的Any CPU,也會 在執行程式時 , 遇到如下圖所示的 錯誤資訊(OSGeo.GDAL.GdalINVOKE中型別初始值設定引發異常,這是因為64位系統和32位系統對應的變數型別所佔的記憶體空間不一致。) :
(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資料夾,然後將你所下載安裝的包放在裡面:
(4)內新增對編譯好的C#版本的GDAL的引用, 在“解決方案管理器”視窗中剛新建的工程下的"引用"處,右鍵選擇“新增引用”,然後選擇“瀏覽”,定位到packages資料夾下,選擇帶“_csharp.dll”的檔案,然後點選確定 。 同時,您也需要將10個“dll”檔案拷貝到Debug目錄,為了日後編譯釋出,也最好同時拷貝到“Release”目錄下,具體操作如下圖所示:
(5)完成上述的GDAL的dll引用後,如下圖,在新建的專案下的“Program.cs”中,首先在程式碼的開頭,使用C#的usinng語句引入GDAL的3個名稱空間,當然目前只用到了“Osgeo.GDAL”;然後,在Main函式中編寫如下程式碼:
(6)如下圖,編寫完程式碼後,選中“解決方案“ConsoleApp1(1個專案)””,然後, 滑鼠右鍵選擇“生成” ,如果沒有報錯,則點選選單欄“除錯”——“ 開始執行(不除錯) ”開始編譯執行程式。
(7)最終如果您看到如下執行結果,則說明您已經成功編譯了C#版本的GDAL, 值得注意的是,您編譯的是具有增加了Proj4的地圖投影、座標轉換等功能的GDAL 。在日後小編推出的相關文章中,您將能體會到這一點。
如果您 沒有 在namke.opt中 新增對proj4的編譯命令 (即,沒有取消對proj4的編譯命令的註釋),則在執行涉及使用投影轉換的函式時,會遇到如下圖所示的 錯誤資訊 :
或者是下面這種錯誤資訊(“開始執行(不除錯)”的執行模型):
本文講解到此結束……若大家實際研究學習中有需求,可按照本文的編譯指導來編譯其他版本的GDAL,這包括了32位版系統本、整合GEOS、HDF4、HDF5、NetCDF等格式檔案的讀寫功能的版本。