WebGISの構築 on Ubuntu20.04 LTS

## はじめに
これまでQGISを使った位置情報の可視化についていくつか整理してきたが、これはデスクトップ側での操作方法のため、可視化したものを公開したり、周りと共同でアップロードするのには向いていない。
今回は、QGISで作成したレイヤを共有するためにWebGIS（QGIS-Server）をセットアップしてみたので、その内容をメモとして残しておく。

## 実行環境
【WebGISの導入環境】
　　・Ubuntu20.04 LTS（GCP上）
　　・QGIS-Server 3.10.4
　　・Apache2.4.41


## やりたい事

１．GCPにUbuntuのインスタンス作成
２．QGIS-Serverのインストール
３．Apache2をインストールしてテストプロジェクトを表示

※２以降の手順は、基本的に **[公式ドキュメント](https://docs.qgis.org/testing/en/docs/server_manual/)** に沿って構築していく。

## １．GCPにUbuntuのインスタンス作成

・GCPのホーム画面に入り、[新しいプロジェクト] をクリック。（ブラウザはChrome）
![Qiita-no010_img01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/66909222-eb91-42c2-5fff-39cd5c868f92.jpeg)

・プロジェクト作成画面が開くため『プロジェクト名』を決めて [作成] をクリック。

・ナビゲーションメニュー内の【ComputeEngine ＞ VMインスタンス】をクリック。
![Qiita-no010_img02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/104c6214-50dc-5b1d-c32c-d48cdacf4e7d.jpeg)

・[作成] をクリックし、以下の情報を入力、選択したら [作成] をクリック。

　＜右側は今回の設定値＞
　　●名前　　　：qgis-web-client2
　　●リージョン：asia-northeast1（東京）
　　●ゾーン　　：asia-northeast1-b

　　●マシン構成
　　　　マシンファミリー：汎用
　　　　シリーズ　　　　：E2
　　　　マシンタイプ　　：e2-small
　
　　●ブートディスク
　　　　OS　　　　　　：Ubuntu
　　　　バージョン　　：Ubuntu20.04 LTS
　　　　ディスクの種類：標準の永続ディスク
　　　　サイズ　　　　：10GB

　　●ファイアウォール
　　　　HTTPトラフィックを許可
　　　　HTTPSトラフィックを許可

　　●ネットワーキング（ネットワークインターフェース）
　　　　外部IP：IPアドレスを作成
　　　　　　　　※名前は適当に決める。


　　※上記以外の設定値はデフォルトのまま

作成には少し時間がかかるが、作成が完了したら 接続-[SSH] をクリックしてコンソール画面を開く。
![Qiita-no010_img03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/38ba9e50-ab8e-e221-1f4b-47b1a921e77b.jpeg)

<font color="red">ここから先の作業はrootログインして実行。</font>（デフォルトのGCPアカウントユーザーで `sudo` を使えるが、毎回打つのが面倒なので）
※GCPのVMインスタンスにrootログインする方法はこちらの記事
　[**【GCPのVMインスタンスにrootでログインする方法】**](https://qiita.com/smiler5617/items/f07252a4f8c1f4c34b67)

## ２．QGIS-Serverのインストール
パッケージ管理ツールの更新。

```shell:
$ apt update
$ apt -y upgrade
```

必要パッケージののインストール。

```shell:
$ apt install -y nano curl iputils-ping net-tools
```

### QGIS-Serverのパッケージをインストール

```shell:
$ apt install qgis-server
```

QGISサーバーの実行ファイルの格納場所を確認。
公式ドキュメントでは `/usr/lib/cgi-bin/qgis_mapserv.fcgi` となっている。

```shell:
$ find / -name 'qgis_mapserv.fcgi'
/usr/lib/cgi-bin/qgis_mapserv.fcgi
```

試しに実行してみる。

```shell:
$ /usr/lib/cgi-bin/qgis_mapserv.fcgi

"Loading native module /usr/lib/qgis/server/libdummy.so"
"Loading native module /usr/lib/qgis/server/libwcs.so"
"Loading native module /usr/lib/qgis/server/libwfs.so"
"Loading native module /usr/lib/qgis/server/libwfs3.so"
"Loading native module /usr/lib/qgis/server/libwms.so"
"Loading native module /usr/lib/qgis/server/libwmts.so"
QFSFileEngine::open: No file name specified
Content-Length: 54
Content-Type: text/xml; charset=utf-8
Server:  Qgis FCGI server - QGis version 3.10.4-A Coruña
Status:  500
<ServerException>Project file error</ServerException>
```


この段階では、上記の様なレスポンスであれば正常に動いているという判断で良いらしい。

### トレーニング用プロジェクトのダウンロード

```shell:
### プロジェクトデータの格納先フォルダの作成
$ mkdir /home/qgis/
$ mkdir /home/qgis/projects/

### トレーニング用プロジェクトのダウンロード。
$ wget https://github.com/qgis/QGIS-Training-Data/archive/master.zip -d

### ダウンロードしたZIPファイルを解凍。　※『QGIS-Training-Data-master』ディレクトリができる。
$ unzip master.zip

### 解凍したファイルのチュートリアル用データをコピー
$ cp -pr ./QGIS-Training-Data-master/exercise_data/qgis-server-tutorial-data/* /home/qgis/projects/
```

コピー先ディレクトリの中身を確認。

```shell:
$ ls -l /home/qgis/projects/

total 13352
drwxrwxr-x 2  Icons
-rw-rw-r-- 1  README.md
drwxrwxr-x 2  Template
-rw-rw-r-- 1  naturalearth.sqlite
-rw-rw-r-- 1  world.qgs
-rw-rw-r-- 1  world3.qgs

# ※上記の表示は一部省略してる。
```

## ３．Apache2をインストールしてテストプロジェクトを表示


・Apacheのインストール＆起動確認
・confファイルの作成
・仮想ホストを作成し、読み込むconfファイルとホスト情報を紐づける。

**必要なパッケージをインストール。**

```shell:
$ apt install -y apache2 libapache2-mod-fcgid
```

`cgi` モジュールの有効化する。

```shell:
# モジュール有効化
$ a2enmod cgid

# Apache2の再起動
$ systemctl restart apache2
```
　
**モジュールの有効化、エイリアスをサイトconfigに設定するため、
`/etc/apache2/sites-available/` に　`qgis_demo.conf` を作成**

```shell:
$ nano /etc/apache2/sites-available/qgis_demo.conf
```


```shell:/etc/apache2/sites-available/qgis_demo.conf

以下の内容で作成（公式ドキュメント参照）
-------------------------------------------------
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf


        # Tell QGIS Server instances to use a specific display number for xvfb
        # necessary for printing, see below
        FcgidInitialEnv DISPLAY ":99"

        # Activate QGIS log (different from apache logs)
        # 今回はここは設定されていなくても大丈夫
        #FcgidInitialEnv QGIS_SERVER_LOG_FILE /var/log/qgis/qgisserver.log
        FcgidInitialEnv QGIS_SERVER_LOG_LEVEL "0"
        FcgidInitialEnv QGIS_SERVER_LOG_STDERR "1"
        FcgidInitialEnv QGIS_DEBUG 1

        # Add a default QGIS project
        SetEnv QGIS_PROJECT_FILE /home/qgis/projects/world.qgs

        # QGIS_AUTH_DB_DIR_PATH must lead to a directory writeable by www-data
        # 今回はここは設定されていなくても大丈夫
        #FcgidInitialEnv QGIS_AUTH_DB_DIR_PATH "/var/www/qgis-server/qgisserverdb/"
        #FcgidInitialEnv QGIS_AUTH_PASSWORD_FILE "/var/www/qgis-server/qgisserverdb/qgis-auth.db"

        <IfModule mod_fcgid.c>
        # Longer timeout for WPS... default = 40
            FcgidIOTimeout 120
            FcgidMaxRequestLen 26214400
            FcgidConnectTimeout 60
        </IfModule>

        # /usr/lib/cgi-bin/qgis_mapserv.fcgi のパスへのエイリアスを作成。
        <Location /qgisserver>
            SetHandler fcgid-script
            FcgidWrapper /usr/lib/cgi-bin/qgis_mapserv.fcgi virtual
            Options +ExecCGI -MultiViews +FollowSymLinks
            Require all granted
        </Location>

</VirtualHost>
-------------------------------------------------
```

作成したサイト設定ファイル `qgis_demo.conf` をApache起動時にロードされる様に展開する。

```shell:
# デフォルトのサイトは一旦削除
$ a2dissite 000-default

# 作成したファイルを展開
$ a2ensite qgis_demo
Enabling site qgis.demo.
```
※`/sites-available/qgis.demo.conf` へのシンボリックリンクとして `/etc/apache2/sites-enabled/qgis.demo.conf` が作成される。
（`/etc/apache2/sites-enabled/*.conf` は`apache`起動時に実行される。）

```shell:
### モジュールを有効化
$ a2enmod fcgid
$ a2enconf serve-cgi-bin

### Apacheサービスの再起動
$ systemctl restart apache2
```

**`xvfb`のインストールとサービスの登録**

```shell:
$ apt install -y xvfb
```

※`Xvfb` 自体はLinuxなどディスプレイを持っていないOS上で、画面入出力をシミュレートするためのツール。デスクトップ環境を用意しなくてもChromeやFirefoxなどでテストができる。


[Xvfb] サービスファイルの作成。

```shell:
$ nano /etc/systemd/system/xvfb.service
```

```vim:/etc/systemd/system/xvfb.service
[Unit]
Description=X Virtual Frame Buffer Service
After=network.target

[Service]
ExecStart=/usr/bin/Xvfb :99 -screen 0 1024x768x24 -ac +extension GLX +render -noreset

[Install]
WantedBy=multi-user.target
```

上記で作成した `Xvfb` サービスの開始

```shell:
$ systemctl enable xvfb.service
$ systemctl start xvfb.service
$ systemctl status xvfb.service
```


apacheの再起動

```
$ systemctl restart apache2
```

Ubuntu内のブラウザから以下のURLにアクセスして、地図の様な画面が開かれればセットアップ完了！

`http://localhost/qgisserver?MAP=/home/qgis/projects/world.qgs&SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&BBOX=-432786,4372992,3358959,7513746&SRS=EPSG:3857&WIDTH=665&HEIGHT=551&LAYERS=countries&FORMAT=image/jpeg`
※外部から試すときは、`localhost`の部分は外部IPにすればOK。（FWの設定で通すの忘れない様に！）

![Qiita-no010_img05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/4666810c-6198-ffff-c653-425a71512b41.jpeg)

※実はこの地図を開くところが上手く行かずにかなり手こずった。（画面を開くけど真っ白だった。）
原因は、参照にした公式ドキュメントに記載されていたトレーニングデータや最後のURL(パラメータ部分)の情報が古かったため。




## まとめ
次はqgsファイルを格納して、ShapeデータやPostgreSQLのデータを表示できるかなどを試したいと思う。（まずはMAPのセットアップなどが必要かもしれないが...）