QGISで楽しく3D表現してみる

[FOSS4G Advent Calendar 2021](https://qiita.com/advent-calendar/2021/foss4g) 12日目の記事です。


**追記**
<font color="red">本記事はQGIS バージョン3.14を使用して書いております。
本記事で紹介しているSAGAツールはQGIS 3.16以降では使えないようですのでご注意ください。</font>


## QGISの地図上にお好きな3Dモデルを生やすことができるんですよ。

いきなりですが、そうなんですよ。知っていましたか？

方法はQgis2threejsプラグインを使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/2564ad29-1be5-86e7-184e-6357f1c5c807.png)

#### QGIS2threejsの使い方
プラグインを実行すると、別ウインドウが立ち上がります。
左パネルのレイヤの一覧から「GSI Elevation Tile」にチェックを入れると立体地形の地図が描画されます。（自身で追加しているDEMのラスタデータにチェックを入れてもOKです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/4253740f-32e6-bc81-8d53-03b173117a04.png)

3Dモデルを配置するポイントデータをレイヤに追加しておき、プラグイン画面でポイントのプロパティを開きます。

設定箇所は以下3点

- Object type をModel Fileにする
- Z coordinateのModeを「Relative to "GSI Elevation Tile"」（もしくは、自身で用意したDEMラスター）にする
- Model fileで配置する3Dモデルのファイルを選択する。（ローカルにあるファイルを選択しても良いし、ネット上のURLを入力しても良い。

![スクリーンショット 2021-12-12 3.24.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/d3b6ebab-6294-0f7b-d56f-b1345a616e5b.png)

以上、設定してOKを押すと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/e87db4f9-55ea-7dd8-fb3d-2deb2949505f.png)

もうサクッと、モデルが配置されるわけなんですね。
これでみなさんも、お好きなモデルを配置してグリグリ動かしてみてください:wink:


以上、「QGISで楽しく3D表現してみる」でした。

おわり


# ここからは余談

## もっと木とかいろんな3Dモデル配置して、実際の風景に近づけたいなぁ
記事の本編は以上になりますが、さすがにこれで終わると味気ないのでもうちょっと遊んでみようと思います。

せっかく3Dモデルを配置できることがわかったので、樹林や建物などいろんな種類のモデルを配置して実際の景色を再現したりできると、楽しそうだと思いませんか？
思いますよね。
うん、思ってきましたね。


例えば本編で紹介した風車のモデルで言うと、障害物がないため風車の足元までしっかり見えていますが、実際には周辺の樹木などによって風車の足元までしっかり見えるということはあまりないかと思います。そのため、このままだと3Dモデルで風車を見せても現実味が薄れてしまいます。

そこで、ここからは樹木などいろいろなモデルを描画させて、さらに現実味の高い3D地図を作成していきたいと思います。

完成イメージとしてこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/b3eaf9b5-32a6-dcd0-b431-adf44d606410.png)



## QGISを使って「おうとまちっく」に樹林のポイントを作ってみる。

樹木のモデルを配置するにしても、本編で紹介したようにその地点のポイントデータが必要になります。つまり樹木1本1本の位置にポイントデータを作成する必要があります。

国土地理院などが公開している航空写真は高解像のものも多く、目で見て1本1本の木がわかるものもあります。
航空写真から判読して手作業でポイントを落としていくのもいいのですがそれだと芸がないので、航空写真からある程度自動で判読して、1本1本の木の位置をポイント化ししていきたいと思います。

![Desktop - 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/156d81c7-8693-a64c-19cf-fdb23a72cecb.png)
（作業イメージ）


## 材料

#### 対象エリアの航空写真（高解像度であればあるほど良い）
樹木のポイントデータを生成するための航空写真を用意します。

