QGIS での WMS/WFS サーバ構築方法

QGIS では、外部システムと地理空間レイヤを連携する方法として、**WMS**, **WMTS**, **WFS**, **OAPIF**, **WCS** サーバ機能が用意されています。
各機能の概要や特徴、メリット/デメリット等を以下に示します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/6155e70f-17a8-d9e3-f081-0e529bd694bc.png" />

今回は、GIS でよく利用されている **WMS (Web Map Service)** および **WFS (Web Feature Service)** サーバの設定を行った後、Web ブラウザや QGIS の WMS/WFS クライアント機能を用いて接続確認を行う手順について説明していこうと思います。

# 1. 前提条件
- QGIS がインストール済みであること。
    - インストールされていない場合は、[QGIS ダウンロードページ](https://qgis.org/en/site/forusers/download.html)からインストーラをダウンロード後インストールしてください。
    - 本手順では、Windows 版 QGIS 3.34.6 を使用します。
- 公開する地理情報データが準備されていること。

# 2. OSGeo4W インストール
**OSGeo4W** は「Open Source Geospatial for Windows」の略で、**Windows 向けのオープンソース地理空間ソフトウェアのパッケージ**です。このプロジェクトは、地理空間データを処理するためのさまざまなツールとライブラリを含む総合的なインストーラーを提供しています。

一般に OSGeo4W は以下のような用途で使用されます。
- **多様な地理空間ソフトウェアの配布**: OSGeo4W は、QGIS、GRASS GIS、GDAL/OGR、MapServer、PostGIS など、多くのオープンソース地理空間プロジェクトを含んでいます。これにより、ユーザーは一つのパッケージを通じて、必要なソフトウェアを簡単にインストールできます。
- **依存関係の管理**: 地理空間ソフトウェアはしばしば複数のライブラリや依存関係を必要とします。OSGeo4W はこれらの依存関係を管理し、ソフトウェアが問題なく動作するようにすることで、インストールプロセスを簡素化します。
- **環境の統一**: OSGeo4W は、地理空間ツールが同じ環境下で統一的に動作するように設計されています。これにより、異なるツール間でのデータの互換性や連携が向上します。
- **更新とメンテナンス**: OSGeo4W は定期的に更新されるため、最新の地理空間技術を簡単に取得できます。ユーザーは OSGeo4W を通じて最新バージョンへのアップグレードが可能です。

QGIS を中心とした WMS (Web Map Service) や WFS (Web Feature Service) サーバを構築する場合において、OSGeo4W は以下のような役割を果たします。

- **サーバソフトウェアの提供**: OSGeo4W は、QGIS Server や MapServer など、WMS や WFS サービスを提供するサーバソフトウェアを含んでいます。これにより、地理情報の Web 公開が容易になります。
- **環境設定のサポート**: QGIS Server などの設定に必要な依存ライブラリやツールが OSGeo4W に含まれているため、サーバ設定の際のトラブルシューティングが簡単になります。

1. [OSGeo4W](https://trac.osgeo.org/osgeo4w/) から OSGeo4W network installer をダウンロードします。

2. インストーラーを実行し、**アドバンスインストール**を選択後、「次へ」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/dbd2f810-7056-330a-a562-b6669afb9a29.png" width="450px" />

3. **インターネットからインストール**を選択後、「次へ」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/86f3a919-502f-6e9b-e80f-703593ea375d.png" width="450px" />

4. ルートディレクトリが問題ないか確認後、「次へ」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/2c81dc91-3d0b-ac07-30da-6621cd028a2b.png" width="450px" />

5. 「次へ」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/bdfe71b7-a71a-4dc5-8f22-6c8d8d28856a.png" width="450px" />

6. プロキシ接続等、特別なインターネット接続を行わない場合は、そのまま「次へ」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/314e2121-d038-7e45-e0f1-0bb526a3ef09.png" width="450px" />

7. 任意のダウンロードサイトを選択後、「次へ」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/531eb616-3654-2858-29cf-b229ce4170c7.png" width="450px" />

8. パッケージリストの Web Services の下にある `qgis-server` を選択してインストールします。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/7a4f952b-5ef0-fd18-5779-5b687ebec9c6.png" width="660px" />

9. **依存関係に対応するパッケージをインストール**にチェックを入れ、「次へ」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/617ae8c3-7ffb-2ecb-4769-0df8b527e898.png" width="450px" />

10. **上記のライセンス条項に同意しました**にチェックを入れ、「次へ」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/e0b80e95-5f0a-cf1b-1e3b-fcd03eeaaa20.png" width="450px" />

11. インストールが完了したら、「完了」ボタンを押下し、インストールを完了します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/261ba911-2bf7-72d3-6f35-8eac1f5a1ddb.png" width="450px" />
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/55e85f53-dc22-ccf8-9d98-07bf2c252add.png" width="450px" />

# 3. Apache セットアップ
## 3.1. Apache ダウンロード

1. [Apache のダウンロードページ](https://www.apachelounge.com/download/)にアクセスし、`httpd-2.4.59-240404-win64-VS17.zip` をダウンロードします。

2. ダウンロードしたファイルを展開し、`Apache24` フォルダを C ドライブ直下にコピーします。

## 3.2. 環境変数設定
1. Windows の**システム環境設定の編集**で、システムのプロパティ・ダイアログを開き、「環境変数」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/3888436f-6555-a89c-dcc6-c401be21cdbb.png" width="350px" />


2. 「システム環境変数」欄の **Path** をダブルクリックし編集画面を開きます。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/b4c348c9-76aa-8e6e-8e40-16f243f0cbf6.png" width="450px" />

3. 「新規」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/b424df88-0827-247a-b3cc-578283ebe405.png" width="450px" />

4. `C:\Apache24\bin\` 追加後、「OK」ボタンを押下して終了します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/4002d3e4-99da-63a0-ac3b-5bfa41eaa1f4.png" width="450px" />

5. コマンドプロンプトを開き、`httpd -v` を実行します。
    バージョンが表示されたら、正しく PATH が通せています。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/b238aec9-45f2-f546-bd95-3deb5e99275b.png" width="400px" />

## 3.3. 設定ファイルの変更

1. コードエディタ等で `C:\Apache24\conf\httpd.conf` を開きます。

2. 下記の通り修正し、8080 ポートでリスンするようにします。
    ```diff
     #Listen 12.34.56.78:80
    -Listen 80
    +Listen 8080
    ```
    ```diff
     #ServerName www.example.com:80
    +ServerName localhost:8080
    ```
    
## 3.4. サービス登録

1. コマンドプロンプトで以下のコマンドを実行し、Apache をサービス登録します。
    ```
    httpd -k install
    ```
2. Windows で `services.msc` を実行し、**コンポーネント サービス**プロンプトを開き、Apache がサービスとして登録されており、**実行中**となっていることを確認します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/caf300db-8288-90fa-c482-6e1d63e2bc95.png" width="600px" />

## 3.5. Apache モジュール設定

1. [Apache Lounge](https://www.apachelounge.com/download/) から **mod_fcgid** モジュールをダウンロードし、解凍後、`mod_fcgid.so` ファイルを `C:\Apache24\modules\` 配下に配置します。

## 3.6. QGIS 接続設定
QGIS サーバは Apache HTTP サーバを使用します。Apache を QGIS サーバと接続するように設定する必要があります。

1. Apache インストールディレクトリ内の `httpd.conf` ファイルを開き、QGIS サーバと接続するために以下のように修正します。
    ```diff
    -    ScriptAlias /cgi-bin/ "${SRVROOT}/cgi-bin/"
    +    ScriptAlias /cgi-bin/ "C:/OSGeo4W/apps/qgis/bin/"
    ```
    ```diff
    -<Directory "${SRVROOT}/cgi-bin">
    +<Directory "C:/OSGeo4W/apps/qgis/bin">
    +    SetHandler cgi-script
         AllowOverride None
    -    Options None
    +    Options ExecCGI
         Require all granted
     </Directory>
    ```
    ```diff
         #AddHandler cgi-script .cgi
    +    AddHandler cgi-script .cgi .exe
    ```
    ```diff
    +# parse OSGeo4W apache conf files
    +IncludeOptional "C:\OSGeo4W\httpd.d\httpd_*.conf"
    +SetEnv GDAL_DATA "C:\OSGeo4W\share\gdal"
    +SetEnv QGIS_AUTH_DB_DIR_PATH "C:\OSGeo4W\apps\qgis\resources"
    ```

2. 設定を適用するため、コマンドプロンプトを開き、以下のコマンドで Apache を再起動します。
    ```
    httpd -k restart
    ```
# 4. WMS サーバ設定
## 4.1. QGIS プロジェクトの作成

1. QGIS を開き、新しいプロジェクトを作成します。
2. 任意の GIS レイヤを取り込み、必要に応じてレイヤのプロパティを設定します。
3. `プロジェクト > プロパティ`を開きます。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/7628a364-30ef-a9e8-45cf-72fb9829726f.png" width="220px" />
4. 性能向上のため、[QGISサーバー] の [Services Capabilities] タブを押下した後、**Service Capabilitiesを有効化**のチェックを外し、「適用」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/3440a339-41ab-8c5d-0640-88335bb586c8.png" width="580px" />
4. [QGISサーバー] の [WMS] タブを押下し、"CRS制限" を有効化した後、「使用中」ボタンを押下し、使用中のCRS をリストに追加します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/94989895-037d-0730-428b-060163ac7030.png" width="580px" />

      :::note info
      **CRS制限**の設定を行うことにより、データを表示またはリクエストする際に使用される座標系を限定することができます。
      これにより、意図しない座標系に起因する不具合を防いだり、パフォーマンスを向上させたりすることができます。
      :::
5. [接続のテスト] にある「起動」ボタンを押下し、"プロジェクトは有効です" と表示されることを確認したら、「適用」ボタンを押下し、設定を終了します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/b9cd61e8-77a5-5fa2-72db-4126eed6f65c.png" width="580px" />
6. プロジェクトファイル（`.qgz` または `.qgs`）を QGIS サーバがアクセスできるディレクトリに保存します。
    今回は、`C:\OSGeo4W\apps\qgis\test.qgz` として保存しています。

# 5. WMS 接続確認
## 5.1. Web ブラウザによる接続確認 (GetCapabilities)
   1. Web ブラウザで **GetCapabilities** リスエストを行い、WMS サーバが動作しているかを確認します。
      - http\://localhost:8080/cgi-bin/qgis_mapserv.fcgi.exe?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities&MAP=C:/OSGeo4W/apps/qgis/test.qgz
     
   2. WMS サーバーが提供する機能や利用可能なデータに関する情報が XML 形式で表示されることを確認します。
        <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/0edcf4a8-d897-3c06-a8ea-07d9b8dae77d.png" />


## 5.2. Web ブラウザによる接続確認 (GetMap)
   1. **GetMap** リスエストを行い、WMTS サーバからデータが取得できるかを確認します。
      - http\://localhost:8080/cgi-bin/qgis_mapserv.fcgi.exe?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&MAP=C:/OSGeo4W/apps/qgis/test.qgz&LAYERS=Sample_Ortho_30cm_8bit_3band_20190525_25&WIDTH=800&HEIGHT=600&CRS=EPSG:4326&BBOX=35.696669,139.518449,35.70216,139.52594
      :::note warn
      WMS は全範囲をすべて取得する仕様のため、レイヤの範囲が広い場合、`WIDTH`, `HEIGHT`, `BBOX` パラメータ等で範囲を絞らない場合、"The requested map size is too large" エラーが表示されることがあります。
      :::
   2. マップが表示されることを確認します。
      <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/997e472c-67f2-685d-110d-ae3fbd32dd01.png" width="450px" />
     
      :::note info
      `BBOX` の範囲のレイヤデータが `WIDTH` および `HEIGHT` で指定したキャンバス上で、引き伸ばされて表示されます。
      :::

## 5.3. QGIS の WMS クライアントによる接続確認

1. QGIS を開きます。
2. `レイヤ > レイヤを追加 > WMS/WMTS を追加` に移動します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/a0e9a31f-b99f-2c87-db77-b6e916c592b4.png" width="500px" />
3. WMS/WMTS 設定で「新規」ボタンを押下し、新規設定を追加します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/b5ac2d80-2f5c-5739-c2d2-dc8d80929d99.png" width="650px" />

4. WMS サービスの**名称**と **URL** を入力し、「OK」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/06674ee4-4a7a-c68a-1c81-fc23829d4597.png" width="450px" />

    尚、今回は以下の設定を行っています。
    | 項目 | 設定値 | 
    |:--|:--|
    | 名称 | test |
    | URL | http\://localhost:8080/cgi-bin/qgis_mapserv.fcgi.exe?SERVICE=WMS&VERSION=1.3.0&MAP=C:/OSGeo4W/apps/qgis/test.qgz |

5. 「接続」ボタンを押下し、WFS サーバに接続後、追加したいレイヤを選択し、「追加」ボタンを押下します。
   （これでレイヤが追加されるので、「閉じる」ボタンでウィンドウを閉じて問題ありません。）
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/2d077b97-5ca9-96c1-487d-f48a7289c825.png" width="650px" />

6. 選択したレイヤが表示されていることを確認します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/b1d8fc98-a339-69b3-2d30-773e31f730b7.png" />  

# 6. WFS サーバ設定
## 6.1. QGIS プロジェクトの作成

1. QGIS を開き、新しいプロジェクトを作成します。
2. 任意の GIS レイヤを取り込み、必要に応じてレイヤのプロパティを設定します。
3. `プロジェクト > プロパティ`を開きます。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/7628a364-30ef-a9e8-45cf-72fb9829726f.png" width="220px" />
4. 性能向上のため、[QGISサーバー] の [Services Capabilities] タブを押下した後、**Service Capabilitiesを有効化**のチェックを外し、「適用」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/3440a339-41ab-8c5d-0640-88335bb586c8.png" width="580px" />
4. [QGISサーバー] の [WFS/OAPIF] タブを押下し、表示されているベクターレイヤの**発行済み**にチェックを入れます。（**更新**や**挿入**、**削除**は、ニーズに合わせて任意でチェックを入れておきます。）
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/758d2c14-22c0-2816-ac23-3a6faad05167.png" width="580px" />
5. [接続のテスト] にある「起動」ボタンを押下し、"プロジェクトは有効です" と表示されることを確認したら、「適用」ボタンを押下し、設定を終了します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/6b78876a-7ed4-e53c-92c4-3e965d1b2fa1.png" width="580px" />
6. プロジェクトファイル（`.qgz` または `.qgs`）を QGIS サーバがアクセスできるディレクトリに保存します。
    今回は、`C:\OSGeo4W\apps\qgis\test2.qgz` として保存しています。


# 7. WFS 接続確認
## 7.1. Web ブラウザによる接続確認 (GetCapabilities)
   1. Web ブラウザで **GetCapabilities** リスエストを行い、WFS サーバが動作しているかを確認します。
      - http\://localhost:8080/cgi-bin/qgis_mapserv.fcgi.exe?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetCapabilities&MAP=C:/OSGeo4W/apps/qgis/test2.qgz
     
   2. WFS サーバーが提供する機能や利用可能なデータに関する情報が XML 形式で表示されることを確認します。
      <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/a0b007dd-77e5-a57d-2b7b-c17b9623d4f7.png" />

## 7.2. Web ブラウザによる接続確認 (GetFeature)
   1. **GetFeature** リスエストを行い、WFS サーバからデータが取得できるかを確認します。
      - http\://localhost:8080/cgi-bin/qgis_mapserv.fcgi.exe?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=W05-08_13-g_Stream&MAP=C:/OSGeo4W/apps/qgis/test2.qgz
   2. WFS サーバーから地理空間データ（特徴）が XML 形式で表示されることを確認します。
     <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/18d304f0-05b9-d78c-5c80-576c7643351c.png" />

     
## 7.3. QGIS の WFS クライアントによる接続確認

1. QGIS を開きます。
2. `レイヤ > レイヤを追加 > WFS / OGC API - 地物レイヤを追加` に移動します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/f921fd46-7131-c92e-4dc2-cc99d2253b60.png" width="500px" />

3. WFS サービスの**名称**と **URL** を入力し、「OK」ボタンを押下します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/79aa66a7-76eb-6655-dba4-829c1fdfd358.png" width="450px" />

    尚、今回は以下の設定を行っています。
    | 項目 | 設定値 | 
    |:--|:--|
    | 名称 | test2 |
    | URL | http\://localhost:8080/cgi-bin/qgis_mapserv.fcgi.exe?SERVICE=WFS&MAP=C:/OSGeo4W/apps/qgis/test2.qgz |
    
4. 「接続」ボタンを押下し、WFS サーバに接続後、追加したいレイヤを選択します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/202c2113-dcd6-2c2b-969f-e061038c00c4.png" width="650px" />

5. **ビュー領域に重なる地物のみをリクエストする**のチェックを外し、「追加」ボタンを押下します。
   （これでレイヤが追加されるので、「閉じる」ボタンでウィンドウを閉じて問題ありません。）
   <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/1df3d5cc-0799-512b-82f0-a10b6e9ecb95.png" width="650px" />
   
   :::note warn
   **ビュー領域に重なる地物のみをリクエストする**がされている状態でレイヤを追加すると、以下のエラーが出力されるため、チェックを外すようにしています。
   - `レイヤ W05-08_13-g_Stream: ジオメトリの座標軸順に関してサーバーと問題があるかもしれません。WFS接続の設定で、軸の向きを無視したり、軸順を反転することできます。`
   :::

6. 追加したレイヤが表示されていることを確認します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/dd16013f-958d-5508-4ea0-c68ac56bd9be.png" width="650px" />
    必要に応じて、レイヤのプロパティで形状等を変更することもできます。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/9be35b58-c443-4618-727c-4aa8968b2009.png" width="650px" />

# 参考資料
- **"QGIS Server の始め方 — QGIS ドキュメント"**, https://docs.qgis.org/3.34/ja/docs/server_manual/getting_started.html#installation-on-windows
- **"WMS (Web Map Service) — QGIS ドキュメント"**, https://docs.qgis.org/3.22/ja/docs/training_manual/online_resources/wms.html
- **"QGIS Server とそのサービス — QGIS ドキュメント"**, https://docs.qgis.org/3.34/ja/docs/server_manual/services.html