QGIS で作成したデータ("プロジェクト")を Web ページで表示する方法について、ノウハウを共有します。
前回は QGIS Server をセットアップしました。
今回は QWC2 (QGIS Web Client 2) をセットアップして、QGIS Server と連携する Web 地図アプリを作成します。
マニュアルとして、QWC2 / QWC Services
のドキュメントを参照します。
このマニュアルには、QGIS Server と QWC2 を中核として含む qwc-services
という統合環境を Docker でインストールする場合と、QWC2 を単独でインストールする場合の説明が混ざり合っています。今回は QWC2 を単独でインストールする場合の説明を読んでいくことになります。
1. 環境整備
1-1. 開発ツール
git
, nodejs
, そして yarnpkg
が必要になりますので、それぞれ dnf
でインストールします。
1-1-1. git
sudo dnf install git
1-1-2. nodejs
AlmaLinux の標準レポジトリからインストール出来るのは Version 16.20.2 ですが、必要とされるバージョンは 18.12.0 以上ですので、dnf install nodejs
の前に一作業必要です。
root にスイッチして作業します。
su -
curl -fsSL https://rpm.nodesource.com/setup_20.x | bash -
dnf install nodejs
参照 : NODESOURCE > Red Hat Based Linux Installation (Node.js 20 lTS)
1-1-3. yarnpkg
sudo dnf install yarnpkg
1-2. Web 地図アプリの環境設定
1-2-1. ルート・ディレクトリ
ここでは、Web 地図アプリのルート・ディレクトリとして '/var/www/qwc2' というディレクトリを作ります。
sudo mkdir /var/www/qwc2
sudo chown my-account:my-accout /var/www/qwc2
sudo chmod 755 /var/www/qwc2
1-2-2. nginx のルーティング
/etc/nginx/conf.d/qwc2.conf
を作成して、Web 地図アプリへのルーティングを設定します。
# webgis.mydomain ... QGIS Web Client 2
server {
listen 80;
server_name webgis.mydomain;
root /var/www/qwc2;
location / {
index index.html;
}
error_log /var/log/nginx/qwc2-error.log;
access_log /var/log/nginx/qwc2-access.log;
}
nginx
を再起動しておきます。
sudo systemctl restart nginx
2. qwc2-demo-app
マニュアルによると、デモ・アプリをインストールする(そして、自分の環境とニーズに合わせてカスタマイズする)のが QWC2 を導入する最も簡単な方法だということですので、それに従って進めていきます。
2-1. qwc2-demo-app のインストール
まず、qwc2-demo-app
を git
で取得します。
cd
git clone --recursive https://github.com/qgis/qwc2-demo-app.git
次に、アプリが依存するパッケージをすべてインストールします。
cd qwc2-demo-app
yarn install
2-2. 開発版アプリのビルドと動作確認
そして、開発版アプリをビルドして動作確認をします。
yarn start
開発版アプリは既定では http://localhost:8081/
で動作します。外部からアクセスする場合は、ホスト名を使うとエラーになりますので、 IP アドレスを使用します。例えば、http://webgis.mydomain:8081/
ではなく、http://192.168.0.9:8081/
とします。
このスクリーンショットのような画面が表示されたら qwc2-demo-app
のインストールとビルドは成功裏に完了しています。
開発版アプリは Ctrl + C
を2回押して終了します。
2-3. 運用版アプリのビルドと配備(デプロイ)
開発版アプリが無事に動作したら、運用版アプリを作成して運用環境に配備します。
次のコマンドで運用版アプリをビルドします。
yarn run prod
これで、./prod
ディレクトリ以下に、運用版アプリの全てのファイルが作成されます。
./prod
ディレクトリ以下のファイルとフォルダを全てアプリのルート・ディレクトリにコピーします。
cp -r ./prod/* /var/www/qwc2/.
ブラウザで以下のアドレスにアクセスして、運用版と同じようにデモ版の地図が表示されることを確認します。
http://webgis.mydomain/
以上で qwc2-demo-app
の一連のインストール作業は完了です。
3. テーマ "world" を追加する
作成した直後の qwc2-demo-app
は、前回セットアップした QGIS Server とはまだ連携していません。
何はともあれ、QGIS Server が提供している筈の "world" というデモ・データを QWC2 で表示して、二つが連携できることを確認したい所です。
3-1. テーマ設定に "world" を追加する
$HOME/qwc2-demo-app/thenesConfig.json
の冒頭部分は現在以下のようになっている筈です。
{
"themes":{
"items": [
{
"url":"http://qwc2.sourcepole.ch/ows/uster/bauprojekte",
"attribution":"Stadt Uster",
"attributionUrl":"https://gis.uster.ch/",
"scales": [
...
この冒頭部分に "world" というテーマ・アイテムを追加します。
{
"themes":{
"items": [
{
"id": "world",
"url": "http://webgis.mydomain:8082/world",
"mapCrs": "EPSG:4326",
"scales": [
200000000,
80000000,
40000000,
20000000,
8000000,
4000000,
2000000,
800000,
400000,
200000,
80000
]
},
{
"url":"http://qwc2.sourcepole.ch/ows/uster/bauprojekte",
"attribution":"Stadt Uster",
"attributionUrl":"https://gis.uster.ch/",
"scales": [
...
-
"url": "http://webgis.mydomain:8082/world"
... 設置した QGIS Server から "world" というプロジェクトをテーマ・アイテムとして取得することを意味します。 -
"mapCrs": "EPSG:4326" ... プロジェクトの CRS が
EPSG:4326 WGS 84` であることを示しています。 -
"scales"
... 選択可能な表示倍率を指定しています。
3-2. 開発版アプリのビルドと動作確認
themesConfig.json
を書き換えたら、開発版アプリをビルドして動作確認をします。
yarn start
ブラウザで http://192.168.0.9:8081/
にアクセスして、以下のような地図が表示されば、思惑通りに QGIS Server との連携が出来たことになります。
3-3. 運用版アプリのビルドと配備(デプロイ)
開発版アプリで確認が取れたら、運用版アプリを作成して配備します。
yarn run prod
rm -rf /var/www/qwc2/*
cp -r ./prod/* /var/www/qwc2/.
4. テーマ "isg" を追加する
実のところ、"world" というテーマ(QGIS のプロジェクト)は、ちょっと扱いづらいところがあります。何故か分かりませんが、qwc2-demo-app
では地図全体が表示されるところまで表示倍率を下げることが出来ません。また、それほど面白い地図ではなく、今後の参考になるとも思えません。
そこで、自分で作成した QGIS プロジェクト "isg"
をテーマとして追加することにします。
4-1. ダウンロード
下記に "isg"
プロジェクトの一式を置いています。ダウンロードして自由にお使い下さい。
4-2. プロジェクトを設置する
zip ファイルを解凍し、前回、2-3. QGIS プロジェクトを設置する で説明したところに従って、書庫に入っているファイルとディレクトリを設置します。
結果として、次のようなディレクトリ構成になります。
基準ディレクトリ (例えば "/home/my-account/qgis-projects")
- world.qgs
- naturalearth.sqlite
+ common
+ rasters
+ shpfiles
- isg.qgs
+ isg
+ rasters
+ shpfiles
4-3. socket と service を構成する
sudo systemctl enable qgis-server@isg.socket
sudo systemctl enable qgis-server@isg.service
sudo systemctl start qgis-server@isg.socket
sudo systemctl start qgis-server@isg.service
4-4. nginx を再構成する
/etc/nginx/conf.d/qgis-server.conf
に isg
用のエントリを追加します。
server {
listen 8082;
server_name webgif.mydomain;
gzip off;
include fastcgi_params;
# CORS を許可
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
location /world/ {
fastcgi_pass unix:/run/qgis-server-world.sock;
}
location /isg/ {
fastcgi_pass unix:/run/qgis-server-isg.sock;
}
error_log /var/log/nginx/qgis-server-error.log;
access_log /var/log/nginx/qgis-server-access.log;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
そして、nginx
を再起動しておきます。
systemctl restart nginx
4-5. テーマ設定に "isg" を追加する
$HOME/qwc2-demo-app/thenesConfig.json
の冒頭部分に "isg" というテーマ・アイテムを追加します。
{
"themes":{
"items": [
{
"id": "isg",
"url": "http://webgis.mydomain:8082/isg"
},
{
"id": "world",
"url": "http://webgis.mydomain:8082/world",
"mapCrs": "EPSG:4326",
"scales": [
200000000,
80000000,
40000000,
20000000,
8000000,
4000000,
2000000,
800000,
400000,
200000,
80000
]
},
...
-
"id"
と"url"
しか設定していませんが、これで大丈夫です。
4-6. 開発版アプリのビルドと動作確認
themesConfig.json
を書き換えたら、開発版アプリをビルドして動作確認をします。
yarn start
ブラウザで http://192.168.0.9:8081/
にアクセスして、以下のような地図が表示されば、テーマ "isg" の追加は成功裏に完了しています。
4-7. 運用版アプリのビルドと配備(デプロイ)
そして、運用版アプリを作成して配備します。
yarn run prod
rm -rf /var/www/qwc2/*
cp -r ./prod/* /var/www/qwc2/.
5. カスタマイズ作業の流れ
qwc2-demo-app
のカスタマイズ作業は、これまでの説明から分かるように、以下のような一連の流れになっています。
-
themesConfig.json
を編集する -
yarn start
で開発版アプリをビルドし、動作確認をする -
yarn run prod
で運用版アプリをビルドする - ビルドされた運用版アプリを運用環境に配備する
この流れをもう少し詳しく知っておくと役に立ちます。
5-1. yarn start
と yarn run prod
package.json
の "scripts"
セクションを見ると、yarn start
と yarn run prod
の動作内容を推測することが出来ます。それによると、これら二つのコマンドは、実際には次のような動作をしています。
-
yarn start
-
tsupdate
... 翻訳の更新 -
themesconfig
... テーマの構成 -
iconfont
... アイコンとフォントの構成 -
webpack serve --mode development
... 開発モードで走らせる
-
-
yarn prod
-
tsupdate
... 翻訳の更新 -
themesconfig
... テーマの構成 -
iconfont
... アイコンとフォントの構成 -
webpack --mode production
... 運用モードでアプリを作成する
-
最後だけが異なっているのですね。
何だ、それなら共通の3つの段階を行うコマンドと最後の段階だけを別々に行うコマンドを合計3つ作ったら効率的だぞ、と思われるかも知れません。
私もそう思ったのでやってみました。初めの3段階はほとんど時間を消費せずすぐに完了します。遅いのは最後の段階です。従って、コマンドを再編成しても、ビルドの速度はあまり変りません。
ただし、共通部分の3つの段階だけを行うコマンドは作っておくと後で役に立ちますので、package.json
の "scripts"
セクションに "make" というコマンドを追加しておきます。
{
...
"scripts": {
"prod": "npm run tsupdate && npm run themesconfig && npm run iconfont && webpack --mode production --progress",
"start": "npm run tsupdate && npm run themesconfig && npm run iconfont && webpack serve --mode development --progress --host 0.0.0.0 --port 8081",
+ "make": "npm run tsupdate && npm run themesconfig && npm run iconfont",
"iconfont": "node qwc2/scripts/makeIconkit.js",
...
}
}
それよりも重要なのは、themesconfig
(テーマの構成)が実際に何をやっているかです。
5-2. themesconfig
themesconfig
では、おおむね、次のように作業が進みます。
-
themesConfig.json
を読み込む- アプリで何個のテーマを扱うかが決まる
- 各テーマについて、
url
によってサーバが特定される
- 各テーマの詳細についてサーバに問い合せを行う
- タイトル、概要説明、キーワード、作成者など、一般的な情報
- サポートされているサービスの種類(WMS, WMTS, WFS, WCS)とその詳細な内容
- CRS、地図の範囲、初期表示範囲
- 各レイヤの「短い名前(≒ ID)」とタイトル、その他の詳細情報
-
themesConfig.json
の情報と問い合せて得た情報を合成する-
themesConfig.json
に記載されている情報が優先される - 指定のない項目については、
themesConfig.json
に記載されている各テーマ共通のデフォルト値が適用される
-
- 合成したテーマ情報を
static/themes.json
に書き出す
そして、開発版アプリも運用版アプリも、テーマについては static/themes.json
を参照してビルドされます。
And so, what's next?
ここまでの作業で実際にやったことは、テーマを追加するということだけで、アプリの外観や機能のカスタマイズについては、まったく手が着いていない状態です。変更したい所が数多くあるのに、その設定方法がよく分からない場合が多くて、前途遼遠です。今現在の themesConfig.json
には自分にとって無関係と思われる記述が初期状態のまま残っており、不要なものをばっさりと削除してすっきりさせたいところですが、それすらも出来ていません。
しかし、ここまで来ると、QWC2 でいろいろと遊ぶことが出来ます。そして、遊んでいるうちに、どうしてもその重さが気になってきます。同じ内容の地図なのに qgis2web
で作成したものに比べると、表示更新速度がカタツムリのように遅いのです。この速度の問題を放置してアプリの見た目にこだわっても、あまり意味が無いと思われます。
ですので、外観や機能のカスタマイズは一先ず後回しにして、表示速度の問題に手を着けることにします。
既に述べたようにパフォーマンス改善のために MapCache
を導入するのですが、その前に、QWC2 だけで対応できる事がいくつかあります。次回は QWC2 において背景地図の取扱いを最適化する方法を説明します。