今回は[国土地理院](https://maps.gsi.go.jp/development/ichiran.html)からタイル配信されているこちらのデータを使います。

令和3年7月1日からの大雨 正射画像 熱海伊豆山地区（7/6撮影）
URL：```https://cyberjapandata.gsi.go.jp/xyz/20210705oame_0706do/{z}/{x}/{y}.png```

#### 土地利用データ
木のモデルを生やすのはもちろん樹林地だけにしたいので、土地利用から樹林地かそうでないかの判別を行うために使います。
今回は、JAXAが提供している[高解像度土地利用土地被覆図](https://www.eorc.jaxa.jp/ALOS/jp/dataset/lulc_j.htm)を使用していきます。

![v21.11_overview_legend_jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/3d17c0d6-44cf-b788-c494-2bcabd6d6b07.png)
(出典：　JAXA 高解像度土地利用土地被覆図)


#### 樹木高さデータ
せっかくなら樹木の高さに合わせてモデルの大きさを変えられたら面白いなと思うので、樹木の地面からの高さ（[DHM：Digital Height Model](https://www.aw3d.jp/glossary/))も算出していきます。

DHMは、建物等の含んだ地物の表層の高さ（DSM）から地盤高の高さ(DTM)を差し引いて求めることができます。
（DHM、DTM、DHMの用語の説明は[こちら](https://www.aw3d.jp/glossary/)をご参照ください）

DSMはJAXA 第一宇宙技術部門 地球観測研究センター（EORC）より提供されている、[ALOS全球数値地表モデル](https://www.eorc.jaxa.jp/ALOS/jp/dataset/aw3d30/aw3d30_j.htm)を、
DEMは一般財団法人宇宙システム開発利用推進機構(Japan Space Systems)より提供されている[ASTER全球3次元地形データ／ASTER GDEM](https://www.jspacesystems.or.jp/ersdac/GDEM/J/)を活用しました。



##調理方法

### 樹木のポイントデータ作成
#### タイルを読み込んで、任意の場所の地図を表示する。

xyz tileの読み込み方はこちらをご参照ください。
[QGIS3でウェブ地図利用が劇的に変化した](https://qiita.com/ishiijunpei/items/59136a778a183484734e)

タイルを読み込んだらお好きな場所を表示させます。
広範囲すぎると樹木のポイントデータが大量にできてしまって、いざ3Dモデルを描画しようとした際に時間がかかってしまうため、狭いエリアで試してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/201af8ef-a24e-3506-3bea-fce89411ceaa.png)


#### 地図を画像にエクスポートする
好きなエリアを表示したら、画像として保存します。

`プロジェクト`　＞`インポートとエクスポート` ＞　　`地図を画像にエクスポート`を選択します。
エクスポートの設定は特にいじらなくて良いですが、`地理参照情報を追加`にはチェックを入れておいてください

![Arrow 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/98d1fa06-7850-7f67-2c6f-d554b094b2ff.png)


#### 樹冠の判読
エクスポートした画像の樹冠を判別していきます。
樹冠の判別方法は様々あるかと思いますが、今回は流域解析(watershed)を使って簡易的に行います。

(watershedを使った樹冠判読はこちらなどを参考にしました。)
[Wan Shafrina Wan Mohd Jaafar et al(2018), Improving Individual Tree Crown Delineation and Attributes Estimation of Tropical Forests, Forests 2018,9(12)Using Airborne LiDAR Data](https://www.mdpi.com/1999-4907/9/12/759)


WatershedはQGISのプロセッシング（正確にはSAGAツール）にも備わっております。
（プロセッシング > SAGA > Watershed segmentation）

![Desktop - 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/463a37e0-c5bb-ee38-220a-fa9491d0a97b.png)

設定は以下の通り
- グリッド：先ほどエクスポートした画像
- 出力：SegmentID
- 方法：Maxima
- 結合セグメント：seed to saddle difference　
- 閾値：5　

接合セグメントと閾値は、樹冠と樹冠の間をどの様に設定するかのパラメータです。結合セグメントはseed(樹冠のトップ)と樹間のヘリのピクセル値の差が閾値で設定した値より大きいところを樹冠の境界にする。というイメージです。
閾値が大きいと１つ１つの樹冠が大きく判読され、小さいと細かい樹冠として判読されます。


処理結果にはセグメント、seed point、境界の３つが出力されますが、必要なのはセグメントのみです。
セグメント：樹冠ごとの領域を示したラスターデータ
seed：それぞれの樹冠ポイントデータ
境界：樹間の境界を示したラスターデータ

![Desktop - 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/45ccf948-0ca3-ac48-1b09-b89eebe9d360.png)

ポイントデータ(seed)も出力されますが、このポイントの位置は、閾値などの設定が反映されていないので、segmentから改めてポイントデータを作ります。

#### ポイントデータの生成
それぞれ以下のプロセッシングで、segmentラスターデータをポリゴン化し、そのポリゴンの重心にポイントを作ります。
segmentラスターデータをポリゴン化：`ラスタのベクタ化`
ポリゴンの重心にポイントを生成：`重心`

結果、こんな感じで、なんとなく1本1本の木にポイントが落ちて、（なんならソーラーパネルにもポイントができて）いい感じになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/7c50f0ff-8e77-10d9-daca-a5a3100caaae.png)


### 樹高を求める

ラスタ計算機でDSM-DTMを計算してDHMを求めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/2d44e024-c043-6f17-56ef-ec796a9510fa.png)

処理結果はこんな感じ。これだけみると何が何だが。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/0a698aea-8b98-8e96-655c-1dfbe4697e25.png)


`ベクタレイヤにラスタ値を付与`ポイントデータの属性に、DHMの値を付与します。



### ポイントデータに土地利用の情報を付与する

JAXAの高解像度土地利用土地被覆図を追加します。
ラスタには以下の凡例にあるように土地利用のコードが記録されています。

![v21.11_overview_legend_jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/6baffed8-12b7-5749-ec1e-770687f5c788.png)


DHMと同様に「ベクタレイヤにラスタ値を付与」を使って、今度はこのコードの値をポイントデータの属性に付与します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/b5b47e22-bb09-89db-3838-51a3aac3d227.png)
(ポイントデータの属性。heiht_1がDHMの値、landuse_1が土地利用のコード)

ポイントデータを土地利用ごとに色分けしたらこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/c3033a75-9c3e-2968-3e14-b5c2b500fbe8.png)


### ポイントデータの属性に3DモデルのURLを付与する。

それぞれのポイントの地点に土地利用に適した3Dモデルを描画するために、属性テーブルを１列追加し、土地利用に合わせたモデルへのリンクを入力していきます。

3Dモデルは自身で用意してもいいですが、今回はこちらに公開されているモデルを使用していきます。
https://market.pmnd.rs/

こちらのサイトで公開されている3Dモデルはダウンロードして使用することもできるし、モデルへのダイレクトリンクも取得できるのでリンクにアクセスして使用することもできます。
（利用の際はそれぞれのモデルのCCライセンスに従ってください。）

例えばこちらの[Tree Beech](https://market.pmnd.rs/model/tree-lime) 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/7c232aaa-e5e0-b798-c846-d52c9f521910.png)

広葉樹林（land useが6か8のポイント）のポイントには、このモデルを生やしたいと思います。
Copy direct linkをクリックして、このモデルのURLをコピーします。


landuseが6と8は広葉樹林なので、3DモデルURLのカラムにコピーしたTree Beechへのリンク入力します。
（属性による選択　→ フィールド計算機）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/06454598-a82f-6887-7070-662cb6d157a3.png)

同様に針葉樹林として[Tree spruce](https://market.pmnd.rs/model/tree-spruce)のモデルのリンクをコピーして、landuseが7と９（針葉樹林）の地物にURLを入力します。


### ３D表現してみる
とりあえず広葉樹林と針葉樹林の用意ができたので、3D描画してみたいと思います。
Qgis2threejsを起動し、ポイインとデータのプロパティで以下の項目を設定します。　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　
- `Object type` :　Model File
- `Z coordinate　Mode` : Relative to "GSI Elevation Tile" 
- `Model file` ：Model path or URLにし、属性テーブルから３DモデルのURLのカラムを指定する。
- `Scale`：樹高などの数値によってモデルの大きさを変えるときにはこちらをいじります。ひとまずデフォルトの１のままやってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/458216a5-fa89-73e3-780b-fdffd8834fee.png)


きちんとそれぞれのモデルが描画できました!!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/95b3db22-d239-ebf6-24cd-acc6c705e3cc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/f5702800-eaf3-7aee-0bc2-d4a174d850d9.png)


## 地物高ごとにモデルの大きさを変えてみる
せっかく地物高を求めたので、その値ごとにモデルの大きさを変えてみたい。やり方としてはポイントデータのプロパティからScaleの項目を一意の値ではなく、地物高の値のカラムを指定すればその値の倍率でモデルが描画されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/6e524169-c578-c33e-fe17-78deac7e1daf.png)

