PostGISのデータをGeoServerで配信してLeafletで表示する

# 環境
- Windows10
- GeoServer 2.17.1
- PostGIS 11
- QGIS 3.12

# 前置き
- PostGIS・QGISは導入済みとします(QGISは部分的に使用します)。また、QGISの操作等について深くは触れません。
- GeoServerの導入以降の手順について記述します。

# 公式ドキュメント
https://docs.geoserver.org/

-----

# 準備
基本的には公式ドキュメント通りの手順なので、自分が躓いたところ以外はサラッと流していきます。

## JREのインストール
- OpenJDK 11(LTS)をインストールします。うっかり14(Latest)をインストールしないように。Latestを入れるとレイヤプレビューが正常に機能しなくなります（うっかりやってしまった）。
- システム環境変数に以下を追加します
    - 変数名：JAVA_HOME
    - 変数値：JREをインストールしたディレクトリ（`C:\Program Files\AdoptOpenJDK\jdk-11.0.7.10-hotspot\`とか）

## GeoServerのインストールと起動
- [ここ](http://geoserver.org/release/stable/)から`Platform Independent Binary`をダウンロードします。
ダウンロードしたzipファイルを適当なディレクトリに展開します（特に理由が無ければ`C:\Program Files\GeoServer`で良いです）。
- 展開した中の`bin`フォルダ内にある`startup.bat`を実行するとGeoServerが起動します。
- 過去のバージョンではwindows用のインストーラーがあったようですが、あるバージョンからインストール方法が変わったようです。
- `http://localhost:8080/geoserver`をウェブブラウザで開き、管理画面が出ればOKです。

## GeoServerにPostGISのレイヤを追加
- 管理画面の左側ペインにある「レイヤプレビュー」を開くと、ずらっとデータが表示されていると思います。これらはデフォルトで入っているサンプルデータなので、まずこれらを消してしまいます（消さなくても良い）。
- 「ストア」から全てチェックを入れて一気に消していきます。同様に「ワークスペース」、「スタイル」もサンプルデータを消していきます。消せないものは消せないようになっているので、どんどん消していって問題ありません。ただしワークスペースは最低一つは作成しておく必要があるため、任意の名前のワークスペースを作成しておきます（作成しなければ警告が出ます）。
- 不要なものをひとしきり消したところで、PostGISのデータを追加します。「ストア」→「ストア新規追加」→「PostGIS」で任意のデータソース名と、自身の環境に合わせてホスト名等を入力します。
- ストアに追加すると「レイヤ」にPostGISのテーブルが並んでいます。レイヤ名をクリックすると「レイヤ編集」画面が表示されます。「範囲矩形」の欄にある`データを基に算出`・`ネイティブの範囲を基に算出`をクリックし、データのバウンディングボックスの範囲を確定します（ここは自動でやってくれればいいのにと思うのですが…）。

とりあえず最低限の準備は以上で終了です。

-----
# データを取得して表示する(GeoJSON)
## WFSでGeoJSONを取得する
- 管理画面トップページ右側の「サービスキャパビリティ」欄に、GeoServerが提供する様々な仕様の配信サービスのリンクが載っています。GeoJSONのようなベクタデータはWFS(Web Feature Service)を使用します。リンクのURLは`http://localhost:8080/geoserver/ows?service=wfs&version=1.0.0&request=GetCapabilities`のようになっています。詳細は`https://docs.geoserver.org/latest/en/user/services/wfs/index.html`が詳しいですが、このように`http://localhost:8080/geoserver/ows`にクエリパラメータを付与してやります。
- 単純にGeoJSONを取得するだけなら`http://localhost:8080/geoserver/test_postgis/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ワークスペース名:レイヤ名`とすれば良いです。ウェブブラウザで開いてみてjsonが確認できればOKです。

## Leafletで表示する
- 先の手順でGeoJSONを取得するためのURLが分かったので、あとはjavascriptのXMLhttprequestなり何なりでGeoJSONを取得して、leafletで表示することができます。
- なお、`C:\Program Files\GeoServer\data_dir\www` 配下に静的なファイルを設置すると、`http://localhost:8080/geoserver/www/`以下でサーブすることができます（参考：[公式ドキュメント](https://docs.geoserver.org/stable/en/user/tutorials/staticfiles.html)）。 
- 本番環境向きでは無いと思いますが、とりあえず。

-----

# データを取得して表示する(画像)
- GeoServerは、接続したデータソースを基に任意のスタイルで地図画像をレンダリングして配信することができます。用途が単なるベースマップだったり、ユーザーのアクションを必要としないようなものであれば、画像として配信した方が良い場合もあります。例えばGeoJSONの描画はフィーチャ数が多いとブラウザにとって結構重い処理になります（それに対する手段としてGeoJSONタイルとかバイナリベクトルタイルとかがあるのですがその辺はよくわかってないです）。

## スタイルの設定ファイルを作成する
- データソースを画像として表現するための設定ファイル(SLDファイル)を作ります。QGISとPostGISを接続し、QGISでよしなにスタイルを設定していきます。
- スタイルの設定に満足したら、QGISの「レイヤプロパティ」→「シンボロジ」→「スタイル」→「スタイルを保存」→「SLDファイルとして」でSLDファイルを任意の場所に保存します。
- GeoServerの「スタイル」→「新規スタイル追加」→「Style Content」で、作成しておいたSLDファイルを指定し、「アップロード」→「送信」します。
- 「レイヤ」→「公開」→「WMS設定」でデフォルトスタイルを作成したスタイルに指定します。

## Leafletで表示する
- こうです（雑）

```js

L.tileLayer.wms('http://localhost:8080/geoserver/ows?SERVICE=WMS&', {
    layers: 'ワークスペース名:レイヤ名',
    format: 'image/png',
    transparent: true,
});
```

## 補足
- 今回はGeoServerを使ってみましたが、[postgREST](http://postgrest.org/en/v7.0.0/)とか[Dirt Simple PostGIS HTTP API](https://github.com/tobinbradley/dirt-simple-postgis-http-api)を使ってjsonを返すREST APIを作ることもできそうです。