MSVC2019でのGDAL環境構築

C++初心者がGDAL環境構築のために調べたことを備忘録として綴ります。
GDALをMicrosoftVisualstudioCommunity2019 C++(x64)で使うための環境構築です。
#ダウンロード
+ <b>MicrosoftVisualStudio2019Community </b>


+ <b>GDAL</b>
https://gdal.org/download.html
から、gdal-3.2.1.tar.gzをダウンロードして「C:\dev\gdal321」に展開

+ <b>PROJ</b>
https://proj.org/install.html#windows
を参考にOSGEO4Wを利用し、インストール

<h1>nmake.optの設定</h1>
「C:\dev\gdal321」内の「nmake.opt」をテキストエディタ等で開きます。

### MSVC_VER
「MSVC_VER=1900」をすべて「MSVC_VER=1926」に変更します。

<details><summary><b>MSVC2019でのMSVC_VERの値について</b></summary>
ファイル内では以下のように
「MSVC2015」と「MSVC2017」の記載しかなくMSVC2019の数値がわからない。
海外サイトを調べたところ「1920」の場合と「1926」で実行している人がいました。
どちらが正しいか、どちらも正しくないかはわかりません。
とりあえずは「1926」で動いている。
<div> 

```nmake.opt
###############################################################################
# Check version of Visual C++ compiler:
# nmake -f makefile.vc MSVC_VER=xxxx
# where xxxx is one of following (older versions no longer supported):
# 1910 = 15.0(2017)
# 1900 = 14.0(2015)
#

!IFNDEF MSVC_VER
#assume msvc VS2015.
MSVC_VER=1900
!ENDIF

###############################################################################
``` 
</div>
</details>


### PROJ
1.　PROJ項の2行目(全体の260行目)と6行目(全体の264行目)のハッシュタグ(#)を外します。
2.　それぞれ、PROJをインストールしたフォルダのパスに変更します。
　「#PROJ_INCLUDE = -Id:\install-proj\local\include」
　　⇒「PROJ_INCLUDE = -IC:\OSGeo4W64\include」
　
　「PROJ_LIBRARY = d:\install-proj\local\lib\proj_6_0.lib shell32.lib ole32.lib」
　　⇒「PROJ_LIBRARY = C:\OSGeo4W64\lib\proj.lib」

```nmake.opt__PROJ変更前
# PROJ stuff (required dependency: PROJ >= 6)
#PROJ_INCLUDE = -Id:\install-proj\local\include
# Note: add shell32.lib is needed starting with PROJ 7.0 in some circumstances
# for static linking. See https://github.com/OSGeo/gdal/issues/2488
# And ole32.lib also since PROJ 7.1 (see https://github.com/OSGeo/gdal/issues/2743)
#PROJ_LIBRARY = d:\install-proj\local\lib\proj_6_0.lib shell32.lib ole32.lib
```

```nmake.opt__PROJ変更後
# PROJ stuff (required dependency: PROJ >= 6)
PROJ_INCLUDE = -IC:\OSGeo4W64\include
# Note: add shell32.lib is needed starting with PROJ 7.0 in some circumstances
# for static linking. See https://github.com/OSGeo/gdal/issues/2488
# And ole32.lib also since PROJ 7.1 (see https://github.com/OSGeo/gdal/issues/2743)
PROJ_LIBRARY = C:\OSGeo4W64\lib\proj.lib
# shell32.lib ole32.lib
```

<details><summary><b>proj_6_0.lib、shell32.lib、ole32.libについて</b></summary>
　複数の方法でPROJ7.2.1をインストールしたが、「proj_7_0.lib、shell32.lib、ole32.lib」のようなファイルはなく、同フォルダ内に「proj.lib」のみが存在した。
　ここでは「proj.lib」にリンクをつなげているが不具合は確認できていない。
</details>


<h1>ソースコードのビルド</h1>
1.　VisualStudio2019コマンドプロントを管理者権限で開きます。
2. 「cd C:\dev\gdal321」を実行
3. 「.\generate_vcxproj.bat 16.0 64 gdal_vs2019」を実行
　　※32bit環境では「.\generate_vcxproj.bat 16.0 32 gdal_vs2019」
4.　 処理が終了したら「C:\gdal321」内に「gdaal_vs2019.vcxproj」が作成されたことを確認します。
5. 「.\gdaal_vs2019.vcxproj」を実行
6. 　処理が終了したら終了です。

<details><summary><b>PROJエラー</b></summary>
<div> 
国内外の過去のインストール情報をもとにいろいろやっていた時、「nmake.opt」のPROJ参照先が不明で以下のようなエラーが出ていた。
これは、PROJ6.0.0以上をインストールしてくださいというエラー

```
!IF !DEFINED(PROJ_INCLUDE)
!ERROR PROJ_INCLUDE should be defined. PROJ >= 6 is a required dependency
!ENDIF
```
 </div>
</details>

<h1>MSVC2019での設定</h1>
空のプロジェクトを作り、ソリューションエクスプローラからソリューションを右クリックしてプロパティを開きます。

<h6>1.　プラットフォームをx64に変更</h6>
<h6>2.　C/C++＞全般＞追加のインクルードディレクトリに以下を追加</h6>

```
C:\dev\gdal321\alg
C:\dev\gdal321\gcore
C:\dev\gdal321\ogr
C:\dev\gdal321\ogr\ogrsf_frmts
C:\dev\gdal321\port
C:\dev\gdal321
```


<h6>3.　C/C++＞プリプロセッサ＞プリプロセッサの定義に以下を追加</h6>

```
_CRT_SECURE_NO_DEPRECATE
```

<h6>4.　リンカー＞全般＞追加のライブラリディレクトリに以下を追加</h6>

```
C:\dev\gdal321
```

<h6>5.　リンカー＞入力＞追加の依存ファイルに以下を追加 </h6>

```
gdal_i_d.lib
```

<h6>6.　適用、OKを押して設定終了</h6>

<h1>動作テスト</h1>
[GDALチュートリアル](https://gdal.org/tutorials/vector_api_tut.html)をもとにベクタデータ（シェープファイル）を読み込むサンプルを以下のように作成。

```C++
//#include "gdal.h"
#include "ogr_geometry.h"//ジオメトリ
#include "ogr_spatialref.h"//空間参照
#include "ogr_feature.h"//機能
#include "gdal_priv.h"//データセットまたはドライバ
#include "ogrsf_frmts.h"//レイヤ

int main(){
    //既知の構成済みGDALドライバーを全登録
    //通常、アプリケーション開始時に１度呼び出す必要がある
    GDALAllRegister();

    //データ読み込み
    GDALDataset* poDS;

    poDS = (GDALDataset*)GDALOpenEx("D:/gdal_test20210201/Project5/test/worldmap.shp", GDAL_OF_VECTOR, NULL, NULL, NULL);

    if (poDS == NULL){
        printf("Open failed.\n");
        exit(1);
    }
}
```

「D:/gdal_test20210201/Project5/test/worldmap.shp」の部分は適宜変更してください。

<h4>実行結果</h4>

![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394814/5d0a5c3e-72a8-eefd-bbdc-8a858bbc9c8e.png)

# 最後に
まだ、C++もGDALも使い始めたばかりで、データ処理とかさっぱりです。
今後、少しずつ学んでいきます。