・・・のだが、今回サンプルで用いたモデルのオリジナルの大きさが大きい（デフォルトで18mくらいの高さ）ので、例えばDHMの値が10のポイントには18 x 10で180mの大木が生えてしまうことになります。どこの密林やねん。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/cfffa8a7-d19c-5cac-7846-8cd0db00af4c.png)


なので、モデルをダウンロードして、blenderでサイズを小さくして（デフォルトの大きさを1mくらいにして）、適当な場所にファイルをアップして、URLを変更します。
（この辺の作業は、QGISじゃないので割愛して画像だけ載せておきます）

![Desktop - 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/3784d87e-e1df-04cf-2fdb-23cd21320c6e.png)


## 結果

実際との樹高の精度はさておき、きちんとスケールごとにモデルの大きさを変えて描画することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/0da5f356-bd3c-6095-9d27-62895f10d43b.png)


せっかくなので、他の土地利用にもそれぞれのモデルを当ててみた。

竹林、建築物、ソーラーパネルなど。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/6c3a41c5-9b44-479d-4feb-c3c1cb794d2b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/a3f405f1-1b52-721b-9336-38aadedbf8c8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61492/9dcffb31-ec09-7d38-734c-d07b04f3d4b1.png)



以上、FOSS4G Advent Calendar 2021 12日目 「QGISで楽しく3D表現してみる」でした。


使用した3Dモデル
[広葉樹林](https://market.pmnd.rs/model/tree-beech)
[針葉樹林](https://market.pmnd.rs/model/tree-spruce)
[都市](https://market.pmnd.rs/model/house1)
[竹林](https://www.cgtrader.com/items/2998423/download-page)